Merge
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index b6c4116..d658d3b 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -198,3 +198,4 @@
 b43aa5bd8ca5c8121336495382d35ecfa7a71536 jdk8-b74
 2a713921952cbd77a1e699626976cb6cdfe3e57e jdk8-b75
 278af9fc67e7eba2884936b49ec07345f423aabb jdk8-b76
+3933eebc659d58c597aa8cb4b3e58f2250ce3e1a jdk8-b77
diff --git a/NewMakefile.gmk b/NewMakefile.gmk
index ce711a8..b02e37f 100644
--- a/NewMakefile.gmk
+++ b/NewMakefile.gmk
@@ -96,6 +96,7 @@
 	$(info .  make all               # Compile everything, all repos and images)
 	$(info .  make images            # Create complete j2sdk and j2re images)
 	$(info .  make overlay-images    # Create limited images for sparc 64 bit platforms)
+	$(info .  make profiles          # Create complete j2re compact profile images)
 	$(info .  make bootcycle-images  # Build images twice, second time with newly build JDK)
 	$(info .  make install           # Install the generated images locally)
 	$(info .  make clean             # Remove all files generated by make, but not those)
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index d53e56e..741160e 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67 for OpenJDK jdk8.
+# Generated by GNU Autoconf 2.68 for OpenJDK jdk8.
 #
 # Report bugs to <build-dev@openjdk.java.net>.
 #
@@ -91,6 +91,7 @@
 IFS=" ""	$as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -216,11 +217,18 @@
   # We cannot yet assume a decent shell, so we have to provide a
 	# neutralization value for shells without unset; and this also
 	# works around shells that cannot unset nonexistent variables.
+	# Preserve -v and -x to the replacement shell.
 	BASH_ENV=/dev/null
 	ENV=/dev/null
 	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
 	export CONFIG_SHELL
-	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+	case $- in # ((((
+	  *v*x* | *x*v* ) as_opts=-vx ;;
+	  *v* ) as_opts=-v ;;
+	  *x* ) as_opts=-x ;;
+	  * ) as_opts= ;;
+	esac
+	exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
 fi
 
     if test x$as_have_required = xno; then :
@@ -641,6 +649,7 @@
 CXXFLAGS_JDKLIB
 CFLAGS_JDKEXE
 CFLAGS_JDKLIB
+MACOSX_REQUIRED_VERSION
 PACKAGE_PATH
 LEGACY_EXTRA_LDFLAGS
 LEGACY_EXTRA_CXXFLAGS
@@ -1433,7 +1442,7 @@
     $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
   esac
@@ -1858,7 +1867,7 @@
 if $ac_init_version; then
   cat <<\_ACEOF
 OpenJDK configure jdk8
-generated by GNU Autoconf 2.67
+generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
@@ -1904,7 +1913,7 @@
 
 	ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_compile
@@ -1942,7 +1951,7 @@
 
 	ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_cxx_try_compile
@@ -1980,7 +1989,7 @@
 
 	ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_objc_try_compile
@@ -2017,7 +2026,7 @@
 
     ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_cpp
@@ -2054,7 +2063,7 @@
 
     ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_cxx_try_cpp
@@ -2067,10 +2076,10 @@
 ac_fn_cxx_check_header_mongrel ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval "test \"\${$3+set}\"" = set; then :
+  if eval \${$3+:} false; then :
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 fi
 eval ac_res=\$$3
@@ -2137,7 +2146,7 @@
 esac
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   eval "$3=\$ac_header_compiler"
@@ -2146,7 +2155,7 @@
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_cxx_check_header_mongrel
 
@@ -2187,7 +2196,7 @@
        ac_retval=$ac_status
 fi
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_cxx_try_run
@@ -2201,7 +2210,7 @@
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2219,7 +2228,7 @@
 eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_cxx_check_header_compile
 
@@ -2396,7 +2405,7 @@
 rm -f conftest.val
 
   fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_cxx_compute_int
@@ -2442,7 +2451,7 @@
   # interfere with the next link command; also delete a directory that is
   # left behind by Apple's compiler.  We do this before executing the actions.
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_cxx_try_link
@@ -2455,7 +2464,7 @@
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2510,7 +2519,7 @@
 eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_cxx_check_func
 
@@ -2523,7 +2532,7 @@
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2541,7 +2550,7 @@
 eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_header_compile
 cat >config.log <<_ACEOF
@@ -2549,7 +2558,7 @@
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by OpenJDK $as_me jdk8, which was
-generated by GNU Autoconf 2.67.  Invocation command line was
+generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
 
@@ -2807,7 +2816,7 @@
       || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
   fi
 done
 
@@ -3723,7 +3732,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1359971740
+DATE_WHEN_GENERATED=1361218904
 
 ###############################################################################
 #
@@ -3761,7 +3770,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BASENAME+set}" = set; then :
+if ${ac_cv_path_BASENAME+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $BASENAME in
@@ -3820,7 +3829,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BASH+set}" = set; then :
+if ${ac_cv_path_BASH+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $BASH in
@@ -3879,7 +3888,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CAT+set}" = set; then :
+if ${ac_cv_path_CAT+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CAT in
@@ -3938,7 +3947,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHMOD+set}" = set; then :
+if ${ac_cv_path_CHMOD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CHMOD in
@@ -3997,7 +4006,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CMP+set}" = set; then :
+if ${ac_cv_path_CMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CMP in
@@ -4056,7 +4065,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_COMM+set}" = set; then :
+if ${ac_cv_path_COMM+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $COMM in
@@ -4115,7 +4124,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CP+set}" = set; then :
+if ${ac_cv_path_CP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CP in
@@ -4174,7 +4183,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CPIO+set}" = set; then :
+if ${ac_cv_path_CPIO+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CPIO in
@@ -4233,7 +4242,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CUT+set}" = set; then :
+if ${ac_cv_path_CUT+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CUT in
@@ -4292,7 +4301,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_DATE+set}" = set; then :
+if ${ac_cv_path_DATE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $DATE in
@@ -4351,7 +4360,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_DIFF+set}" = set; then :
+if ${ac_cv_path_DIFF+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $DIFF in
@@ -4410,7 +4419,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_DIRNAME+set}" = set; then :
+if ${ac_cv_path_DIRNAME+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $DIRNAME in
@@ -4469,7 +4478,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_ECHO+set}" = set; then :
+if ${ac_cv_path_ECHO+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $ECHO in
@@ -4528,7 +4537,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_EXPR+set}" = set; then :
+if ${ac_cv_path_EXPR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $EXPR in
@@ -4587,7 +4596,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_FILE+set}" = set; then :
+if ${ac_cv_path_FILE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $FILE in
@@ -4646,7 +4655,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_FIND+set}" = set; then :
+if ${ac_cv_path_FIND+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $FIND in
@@ -4705,7 +4714,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_HEAD+set}" = set; then :
+if ${ac_cv_path_HEAD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $HEAD in
@@ -4764,7 +4773,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_LN+set}" = set; then :
+if ${ac_cv_path_LN+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $LN in
@@ -4823,7 +4832,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_LS+set}" = set; then :
+if ${ac_cv_path_LS+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $LS in
@@ -4882,7 +4891,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_MKDIR+set}" = set; then :
+if ${ac_cv_path_MKDIR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $MKDIR in
@@ -4941,7 +4950,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_MKTEMP+set}" = set; then :
+if ${ac_cv_path_MKTEMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $MKTEMP in
@@ -5000,7 +5009,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_MV+set}" = set; then :
+if ${ac_cv_path_MV+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $MV in
@@ -5059,7 +5068,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_PRINTF+set}" = set; then :
+if ${ac_cv_path_PRINTF+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $PRINTF in
@@ -5118,7 +5127,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_THEPWDCMD+set}" = set; then :
+if ${ac_cv_path_THEPWDCMD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $THEPWDCMD in
@@ -5177,7 +5186,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_RM+set}" = set; then :
+if ${ac_cv_path_RM+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $RM in
@@ -5236,7 +5245,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_SH+set}" = set; then :
+if ${ac_cv_path_SH+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $SH in
@@ -5295,7 +5304,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_SORT+set}" = set; then :
+if ${ac_cv_path_SORT+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $SORT in
@@ -5354,7 +5363,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TAIL+set}" = set; then :
+if ${ac_cv_path_TAIL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $TAIL in
@@ -5413,7 +5422,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TAR+set}" = set; then :
+if ${ac_cv_path_TAR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $TAR in
@@ -5472,7 +5481,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TEE+set}" = set; then :
+if ${ac_cv_path_TEE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $TEE in
@@ -5531,7 +5540,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TOUCH+set}" = set; then :
+if ${ac_cv_path_TOUCH+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $TOUCH in
@@ -5590,7 +5599,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TR+set}" = set; then :
+if ${ac_cv_path_TR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $TR in
@@ -5649,7 +5658,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_UNAME+set}" = set; then :
+if ${ac_cv_path_UNAME+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $UNAME in
@@ -5708,7 +5717,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_UNIQ+set}" = set; then :
+if ${ac_cv_path_UNIQ+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $UNIQ in
@@ -5767,7 +5776,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_WC+set}" = set; then :
+if ${ac_cv_path_WC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $WC in
@@ -5826,7 +5835,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_WHICH+set}" = set; then :
+if ${ac_cv_path_WHICH+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $WHICH in
@@ -5885,7 +5894,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_XARGS+set}" = set; then :
+if ${ac_cv_path_XARGS+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $XARGS in
@@ -5945,7 +5954,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
+if ${ac_cv_prog_AWK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AWK"; then
@@ -5995,7 +6004,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
 $as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
+if ${ac_cv_path_GREP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$GREP"; then
@@ -6070,7 +6079,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
 $as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
+if ${ac_cv_path_EGREP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
@@ -6149,7 +6158,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
 $as_echo_n "checking for fgrep... " >&6; }
-if test "${ac_cv_path_FGREP+set}" = set; then :
+if ${ac_cv_path_FGREP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
@@ -6228,7 +6237,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
 $as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if test "${ac_cv_path_SED+set}" = set; then :
+if ${ac_cv_path_SED+:} false; then :
   $as_echo_n "(cached) " >&6
 else
             ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
@@ -6314,7 +6323,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_NAWK+set}" = set; then :
+if ${ac_cv_path_NAWK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $NAWK in
@@ -6374,7 +6383,7 @@
 set dummy cygpath; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CYGPATH+set}" = set; then :
+if ${ac_cv_path_CYGPATH+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CYGPATH in
@@ -6414,7 +6423,7 @@
 set dummy readlink; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_READLINK+set}" = set; then :
+if ${ac_cv_path_READLINK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $READLINK in
@@ -6454,7 +6463,7 @@
 set dummy df; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_DF+set}" = set; then :
+if ${ac_cv_path_DF+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $DF in
@@ -6494,7 +6503,7 @@
 set dummy SetFile; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_SETFILE+set}" = set; then :
+if ${ac_cv_path_SETFILE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $SETFILE in
@@ -6540,7 +6549,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
 $as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
+if ${ac_cv_build+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_build_alias=$build_alias
@@ -6556,7 +6565,7 @@
 $as_echo "$ac_cv_build" >&6; }
 case $ac_cv_build in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
 esac
 build=$ac_cv_build
 ac_save_IFS=$IFS; IFS='-'
@@ -6574,7 +6583,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
 $as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
+if ${ac_cv_host+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test "x$host_alias" = x; then
@@ -6589,7 +6598,7 @@
 $as_echo "$ac_cv_host" >&6; }
 case $ac_cv_host in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
 esac
 host=$ac_cv_host
 ac_save_IFS=$IFS; IFS='-'
@@ -6607,7 +6616,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
 $as_echo_n "checking target system type... " >&6; }
-if test "${ac_cv_target+set}" = set; then :
+if ${ac_cv_target+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test "x$target_alias" = x; then
@@ -6622,7 +6631,7 @@
 $as_echo "$ac_cv_target" >&6; }
 case $ac_cv_target in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
 esac
 target=$ac_cv_target
 ac_save_IFS=$IFS; IFS='-'
@@ -8088,7 +8097,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_PKGHANDLER+set}" = set; then :
+if ${ac_cv_prog_PKGHANDLER+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$PKGHANDLER"; then
@@ -8453,7 +8462,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHECK_GMAKE+set}" = set; then :
+if ${ac_cv_path_CHECK_GMAKE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CHECK_GMAKE in
@@ -8807,7 +8816,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHECK_MAKE+set}" = set; then :
+if ${ac_cv_path_CHECK_MAKE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CHECK_MAKE in
@@ -9166,7 +9175,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then :
+if ${ac_cv_path_CHECK_TOOLSDIR_GMAKE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CHECK_TOOLSDIR_GMAKE in
@@ -9519,7 +9528,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then :
+if ${ac_cv_path_CHECK_TOOLSDIR_MAKE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CHECK_TOOLSDIR_MAKE in
@@ -9915,7 +9924,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_UNZIP+set}" = set; then :
+if ${ac_cv_path_UNZIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $UNZIP in
@@ -9974,7 +9983,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_ZIP+set}" = set; then :
+if ${ac_cv_path_ZIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $ZIP in
@@ -10033,7 +10042,7 @@
 set dummy ldd; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_LDD+set}" = set; then :
+if ${ac_cv_path_LDD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $LDD in
@@ -10079,7 +10088,7 @@
 set dummy otool; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_OTOOL+set}" = set; then :
+if ${ac_cv_path_OTOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $OTOOL in
@@ -10124,7 +10133,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_READELF+set}" = set; then :
+if ${ac_cv_path_READELF+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $READELF in
@@ -10167,7 +10176,7 @@
 set dummy hg; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_HG+set}" = set; then :
+if ${ac_cv_path_HG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $HG in
@@ -10207,7 +10216,7 @@
 set dummy stat; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_STAT+set}" = set; then :
+if ${ac_cv_path_STAT+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $STAT in
@@ -10247,7 +10256,7 @@
 set dummy time; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TIME+set}" = set; then :
+if ${ac_cv_path_TIME+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $TIME in
@@ -10292,7 +10301,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_COMM+set}" = set; then :
+if ${ac_cv_path_COMM+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $COMM in
@@ -10356,7 +10365,7 @@
 set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $PKG_CONFIG in
@@ -10399,7 +10408,7 @@
 set dummy pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_PKG_CONFIG in
@@ -10572,7 +10581,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then :
+if ${ac_cv_prog_BDEPS_UNZIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$BDEPS_UNZIP"; then
@@ -10618,7 +10627,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_BDEPS_FTP+set}" = set; then :
+if ${ac_cv_prog_BDEPS_FTP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$BDEPS_FTP"; then
@@ -11885,7 +11894,7 @@
 set dummy javac; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then :
+if ${ac_cv_path_JAVAC_CHECK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $JAVAC_CHECK in
@@ -11925,7 +11934,7 @@
 set dummy java; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_JAVA_CHECK+set}" = set; then :
+if ${ac_cv_path_JAVA_CHECK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $JAVA_CHECK in
@@ -15984,7 +15993,7 @@
 set dummy link; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then :
+if ${ac_cv_path_CYGWIN_LINK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CYGWIN_LINK in
@@ -16973,7 +16982,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BUILD_CC+set}" = set; then :
+if ${ac_cv_path_BUILD_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $BUILD_CC in
@@ -17284,7 +17293,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BUILD_CXX+set}" = set; then :
+if ${ac_cv_path_BUILD_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $BUILD_CXX in
@@ -17593,7 +17602,7 @@
 set dummy ld; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BUILD_LD+set}" = set; then :
+if ${ac_cv_path_BUILD_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $BUILD_LD in
@@ -18105,7 +18114,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then :
+if ${ac_cv_path_TOOLS_DIR_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $TOOLS_DIR_CC in
@@ -18157,7 +18166,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_POTENTIAL_CC+set}" = set; then :
+if ${ac_cv_path_POTENTIAL_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $POTENTIAL_CC in
@@ -18570,7 +18579,7 @@
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then :
+if ${ac_cv_prog_PROPER_COMPILER_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$PROPER_COMPILER_CC"; then
@@ -18614,7 +18623,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_PROPER_COMPILER_CC"; then
@@ -19064,7 +19073,7 @@
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -19108,7 +19117,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -19161,7 +19170,7 @@
 test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
 $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -19276,7 +19285,7 @@
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
@@ -19319,7 +19328,7 @@
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest conftest$ac_cv_exeext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -19378,7 +19387,7 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
     fi
   fi
 fi
@@ -19389,7 +19398,7 @@
 ac_clean_files=$ac_clean_files_save
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
 $as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
+if ${ac_cv_objext+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -19430,7 +19439,7 @@
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
@@ -19440,7 +19449,7 @@
 ac_objext=$OBJEXT
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+if ${ac_cv_c_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -19477,7 +19486,7 @@
 ac_save_CFLAGS=$CFLAGS
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
 $as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
+if ${ac_cv_prog_cc_g+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_save_c_werror_flag=$ac_c_werror_flag
@@ -19555,7 +19564,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
+if ${ac_cv_prog_cc_c89+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_prog_cc_c89=no
@@ -19674,7 +19683,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then :
+if ${ac_cv_path_TOOLS_DIR_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $TOOLS_DIR_CXX in
@@ -19726,7 +19735,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then :
+if ${ac_cv_path_POTENTIAL_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $POTENTIAL_CXX in
@@ -20139,7 +20148,7 @@
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then :
+if ${ac_cv_prog_PROPER_COMPILER_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$PROPER_COMPILER_CXX"; then
@@ -20183,7 +20192,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then :
+if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_PROPER_COMPILER_CXX"; then
@@ -20637,7 +20646,7 @@
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CXX+set}" = set; then :
+if ${ac_cv_prog_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CXX"; then
@@ -20681,7 +20690,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CXX"; then
@@ -20759,7 +20768,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20796,7 +20805,7 @@
 ac_save_CXXFLAGS=$CXXFLAGS
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
 $as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if test "${ac_cv_prog_cxx_g+set}" = set; then :
+if ${ac_cv_prog_cxx_g+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_save_cxx_werror_flag=$ac_cxx_werror_flag
@@ -20894,7 +20903,7 @@
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJC+set}" = set; then :
+if ${ac_cv_prog_OBJC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$OBJC"; then
@@ -20938,7 +20947,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_OBJC"; then
@@ -21014,7 +21023,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5
 $as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; }
-if test "${ac_cv_objc_compiler_gnu+set}" = set; then :
+if ${ac_cv_objc_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -21051,7 +21060,7 @@
 ac_save_OBJCFLAGS=$OBJCFLAGS
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5
 $as_echo_n "checking whether $OBJC accepts -g... " >&6; }
-if test "${ac_cv_prog_objc_g+set}" = set; then :
+if ${ac_cv_prog_objc_g+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_save_objc_werror_flag=$ac_objc_werror_flag
@@ -21427,7 +21436,7 @@
 set dummy ${ac_tool_prefix}ar; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
+if ${ac_cv_prog_AR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AR"; then
@@ -21467,7 +21476,7 @@
 set dummy ar; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_AR"; then
@@ -21809,7 +21818,7 @@
 set dummy link; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_WINLD+set}" = set; then :
+if ${ac_cv_prog_WINLD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$WINLD"; then
@@ -22148,7 +22157,7 @@
 set dummy mt; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_MT+set}" = set; then :
+if ${ac_cv_prog_MT+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$MT"; then
@@ -22469,7 +22478,7 @@
 set dummy rc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RC+set}" = set; then :
+if ${ac_cv_prog_RC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$RC"; then
@@ -22860,7 +22869,7 @@
 set dummy lib; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_WINAR+set}" = set; then :
+if ${ac_cv_prog_WINAR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$WINAR"; then
@@ -23166,7 +23175,7 @@
 set dummy dumpbin; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+if ${ac_cv_prog_DUMPBIN+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$DUMPBIN"; then
@@ -23485,7 +23494,7 @@
   CPP=
 fi
 if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then :
+  if ${ac_cv_prog_CPP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
       # Double quotes because CPP needs to be expanded
@@ -23601,7 +23610,7 @@
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 ac_ext=cpp
@@ -23885,7 +23894,7 @@
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
 $as_echo_n "checking how to run the C++ preprocessor... " >&6; }
 if test -z "$CXXCPP"; then
-  if test "${ac_cv_prog_CXXCPP+set}" = set; then :
+  if ${ac_cv_prog_CXXCPP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
       # Double quotes because CXXCPP needs to be expanded
@@ -24001,7 +24010,7 @@
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 ac_ext=cpp
@@ -24303,7 +24312,7 @@
 set dummy as; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_AS+set}" = set; then :
+if ${ac_cv_path_AS+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $AS in
@@ -24617,7 +24626,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_NM+set}" = set; then :
+if ${ac_cv_path_NM+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $NM in
@@ -24926,7 +24935,7 @@
 set dummy strip; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_STRIP+set}" = set; then :
+if ${ac_cv_path_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $STRIP in
@@ -25232,7 +25241,7 @@
 set dummy mcs; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_MCS+set}" = set; then :
+if ${ac_cv_path_MCS+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $MCS in
@@ -25540,7 +25549,7 @@
 set dummy ${ac_tool_prefix}nm; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_NM+set}" = set; then :
+if ${ac_cv_prog_NM+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$NM"; then
@@ -25580,7 +25589,7 @@
 set dummy nm; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_NM+set}" = set; then :
+if ${ac_cv_prog_ac_ct_NM+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_NM"; then
@@ -25898,7 +25907,7 @@
 set dummy ${ac_tool_prefix}strip; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
+if ${ac_cv_prog_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$STRIP"; then
@@ -25938,7 +25947,7 @@
 set dummy strip; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_STRIP"; then
@@ -26263,7 +26272,7 @@
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJCOPY+set}" = set; then :
+if ${ac_cv_prog_OBJCOPY+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$OBJCOPY"; then
@@ -26307,7 +26316,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_OBJCOPY"; then
@@ -26634,7 +26643,7 @@
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_OBJDUMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$OBJDUMP"; then
@@ -26678,7 +26687,7 @@
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_OBJDUMP"; then
@@ -27002,7 +27011,7 @@
 set dummy lipo; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_LIPO+set}" = set; then :
+if ${ac_cv_path_LIPO+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $LIPO in
@@ -27317,7 +27326,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -27493,7 +27502,7 @@
 for ac_header in stdio.h
 do :
   ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default"
-if test "x$ac_cv_header_stdio_h" = x""yes; then :
+if test "x$ac_cv_header_stdio_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_STDIO_H 1
 _ACEOF
@@ -27522,7 +27531,7 @@
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5
 $as_echo_n "checking size of int *... " >&6; }
-if test "${ac_cv_sizeof_int_p+set}" = set; then :
+if ${ac_cv_sizeof_int_p+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p"        "$ac_includes_default"; then :
@@ -27532,7 +27541,7 @@
      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (int *)
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
    else
      ac_cv_sizeof_int_p=0
    fi
@@ -27579,7 +27588,7 @@
 #
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
 $as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if test "${ac_cv_c_bigendian+set}" = set; then :
+if ${ac_cv_c_bigendian+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_c_bigendian=unknown
@@ -28233,6 +28242,10 @@
 fi
 if test "x$OPENJDK_TARGET_OS" = xmacosx; then
     CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE"
+    # Adding these macros will make it an error to link to mac APIs newer than OS version 10.7
+    MACOSX_REQUIRED_VERSION=1070
+
+    CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(MACOSX_REQUIRED_VERSION) -DMAC_OS_X_VERSION_MIN_REQUIRED=\$(MACOSX_REQUIRED_VERSION)"
 fi
 if test "x$OPENJDK_TARGET_OS" = xbsd; then
     CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DBSD -D_ALLBSD_SOURCE"
@@ -28579,8 +28592,8 @@
   have_x=disabled
 else
   case $x_includes,$x_libraries in #(
-    *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #(
-    *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then :
+    *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
+    *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   # One or both of the vars are not set, and there is no cached value.
@@ -28857,7 +28870,7 @@
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5
 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; }
-if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then :
+if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28891,14 +28904,14 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; }
-if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then :
+if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then :
   X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
 fi
 
     if test $ac_cv_lib_dnet_dnet_ntoa = no; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5
 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; }
-if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then :
+if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28932,7 +28945,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; }
-if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then :
+if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then :
   X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
 fi
 
@@ -28951,14 +28964,14 @@
     # The functions gethostbyname, getservbyname, and inet_addr are
     # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
     ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
-if test "x$ac_cv_func_gethostbyname" = x""yes; then :
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
 
 fi
 
     if test $ac_cv_func_gethostbyname = no; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
-if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then :
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28992,14 +29005,14 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
-if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then :
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
   X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
 fi
 
       if test $ac_cv_lib_nsl_gethostbyname = no; then
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5
 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; }
-if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then :
+if ${ac_cv_lib_bsd_gethostbyname+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29033,7 +29046,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5
 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; }
-if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then :
+if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then :
   X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
 fi
 
@@ -29048,14 +29061,14 @@
     # must be given before -lnsl if both are needed.  We assume that
     # if connect needs -lnsl, so does gethostbyname.
     ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect"
-if test "x$ac_cv_func_connect" = x""yes; then :
+if test "x$ac_cv_func_connect" = xyes; then :
 
 fi
 
     if test $ac_cv_func_connect = no; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5
 $as_echo_n "checking for connect in -lsocket... " >&6; }
-if test "${ac_cv_lib_socket_connect+set}" = set; then :
+if ${ac_cv_lib_socket_connect+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29089,7 +29102,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5
 $as_echo "$ac_cv_lib_socket_connect" >&6; }
-if test "x$ac_cv_lib_socket_connect" = x""yes; then :
+if test "x$ac_cv_lib_socket_connect" = xyes; then :
   X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
 fi
 
@@ -29097,14 +29110,14 @@
 
     # Guillermo Gomez says -lposix is necessary on A/UX.
     ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove"
-if test "x$ac_cv_func_remove" = x""yes; then :
+if test "x$ac_cv_func_remove" = xyes; then :
 
 fi
 
     if test $ac_cv_func_remove = no; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5
 $as_echo_n "checking for remove in -lposix... " >&6; }
-if test "${ac_cv_lib_posix_remove+set}" = set; then :
+if ${ac_cv_lib_posix_remove+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29138,7 +29151,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5
 $as_echo "$ac_cv_lib_posix_remove" >&6; }
-if test "x$ac_cv_lib_posix_remove" = x""yes; then :
+if test "x$ac_cv_lib_posix_remove" = xyes; then :
   X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
 fi
 
@@ -29146,14 +29159,14 @@
 
     # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
     ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat"
-if test "x$ac_cv_func_shmat" = x""yes; then :
+if test "x$ac_cv_func_shmat" = xyes; then :
 
 fi
 
     if test $ac_cv_func_shmat = no; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5
 $as_echo_n "checking for shmat in -lipc... " >&6; }
-if test "${ac_cv_lib_ipc_shmat+set}" = set; then :
+if ${ac_cv_lib_ipc_shmat+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29187,7 +29200,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5
 $as_echo "$ac_cv_lib_ipc_shmat" >&6; }
-if test "x$ac_cv_lib_ipc_shmat" = x""yes; then :
+if test "x$ac_cv_lib_ipc_shmat" = xyes; then :
   X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
 fi
 
@@ -29205,7 +29218,7 @@
   # John Interrante, Karl Berry
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5
 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; }
-if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then :
+if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29239,7 +29252,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; }
-if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then :
+if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then :
   X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
 fi
 
@@ -30252,7 +30265,7 @@
             LDFLAGS="$FREETYPE2_LIBS"
             { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5
 $as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; }
-if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then :
+if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -30286,7 +30299,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5
 $as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; }
-if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then :
+if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then :
   FREETYPE2_FOUND=true
 else
   as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5
@@ -30574,7 +30587,7 @@
 	    for ac_header in alsa/asoundlib.h
 do :
   ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then :
+if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_ALSA_ASOUNDLIB_H 1
 _ACEOF
@@ -30633,7 +30646,7 @@
 USE_EXTERNAL_LIBJPEG=true
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5
 $as_echo_n "checking for main in -ljpeg... " >&6; }
-if test "${ac_cv_lib_jpeg_main+set}" = set; then :
+if ${ac_cv_lib_jpeg_main+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -30661,7 +30674,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5
 $as_echo "$ac_cv_lib_jpeg_main" >&6; }
-if test "x$ac_cv_lib_jpeg_main" = x""yes; then :
+if test "x$ac_cv_lib_jpeg_main" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LIBJPEG 1
 _ACEOF
@@ -30685,7 +30698,7 @@
 USE_EXTERNAL_LIBJPEG=true
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgif" >&5
 $as_echo_n "checking for main in -lgif... " >&6; }
-if test "${ac_cv_lib_gif_main+set}" = set; then :
+if ${ac_cv_lib_gif_main+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -30713,7 +30726,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_main" >&5
 $as_echo "$ac_cv_lib_gif_main" >&6; }
-if test "x$ac_cv_lib_gif_main" = x""yes; then :
+if test "x$ac_cv_lib_gif_main" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LIBGIF 1
 _ACEOF
@@ -30743,7 +30756,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5
 $as_echo_n "checking for compress in -lz... " >&6; }
-if test "${ac_cv_lib_z_compress+set}" = set; then :
+if ${ac_cv_lib_z_compress+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -30777,7 +30790,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5
 $as_echo "$ac_cv_lib_z_compress" >&6; }
-if test "x$ac_cv_lib_z_compress" = x""yes; then :
+if test "x$ac_cv_lib_z_compress" = xyes; then :
    ZLIB_FOUND=yes
 else
    ZLIB_FOUND=no
@@ -30870,7 +30883,7 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
 $as_echo_n "checking for cos in -lm... " >&6; }
-if test "${ac_cv_lib_m_cos+set}" = set; then :
+if ${ac_cv_lib_m_cos+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -30904,7 +30917,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
 $as_echo "$ac_cv_lib_m_cos" >&6; }
-if test "x$ac_cv_lib_m_cos" = x""yes; then :
+if test "x$ac_cv_lib_m_cos" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LIBM 1
 _ACEOF
@@ -30928,7 +30941,7 @@
 LIBS=""
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+if ${ac_cv_lib_dl_dlopen+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -30962,7 +30975,7 @@
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LIBDL 1
 _ACEOF
@@ -31606,7 +31619,7 @@
 set dummy ccache; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CCACHE+set}" = set; then :
+if ${ac_cv_path_CCACHE+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $CCACHE in
@@ -31867,10 +31880,21 @@
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
+    if test "x$cache_file" != "x/dev/null"; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
 $as_echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -31902,7 +31926,7 @@
 
 
 
-: ${CONFIG_STATUS=./config.status}
+: "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
@@ -32003,6 +32027,7 @@
 IFS=" ""	$as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -32310,7 +32335,7 @@
 # values after options handling.
 ac_log="
 This file was extended by OpenJDK $as_me jdk8, which was
-generated by GNU Autoconf 2.67.  Invocation command line was
+generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -32373,7 +32398,7 @@
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 OpenJDK config.status jdk8
-configured by $0, generated by GNU Autoconf 2.67,
+configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -32502,7 +32527,7 @@
     "$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;;
     "$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;;
 
-  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
@@ -32524,9 +32549,10 @@
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp=
+  tmp= ac_tmp=
   trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
 ' 0
   trap 'as_fn_exit 1' 1 2 13 15
 }
@@ -32534,12 +32560,13 @@
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
 } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
 
 # Set up the scripts for CONFIG_FILES section.
 # No need to generate them if there are no CONFIG_FILES.
@@ -32561,7 +32588,7 @@
   ac_cs_awk_cr=$ac_cr
 fi
 
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
 _ACEOF
 
 
@@ -32589,7 +32616,7 @@
 rm -f conf$$subs.sh
 
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
 sed -n '
 h
@@ -32637,7 +32664,7 @@
 rm -f conf$$subs.awk
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
   for (key in S) S_is_set[key] = 1
   FS = ""
 
@@ -32669,7 +32696,7 @@
   sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
 else
   cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
   || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
@@ -32703,7 +32730,7 @@
 # No need to generate them if there are no CONFIG_HEADERS.
 # This happens for instance with `./config.status Makefile'.
 if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
 BEGIN {
 _ACEOF
 
@@ -32715,8 +32742,8 @@
 # handling of long lines.
 ac_delim='%!_!# '
 for ac_last_try in false false :; do
-  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
-  if test -z "$ac_t"; then
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
     break
   elif $ac_last_try; then
     as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
@@ -32817,7 +32844,7 @@
   esac
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
   esac
@@ -32836,7 +32863,7 @@
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$tmp/stdin";;
+      -) ac_f="$ac_tmp/stdin";;
       *) # Look for the file first in the build tree, then in the source tree
 	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
 	 # because $ac_f cannot contain `:'.
@@ -32845,7 +32872,7 @@
 	   [\\/$]*) false;;
 	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
 	   esac ||
-	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
       case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
@@ -32871,8 +32898,8 @@
     esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5  ;;
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
   esac
@@ -32997,21 +33024,22 @@
 s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
 $ac_datarootdir_hack
 "
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
-  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&5
 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&2;}
 
-  rm -f "$tmp/stdin"
+  rm -f "$ac_tmp/stdin"
   case $ac_file in
-  -) cat "$tmp/out" && rm -f "$tmp/out";;
-  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
   esac \
   || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
@@ -33022,20 +33050,20 @@
   if test x"$ac_file" != x-; then
     {
       $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
-    } >"$tmp/config.h" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
       || as_fn_error $? "could not create $ac_file" "$LINENO" 5
-    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
 $as_echo "$as_me: $ac_file is unchanged" >&6;}
     else
       rm -f "$ac_file"
-      mv "$tmp/config.h" "$ac_file" \
+      mv "$ac_tmp/config.h" "$ac_file" \
 	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
     $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
       || as_fn_error $? "could not create -" "$LINENO" 5
   fi
  ;;
diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in
index ad88295..ec47d03 100644
--- a/common/autoconf/spec.gmk.in
+++ b/common/autoconf/spec.gmk.in
@@ -282,6 +282,9 @@
 X_LIBS:=@X_LIBS@
 OPENWIN_HOME:=@OPENWIN_HOME@
 
+# The lowest required version of macosx to enforce compatiblity for
+MACOSX_REQUIRED_VERSION=@MACOSX_REQUIRED_VERSION@
+
 # There are two types: CC or CL
 # CC is gcc and others behaving reasonably similar.
 # CL is cl.exe only.
diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4
index 7b7f19f..740b0c4 100644
--- a/common/autoconf/toolchain.m4
+++ b/common/autoconf/toolchain.m4
@@ -876,6 +876,10 @@
 fi
 if test "x$OPENJDK_TARGET_OS" = xmacosx; then
     CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE"
+    # Adding these macros will make it an error to link to mac APIs newer than OS version 10.7
+    MACOSX_REQUIRED_VERSION=1070
+    AC_SUBST(MACOSX_REQUIRED_VERSION)
+    CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(MACOSX_REQUIRED_VERSION) -DMAC_OS_X_VERSION_MIN_REQUIRED=\$(MACOSX_REQUIRED_VERSION)" 
 fi
 if test "x$OPENJDK_TARGET_OS" = xbsd; then
     CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DBSD -D_ALLBSD_SOURCE"
diff --git a/common/bin/hgforest.sh b/common/bin/hgforest.sh
index cbda871..29e8030 100644
--- a/common/bin/hgforest.sh
+++ b/common/bin/hgforest.sh
@@ -64,33 +64,33 @@
 mkdir -p ${tmp}
 
 safe_interrupt () {
-  if [ -d ${tmp} ]; then 
-    if [ "`ls ${tmp}`" != "" ]; then 
-      echo "Waiting for processes ( `cat ${tmp}/* | tr '\n' ' '`) to terminate nicely!"
+  if [ -d ${tmp} ]; then
+    if [ "`ls ${tmp}/*.pid`" != "" ]; then
+      echo "Waiting for processes ( `cat ${tmp}/*.pid | tr '\n' ' '`) to terminate nicely!"
       sleep 1
       # Pipe stderr to dev/null to silence kill, that complains when trying to kill
       # a subprocess that has already exited.
-      kill -TERM `cat ${tmp}/* | tr '\n' ' '` 2> /dev/null
-      wait 
-      echo Interrupt complete! 
-    fi 
+      kill -TERM `cat ${tmp}/*.pid | tr '\n' ' '` 2> /dev/null
+      wait
+      echo Interrupt complete!
+    fi
   fi
   rm -f -r ${tmp}
   exit 1
 }
 
 nice_exit () {
-  if [ -d ${tmp} ]; then 
-    if [ "`ls ${tmp}`" != "" ]; then 
-      wait 
-    fi 
+  if [ -d ${tmp} ]; then
+    if [ "`ls ${tmp}`" != "" ]; then
+      wait
+    fi
   fi
   rm -f -r ${tmp}
 }
 
 trap 'safe_interrupt' INT QUIT
 trap 'nice_exit' EXIT
- 
+
 # Only look in specific locations for possible forests (avoids long searches)
 pull_default=""
 repos=""
@@ -172,14 +172,26 @@
       if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
         pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
         echo ${hg} clone ${pull_newrepo} ${i}
-        ${hg} clone ${pull_newrepo} ${i} &
+        path="`dirname ${i}`"
+        if [ "${path}" != "." ] ; then
+          times=0
+          while [ ! -d "${path}" ]   ## nested repo, ensure containing dir exists
+          do
+            times=`expr ${times} '+' 1`
+            if [ `expr ${times} '%' 10` -eq 0 ] ; then
+              echo ${path} still not created, waiting...
+            fi
+            sleep 5
+          done
+        fi
+        (${hg} clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc )&
       else
         echo "cd ${i} && ${hg} $*"
-        cd ${i} && ${hg} "$@" &
-      fi 
+        cd ${i} && (${hg} "$@"; echo "$?" > ${tmp}/${repopidfile}.pid.rc )&
+      fi
       echo $! > ${tmp}/${repopidfile}.pid
     ) 2>&1 | sed -e "s@^@${reponame}:   @") &
-  
+
   if [ `expr ${n} '%' ${at_a_time}` -eq 0 ] ; then
     sleep 2
     echo Waiting 5 secs before spawning next background command.
@@ -189,6 +201,15 @@
 # Wait for all hg commands to complete
 wait
 
-# Terminate with exit 0 all the time (hard to know when to say "failed")
-exit 0
-
+# Terminate with exit 0 only if all subprocesses were successful
+ec=0
+if [ -d ${tmp} ]; then
+  for rc in ${tmp}/*.pid.rc ; do
+    exit_code=`cat ${rc} | tr -d ' \n\r'`
+    if [ "${exit_code}" != "0" ] ; then
+      echo "WARNING: ${rc} exited abnormally."
+      ec=1
+    fi
+  done
+fi
+exit ${ec}
diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk
index ded49ff..1fce2e2 100644
--- a/common/makefiles/Main.gmk
+++ b/common/makefiles/Main.gmk
@@ -129,7 +129,9 @@
 	@($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk demos)
 	@$(call TargetExit)
 
-images: source-tips demos images-only
+# Note: This double-colon rule is intentional, to support
+# custom make file integration.
+images:: source-tips demos images-only
 images-only: start-make
 	@$(call TargetEnter)
 	@($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk images)
@@ -141,6 +143,17 @@
 	@($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk overlay-images)
 	@$(call TargetExit)
 
+profiles: profiles-oscheck source-tips jdk hotspot profiles-only
+profiles-only: start-make
+	@$(call TargetEnter)
+	@($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk profiles)
+	@$(call TargetExit)
+
+profiles-oscheck:
+ifneq ($(OPENJDK_TARGET_OS), linux)
+	@echo "Error: The Java SE 8 Compact Profiles are only implemented for Linux at this time" && exit 1
+endif
+
 install: images install-only
 install-only: start-make
 	@$(call TargetEnter)
@@ -167,7 +180,7 @@
 
 test: start-make
 	@$(call TargetEnter)
-	@($(CD) $(SRC_ROOT)/test && $(BUILD_LOG_WRAPPER) $(MAKE) MAKEFLAGS= -j1 PRODUCT_HOME=$(OUTPUT_ROOT)/jdk JPRT_JAVA_HOME=$(OUTPUT_ROOT)/jdk ALT_OUTPUTDIR=$(OUTPUT_ROOT) $(TEST)) || true
+	@($(CD) $(SRC_ROOT)/test && $(BUILD_LOG_WRAPPER) $(MAKE) -j1 -k MAKEFLAGS= PRODUCT_HOME=$(OUTPUT_ROOT)/jdk JPRT_JAVA_HOME=$(OUTPUT_ROOT)/jdk ALT_OUTPUTDIR=$(OUTPUT_ROOT) $(TEST)) || true
 	@$(call TargetExit)
 
 # Stores the tips for each repository. This file is be used when constructing the jdk image and can be
@@ -224,5 +237,6 @@
 .PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only images-only overlay-images-only install-only
 .PHONY: all test clean dist-clean bootcycle-images start-make
 .PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-images clean-overlay-images clean-bootcycle-build
+.PHONY: profiles profiles-only profiles-oscheck
 
 FRC: # Force target
diff --git a/common/makefiles/javadoc/CORE_PKGS.gmk b/common/makefiles/javadoc/CORE_PKGS.gmk
index b91aae1..43c7a27 100644
--- a/common/makefiles/javadoc/CORE_PKGS.gmk
+++ b/common/makefiles/javadoc/CORE_PKGS.gmk
@@ -128,9 +128,9 @@
   java.text                                      \
   java.text.spi                                  \
   java.time                                      \
-  java.time.temporal                             \
-  java.time.calendar                             \
+  java.time.chrono                               \
   java.time.format                               \
+  java.time.temporal                             \
   java.time.zone                                 \
   java.util                                      \
   java.util.concurrent                           \
diff --git a/common/makefiles/javadoc/Javadoc.gmk b/common/makefiles/javadoc/Javadoc.gmk
index 1d79812..f944a7e 100644
--- a/common/makefiles/javadoc/Javadoc.gmk
+++ b/common/makefiles/javadoc/Javadoc.gmk
@@ -267,6 +267,7 @@
                 -use					\
                 -keywords				\
 		-Xdoclint:none				\
+                -Xprofilespath $(JDK_TOPDIR)/makefiles/profile-rtjar-includes.txt \
 		$(ADDITIONAL_JAVADOCFLAGS)
 
 ifdef OPENJDK
diff --git a/corba/.hgtags b/corba/.hgtags
index c292f1b..b9ad7c1 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -198,3 +198,4 @@
 2132845cf5f717ff5c240a2431c0c0e03e66e3a5 jdk8-b74
 d4e68ce17795601017ac2f952baad7272942c36e jdk8-b75
 58be6ca3c0603882a1ec478724e337aac85e0da0 jdk8-b76
+35684a40c5845782324dbcc9ac8969528020ff61 jdk8-b77
diff --git a/get_source.sh b/get_source.sh
index bc4d18d..f83a376 100644
--- a/get_source.sh
+++ b/get_source.sh
@@ -26,7 +26,7 @@
 #
 
 # Get clones of all nested repositories
-sh ./common/bin/hgforest.sh clone "$@"
+sh ./common/bin/hgforest.sh clone "$@" || exit 1
 
 # Update all existing repositories to the latest sources
 sh ./common/bin/hgforest.sh pull -u
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index da10e70..7123283 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -314,3 +314,5 @@
 6778d0b1659323a506ca47600ca29a9d9f8b383d jdk8-b75
 20b605466ccb1b3725eb25314d9e8782199630c5 jdk8-b76
 412d722168bc23f8e6d98995202728678561417f hs25-b18
+cdb46031e7184d37301288f5719121a63c7054b5 jdk8-b77
+9f19f4a7d48a4ebe7f616b6068971ea5f8b075fa hs25-b19
diff --git a/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m b/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m
index 435262c..2f064a9 100644
--- a/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m
+++ b/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m
@@ -97,7 +97,8 @@
  * Method:    init0
  * Signature: ()V
  */
-JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) {
+JNIEXPORT void JNICALL 
+Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) {
   symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J");
   taskID = (*env)->GetFieldID(env, cls, "task", "J");
   CHECK_EXCEPTION;
@@ -108,7 +109,11 @@
  * Method:    lookupByName0
  * Signature: (Ljava/lang/String;Ljava/lang/String;)J
  */
-JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0(JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
+JNIEXPORT jlong JNICALL 
+Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0(
+  JNIEnv *env, jobject this_obj, 
+  jstring objectName, jstring symbolName) 
+{
   jlong address = 0;
 
 JNF_COCOA_ENTER(env);
@@ -137,7 +142,11 @@
  * Method:    readBytesFromProcess0
  * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
  */
-JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0(JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {
+JNIEXPORT jbyteArray JNICALL
+Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0(
+  JNIEnv *env, jobject this_obj, 
+  jlong addr, jlong numBytes) 
+{
   if (debug) printf("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes);
 
   // must allocate storage instead of using former parameter buf
@@ -209,12 +218,74 @@
   return array;
 }
 
+
 /*
- * Class:     sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal
- * Method:    getThreadIntegerRegisterSet0
- * Signature: (I)[J
+ * Lookup the thread_t that corresponds to the given thread_id.
+ * The thread_id should be the result from calling thread_info() with THREAD_IDENTIFIER_INFO
+ * and reading the m_ident_info.thread_id returned.
+ * The returned thread_t is the mach send right to the kernel port for the corresponding thread.
+ *
+ * We cannot simply use the OSThread._thread_id field in the JVM. This is set to ::mach_thread_self()
+ * in the VM, but that thread port is not valid for a remote debugger to access the thread.
  */
-JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0(JNIEnv *env, jobject this_obj, jint lwp_id) {
+thread_t
+lookupThreadFromThreadId(task_t task, jlong thread_id) {
+  if (debug) {
+    printf("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id);
+  }
+  
+  thread_array_t thread_list = NULL;
+  mach_msg_type_number_t thread_list_count = 0;
+  thread_t result_thread = 0;
+  int i;
+  
+  // get the list of all the send rights
+  kern_return_t result = task_threads(task, &thread_list, &thread_list_count);
+  if (result != KERN_SUCCESS) {
+    if (debug) {
+      printf("task_threads returned 0x%x\n", result);
+    }
+    return 0;
+  }
+  
+  for(i = 0 ; i < thread_list_count; i++) {
+    thread_identifier_info_data_t m_ident_info;
+    mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
+
+    // get the THREAD_IDENTIFIER_INFO for the send right
+    result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
+    if (result != KERN_SUCCESS) {
+      if (debug) {
+        printf("thread_info returned 0x%x\n", result);
+      }
+      break;
+    }
+    
+    // if this is the one we're looking for, return the send right
+    if (thread_id == m_ident_info.thread_id)
+    {
+      result_thread = thread_list[i];
+      break;
+    }
+  }
+  
+  vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (thread_t));
+  vm_deallocate(mach_task_self(), (vm_address_t) thread_list, thread_list_count);
+  
+  return result_thread;
+}
+
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    getThreadIntegerRegisterSet0
+ * Signature: (J)[J
+ */
+JNIEXPORT jlongArray JNICALL 
+Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0(
+  JNIEnv *env, jobject this_obj, 
+  jlong thread_id) 
+{
   if (debug)
     printf("getThreadRegisterSet0 called\n");
 
@@ -226,8 +297,9 @@
   int i;
   jlongArray registerArray;
   jlong *primitiveArray;
+  task_t gTask = getTask(env, this_obj);
 
-  tid = lwp_id;
+  tid = lookupThreadFromThreadId(gTask, thread_id);
 
   result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count);
 
@@ -328,19 +400,21 @@
 }
 
 /*
- * Class:     sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
  * Method:    translateTID0
  * Signature: (I)I
  */
 JNIEXPORT jint JNICALL
-Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0(JNIEnv *env, jobject this_obj, jint tid) {
+Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0(
+  JNIEnv *env, jobject this_obj, jint tid) 
+{
   if (debug)
     printf("translateTID0 called on tid = 0x%x\n", (int)tid);
 
   kern_return_t result;
   thread_t foreign_tid, usable_tid;
   mach_msg_type_name_t type;
-    
+  
   foreign_tid = tid;
     
   task_t gTask = getTask(env, this_obj);
@@ -361,7 +435,10 @@
  * Method:    attach0
  * Signature: (I)V
  */
-JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I(JNIEnv *env, jobject this_obj, jint jpid) {
+JNIEXPORT void JNICALL 
+Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I(
+  JNIEnv *env, jobject this_obj, jint jpid) 
+{
 JNF_COCOA_ENTER(env);
   if (getenv("JAVA_SAPROC_DEBUG") != NULL)
     debug = JNI_TRUE;
@@ -401,7 +478,10 @@
  * Method:    detach0
  * Signature: ()V
  */
-JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0(JNIEnv *env, jobject this_obj) {
+JNIEXPORT void JNICALL 
+Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0(
+  JNIEnv *env, jobject this_obj) 
+{
 JNF_COCOA_ENTER(env);
   if (debug) printf("detach0 called\n");
 
@@ -419,10 +499,13 @@
  * Method:    load_library
  * Signature: (Ljava/lang/String;)L
  */
-JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIEnv * env,
-                                                                           jclass disclass,
-                                                                           jstring jrepath_s,
-                                                                           jstring libname_s) {
+JNIEXPORT jlong JNICALL
+Java_sun_jvm_hotspot_asm_Disassembler_load_1library(
+  JNIEnv * env, 
+  jclass disclass,
+  jstring jrepath_s,
+  jstring libname_s) 
+{
   uintptr_t func = 0;
   const char* error_message = NULL;
   const char* java_home;
@@ -533,13 +616,16 @@
  * Method:    decode
  * Signature: (Lsun/jvm/hotspot/asm/InstructionVisitor;J[BLjava/lang/String;J)V
  */
-JNIEXPORT void JNICALL Java_sun_jvm_hotspot_asm_Disassembler_decode(JNIEnv * env,
-                                                                    jobject dis,
-                                                                    jobject visitor,
-                                                                    jlong startPc,
-                                                                    jbyteArray code,
-                                                                    jstring options_s,
-                                                                    jlong decode_instructions_virtual) {
+JNIEXPORT void JNICALL
+Java_sun_jvm_hotspot_asm_Disassembler_decode(
+   JNIEnv * env,
+   jobject dis,
+   jobject visitor,
+   jlong startPc,
+   jbyteArray code,
+   jstring options_s,
+   jlong decode_instructions_virtual) 
+{
   jboolean isCopy;
   jbyte* start = (*env)->GetByteArrayElements(env, code, &isCopy);
   jbyte* end = start + (*env)->GetArrayLength(env, code);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java
index 3500e38..34e848b 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java
@@ -49,7 +49,7 @@
   public BsdAddress readCompKlassAddress(long address) throws DebuggerException;
   public BsdOopHandle readOopHandle(long address) throws DebuggerException;
   public BsdOopHandle readCompOopHandle(long address) throws DebuggerException;
-  public long[]       getThreadIntegerRegisterSet(int lwp_id) throws DebuggerException;
+  public long[]       getThreadIntegerRegisterSet(long unique_thread_id) throws DebuggerException;
   public long         getAddressValue(Address addr) throws DebuggerException;
   public Address      newAddress(long value) throws DebuggerException;
 
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
index 9596d26..c6fbb7d 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
@@ -90,7 +90,7 @@
                                 throws DebuggerException;
     private native ClosestSymbol lookupByAddress0(long address)
                                 throws DebuggerException;
-    private native long[] getThreadIntegerRegisterSet0(int lwp_id)
+    private native long[] getThreadIntegerRegisterSet0(long unique_thread_id)
                                 throws DebuggerException;
     private native byte[] readBytesFromProcess0(long address, long numBytes)
                                 throws DebuggerException;
@@ -400,9 +400,14 @@
     //
 
     /** From the ThreadAccess interface via Debugger and JVMDebugger */
-    public ThreadProxy getThreadForIdentifierAddress(Address addr) {
-        return new BsdThread(this, addr);
+    public ThreadProxy getThreadForIdentifierAddress(Address threadIdAddr, Address uniqueThreadIdAddr) {
+        return new BsdThread(this, threadIdAddr, uniqueThreadIdAddr);
     }
+    @Override
+    public ThreadProxy getThreadForIdentifierAddress(Address addr) {
+        throw new RuntimeException("unimplemented");
+    }
+
 
     /** From the ThreadAccess interface via Debugger and JVMDebugger */
     public ThreadProxy getThreadForThreadId(long id) {
@@ -455,22 +460,22 @@
     // Thread context access
     //
 
-    public synchronized long[] getThreadIntegerRegisterSet(int lwp_id)
+    public synchronized long[] getThreadIntegerRegisterSet(long unique_thread_id)
                                             throws DebuggerException {
         requireAttach();
         if (isCore) {
-            return getThreadIntegerRegisterSet0(lwp_id);
+            return getThreadIntegerRegisterSet0(unique_thread_id);
         } else {
             class GetThreadIntegerRegisterSetTask implements WorkerThreadTask {
-                int lwp_id;
+                long unique_thread_id;
                 long[] result;
                 public void doit(BsdDebuggerLocal debugger) {
-                    result = debugger.getThreadIntegerRegisterSet0(lwp_id);
+                    result = debugger.getThreadIntegerRegisterSet0(unique_thread_id);
                 }
             }
 
             GetThreadIntegerRegisterSetTask task = new GetThreadIntegerRegisterSetTask();
-            task.lwp_id = lwp_id;
+            task.unique_thread_id = unique_thread_id;
             workerThread.execute(task);
             return task.result;
         }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java
index b7c507c..f3351fb 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java
@@ -28,21 +28,23 @@
 
 class BsdThread implements ThreadProxy {
     private BsdDebugger debugger;
-    private int           lwp_id;
+    private int         thread_id;
+    private long        unique_thread_id;
 
     /** The address argument must be the address of the _thread_id in the
         OSThread. It's value is result ::gettid() call. */
-    BsdThread(BsdDebugger debugger, Address addr) {
+    BsdThread(BsdDebugger debugger, Address threadIdAddr, Address uniqueThreadIdAddr) {
         this.debugger = debugger;
         // FIXME: size of data fetched here should be configurable.
         // However, making it so would produce a dependency on the "types"
         // package from the debugger package, which is not desired.
-        this.lwp_id = (int) addr.getCIntegerAt(0, 4, true);
+        this.thread_id = (int) threadIdAddr.getCIntegerAt(0, 4, true);
+        this.unique_thread_id = uniqueThreadIdAddr.getCIntegerAt(0, 8, true);
     }
 
     BsdThread(BsdDebugger debugger, long id) {
         this.debugger = debugger;
-        this.lwp_id = (int) id;
+        this.thread_id = (int) id;
     }
 
     public boolean equals(Object obj) {
@@ -50,19 +52,19 @@
             return false;
         }
 
-        return (((BsdThread) obj).lwp_id == lwp_id);
+        return (((BsdThread) obj).thread_id == thread_id);
     }
 
     public int hashCode() {
-        return lwp_id;
+        return thread_id;
     }
 
     public String toString() {
-        return Integer.toString(lwp_id);
+        return Integer.toString(thread_id);
     }
 
     public ThreadContext getContext() throws IllegalThreadStateException {
-        long[] data = debugger.getThreadIntegerRegisterSet(lwp_id);
+        long[] data = debugger.getThreadIntegerRegisterSet(unique_thread_id);
         ThreadContext context = BsdThreadContextFactory.createThreadContext(debugger);
         for (int i = 0; i < data.length; i++) {
             context.setRegister(i, data[i]);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
index ad495d7..3d0a370 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -49,12 +49,18 @@
   private static int HAS_LOCALVARIABLE_TABLE;
   private static int HAS_EXCEPTION_TABLE;
   private static int HAS_GENERIC_SIGNATURE;
+  private static int HAS_METHOD_ANNOTATIONS;
+  private static int HAS_PARAMETER_ANNOTATIONS;
+  private static int HAS_DEFAULT_ANNOTATIONS;
+  private static int HAS_TYPE_ANNOTATIONS;
+
+  private static final int sizeofShort = 2;
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type type                  = db.lookupType("ConstMethod");
     constants                  = new MetadataField(type.getAddressField("_constants"), 0);
     constMethodSize            = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
-    flags                      = new ByteField(type.getJByteField("_flags"), 0);
+    flags                      = new CIntField(type.getCIntegerField("_flags"), 0);
 
     // enum constants for flags
     HAS_LINENUMBER_TABLE      = db.lookupIntConstant("ConstMethod::_has_linenumber_table").intValue();
@@ -62,6 +68,10 @@
     HAS_LOCALVARIABLE_TABLE   = db.lookupIntConstant("ConstMethod::_has_localvariable_table").intValue();
     HAS_EXCEPTION_TABLE       = db.lookupIntConstant("ConstMethod::_has_exception_table").intValue();
     HAS_GENERIC_SIGNATURE     = db.lookupIntConstant("ConstMethod::_has_generic_signature").intValue();
+    HAS_METHOD_ANNOTATIONS    = db.lookupIntConstant("ConstMethod::_has_method_annotations").intValue();
+    HAS_PARAMETER_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_parameter_annotations").intValue();
+    HAS_DEFAULT_ANNOTATIONS   = db.lookupIntConstant("ConstMethod::_has_default_annotations").intValue();
+    HAS_TYPE_ANNOTATIONS      = db.lookupIntConstant("ConstMethod::_has_type_annotations").intValue();
 
     // Size of Java bytecodes allocated immediately after ConstMethod*.
     codeSize                   = new CIntField(type.getCIntegerField("_code_size"), 0);
@@ -92,7 +102,7 @@
   // Fields
   private static MetadataField constants;
   private static CIntField constMethodSize;
-  private static ByteField flags;
+  private static CIntField flags;
   private static CIntField codeSize;
   private static CIntField nameIndex;
   private static CIntField signatureIndex;
@@ -123,7 +133,7 @@
     return constMethodSize.getValue(this);
   }
 
-  public byte getFlags() {
+  public long getFlags() {
     return flags.getValue(this);
   }
 
@@ -253,7 +263,7 @@
   public void iterateFields(MetadataVisitor visitor) {
     visitor.doMetadata(constants, true);
       visitor.doCInt(constMethodSize, true);
-      visitor.doByte(flags, true);
+      visitor.doCInt(flags, true);
       visitor.doCInt(codeSize, true);
       visitor.doCInt(nameIndex, true);
       visitor.doCInt(signatureIndex, true);
@@ -381,6 +391,22 @@
     return (getFlags() & HAS_GENERIC_SIGNATURE) != 0;
   }
 
+  private boolean hasMethodAnnotations() {
+    return (getFlags() & HAS_METHOD_ANNOTATIONS) != 0;
+  }
+
+  private boolean hasParameterAnnotations() {
+    return (getFlags() & HAS_PARAMETER_ANNOTATIONS) != 0;
+  }
+
+  private boolean hasDefaultAnnotations() {
+    return (getFlags() & HAS_DEFAULT_ANNOTATIONS) != 0;
+  }
+
+  private boolean hasTypeAnnotations() {
+    return (getFlags() & HAS_TYPE_ANNOTATIONS) != 0;
+  }
+
 
   //---------------------------------------------------------------------------
   // Internals only below this point
@@ -400,9 +426,15 @@
     return offsetOfCodeEnd() + (isNative() ? 2 * VM.getVM().getAddressSize() : 0);
   }
 
-  // Offset of last short in Method*
+  // Offset of last short in Method* before annotations, if present
   private long offsetOfLastU2Element() {
-    return getSize() * VM.getVM().getObjectHeap().getOopSize() - 2;
+    int offset = 0;
+    if (hasMethodAnnotations()) offset++;
+    if (hasParameterAnnotations()) offset++;
+    if (hasTypeAnnotations()) offset++;
+    if (hasDefaultAnnotations()) offset++;
+    long wordSize = VM.getVM().getObjectHeap().getOopSize();
+    return (getSize() * wordSize) - (offset * wordSize) - sizeofShort;
   }
 
   // Offset of the generic signature index
@@ -411,7 +443,7 @@
   }
 
   private long offsetOfCheckedExceptionsLength() {
-    return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+    return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort :
                                    offsetOfLastU2Element();
   }
 
@@ -461,11 +493,11 @@
     }
 
     if (hasExceptionTable()) {
-      return offsetOfExceptionTable() - 2;
+      return offsetOfExceptionTable() - sizeofShort;
     } else if (hasCheckedExceptions()) {
-      return offsetOfCheckedExceptions() - 2;
+      return offsetOfCheckedExceptions() - sizeofShort;
     } else {
-      return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+      return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort :
                                      offsetOfLastU2Element();
     }
   }
@@ -493,9 +525,9 @@
       Assert.that(hasExceptionTable(), "should only be called if table is present");
     }
     if (hasCheckedExceptions()) {
-      return offsetOfCheckedExceptions() - 2;
+      return offsetOfCheckedExceptions() - sizeofShort;
     } else {
-      return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+      return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort :
                                      offsetOfLastU2Element();
     }
   }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java
index c0de138..03e35de 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java
@@ -28,6 +28,8 @@
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.debugger.amd64.*;
+import sun.jvm.hotspot.debugger.bsd.BsdDebugger;
+import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.runtime.amd64.*;
 import sun.jvm.hotspot.runtime.x86.*;
@@ -38,8 +40,9 @@
   private static AddressField  lastJavaFPField;
   private static AddressField  osThreadField;
 
-  // Field from OSThread
+  // Fields from OSThread
   private static CIntegerField osThreadThreadIDField;
+  private static CIntegerField osThreadUniqueThreadIDField;
 
   // This is currently unneeded but is being kept in case we change
   // the currentFrameGuess algorithm
@@ -61,7 +64,8 @@
     lastJavaFPField         = anchorType.getAddressField("_last_Java_fp");
 
     Type osThreadType = db.lookupType("OSThread");
-    osThreadThreadIDField   = osThreadType.getCIntegerField("_thread_id");
+    osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id");
+    osThreadUniqueThreadIDField = osThreadType.getCIntegerField("_unique_thread_id");
   }
 
   public    Address getLastJavaFP(Address addr) {
@@ -125,8 +129,9 @@
     Address osThreadAddr = osThreadField.getValue(addr);
     // Get the address of the _thread_id from the OSThread
     Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
+    Address uniqueThreadIdAddr = osThreadAddr.addOffsetTo(osThreadUniqueThreadIDField.getOffset());
 
-    JVMDebugger debugger = VM.getVM().getDebugger();
-    return debugger.getThreadForIdentifierAddress(threadIdAddr);
+    BsdDebuggerLocal debugger = (BsdDebuggerLocal) VM.getVM().getDebugger();
+    return debugger.getThreadForIdentifierAddress(threadIdAddr, uniqueThreadIdAddr);
   }
 }
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index 6f09485..beedf82 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=25
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=18
+HS_BUILD_NUMBER=19
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp
index b94aaa9..a18d804 100644
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp
@@ -2270,10 +2270,11 @@
 }
 
 void Assembler::vpermq(XMMRegister dst, XMMRegister src, int imm8, bool vector256) {
-    int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, true, vector256);
-    emit_int8(0x00);
-    emit_int8(0xC0 | encode);
-    emit_int8(imm8);
+  assert(VM_Version::supports_avx2(), "");
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, true, vector256);
+  emit_int8(0x00);
+  emit_int8(0xC0 | encode);
+  emit_int8(imm8);
 }
 
 void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
index c1e4c96..bda1550 100644
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
@@ -5691,7 +5691,7 @@
   Address::ScaleFactor scale = Address::times_2;
   int stride = 8;
 
-  if (UseAVX >= 2) {
+  if (UseAVX >= 2 && UseSSE42Intrinsics) {
     Label COMPARE_WIDE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_WIDE_TAIL, COMPARE_SMALL_STR;
     Label COMPARE_WIDE_VECTORS_LOOP, COMPARE_16_CHARS, COMPARE_INDEX_CHAR;
     Label COMPARE_TAIL_LONG;
diff --git a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp
index dae7249..1d17143 100644
--- a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp
+++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -51,7 +51,7 @@
 define_pd_global(intx,     OnStackReplacePercentage,     933  );
 define_pd_global(intx,     FreqInlineSize,               325  );
 define_pd_global(intx,     InlineSmallCode,              1000 );
-define_pd_global(intx,     NewRatio,                     12   );
+define_pd_global(uintx,    NewRatio,                     12   );
 define_pd_global(intx,     NewSizeThreadIncrease,        4*K  );
 define_pd_global(intx,     InitialCodeCacheSize,         160*K);
 define_pd_global(intx,     ReservedCodeCacheSize,        32*M );
diff --git a/hotspot/src/os/bsd/vm/osThread_bsd.hpp b/hotspot/src/os/bsd/vm/osThread_bsd.hpp
index a5d5039..b49c3ca 100644
--- a/hotspot/src/os/bsd/vm/osThread_bsd.hpp
+++ b/hotspot/src/os/bsd/vm/osThread_bsd.hpp
@@ -49,6 +49,11 @@
   // (e.g. pthread_kill).
   pthread_t _pthread_id;
 
+  // This is the "thread_id" from struct thread_identifier_info. According to a
+  // comment in thread_info.h, this is a "system-wide unique 64-bit thread id".
+  // The value is used by SA to correlate threads.
+  uint64_t _unique_thread_id;
+
   sigset_t _caller_sigmask; // Caller's signal mask
 
  public:
@@ -77,6 +82,10 @@
     _pthread_id = tid;
   }
 
+  void set_unique_thread_id(uint64_t id) {
+    _unique_thread_id = id;
+  }
+
   // ***************************************************************
   // suspension support.
   // ***************************************************************
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index 477b492..a11ca37 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -657,6 +657,18 @@
 objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NULL;
 #endif
 
+#ifdef __APPLE__
+static uint64_t locate_unique_thread_id() {
+  // Additional thread_id used to correlate threads in SA
+  thread_identifier_info_data_t     m_ident_info;
+  mach_msg_type_number_t            count = THREAD_IDENTIFIER_INFO_COUNT;
+
+  thread_info(::mach_thread_self(), THREAD_IDENTIFIER_INFO,
+              (thread_info_t) &m_ident_info, &count);
+  return m_ident_info.thread_id;
+}
+#endif
+
 // Thread start routine for all newly created threads
 static void *java_start(Thread *thread) {
   // Try to randomize the cache line index of hot stack frames.
@@ -685,6 +697,7 @@
 #ifdef __APPLE__
   // thread_id is mach thread on macos
   osthread->set_thread_id(::mach_thread_self());
+  osthread->set_unique_thread_id(locate_unique_thread_id());
 #else
   // thread_id is pthread_id on BSD
   osthread->set_thread_id(::pthread_self());
@@ -847,6 +860,7 @@
   // Store pthread info into the OSThread
 #ifdef __APPLE__
   osthread->set_thread_id(::mach_thread_self());
+  osthread->set_unique_thread_id(locate_unique_thread_id());
 #else
   osthread->set_thread_id(::pthread_self());
 #endif
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp b/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp
index 3a8d42a..1144115 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -42,7 +42,7 @@
 #endif // AMD64
 
 define_pd_global(intx, CompilerThreadStackSize,  0);
-define_pd_global(intx, SurvivorRatio,            8);
+define_pd_global(uintx, SurvivorRatio,           8);
 
 define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
 
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp b/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
index edfbcfa..b1460ed 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
@@ -35,17 +35,16 @@
   /* Threads (NOTE: incomplete) */                                                                                                   \
   /******************************/                                                                                                   \
   nonstatic_field(OSThread,                      _thread_id,                                      OSThread::thread_id_t)             \
-  nonstatic_field(OSThread,                      _pthread_id,                                     pthread_t)
+  nonstatic_field(OSThread,                      _unique_thread_id,                               uint64_t)
 
 
 #define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
                                                                           \
   /**********************/                                                \
-  /* Posix Thread IDs   */                                                \
+  /* Thread IDs         */                                                \
   /**********************/                                                \
                                                                           \
-  declare_unsigned_integer_type(OSThread::thread_id_t)                    \
-  declare_unsigned_integer_type(pthread_t)
+  declare_unsigned_integer_type(OSThread::thread_id_t)
 
 #define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
 
diff --git a/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java b/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
index ecc5085..70ee48b 100644
--- a/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
+++ b/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
@@ -23,6 +23,8 @@
  */
 
 package sun.hotspot;
+
+import java.lang.reflect.Method;
 import java.security.BasicPermission;
 import sun.hotspot.parser.DiagnosticCommand;
 
@@ -81,4 +83,15 @@
   public native boolean NMTAllocTest();
   public native boolean NMTFreeTestMemory();
   public native boolean NMTWaitForDataMerge();
+
+  // Compiler
+  public native void    deoptimizeAll();
+  public native boolean isMethodCompiled(Method method);
+  public native boolean isMethodCompilable(Method method);
+  public native boolean isMethodQueuedForCompilation(Method method);
+  public native int     deoptimizeMethod(Method method);
+  public native void    makeMethodNotCompilable(Method method);
+  public native int     getMethodCompilationLevel(Method method);
+  public native boolean setDontInlineMethod(Method method, boolean value);
+  public native int     getCompileQueuesSize();
 }
diff --git a/hotspot/src/share/vm/asm/macroAssembler.hpp b/hotspot/src/share/vm/asm/macroAssembler.hpp
index 92ecd13..96c6b01 100644
--- a/hotspot/src/share/vm/asm/macroAssembler.hpp
+++ b/hotspot/src/share/vm/asm/macroAssembler.hpp
@@ -37,10 +37,10 @@
 # include "assembler_zero.hpp"
 #endif
 #ifdef TARGET_ARCH_arm
-# include "assembler_arm.hpp"
+# include "macroAssembler_arm.hpp"
 #endif
 #ifdef TARGET_ARCH_ppc
-# include "assembler_ppc.hpp"
+# include "macroAssembler_ppc.hpp"
 #endif
 
 #endif // SHARE_VM_ASM_MACROASSEMBLER_HPP
diff --git a/hotspot/src/share/vm/asm/macroAssembler.inline.hpp b/hotspot/src/share/vm/asm/macroAssembler.inline.hpp
index 70a157c..e61fc37 100644
--- a/hotspot/src/share/vm/asm/macroAssembler.inline.hpp
+++ b/hotspot/src/share/vm/asm/macroAssembler.inline.hpp
@@ -37,10 +37,10 @@
 # include "assembler_zero.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_arm
-# include "assembler_arm.inline.hpp"
+# include "macroAssembler_arm.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_ppc
-# include "assembler_ppc.inline.hpp"
+# include "macroAssembler_ppc.inline.hpp"
 #endif
 
 #endif // SHARE_VM_ASM_MACROASSEMBLER_INLINE_HPP
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index d46a1ea..3650e05 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -1856,6 +1856,154 @@
 #define MAX_CODE_SIZE 65535
 #define INITIAL_MAX_LVT_NUMBER 256
 
+/* Copy class file LVT's/LVTT's into the HotSpot internal LVT.
+ *
+ * Rules for LVT's and LVTT's are:
+ *   - There can be any number of LVT's and LVTT's.
+ *   - If there are n LVT's, it is the same as if there was just
+ *     one LVT containing all the entries from the n LVT's.
+ *   - There may be no more than one LVT entry per local variable.
+ *     Two LVT entries are 'equal' if these fields are the same:
+ *        start_pc, length, name, slot
+ *   - There may be no more than one LVTT entry per each LVT entry.
+ *     Each LVTT entry has to match some LVT entry.
+ *   - HotSpot internal LVT keeps natural ordering of class file LVT entries.
+ */
+void ClassFileParser::copy_localvariable_table(ConstMethod* cm,
+                                               int lvt_cnt,
+                                               u2* localvariable_table_length,
+                                               u2** localvariable_table_start,
+                                               int lvtt_cnt,
+                                               u2* localvariable_type_table_length,
+                                               u2** localvariable_type_table_start,
+                                               TRAPS) {
+
+  LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE);
+  initialize_hashtable(lvt_Hash);
+
+  // To fill LocalVariableTable in
+  Classfile_LVT_Element*  cf_lvt;
+  LocalVariableTableElement* lvt = cm->localvariable_table_start();
+
+  for (int tbl_no = 0; tbl_no < lvt_cnt; tbl_no++) {
+    cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no];
+    for (int idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) {
+      copy_lvt_element(&cf_lvt[idx], lvt);
+      // If no duplicates, add LVT elem in hashtable lvt_Hash.
+      if (LVT_put_after_lookup(lvt, lvt_Hash) == false
+          && _need_verify
+          && _major_version >= JAVA_1_5_VERSION) {
+        clear_hashtable(lvt_Hash);
+        ConstantPool* cp = cm->constants();
+        classfile_parse_error("Duplicated LocalVariableTable attribute "
+                              "entry for '%s' in class file %s",
+                               cp->symbol_at(lvt->name_cp_index)->as_utf8(),
+                               CHECK);
+      }
+    }
+  }
+
+  // To merge LocalVariableTable and LocalVariableTypeTable
+  Classfile_LVT_Element* cf_lvtt;
+  LocalVariableTableElement lvtt_elem;
+
+  for (int tbl_no = 0; tbl_no < lvtt_cnt; tbl_no++) {
+    cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no];
+    for (int idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) {
+      copy_lvt_element(&cf_lvtt[idx], &lvtt_elem);
+      int index = hash(&lvtt_elem);
+      LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash);
+      if (entry == NULL) {
+        if (_need_verify) {
+          clear_hashtable(lvt_Hash);
+          ConstantPool* cp = cm->constants();
+          classfile_parse_error("LVTT entry for '%s' in class file %s "
+                                "does not match any LVT entry",
+                                 cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
+                                 CHECK);
+        }
+      } else if (entry->_elem->signature_cp_index != 0 && _need_verify) {
+        clear_hashtable(lvt_Hash);
+        ConstantPool* cp = cm->constants();
+        classfile_parse_error("Duplicated LocalVariableTypeTable attribute "
+                              "entry for '%s' in class file %s",
+                               cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
+                               CHECK);
+      } else {
+        // to add generic signatures into LocalVariableTable
+        entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index;
+      }
+    }
+  }
+  clear_hashtable(lvt_Hash);
+}
+
+
+void ClassFileParser::copy_method_annotations(ClassLoaderData* loader_data,
+                                       ConstMethod* cm,
+                                       u1* runtime_visible_annotations,
+                                       int runtime_visible_annotations_length,
+                                       u1* runtime_invisible_annotations,
+                                       int runtime_invisible_annotations_length,
+                                       u1* runtime_visible_parameter_annotations,
+                                       int runtime_visible_parameter_annotations_length,
+                                       u1* runtime_invisible_parameter_annotations,
+                                       int runtime_invisible_parameter_annotations_length,
+                                       u1* runtime_visible_type_annotations,
+                                       int runtime_visible_type_annotations_length,
+                                       u1* runtime_invisible_type_annotations,
+                                       int runtime_invisible_type_annotations_length,
+                                       u1* annotation_default,
+                                       int annotation_default_length,
+                                       TRAPS) {
+
+  AnnotationArray* a;
+
+  if (runtime_visible_annotations_length +
+      runtime_invisible_annotations_length > 0) {
+     a = assemble_annotations(loader_data,
+                              runtime_visible_annotations,
+                              runtime_visible_annotations_length,
+                              runtime_invisible_annotations,
+                              runtime_invisible_annotations_length,
+                              CHECK);
+     cm->set_method_annotations(a);
+  }
+
+  if (runtime_visible_parameter_annotations_length +
+      runtime_invisible_parameter_annotations_length > 0) {
+    a = assemble_annotations(loader_data,
+                             runtime_visible_parameter_annotations,
+                             runtime_visible_parameter_annotations_length,
+                             runtime_invisible_parameter_annotations,
+                             runtime_invisible_parameter_annotations_length,
+                             CHECK);
+    cm->set_parameter_annotations(a);
+  }
+
+  if (annotation_default_length > 0) {
+    a = assemble_annotations(loader_data,
+                             annotation_default,
+                             annotation_default_length,
+                             NULL,
+                             0,
+                             CHECK);
+    cm->set_default_annotations(a);
+  }
+
+  if (runtime_visible_type_annotations_length +
+      runtime_invisible_type_annotations_length > 0) {
+    a = assemble_annotations(loader_data,
+                             runtime_visible_type_annotations,
+                             runtime_visible_type_annotations_length,
+                             runtime_invisible_type_annotations,
+                             runtime_invisible_type_annotations_length,
+                             CHECK);
+    cm->set_type_annotations(a);
+  }
+}
+
+
 // Note: the parse_method below is big and clunky because all parsing of the code and exceptions
 // attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the
 // Method* to save footprint, so we only know the size of the resulting Method* when the
@@ -1869,10 +2017,6 @@
                                            constantPoolHandle cp,
                                            bool is_interface,
                                            AccessFlags *promoted_flags,
-                                           AnnotationArray** method_annotations,
-                                           AnnotationArray** method_parameter_annotations,
-                                           AnnotationArray** method_default_annotations,
-                                           AnnotationArray** method_type_annotations,
                                            TRAPS) {
   ClassFileStream* cfs = stream();
   methodHandle nullHandle;
@@ -2273,10 +2417,24 @@
   }
 
   // All sizing information for a Method* is finally available, now create it
+  InlineTableSizes sizes(
+      total_lvt_length,
+      linenumber_table_length,
+      exception_table_length,
+      checked_exceptions_length,
+      method_parameters_length,
+      generic_signature_index,
+      runtime_visible_annotations_length +
+           runtime_invisible_annotations_length,
+      runtime_visible_parameter_annotations_length +
+           runtime_invisible_parameter_annotations_length,
+      runtime_visible_type_annotations_length +
+           runtime_invisible_type_annotations_length,
+      annotation_default_length,
+      0);
+
   Method* m = Method::allocate(
-      loader_data, code_length, access_flags, linenumber_table_length,
-      total_lvt_length, exception_table_length, checked_exceptions_length,
-      method_parameters_length, generic_signature_index,
+      loader_data, code_length, access_flags, &sizes,
       ConstMethod::NORMAL, CHECK_(nullHandle));
 
   ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
@@ -2347,107 +2505,37 @@
     copy_u2_with_conversion((u2*) m->checked_exceptions_start(), checked_exceptions_start, size);
   }
 
-  /* Copy class file LVT's/LVTT's into the HotSpot internal LVT.
-   *
-   * Rules for LVT's and LVTT's are:
-   *   - There can be any number of LVT's and LVTT's.
-   *   - If there are n LVT's, it is the same as if there was just
-   *     one LVT containing all the entries from the n LVT's.
-   *   - There may be no more than one LVT entry per local variable.
-   *     Two LVT entries are 'equal' if these fields are the same:
-   *        start_pc, length, name, slot
-   *   - There may be no more than one LVTT entry per each LVT entry.
-   *     Each LVTT entry has to match some LVT entry.
-   *   - HotSpot internal LVT keeps natural ordering of class file LVT entries.
-   */
+  // Copy class file LVT's/LVTT's into the HotSpot internal LVT.
   if (total_lvt_length > 0) {
-    int tbl_no, idx;
-
     promoted_flags->set_has_localvariable_table();
-
-    LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE);
-    initialize_hashtable(lvt_Hash);
-
-    // To fill LocalVariableTable in
-    Classfile_LVT_Element*  cf_lvt;
-    LocalVariableTableElement* lvt = m->localvariable_table_start();
-
-    for (tbl_no = 0; tbl_no < lvt_cnt; tbl_no++) {
-      cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no];
-      for (idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) {
-        copy_lvt_element(&cf_lvt[idx], lvt);
-        // If no duplicates, add LVT elem in hashtable lvt_Hash.
-        if (LVT_put_after_lookup(lvt, lvt_Hash) == false
-          && _need_verify
-          && _major_version >= JAVA_1_5_VERSION ) {
-          clear_hashtable(lvt_Hash);
-          classfile_parse_error("Duplicated LocalVariableTable attribute "
-                                "entry for '%s' in class file %s",
-                                 cp->symbol_at(lvt->name_cp_index)->as_utf8(),
-                                 CHECK_(nullHandle));
-        }
-      }
-    }
-
-    // To merge LocalVariableTable and LocalVariableTypeTable
-    Classfile_LVT_Element* cf_lvtt;
-    LocalVariableTableElement lvtt_elem;
-
-    for (tbl_no = 0; tbl_no < lvtt_cnt; tbl_no++) {
-      cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no];
-      for (idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) {
-        copy_lvt_element(&cf_lvtt[idx], &lvtt_elem);
-        int index = hash(&lvtt_elem);
-        LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash);
-        if (entry == NULL) {
-          if (_need_verify) {
-            clear_hashtable(lvt_Hash);
-            classfile_parse_error("LVTT entry for '%s' in class file %s "
-                                  "does not match any LVT entry",
-                                   cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
-                                   CHECK_(nullHandle));
-          }
-        } else if (entry->_elem->signature_cp_index != 0 && _need_verify) {
-          clear_hashtable(lvt_Hash);
-          classfile_parse_error("Duplicated LocalVariableTypeTable attribute "
-                                "entry for '%s' in class file %s",
-                                 cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
-                                 CHECK_(nullHandle));
-        } else {
-          // to add generic signatures into LocalVariableTable
-          entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index;
-        }
-      }
-    }
-    clear_hashtable(lvt_Hash);
+    copy_localvariable_table(m->constMethod(), lvt_cnt,
+                             localvariable_table_length,
+                             localvariable_table_start,
+                             lvtt_cnt,
+                             localvariable_type_table_length,
+                             localvariable_type_table_start, CHECK_NULL);
   }
 
   if (parsed_annotations.has_any_annotations())
     parsed_annotations.apply_to(m);
-  *method_annotations = assemble_annotations(loader_data,
-                                             runtime_visible_annotations,
-                                             runtime_visible_annotations_length,
-                                             runtime_invisible_annotations,
-                                             runtime_invisible_annotations_length,
-                                             CHECK_(nullHandle));
-  *method_parameter_annotations = assemble_annotations(loader_data,
-                                                       runtime_visible_parameter_annotations,
-                                                       runtime_visible_parameter_annotations_length,
-                                                       runtime_invisible_parameter_annotations,
-                                                       runtime_invisible_parameter_annotations_length,
-                                                       CHECK_(nullHandle));
-  *method_default_annotations = assemble_annotations(loader_data,
-                                                     annotation_default,
-                                                     annotation_default_length,
-                                                     NULL,
-                                                     0,
-                                                     CHECK_(nullHandle));
-  *method_type_annotations = assemble_annotations(loader_data,
-                                                  runtime_visible_type_annotations,
-                                                  runtime_visible_type_annotations_length,
-                                                  runtime_invisible_type_annotations,
-                                                  runtime_invisible_type_annotations_length,
-                                                  CHECK_(nullHandle));
+
+  // Copy annotations
+  copy_method_annotations(loader_data, m->constMethod(),
+                          runtime_visible_annotations,
+                          runtime_visible_annotations_length,
+                          runtime_invisible_annotations,
+                          runtime_invisible_annotations_length,
+                          runtime_visible_parameter_annotations,
+                          runtime_visible_parameter_annotations_length,
+                          runtime_invisible_parameter_annotations,
+                          runtime_invisible_parameter_annotations_length,
+                          runtime_visible_type_annotations,
+                          runtime_visible_type_annotations_length,
+                          runtime_invisible_type_annotations,
+                          runtime_invisible_type_annotations_length,
+                          annotation_default,
+                          annotation_default_length,
+                          CHECK_NULL);
 
   if (name == vmSymbols::finalize_method_name() &&
       signature == vmSymbols::void_method_signature()) {
@@ -2463,6 +2551,7 @@
     _has_vanilla_constructor = true;
   }
 
+  NOT_PRODUCT(m->verify());
   return m;
 }
 
@@ -2476,17 +2565,9 @@
                                                bool is_interface,
                                                AccessFlags* promoted_flags,
                                                bool* has_final_method,
-                                               Array<AnnotationArray*>** methods_annotations,
-                                               Array<AnnotationArray*>** methods_parameter_annotations,
-                                               Array<AnnotationArray*>** methods_default_annotations,
-                                               Array<AnnotationArray*>** methods_type_annotations,
                                                bool* has_default_methods,
                                                TRAPS) {
   ClassFileStream* cfs = stream();
-  AnnotationArray* method_annotations = NULL;
-  AnnotationArray* method_parameter_annotations = NULL;
-  AnnotationArray* method_default_annotations = NULL;
-  AnnotationArray* method_type_annotations = NULL;
   cfs->guarantee_more(2, CHECK_NULL);  // length
   u2 length = cfs->get_u2_fast();
   if (length == 0) {
@@ -2500,10 +2581,6 @@
       methodHandle method = parse_method(loader_data,
                                          cp, is_interface,
                                          promoted_flags,
-                                         &method_annotations,
-                                         &method_parameter_annotations,
-                                         &method_default_annotations,
-                                         &method_type_annotations,
                                          CHECK_NULL);
 
       if (method->is_final()) {
@@ -2514,38 +2591,6 @@
         *has_default_methods = true;
       }
       methods->at_put(index, method());
-
-      if (method_annotations != NULL) {
-        if (*methods_annotations == NULL) {
-          *methods_annotations =
-              MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
-        }
-        (*methods_annotations)->at_put(index, method_annotations);
-      }
-
-      if (method_parameter_annotations != NULL) {
-        if (*methods_parameter_annotations == NULL) {
-          *methods_parameter_annotations =
-              MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
-        }
-        (*methods_parameter_annotations)->at_put(index, method_parameter_annotations);
-      }
-
-      if (method_default_annotations != NULL) {
-        if (*methods_default_annotations == NULL) {
-          *methods_default_annotations =
-              MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
-        }
-        (*methods_default_annotations)->at_put(index, method_default_annotations);
-      }
-
-      if (method_type_annotations != NULL) {
-        if (*methods_type_annotations == NULL) {
-          *methods_type_annotations =
-              MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
-        }
-        (*methods_type_annotations)->at_put(index, method_type_annotations);
-      }
     }
 
     if (_need_verify && length > 1) {
@@ -2578,11 +2623,7 @@
 
 Array<int>* ClassFileParser::sort_methods(ClassLoaderData* loader_data,
                                           Array<Method*>* methods,
-                                          Array<AnnotationArray*>* methods_annotations,
-                                          Array<AnnotationArray*>* methods_parameter_annotations,
-                                          Array<AnnotationArray*>* methods_default_annotations,
-                                          Array<AnnotationArray*>* methods_type_annotations,
-                                              TRAPS) {
+                                          TRAPS) {
   int length = methods->length();
   // If JVMTI original method ordering or sharing is enabled we have to
   // remember the original class file ordering.
@@ -2598,10 +2639,7 @@
   }
   // Sort method array by ascending method name (for faster lookups & vtable construction)
   // Note that the ordering is not alphabetical, see Symbol::fast_compare
-  Method::sort_methods(methods, methods_annotations,
-                       methods_parameter_annotations,
-                       methods_default_annotations,
-                       methods_type_annotations);
+  Method::sort_methods(methods);
 
   // If JVMTI original method ordering or sharing is enabled construct int
   // array remembering the original ordering
@@ -3048,9 +3086,6 @@
     k->set_source_debug_extension(_sde_buffer, _sde_length);
   }
   k->set_inner_classes(_inner_classes);
-  if (_annotations != NULL) {
-    k->annotations()->set_class_annotations(_annotations);
-  }
 }
 
 AnnotationArray* ClassFileParser::assemble_annotations(ClassLoaderData* loader_data,
@@ -3361,19 +3396,10 @@
     bool has_final_method = false;
     AccessFlags promoted_flags;
     promoted_flags.set_flags(0);
-
-    Array<AnnotationArray*>* methods_annotations = NULL;
-    Array<AnnotationArray*>* methods_parameter_annotations = NULL;
-    Array<AnnotationArray*>* methods_default_annotations = NULL;
-    Array<AnnotationArray*>* methods_type_annotations = NULL;
     Array<Method*>* methods = parse_methods(loader_data,
                                             cp, access_flags.is_interface(),
                                             &promoted_flags,
                                             &has_final_method,
-                                            &methods_annotations,
-                                            &methods_parameter_annotations,
-                                            &methods_default_annotations,
-                                            &methods_type_annotations,
                                             &has_default_methods,
                                             CHECK_(nullHandle));
 
@@ -3432,10 +3458,6 @@
     // sort methods
     Array<int>* method_ordering = sort_methods(loader_data,
                                                methods,
-                                               methods_annotations,
-                                               methods_parameter_annotations,
-                                               methods_default_annotations,
-                                               methods_type_annotations,
                                                CHECK_(nullHandle));
 
     // promote flags from parse_methods() to the klass' flags
@@ -4035,7 +4057,6 @@
     const unsigned int total_oop_map_count =
       compute_oop_map_count(super_klass, nonstatic_oop_map_count,
                             first_nonstatic_oop_offset);
-
     // Compute reference type
     ReferenceType rt;
     if (super_klass() == NULL) {
@@ -4057,7 +4078,7 @@
                                                        access_flags,
                                                        name,
                                                        super_klass(),
-                                                       host_klass,
+                                                       !host_klass.is_null(),
                                                        CHECK_(nullHandle));
 
     // Add all classes to our internal class loader list here,
@@ -4103,31 +4124,15 @@
     if (is_anonymous())  // I am well known to myself
       cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
 
-    // Allocate an annotation type if needed.
-    if (fields_annotations != NULL ||
-        methods_annotations != NULL ||
-        methods_parameter_annotations != NULL ||
-        methods_default_annotations != NULL ||
-        fields_type_annotations != NULL ||
-        methods_type_annotations != NULL) {
-      Annotations* anno = Annotations::allocate(loader_data,
-                            fields_annotations, methods_annotations,
-                            methods_parameter_annotations,
-                            methods_default_annotations, CHECK_(nullHandle));
-      this_klass->set_annotations(anno);
-    } else {
-      this_klass->set_annotations(NULL);
-    }
-
-    if (fields_type_annotations != NULL ||
-        methods_type_annotations != NULL) {
-      assert(this_klass->annotations() != NULL, "annotations should have been allocated");
-      Annotations* anno = Annotations::allocate(loader_data,
-                                                fields_type_annotations,
-                                                methods_type_annotations,
-                                                NULL,
-                                                NULL, CHECK_(nullHandle));
-      this_klass->annotations()->set_type_annotations(anno);
+    // Assign allocations if needed
+    if (_annotations != NULL || _type_annotations != NULL ||
+        fields_annotations != NULL || fields_type_annotations != NULL) {
+      Annotations* annotations = Annotations::allocate(loader_data, CHECK_NULL);
+      annotations->set_class_annotations(_annotations);
+      annotations->set_class_type_annotations(_type_annotations);
+      annotations->set_fields_annotations(fields_annotations);
+      annotations->set_fields_type_annotations(fields_type_annotations);
+      this_klass->set_annotations(annotations);
     }
 
     this_klass->set_minor_version(minor_version);
@@ -4153,27 +4158,8 @@
     // Fill in field values obtained by parse_classfile_attributes
     if (parsed_annotations.has_any_annotations())
       parsed_annotations.apply_to(this_klass);
-
-    // Create annotations
-    if (_annotations != NULL && this_klass->annotations() == NULL) {
-      Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
-      this_klass->set_annotations(anno);
-    }
     apply_parsed_class_attributes(this_klass);
 
-    // Create type annotations
-    if (_type_annotations != NULL) {
-      if (this_klass->annotations() == NULL) {
-        Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
-        this_klass->set_annotations(anno);
-      }
-      if (this_klass->annotations()->type_annotations() == NULL) {
-        Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
-        this_klass->annotations()->set_type_annotations(anno);
-      }
-      this_klass->annotations()->type_annotations()->set_class_annotations(_type_annotations);
-    }
-
     // Miranda methods
     if ((num_miranda_methods > 0) ||
         // if this class introduced new miranda methods or
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
index cc0193a..7cedcef 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -199,29 +199,17 @@
                             constantPoolHandle cp,
                             bool is_interface,
                             AccessFlags* promoted_flags,
-                            AnnotationArray** method_annotations,
-                            AnnotationArray** method_parameter_annotations,
-                            AnnotationArray** method_default_annotations,
-                            AnnotationArray** method_type_annotations,
                             TRAPS);
   Array<Method*>* parse_methods(ClassLoaderData* loader_data,
                                 constantPoolHandle cp,
                                 bool is_interface,
                                 AccessFlags* promoted_flags,
                                 bool* has_final_method,
-                                Array<AnnotationArray*>** methods_annotations,
-                                Array<AnnotationArray*>** methods_parameter_annotations,
-                                Array<AnnotationArray*>** methods_default_annotations,
-                                Array<AnnotationArray*>** methods_type_annotations,
                                 bool* has_default_method,
                                 TRAPS);
   Array<int>* sort_methods(ClassLoaderData* loader_data,
                            Array<Method*>* methods,
-                           Array<AnnotationArray*>* methods_annotations,
-                           Array<AnnotationArray*>* methods_parameter_annotations,
-                           Array<AnnotationArray*>* methods_default_annotations,
-                           Array<AnnotationArray*>* methods_type_annotations,
-                                TRAPS);
+                           TRAPS);
   u2* parse_exception_table(ClassLoaderData* loader_data,
                             u4 code_length, u4 exception_table_length,
                             constantPoolHandle cp, TRAPS);
@@ -377,6 +365,32 @@
             : cp->tag_at(index).is_klass_reference());
   }
 
+  void copy_localvariable_table(ConstMethod* cm, int lvt_cnt,
+                                u2* localvariable_table_length,
+                                u2** localvariable_table_start,
+                                int lvtt_cnt,
+                                u2* localvariable_type_table_length,
+                                u2** localvariable_type_table_start,
+                                TRAPS);
+
+  void copy_method_annotations(ClassLoaderData* loader_data,
+                               ConstMethod* cm,
+                               u1* runtime_visible_annotations,
+                               int runtime_visible_annotations_length,
+                               u1* runtime_invisible_annotations,
+                               int runtime_invisible_annotations_length,
+                               u1* runtime_visible_parameter_annotations,
+                               int runtime_visible_parameter_annotations_length,
+                               u1* runtime_invisible_parameter_annotations,
+                               int runtime_invisible_parameter_annotations_length,
+                               u1* runtime_visible_type_annotations,
+                               int runtime_visible_type_annotations_length,
+                               u1* runtime_invisible_type_annotations,
+                               int runtime_invisible_type_annotations_length,
+                               u1* annotation_default,
+                               int annotation_default_length,
+                               TRAPS);
+
  public:
   // Constructor
   ClassFileParser(ClassFileStream* st) { set_stream(st); }
diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp
index ce516b84..4e43d7f 100644
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -1146,9 +1146,10 @@
 
   address code_start = static_cast<address>(bytecodes->adr_at(0));
   int code_length = bytecodes->length();
+  InlineTableSizes sizes;
 
   Method* m = Method::allocate(cp->pool_holder()->class_loader_data(),
-                               code_length, flags, 0, 0, 0, 0, 0, 0,
+                               code_length, flags, &sizes,
                                mt, CHECK_NULL);
 
   m->set_constants(NULL); // This will get filled in later
@@ -1285,33 +1286,15 @@
 
   enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS };
 
-  Array<AnnotationArray*>* original_annots[NUM_ARRAYS] = { NULL };
-
   Array<Method*>* original_methods = klass->methods();
-  Annotations* annots = klass->annotations();
-  if (annots != NULL) {
-    original_annots[ANNOTATIONS] = annots->methods_annotations();
-    original_annots[PARAMETERS]  = annots->methods_parameter_annotations();
-    original_annots[DEFAULTS]    = annots->methods_default_annotations();
-  }
-
   Array<int>* original_ordering = klass->method_ordering();
   Array<int>* merged_ordering = Universe::the_empty_int_array();
 
   int new_size = klass->methods()->length() + new_methods->length();
 
-  Array<AnnotationArray*>* merged_annots[NUM_ARRAYS];
-
   Array<Method*>* merged_methods = MetadataFactory::new_array<Method*>(
       klass->class_loader_data(), new_size, NULL, CHECK);
-  for (int i = 0; i < NUM_ARRAYS; ++i) {
-    if (original_annots[i] != NULL) {
-      merged_annots[i] = MetadataFactory::new_array<AnnotationArray*>(
-          klass->class_loader_data(), new_size, CHECK);
-    } else {
-      merged_annots[i] = NULL;
-    }
-  }
+
   if (original_ordering != NULL && original_ordering->length() > 0) {
     merged_ordering = MetadataFactory::new_array<int>(
         klass->class_loader_data(), new_size, CHECK);
@@ -1338,12 +1321,6 @@
         (new_method == NULL || orig_method->name() < new_method->name())) {
       merged_methods->at_put(i, orig_method);
       original_methods->at_put(orig_idx, NULL);
-      for (int j = 0; j < NUM_ARRAYS; ++j) {
-        if (merged_annots[j] != NULL) {
-          merged_annots[j]->at_put(i, original_annots[j]->at(orig_idx));
-          original_annots[j]->at_put(orig_idx, NULL);
-        }
-      }
       if (merged_ordering->length() > 0) {
         merged_ordering->at_put(i, original_ordering->at(orig_idx));
       }
@@ -1372,21 +1349,9 @@
 
   // Replace klass methods with new merged lists
   klass->set_methods(merged_methods);
-  if (annots != NULL) {
-    annots->set_methods_annotations(merged_annots[ANNOTATIONS]);
-    annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]);
-    annots->set_methods_default_annotations(merged_annots[DEFAULTS]);
-  } else {
-    assert(merged_annots[ANNOTATIONS] == NULL, "Must be");
-    assert(merged_annots[PARAMETERS] == NULL, "Must be");
-    assert(merged_annots[DEFAULTS] == NULL, "Must be");
-  }
 
   ClassLoaderData* cld = klass->class_loader_data();
   MetadataFactory::free_array(cld, original_methods);
-  for (int i = 0; i < NUM_ARRAYS; ++i) {
-    MetadataFactory::free_array(cld, original_annots[i]);
-  }
   if (original_ordering->length() > 0) {
     klass->set_method_ordering(merged_ordering);
     MetadataFactory::free_array(cld, original_ordering);
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 6c1de18..a9b2714 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -274,8 +274,8 @@
 // end of a collection, we let CMSTriggerRatio of the (purported) free
 // space be allocated before initiating a new collection cycle.
 //
-void ConcurrentMarkSweepGeneration::init_initiating_occupancy(intx io, intx tr) {
-  assert(io <= 100 && tr >= 0 && tr <= 100, "Check the arguments");
+void ConcurrentMarkSweepGeneration::init_initiating_occupancy(intx io, uintx tr) {
+  assert(io <= 100 && tr <= 100, "Check the arguments");
   if (io >= 0) {
     _initiating_occupancy = (double)io / 100.0;
   } else {
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
index abc9be6..b688be7 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -1093,7 +1093,7 @@
 
   // getter and initializer for _initiating_occupancy field.
   double initiating_occupancy() const { return _initiating_occupancy; }
-  void   init_initiating_occupancy(intx io, intx tr);
+  void   init_initiating_occupancy(intx io, uintx tr);
 
  public:
   ConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size,
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 28c733c..cc2a611 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -4062,15 +4062,36 @@
       if (_cm->verbose_low()) {
         gclog_or_tty->print_cr("[%u] we're scanning part "
                                "["PTR_FORMAT", "PTR_FORMAT") "
-                               "of region "PTR_FORMAT,
-                               _worker_id, _finger, _region_limit, _curr_region);
+                               "of region "HR_FORMAT,
+                               _worker_id, _finger, _region_limit,
+                               HR_FORMAT_PARAMS(_curr_region));
       }
 
-      // Let's iterate over the bitmap of the part of the
-      // region that is left.
-      if (mr.is_empty() || _nextMarkBitMap->iterate(&bitmap_closure, mr)) {
-        // We successfully completed iterating over the region. Now,
-        // let's give up the region.
+      assert(!_curr_region->isHumongous() || mr.start() == _curr_region->bottom(),
+             "humongous regions should go around loop once only");
+
+      // Some special cases:
+      // If the memory region is empty, we can just give up the region.
+      // If the current region is humongous then we only need to check
+      // the bitmap for the bit associated with the start of the object,
+      // scan the object if it's live, and give up the region.
+      // Otherwise, let's iterate over the bitmap of the part of the region
+      // that is left.
+      // If the iteration is successful, give up the region.
+      if (mr.is_empty()) {
+        giveup_current_region();
+        regular_clock_call();
+      } else if (_curr_region->isHumongous() && mr.start() == _curr_region->bottom()) {
+        if (_nextMarkBitMap->isMarked(mr.start())) {
+          // The object is marked - apply the closure
+          BitMap::idx_t offset = _nextMarkBitMap->heapWordToOffset(mr.start());
+          bitmap_closure.do_bit(offset);
+        }
+        // Even if this task aborted while scanning the humongous object
+        // we can (and should) give up the current region.
+        giveup_current_region();
+        regular_clock_call();
+      } else if (_nextMarkBitMap->iterate(&bitmap_closure, mr)) {
         giveup_current_region();
         regular_clock_call();
       } else {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index cc11754..6464797 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -1893,7 +1893,6 @@
   _ref_processor_stw(NULL),
   _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
   _bot_shared(NULL),
-  _objs_with_preserved_marks(NULL), _preserved_marks_of_objs(NULL),
   _evac_failure_scan_stack(NULL) ,
   _mark_in_progress(false),
   _cg1r(NULL), _summary_bytes_used(0),
@@ -4215,22 +4214,15 @@
   assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
 
   // Now restore saved marks, if any.
-  if (_objs_with_preserved_marks != NULL) {
-    assert(_preserved_marks_of_objs != NULL, "Both or none.");
-    guarantee(_objs_with_preserved_marks->length() ==
-              _preserved_marks_of_objs->length(), "Both or none.");
-    for (int i = 0; i < _objs_with_preserved_marks->length(); i++) {
-      oop obj   = _objs_with_preserved_marks->at(i);
-      markOop m = _preserved_marks_of_objs->at(i);
-      obj->set_mark(m);
-    }
-
-    // Delete the preserved marks growable arrays (allocated on the C heap).
-    delete _objs_with_preserved_marks;
-    delete _preserved_marks_of_objs;
-    _objs_with_preserved_marks = NULL;
-    _preserved_marks_of_objs = NULL;
+  assert(_objs_with_preserved_marks.size() ==
+            _preserved_marks_of_objs.size(), "Both or none.");
+  while (!_objs_with_preserved_marks.is_empty()) {
+    oop obj = _objs_with_preserved_marks.pop();
+    markOop m = _preserved_marks_of_objs.pop();
+    obj->set_mark(m);
   }
+  _objs_with_preserved_marks.clear(true);
+  _preserved_marks_of_objs.clear(true);
 }
 
 void G1CollectedHeap::push_on_evac_failure_scan_stack(oop obj) {
@@ -4313,15 +4305,8 @@
   // We want to call the "for_promotion_failure" version only in the
   // case of a promotion failure.
   if (m->must_be_preserved_for_promotion_failure(obj)) {
-    if (_objs_with_preserved_marks == NULL) {
-      assert(_preserved_marks_of_objs == NULL, "Both or none.");
-      _objs_with_preserved_marks =
-        new (ResourceObj::C_HEAP, mtGC) GrowableArray<oop>(40, true);
-      _preserved_marks_of_objs =
-        new (ResourceObj::C_HEAP, mtGC) GrowableArray<markOop>(40, true);
-    }
-    _objs_with_preserved_marks->push(obj);
-    _preserved_marks_of_objs->push(m);
+    _objs_with_preserved_marks.push(obj);
+    _preserved_marks_of_objs.push(m);
   }
 }
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index 816d4f2..7dc5bd8 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -37,6 +37,7 @@
 #include "memory/barrierSet.hpp"
 #include "memory/memRegion.hpp"
 #include "memory/sharedHeap.hpp"
+#include "utilities/stack.hpp"
 
 // A "G1CollectedHeap" is an implementation of a java heap for HotSpot.
 // It uses the "Garbage First" heap organization and algorithm, which
@@ -877,10 +878,9 @@
   // forwarding pointers to themselves.  Reset them.
   void remove_self_forwarding_pointers();
 
-  // When one is non-null, so is the other.  Together, they each pair is
-  // an object with a preserved mark, and its mark value.
-  GrowableArray<oop>*     _objs_with_preserved_marks;
-  GrowableArray<markOop>* _preserved_marks_of_objs;
+  // Together, these store an object with a preserved mark, and its mark value.
+  Stack<oop, mtGC>     _objs_with_preserved_marks;
+  Stack<markOop, mtGC> _preserved_marks_of_objs;
 
   // Preserve the mark of "obj", if necessary, in preparation for its mark
   // word being overwritten with a self-forwarding-pointer.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
index d362956..1111cec 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
@@ -101,9 +101,6 @@
           "to-space, we will allow regions whose survival rate is up to "   \
           "S + (1 - S)*X, where X is this parameter (as a fraction.)")      \
                                                                             \
-  develop(intx, G1InitYoungSurvRatio, 50,                                   \
-          "Expected Survival Rate for newly allocated bytes")               \
-                                                                            \
   develop(bool, G1SATBPrintStubs, false,                                    \
           "If true, print generated stubs for the SATB barrier")            \
                                                                             \
diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp
index c080cb8..a5de455 100644
--- a/hotspot/src/share/vm/memory/heapInspection.hpp
+++ b/hotspot/src/share/vm/memory/heapInspection.hpp
@@ -85,16 +85,20 @@
         "Number of bytes used by the InstanceKlass::singers() array") \
     f(class_annotations_bytes, class_annotations, \
         "Size of class annotations") \
+    f(class_type_annotations_bytes, class_type_annotations, \
+        "Size of class type annotations") \
     f(fields_annotations_bytes, fields_annotations, \
         "Size of field annotations") \
+    f(fields_type_annotations_bytes, fields_type_annotations, \
+        "Size of field type annotations") \
     f(methods_annotations_bytes, methods_annotations, \
         "Size of method annotations") \
     f(methods_parameter_annotations_bytes, methods_parameter_annotations, \
         "Size of method parameter annotations") \
+    f(methods_type_annotations_bytes, methods_type_annotations, \
+        "Size of methods type annotations") \
     f(methods_default_annotations_bytes, methods_default_annotations, \
         "Size of methods default annotations") \
-    f(type_annotations_bytes, type_annotations, \
-        "Size of type annotations") \
     f(annotations_bytes, annotations, \
         "Size of all annotations") \
     f(cp_bytes, Cp, \
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index c629e17..b089115 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -1064,11 +1064,11 @@
 //
 // After the GC the compute_new_size() for MetaspaceGC is called to
 // resize the capacity of the metaspaces.  The current implementation
-// is based on the flags MinHeapFreeRatio and MaxHeapFreeRatio used
+// is based on the flags MinMetaspaceFreeRatio and MaxHeapFreeRatio used
 // to resize the Java heap by some GC's.  New flags can be implemented
 // if really needed.  MinHeapFreeRatio is used to calculate how much
 // free space is desirable in the metaspace capacity to decide how much
-// to increase the HWM.  MaxHeapFreeRatio is used to decide how much
+// to increase the HWM.  MaxMetaspaceFreeRatio is used to decide how much
 // free space is desirable in the metaspace capacity before decreasing
 // the HWM.
 
@@ -1166,7 +1166,7 @@
   size_t capacity_until_GC = vsl->capacity_bytes_sum();
   size_t free_after_gc = capacity_until_GC - used_after_gc;
 
-  const double minimum_free_percentage = MinHeapFreeRatio / 100.0;
+  const double minimum_free_percentage = MinMetaspaceFreeRatio / 100.0;
   const double maximum_used_percentage = 1.0 - minimum_free_percentage;
 
   const double min_tmp = used_after_gc / maximum_used_percentage;
@@ -1232,8 +1232,8 @@
     max_shrink_words));
 
   // Should shrinking be considered?
-  if (MaxHeapFreeRatio < 100) {
-    const double maximum_free_percentage = MaxHeapFreeRatio / 100.0;
+  if (MaxMetaspaceFreeRatio < 100) {
+    const double maximum_free_percentage = MaxMetaspaceFreeRatio / 100.0;
     const double minimum_used_percentage = 1.0 - maximum_free_percentage;
     const double max_tmp = used_after_gc / minimum_used_percentage;
     size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
diff --git a/hotspot/src/share/vm/oops/annotations.cpp b/hotspot/src/share/vm/oops/annotations.cpp
index 9e5d6ef..546257a 100644
--- a/hotspot/src/share/vm/oops/annotations.cpp
+++ b/hotspot/src/share/vm/oops/annotations.cpp
@@ -36,16 +36,8 @@
   return new (loader_data, size(), true, THREAD) Annotations();
 }
 
-Annotations* Annotations::allocate(ClassLoaderData* loader_data,
-                                   Array<AnnotationArray*>* fa,
-                                   Array<AnnotationArray*>* ma,
-                                   Array<AnnotationArray*>* mpa,
-                                   Array<AnnotationArray*>* mda, TRAPS) {
-  return new (loader_data, size(), true, THREAD) Annotations(fa, ma, mpa, mda);
-}
-
 // helper
-static void free_contents(ClassLoaderData* loader_data, Array<AnnotationArray*>* p) {
+void Annotations::free_contents(ClassLoaderData* loader_data, Array<AnnotationArray*>* p) {
   if (p != NULL) {
     for (int i = 0; i < p->length(); i++) {
       MetadataFactory::free_array<u1>(loader_data, p->at(i));
@@ -59,44 +51,16 @@
     MetadataFactory::free_array<u1>(loader_data, class_annotations());
   }
   free_contents(loader_data, fields_annotations());
-  free_contents(loader_data, methods_annotations());
-  free_contents(loader_data, methods_parameter_annotations());
-  free_contents(loader_data, methods_default_annotations());
 
-  // Recursively deallocate optional Annotations linked through this one
-  MetadataFactory::free_metadata(loader_data, type_annotations());
+  if (class_type_annotations() != NULL) {
+    MetadataFactory::free_array<u1>(loader_data, class_type_annotations());
+  }
+  free_contents(loader_data, fields_type_annotations());
 }
 
-// Set the annotation at 'idnum' to 'anno'.
-// We don't want to create or extend the array if 'anno' is NULL, since that is the
-// default value.  However, if the array exists and is long enough, we must set NULL values.
-void Annotations::set_methods_annotations_of(instanceKlassHandle ik,
-                                             int idnum, AnnotationArray* anno,
-                                             Array<AnnotationArray*>** md_p,
-                                             TRAPS) {
-  Array<AnnotationArray*>* md = *md_p;
-  if (md != NULL && md->length() > idnum) {
-    md->at_put(idnum, anno);
-  } else if (anno != NULL) {
-    // create the array
-    int length = MAX2(idnum+1, (int)ik->idnum_allocated_count());
-    md = MetadataFactory::new_array<AnnotationArray*>(ik->class_loader_data(), length, CHECK);
-    if (*md_p != NULL) {
-      // copy the existing entries
-      for (int index = 0; index < (*md_p)->length(); index++) {
-        md->at_put(index, (*md_p)->at(index));
-      }
-    }
-    set_annotations(md, md_p);
-    md->at_put(idnum, anno);
-  } // if no array and idnum isn't included there is nothing to do
-}
-
-// Keep created annotations in a global growable array (should be hashtable)
-// need to add, search, delete when class is unloaded.
-// Does it need a lock?  yes.  This sucks.
-
 // Copy annotations to JVM call or reflection to the java heap.
+// The alternative to creating this array and adding to Java heap pressure
+// is to have a hashtable of the already created typeArrayOops
 typeArrayOop Annotations::make_java_array(AnnotationArray* annotations, TRAPS) {
   if (annotations != NULL) {
     int length = annotations->length();
@@ -132,28 +96,15 @@
 void Annotations::collect_statistics(KlassSizeStats *sz) const {
   sz->_annotations_bytes = sz->count(this);
   sz->_class_annotations_bytes = sz->count(class_annotations());
+  sz->_class_type_annotations_bytes = sz->count(class_type_annotations());
   sz->_fields_annotations_bytes = count_bytes(fields_annotations());
-  sz->_methods_annotations_bytes = count_bytes(methods_annotations());
-  sz->_methods_parameter_annotations_bytes =
-                          count_bytes(methods_parameter_annotations());
-  sz->_methods_default_annotations_bytes =
-                          count_bytes(methods_default_annotations());
-
-  const Annotations* type_anno = type_annotations();
-  if (type_anno != NULL) {
-    sz->_type_annotations_bytes = sz->count(type_anno);
-    sz->_type_annotations_bytes += sz->count(type_anno->class_annotations());
-    sz->_type_annotations_bytes += count_bytes(type_anno->fields_annotations());
-    sz->_type_annotations_bytes += count_bytes(type_anno->methods_annotations());
-  }
+  sz->_fields_type_annotations_bytes = count_bytes(fields_type_annotations());
 
   sz->_annotations_bytes +=
       sz->_class_annotations_bytes +
+      sz->_class_type_annotations_bytes +
       sz->_fields_annotations_bytes +
-      sz->_methods_annotations_bytes +
-      sz->_methods_parameter_annotations_bytes +
-      sz->_methods_default_annotations_bytes +
-      sz->_type_annotations_bytes;
+      sz->_fields_type_annotations_bytes;
 
   sz->_ro_bytes += sz->_annotations_bytes;
 }
@@ -165,8 +116,7 @@
 void Annotations::print_on(outputStream* st) const {
   st->print(BULLET"class_annotations            "); class_annotations()->print_value_on(st);
   st->print(BULLET"fields_annotations           "); fields_annotations()->print_value_on(st);
-  st->print(BULLET"methods_annotations          "); methods_annotations()->print_value_on(st);
-  st->print(BULLET"methods_parameter_annotations"); methods_parameter_annotations()->print_value_on(st);
-  st->print(BULLET"methods_default_annotations  "); methods_default_annotations()->print_value_on(st);
+  st->print(BULLET"class_type_annotations       "); class_type_annotations()->print_value_on(st);
+  st->print(BULLET"fields_type_annotations      "); fields_type_annotations()->print_value_on(st);
 }
 #endif // PRODUCT
diff --git a/hotspot/src/share/vm/oops/annotations.hpp b/hotspot/src/share/vm/oops/annotations.hpp
index 82d701a..ad405a8 100644
--- a/hotspot/src/share/vm/oops/annotations.hpp
+++ b/hotspot/src/share/vm/oops/annotations.hpp
@@ -49,38 +49,15 @@
   // Annotation objects (byte arrays) for fields, or null if no annotations.
   // Indices correspond to entries (not indices) in fields array.
   Array<AnnotationArray*>*     _fields_annotations;
-  // Annotation objects (byte arrays) for methods, or null if no annotations.
-  // Index is the idnum, which is initially the same as the methods array index.
-  Array<AnnotationArray*>*     _methods_annotations;
-  // Annotation objects (byte arrays) for methods' parameters, or null if no
-  // such annotations.
-  // Index is the idnum, which is initially the same as the methods array index.
-  Array<AnnotationArray*>*     _methods_parameter_annotations;
-  // Annotation objects (byte arrays) for methods' default values, or null if no
-  // such annotations.
-  // Index is the idnum, which is initially the same as the methods array index.
-  Array<AnnotationArray*>*     _methods_default_annotations;
   // Type annotations for this class, or null if none.
-  Annotations*                 _type_annotations;
-
-  // Constructor where some some values are known to not be null
-  Annotations(Array<AnnotationArray*>* fa, Array<AnnotationArray*>* ma,
-              Array<AnnotationArray*>* mpa, Array<AnnotationArray*>* mda) :
-                 _class_annotations(NULL),
-                 _fields_annotations(fa),
-                 _methods_annotations(ma),
-                 _methods_parameter_annotations(mpa),
-                 _methods_default_annotations(mda),
-                 _type_annotations(NULL) {}
+  AnnotationArray*             _class_type_annotations;
+  Array<AnnotationArray*>*     _fields_type_annotations;
 
  public:
   // Allocate instance of this class
   static Annotations* allocate(ClassLoaderData* loader_data, TRAPS);
-  static Annotations* allocate(ClassLoaderData* loader_data,
-                               Array<AnnotationArray*>* fa,
-                               Array<AnnotationArray*>* ma,
-                               Array<AnnotationArray*>* mpa,
-                               Array<AnnotationArray*>* mda, TRAPS);
+
+  static void free_contents(ClassLoaderData* loader_data, Array<AnnotationArray*>* p);
   void deallocate_contents(ClassLoaderData* loader_data);
   DEBUG_ONLY(bool on_stack() { return false; })  // for template
 
@@ -93,61 +70,24 @@
   // Constructor to initialize to null
   Annotations() : _class_annotations(NULL),
                   _fields_annotations(NULL),
-                  _methods_annotations(NULL),
-                  _methods_parameter_annotations(NULL),
-                  _methods_default_annotations(NULL),
-                  _type_annotations(NULL) {}
+                  _class_type_annotations(NULL),
+                  _fields_type_annotations(NULL) {}
 
   AnnotationArray* class_annotations() const                       { return _class_annotations; }
   Array<AnnotationArray*>* fields_annotations() const              { return _fields_annotations; }
-  Array<AnnotationArray*>* methods_annotations() const             { return _methods_annotations; }
-  Array<AnnotationArray*>* methods_parameter_annotations() const   { return _methods_parameter_annotations; }
-  Array<AnnotationArray*>* methods_default_annotations() const     { return _methods_default_annotations; }
-  Annotations* type_annotations() const                            { return _type_annotations; }
+  AnnotationArray* class_type_annotations() const                  { return _class_type_annotations; }
+  Array<AnnotationArray*>* fields_type_annotations() const         { return _fields_type_annotations; }
 
   void set_class_annotations(AnnotationArray* md)                     { _class_annotations = md; }
   void set_fields_annotations(Array<AnnotationArray*>* md)            { _fields_annotations = md; }
-  void set_methods_annotations(Array<AnnotationArray*>* md)           { _methods_annotations = md; }
-  void set_methods_parameter_annotations(Array<AnnotationArray*>* md) { _methods_parameter_annotations = md; }
-  void set_methods_default_annotations(Array<AnnotationArray*>* md)   { _methods_default_annotations = md; }
-  void set_type_annotations(Annotations* annos)                       { _type_annotations = annos; }
-
-  // Redefine classes support
-  AnnotationArray* get_method_annotations_of(int idnum)
-                                                { return get_method_annotations_from(idnum, _methods_annotations); }
-
-  AnnotationArray* get_method_parameter_annotations_of(int idnum)
-                                                { return get_method_annotations_from(idnum, _methods_parameter_annotations); }
-  AnnotationArray* get_method_default_annotations_of(int idnum)
-                                                { return get_method_annotations_from(idnum, _methods_default_annotations); }
-
-
-  void set_method_annotations_of(instanceKlassHandle ik,
-                                 int idnum, AnnotationArray* anno, TRAPS) {
-    set_methods_annotations_of(ik, idnum, anno, &_methods_annotations, THREAD);
-  }
-
-  void set_method_parameter_annotations_of(instanceKlassHandle ik,
-                                 int idnum, AnnotationArray* anno, TRAPS) {
-    set_methods_annotations_of(ik, idnum, anno, &_methods_parameter_annotations, THREAD);
-  }
-
-  void set_method_default_annotations_of(instanceKlassHandle ik,
-                                 int idnum, AnnotationArray* anno, TRAPS) {
-    set_methods_annotations_of(ik, idnum, anno, &_methods_default_annotations, THREAD);
-  }
+  void set_class_type_annotations(AnnotationArray* cta)               { _class_type_annotations = cta; }
+  void set_fields_type_annotations(Array<AnnotationArray*>* fta)      { _fields_type_annotations = fta; }
 
   // Turn metadata annotations into a Java heap object (oop)
   static typeArrayOop make_java_array(AnnotationArray* annotations, TRAPS);
 
-  inline AnnotationArray* get_method_annotations_from(int idnum, Array<AnnotationArray*>* annos);
-  void set_annotations(Array<AnnotationArray*>* md, Array<AnnotationArray*>** md_p)  { *md_p = md; }
-
   bool is_klass() const { return false; }
  private:
-  void set_methods_annotations_of(instanceKlassHandle ik,
-                                  int idnum, AnnotationArray* anno,
-                                  Array<AnnotationArray*>** md_p, TRAPS);
   static julong count_bytes(Array<AnnotationArray*>* p);
  public:
   const char* internal_name() const { return "{constant pool}"; }
@@ -156,13 +96,4 @@
 #endif
   void print_value_on(outputStream* st) const;
 };
-
-
-// For method with idnum get the method's Annotations
-inline AnnotationArray* Annotations::get_method_annotations_from(int idnum, Array<AnnotationArray*>* annos) {
-  if (annos == NULL || annos->length() <= idnum) {
-    return NULL;
-  }
-  return annos->at(idnum);
-}
 #endif // SHARE_VM_OOPS_ANNOTATIONS_HPP
diff --git a/hotspot/src/share/vm/oops/constMethod.cpp b/hotspot/src/share/vm/oops/constMethod.cpp
index 3358d22..35b7be2 100644
--- a/hotspot/src/share/vm/oops/constMethod.cpp
+++ b/hotspot/src/share/vm/oops/constMethod.cpp
@@ -36,51 +36,26 @@
 
 ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
                                    int byte_code_size,
-                                   int compressed_line_number_size,
-                                   int localvariable_table_length,
-                                   int exception_table_length,
-                                   int checked_exceptions_length,
-                                   int method_parameters_length,
-                                   u2  generic_signature_index,
+                                   InlineTableSizes* sizes,
                                    MethodType method_type,
                                    TRAPS) {
-  int size = ConstMethod::size(byte_code_size,
-                               compressed_line_number_size,
-                               localvariable_table_length,
-                               exception_table_length,
-                               checked_exceptions_length,
-                               method_parameters_length,
-                               generic_signature_index);
+  int size = ConstMethod::size(byte_code_size, sizes);
   return new (loader_data, size, true, THREAD) ConstMethod(
-      byte_code_size, compressed_line_number_size, localvariable_table_length,
-      exception_table_length, checked_exceptions_length,
-      method_parameters_length, generic_signature_index,
-      method_type, size);
+      byte_code_size, sizes, method_type, size);
 }
 
 ConstMethod::ConstMethod(int byte_code_size,
-                         int compressed_line_number_size,
-                         int localvariable_table_length,
-                         int exception_table_length,
-                         int checked_exceptions_length,
-                         int method_parameters_length,
-                         u2  generic_signature_index,
+                         InlineTableSizes* sizes,
                          MethodType method_type,
                          int size) {
 
   No_Safepoint_Verifier no_safepoint;
-  set_interpreter_kind(Interpreter::invalid);
   init_fingerprint();
   set_constants(NULL);
   set_stackmap_data(NULL);
   set_code_size(byte_code_size);
   set_constMethod_size(size);
-  set_inlined_tables_length(generic_signature_index,
-                            checked_exceptions_length,
-                            compressed_line_number_size,
-                            localvariable_table_length,
-                            exception_table_length,
-                            method_parameters_length);
+  set_inlined_tables_length(sizes);
   set_method_type(method_type);
   assert(this->size() == size, "wrong size for object");
 }
@@ -88,47 +63,70 @@
 
 // Deallocate metadata fields associated with ConstMethod*
 void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {
-  set_interpreter_kind(Interpreter::invalid);
   if (stackmap_data() != NULL) {
     MetadataFactory::free_array<u1>(loader_data, stackmap_data());
   }
   set_stackmap_data(NULL);
+
+  // deallocate annotation arrays
+  if (has_method_annotations())
+    MetadataFactory::free_array<u1>(loader_data, method_annotations());
+  if (has_parameter_annotations())
+    MetadataFactory::free_array<u1>(loader_data, parameter_annotations());
+  if (has_type_annotations())
+    MetadataFactory::free_array<u1>(loader_data, type_annotations());
+  if (has_default_annotations())
+    MetadataFactory::free_array<u1>(loader_data, default_annotations());
 }
 
 // How big must this constMethodObject be?
 
 int ConstMethod::size(int code_size,
-                      int compressed_line_number_size,
-                      int local_variable_table_length,
-                      int exception_table_length,
-                      int checked_exceptions_length,
-                      int method_parameters_length,
-                      u2  generic_signature_index) {
+                      InlineTableSizes* sizes) {
   int extra_bytes = code_size;
-  if (compressed_line_number_size > 0) {
-    extra_bytes += compressed_line_number_size;
+  if (sizes->compressed_linenumber_size() > 0) {
+    extra_bytes += sizes->compressed_linenumber_size();
   }
-  if (checked_exceptions_length > 0) {
+  if (sizes->checked_exceptions_length() > 0) {
     extra_bytes += sizeof(u2);
-    extra_bytes += checked_exceptions_length * sizeof(CheckedExceptionElement);
+    extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement);
   }
-  if (local_variable_table_length > 0) {
+  if (sizes->localvariable_table_length() > 0) {
     extra_bytes += sizeof(u2);
     extra_bytes +=
-              local_variable_table_length * sizeof(LocalVariableTableElement);
+              sizes->localvariable_table_length() * sizeof(LocalVariableTableElement);
   }
-  if (exception_table_length > 0) {
+  if (sizes->exception_table_length() > 0) {
     extra_bytes += sizeof(u2);
-    extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
+    extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement);
   }
-  if (generic_signature_index != 0) {
+  if (sizes->generic_signature_index() != 0) {
     extra_bytes += sizeof(u2);
   }
-  if (method_parameters_length > 0) {
+  if (sizes->method_parameters_length() > 0) {
     extra_bytes += sizeof(u2);
-    extra_bytes += method_parameters_length * sizeof(MethodParametersElement);
+    extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
   }
+
+  // Align sizes up to a word.
+  extra_bytes = align_size_up(extra_bytes, BytesPerWord);
+
+  // One pointer per annotation array
+  if (sizes->method_annotations_length() > 0) {
+    extra_bytes += sizeof(AnnotationArray*);
+  }
+  if (sizes->parameter_annotations_length() > 0) {
+    extra_bytes += sizeof(AnnotationArray*);
+  }
+  if (sizes->type_annotations_length() > 0) {
+    extra_bytes += sizeof(AnnotationArray*);
+  }
+  if (sizes->default_annotations_length() > 0) {
+    extra_bytes += sizeof(AnnotationArray*);
+  }
+
   int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
+  assert(extra_words == extra_bytes/BytesPerWord, "should already be aligned");
   return align_object_size(header_size() + extra_words);
 }
 
@@ -145,12 +143,28 @@
   return code_end();
 }
 
+// Last short in ConstMethod* before annotations
+u2* ConstMethod::last_u2_element() const {
+  int offset = 0;
+  if (has_method_annotations()) offset++;
+  if (has_parameter_annotations()) offset++;
+  if (has_type_annotations()) offset++;
+  if (has_default_annotations()) offset++;
+  return (u2*)((AnnotationArray**)constMethod_end() - offset) - 1;
+}
+
 u2* ConstMethod::generic_signature_index_addr() const {
   // Located at the end of the constMethod.
   assert(has_generic_signature(), "called only if generic signature exists");
   return last_u2_element();
 }
 
+u2* ConstMethod::method_parameters_length_addr() const {
+  assert(has_method_parameters(), "called only if table is present");
+  return has_generic_signature() ? (last_u2_element() - 1) :
+                                    last_u2_element();
+}
+
 u2* ConstMethod::checked_exceptions_length_addr() const {
   // Located immediately before the generic signature index.
   assert(has_checked_exceptions(), "called only if table is present");
@@ -164,12 +178,6 @@
   }
 }
 
-u2* ConstMethod::method_parameters_length_addr() const {
-  assert(has_method_parameters(), "called only if table is present");
-  return has_generic_signature() ? (last_u2_element() - 1) :
-                                    last_u2_element();
-}
-
 u2* ConstMethod::exception_table_length_addr() const {
   assert(has_exception_handler(), "called only if table is present");
   if (has_checked_exceptions()) {
@@ -181,9 +189,9 @@
       return (u2*)method_parameters_start() - 1;
     } else {
       // Else, the exception table is at the end of the constMethod.
-    return has_generic_signature() ? (last_u2_element() - 1) :
-                                      last_u2_element();
-  }
+      return has_generic_signature() ? (last_u2_element() - 1) :
+                                        last_u2_element();
+    }
   }
 }
 
@@ -204,32 +212,38 @@
         // Else, the exception table is at the end of the constMethod.
       return has_generic_signature() ? (last_u2_element() - 1) :
                                         last_u2_element();
+      }
     }
   }
-  }
 }
 
 // Update the flags to indicate the presence of these optional fields.
-void ConstMethod::set_inlined_tables_length(u2  generic_signature_index,
-                                            int checked_exceptions_len,
-                                            int compressed_line_number_size,
-                                            int localvariable_table_len,
-                                            int exception_table_len,
-                                            int method_parameters_len) {
-  assert(_flags == 0, "Error");
-  if (compressed_line_number_size > 0)
+void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
+  _flags = 0;
+  if (sizes->compressed_linenumber_size() > 0)
     _flags |= _has_linenumber_table;
-  if (generic_signature_index != 0)
+  if (sizes->generic_signature_index() != 0)
     _flags |= _has_generic_signature;
-  if (method_parameters_len > 0)
+  if (sizes->method_parameters_length() > 0)
     _flags |= _has_method_parameters;
-  if (checked_exceptions_len > 0)
+  if (sizes->checked_exceptions_length() > 0)
     _flags |= _has_checked_exceptions;
-  if (exception_table_len > 0)
+  if (sizes->exception_table_length() > 0)
     _flags |= _has_exception_table;
-  if (localvariable_table_len > 0)
+  if (sizes->localvariable_table_length() > 0)
     _flags |= _has_localvariable_table;
 
+  // annotations, they are all pointer sized embedded objects so don't have
+  // a length embedded also.
+  if (sizes->method_annotations_length() > 0)
+    _flags |= _has_method_annotations;
+  if (sizes->parameter_annotations_length() > 0)
+    _flags |= _has_parameter_annotations;
+  if (sizes->type_annotations_length() > 0)
+    _flags |= _has_type_annotations;
+  if (sizes->default_annotations_length() > 0)
+    _flags |= _has_default_annotations;
+
   // This code is extremely brittle and should possibly be revised.
   // The *_length_addr functions walk backwards through the
   // constMethod data, using each of the length indexes ahead of them,
@@ -242,17 +256,17 @@
   // Also, the servicability agent needs to be informed anytime
   // anything is added here.  It might be advisable to have some sort
   // of indication of this inline.
-  if (generic_signature_index != 0)
-    *(generic_signature_index_addr()) = generic_signature_index;
+  if (sizes->generic_signature_index() != 0)
+    *(generic_signature_index_addr()) = sizes->generic_signature_index();
   // New data should probably go here.
-  if (method_parameters_len > 0)
-    *(method_parameters_length_addr()) = method_parameters_len;
-  if (checked_exceptions_len > 0)
-    *(checked_exceptions_length_addr()) = checked_exceptions_len;
-  if (exception_table_len > 0)
-    *(exception_table_length_addr()) = exception_table_len;
-  if (localvariable_table_len > 0)
-    *(localvariable_table_length_addr()) = localvariable_table_len;
+  if (sizes->method_parameters_length() > 0)
+    *(method_parameters_length_addr()) = sizes->method_parameters_length();
+  if (sizes->checked_exceptions_length() > 0)
+    *(checked_exceptions_length_addr()) = sizes->checked_exceptions_length();
+  if (sizes->exception_table_length() > 0)
+    *(exception_table_length_addr()) = sizes->exception_table_length();
+  if (sizes->localvariable_table_length() > 0)
+    *(localvariable_table_length_addr()) = sizes->localvariable_table_length();
 }
 
 int ConstMethod::method_parameters_length() const {
@@ -307,6 +321,34 @@
   return (ExceptionTableElement*)addr;
 }
 
+AnnotationArray** ConstMethod::method_annotations_addr() const {
+  assert(has_method_annotations(), "should only be called if method annotations are present");
+  return (AnnotationArray**)constMethod_end() - 1;
+}
+
+AnnotationArray** ConstMethod::parameter_annotations_addr() const {
+  assert(has_parameter_annotations(), "should only be called if method parameter annotations are present");
+  int offset = 1;
+  if (has_method_annotations()) offset++;
+  return (AnnotationArray**)constMethod_end() - offset;
+}
+
+AnnotationArray** ConstMethod::type_annotations_addr() const {
+  assert(has_type_annotations(), "should only be called if method type annotations are present");
+  int offset = 1;
+  if (has_method_annotations()) offset++;
+  if (has_parameter_annotations()) offset++;
+  return (AnnotationArray**)constMethod_end() - offset;
+}
+
+AnnotationArray** ConstMethod::default_annotations_addr() const {
+  assert(has_default_annotations(), "should only be called if method default annotations are present");
+  int offset = 1;
+  if (has_method_annotations()) offset++;
+  if (has_parameter_annotations()) offset++;
+  if (has_type_annotations()) offset++;
+  return (AnnotationArray**)constMethod_end() - offset;
+}
 
 // Printing
 
@@ -339,8 +381,25 @@
   sz->_bytecode_bytes     += (n2 = code_size());
   sz->_stackmap_bytes     += (n3 = sz->count_array(stackmap_data()));
 
-  sz->_method_all_bytes += n1 + n3; // note: n2 is part of n3
-  sz->_ro_bytes += n1 + n3;
+  // Count method annotations
+  int a1 = 0, a2 = 0, a3 = 0, a4 = 0;
+  if (has_method_annotations()) {
+    sz->_methods_annotations_bytes += (a1 = sz->count_array(method_annotations()));
+  }
+  if (has_parameter_annotations()) {
+    sz->_methods_parameter_annotations_bytes += (a2 = sz->count_array(parameter_annotations()));
+  }
+  if (has_type_annotations()) {
+    sz->_methods_type_annotations_bytes += (a3 = sz->count_array(type_annotations()));
+  }
+  if (has_default_annotations()) {
+    sz->_methods_default_annotations_bytes += (a4 = sz->count_array(default_annotations()));
+  }
+
+  int size_annotations = a1 + a2 + a3 + a4;
+
+  sz->_method_all_bytes += n1 + n3 + size_annotations; // note: n2 is part of n3
+  sz->_ro_bytes += n1 + n3 + size_annotations;
 }
 #endif // INCLUDE_SERVICES
 
@@ -352,10 +411,9 @@
 
   // Verification can occur during oop construction before the method or
   // other fields have been initialized.
-  guarantee(is_metadata(), err_msg("Should be metadata " PTR_FORMAT, this));
   guarantee(method()->is_method(), "should be method");
 
-  address m_end = (address)((oop*) this + size());
+  address m_end = (address)((intptr_t) this + size());
   address compressed_table_start = code_end();
   guarantee(compressed_table_start <= m_end, "invalid method layout");
   address compressed_table_end = compressed_table_start;
diff --git a/hotspot/src/share/vm/oops/constMethod.hpp b/hotspot/src/share/vm/oops/constMethod.hpp
index 12a36c2..21fa344 100644
--- a/hotspot/src/share/vm/oops/constMethod.hpp
+++ b/hotspot/src/share/vm/oops/constMethod.hpp
@@ -86,19 +86,22 @@
 // | generic signature index (u2)                         |
 // |  (indexed from start of constMethodOop)              |
 // |------------------------------------------------------|
+// | annotations arrays - method, parameter, type, default|
+// | pointer to Array<u1> if annotation is present        |
+// |------------------------------------------------------|
 //
 // IMPORTANT: If anything gets added here, there need to be changes to
 // ensure that ServicabilityAgent doesn't get broken as a result!
 
 
-// Utitily class decribing elements in checked exceptions table inlined in Method*.
+// Utility class describing elements in checked exceptions table inlined in Method*.
 class CheckedExceptionElement VALUE_OBJ_CLASS_SPEC {
  public:
   u2 class_cp_index;
 };
 
 
-// Utitily class decribing elements in local variable table inlined in Method*.
+// Utility class describing elements in local variable table inlined in Method*.
 class LocalVariableTableElement VALUE_OBJ_CLASS_SPEC {
  public:
   u2 start_bci;
@@ -109,7 +112,7 @@
   u2 slot;
 };
 
-// Utitily class describing elements in exception table
+// Utility class describing elements in exception table
 class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
  public:
   u2 start_pc;
@@ -127,6 +130,51 @@
 
 class KlassSizeStats;
 
+// Class to collect the sizes of ConstMethod inline tables
+#define INLINE_TABLES_DO(do_element)            \
+  do_element(localvariable_table_length)        \
+  do_element(compressed_linenumber_size)        \
+  do_element(exception_table_length)            \
+  do_element(checked_exceptions_length)         \
+  do_element(method_parameters_length)          \
+  do_element(generic_signature_index)           \
+  do_element(method_annotations_length)         \
+  do_element(parameter_annotations_length)      \
+  do_element(type_annotations_length)           \
+  do_element(default_annotations_length)
+
+#define INLINE_TABLE_DECLARE(sym)    int _##sym;
+#define INLINE_TABLE_PARAM(sym)      int sym,
+#define INLINE_TABLE_INIT(sym)       _##sym(sym),
+#define INLINE_TABLE_NULL(sym)       _##sym(0),
+#define INLINE_TABLE_ACCESSOR(sym)   int sym() const { return _##sym; }
+
+class InlineTableSizes : StackObj {
+  // declarations
+  INLINE_TABLES_DO(INLINE_TABLE_DECLARE)
+  int _end;
+ public:
+  InlineTableSizes(
+      INLINE_TABLES_DO(INLINE_TABLE_PARAM)
+      int end) :
+      INLINE_TABLES_DO(INLINE_TABLE_INIT)
+      _end(end) {}
+
+  // Default constructor for no inlined tables
+  InlineTableSizes() :
+      INLINE_TABLES_DO(INLINE_TABLE_NULL)
+      _end(0) {}
+
+  // Accessors
+  INLINE_TABLES_DO(INLINE_TABLE_ACCESSOR)
+};
+#undef INLINE_TABLE_ACCESSOR
+#undef INLINE_TABLE_NULL
+#undef INLINE_TABLE_INIT
+#undef INLINE_TABLE_PARAM
+#undef INLINE_TABLE_DECLARE
+
+
 class ConstMethod : public MetaspaceObj {
   friend class VMStructs;
 
@@ -135,13 +183,17 @@
 
 private:
   enum {
-    _has_linenumber_table = 1,
-    _has_checked_exceptions = 2,
-    _has_localvariable_table = 4,
-    _has_exception_table = 8,
-    _has_generic_signature = 16,
-    _has_method_parameters = 32,
-    _is_overpass = 64
+    _has_linenumber_table = 0x0001,
+    _has_checked_exceptions = 0x0002,
+    _has_localvariable_table = 0x0004,
+    _has_exception_table = 0x0008,
+    _has_generic_signature = 0x0010,
+    _has_method_parameters = 0x0020,
+    _is_overpass = 0x0040,
+    _has_method_annotations = 0x0080,
+    _has_parameter_annotations = 0x0100,
+    _has_type_annotations = 0x0200,
+    _has_default_annotations = 0x0400
   };
 
   // Bit vector of signature
@@ -158,8 +210,7 @@
   Array<u1>*        _stackmap_data;
 
   int               _constMethod_size;
-  jbyte             _interpreter_kind;
-  jbyte             _flags;
+  u2                _flags;
 
   // Size of Java bytecodes allocated immediately after Method*.
   u2                _code_size;
@@ -174,36 +225,21 @@
 
   // Constructor
   ConstMethod(int byte_code_size,
-              int compressed_line_number_size,
-              int localvariable_table_length,
-              int exception_table_length,
-              int checked_exceptions_length,
-              int method_parameters_length,
-              u2  generic_signature_index,
+              InlineTableSizes* sizes,
               MethodType is_overpass,
               int size);
 public:
 
   static ConstMethod* allocate(ClassLoaderData* loader_data,
                                int byte_code_size,
-                               int compressed_line_number_size,
-                               int localvariable_table_length,
-                               int exception_table_length,
-                               int checked_exceptions_length,
-                               int method_parameters_length,
-                               u2  generic_signature_index,
+                               InlineTableSizes* sizes,
                                MethodType mt,
                                TRAPS);
 
   bool is_constMethod() const { return true; }
 
   // Inlined tables
-  void set_inlined_tables_length(u2  generic_signature_index,
-                                 int checked_exceptions_len,
-                                 int compressed_line_number_size,
-                                 int localvariable_table_len,
-                                 int exception_table_len,
-                                 int method_parameters_length);
+  void set_inlined_tables_length(InlineTableSizes* sizes);
 
   bool has_generic_signature() const
     { return (_flags & _has_generic_signature) != 0; }
@@ -235,10 +271,6 @@
     }
   }
 
-
-  void set_interpreter_kind(int kind)      { _interpreter_kind = kind; }
-  int  interpreter_kind(void) const        { return _interpreter_kind; }
-
   // constant pool
   ConstantPool* constants() const        { return _constants; }
   void set_constants(ConstantPool* c)    { _constants = c; }
@@ -307,12 +339,7 @@
   }
 
   // Size needed
-  static int size(int code_size, int compressed_line_number_size,
-                  int local_variable_table_length,
-                  int exception_table_length,
-                  int checked_exceptions_length,
-                  int method_parameters_length,
-                  u2  generic_signature_index);
+  static int size(int code_size, InlineTableSizes* sizes);
 
   int size() const                    { return _constMethod_size;}
   void set_constMethod_size(int size)     { _constMethod_size = size; }
@@ -354,6 +381,65 @@
   int method_parameters_length() const;
   MethodParametersElement* method_parameters_start() const;
 
+  // method annotations
+  bool has_method_annotations() const
+    { return (_flags & _has_method_annotations) != 0; }
+
+  bool has_parameter_annotations() const
+    { return (_flags & _has_parameter_annotations) != 0; }
+
+  bool has_type_annotations() const
+    { return (_flags & _has_type_annotations) != 0; }
+
+  bool has_default_annotations() const
+    { return (_flags & _has_default_annotations) != 0; }
+
+
+  AnnotationArray** method_annotations_addr() const;
+  AnnotationArray* method_annotations() const  {
+    return has_method_annotations() ? *(method_annotations_addr()) : NULL;
+  }
+  void set_method_annotations(AnnotationArray* anno) {
+    *(method_annotations_addr()) = anno;
+  }
+
+  AnnotationArray** parameter_annotations_addr() const;
+  AnnotationArray* parameter_annotations() const {
+    return has_parameter_annotations() ? *(parameter_annotations_addr()) : NULL;
+  }
+  void set_parameter_annotations(AnnotationArray* anno) {
+    *(parameter_annotations_addr()) = anno;
+  }
+
+  AnnotationArray** type_annotations_addr() const;
+  AnnotationArray* type_annotations() const {
+    return has_type_annotations() ? *(type_annotations_addr()) : NULL;
+  }
+  void set_type_annotations(AnnotationArray* anno) {
+    *(type_annotations_addr()) = anno;
+  }
+
+  AnnotationArray** default_annotations_addr() const;
+  AnnotationArray* default_annotations() const {
+    return has_default_annotations() ? *(default_annotations_addr()) : NULL;
+  }
+  void set_default_annotations(AnnotationArray* anno) {
+    *(default_annotations_addr()) = anno;
+  }
+
+  int method_annotations_length() const {
+    return has_method_annotations() ? method_annotations()->length() : 0;
+  }
+  int parameter_annotations_length() const {
+    return has_parameter_annotations() ? parameter_annotations()->length() : 0;
+  }
+  int type_annotations_length() const {
+    return has_type_annotations() ? type_annotations()->length() : 0;
+  }
+  int default_annotations_length() const {
+    return has_default_annotations() ? default_annotations()->length() : 0;
+  }
+
   // byte codes
   void    set_code(address code) {
     if (code_size() > 0) {
@@ -409,11 +495,10 @@
 
   // First byte after ConstMethod*
   address constMethod_end() const
-                          { return (address)((oop*)this + _constMethod_size); }
+                          { return (address)((intptr_t*)this + _constMethod_size); }
 
   // Last short in ConstMethod*
-  u2* last_u2_element() const
-                                         { return (u2*)constMethod_end() - 1; }
+  u2* last_u2_element() const;
 
  public:
   // Printing
diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp
index 7d6d36b..11ab856 100644
--- a/hotspot/src/share/vm/oops/cpCache.cpp
+++ b/hotspot/src/share/vm/oops/cpCache.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -402,8 +402,9 @@
 }
 
 
+#if INCLUDE_JVMTI
 // RedefineClasses() API support:
-// If this constantPoolCacheEntry refers to old_method then update it
+// If this ConstantPoolCacheEntry refers to old_method then update it
 // to refer to new_method.
 bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
        Method* new_method, bool * trace_name_printed) {
@@ -461,16 +462,24 @@
   return false;
 }
 
-#ifndef PRODUCT
-bool ConstantPoolCacheEntry::check_no_old_entries() {
+// a constant pool cache entry should never contain old or obsolete methods
+bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
   if (is_vfinal()) {
+    // virtual and final so _f2 contains method ptr instead of vtable index
     Metadata* f2 = (Metadata*)_f2;
-    return (f2->is_valid() && f2->is_method() && !((Method*)f2)->is_old());
-  } else {
-    return (_f1 == NULL || (_f1->is_valid() && _f1->is_method() && !((Method*)_f1)->is_old()));
+    // Return false if _f2 refers to an old or an obsolete method.
+    // _f2 == NULL || !_f2->is_method() are just as unexpected here.
+    return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() &&
+            !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete());
+  } else if (_f1 == NULL ||
+             (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) {
+    // _f1 == NULL || !_f1->is_method() are OK here
+    return true;
   }
+  // return false if _f1 refers to an old or an obsolete method
+  return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() &&
+          !((Method*)_f1)->is_old() && !((Method*)_f1)->is_obsolete());
 }
-#endif
 
 bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) {
   if (!is_method_entry()) {
@@ -503,13 +512,15 @@
   // the method is in the interesting class so the entry is interesting
   return true;
 }
+#endif // INCLUDE_JVMTI
 
 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
   // print separator
   if (index == 0) st->print_cr("                 -------------");
   // print entry
   st->print("%3d  ("PTR_FORMAT")  ", index, (intptr_t)this);
-    st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index());
+  st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(),
+               constant_pool_index());
   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f1);
   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f2);
   st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_flags);
@@ -553,8 +564,9 @@
   }
 }
 
+#if INCLUDE_JVMTI
 // RedefineClasses() API support:
-// If any entry of this constantPoolCache points to any of
+// If any entry of this ConstantPoolCache points to any of
 // old_methods, replace it with the corresponding new_method.
 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods,
                                                      int methods_length, bool * trace_name_printed) {
@@ -573,7 +585,7 @@
       continue;
     }
 
-    // The constantPoolCache contains entries for several different
+    // The ConstantPoolCache contains entries for several different
     // things, but we only care about methods. In fact, we only care
     // about methods in the same class as the one that contains the
     // old_methods. At this point, we have an interesting entry.
@@ -592,17 +604,25 @@
   }
 }
 
-#ifndef PRODUCT
-bool ConstantPoolCache::check_no_old_entries() {
+// the constant pool cache should never contain old or obsolete methods
+bool ConstantPoolCache::check_no_old_or_obsolete_entries() {
   for (int i = 1; i < length(); i++) {
     if (entry_at(i)->is_interesting_method_entry(NULL) &&
-       !entry_at(i)->check_no_old_entries()) {
+        !entry_at(i)->check_no_old_or_obsolete_entries()) {
       return false;
     }
   }
   return true;
 }
-#endif // PRODUCT
+
+void ConstantPoolCache::dump_cache() {
+  for (int i = 1; i < length(); i++) {
+    if (entry_at(i)->is_interesting_method_entry(NULL)) {
+      entry_at(i)->print(tty, i);
+    }
+  }
+}
+#endif // INCLUDE_JVMTI
 
 
 // Printing
diff --git a/hotspot/src/share/vm/oops/cpCache.hpp b/hotspot/src/share/vm/oops/cpCache.hpp
index 90308e4..c1e058d 100644
--- a/hotspot/src/share/vm/oops/cpCache.hpp
+++ b/hotspot/src/share/vm/oops/cpCache.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -337,16 +337,18 @@
   static ByteSize f2_offset()                    { return byte_offset_of(ConstantPoolCacheEntry, _f2); }
   static ByteSize flags_offset()                 { return byte_offset_of(ConstantPoolCacheEntry, _flags); }
 
+#if INCLUDE_JVMTI
   // RedefineClasses() API support:
-  // If this constantPoolCacheEntry refers to old_method then update it
+  // If this ConstantPoolCacheEntry refers to old_method then update it
   // to refer to new_method.
   // trace_name_printed is set to true if the current call has
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
   bool adjust_method_entry(Method* old_method, Method* new_method,
          bool * trace_name_printed);
-  NOT_PRODUCT(bool check_no_old_entries();)
+  bool check_no_old_or_obsolete_entries();
   bool is_interesting_method_entry(Klass* k);
+#endif // INCLUDE_JVMTI
 
   // Debugging & Printing
   void print (outputStream* st, int index) const;
@@ -423,15 +425,18 @@
     return (base_offset() + ConstantPoolCacheEntry::size_in_bytes() * index);
   }
 
+#if INCLUDE_JVMTI
   // RedefineClasses() API support:
-  // If any entry of this constantPoolCache points to any of
+  // If any entry of this ConstantPoolCache points to any of
   // old_methods, replace it with the corresponding new_method.
   // trace_name_printed is set to true if the current call has
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
   void adjust_method_entries(Method** old_methods, Method** new_methods,
                              int methods_length, bool * trace_name_printed);
-  NOT_PRODUCT(bool check_no_old_entries();)
+  bool check_no_old_or_obsolete_entries();
+  void dump_cache();
+#endif // INCLUDE_JVMTI
 
   // Deallocate - no fields to deallocate
   DEBUG_ONLY(bool on_stack() { return false; })
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 4af6e32..f492b89 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -166,20 +166,19 @@
 volatile int InstanceKlass::_total_instanceKlass_count = 0;
 
 Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data,
-                                                int vtable_len,
-                                                int itable_len,
-                                                int static_field_size,
-                                                int nonstatic_oop_map_size,
-                                                ReferenceType rt,
-                                                AccessFlags access_flags,
-                                                Symbol* name,
+                                              int vtable_len,
+                                              int itable_len,
+                                              int static_field_size,
+                                              int nonstatic_oop_map_size,
+                                              ReferenceType rt,
+                                              AccessFlags access_flags,
+                                              Symbol* name,
                                               Klass* super_klass,
-                                                KlassHandle host_klass,
-                                                TRAPS) {
+                                              bool is_anonymous,
+                                              TRAPS) {
 
   int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
-                                 access_flags.is_interface(),
-                                 !host_klass.is_null());
+                                 access_flags.is_interface(), is_anonymous);
 
   // Allocation
   InstanceKlass* ik;
@@ -187,25 +186,25 @@
     if (name == vmSymbols::java_lang_Class()) {
       ik = new (loader_data, size, THREAD) InstanceMirrorKlass(
         vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
-        access_flags, !host_klass.is_null());
+        access_flags, is_anonymous);
     } else if (name == vmSymbols::java_lang_ClassLoader() ||
           (SystemDictionary::ClassLoader_klass_loaded() &&
           super_klass != NULL &&
           super_klass->is_subtype_of(SystemDictionary::ClassLoader_klass()))) {
       ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(
         vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
-        access_flags, !host_klass.is_null());
+        access_flags, is_anonymous);
     } else {
       // normal class
       ik = new (loader_data, size, THREAD) InstanceKlass(
         vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
-        access_flags, !host_klass.is_null());
+        access_flags, is_anonymous);
     }
   } else {
     // reference klass
     ik = new (loader_data, size, THREAD) InstanceRefKlass(
         vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt,
-        access_flags, !host_klass.is_null());
+        access_flags, is_anonymous);
   }
 
   Atomic::inc(&_total_instanceKlass_count);
@@ -2793,7 +2792,10 @@
     st->print("%s", source_debug_extension());
     st->cr();
   }
-  st->print(BULLET"annotations:       "); annotations()->print_value_on(st); st->cr();
+  st->print(BULLET"class annotations:       "); class_annotations()->print_value_on(st); st->cr();
+  st->print(BULLET"class type annotations:  "); class_type_annotations()->print_value_on(st); st->cr();
+  st->print(BULLET"field annotations:       "); fields_annotations()->print_value_on(st); st->cr();
+  st->print(BULLET"field type annotations:  "); fields_type_annotations()->print_value_on(st); st->cr();
   {
     ResourceMark rm;
     // PreviousVersionInfo objects returned via PreviousVersionWalker
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 025da12..600cb56 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -155,8 +155,8 @@
                                           ReferenceType rt,
                                           AccessFlags access_flags,
                                           Symbol* name,
-                                        Klass* super_klass,
-                                          KlassHandle host_klass,
+                                          Klass* super_klass,
+                                          bool is_anonymous,
                                           TRAPS);
 
   InstanceKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
@@ -679,19 +679,19 @@
   // annotations support
   Annotations* annotations() const          { return _annotations; }
   void set_annotations(Annotations* anno)   { _annotations = anno; }
+
   AnnotationArray* class_annotations() const {
-    if (annotations() == NULL) return NULL;
-    return annotations()->class_annotations();
+    return (_annotations != NULL) ? _annotations->class_annotations() : NULL;
   }
   Array<AnnotationArray*>* fields_annotations() const {
-    if (annotations() == NULL) return NULL;
-    return annotations()->fields_annotations();
+    return (_annotations != NULL) ? _annotations->fields_annotations() : NULL;
   }
-  Annotations* type_annotations() const {
-    if (annotations() == NULL) return NULL;
-    return annotations()->type_annotations();
+  AnnotationArray* class_type_annotations() const {
+    return (_annotations != NULL) ? _annotations->class_type_annotations() : NULL;
   }
-
+  Array<AnnotationArray*>* fields_type_annotations() const {
+    return (_annotations != NULL) ? _annotations->fields_type_annotations() : NULL;
+  }
   // allocation
   instanceOop allocate_instance(TRAPS);
 
@@ -810,6 +810,7 @@
 
   // Sizing (in words)
   static int header_size()            { return align_object_offset(sizeof(InstanceKlass)/HeapWordSize); }
+
   static int size(int vtable_length, int itable_length,
                   int nonstatic_oop_map_size,
                   bool is_interface, bool is_anonymous) {
@@ -847,10 +848,14 @@
     return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length()));
   }
 
+  Klass** end_of_nonstatic_oop_maps() const {
+    return (Klass**)(start_of_nonstatic_oop_maps() +
+                     nonstatic_oop_map_count());
+  }
+
   Klass** adr_implementor() const {
     if (is_interface()) {
-      return (Klass**)(start_of_nonstatic_oop_maps() +
-                    nonstatic_oop_map_count());
+      return (Klass**)end_of_nonstatic_oop_maps();
     } else {
       return NULL;
     }
@@ -862,8 +867,7 @@
       if (adr_impl != NULL) {
         return adr_impl + 1;
       } else {
-        return (Klass**)(start_of_nonstatic_oop_maps() +
-                      nonstatic_oop_map_count());
+        return end_of_nonstatic_oop_maps();
       }
     } else {
       return NULL;
diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp
index f8e4d02..43036e7 100644
--- a/hotspot/src/share/vm/oops/klassVtable.cpp
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -610,6 +610,7 @@
   Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size());
 }
 
+#if INCLUDE_JVMTI
 void klassVtable::adjust_method_entries(Method** old_methods, Method** new_methods,
                                         int methods_length, bool * trace_name_printed) {
   // search the vtable for uses of either obsolete or EMCP methods
@@ -638,11 +639,39 @@
                                 new_method->name()->as_C_string(),
                                 new_method->signature()->as_C_string()));
         }
+        // cannot 'break' here; see for-loop comment above.
       }
     }
   }
 }
 
+// a vtable should never contain old or obsolete methods
+bool klassVtable::check_no_old_or_obsolete_entries() {
+  for (int i = 0; i < length(); i++) {
+    Method* m = unchecked_method_at(i);
+    if (m != NULL &&
+        (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+void klassVtable::dump_vtable() {
+  tty->print_cr("vtable dump --");
+  for (int i = 0; i < length(); i++) {
+    Method* m = unchecked_method_at(i);
+    if (m != NULL) {
+      tty->print("      (%5d)  ", i);
+      m->access_flags().print_on(tty);
+      tty->print(" --  ");
+      m->print_name(tty);
+      tty->cr();
+    }
+  }
+}
+#endif // INCLUDE_JVMTI
+
 // CDS/RedefineClasses support - clear vtables so they can be reinitialized
 void klassVtable::clear_vtable() {
   for (int i = 0; i < _length; i++) table()[i].clear();
@@ -805,6 +834,7 @@
   }
 }
 
+#if INCLUDE_JVMTI
 void klassItable::adjust_method_entries(Method** old_methods, Method** new_methods,
                                         int methods_length, bool * trace_name_printed) {
   // search the itable for uses of either obsolete or EMCP methods
@@ -833,13 +863,44 @@
             new_method->name()->as_C_string(),
             new_method->signature()->as_C_string()));
         }
-        // Cannot break because there might be another entry for this method
+        // cannot 'break' here; see for-loop comment above.
       }
       ime++;
     }
   }
 }
 
+// an itable should never contain old or obsolete methods
+bool klassItable::check_no_old_or_obsolete_entries() {
+  itableMethodEntry* ime = method_entry(0);
+  for (int i = 0; i < _size_method_table; i++) {
+    Method* m = ime->method();
+    if (m != NULL &&
+        (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) {
+      return false;
+    }
+    ime++;
+  }
+  return true;
+}
+
+void klassItable::dump_itable() {
+  itableMethodEntry* ime = method_entry(0);
+  tty->print_cr("itable dump --");
+  for (int i = 0; i < _size_method_table; i++) {
+    Method* m = ime->method();
+    if (m != NULL) {
+      tty->print("      (%5d)  ", i);
+      m->access_flags().print_on(tty);
+      tty->print(" --  ");
+      m->print_name(tty);
+      tty->cr();
+    }
+    ime++;
+  }
+}
+#endif // INCLUDE_JVMTI
+
 
 // Setup
 class InterfaceVisiterClosure : public StackObj {
@@ -1126,43 +1187,6 @@
   tty->print_cr("%6d bytes total", total);
 }
 
-bool klassVtable::check_no_old_entries() {
-  // Check that there really is no entry
-  for (int i = 0; i < length(); i++) {
-    Method* m = unchecked_method_at(i);
-    if (m != NULL) {
-        if (!m->is_valid() || m->is_old()) {
-            return false;
-        }
-    }
-  }
-  return true;
-}
-
-void klassVtable::dump_vtable() {
-  tty->print_cr("vtable dump --");
-  for (int i = 0; i < length(); i++) {
-    Method* m = unchecked_method_at(i);
-    if (m != NULL) {
-      tty->print("      (%5d)  ", i);
-      m->access_flags().print_on(tty);
-      tty->print(" --  ");
-      m->print_name(tty);
-      tty->cr();
-    }
-  }
-}
-
-bool klassItable::check_no_old_entries() {
-  itableMethodEntry* ime = method_entry(0);
-  for(int i = 0; i < _size_method_table; i++) {
-    Method* m = ime->method();
-    if (m != NULL && (!m->is_valid() || m->is_old())) return false;
-    ime++;
-  }
-  return true;
-}
-
 int  klassItable::_total_classes;   // Total no. of classes with itables
 long klassItable::_total_size;      // Total no. of bytes used for itables
 
diff --git a/hotspot/src/share/vm/oops/klassVtable.hpp b/hotspot/src/share/vm/oops/klassVtable.hpp
index c2c0c5c..01495e3 100644
--- a/hotspot/src/share/vm/oops/klassVtable.hpp
+++ b/hotspot/src/share/vm/oops/klassVtable.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -90,6 +90,7 @@
       Array<Method*>* methods, AccessFlags class_flags, Handle classloader,
       Symbol* classname, Array<Klass*>* local_interfaces, TRAPS);
 
+#if INCLUDE_JVMTI
   // RedefineClasses() API support:
   // If any entry of this vtable points to any of old_methods,
   // replace it with the corresponding new_method.
@@ -98,17 +99,15 @@
   // group don't print the klass name.
   void adjust_method_entries(Method** old_methods, Method** new_methods,
                              int methods_length, bool * trace_name_printed);
+  bool check_no_old_or_obsolete_entries();
+  void dump_vtable();
+#endif // INCLUDE_JVMTI
 
   // Debugging code
   void print()                                              PRODUCT_RETURN;
   void verify(outputStream* st, bool force = false);
   static void print_statistics()                            PRODUCT_RETURN;
 
-#ifndef PRODUCT
-  bool check_no_old_entries();
-  void dump_vtable();
-#endif
-
  protected:
   friend class vtableEntry;
  private:
@@ -275,6 +274,7 @@
   // Updates
   void initialize_with_method(Method* m);
 
+#if INCLUDE_JVMTI
   // RedefineClasses() API support:
   // if any entry of this itable points to any of old_methods,
   // replace it with the corresponding new_method.
@@ -283,6 +283,9 @@
   // group don't print the klass name.
   void adjust_method_entries(Method** old_methods, Method** new_methods,
                              int methods_length, bool * trace_name_printed);
+  bool check_no_old_or_obsolete_entries();
+  void dump_itable();
+#endif // INCLUDE_JVMTI
 
   // Setup of itable
   static int compute_itable_size(Array<Klass*>* transitive_interfaces);
@@ -307,11 +310,6 @@
   NOT_PRODUCT(static long _total_size;)      // Total no. of bytes used for itables
 
   static void update_stats(int size) PRODUCT_RETURN NOT_PRODUCT({ _total_classes++; _total_size += size; })
-
- public:
-#ifndef PRODUCT
-  bool check_no_old_entries();
-#endif
 };
 
 #endif // SHARE_VM_OOPS_KLASSVTABLE_HPP
diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index 110148a..bb9a511 100644
--- a/hotspot/src/share/vm/oops/method.cpp
+++ b/hotspot/src/share/vm/oops/method.cpp
@@ -61,24 +61,14 @@
 Method* Method::allocate(ClassLoaderData* loader_data,
                          int byte_code_size,
                          AccessFlags access_flags,
-                         int compressed_line_number_size,
-                         int localvariable_table_length,
-                         int exception_table_length,
-                         int checked_exceptions_length,
-                         int method_parameters_length,
-                         u2  generic_signature_index,
+                         InlineTableSizes* sizes,
                          ConstMethod::MethodType method_type,
                          TRAPS) {
   assert(!access_flags.is_native() || byte_code_size == 0,
          "native methods should not contain byte codes");
   ConstMethod* cm = ConstMethod::allocate(loader_data,
                                           byte_code_size,
-                                          compressed_line_number_size,
-                                          localvariable_table_length,
-                                          exception_table_length,
-                                          checked_exceptions_length,
-                                          method_parameters_length,
-                                          generic_signature_index,
+                                          sizes,
                                           method_type,
                                           CHECK_NULL);
 
@@ -317,14 +307,6 @@
 }
 
 
-void Method::set_interpreter_kind() {
-  int kind = Interpreter::method_kind(this);
-  assert(kind != Interpreter::invalid,
-         "interpreter entry must be valid");
-  set_interpreter_kind(kind);
-}
-
-
 // Attempt to return method oop to original state.  Clear any pointers
 // (to objects outside the shared spaces).  We won't be able to predict
 // where they should point in a new JVM.  Further initialize some
@@ -332,7 +314,6 @@
 
 void Method::remove_unshareable_info() {
   unlink_method();
-  set_interpreter_kind();
 }
 
 
@@ -1045,9 +1026,9 @@
 
   methodHandle m;
   {
+    InlineTableSizes sizes;
     Method* m_oop = Method::allocate(loader_data, 0,
-                                     accessFlags_from(flags_bits),
-                                     0, 0, 0, 0, 0, 0,
+                                     accessFlags_from(flags_bits), &sizes,
                                      ConstMethod::NORMAL, CHECK_(empty));
     m = methodHandle(THREAD, m_oop);
   }
@@ -1096,22 +1077,35 @@
   assert(!m->is_native(), "cannot rewrite native methods");
   // Allocate new Method*
   AccessFlags flags = m->access_flags();
-  u2  generic_signature_index = m->generic_signature_index();
-  int checked_exceptions_len = m->checked_exceptions_length();
-  int localvariable_len = m->localvariable_table_length();
-  int exception_table_len = m->exception_table_length();
-  int method_parameters_len = m->method_parameters_length();
+
+  ConstMethod* cm = m->constMethod();
+  int checked_exceptions_len = cm->checked_exceptions_length();
+  int localvariable_len = cm->localvariable_table_length();
+  int exception_table_len = cm->exception_table_length();
+  int method_parameters_len = cm->method_parameters_length();
+  int method_annotations_len = cm->method_annotations_length();
+  int parameter_annotations_len = cm->parameter_annotations_length();
+  int type_annotations_len = cm->type_annotations_length();
+  int default_annotations_len = cm->default_annotations_length();
+
+  InlineTableSizes sizes(
+      localvariable_len,
+      new_compressed_linenumber_size,
+      exception_table_len,
+      checked_exceptions_len,
+      method_parameters_len,
+      cm->generic_signature_index(),
+      method_annotations_len,
+      parameter_annotations_len,
+      type_annotations_len,
+      default_annotations_len,
+      0);
 
   ClassLoaderData* loader_data = m->method_holder()->class_loader_data();
   Method* newm_oop = Method::allocate(loader_data,
                                       new_code_length,
                                       flags,
-                                      new_compressed_linenumber_size,
-                                      localvariable_len,
-                                      exception_table_len,
-                                      checked_exceptions_len,
-                                      method_parameters_len,
-                                      generic_signature_index,
+                                      &sizes,
                                       m->method_type(),
                                       CHECK_(methodHandle()));
   methodHandle newm (THREAD, newm_oop);
@@ -1311,29 +1305,6 @@
     MethodHandles::print_as_basic_type_signature_on(st, signature(), true);
 }
 
-// This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
-static void reorder_based_on_method_index(Array<Method*>* methods,
-                                          Array<AnnotationArray*>* annotations,
-                                          GrowableArray<AnnotationArray*>* temp_array) {
-  if (annotations == NULL) {
-    return;
-  }
-
-  int length = methods->length();
-  int i;
-  // Copy to temp array
-  temp_array->clear();
-  for (i = 0; i < length; i++) {
-    temp_array->append(annotations->at(i));
-  }
-
-  // Copy back using old method indices
-  for (i = 0; i < length; i++) {
-    Method* m = methods->at(i);
-    annotations->at_put(i, temp_array->at(m->method_idnum()));
-  }
-}
-
 // Comparer for sorting an object array containing
 // Method*s.
 static int method_comparator(Method* a, Method* b) {
@@ -1341,48 +1312,13 @@
 }
 
 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
-void Method::sort_methods(Array<Method*>* methods,
-                                 Array<AnnotationArray*>* methods_annotations,
-                                 Array<AnnotationArray*>* methods_parameter_annotations,
-                                 Array<AnnotationArray*>* methods_default_annotations,
-                                 Array<AnnotationArray*>* methods_type_annotations,
-                                 bool idempotent) {
+void Method::sort_methods(Array<Method*>* methods, bool idempotent) {
   int length = methods->length();
   if (length > 1) {
-    bool do_annotations = false;
-    if (methods_annotations != NULL ||
-        methods_parameter_annotations != NULL ||
-        methods_default_annotations != NULL ||
-        methods_type_annotations != NULL) {
-      do_annotations = true;
-    }
-    if (do_annotations) {
-      // Remember current method ordering so we can reorder annotations
-      for (int i = 0; i < length; i++) {
-        Method* m = methods->at(i);
-        m->set_method_idnum(i);
-      }
-    }
     {
       No_Safepoint_Verifier nsv;
       QuickSort::sort<Method*>(methods->data(), length, method_comparator, idempotent);
     }
-
-    // Sort annotations if necessary
-    assert(methods_annotations == NULL           || methods_annotations->length() == methods->length(), "");
-    assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
-    assert(methods_default_annotations == NULL   || methods_default_annotations->length() == methods->length(), "");
-    assert(methods_type_annotations == NULL   || methods_type_annotations->length() == methods->length(), "");
-    if (do_annotations) {
-      ResourceMark rm;
-      // Allocate temporary storage
-      GrowableArray<AnnotationArray*>* temp_array = new GrowableArray<AnnotationArray*>(length);
-      reorder_based_on_method_index(methods, methods_annotations, temp_array);
-      reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
-      reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
-      reorder_based_on_method_index(methods, methods_type_annotations, temp_array);
-    }
-
     // Reset method ordering
     for (int i = 0; i < length; i++) {
       Method* m = methods->at(i);
@@ -1393,9 +1329,9 @@
 
 
 //-----------------------------------------------------------------------------------
-// Non-product code
+// Non-product code unless JVM/TI needs it
 
-#ifndef PRODUCT
+#if !defined(PRODUCT) || INCLUDE_JVMTI
 class SignatureTypePrinter : public SignatureTypeNames {
  private:
   outputStream* _st;
@@ -1430,8 +1366,13 @@
   sig.print_parameters();
   st->print(")");
 }
+#endif // !PRODUCT || INCLUDE_JVMTI
 
 
+//-----------------------------------------------------------------------------------
+// Non-product code
+
+#ifndef PRODUCT
 void Method::print_codes_on(outputStream* st) const {
   print_codes_on(0, code_size(), st);
 }
diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp
index 339380f..a2d24ebc 100644
--- a/hotspot/src/share/vm/oops/method.hpp
+++ b/hotspot/src/share/vm/oops/method.hpp
@@ -101,6 +101,7 @@
 class AdapterHandlerEntry;
 class MethodData;
 class ConstMethod;
+class InlineTableSizes;
 class KlassSizeStats;
 
 class Method : public Metadata {
@@ -157,12 +158,7 @@
   static Method* allocate(ClassLoaderData* loader_data,
                           int byte_code_size,
                           AccessFlags access_flags,
-                          int compressed_line_number_size,
-                          int localvariable_table_length,
-                          int exception_table_length,
-                          int checked_exceptions_length,
-                          int method_parameters_length,
-                          u2 generic_signature_index,
+                          InlineTableSizes* sizes,
                           ConstMethod::MethodType method_type,
                           TRAPS);
 
@@ -207,33 +203,17 @@
 
   // annotations support
   AnnotationArray* annotations() const           {
-    InstanceKlass* ik = method_holder();
-    if (ik->annotations() == NULL) {
-      return NULL;
-    }
-    return ik->annotations()->get_method_annotations_of(method_idnum());
+    return constMethod()->method_annotations();
   }
   AnnotationArray* parameter_annotations() const {
-    InstanceKlass* ik = method_holder();
-    if (ik->annotations() == NULL) {
-      return NULL;
-    }
-    return ik->annotations()->get_method_parameter_annotations_of(method_idnum());
+    return constMethod()->parameter_annotations();
   }
   AnnotationArray* annotation_default() const    {
-    InstanceKlass* ik = method_holder();
-    if (ik->annotations() == NULL) {
-      return NULL;
-    }
-    return ik->annotations()->get_method_default_annotations_of(method_idnum());
+    return constMethod()->default_annotations();
   }
-  AnnotationArray* type_annotations() const {
-  InstanceKlass* ik = method_holder();
-  Annotations* type_annos = ik->type_annotations();
-  if (type_annos == NULL)
-    return NULL;
-  return type_annos->get_method_annotations_of(method_idnum());
-}
+  AnnotationArray* type_annotations() const      {
+    return constMethod()->type_annotations();
+  }
 
 #ifdef CC_INTERP
   void set_result_index(BasicType type);
@@ -439,13 +419,6 @@
   address interpreter_entry() const              { return _i2i_entry; }
   // Only used when first initialize so we can set _i2i_entry and _from_interpreted_entry
   void set_interpreter_entry(address entry)      { _i2i_entry = entry;  _from_interpreted_entry = entry; }
-  int  interpreter_kind(void) {
-     return constMethod()->interpreter_kind();
-  }
-  void set_interpreter_kind();
-  void set_interpreter_kind(int kind) {
-    constMethod()->set_interpreter_kind(kind);
-  }
 
   // native function (used for native methods only)
   enum {
@@ -800,16 +773,15 @@
   static bool has_unloaded_classes_in_signature(methodHandle m, TRAPS);
 
   // Printing
-  void print_short_name(outputStream* st = tty)  /*PRODUCT_RETURN*/; // prints as klassname::methodname; Exposed so field engineers can debug VM
+  void print_short_name(outputStream* st = tty); // prints as klassname::methodname; Exposed so field engineers can debug VM
+#if INCLUDE_JVMTI
+  void print_name(outputStream* st = tty); // prints as "virtual void foo(int)"; exposed for TraceRedefineClasses
+#else
   void print_name(outputStream* st = tty)        PRODUCT_RETURN; // prints as "virtual void foo(int)"
+#endif
 
   // Helper routine used for method sorting
-  static void sort_methods(Array<Method*>* methods,
-                           Array<AnnotationArray*>* methods_annotations,
-                           Array<AnnotationArray*>* methods_parameter_annotations,
-                           Array<AnnotationArray*>* methods_default_annotations,
-                           Array<AnnotationArray*>* methods_type_annotations,
-                           bool idempotent = false);
+  static void sort_methods(Array<Method*>* methods, bool idempotent = false);
 
   // Deallocation function for redefine classes or if an error occurs
   void deallocate_contents(ClassLoaderData* loader_data);
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
index e189122..43895fc 100644
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
@@ -618,6 +618,9 @@
                                                                             \
   product(intx, LiveNodeCountInliningCutoff, 20000,                         \
           "max number of live nodes in a method")                           \
+                                                                            \
+  diagnostic(bool, OptimizeExpensiveOps, true,                              \
+          "Find best control for expensive operations")                     \
 
 
 C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index ae9d699..4b80483 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -409,6 +409,13 @@
       remove_macro_node(n);
     }
   }
+  // Remove useless expensive node
+  for (int i = C->expensive_count()-1; i >= 0; i--) {
+    Node* n = C->expensive_node(i);
+    if (!useful.member(n)) {
+      remove_expensive_node(n);
+    }
+  }
   // clean up the late inline lists
   remove_useless_late_inlines(&_string_late_inlines, useful);
   remove_useless_late_inlines(&_late_inlines, useful);
@@ -1061,6 +1068,7 @@
   _intrinsics = NULL;
   _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
   _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
+  _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
   register_library_intrinsics();
 }
 
@@ -1927,6 +1935,10 @@
 
   if (failing())  return;
 
+  // No more new expensive nodes will be added to the list from here
+  // so keep only the actual candidates for optimizations.
+  cleanup_expensive_nodes(igvn);
+
   // Perform escape analysis
   if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
     if (has_loops()) {
@@ -3010,6 +3022,15 @@
     return true;
   }
 
+  // Expensive nodes have their control input set to prevent the GVN
+  // from freely commoning them. There's no GVN beyond this point so
+  // no need to keep the control input. We want the expensive nodes to
+  // be freely moved to the least frequent code path by gcm.
+  assert(OptimizeExpensiveOps || expensive_count() == 0, "optimization off but list non empty?");
+  for (int i = 0; i < expensive_count(); i++) {
+    _expensive_nodes->at(i)->set_req(0, NULL);
+  }
+
   Final_Reshape_Counts frc;
 
   // Visit everybody reachable!
@@ -3525,3 +3546,126 @@
     }
   }
 }
+
+int Compile::cmp_expensive_nodes(Node* n1, Node* n2) {
+  if (n1->Opcode() < n2->Opcode())      return -1;
+  else if (n1->Opcode() > n2->Opcode()) return 1;
+
+  assert(n1->req() == n2->req(), err_msg_res("can't compare %s nodes: n1->req() = %d, n2->req() = %d", NodeClassNames[n1->Opcode()], n1->req(), n2->req()));
+  for (uint i = 1; i < n1->req(); i++) {
+    if (n1->in(i) < n2->in(i))      return -1;
+    else if (n1->in(i) > n2->in(i)) return 1;
+  }
+
+  return 0;
+}
+
+int Compile::cmp_expensive_nodes(Node** n1p, Node** n2p) {
+  Node* n1 = *n1p;
+  Node* n2 = *n2p;
+
+  return cmp_expensive_nodes(n1, n2);
+}
+
+void Compile::sort_expensive_nodes() {
+  if (!expensive_nodes_sorted()) {
+    _expensive_nodes->sort(cmp_expensive_nodes);
+  }
+}
+
+bool Compile::expensive_nodes_sorted() const {
+  for (int i = 1; i < _expensive_nodes->length(); i++) {
+    if (cmp_expensive_nodes(_expensive_nodes->adr_at(i), _expensive_nodes->adr_at(i-1)) < 0) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool Compile::should_optimize_expensive_nodes(PhaseIterGVN &igvn) {
+  if (_expensive_nodes->length() == 0) {
+    return false;
+  }
+
+  assert(OptimizeExpensiveOps, "optimization off?");
+
+  // Take this opportunity to remove dead nodes from the list
+  int j = 0;
+  for (int i = 0; i < _expensive_nodes->length(); i++) {
+    Node* n = _expensive_nodes->at(i);
+    if (!n->is_unreachable(igvn)) {
+      assert(n->is_expensive(), "should be expensive");
+      _expensive_nodes->at_put(j, n);
+      j++;
+    }
+  }
+  _expensive_nodes->trunc_to(j);
+
+  // Then sort the list so that similar nodes are next to each other
+  // and check for at least two nodes of identical kind with same data
+  // inputs.
+  sort_expensive_nodes();
+
+  for (int i = 0; i < _expensive_nodes->length()-1; i++) {
+    if (cmp_expensive_nodes(_expensive_nodes->adr_at(i), _expensive_nodes->adr_at(i+1)) == 0) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void Compile::cleanup_expensive_nodes(PhaseIterGVN &igvn) {
+  if (_expensive_nodes->length() == 0) {
+    return;
+  }
+
+  assert(OptimizeExpensiveOps, "optimization off?");
+
+  // Sort to bring similar nodes next to each other and clear the
+  // control input of nodes for which there's only a single copy.
+  sort_expensive_nodes();
+
+  int j = 0;
+  int identical = 0;
+  int i = 0;
+  for (; i < _expensive_nodes->length()-1; i++) {
+    assert(j <= i, "can't write beyond current index");
+    if (_expensive_nodes->at(i)->Opcode() == _expensive_nodes->at(i+1)->Opcode()) {
+      identical++;
+      _expensive_nodes->at_put(j++, _expensive_nodes->at(i));
+      continue;
+    }
+    if (identical > 0) {
+      _expensive_nodes->at_put(j++, _expensive_nodes->at(i));
+      identical = 0;
+    } else {
+      Node* n = _expensive_nodes->at(i);
+      igvn.hash_delete(n);
+      n->set_req(0, NULL);
+      igvn.hash_insert(n);
+    }
+  }
+  if (identical > 0) {
+    _expensive_nodes->at_put(j++, _expensive_nodes->at(i));
+  } else if (_expensive_nodes->length() >= 1) {
+    Node* n = _expensive_nodes->at(i);
+    igvn.hash_delete(n);
+    n->set_req(0, NULL);
+    igvn.hash_insert(n);
+  }
+  _expensive_nodes->trunc_to(j);
+}
+
+void Compile::add_expensive_node(Node * n) {
+  assert(!_expensive_nodes->contains(n), "duplicate entry in expensive list");
+  assert(n->is_expensive(), "expensive nodes with non-null control here only");
+  assert(!n->is_CFG() && !n->is_Mem(), "no cfg or memory nodes here");
+  if (OptimizeExpensiveOps) {
+    _expensive_nodes->append(n);
+  } else {
+    // Clear control input and let IGVN optimize expensive nodes if
+    // OptimizeExpensiveOps is off.
+    n->set_req(0, NULL);
+  }
+}
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index 5848295..2cb12fa 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -314,6 +314,7 @@
   GrowableArray<CallGenerator*>* _intrinsics;   // List of intrinsics.
   GrowableArray<Node*>* _macro_nodes;           // List of nodes which need to be expanded before matching.
   GrowableArray<Node*>* _predicate_opaqs;       // List of Opaque1 nodes for the loop predicates.
+  GrowableArray<Node*>* _expensive_nodes;       // List of nodes that are expensive to compute and that we'd better not let the GVN freely common
   ConnectionGraph*      _congraph;
 #ifndef PRODUCT
   IdealGraphPrinter*    _printer;
@@ -398,6 +399,13 @@
   GrowableArray<PrintInliningBuffer>* _print_inlining_list;
   int _print_inlining;
 
+  // Only keep nodes in the expensive node list that need to be optimized
+  void cleanup_expensive_nodes(PhaseIterGVN &igvn);
+  // Use for sorting expensive nodes to bring similar nodes together
+  static int cmp_expensive_nodes(Node** n1, Node** n2);
+  // Expensive nodes list already sorted?
+  bool expensive_nodes_sorted() const;
+
  public:
 
   outputStream* print_inlining_stream() const {
@@ -573,8 +581,10 @@
 
   int           macro_count()                   { return _macro_nodes->length(); }
   int           predicate_count()               { return _predicate_opaqs->length();}
+  int           expensive_count()               { return _expensive_nodes->length(); }
   Node*         macro_node(int idx)             { return _macro_nodes->at(idx); }
   Node*         predicate_opaque1_node(int idx) { return _predicate_opaqs->at(idx);}
+  Node*         expensive_node(int idx)         { return _expensive_nodes->at(idx); }
   ConnectionGraph* congraph()                   { return _congraph;}
   void set_congraph(ConnectionGraph* congraph)  { _congraph = congraph;}
   void add_macro_node(Node * n) {
@@ -592,6 +602,12 @@
       _predicate_opaqs->remove(n);
     }
   }
+  void add_expensive_node(Node * n);
+  void remove_expensive_node(Node * n) {
+    if (_expensive_nodes->contains(n)) {
+      _expensive_nodes->remove(n);
+    }
+  }
   void add_predicate_opaq(Node * n) {
     assert(!_predicate_opaqs->contains(n), " duplicate entry in predicate opaque1");
     assert(_macro_nodes->contains(n), "should have already been in macro list");
@@ -604,6 +620,13 @@
     return _predicate_opaqs->contains(n);
   }
 
+  // Are there candidate expensive nodes for optimization?
+  bool should_optimize_expensive_nodes(PhaseIterGVN &igvn);
+  // Check whether n1 and n2 are similar
+  static int cmp_expensive_nodes(Node* n1, Node* n2);
+  // Sort expensive nodes to locate similar expensive nodes
+  void sort_expensive_nodes();
+
   // Compilation environment.
   Arena*            comp_arena()                { return &_comp_arena; }
   ciEnv*            env() const                 { return _env; }
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index e3aee70..3969f38 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -1653,7 +1653,7 @@
 // really odd corner cases (+/- Infinity).  Just uncommon-trap them.
 bool LibraryCallKit::inline_exp() {
   Node* arg = round_double_node(argument(0));
-  Node* n   = _gvn.transform(new (C) ExpDNode(0, arg));
+  Node* n   = _gvn.transform(new (C) ExpDNode(C, control(), arg));
 
   finish_pow_exp(n, arg, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
 
@@ -1688,7 +1688,7 @@
 
   if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
     // Short form: skip the fancy tests and just check for NaN result.
-    result = _gvn.transform(new (C) PowDNode(0, x, y));
+    result = _gvn.transform(new (C) PowDNode(C, control(), x, y));
   } else {
     // If this inlining ever returned NaN in the past, include all
     // checks + call to the runtime.
@@ -1715,7 +1715,7 @@
     Node *complex_path = _gvn.transform( new (C) IfTrueNode(if1) );
 
     // Set fast path result
-    Node *fast_result = _gvn.transform( new (C) PowDNode(0, x, y) );
+    Node *fast_result = _gvn.transform( new (C) PowDNode(C, control(), x, y) );
     phi->init_req(3, fast_result);
 
     // Complex path
@@ -1775,7 +1775,7 @@
     // abs(x)
     Node *absx=_gvn.transform( new (C) AbsDNode(x));
     // abs(x)^y
-    Node *absxpowy = _gvn.transform( new (C) PowDNode(0, absx, y) );
+    Node *absxpowy = _gvn.transform( new (C) PowDNode(C, control(), absx, y) );
     // -abs(x)^y
     Node *negabsxpowy = _gvn.transform(new (C) NegDNode (absxpowy));
     // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y)
diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp
index a483f01..6812c62 100644
--- a/hotspot/src/share/vm/opto/loopnode.cpp
+++ b/hotspot/src/share/vm/opto/loopnode.cpp
@@ -88,9 +88,9 @@
   assert( !n->is_Phi() && !n->is_CFG(), "this code only handles data nodes" );
   uint i;
   Node *early;
-  if( n->in(0) ) {
+  if (n->in(0) && !n->is_expensive()) {
     early = n->in(0);
-    if( !early->is_CFG() ) // Might be a non-CFG multi-def
+    if (!early->is_CFG()) // Might be a non-CFG multi-def
       early = get_ctrl(early);        // So treat input as a straight data input
     i = 1;
   } else {
@@ -99,28 +99,28 @@
   }
   uint e_d = dom_depth(early);
   assert( early, "" );
-  for( ; i < n->req(); i++ ) {
+  for (; i < n->req(); i++) {
     Node *cin = get_ctrl(n->in(i));
     assert( cin, "" );
     // Keep deepest dominator depth
     uint c_d = dom_depth(cin);
-    if( c_d > e_d ) {           // Deeper guy?
+    if (c_d > e_d) {           // Deeper guy?
       early = cin;              // Keep deepest found so far
       e_d = c_d;
-    } else if( c_d == e_d &&    // Same depth?
-               early != cin ) { // If not equal, must use slower algorithm
+    } else if (c_d == e_d &&    // Same depth?
+               early != cin) { // If not equal, must use slower algorithm
       // If same depth but not equal, one _must_ dominate the other
       // and we want the deeper (i.e., dominated) guy.
       Node *n1 = early;
       Node *n2 = cin;
-      while( 1 ) {
+      while (1) {
         n1 = idom(n1);          // Walk up until break cycle
         n2 = idom(n2);
-        if( n1 == cin ||        // Walked early up to cin
-            dom_depth(n2) < c_d )
+        if (n1 == cin ||        // Walked early up to cin
+            dom_depth(n2) < c_d)
           break;                // early is deeper; keep him
-        if( n2 == early ||      // Walked cin up to early
-            dom_depth(n1) < c_d ) {
+        if (n2 == early ||      // Walked cin up to early
+            dom_depth(n1) < c_d) {
           early = cin;          // cin is deeper; keep him
           break;
         }
@@ -132,9 +132,108 @@
   // Return earliest legal location
   assert(early == find_non_split_ctrl(early), "unexpected early control");
 
+  if (n->is_expensive()) {
+    assert(n->in(0), "should have control input");
+    early = get_early_ctrl_for_expensive(n, early);
+  }
+
   return early;
 }
 
+//------------------------------get_early_ctrl_for_expensive---------------------------------
+// Move node up the dominator tree as high as legal while still beneficial
+Node *PhaseIdealLoop::get_early_ctrl_for_expensive(Node *n, Node* earliest) {
+  assert(n->in(0) && n->is_expensive(), "expensive node with control input here");
+  assert(OptimizeExpensiveOps, "optimization off?");
+
+  Node* ctl = n->in(0);
+  assert(ctl->is_CFG(), "expensive input 0 must be cfg");
+  uint min_dom_depth = dom_depth(earliest);
+#ifdef ASSERT
+  if (!is_dominator(ctl, earliest) && !is_dominator(earliest, ctl)) {
+    dump_bad_graph("Bad graph detected in get_early_ctrl_for_expensive", n, earliest, ctl);
+    assert(false, "Bad graph detected in get_early_ctrl_for_expensive");
+  }
+#endif
+  if (dom_depth(ctl) < min_dom_depth) {
+    return earliest;
+  }
+
+  while (1) {
+    Node *next = ctl;
+    // Moving the node out of a loop on the projection of a If
+    // confuses loop predication. So once we hit a Loop in a If branch
+    // that doesn't branch to an UNC, we stop. The code that process
+    // expensive nodes will notice the loop and skip over it to try to
+    // move the node further up.
+    if (ctl->is_CountedLoop() && ctl->in(1) != NULL && ctl->in(1)->in(0) != NULL && ctl->in(1)->in(0)->is_If()) {
+      if (!is_uncommon_trap_if_pattern(ctl->in(1)->as_Proj(), Deoptimization::Reason_none)) {
+        break;
+      }
+      next = idom(ctl->in(1)->in(0));
+    } else if (ctl->is_Proj()) {
+      // We only move it up along a projection if the projection is
+      // the single control projection for its parent: same code path,
+      // if it's a If with UNC or fallthrough of a call.
+      Node* parent_ctl = ctl->in(0);
+      if (parent_ctl == NULL) {
+        break;
+      } else if (parent_ctl->is_CountedLoopEnd() && parent_ctl->as_CountedLoopEnd()->loopnode() != NULL) {
+        next = parent_ctl->as_CountedLoopEnd()->loopnode()->init_control();
+      } else if (parent_ctl->is_If()) {
+        if (!is_uncommon_trap_if_pattern(ctl->as_Proj(), Deoptimization::Reason_none)) {
+          break;
+        }
+        assert(idom(ctl) == parent_ctl, "strange");
+        next = idom(parent_ctl);
+      } else if (ctl->is_CatchProj()) {
+        if (ctl->as_Proj()->_con != CatchProjNode::fall_through_index) {
+          break;
+        }
+        assert(parent_ctl->in(0)->in(0)->is_Call(), "strange graph");
+        next = parent_ctl->in(0)->in(0)->in(0);
+      } else {
+        // Check if parent control has a single projection (this
+        // control is the only possible successor of the parent
+        // control). If so, we can try to move the node above the
+        // parent control.
+        int nb_ctl_proj = 0;
+        for (DUIterator_Fast imax, i = parent_ctl->fast_outs(imax); i < imax; i++) {
+          Node *p = parent_ctl->fast_out(i);
+          if (p->is_Proj() && p->is_CFG()) {
+            nb_ctl_proj++;
+            if (nb_ctl_proj > 1) {
+              break;
+            }
+          }
+        }
+
+        if (nb_ctl_proj > 1) {
+          break;
+        }
+        assert(parent_ctl->is_Start() || parent_ctl->is_MemBar() || parent_ctl->is_Call(), "unexpected node");
+        assert(idom(ctl) == parent_ctl, "strange");
+        next = idom(parent_ctl);
+      }
+    } else {
+      next = idom(ctl);
+    }
+    if (next->is_Root() || next->is_Start() || dom_depth(next) < min_dom_depth) {
+      break;
+    }
+    ctl = next;
+  }
+
+  if (ctl != n->in(0)) {
+    _igvn.hash_delete(n);
+    n->set_req(0, ctl);
+    _igvn.hash_insert(n);
+  }
+
+  return ctl;
+}
+
+
 //------------------------------set_early_ctrl---------------------------------
 // Set earliest legal control
 void PhaseIdealLoop::set_early_ctrl( Node *n ) {
@@ -1892,6 +1991,98 @@
   }
 }
 
+//------------------------process_expensive_nodes-----------------------------
+// Expensive nodes have their control input set to prevent the GVN
+// from commoning them and as a result forcing the resulting node to
+// be in a more frequent path. Use CFG information here, to change the
+// control inputs so that some expensive nodes can be commoned while
+// not executed more frequently.
+bool PhaseIdealLoop::process_expensive_nodes() {
+  assert(OptimizeExpensiveOps, "optimization off?");
+
+  // Sort nodes to bring similar nodes together
+  C->sort_expensive_nodes();
+
+  bool progress = false;
+
+  for (int i = 0; i < C->expensive_count(); ) {
+    Node* n = C->expensive_node(i);
+    int start = i;
+    // Find nodes similar to n
+    i++;
+    for (; i < C->expensive_count() && Compile::cmp_expensive_nodes(n, C->expensive_node(i)) == 0; i++);
+    int end = i;
+    // And compare them two by two
+    for (int j = start; j < end; j++) {
+      Node* n1 = C->expensive_node(j);
+      if (is_node_unreachable(n1)) {
+        continue;
+      }
+      for (int k = j+1; k < end; k++) {
+        Node* n2 = C->expensive_node(k);
+        if (is_node_unreachable(n2)) {
+          continue;
+        }
+
+        assert(n1 != n2, "should be pair of nodes");
+
+        Node* c1 = n1->in(0);
+        Node* c2 = n2->in(0);
+
+        Node* parent_c1 = c1;
+        Node* parent_c2 = c2;
+
+        // The call to get_early_ctrl_for_expensive() moves the
+        // expensive nodes up but stops at loops that are in a if
+        // branch. See whether we can exit the loop and move above the
+        // If.
+        if (c1->is_Loop()) {
+          parent_c1 = c1->in(1);
+        }
+        if (c2->is_Loop()) {
+          parent_c2 = c2->in(1);
+        }
+
+        if (parent_c1 == parent_c2) {
+          _igvn._worklist.push(n1);
+          _igvn._worklist.push(n2);
+          continue;
+        }
+
+        // Look for identical expensive node up the dominator chain.
+        if (is_dominator(c1, c2)) {
+          c2 = c1;
+        } else if (is_dominator(c2, c1)) {
+          c1 = c2;
+        } else if (parent_c1->is_Proj() && parent_c1->in(0)->is_If() &&
+                   parent_c2->is_Proj() && parent_c1->in(0) == parent_c2->in(0)) {
+          // Both branches have the same expensive node so move it up
+          // before the if.
+          c1 = c2 = idom(parent_c1->in(0));
+        }
+        // Do the actual moves
+        if (n1->in(0) != c1) {
+          _igvn.hash_delete(n1);
+          n1->set_req(0, c1);
+          _igvn.hash_insert(n1);
+          _igvn._worklist.push(n1);
+          progress = true;
+        }
+        if (n2->in(0) != c2) {
+          _igvn.hash_delete(n2);
+          n2->set_req(0, c2);
+          _igvn.hash_insert(n2);
+          _igvn._worklist.push(n2);
+          progress = true;
+        }
+      }
+    }
+  }
+
+  return progress;
+}
+
+
 //=============================================================================
 //----------------------------build_and_optimize-------------------------------
 // Create a PhaseLoop.  Build the ideal Loop tree.  Map each Ideal Node to
@@ -1960,7 +2151,9 @@
   }
 
   // Nothing to do, so get out
-  if( !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only ) {
+  bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only;
+  bool do_expensive_nodes = C->should_optimize_expensive_nodes(_igvn);
+  if (stop_early && !do_expensive_nodes) {
     _igvn.optimize();           // Cleanup NeverBranches
     return;
   }
@@ -2058,6 +2251,21 @@
     return;
   }
 
+  if (stop_early) {
+    assert(do_expensive_nodes, "why are we here?");
+    if (process_expensive_nodes()) {
+      // If we made some progress when processing expensive nodes then
+      // the IGVN may modify the graph in a way that will allow us to
+      // make some more progress: we need to try processing expensive
+      // nodes again.
+      C->set_major_progress();
+    }
+
+    _igvn.optimize();
+
+    return;
+  }
+
   // Some parser-inserted loop predicates could never be used by loop
   // predication or they were moved away from loop during some optimizations.
   // For example, peeling. Eliminate them before next loop optimizations.
@@ -2120,6 +2328,10 @@
     NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); );
   }
 
+  if (!C->major_progress() && do_expensive_nodes && process_expensive_nodes()) {
+    C->set_major_progress();
+  }
+
   // Perform loop predication before iteration splitting
   if (C->has_loops() && !C->major_progress() && (C->predicate_count() > 0)) {
     _ltree_root->_child->loop_predication(this);
@@ -3299,7 +3511,7 @@
 #ifdef ASSERT
     if (legal->is_Start() && !early->is_Root()) {
       // Bad graph. Print idom path and fail.
-      dump_bad_graph(n, early, LCA);
+      dump_bad_graph("Bad graph detected in build_loop_late", n, early, LCA);
       assert(false, "Bad graph detected in build_loop_late");
     }
 #endif
@@ -3350,8 +3562,8 @@
 }
 
 #ifdef ASSERT
-void PhaseIdealLoop::dump_bad_graph(Node* n, Node* early, Node* LCA) {
-  tty->print_cr( "Bad graph detected in build_loop_late");
+void PhaseIdealLoop::dump_bad_graph(const char* msg, Node* n, Node* early, Node* LCA) {
+  tty->print_cr(msg);
   tty->print("n: "); n->dump();
   tty->print("early(n): "); early->dump();
   if (n->in(0) != NULL  && !n->in(0)->is_top() &&
diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp
index 42096c0..104d7b7 100644
--- a/hotspot/src/share/vm/opto/loopnode.hpp
+++ b/hotspot/src/share/vm/opto/loopnode.hpp
@@ -263,9 +263,18 @@
   bool stride_is_con() const        { Node *tmp = stride  (); return (tmp != NULL && tmp->is_Con()); }
   BoolTest::mask test_trip() const  { return in(TestValue)->as_Bool()->_test._test; }
   CountedLoopNode *loopnode() const {
+    // The CountedLoopNode that goes with this CountedLoopEndNode may
+    // have been optimized out by the IGVN so be cautious with the
+    // pattern matching on the graph
+    if (phi() == NULL) {
+      return NULL;
+    }
     Node *ln = phi()->in(0);
-    assert( ln->Opcode() == Op_CountedLoop, "malformed loop" );
-    return (CountedLoopNode*)ln; }
+    if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) {
+      return (CountedLoopNode*)ln;
+    }
+    return NULL;
+  }
 
 #ifndef PRODUCT
   virtual void dump_spec(outputStream *st) const;
@@ -598,6 +607,7 @@
   // check if transform created new nodes that need _ctrl recorded
   Node *get_late_ctrl( Node *n, Node *early );
   Node *get_early_ctrl( Node *n );
+  Node *get_early_ctrl_for_expensive(Node *n, Node* earliest);
   void set_early_ctrl( Node *n );
   void set_subtree_ctrl( Node *root );
   void set_ctrl( Node *n, Node *ctrl ) {
@@ -905,6 +915,16 @@
   void collect_potentially_useful_predicates(IdealLoopTree *loop, Unique_Node_List &predicate_opaque1);
   void eliminate_useless_predicates();
 
+  // Change the control input of expensive nodes to allow commoning by
+  // IGVN when it is guaranteed to not result in a more frequent
+  // execution of the expensive node. Return true if progress.
+  bool process_expensive_nodes();
+
+  // Check whether node has become unreachable
+  bool is_node_unreachable(Node *n) const {
+    return !has_node(n) || n->is_unreachable(_igvn);
+  }
+
   // Eliminate range-checks and other trip-counter vs loop-invariant tests.
   void do_range_check( IdealLoopTree *loop, Node_List &old_new );
 
@@ -1043,7 +1063,7 @@
   void register_new_node( Node *n, Node *blk );
 
 #ifdef ASSERT
-void dump_bad_graph(Node* n, Node* early, Node* LCA);
+  void dump_bad_graph(const char* msg, Node* n, Node* early, Node* LCA);
 #endif
 
 #ifndef PRODUCT
diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp
index 16157f6..5ec7ddd 100644
--- a/hotspot/src/share/vm/opto/node.cpp
+++ b/hotspot/src/share/vm/opto/node.cpp
@@ -493,6 +493,8 @@
   }
   if (is_macro())
     compile->add_macro_node(n);
+  if (is_expensive())
+    compile->add_expensive_node(n);
 
   n->set_idx(compile->next_unique()); // Get new unique index as well
   debug_only( n->verify_construction() );
@@ -616,6 +618,9 @@
   if (is_macro()) {
     compile->remove_macro_node(this);
   }
+  if (is_expensive()) {
+    compile->remove_expensive_node(this);
+  }
 #ifdef ASSERT
   // We will not actually delete the storage, but we'll make the node unusable.
   *(address*)this = badAddress;  // smash the C++ vtbl, probably
@@ -689,6 +694,13 @@
 }
 #endif
 
+
+//------------------------------is_unreachable---------------------------------
+bool Node::is_unreachable(PhaseIterGVN &igvn) const {
+  assert(!is_Mach(), "doesn't work with MachNodes");
+  return outcnt() == 0 || igvn.type(this) == Type::TOP || in(0)->is_top();
+}
+
 //------------------------------add_req----------------------------------------
 // Add a new required input at the end
 void Node::add_req( Node *n ) {
@@ -1246,6 +1258,9 @@
       if (dead->is_macro()) {
         igvn->C->remove_macro_node(dead);
       }
+      if (dead->is_expensive()) {
+        igvn->C->remove_expensive_node(dead);
+      }
       // Kill all inputs to the dead guy
       for (uint i=0; i < dead->req(); i++) {
         Node *n = dead->in(i);      // Get input to dead guy
diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp
index 0dafb00..f8f2c24 100644
--- a/hotspot/src/share/vm/opto/node.hpp
+++ b/hotspot/src/share/vm/opto/node.hpp
@@ -378,6 +378,8 @@
   bool is_dead() const;
 #define is_not_dead(n) ((n) == NULL || !VerifyIterativeGVN || !((n)->is_dead()))
 #endif
+  // Check whether node has become unreachable
+  bool is_unreachable(PhaseIterGVN &igvn) const;
 
   // Set a required input edge, also updates corresponding output edge
   void add_req( Node *n ); // Append a NEW required input
@@ -646,7 +648,8 @@
     Flag_may_be_short_branch = Flag_is_dead_loop_safe << 1,
     Flag_avoid_back_to_back  = Flag_may_be_short_branch << 1,
     Flag_has_call            = Flag_avoid_back_to_back << 1,
-    _max_flags = (Flag_has_call << 1) - 1 // allow flags combination
+    Flag_is_expensive        = Flag_has_call << 1,
+    _max_flags = (Flag_is_expensive << 1) - 1 // allow flags combination
   };
 
 private:
@@ -819,6 +822,8 @@
 
   // The node is a "macro" node which needs to be expanded before matching
   bool is_macro() const { return (_flags & Flag_is_macro) != 0; }
+  // The node is expensive: the best control is set during loop opts
+  bool is_expensive() const { return (_flags & Flag_is_expensive) != 0 && in(0) != NULL; }
 
 //----------------- Optimization
 
diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp
index 7feb0fa..130efbe 100644
--- a/hotspot/src/share/vm/opto/phaseX.cpp
+++ b/hotspot/src/share/vm/opto/phaseX.cpp
@@ -1203,6 +1203,9 @@
         if (dead->is_macro()) {
           C->remove_macro_node(dead);
         }
+        if (dead->is_expensive()) {
+          C->remove_expensive_node(dead);
+        }
 
         if (recurse) {
           continue;
diff --git a/hotspot/src/share/vm/opto/regmask.cpp b/hotspot/src/share/vm/opto/regmask.cpp
index f286a87..9e9bac6 100644
--- a/hotspot/src/share/vm/opto/regmask.cpp
+++ b/hotspot/src/share/vm/opto/regmask.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -241,7 +241,8 @@
       } else {                  // Else its a split-pair case
         if( bit != _A[i] ) return false; // Found many bits, so fail
         i++;                    // Skip iteration forward
-        if( _A[i] != 1 ) return false; // Require 1 lo bit in next word
+        if( i >= RM_SIZE || _A[i] != 1 )
+          return false; // Require 1 lo bit in next word
       }
     }
   }
@@ -254,7 +255,7 @@
 // Find the lowest-numbered register set in the mask.  Return the
 // HIGHEST register number in the set, or BAD if no sets.
 // Works also for size 1.
-OptoReg::Name RegMask::find_first_set(int size) const {
+OptoReg::Name RegMask::find_first_set(const int size) const {
   verify_sets(size);
   for (int i = 0; i < RM_SIZE; i++) {
     if (_A[i]) {                // Found some bits
@@ -268,7 +269,7 @@
 
 //------------------------------clear_to_sets----------------------------------
 // Clear out partial bits; leave only aligned adjacent bit pairs
-void RegMask::clear_to_sets(int size) {
+void RegMask::clear_to_sets(const int size) {
   if (size == 1) return;
   assert(2 <= size && size <= 8, "update low bits table");
   assert(is_power_of_2(size), "sanity");
@@ -293,7 +294,7 @@
 
 //------------------------------smear_to_sets----------------------------------
 // Smear out partial bits to aligned adjacent bit sets
-void RegMask::smear_to_sets(int size) {
+void RegMask::smear_to_sets(const int size) {
   if (size == 1) return;
   assert(2 <= size && size <= 8, "update low bits table");
   assert(is_power_of_2(size), "sanity");
@@ -318,7 +319,7 @@
 }
 
 //------------------------------is_aligned_set--------------------------------
-bool RegMask::is_aligned_sets(int size) const {
+bool RegMask::is_aligned_sets(const int size) const {
   if (size == 1) return true;
   assert(2 <= size && size <= 8, "update low bits table");
   assert(is_power_of_2(size), "sanity");
@@ -344,7 +345,7 @@
 //------------------------------is_bound_set-----------------------------------
 // Return TRUE if the mask contains one adjacent set of bits and no other bits.
 // Works also for size 1.
-int RegMask::is_bound_set(int size) const {
+int RegMask::is_bound_set(const int size) const {
   if( is_AllStack() ) return false;
   assert(1 <= size && size <= 8, "update low bits table");
   int bit = -1;                 // Set to hold the one bit allowed
@@ -352,7 +353,7 @@
     if (_A[i] ) {               // Found some bits
       if (bit != -1)
        return false;            // Already had bits, so fail
-      bit = _A[i] & -_A[i];     // Extract 1 bit from mask
+      bit = _A[i] & -_A[i];     // Extract low bit from mask
       int hi_bit = bit << (size-1); // high bit
       if (hi_bit != 0) {        // Bit set stays in same word?
         int set = hi_bit + ((hi_bit-1) & ~(bit-1));
@@ -362,12 +363,12 @@
         if (((-1) & ~(bit-1)) != _A[i])
           return false;         // Found many bits, so fail
         i++;                    // Skip iteration forward and check high part
-        assert(size <= 8, "update next code");
         // The lower 24 bits should be 0 since it is split case and size <= 8.
         int set = bit>>24;
         set = set & -set; // Remove sign extension.
         set = (((set << size) - 1) >> 8);
-        if (_A[i] != set) return false; // Require 1 lo bit in next word
+        if (i >= RM_SIZE || _A[i] != set)
+          return false; // Require expected low bits in next word
       }
     }
   }
diff --git a/hotspot/src/share/vm/opto/regmask.hpp b/hotspot/src/share/vm/opto/regmask.hpp
index 7e3376b..7171ceb 100644
--- a/hotspot/src/share/vm/opto/regmask.hpp
+++ b/hotspot/src/share/vm/opto/regmask.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -225,22 +225,22 @@
   // Find the lowest-numbered register set in the mask.  Return the
   // HIGHEST register number in the set, or BAD if no sets.
   // Assert that the mask contains only bit sets.
-  OptoReg::Name find_first_set(int size) const;
+  OptoReg::Name find_first_set(const int size) const;
 
   // Clear out partial bits; leave only aligned adjacent bit sets of size.
-  void clear_to_sets(int size);
+  void clear_to_sets(const int size);
   // Smear out partial bits to aligned adjacent bit sets.
-  void smear_to_sets(int size);
+  void smear_to_sets(const int size);
   // Verify that the mask contains only aligned adjacent bit sets
   void verify_sets(int size) const { assert(is_aligned_sets(size), "mask is not aligned, adjacent sets"); }
   // Test that the mask contains only aligned adjacent bit sets
-  bool is_aligned_sets(int size) const;
+  bool is_aligned_sets(const int size) const;
 
   // mask is a set of misaligned registers
   bool is_misaligned_set(int size) const { return (int)Size()==size && !is_aligned_sets(size);}
 
   // Test for a single adjacent set
-  int is_bound_set(int size) const;
+  int is_bound_set(const int size) const;
 
   static bool is_vector(uint ireg);
   static int num_registers(uint ireg);
diff --git a/hotspot/src/share/vm/opto/subnode.hpp b/hotspot/src/share/vm/opto/subnode.hpp
index 862519d..c3a31ff 100644
--- a/hotspot/src/share/vm/opto/subnode.hpp
+++ b/hotspot/src/share/vm/opto/subnode.hpp
@@ -456,7 +456,10 @@
 //  Exponentiate a double
 class ExpDNode : public Node {
 public:
-  ExpDNode( Node *c, Node *in1 ) : Node(c, in1) {}
+  ExpDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {
+    init_flags(Flag_is_expensive);
+    C->add_expensive_node(this);
+  }
   virtual int Opcode() const;
   const Type *bottom_type() const { return Type::DOUBLE; }
   virtual uint ideal_reg() const { return Op_RegD; }
@@ -489,7 +492,10 @@
 // Raise a double to a double power
 class PowDNode : public Node {
 public:
-  PowDNode(Node *c, Node *in1, Node *in2  ) : Node(c, in1, in2) {}
+  PowDNode(Compile* C, Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {
+    init_flags(Flag_is_expensive);
+    C->add_expensive_node(this);
+  }
   virtual int Opcode() const;
   const Type *bottom_type() const { return Type::DOUBLE; }
   virtual uint ideal_reg() const { return Op_RegD; }
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index 84ab5f0..1c277b7 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -1573,9 +1573,9 @@
   if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
     Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
     if (k->oop_is_instance()) {
-      Annotations* type_annotations = InstanceKlass::cast(k)->type_annotations();
+      AnnotationArray* type_annotations = InstanceKlass::cast(k)->class_type_annotations();
       if (type_annotations != NULL) {
-        typeArrayOop a = Annotations::make_java_array(type_annotations->class_annotations(), CHECK_NULL);
+        typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);
         return (jbyteArray) JNIHandles::make_local(env, a);
       }
     }
@@ -4528,6 +4528,5 @@
   // consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat
   // counter defined in runtimeService.cpp.
   info->is_attachable = AttachListener::is_attach_supported();
-  info->is_kernel_jvm = 0; // false;
 }
 JVM_END
diff --git a/hotspot/src/share/vm/prims/jvm.h b/hotspot/src/share/vm/prims/jvm.h
index dea46d1..52cef93 100644
--- a/hotspot/src/share/vm/prims/jvm.h
+++ b/hotspot/src/share/vm/prims/jvm.h
@@ -1559,8 +1559,7 @@
      * the new bit is also added in the main/baseline.
      */
     unsigned int is_attachable : 1;
-    unsigned int is_kernel_jvm : 1;
-    unsigned int : 30;
+    unsigned int : 31;
     unsigned int : 32;
     unsigned int : 32;
 } jvm_version_info;
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
index ce1ec56..14cb63c 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
@@ -154,8 +154,15 @@
   // See jvmtiExport.hpp for detailed explanation.
   JvmtiExport::set_has_redefined_a_class();
 
-#ifdef ASSERT
-  SystemDictionary::classes_do(check_class, thread);
+// check_class() is optionally called for product bits, but is
+// always called for non-product bits.
+#ifdef PRODUCT
+  if (RC_TRACE_ENABLED(0x00004000)) {
+#endif
+    RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
+    SystemDictionary::classes_do(check_class, thread);
+#ifdef PRODUCT
+  }
 #endif
 }
 
@@ -485,26 +492,6 @@
 } // end find_or_append_indirect_entry()
 
 
-void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS) {
-  AnnotationArray* save;
-
-  Annotations* sca = scratch_class->annotations();
-  if (sca == NULL) return;
-
-  save = sca->get_method_annotations_of(i);
-  sca->set_method_annotations_of(scratch_class, i, sca->get_method_annotations_of(j), CHECK);
-  sca->set_method_annotations_of(scratch_class, j, save, CHECK);
-
-  save = sca->get_method_parameter_annotations_of(i);
-  sca->set_method_parameter_annotations_of(scratch_class, i, sca->get_method_parameter_annotations_of(j), CHECK);
-  sca->set_method_parameter_annotations_of(scratch_class, j, save, CHECK);
-
-  save = sca->get_method_default_annotations_of(i);
-  sca->set_method_default_annotations_of(scratch_class, i, sca->get_method_default_annotations_of(j), CHECK);
-  sca->set_method_default_annotations_of(scratch_class, j, save, CHECK);
-}
-
-
 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
              instanceKlassHandle the_class,
              instanceKlassHandle scratch_class) {
@@ -686,10 +673,9 @@
             idnum_owner->set_method_idnum(new_num);
           }
           k_new_method->set_method_idnum(old_num);
-          swap_all_method_annotations(old_num, new_num, scratch_class, thread);
-           if (thread->has_pending_exception()) {
-             return JVMTI_ERROR_OUT_OF_MEMORY;
-           }
+          if (thread->has_pending_exception()) {
+            return JVMTI_ERROR_OUT_OF_MEMORY;
+          }
         }
       }
       RC_TRACE(0x00008000, ("Method matched: new: %s [%d] == old: %s [%d]",
@@ -722,7 +708,6 @@
           idnum_owner->set_method_idnum(new_num);
         }
         k_new_method->set_method_idnum(num);
-        swap_all_method_annotations(new_num, num, scratch_class, thread);
         if (thread->has_pending_exception()) {
           return JVMTI_ERROR_OUT_OF_MEMORY;
         }
@@ -1564,9 +1549,9 @@
             bcp, cp_index, new_index));
           // Rewriter::rewrite_method() uses put_native_u2() in this
           // situation because it is reusing the constant pool index
-          // location for a native index into the constantPoolCache.
+          // location for a native index into the ConstantPoolCache.
           // Since we are updating the constant pool index prior to
-          // verification and constantPoolCache initialization, we
+          // verification and ConstantPoolCache initialization, we
           // need to keep the new index in Java byte order.
           Bytes::put_Java_u2(p, new_index);
         }
@@ -1888,10 +1873,7 @@
 bool VM_RedefineClasses::rewrite_cp_refs_in_fields_annotations(
        instanceKlassHandle scratch_class, TRAPS) {
 
-  Annotations* sca = scratch_class->annotations();
-  if (sca == NULL) return true;
-
-  Array<AnnotationArray*>* fields_annotations = sca->fields_annotations();
+  Array<AnnotationArray*>* fields_annotations = scratch_class->fields_annotations();
 
   if (fields_annotations == NULL || fields_annotations->length() == 0) {
     // no fields_annotations so nothing to do
@@ -1926,21 +1908,10 @@
 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_annotations(
        instanceKlassHandle scratch_class, TRAPS) {
 
-  Annotations* sca = scratch_class->annotations();
-  if (sca == NULL) return true;
+  for (int i = 0; i < scratch_class->methods()->length(); i++) {
+    Method* m = scratch_class->methods()->at(i);
+    AnnotationArray* method_annotations = m->constMethod()->method_annotations();
 
-  Array<AnnotationArray*>* methods_annotations = sca->methods_annotations();
-
-  if (methods_annotations == NULL || methods_annotations->length() == 0) {
-    // no methods_annotations so nothing to do
-    return true;
-  }
-
-  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
-    ("methods_annotations length=%d", methods_annotations->length()));
-
-  for (int i = 0; i < methods_annotations->length(); i++) {
-    AnnotationArray* method_annotations = methods_annotations->at(i);
     if (method_annotations == NULL || method_annotations->length() == 0) {
       // this method does not have any annotations so skip it
       continue;
@@ -1976,24 +1947,9 @@
 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_parameter_annotations(
        instanceKlassHandle scratch_class, TRAPS) {
 
-  Annotations* sca = scratch_class->annotations();
-  if (sca == NULL) return true;
-
-  Array<AnnotationArray*>* methods_parameter_annotations =
-    sca->methods_parameter_annotations();
-
-  if (methods_parameter_annotations == NULL
-      || methods_parameter_annotations->length() == 0) {
-    // no methods_parameter_annotations so nothing to do
-    return true;
-  }
-
-  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
-    ("methods_parameter_annotations length=%d",
-    methods_parameter_annotations->length()));
-
-  for (int i = 0; i < methods_parameter_annotations->length(); i++) {
-    AnnotationArray* method_parameter_annotations = methods_parameter_annotations->at(i);
+  for (int i = 0; i < scratch_class->methods()->length(); i++) {
+    Method* m = scratch_class->methods()->at(i);
+    AnnotationArray* method_parameter_annotations = m->constMethod()->parameter_annotations();
     if (method_parameter_annotations == NULL
         || method_parameter_annotations->length() == 0) {
       // this method does not have any parameter annotations so skip it
@@ -2043,24 +1999,9 @@
 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_default_annotations(
        instanceKlassHandle scratch_class, TRAPS) {
 
-  Annotations* sca = scratch_class->annotations();
-  if (sca == NULL) return true;
-
-  Array<AnnotationArray*>* methods_default_annotations =
-    sca->methods_default_annotations();
-
-  if (methods_default_annotations == NULL
-      || methods_default_annotations->length() == 0) {
-    // no methods_default_annotations so nothing to do
-    return true;
-  }
-
-  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
-    ("methods_default_annotations length=%d",
-    methods_default_annotations->length()));
-
-  for (int i = 0; i < methods_default_annotations->length(); i++) {
-    AnnotationArray* method_default_annotations = methods_default_annotations->at(i);
+  for (int i = 0; i < scratch_class->methods()->length(); i++) {
+    Method* m = scratch_class->methods()->at(i);
+    AnnotationArray* method_default_annotations = m->constMethod()->default_annotations();
     if (method_default_annotations == NULL
         || method_default_annotations->length() == 0) {
       // this method does not have any default annotations so skip it
@@ -3065,6 +3006,31 @@
 }
 
 
+void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class,
+                                          instanceKlassHandle scratch_class) {
+  // Since there is currently no rewriting of type annotations indexes
+  // into the CP, we null out type annotations on scratch_class before
+  // we swap annotations with the_class rather than facing the
+  // possibility of shipping annotations with broken indexes to
+  // Java-land.
+  ClassLoaderData* loader_data = scratch_class->class_loader_data();
+  AnnotationArray* new_class_type_annotations = scratch_class->class_type_annotations();
+  if (new_class_type_annotations != NULL) {
+    MetadataFactory::free_array<u1>(loader_data, new_class_type_annotations);
+    scratch_class->annotations()->set_class_type_annotations(NULL);
+  }
+  Array<AnnotationArray*>* new_field_type_annotations = scratch_class->fields_type_annotations();
+  if (new_field_type_annotations != NULL) {
+    Annotations::free_contents(loader_data, new_field_type_annotations);
+    scratch_class->annotations()->set_fields_type_annotations(NULL);
+  }
+
+  // Swap annotation fields values
+  Annotations* old_annotations = the_class->annotations();
+  the_class->set_annotations(scratch_class->annotations());
+  scratch_class->set_annotations(old_annotations);
+}
+
 
 // Install the redefinition of a class:
 //    - house keeping (flushing breakpoints and caches, deoptimizing
@@ -3275,23 +3241,7 @@
     the_class->set_access_flags(flags);
   }
 
-  // Since there is currently no rewriting of type annotations indexes
-  // into the CP, we null out type annotations on scratch_class before
-  // we swap annotations with the_class rather than facing the
-  // possibility of shipping annotations with broken indexes to
-  // Java-land.
-  Annotations* new_annotations = scratch_class->annotations();
-  if (new_annotations != NULL) {
-    Annotations* new_type_annotations = new_annotations->type_annotations();
-    if (new_type_annotations != NULL) {
-      MetadataFactory::free_metadata(scratch_class->class_loader_data(), new_type_annotations);
-      new_annotations->set_type_annotations(NULL);
-    }
-  }
-  // Swap annotation fields values
-  Annotations* old_annotations = the_class->annotations();
-  the_class->set_annotations(scratch_class->annotations());
-  scratch_class->set_annotations(old_annotations);
+  swap_annotations(the_class, scratch_class);
 
   // Replace minor version number of class file
   u2 old_minor_version = the_class->minor_version();
@@ -3371,7 +3321,6 @@
   }
 }
 
-#ifndef PRODUCT
 void VM_RedefineClasses::check_class(Klass* k_oop,
                                      ClassLoaderData* initiating_loader,
                                      TRAPS) {
@@ -3379,82 +3328,110 @@
   if (k->oop_is_instance()) {
     HandleMark hm(THREAD);
     InstanceKlass *ik = (InstanceKlass *) k;
+    bool no_old_methods = true;  // be optimistic
+    ResourceMark rm(THREAD);
 
-    if (ik->vtable_length() > 0) {
-      ResourceMark rm(THREAD);
-      if (!ik->vtable()->check_no_old_entries()) {
-        tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name());
+    // a vtable should never contain old or obsolete methods
+    if (ik->vtable_length() > 0 &&
+        !ik->vtable()->check_no_old_or_obsolete_entries()) {
+      if (RC_TRACE_ENABLED(0x00004000)) {
+        RC_TRACE_WITH_THREAD(0x00004000, THREAD,
+          ("klassVtable::check_no_old_or_obsolete_entries failure"
+           " -- OLD or OBSOLETE method found -- class: %s",
+           ik->signature_name()));
         ik->vtable()->dump_vtable();
-        assert(false, "OLD method found");
       }
+      no_old_methods = false;
     }
-    if (ik->itable_length() > 0) {
-      ResourceMark rm(THREAD);
-      if (!ik->itable()->check_no_old_entries()) {
-        tty->print_cr("klassItable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name());
-        assert(false, "OLD method found");
+
+    // an itable should never contain old or obsolete methods
+    if (ik->itable_length() > 0 &&
+        !ik->itable()->check_no_old_or_obsolete_entries()) {
+      if (RC_TRACE_ENABLED(0x00004000)) {
+        RC_TRACE_WITH_THREAD(0x00004000, THREAD,
+          ("klassItable::check_no_old_or_obsolete_entries failure"
+           " -- OLD or OBSOLETE method found -- class: %s",
+           ik->signature_name()));
+        ik->itable()->dump_itable();
       }
+      no_old_methods = false;
     }
-    // Check that the constant pool cache has no deleted entries.
+
+    // the constant pool cache should never contain old or obsolete methods
     if (ik->constants() != NULL &&
         ik->constants()->cache() != NULL &&
-       !ik->constants()->cache()->check_no_old_entries()) {
-      tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name());
-      assert(false, "OLD method found");
+        !ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
+      if (RC_TRACE_ENABLED(0x00004000)) {
+        RC_TRACE_WITH_THREAD(0x00004000, THREAD,
+          ("cp-cache::check_no_old_or_obsolete_entries failure"
+           " -- OLD or OBSOLETE method found -- class: %s",
+           ik->signature_name()));
+        ik->constants()->cache()->dump_cache();
+      }
+      no_old_methods = false;
+    }
+
+    if (!no_old_methods) {
+      if (RC_TRACE_ENABLED(0x00004000)) {
+        dump_methods();
+      } else {
+        tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
+          "to see more info about the following guarantee() failure.");
+      }
+      guarantee(false, "OLD and/or OBSOLETE method(s) found");
     }
   }
 }
 
 void VM_RedefineClasses::dump_methods() {
-        int j;
-        tty->print_cr("_old_methods --");
-        for (j = 0; j < _old_methods->length(); ++j) {
-          Method* m = _old_methods->at(j);
-          tty->print("%4d  (%5d)  ", j, m->vtable_index());
-          m->access_flags().print_on(tty);
-          tty->print(" --  ");
-          m->print_name(tty);
-          tty->cr();
-        }
-        tty->print_cr("_new_methods --");
-        for (j = 0; j < _new_methods->length(); ++j) {
-          Method* m = _new_methods->at(j);
-          tty->print("%4d  (%5d)  ", j, m->vtable_index());
-          m->access_flags().print_on(tty);
-          tty->print(" --  ");
-          m->print_name(tty);
-          tty->cr();
-        }
-        tty->print_cr("_matching_(old/new)_methods --");
-        for (j = 0; j < _matching_methods_length; ++j) {
-          Method* m = _matching_old_methods[j];
-          tty->print("%4d  (%5d)  ", j, m->vtable_index());
-          m->access_flags().print_on(tty);
-          tty->print(" --  ");
-          m->print_name(tty);
-          tty->cr();
-          m = _matching_new_methods[j];
-          tty->print("      (%5d)  ", m->vtable_index());
-          m->access_flags().print_on(tty);
-          tty->cr();
-        }
-        tty->print_cr("_deleted_methods --");
-        for (j = 0; j < _deleted_methods_length; ++j) {
-          Method* m = _deleted_methods[j];
-          tty->print("%4d  (%5d)  ", j, m->vtable_index());
-          m->access_flags().print_on(tty);
-          tty->print(" --  ");
-          m->print_name(tty);
-          tty->cr();
-        }
-        tty->print_cr("_added_methods --");
-        for (j = 0; j < _added_methods_length; ++j) {
-          Method* m = _added_methods[j];
-          tty->print("%4d  (%5d)  ", j, m->vtable_index());
-          m->access_flags().print_on(tty);
-          tty->print(" --  ");
-          m->print_name(tty);
-          tty->cr();
-        }
+  int j;
+  RC_TRACE(0x00004000, ("_old_methods --"));
+  for (j = 0; j < _old_methods->length(); ++j) {
+    Method* m = _old_methods->at(j);
+    RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
+    m->access_flags().print_on(tty);
+    tty->print(" --  ");
+    m->print_name(tty);
+    tty->cr();
+  }
+  RC_TRACE(0x00004000, ("_new_methods --"));
+  for (j = 0; j < _new_methods->length(); ++j) {
+    Method* m = _new_methods->at(j);
+    RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
+    m->access_flags().print_on(tty);
+    tty->print(" --  ");
+    m->print_name(tty);
+    tty->cr();
+  }
+  RC_TRACE(0x00004000, ("_matching_(old/new)_methods --"));
+  for (j = 0; j < _matching_methods_length; ++j) {
+    Method* m = _matching_old_methods[j];
+    RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
+    m->access_flags().print_on(tty);
+    tty->print(" --  ");
+    m->print_name(tty);
+    tty->cr();
+    m = _matching_new_methods[j];
+    RC_TRACE_NO_CR(0x00004000, ("      (%5d)  ", m->vtable_index()));
+    m->access_flags().print_on(tty);
+    tty->cr();
+  }
+  RC_TRACE(0x00004000, ("_deleted_methods --"));
+  for (j = 0; j < _deleted_methods_length; ++j) {
+    Method* m = _deleted_methods[j];
+    RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
+    m->access_flags().print_on(tty);
+    tty->print(" --  ");
+    m->print_name(tty);
+    tty->cr();
+  }
+  RC_TRACE(0x00004000, ("_added_methods --"));
+  for (j = 0; j < _added_methods_length; ++j) {
+    Method* m = _added_methods[j];
+    RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
+    m->access_flags().print_on(tty);
+    tty->print(" --  ");
+    m->print_name(tty);
+    tty->cr();
+  }
 }
-#endif
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
index d348ed2..d296748 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
@@ -384,11 +384,6 @@
   jvmtiError compare_and_normalize_class_versions(
     instanceKlassHandle the_class, instanceKlassHandle scratch_class);
 
-  // Swap annotations[i] with annotations[j]
-  // Used by compare_and_normalize_class_versions() when normalizing
-  // overloaded methods or changing idnum as when adding or deleting methods.
-  void swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS);
-
   // Figure out which new methods match old methods in name and signature,
   // which methods have been added, and which are no longer present
   void compute_added_deleted_matching_methods();
@@ -417,6 +412,9 @@
   void redefine_single_class(jclass the_jclass,
     Klass* scratch_class_oop, TRAPS);
 
+  void swap_annotations(instanceKlassHandle new_class,
+                        instanceKlassHandle scratch_class);
+
   // Increment the classRedefinedCount field in the specific InstanceKlass
   // and in all direct and indirect subclasses.
   void increment_class_counter(InstanceKlass *ik, TRAPS);
@@ -468,9 +466,9 @@
 
   void flush_dependent_code(instanceKlassHandle k_h, TRAPS);
 
-  static void check_class(Klass* k_oop, ClassLoaderData* initiating_loader, TRAPS) PRODUCT_RETURN;
-
-  static void dump_methods()   PRODUCT_RETURN;
+  static void check_class(Klass* k_oop, ClassLoaderData* initiating_loader,
+                TRAPS);
+  static void dump_methods();
 
  public:
   VM_RedefineClasses(jint class_count,
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp b/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp
index e79534f..878d300 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -54,7 +54,7 @@
 //    0x00000800 |       2048 - previous class breakpoint mgmt
 //    0x00001000 |       4096 - detect calls to obsolete methods
 //    0x00002000 |       8192 - fail a guarantee() in addition to detection
-//    0x00004000 |      16384 - unused
+//    0x00004000 |      16384 - detect old/obsolete methods in metadata
 //    0x00008000 |      32768 - old/new method matching/add/delete
 //    0x00010000 |      65536 - impl details: CP size info
 //    0x00020000 |     131072 - impl details: CP merge pass info
@@ -82,6 +82,13 @@
     tty->print_cr args; \
   } while (0)
 
+#define RC_TRACE_NO_CR(level, args) \
+  if ((TraceRedefineClasses & level) != 0) { \
+    ResourceMark rm; \
+    tty->print("RedefineClasses-0x%x: ", level); \
+    tty->print args; \
+  } while (0)
+
 #define RC_TRACE_WITH_THREAD(level, thread, args) \
   if ((TraceRedefineClasses & level) != 0) { \
     ResourceMark rm(thread); \
diff --git a/hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp b/hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp
index 8efdd9d..ae80864 100644
--- a/hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp
+++ b/hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp
@@ -27,6 +27,6 @@
 #include "prims/jni.h"
 #include "prims/whitebox.hpp"
 
-WB_METHOD_DECLARE WB_ParseCommandLine(JNIEnv* env, jobject o, jstring args, jobjectArray arguments);
+WB_METHOD_DECLARE(jobjectArray) WB_ParseCommandLine(JNIEnv* env, jobject o, jstring args, jobjectArray arguments);
 
 #endif //SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp
index 7bbec83..4758210 100644
--- a/hotspot/src/share/vm/prims/whitebox.cpp
+++ b/hotspot/src/share/vm/prims/whitebox.cpp
@@ -48,6 +48,8 @@
 #include "services/memTracker.hpp"
 #endif // INCLUDE_NMT
 
+#include "compiler/compileBroker.hpp"
+
 bool WhiteBox::_used = false;
 
 WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
@@ -169,6 +171,89 @@
 
 #endif // INCLUDE_NMT
 
+static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
+  assert(method != NULL, "method should not be null");
+  ThreadToNativeFromVM ttn(thread);
+  return env->FromReflectedMethod(method);
+}
+
+WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
+  MutexLockerEx mu(Compile_lock);
+  CodeCache::mark_all_nmethods_for_deoptimization();
+  VM_Deoptimize op;
+  VMThread::execute(&op);
+WB_END
+
+WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  MutexLockerEx mu(Compile_lock);
+  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+  int result = 0;
+  nmethod* code = mh->code();
+  if (code != NULL) {
+    code->mark_for_deoptimization();
+    ++result;
+  }
+  result += CodeCache::mark_for_deoptimization(mh());
+  if (result > 0) {
+    VM_Deoptimize op;
+    VMThread::execute(&op);
+  }
+  return result;
+WB_END
+
+WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  MutexLockerEx mu(Compile_lock);
+  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+  nmethod* code = mh->code();
+  if (code == NULL) {
+    return JNI_FALSE;
+  }
+  return (code->is_alive() && !code->is_marked_for_deoptimization());
+WB_END
+
+WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  MutexLockerEx mu(Compile_lock);
+  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+  return !mh->is_not_compilable();
+WB_END
+
+WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  MutexLockerEx mu(Compile_lock);
+  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+  return mh->queued_for_compilation();
+WB_END
+
+WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+  nmethod* code = mh->code();
+  return (code != NULL ? code->comp_level() : CompLevel_none);
+WB_END
+
+
+WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+  mh->set_not_compilable();
+WB_END
+
+WB_ENTRY(jboolean, WB_SetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
+  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+  bool result = mh->dont_inline();
+  mh->set_dont_inline(value == JNI_TRUE);
+  return result;
+WB_END
+
+WB_ENTRY(jint, WB_GetCompileQueuesSize(JNIEnv* env, jobject o))
+  return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
+         CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
+WB_END
+
 //Some convenience methods to deal with objects from java
 int WhiteBox::offset_for_field(const char* field_name, oop object,
     Symbol* signature_symbol) {
@@ -225,9 +310,9 @@
 static JNINativeMethod methods[] = {
   {CC"getObjectAddress",   CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress  },
   {CC"getHeapOopSize",     CC"()I",                   (void*)&WB_GetHeapOopSize    },
-  {CC"isClassAlive0",       CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive      },
-  {CC "parseCommandLine",
-      CC "(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
+  {CC"isClassAlive0",      CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive      },
+  {CC"parseCommandLine",
+      CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
       (void*) &WB_ParseCommandLine
   },
 #if INCLUDE_ALL_GCS
@@ -241,6 +326,23 @@
   {CC"NMTFreeTestMemory",  CC"()Z",                   (void*)&WB_NMTFreeTestMemory },
   {CC"NMTWaitForDataMerge",CC"()Z",                   (void*)&WB_NMTWaitForDataMerge},
 #endif // INCLUDE_NMT
+  {CC"deoptimizeAll",      CC"()V",                   (void*)&WB_DeoptimizeAll     },
+  {CC"deoptimizeMethod",   CC"(Ljava/lang/reflect/Method;)I",
+                                                      (void*)&WB_DeoptimizeMethod  },
+  {CC"isMethodCompiled",   CC"(Ljava/lang/reflect/Method;)Z",
+                                                      (void*)&WB_IsMethodCompiled  },
+  {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Method;)Z",
+                                                      (void*)&WB_IsMethodCompilable},
+  {CC"isMethodQueuedForCompilation",
+      CC"(Ljava/lang/reflect/Method;)Z",              (void*)&WB_IsMethodQueuedForCompilation},
+  {CC"makeMethodNotCompilable",
+      CC"(Ljava/lang/reflect/Method;)V",              (void*)&WB_MakeMethodNotCompilable},
+  {CC"setDontInlineMethod",
+      CC"(Ljava/lang/reflect/Method;Z)Z",             (void*)&WB_SetDontInlineMethod},
+  {CC"getMethodCompilationLevel",
+      CC"(Ljava/lang/reflect/Method;)I",              (void*)&WB_GetMethodCompilationLevel},
+  {CC"getCompileQueuesSize",
+      CC"()I",                                        (void*)&WB_GetCompileQueuesSize},
 };
 
 #undef CC
diff --git a/hotspot/src/share/vm/prims/whitebox.hpp b/hotspot/src/share/vm/prims/whitebox.hpp
index a5dda9b..a404b84 100644
--- a/hotspot/src/share/vm/prims/whitebox.hpp
+++ b/hotspot/src/share/vm/prims/whitebox.hpp
@@ -34,7 +34,7 @@
 
 #define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
 #define WB_END JNI_END
-#define WB_METHOD_DECLARE extern "C" jobjectArray JNICALL
+#define WB_METHOD_DECLARE(result_type) extern "C" result_type JNICALL
 
 class WhiteBox : public AllStatic {
  private:
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index de596c1..84df1ab 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -1086,7 +1086,7 @@
   }
   // Increase the code cache size - tiered compiles a lot more.
   if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
-    FLAG_SET_DEFAULT(ReservedCodeCacheSize, ReservedCodeCacheSize * 2);
+    FLAG_SET_DEFAULT(ReservedCodeCacheSize, ReservedCodeCacheSize * 5);
   }
 }
 
@@ -1257,7 +1257,7 @@
   // prefer minuscule survivor spaces so as not to waste
   // space for (non-existent) survivors
   if (FLAG_IS_DEFAULT(SurvivorRatio) && MaxTenuringThreshold == 0) {
-    FLAG_SET_ERGO(intx, SurvivorRatio, MAX2((intx)1024, SurvivorRatio));
+    FLAG_SET_ERGO(uintx, SurvivorRatio, MAX2((uintx)1024, SurvivorRatio));
   }
   // If OldPLABSize is set and CMSParPromoteBlocksToClaim is not,
   // set CMSParPromoteBlocksToClaim equal to OldPLABSize.
@@ -1897,6 +1897,24 @@
   // Keeping the heap 100% free is hard ;-) so limit it to 99%.
   MinHeapFreeRatio = MIN2(MinHeapFreeRatio, (uintx) 99);
 
+  // Min/MaxMetaspaceFreeRatio
+  status = status && verify_percentage(MinMetaspaceFreeRatio, "MinMetaspaceFreeRatio");
+  status = status && verify_percentage(MaxMetaspaceFreeRatio, "MaxMetaspaceFreeRatio");
+
+  if (MinMetaspaceFreeRatio > MaxMetaspaceFreeRatio) {
+    jio_fprintf(defaultStream::error_stream(),
+                "MinMetaspaceFreeRatio (%s" UINTX_FORMAT ") must be less than or "
+                "equal to MaxMetaspaceFreeRatio (%s" UINTX_FORMAT ")\n",
+                FLAG_IS_DEFAULT(MinMetaspaceFreeRatio) ? "Default: " : "",
+                MinMetaspaceFreeRatio,
+                FLAG_IS_DEFAULT(MaxMetaspaceFreeRatio) ? "Default: " : "",
+                MaxMetaspaceFreeRatio);
+    status = false;
+  }
+
+  // Trying to keep 100% free is not practical
+  MinMetaspaceFreeRatio = MIN2(MinMetaspaceFreeRatio, (uintx) 99);
+
   if (FullGCALot && FLAG_IS_DEFAULT(MarkSweepAlwaysCompactCount)) {
     MarkSweepAlwaysCompactCount = 1;  // Move objects every gc.
   }
@@ -1904,7 +1922,7 @@
   if (UseParallelOldGC && ParallelOldGCSplitALot) {
     // Settings to encourage splitting.
     if (!FLAG_IS_CMDLINE(NewRatio)) {
-      FLAG_SET_CMDLINE(intx, NewRatio, 2);
+      FLAG_SET_CMDLINE(uintx, NewRatio, 2);
     }
     if (!FLAG_IS_CMDLINE(ScavengeBeforeFullGC)) {
       FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
index 54a225a..23d6794 100644
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -67,13 +67,10 @@
 
 AnnotationArray* fieldDescriptor::type_annotations() const {
   InstanceKlass* ik = field_holder();
-  Annotations* type_annos = ik->type_annotations();
+  Array<AnnotationArray*>* type_annos = ik->fields_type_annotations();
   if (type_annos == NULL)
     return NULL;
-  Array<AnnotationArray*>* md = type_annos->fields_annotations();
-  if (md == NULL)
-    return NULL;
-  return md->at(index());
+  return type_annos->at(index());
 }
 
 constantTag fieldDescriptor::initial_value_tag() const {
diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp
index dd32cb3..9d0b938 100644
--- a/hotspot/src/share/vm/runtime/globals.cpp
+++ b/hotspot/src/share/vm/runtime/globals.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -69,7 +69,10 @@
 }
 
 bool Flag::is_unlocked() const {
-  if (strcmp(kind, "{diagnostic}") == 0) {
+  if (strcmp(kind, "{diagnostic}") == 0 ||
+      strcmp(kind, "{C2 diagnostic}") == 0 ||
+      strcmp(kind, "{ARCH diagnostic}") == 0 ||
+      strcmp(kind, "{Shark diagnostic}") == 0) {
     if (strcmp(name, "EnableInvokeDynamic") == 0 && UnlockExperimentalVMOptions && !UnlockDiagnosticVMOptions) {
       // transitional logic to allow tests to run until they are changed
       static int warned;
@@ -78,7 +81,9 @@
     }
     return UnlockDiagnosticVMOptions;
   } else if (strcmp(kind, "{experimental}") == 0 ||
-             strcmp(kind, "{C2 experimental}") == 0) {
+             strcmp(kind, "{C2 experimental}") == 0 ||
+             strcmp(kind, "{ARCH experimental}") == 0 ||
+             strcmp(kind, "{Shark experimental}") == 0) {
     return UnlockExperimentalVMOptions;
   } else {
     return is_unlocked_ext();
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 7db81d8..8a0be8f 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1802,7 +1802,7 @@
   product(bool, ParallelRefProcBalancingEnabled, true,                      \
           "Enable balancing of reference processing queues")                \
                                                                             \
-  product(intx, CMSTriggerRatio, 80,                                        \
+  product(uintx, CMSTriggerRatio, 80,                                       \
           "Percentage of MinHeapFreeRatio in CMS generation that is "       \
           "allocated before a CMS collection cycle commences")              \
                                                                             \
@@ -1816,7 +1816,7 @@
                                                                             \
   product(uintx, InitiatingHeapOccupancyPercent, 45,                        \
           "Percentage of the (entire) heap occupancy to start a "           \
-          "concurrent GC cycle. It us used by GCs that trigger a "          \
+          "concurrent GC cycle. It is used by GCs that trigger a "          \
           "concurrent GC cycle based on the occupancy of the entire heap, " \
           "not just one of the generations (e.g., G1). A value of 0 "       \
           "denotes 'do constant GC cycles'.")                               \
@@ -2977,10 +2977,10 @@
   product(uintx, TLABWasteIncrement,    4,                                  \
           "Increment allowed waste at slow allocation")                     \
                                                                             \
-  product(intx, SurvivorRatio, 8,                                           \
+  product(uintx, SurvivorRatio, 8,                                          \
           "Ratio of eden/survivor space size")                              \
                                                                             \
-  product(intx, NewRatio, 2,                                                \
+  product(uintx, NewRatio, 2,                                               \
           "Ratio of new/old generation sizes")                              \
                                                                             \
   product_pd(uintx, NewSizeThreadIncrease,                                  \
@@ -3010,10 +3010,16 @@
           "Min change in heap space due to GC (in bytes)")                  \
                                                                             \
   product(uintx, MinMetaspaceExpansion, ScaleForWordSize(256*K),            \
-          "Min expansion of permanent heap (in bytes)")                     \
+          "Min expansion of Metaspace (in bytes)")                          \
+                                                                            \
+  product(uintx, MinMetaspaceFreeRatio,    40,                              \
+          "Min percentage of Metaspace free after GC to avoid expansion")   \
+                                                                            \
+  product(uintx, MaxMetaspaceFreeRatio,    70,                              \
+          "Max percentage of Metaspace free after GC to avoid shrinking")   \
                                                                             \
   product(uintx, MaxMetaspaceExpansion, ScaleForWordSize(4*M),              \
-          "Max expansion of permanent heap without full GC (in bytes)")     \
+          "Max expansion of Metaspace without full GC (in bytes)")          \
                                                                             \
   product(intx, QueuedAllocationWarningCount, 0,                            \
           "Number of times an allocation that queues behind a GC "          \
@@ -3031,7 +3037,7 @@
   product(uintx, InitialTenuringThreshold,    7,                            \
           "Initial value for tenuring threshold")                           \
                                                                             \
-  product(intx, TargetSurvivorRatio,    50,                                 \
+  product(uintx, TargetSurvivorRatio,    50,                                \
           "Desired percentage of survivor space used after scavenge")       \
                                                                             \
   product(uintx, MarkSweepDeadRatio,     5,                                 \
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index 86169fc..d21c2c1 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -366,11 +366,10 @@
   volatile_nonstatic_field(Method,      _from_compiled_entry,                          address)                               \
   volatile_nonstatic_field(Method,      _from_interpreted_entry,                       address)                               \
   volatile_nonstatic_field(ConstMethod, _fingerprint,                                  uint64_t)                              \
-  nonstatic_field(ConstMethod,          _constants,                                    ConstantPool*)                  \
+  nonstatic_field(ConstMethod,          _constants,                                    ConstantPool*)                         \
   nonstatic_field(ConstMethod,          _stackmap_data,                                Array<u1>*)                            \
   nonstatic_field(ConstMethod,          _constMethod_size,                             int)                                   \
-  nonstatic_field(ConstMethod,          _interpreter_kind,                             jbyte)                                 \
-  nonstatic_field(ConstMethod,          _flags,                                        jbyte)                                 \
+  nonstatic_field(ConstMethod,          _flags,                                        u2)                                    \
   nonstatic_field(ConstMethod,          _code_size,                                    u2)                                    \
   nonstatic_field(ConstMethod,          _name_index,                                   u2)                                    \
   nonstatic_field(ConstMethod,          _signature_index,                              u2)                                    \
@@ -2261,14 +2260,18 @@
   declare_constant(Klass::_lh_array_tag_obj_value)                        \
                                                                           \
   /********************************/                                      \
-  /* ConstMethod anon-enum */                                      \
+  /* ConstMethod anon-enum */                                             \
   /********************************/                                      \
                                                                           \
-  declare_constant(ConstMethod::_has_linenumber_table)             \
-  declare_constant(ConstMethod::_has_checked_exceptions)           \
-  declare_constant(ConstMethod::_has_localvariable_table)          \
-  declare_constant(ConstMethod::_has_exception_table)              \
-  declare_constant(ConstMethod::_has_generic_signature)            \
+  declare_constant(ConstMethod::_has_linenumber_table)                    \
+  declare_constant(ConstMethod::_has_checked_exceptions)                  \
+  declare_constant(ConstMethod::_has_localvariable_table)                 \
+  declare_constant(ConstMethod::_has_exception_table)                     \
+  declare_constant(ConstMethod::_has_generic_signature)                   \
+  declare_constant(ConstMethod::_has_method_annotations)                  \
+  declare_constant(ConstMethod::_has_parameter_annotations)               \
+  declare_constant(ConstMethod::_has_default_annotations)                 \
+  declare_constant(ConstMethod::_has_type_annotations)                    \
                                                                           \
   /*************************************/                                 \
   /* InstanceKlass enum                */                                 \
diff --git a/hotspot/src/share/vm/utilities/accessFlags.cpp b/hotspot/src/share/vm/utilities/accessFlags.cpp
index 933f1cb..6ae8e74 100644
--- a/hotspot/src/share/vm/utilities/accessFlags.cpp
+++ b/hotspot/src/share/vm/utilities/accessFlags.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -59,7 +59,7 @@
   } while(f != old_flags);
 }
 
-#ifndef PRODUCT
+#if !defined(PRODUCT) || INCLUDE_JVMTI
 
 void AccessFlags::print_on(outputStream* st) const {
   if (is_public      ()) st->print("public "      );
@@ -80,7 +80,7 @@
   if (on_stack       ()) st->print("{on_stack} "  );
 }
 
-#endif
+#endif // !PRODUCT || INCLUDE_JVMTI
 
 void accessFlags_init() {
   assert(sizeof(AccessFlags) == sizeof(jint), "just checking size of flags");
diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp
index c2729eb..3d2d9aa 100644
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -239,7 +239,11 @@
   inline friend AccessFlags accessFlags_from(jint flags);
 
   // Printing/debugging
+#if INCLUDE_JVMTI
+  void print_on(outputStream* st) const;
+#else
   void print_on(outputStream* st) const PRODUCT_RETURN;
+#endif
 };
 
 inline AccessFlags accessFlags_from(jint flags) {
diff --git a/hotspot/test/compiler/7009359/Test7009359.java b/hotspot/test/compiler/7009359/Test7009359.java
index 408fd71..8672493 100644
--- a/hotspot/test/compiler/7009359/Test7009359.java
+++ b/hotspot/test/compiler/7009359/Test7009359.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -27,13 +27,13 @@
  * @bug 7009359
  * @summary HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
  *
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+OptimizeStringConcat -XX:CompileCommand=exclude,Test7009359,main Test7009359
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+OptimizeStringConcat -XX:CompileCommand=dontinline,Test7009359,stringmakerBUG Test7009359
  *
  */
 
 public class Test7009359 {
     public static void main (String[] args) {
-        for(int i = 0; i < 1000000; i++) {
+        for(int i = 0; i < 100000; i++) {
             if(!stringmakerBUG(null).equals("NPE")) {
                 System.out.println("StringBuffer(null) does not throw NPE");
                 System.exit(97);
diff --git a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java
new file mode 100644
index 0000000..ebd5a9a
--- /dev/null
+++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import sun.hotspot.WhiteBox;
+import sun.management.ManagementFactoryHelper;
+import com.sun.management.HotSpotDiagnosticMXBean;
+
+import java.lang.reflect.Method;
+
+/*
+ * @author igor.ignatyev@oracle.com
+ */
+public abstract class CompilerWhiteBoxTest {
+    protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+    protected static final Method METHOD = getMethod("method");
+    protected static final int COMPILE_THRESHOLD
+            = Integer.parseInt(getVMOption("CompileThreshold", "10000"));
+
+    protected static Method getMethod(String name) {
+        try {
+            return CompilerWhiteBoxTest.class.getDeclaredMethod(name);
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new RuntimeException(
+                    "exception on getting method " + name, e);
+        }
+    }
+
+    protected static String getVMOption(String name, String defaultValue) {
+        String result;
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        result = diagnostic.getVMOption(name).getValue();
+        return result == null ? defaultValue : result;
+    }
+
+    protected final void runTest() throws RuntimeException {
+        if (ManagementFactoryHelper.getCompilationMXBean() == null) {
+            System.err.println(
+                    "Warning: test is not applicable in interpreted mode");
+            return;
+        }
+        System.out.println("at test's start:");
+        printInfo(METHOD);
+        try {
+            test();
+        } catch (Exception e) {
+            System.out.printf("on exception '%s':", e.getMessage());
+            printInfo(METHOD);
+            throw new RuntimeException(e);
+        }
+        System.out.println("at test's end:");
+        printInfo(METHOD);
+    }
+
+    protected static void checkNotCompiled(Method method) {
+        if (WHITE_BOX.isMethodCompiled(method)) {
+            throw new RuntimeException(method + " must be not compiled");
+        }
+        if (WHITE_BOX.getMethodCompilationLevel(method) != 0) {
+            throw new RuntimeException(method + " comp_level must be == 0");
+        }
+    }
+
+    protected static void checkCompiled(Method method)
+            throws InterruptedException {
+        final long start = System.currentTimeMillis();
+        waitBackgroundCompilation(method);
+        if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
+            System.err.printf("Warning: %s is still in queue after %dms%n",
+                    method, System.currentTimeMillis() - start);
+            return;
+        }
+        if (!WHITE_BOX.isMethodCompiled(method)) {
+            throw new RuntimeException(method + " must be compiled");
+        }
+        if (WHITE_BOX.getMethodCompilationLevel(method) == 0) {
+            throw new RuntimeException(method + " comp_level must be != 0");
+        }
+    }
+
+    protected static void waitBackgroundCompilation(Method method)
+            throws InterruptedException {
+        final Object obj = new Object();
+        synchronized (obj) {
+            for (int i = 0; i < 10; ++i) {
+                if (!WHITE_BOX.isMethodQueuedForCompilation(method)) {
+                    break;
+                }
+                obj.wait(1000);
+            }
+        }
+    }
+
+    protected static void printInfo(Method method) {
+        System.out.printf("%n%s:%n", method);
+        System.out.printf("\tcompilable:\t%b%n",
+                WHITE_BOX.isMethodCompilable(method));
+        System.out.printf("\tcompiled:\t%b%n",
+                WHITE_BOX.isMethodCompiled(method));
+        System.out.printf("\tcomp_level:\t%d%n",
+                WHITE_BOX.getMethodCompilationLevel(method));
+        System.out.printf("\tin_queue:\t%b%n",
+                WHITE_BOX.isMethodQueuedForCompilation(method));
+        System.out.printf("compile_queues_size:\t%d%n%n",
+                WHITE_BOX.getCompileQueuesSize());
+    }
+
+    protected abstract void test() throws Exception;
+
+    protected final int compile() {
+        int result = 0;
+        for (int i = 0; i < COMPILE_THRESHOLD; ++i) {
+            result += method();
+        }
+        return result;
+    }
+
+
+    protected int method() {
+        return 42;
+    }
+}
diff --git a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java
new file mode 100644
index 0000000..a0b41d3
--- /dev/null
+++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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 DeoptimizeAllTest
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI DeoptimizeAllTest.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest
+ * @author igor.ignatyev@oracle.com
+ */
+public class DeoptimizeAllTest extends CompilerWhiteBoxTest {
+
+    public static void main(String[] args) throws Exception {
+        new DeoptimizeAllTest().runTest();
+    }
+
+    protected void test() throws Exception {
+        // to prevent inlining #method into #compile()
+        WHITE_BOX.setDontInlineMethod(METHOD, true);
+        compile();
+        checkCompiled(METHOD);
+        WHITE_BOX.deoptimizeAll();
+        checkNotCompiled(METHOD);
+    }
+}
diff --git a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java
new file mode 100644
index 0000000..66b45cc
--- /dev/null
+++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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 DeoptimizeMethodTest
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI DeoptimizeMethodTest.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest
+ * @author igor.ignatyev@oracle.com
+ */
+public class DeoptimizeMethodTest extends CompilerWhiteBoxTest {
+
+    public static void main(String[] args) throws Exception {
+        new DeoptimizeMethodTest().runTest();
+    }
+
+    protected void test() throws Exception {
+        // to prevent inlining #method into #compile()
+        WHITE_BOX.setDontInlineMethod(METHOD, true);
+        compile();
+        checkCompiled(METHOD);
+        WHITE_BOX.deoptimizeMethod(METHOD);
+        checkNotCompiled(METHOD);
+    }
+}
diff --git a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java
new file mode 100644
index 0000000..21878b5
--- /dev/null
+++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test IsMethodCompilableTest
+ * @bug 8007270
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI IsMethodCompilableTest.java
+ * @run main/othervm/timeout=600 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest
+ * @author igor.ignatyev@oracle.com
+ */
+public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
+    protected static final long PER_METHOD_RECOMPILATION_CUTOFF;
+
+    static {
+        long tmp = Long.parseLong(
+                getVMOption("PerMethodRecompilationCutoff", "400"));
+        if (tmp == -1) {
+            PER_METHOD_RECOMPILATION_CUTOFF = -1 /* Inf */;
+        } else {
+            PER_METHOD_RECOMPILATION_CUTOFF = 1 + (0xFFFFFFFFL & tmp);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        new IsMethodCompilableTest().runTest();
+    }
+
+    protected void test() throws Exception {
+        if (!WHITE_BOX.isMethodCompilable(METHOD)) {
+            throw new RuntimeException(METHOD + " must be compilable");
+        }
+        System.out.println("PerMethodRecompilationCutoff = "
+                + PER_METHOD_RECOMPILATION_CUTOFF);
+        if (PER_METHOD_RECOMPILATION_CUTOFF == -1) {
+            System.err.println(
+                    "Warning: test is not applicable if PerMethodRecompilationCutoff == Inf");
+            return;
+        }
+        // to prevent inlining #method into #compile()
+        WHITE_BOX.setDontInlineMethod(METHOD, true);
+        boolean madeNotCompilable = false;
+
+        for (long i = 0; i < PER_METHOD_RECOMPILATION_CUTOFF; ++i) {
+            compile();
+            waitBackgroundCompilation(METHOD);
+            WHITE_BOX.deoptimizeMethod(METHOD);
+            if (!WHITE_BOX.isMethodCompilable(METHOD)) {
+                madeNotCompilable = true;
+                break;
+            }
+        }
+        if (!madeNotCompilable) {
+            throw new RuntimeException(METHOD + " is still compilable after "
+                    + PER_METHOD_RECOMPILATION_CUTOFF + " iterations");
+        }
+        compile();
+        if (WHITE_BOX.isMethodCompiled(METHOD)) {
+            printInfo(METHOD);
+            throw new RuntimeException(
+                    METHOD + " is not compilable but compiled");
+        }
+    }
+}
diff --git a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java
new file mode 100644
index 0000000..6916b16
--- /dev/null
+++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test MakeMethodNotCompilableTest
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI MakeMethodNotCompilableTest.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest
+ * @author igor.ignatyev@oracle.com
+ */
+public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
+
+    public static void main(String[] args) throws Exception {
+        new MakeMethodNotCompilableTest().runTest();
+    }
+
+    protected void test() throws Exception  {
+        if (!WHITE_BOX.isMethodCompilable(METHOD)) {
+            throw new RuntimeException(METHOD + " must be compilable");
+        }
+        WHITE_BOX.makeMethodNotCompilable(METHOD);
+        if (WHITE_BOX.isMethodCompilable(METHOD)) {
+            throw new RuntimeException(METHOD + " must be not compilable");
+        }
+        compile();
+        if (WHITE_BOX.isMethodQueuedForCompilation(METHOD)) {
+            throw new RuntimeException(METHOD + " must not be in queue");
+        }
+        checkNotCompiled(METHOD);
+        if (WHITE_BOX.isMethodCompilable(METHOD)) {
+            throw new RuntimeException(METHOD + " must be not compilable");
+        }
+    }
+}
diff --git a/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java b/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java
new file mode 100644
index 0000000..01daa0e
--- /dev/null
+++ b/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test SetDontInlineMethodTest
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
+ * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI SetDontInlineMethodTest.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest
+ * @author igor.ignatyev@oracle.com
+ */
+public class SetDontInlineMethodTest extends CompilerWhiteBoxTest {
+
+    public static void main(String[] args) throws Exception {
+        new SetDontInlineMethodTest().runTest();
+    }
+
+    protected void test() throws Exception {
+        if (WHITE_BOX.setDontInlineMethod(METHOD, true)) {
+            throw new RuntimeException("on start " + METHOD
+                    + " must be inlineable");
+        }
+        if (!WHITE_BOX.setDontInlineMethod(METHOD, true)) {
+            throw new RuntimeException("after first change to true " + METHOD
+                    + " must be not inlineable");
+        }
+        if (!WHITE_BOX.setDontInlineMethod(METHOD, false)) {
+            throw new RuntimeException("after second change to true " + METHOD
+                    + " must be still not inlineable");
+        }
+        if (WHITE_BOX.setDontInlineMethod(METHOD, false)) {
+            throw new RuntimeException("after first change to false" + METHOD
+                    + " must be inlineable");
+        }
+        if (WHITE_BOX.setDontInlineMethod(METHOD, false)) {
+            throw new RuntimeException("after second change to false " + METHOD
+                    + " must be inlineable");
+        }
+    }
+}
diff --git a/hotspot/test/runtime/8007320/ConstMethodTest.java b/hotspot/test/runtime/8007320/ConstMethodTest.java
new file mode 100644
index 0000000..68ca8dc
--- /dev/null
+++ b/hotspot/test/runtime/8007320/ConstMethodTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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 8007320
+ * @summary Test all optional fields in ConstMethod
+ * @compile -g -parameters ConstMethodTest.java
+ * @run main ConstMethodTest
+ */
+
+import java.util.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.io.Serializable;
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyAnnotation {
+    public String name();
+    public String value();
+    public String date() default "today";
+}
+
+@Target(ElementType.TYPE_USE)
+@Retention(RetentionPolicy.RUNTIME)
+@interface TypeAnno {
+    String value();
+}
+
+@Target(ElementType.TYPE_USE)
+@Retention(RetentionPolicy.RUNTIME)
+@interface TypeAnno2 {
+    String value();
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+@interface Named {
+  String value();
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface ScalarTypesWithDefault {
+    byte     b()    default 11;
+    short    s()    default 12;
+    int      i()    default 13;
+    long     l()    default 14;
+    char     c()    default 'V';
+}
+
+// Some exception class
+class OkException extends RuntimeException {};
+
+
+@MyAnnotation(name="someName", value = "Hello World")
+public class ConstMethodTest {
+
+    private static void check(boolean b) {
+        if (!b)
+            throw new RuntimeException();
+    }
+    private static void fail(String msg) {
+       System.err.println(msg);
+       throw new RuntimeException();
+    }
+    private static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) {
+        } else {
+            fail(x + " not equal to " + y);
+        }
+    }
+    private static final String[] parameter_names = {
+        "parameter", "parameter2", "x"
+    };
+
+    // Declare a function with everything in it.
+    @MyAnnotation(name="someName", value="Hello World")
+    static <T> void kitchenSinkFunc(@Named(value="aName") String parameter,
+              @Named("bName") String parameter2,
+              @ScalarTypesWithDefault T x)
+            throws @TypeAnno("RE") @TypeAnno2("RE2") RuntimeException,
+                NullPointerException,
+                @TypeAnno("AIOOBE") ArrayIndexOutOfBoundsException {
+      int i, j, k;
+      try {
+        System.out.println("calling kitchenSinkFunc " + parameter);
+        throw new OkException();  // to see stack trace with line numbers
+      } catch (Exception e) {
+       e.printStackTrace();
+      }
+    }
+
+    private static void test1() throws Throwable {
+        for (Method m : ConstMethodTest.class.getDeclaredMethods()) {
+            if (m.getName().equals("kitchenSinkFunc")) {
+                Annotation[][] ann = m.getParameterAnnotations();
+                equal(ann.length, 3);
+                Annotation foo = ann[0][0];
+                Annotation bar = ann[1][0];
+                equal(foo.toString(), "@Named(value=aName)");
+                equal(bar.toString(), "@Named(value=bName)");
+                check(foo.equals(foo));
+                check(bar.equals(bar));
+                check(! foo.equals(bar));
+                // method annotations
+                Annotation[] ann2 = m.getAnnotations();
+                equal(ann2.length, 1);
+                Annotation mann = ann2[0];
+                equal(mann.toString(), "@MyAnnotation(date=today, name=someName, value=Hello World)");
+                // Test Method parameter names
+                Parameter[] parameters = m.getParameters();
+                if(parameters == null)
+                    throw new Exception("getParameters should never be null");
+                for(int i = 0; i < parameters.length; i++) {
+                    Parameter p = parameters[i];
+                    equal(parameters[i].getName(), parameter_names[i]);
+                }
+            }
+        }
+    }
+
+    public static void main(java.lang.String[] unused) throws Throwable {
+        // pass 5 so kitchenSinkFunc is instantiated with an int
+        kitchenSinkFunc("parameter", "param2", 5);
+        test1();
+    }
+};
+
diff --git a/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java b/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java
new file mode 100644
index 0000000..85f533a
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006298
+ * @summary Setting an invalid value for a bool argument should result in a useful error message
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class BooleanFlagWithInvalidValue {
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:+UseLargePages=8", "-version");
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Improperly specified VM option 'UseLargePages=8'");
+    output.shouldHaveExitValue(1);
+
+    pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:-UseLargePages=8", "-version");
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Improperly specified VM option 'UseLargePages=8'");
+    output.shouldHaveExitValue(1);
+  }
+}
diff --git a/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java b/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java
new file mode 100644
index 0000000..9d475c2
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java
@@ -0,0 +1,42 @@
+/*
+ * 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 8006298
+ * @summary Setting a flag to an invalid value should print a useful error message
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class FlagWithInvalidValue {
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:ObjectAlignmentInBytes=v", "-version");
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Improperly specified VM option 'ObjectAlignmentInBytes=v'");
+    output.shouldHaveExitValue(1);
+  }
+}
diff --git a/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java b/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java
new file mode 100644
index 0000000..d84570e
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java
@@ -0,0 +1,50 @@
+/*
+ * 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 8006298
+ * @summary Using a bool (+/-) prefix on non-bool flag should result in a useful error message
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class NonBooleanFlagWithInvalidBooleanPrefix {
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:-ObjectAlignmentInBytes=16", "-version");
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Unexpected +/- setting in VM option 'ObjectAlignmentInBytes=16'");
+    output.shouldHaveExitValue(1);
+
+    pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:+ObjectAlignmentInBytes=16", "-version");
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Unexpected +/- setting in VM option 'ObjectAlignmentInBytes=16'");
+    output.shouldHaveExitValue(1);
+
+  }
+}
diff --git a/hotspot/test/runtime/CommandLine/UnrecognizedVMOption.java b/hotspot/test/runtime/CommandLine/UnrecognizedVMOption.java
new file mode 100644
index 0000000..040704f
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/UnrecognizedVMOption.java
@@ -0,0 +1,42 @@
+/*
+ * 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 8006298
+ * @summary Using an unrecognized VM option should print the name of the option
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class UnrecognizedVMOption {
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:bogus_option", "-version");
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Unrecognized VM option 'bogus_option'");
+    output.shouldHaveExitValue(1);
+  }
+}
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index ce25c2d..6f6829e 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -198,3 +198,4 @@
 2087e24a4357eceb6432e94918e75fdc706a27d6 jdk8-b74
 ff0b73a6b3f6cea644d37d56d746a37743419fa7 jdk8-b75
 0c08593944d0cd30645f6e1e4946c51ff2b10c8c jdk8-b76
+573e789c187a69a3ae00bffd26eb35c0f4a60636 jdk8-b77
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index 54f020a..9931fa8 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -198,3 +198,4 @@
 12db3c5a3393b03eeb09ff26f418c4420c21aaab jdk8-b74
 966bf9f3c41a59ff5d86ff4275291c52f329f984 jdk8-b75
 c4853f3f0e89ac60aa5b517f5f224f0f60e08577 jdk8-b76
+64dfba1bad16433f609f17a42c3c5990367c5c0b jdk8-b77
diff --git a/jdk/.hgtags b/jdk/.hgtags
index ea48085..6622885 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -198,3 +198,4 @@
 57d5d954462831ac353a1f40d3bb05ddb4620952 jdk8-b74
 4a67fdb752b7d6329d9be9c28d3f9d6cf7eb9a3c jdk8-b75
 3a263052866137b645ab86498a43693ff5c19e69 jdk8-b76
+b2fc8e31cecc35b76188e821d4c5dc0e0b74ac24 jdk8-b77
diff --git a/jdk/make/common/Defs-macosx.gmk b/jdk/make/common/Defs-macosx.gmk
index b3349db..951a18d 100644
--- a/jdk/make/common/Defs-macosx.gmk
+++ b/jdk/make/common/Defs-macosx.gmk
@@ -405,3 +405,11 @@
 endif
 
 LIB_LOCATION ?= $(LIBDIR)
+
+# Adding these macros will make it an error to link to mac APIs newer than OS version 10.7
+ifeq ($(MACOSX_REQUIRED_VERSION),)
+  MACOSX_REQUIRED_VERSION:=1070
+endif
+MACOSX_OS_VERSION_CFLAGS := -DMAC_OS_X_VERSION_MAX_ALLOWED=$(MACOSX_REQUIRED_VERSION) -DMAC_OS_X_VERSION_MIN_REQUIRED=$(MACOSX_REQUIRED_VERSION)
+OTHER_CFLAGS += $(MACOSX_OS_VERSION_CFLAGS)
+OTHER_CXXFLAGS += $(MACOSX_OS_VERSION_CFLAGS)
diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk
index 367eab8..70033e4 100644
--- a/jdk/make/common/Release.gmk
+++ b/jdk/make/common/Release.gmk
@@ -1056,6 +1056,7 @@
 	    -processor com.sun.tools.javac.sym.CreateSymbols \
 	    -Acom.sun.tools.javac.sym.Jar=$(RT_JAR) \
 	    -Acom.sun.tools.javac.sym.Dest=$(OUTPUTDIR)/symbols/META-INF/sym/rt.jar \
+	    -Acom.sun.tools.javac.sym.Profiles=$(JDK_TOPDIR)/makefiles/profile-rtjar-includes.txt \
 	    $(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS) $(EXPORTED_PRIVATE_PKGS)
 	$(BOOT_JAR_CMD) $(CREATE_JAR_OPTS_NOMANIFEST) $(LIBDIR)/ct.sym \
 	    -C $(OUTPUTDIR)/symbols META-INF $(BOOT_JAR_JFLAGS)
diff --git a/jdk/make/docs/CORE_PKGS.gmk b/jdk/make/docs/CORE_PKGS.gmk
index 86aeae9..d55bb8b 100644
--- a/jdk/make/docs/CORE_PKGS.gmk
+++ b/jdk/make/docs/CORE_PKGS.gmk
@@ -128,9 +128,9 @@
   java.text                                      \
   java.text.spi                                  \
   java.time                                      \
-  java.time.temporal                             \
-  java.time.calendar                             \
+  java.time.chrono                               \
   java.time.format                               \
+  java.time.temporal                             \
   java.time.zone                                 \
   java.util                                      \
   java.util.concurrent                           \
diff --git a/jdk/make/docs/Makefile b/jdk/make/docs/Makefile
index c49fa8f..6681097 100644
--- a/jdk/make/docs/Makefile
+++ b/jdk/make/docs/Makefile
@@ -1,4 +1,4 @@
-# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 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
@@ -208,6 +208,7 @@
                 -use					\
                 -keywords				\
 		-Xdoclint:none				\
+                -Xprofilespath $(JDK_TOPDIR)/makefiles/profile-rtjar-includes.txt \
 		$(ADDITIONAL_JAVADOCFLAGS)
 
 ifdef OPENJDK
diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk
index bf0f983..8c2f80c 100644
--- a/jdk/make/java/java/FILES_java.gmk
+++ b/jdk/make/java/java/FILES_java.gmk
@@ -255,7 +255,6 @@
         java/util/SimpleTimeZone.java \
         sun/util/calendar/ZoneInfo.java \
         sun/util/calendar/ZoneInfoFile.java \
-        sun/util/calendar/TzIDOldMapping.java \
     java/util/TooManyListenersException.java \
     java/util/Comparator.java \
     java/util/Collections.java \
@@ -389,6 +388,7 @@
     java/util/concurrent/locks/ReadWriteLock.java \
     java/util/concurrent/locks/ReentrantLock.java \
     java/util/concurrent/locks/ReentrantReadWriteLock.java \
+    java/util/concurrent/locks/StampedLock.java \
     java/util/regex/Pattern.java \
     java/util/regex/Matcher.java \
     java/util/regex/MatchResult.java \
diff --git a/jdk/make/java/version/Makefile b/jdk/make/java/version/Makefile
index 76a16c3..824300e 100644
--- a/jdk/make/java/version/Makefile
+++ b/jdk/make/java/version/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 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
@@ -40,6 +40,7 @@
 	    -e 's/@@java_version@@/$(RELEASE)/g' \
 	    -e 's/@@java_runtime_version@@/$(FULL_VERSION)/g' \
 	    -e 's/@@java_runtime_name@@/$(RUNTIME_NAME)/g' \
+	    -e 's/@@java_profile_name@@//g' \
 	$< > $@.temp
 	@$(MV) $@.temp $@
 
diff --git a/jdk/make/jprt.properties b/jdk/make/jprt.properties
index a6d2ea1..8f7038e 100644
--- a/jdk/make/jprt.properties
+++ b/jdk/make/jprt.properties
@@ -63,6 +63,7 @@
     ${jprt.my.test.target.set:TESTNAME=jvm98}
 
 # Default jdk test targets (testset=default)
+# NOTE: This does not match test/Makefile :: jdk_default
 jprt.make.rule.default.test.targets=				\
     ${jprt.my.test.target.set:TESTNAME=jdk_lang},               \
     ${jprt.my.test.target.set:TESTNAME=jdk_math}
@@ -72,6 +73,7 @@
     ${jprt.vm.default.test.targets}
 
 # Core jdk test targets (testset=core)
+# NOTE: please keep this in sync with test/Makefile :: jdk_core
 jprt.make.rule.core.test.targets=                               \
     ${jprt.make.rule.default.test.targets},                     \
     ${jprt.my.test.target.set:TESTNAME=jdk_util},               \
@@ -97,6 +99,7 @@
     ${jprt.my.test.target.set:TESTNAME=jbb_default}
 
 # All jdk test targets (testset=all)
+# NOTE: This does not match test/Makefile :: jdk_all
 jprt.make.rule.all.test.targets=    				\
     ${jprt.make.rule.core.test.targets}, 			\
     ${jprt.my.test.target.set:TESTNAME=jdk_awt},                \
diff --git a/jdk/make/sun/Makefile b/jdk/make/sun/Makefile
index 3d26ee5e..35fb554 100644
--- a/jdk/make/sun/Makefile
+++ b/jdk/make/sun/Makefile
@@ -70,7 +70,7 @@
 endif
 
 # nio need to be compiled before awt to have all charsets ready
-SUBDIRS            = jar security javazic misc net nio text util launcher cldr tzdb
+SUBDIRS            = jar security misc net nio text util launcher cldr tzdb
 
 ifdef BUILD_HEADLESS_ONLY
   DISPLAY_LIBS = awt $(HEADLESS_SUBDIR)
diff --git a/jdk/make/sun/javazic/Makefile b/jdk/make/sun/javazic/Makefile
index 2328031..9ae3c00 100644
--- a/jdk/make/sun/javazic/Makefile
+++ b/jdk/make/sun/javazic/Makefile
@@ -33,11 +33,11 @@
 
 # Time zone data file creation
 TZDATA = ./tzdata/
-TZDATA_VER = `$(GREP) '^tzdata' $(TZDATA)VERSION`
+TZDATA_VER := $(shell $(GREP) '^tzdata' $(TZDATA)VERSION)
 TZFILE = \
     africa antarctica asia australasia europe northamerica \
     pacificnew southamerica backward \
-    etcetera solar87 solar88 solar89 systemv
+    etcetera systemv
 JDKTZDATA = ./tzdata_jdk/
 JDKTZFILES = gmt jdk11_backward
 TZFILES = \
diff --git a/jdk/make/sun/javazic/tzdata/gmt b/jdk/make/sun/javazic/tzdata/gmt
new file mode 100644
index 0000000..0be3179
--- /dev/null
+++ b/jdk/make/sun/javazic/tzdata/gmt
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2000, 2005, 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.
+#
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	GMT		0:00	-	GMT
diff --git a/jdk/make/sun/javazic/tzdata/jdk11_backward b/jdk/make/sun/javazic/tzdata/jdk11_backward
new file mode 100644
index 0000000..5404cea
--- /dev/null
+++ b/jdk/make/sun/javazic/tzdata/jdk11_backward
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2000, 2006, 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.
+#
+# JDK 1.1.x compatible time zone IDs
+#
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
+Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
+Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
+Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
+Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
+Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
+Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
+Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
+Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
+Zone	SystemV/AST4	-4:00	-		AST
+Zone	SystemV/EST5	-5:00	-		EST
+Zone	SystemV/CST6	-6:00	-		CST
+Zone	SystemV/MST7	-7:00	-		MST
+Zone	SystemV/PST8	-8:00	-		PST
+Zone	SystemV/YST9	-9:00	-		YST
+Zone	SystemV/HST10	-10:00	-		HST
diff --git a/jdk/make/sun/tzdb/Makefile b/jdk/make/sun/tzdb/Makefile
index d09a125..14fd87a 100644
--- a/jdk/make/sun/tzdb/Makefile
+++ b/jdk/make/sun/tzdb/Makefile
@@ -43,9 +43,15 @@
 #
 TZDATA_DIR := ../javazic/tzdata
 TZDATA_VER := $(subst tzdata,,$(shell $(GREP) '^tzdata' $(TZDATA_DIR)/VERSION))
-TZFILE := africa antarctica asia australasia europe northamerica southamerica backward etcetera
+TZFILE := \
+    africa antarctica asia australasia europe northamerica \
+    pacificnew southamerica backward etcetera \
+    gmt jdk11_backward
+
 TZFILES := $(addprefix $(TZDATA_DIR)/,$(TZFILE))
 
+
+
 TZDB_JAR = tzdb.jar
 
 #
@@ -61,7 +67,7 @@
 $(LIBDIR)/$(TZDB_JAR): $(TZFILES)
 	$(prep-target)
 	echo build tzdb from version $(TZDATA_VER)
-	$(BOOT_JAVA_CMD) -jar $(BUILDTOOLJARDIR)/tzdb.jar -verbose \
+	$(BOOT_JAVA_CMD) -jar $(BUILDTOOLJARDIR)/tzdb.jar \
 	  -version $(TZDATA_VER) -srcdir $(TZDATA_DIR) -dstdir $(LIBDIR) $(TZFILE)
 
 clean clobber::
diff --git a/jdk/make/tools/Makefile b/jdk/make/tools/Makefile
index 586a169..e01f77e 100644
--- a/jdk/make/tools/Makefile
+++ b/jdk/make/tools/Makefile
@@ -48,7 +48,6 @@
   hasher_classes            \
   jarreorder                \
   jarsplit                  \
-  javazic                   \
   jdwpgen                   \
   makeclasslist             \
   strip_properties          \
diff --git a/jdk/make/tools/src/build/tools/classfile/RemoveMethods.java b/jdk/make/tools/src/build/tools/classfile/RemoveMethods.java
new file mode 100644
index 0000000..fd2de66
--- /dev/null
+++ b/jdk/make/tools/src/build/tools/classfile/RemoveMethods.java
@@ -0,0 +1,115 @@
+/*
+ * 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.  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 build.tools.classfile;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Set;
+import java.util.HashSet;
+
+import com.sun.tools.classfile.AccessFlags;
+import com.sun.tools.classfile.Attributes;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ClassWriter;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.Field;
+import com.sun.tools.classfile.Method;
+
+public class RemoveMethods {
+
+    public static void main(String[] args) throws Exception {
+        if (args.length < 2) {
+            System.err.println("Usage: java RemoveMethods classfile output [method...]");
+            System.exit(-1);
+        }
+
+        // class file to read
+        Path input = Paths.get(args[0]);
+
+        // class file to write, if directory then use the name of the input
+        Path output = Paths.get(args[1]);
+        if (Files.isDirectory(output))
+            output = output.resolve(input.getFileName());
+
+        // the methods to remove
+        Set<String> methodsToRemove = new HashSet<>();
+        int i = 2;
+        while (i < args.length)
+            methodsToRemove.add(args[i++]);
+
+        // read class file
+        ClassFile cf;
+        try (InputStream in = Files.newInputStream(input)) {
+             cf = ClassFile.read(in);
+        }
+
+        final int magic = cf.magic;
+        final int major_version = cf.major_version;
+        final int minor_version = cf.minor_version;
+        final ConstantPool cp = cf.constant_pool;
+        final AccessFlags access_flags = cf.access_flags;
+        final int this_class = cf.this_class;
+        final int super_class = cf.super_class;
+        final int[] interfaces = cf.interfaces;
+        final Field[] fields = cf.fields;
+        final Attributes class_attrs = cf.attributes;
+
+        // remove the requested methods, no signature check at this time
+        Method[] methods = cf.methods;
+        i = 0;
+        while (i < methods.length) {
+            Method m = methods[i];
+            String name = m.getName(cp);
+            if (methodsToRemove.contains(name)) {
+                int len = methods.length;
+                Method[] newMethods = new Method[len-1];
+                if (i > 0)
+                    System.arraycopy(methods, 0, newMethods, 0, i);
+                int after = methods.length - i - 1;
+                if (after > 0)
+                    System.arraycopy(methods, i+1, newMethods, i, after);
+                methods = newMethods;
+                String paramTypes = m.descriptor.getParameterTypes(cp);
+                System.out.format("Removed method %s%s from %s%n",
+                    name, paramTypes, cf.getName());
+                continue;
+            }
+            i++;
+        }
+
+        // TBD, prune constant pool of entries that are no longer referenced
+
+        // re-write class file
+        cf = new ClassFile(magic, minor_version, major_version, cp, access_flags,
+                this_class, super_class, interfaces, fields, methods, class_attrs);
+        try (OutputStream out = Files.newOutputStream(output)) {
+             new ClassWriter().write(cf, out);
+        }
+    }
+}
diff --git a/jdk/make/tools/src/build/tools/deps/CheckDeps.java b/jdk/make/tools/src/build/tools/deps/CheckDeps.java
new file mode 100644
index 0000000..347a2b2
--- /dev/null
+++ b/jdk/make/tools/src/build/tools/deps/CheckDeps.java
@@ -0,0 +1,226 @@
+/*
+ * 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.  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 build.tools.deps;
+
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.charset.StandardCharsets;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Dependencies;
+import com.sun.tools.classfile.Dependency;
+
+/**
+ * A simple tool to check the JAR files in a JRE image to ensure that there
+ * aren't any references to types that do not exist. The tool is intended to
+ * be used in the JDK "profiles" build to help ensure that the profile
+ * definitions are kept up to date.
+ */
+
+public class CheckDeps {
+
+    // classfile API for finding dependencies
+    static final Dependency.Finder finder = Dependencies.getClassDependencyFinder();
+
+    // "known types", found in rt.jar or other JAR files
+    static final Set<String> knownTypes = new HashSet<>();
+
+    // References to unknown types. The map key is the unknown type, the
+    // map value is the set of classes that reference it.
+    static final Map<String,Set<String>> unknownRefs = new HashMap<>();
+
+    // The property name is the name of an unknown type that is allowed to be
+    // references. The property value is a comma separated list of the types
+    // that are allowed to reference it. The list also includes the names of
+    // the profiles that the reference is allowed.
+    static final Properties allowedBadRefs = new Properties();
+
+    /**
+     * Returns the class name for the given class file. In the case of inner
+     * classes then the enclosing class is returned in order to keep the
+     * rules simple.
+     */
+    static String toClassName(String s) {
+        int i = s.indexOf('$');
+        if (i > 0)
+            s = s.substring(0, i);
+        return s.replace("/", ".");
+    }
+
+    /**
+     * Analyze the dependencies of all classes in the given JAR file. The
+     * method updates knownTypes and unknownRefs as part of the analysis.
+     */
+    static void analyzeDependencies(Path jarpath) throws Exception {
+        System.out.format("Analyzing %s%n", jarpath);
+        try (JarFile jf = new JarFile(jarpath.toFile())) {
+            Enumeration<JarEntry> entries = jf.entries();
+            while (entries.hasMoreElements()) {
+                JarEntry e = entries.nextElement();
+                String name = e.getName();
+                if (name.endsWith(".class")) {
+                    ClassFile cf = ClassFile.read(jf.getInputStream(e));
+                    for (Dependency d : finder.findDependencies(cf)) {
+                        String origin = toClassName(d.getOrigin().getName());
+                        String target = toClassName(d.getTarget().getName());
+
+                        // origin is now known
+                        unknownRefs.remove(origin);
+                        knownTypes.add(origin);
+
+                        // if the target is not known then record the reference
+                        if (!knownTypes.contains(target)) {
+                            Set<String> refs = unknownRefs.get(target);
+                            if (refs == null) {
+                                // first time seeing this unknown type
+                                refs = new HashSet<>();
+                                unknownRefs.put(target, refs);
+                            }
+                            refs.add(origin);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * We have closure (no references to types that do not exist) if
+     * unknownRefs is empty. When unknownRefs is not empty then it should
+     * only contain references that are allowed to be present (these are
+     * loaded from the refs.allowed properties file).
+     *
+     * @param the profile that is being tested, this determines the exceptions
+     *   in {@code allowedBadRefs} that apply.
+     *
+     * @return {@code true} if there are no missing types or the only references
+     *   to missing types are described by {@code allowedBadRefs}.
+     */
+    static boolean checkClosure(String profile) {
+        // process the references to types that do not exist.
+        boolean fail = false;
+        for (Map.Entry<String,Set<String>> entry: unknownRefs.entrySet()) {
+            String target = entry.getKey();
+            for (String origin: entry.getValue()) {
+                // check if origin -> target allowed
+                String value = allowedBadRefs.getProperty(target);
+                if (value == null) {
+                    System.err.format("%s -> %s (unknown type)%n", origin, target);
+                    fail = true;
+                } else {
+                    // target is known, check if the origin is one that we
+                    // expect and that the exception applies to the profile.
+                    boolean found = false;
+                    boolean applicable = false;
+                    for (String s: value.split(",")) {
+                        s = s.trim();
+                        if (s.equals(origin))
+                            found = true;
+                        if (s.equals(profile))
+                            applicable = true;
+                    }
+                    if (!found || !applicable) {
+                        if (!found) {
+                            System.err.format("%s -> %s (not allowed)%n", origin, target);
+                        } else {
+                            System.err.format("%s -> %s (reference not applicable to %s)%n",
+                                origin, target, profile);
+                        }
+                        fail = true;
+                    }
+                }
+
+            }
+        }
+
+        return !fail;
+    }
+
+    static void fail(URL url) throws Exception {
+        System.err.println("One or more unexpected references encountered");
+        if (url != null)
+            System.err.format("Check %s is up to date%n", Paths.get(url.toURI()));
+        System.exit(-1);
+    }
+
+    public static void main(String[] args) throws Exception {
+        // load properties file so that we know what missing types that are
+        // allowed to be referenced.
+        URL url = CheckDeps.class.getResource("refs.allowed");
+        if (url != null) {
+            try (InputStream in = url.openStream()) {
+                allowedBadRefs.load(new InputStreamReader(in, StandardCharsets.UTF_8));
+            }
+        }
+
+        if (args.length != 2) {
+            System.err.println("Usage: java CheckDeps <image> <profile>");
+            System.exit(-1);
+        }
+
+        String image = args[0];
+        String profile = args[1];
+
+        // process JAR files on boot class path
+        Path lib = Paths.get(image, "lib");
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(lib, "*.jar")) {
+            for (Path jarpath: stream) {
+                analyzeDependencies(jarpath);
+            }
+        }
+
+        // classes on boot class path should not reference other types
+        boolean okay = checkClosure(profile);
+        if (!okay)
+            fail(url);
+
+        // process JAR files in the extensions directory
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(lib.resolve("ext"), "*.jar")) {
+            for (Path jarpath: stream) {
+                analyzeDependencies(jarpath);
+            }
+        }
+
+        // re-check to ensure that the extensions doesn't reference types that
+        // do not exist.
+        okay = checkClosure(profile);
+        if (!okay)
+            fail(url);
+    }
+}
diff --git a/jdk/make/tools/src/build/tools/deps/refs.allowed b/jdk/make/tools/src/build/tools/deps/refs.allowed
new file mode 100644
index 0000000..91605d5
--- /dev/null
+++ b/jdk/make/tools/src/build/tools/deps/refs.allowed
@@ -0,0 +1,40 @@
+#
+# This properties-formatted file contains the names of the non-existent types
+# that are allowed to be referenced from classes in a profiles image.
+#
+# The property key is a type that does not exist. The property value is one or
+# more types that reference the missing type. The property value also encodes
+# the names of the profiles where this reference is allowed.
+
+# jsse.jar is not subsetted by the profiles build. For compact1 and compact2
+# then this means that there are references to Kerberos types that do not
+# exist. These references are harmless.
+#
+javax.security.auth.kerberos.KerberosKey=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
+javax.security.auth.kerberos.KerberosPrincipal=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
+javax.security.auth.kerberos.KerberosTicket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+javax.security.auth.kerberos.ServicePermission=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
+sun.security.jgss.GSSCaller=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
+sun.security.jgss.krb5.Krb5Util=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
+sun.security.jgss.krb5.ServiceCreds=sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
+sun.security.krb5.EncryptedData= sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+sun.security.krb5.EncryptionKey=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+sun.security.krb5.internal.crypto.KeyUsage=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+sun.security.krb5.internal.EncTicketPart=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+sun.security.krb5.internal.Krb5=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+sun.security.krb5.internal.Ticket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+sun.security.krb5.KrbException=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+sun.security.krb5.PrincipalName=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+sun.security.krb5.Realm=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
+
+# Residual references to java.beans.
+# The RemoveMethods tool does not yet purge the constant pool.
+# Rhino is due to be replaced so not worth addressing this dependency now.
+#
+java.beans.PropertyChangeListener=java.util.logging.LogManager,sun.org.mozilla.javascript.internal.Context,compact1,compact2,compact3
+java.beans.PropertyChangeEvent=sun.org.mozilla.javascript.internal.Context,compact3
+
+# JFR traces even in builds with JFR disabled
+com.oracle.jrockit.jfr.FlightRecorder: com.sun.management.MissionControl, compact3
+com.oracle.jrockit.jfr.management.FlightRecorderMBean: com.sun.management.MissionControl, compact3
+
diff --git a/jdk/make/tools/src/build/tools/jarreorder/JarReorder.java b/jdk/make/tools/src/build/tools/jarreorder/JarReorder.java
index c06808c..1d79ad0 100644
--- a/jdk/make/tools/src/build/tools/jarreorder/JarReorder.java
+++ b/jdk/make/tools/src/build/tools/jarreorder/JarReorder.java
@@ -162,8 +162,9 @@
         for (int i = orderList.size() - 1; i >= 0; --i) {
             String s = orderList.get(i);
             if (allFilesExcluded.contains(s)) {
-                System.err.println("Included order file " + s
-                    + " is also excluded, skipping.");
+                // Disable this warning until 8005688 is fixed
+                // System.err.println("Included order file " + s
+                //    + " is also excluded, skipping.");
             } else if (new File(s).exists()) {
                 allFiles.add(s);
             } else {
diff --git a/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java b/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java
index 5614a3c..129f87c 100644
--- a/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java
+++ b/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java
@@ -490,11 +490,16 @@
                                             tz.addUsedRec(rrec);
                                             usedZone = true;
                                         }
-                                    } else {
+                                    } else {  // fromTime == minTime
                                         int save = rrec.getSave();
-                                        tz.addTransition(fromTime,
+                                        tz.addTransition(minTime,
+                                                         tz.getOffsetIndex(gmtOffset),
+                                                         tz.getDstOffsetIndex(0));
+
+                                        tz.addTransition(transition,
                                                          tz.getOffsetIndex(gmtOffset+save),
                                                          tz.getDstOffsetIndex(save));
+
                                         tz.addUsedRec(rrec);
                                         usedZone = true;
                                     }
diff --git a/jdk/make/tools/src/build/tools/tzdb/TzdbZoneRulesCompiler.java b/jdk/make/tools/src/build/tools/tzdb/TzdbZoneRulesCompiler.java
index 7b32ccf..6f42dd9 100644
--- a/jdk/make/tools/src/build/tools/tzdb/TzdbZoneRulesCompiler.java
+++ b/jdk/make/tools/src/build/tools/tzdb/TzdbZoneRulesCompiler.java
@@ -227,6 +227,7 @@
         Map<String, SortedMap<String, ZoneRules>> allBuiltZones = new TreeMap<>();
         Set<String> allRegionIds = new TreeSet<String>();
         Set<ZoneRules> allRules = new HashSet<ZoneRules>();
+        Map<String, Map<String, String>> allLinks = new TreeMap<>();
 
         for (File srcDir : srcDirs) {
             // source files in this directory
@@ -242,7 +243,8 @@
             }
 
             // compile
-            String loopVersion = srcDir.getName();
+            String loopVersion = (srcDirs.size() == 1 && version != null)
+                                 ? version : srcDir.getName();
             TzdbZoneRulesCompiler compiler = new TzdbZoneRulesCompiler(loopVersion, srcFiles, verbose);
             try {
                 // compile
@@ -255,12 +257,13 @@
                 if (verbose) {
                     System.out.println("Outputting file: " + dstFile);
                 }
-                outputFile(dstFile, loopVersion, builtZones);
+                outputFile(dstFile, loopVersion, builtZones, compiler.links);
 
                 // create totals
                 allBuiltZones.put(loopVersion, builtZones);
                 allRegionIds.addAll(builtZones.keySet());
                 allRules.addAll(builtZones.values());
+                allLinks.put(loopVersion, compiler.links);
             } catch (Exception ex) {
                 System.out.println("Failed: " + ex.toString());
                 ex.printStackTrace();
@@ -274,7 +277,7 @@
             if (verbose) {
                 System.out.println("Outputting combined file: " + dstFile);
             }
-            outputFile(dstFile, allBuiltZones, allRegionIds, allRules);
+            outputFile(dstFile, allBuiltZones, allRegionIds, allRules, allLinks);
         }
     }
 
@@ -283,12 +286,15 @@
      */
     private static void outputFile(File dstFile,
                                    String version,
-                                   SortedMap<String, ZoneRules> builtZones) {
+                                   SortedMap<String, ZoneRules> builtZones,
+                                   Map<String, String> links) {
         Map<String, SortedMap<String, ZoneRules>> loopAllBuiltZones = new TreeMap<>();
         loopAllBuiltZones.put(version, builtZones);
         Set<String> loopAllRegionIds = new TreeSet<String>(builtZones.keySet());
         Set<ZoneRules> loopAllRules = new HashSet<ZoneRules>(builtZones.values());
-        outputFile(dstFile, loopAllBuiltZones, loopAllRegionIds, loopAllRules);
+        Map<String, Map<String, String>> loopAllLinks = new TreeMap<>();
+        loopAllLinks.put(version, links);
+        outputFile(dstFile, loopAllBuiltZones, loopAllRegionIds, loopAllRules, loopAllLinks);
     }
 
     /**
@@ -297,10 +303,10 @@
     private static void outputFile(File dstFile,
                                    Map<String, SortedMap<String, ZoneRules>> allBuiltZones,
                                    Set<String> allRegionIds,
-                                   Set<ZoneRules> allRules)
-    {
+                                   Set<ZoneRules> allRules,
+                                   Map<String, Map<String, String>> allLinks) {
         try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(dstFile))) {
-            outputTZEntry(jos, allBuiltZones, allRegionIds, allRules);
+            outputTZEntry(jos, allBuiltZones, allRegionIds, allRules, allLinks);
         } catch (Exception ex) {
             System.out.println("Failed: " + ex.toString());
             ex.printStackTrace();
@@ -314,7 +320,8 @@
     private static void outputTZEntry(JarOutputStream jos,
                                       Map<String, SortedMap<String, ZoneRules>> allBuiltZones,
                                       Set<String> allRegionIds,
-                                      Set<ZoneRules> allRules) {
+                                      Set<ZoneRules> allRules,
+                                      Map<String, Map<String, String>> allLinks) {
         // this format is not publicly specified
         try {
             jos.putNextEntry(new ZipEntry("TZDB.dat"));
@@ -359,6 +366,16 @@
                      out.writeShort(rulesIndex);
                 }
             }
+            // alias-region
+            for (String version : allLinks.keySet()) {
+                out.writeShort(allLinks.get(version).size());
+                for (Map.Entry<String, String> entry : allLinks.get(version).entrySet()) {
+                     int aliasIndex = Arrays.binarySearch(regionArray, entry.getKey());
+                     int regionIndex = Arrays.binarySearch(regionArray, entry.getValue());
+                     out.writeShort(aliasIndex);
+                     out.writeShort(regionIndex);
+                }
+            }
             out.flush();
             jos.closeEntry();
         } catch (Exception ex) {
@@ -621,7 +638,8 @@
     private int parseYear(String str, int defaultYear) {
         if (YEAR.reset(str).matches()) {
             if (YEAR.group("min") != null) {
-                return YEAR_MIN_VALUE;
+                //return YEAR_MIN_VALUE;
+                return 1900;  // systemv has min
             } else if (YEAR.group("max") != null) {
                 return YEAR_MAX_VALUE;
             } else if (YEAR.group("only") != null) {
@@ -742,16 +760,20 @@
                 if (realRules == null) {
                     throw new IllegalArgumentException("Alias '" + aliasId + "' links to invalid zone '" + realId + "' for '" + version + "'");
                 }
+                links.put(aliasId, realId);
+
             }
             builtZones.put(aliasId, realRules);
         }
 
         // remove UTC and GMT
-        builtZones.remove("UTC");
-        builtZones.remove("GMT");
-        builtZones.remove("GMT0");
+        //builtZones.remove("UTC");
+        //builtZones.remove("GMT");
+        //builtZones.remove("GMT0");
         builtZones.remove("GMT+0");
         builtZones.remove("GMT-0");
+        links.remove("GMT+0");
+        links.remove("GMT-0");
     }
 
     //-----------------------------------------------------------------------
@@ -785,7 +807,6 @@
         boolean endOfDay;
         /** The time of the cutover. */
         TimeDefinition timeDefinition = TimeDefinition.WALL;
-
         void adjustToFowards(int year) {
             if (adjustForwards == false && dayOfMonth > 0) {
                 LocalDate adjustedDate = LocalDate.of(year, month, dayOfMonth).minusDays(6);
diff --git a/jdk/makefiles/BuildJdk.gmk b/jdk/makefiles/BuildJdk.gmk
index bf7e1f9..d6c1033 100644
--- a/jdk/makefiles/BuildJdk.gmk
+++ b/jdk/makefiles/BuildJdk.gmk
@@ -39,6 +39,12 @@
 # Setup the java compilers for the JDK build.
 include Setup.gmk
 
+# Include Profile information
+include ProfileNames.gmk
+
+# Include the corresponding custom file, if present.
+-include $(CUSTOM_MAKE_DIR)/BuildJdk.gmk
+
 import: import-only
 import-only:
 #       Import (corba jaxp jaxws langtools hotspot)
@@ -85,10 +91,11 @@
 	+$(MAKE) -f CopySamples.gmk
 
 # Create the final jdk and jre images, to be wrapped up
-# into packages, or installed.
+# into packages, or installed. Ensure PROFILE is not set
+# in these cases.
 images:
-	+$(MAKE) -f CreateJars.gmk
-	+$(MAKE) -f Images.gmk
+	+$(MAKE) PROFILE="" -f CreateJars.gmk
+	+$(MAKE) PROFILE="" -f Images.gmk
 ifeq ($(OPENJDK_TARGET_OS), macosx)
 	+$(MAKE) -f Bundles.gmk
 endif
@@ -97,6 +104,13 @@
 	+$(MAKE) -f CompileLaunchers.gmk OVERLAY_IMAGES=true
 	+$(MAKE) -f Images.gmk overlay-images
 
+# Create Compact Profile images
+$(ALL_PROFILES):
+	+$(MAKE) PROFILE=$@ -f CreateJars.gmk
+	+$(MAKE) PROFILE=$@ JRE_IMAGE_DIR=$(IMAGES_OUTPUTDIR)/j2re-$(word $(call profile_number,$@),$(PROFILE_NAMES))-image -f Images.gmk profile-image
+
+profiles: $(ALL_PROFILES)
+
 sign-jars:
 	+$(MAKE) -f SignJars.gmk
 
@@ -121,3 +135,4 @@
 .PHONY: import gensrc gendata classes libs launchers genclasses
 .PHONY: import-only gensrc-only gendata-only classes-only libs-only launchers-only genclasses-only
 .PHONY: all jdk demos images overlay-images bundles install
+.PHONY: profiles $(ALL_PROFILES)
diff --git a/jdk/makefiles/CompileDemos.gmk b/jdk/makefiles/CompileDemos.gmk
index 4346e3d..f3100b1 100644
--- a/jdk/makefiles/CompileDemos.gmk
+++ b/jdk/makefiles/CompileDemos.gmk
@@ -421,6 +421,7 @@
 		CFLAGS:=$(CFLAGS_JDKLIB) $(SHARED_LIBRARY_FLAGS) \
                         -I$(JDK_OUTPUTDIR)/democlasses/jni/Poller, \
 		LDFLAGS:=$(LDFLAGS_JDKLIB), \
+		LDFLAGS_SUFFIX_solaris:=-lc,\
 		OBJECT_DIR:=$(JDK_OUTPUTDIR)/demoobjs/jni/Poller,\
                 OUTPUT_DIR:=$(JDK_OUTPUTDIR)/demoobjs, \
 		LIBRARY:=Poller))
diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk
index fdd2762..01dbc2b 100644
--- a/jdk/makefiles/CompileNativeLibraries.gmk
+++ b/jdk/makefiles/CompileNativeLibraries.gmk
@@ -2188,6 +2188,7 @@
 		MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libjfr/mapfile-vers, \
 		LDFLAGS:=$(LDFLAGS_JDKLIB) \
 			 $(call SET_SHARED_LIBRARY_ORIGIN),\
+		LDFLAGS_SUFFIX_solaris:=-lc,\
 		VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
 		RC_FLAGS:=$(RC_FLAGS)\
 			  -D "JDK_FNAME=jfr.dll" \
@@ -2236,6 +2237,7 @@
 		LDFLAGS:=$(LDFLAGS_JDKLIB) \
 			 $(call SET_SHARED_LIBRARY_ORIGIN),\
 		LDFLAGS_SUFFIX_linux:=-lc -lpthread,\
+		LDFLAGS_SUFFIX_solaris:=-lc,\
 		LDFLAGS_SUFFIX_windows:=$(WIN_JAVA_LIB) advapi32.lib user32.lib version.lib, \
 		LDFLAGS_SUFFIX_posix:=-lm -ljava -ljvm,\
 		VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/closed/share/native/sun/java2d/cmm/kcms/cmm.rc,\
@@ -2939,6 +2941,7 @@
 		MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libj2ucrypto/mapfile-vers, \
 		LDFLAGS:=$(LDFLAGS_JDKLIB),\
 		LDFLAGS_SUFFIX:=$(LIBDL),\
+		LDFLAGS_SUFFIX_solaris:=-lc,\
 		OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libj2ucrypto))
 
 $(BUILD_LIBJ2UCRYPTO) : $(BUILD_LIBJAVA)
diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk
index fae6d52..7e33790 100644
--- a/jdk/makefiles/CreateJars.gmk
+++ b/jdk/makefiles/CreateJars.gmk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -35,16 +35,19 @@
 
 include Tools.gmk
 
+include Profiles.gmk
+
 #
 # This makefile...so that altering will trigger rebuilding include/exclude-lists => jars
 #
 MAKEFILE=$(JDK_TOPDIR)/makefiles/CreateJars.gmk
+#
+# And similarly for the Profiles
+PROFILE_MAKEFILES=$(JDK_TOPDIR)/makefiles/Profiles.gmk $(JDK_TOPDIR)/makefiles/profile-rtjar-includes.txt
 
 MAINMANIFEST := $(JDK_TOPDIR)/make/tools/manifest.mf
 BEANMANIFEST := $(JDK_TOPDIR)/make/javax/swing/beaninfo/manifest
 
-JARS:=
-
 $(eval $(call MakeDir,$(IMAGES_OUTPUTDIR)/lib))
 
 ##########################################################################################
@@ -57,7 +60,6 @@
 		JAR:=$(IMAGES_OUTPUTDIR)/lib/jconsole.jar,\
 		SKIP_METAINF:=true))
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/jconsole.jar
 
 ##########################################################################################
 
@@ -68,7 +70,6 @@
 		JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/dnsns.jar,\
 		SKIP_METAINF:=true))
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/ext/dnsns.jar
 
 ##########################################################################################
 
@@ -127,15 +128,20 @@
 		JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/localedata.jar,\
 		SKIP_METAINF:=true))
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/ext/localedata.jar
-
 ##########################################################################################
-# rt.jar and resources.jar are being built in the same way as in the old build. They require
-# the files to be in a certain order and converting that is not easy and will not be needed
-# in jigsaw anyway.
+#
+# Different variants of rt.jar are built based on the current profile. The output
+# directory is augmented with the profile name so that the final jar file and all the
+# intermediary list files will be in directory. This has the form lib$PROFILE rather than
+# lib/$PROFILE so that it won't get copied as part of the image generation process.
+# Each profile customizes the RT_JAR_EXCLUDES variable.
+#
+##########################################################################################
 
-# Exclude list for rt.jar and resources.jar
-RT_JAR_EXCLUDES := \
+# Full JRE exclude list for rt.jar and resources.jar
+# This value should exclude types destined for jars other than rt.jar and resources.jar. 
+# When building a Profile this value augments the profile specific exclusions
+RT_JAR_EXCLUDES += \
 	com/oracle/security \
 	com/sun/codemodel \
 	com/sun/crypto/provider \
@@ -258,24 +264,9 @@
 	sun/tools/util \
 	sun/util/cldr/CLDRLocaleDataMetaInfo.class \
 	sun/util/resources/cldr \
-	$(LOCALEDATA_INCLUDES)
-
-# These files should never be put into rt.jar
-# but due to a misstake...some are put there if embedded
-#
-ifneq ($(JAVASE_EMBEDDED), true)
-# normal (correct) case
-RT_JAR_EXCLUDES += \
+	$(LOCALEDATA_INCLUDES) \
 	com/oracle/jrockit/jfr \
 	oracle/jrockit/jfr
-else
-# embedded (broken) case
-RT_JAR_EXCLUDES += \
-  oracle/jrockit/jfr/parser \
-  oracle/jrockit/jfr/tools \
-  oracle/jrockit/jfr/NativeOptions.class \
-  oracle/jrockit/jfr/RepositoryChunkHandler.class
-endif
 
 ifeq ($(OPENJDK_TARGET_OS), macosx)
         RT_JAR_EXCLUDES += com/sun/nio/sctp \
@@ -286,8 +277,8 @@
 ALL_FILES_IN_CLASSES := $(call not-containing,_the.,$(filter-out %javac_state,\
                         $(call CacheFind,$(JDK_OUTPUTDIR)/classes)))
 
-RT_JAR_MANIFEST_FILE := $(IMAGES_OUTPUTDIR)/lib/_the.rt.jar_manifest
-RESOURCE_JAR_MANIFEST_FILE := $(IMAGES_OUTPUTDIR)/lib/_the.resources.jar_manifest
+RT_JAR_MANIFEST_FILE := $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.rt.jar_manifest
+RESOURCE_JAR_MANIFEST_FILE := $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.resources.jar_manifest
 
 $(RT_JAR_MANIFEST_FILE): $(MAINMANIFEST) $(BEANMANIFEST)
 	$(MKDIR) -p $(@D)
@@ -307,7 +298,7 @@
 	       $(MAINMANIFEST) >> $@.tmp
 	$(MV) $@.tmp $@
 
-$(IMAGES_OUTPUTDIR)/lib/_the.jars.exclude: $(MAKEFILE)
+$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.exclude: $(MAKEFILE) $(PROFILE_MAKEFILES)
 	$(MKDIR) -p $(@D)
 	$(RM) $@ $@.tmp
 	$(call ListPathsSafely,RT_JAR_EXCLUDES,\n, >> $@.tmp)
@@ -320,55 +311,115 @@
 	$(TOOL_ADDJSUM) $< $@.tmp
 	$(MV) $@.tmp $@
 
-$(IMAGES_OUTPUTDIR)/lib/_the.jars.contents: $(BUILD_TOOLS) $(IMAGES_OUTPUTDIR)/lib/_the.jars.exclude \
+$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.contents: $(BUILD_TOOLS) $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.exclude \
 					 $(ALL_FILES_IN_CLASSES) $(IMAGES_OUTPUTDIR)/lib/classlist
 	$(MKDIR) -p $(@D)
 	$(RM) $@ $@.tmp
 	($(CD) $(JDK_OUTPUTDIR)/classes && \
 	    $(TOOL_JARREORDER) \
-		-o  $@.tmp $(IMAGES_OUTPUTDIR)/lib/classlist $(IMAGES_OUTPUTDIR)/lib/_the.jars.exclude . )
+		-o  $@.tmp $(IMAGES_OUTPUTDIR)/lib/classlist $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.exclude . )
 	$(MV) $@.tmp $@
 
-$(IMAGES_OUTPUTDIR)/lib/_the.rt.jar.contents: $(IMAGES_OUTPUTDIR)/lib/_the.jars.contents
+$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.rt.jar.contents: $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.contents
 	$(MKDIR) -p $(@D)
 	$(RM) $@ $@.tmp
-	$(GREP) -e '\.class$$' $(IMAGES_OUTPUTDIR)/lib/_the.jars.contents > $@.tmp
+	$(GREP) -e '\.class$$' $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.contents > $@.tmp
+ifneq ($(PROFILE),)
+#       # Add back classes from excluded packages (fixing the $ substitution in the process)
+	for type in  $(subst \$$,\, $(RT_JAR_INCLUDE_TYPES)) ; do \
+	  $(ECHO) $$type >> $@.tmp ; \
+	done
+endif
 	$(MV) $@.tmp $@
 
-$(IMAGES_OUTPUTDIR)/lib/_the.resources.jar.contents: $(IMAGES_OUTPUTDIR)/lib/_the.jars.contents
+$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.resources.jar.contents: $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.contents
 	$(MKDIR) -p $(@D)
 	$(RM) $@ $@.tmp
 	$(GREP) -v -e '\.class$$' \
 	    -e '/_the\.*' -e '^_the\.*' -e '\\_the\.*' -e 'javac_state' \
-	    $(IMAGES_OUTPUTDIR)/lib/_the.jars.contents > $@.tmp
+	    $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.jars.contents > $@.tmp
+ifneq ($(PROFILE),)
+#       # Strip out all META-INF/services/ entries
+	$(GREP) -v -e 'META-INF/services/' $@.tmp > $@.tmp2
+#       # Add back the required services
+#       # FIXME: On Solaris if PROFILE_INCLUDE_METAINF_SERVICES is not defined
+#       # we get a syntax error from sh. That doesn't happen on linux
+	for service in $(PROFILE_INCLUDE_METAINF_SERVICES) ; do \
+	  $(ECHO) $$service >> $@.tmp2; \
+	done
+	$(MV) $@.tmp2 $@.tmp
+endif
 	$(MV) $@.tmp $@
 
-RT_JAR_CREATE_OPTIONS := c0fm
-ifeq ($(COMPRESS_JARS), true)
-    RT_JAR_CREATE_OPTIONS := cfm
+# This is a hack but I don't know how to make this fit into the existing scheme
+$(PROFILE_VERSION_CLASS_TARGETS) : $(PROFILE_VERSION_JAVA_TARGETS)
+	@$(JAVAC) -d $(@D)/../../ $(@D)/$(VERSION_JAVA_FILE)
+
+
+# Support for removing the addPropertyChangeListener and removePropertyChangeListener
+# methods from classes that only go into the profile builds. For now the Pack200.Packer
+# and Packer200.Unpacker classes have special handling because of the $ in the file
+# name.
+BEANLESS_CLASSES = $(IMAGES_OUTPUTDIR)/beanless
+
+$(BEANLESS_CLASSES)/%: $(JDK_OUTPUTDIR)/classes/%
+	$(MKDIR) -p $(@D)
+	$(TOOL_REMOVEMETHODS) $< $@ addPropertyChangeListener removePropertyChangeListener
+
+CLASSES_TO_DEBEAN = \
+    java/util/logging/LogManager.class \
+    com/sun/java/util/jar/pack/PackerImpl.class \
+    com/sun/java/util/jar/pack/UnpackerImpl.class
+
+BEANLESS_CLASSES_TARGETS =
+ifneq ($(PROFILE),)
+    BEANLESS_CLASSES_TARGETS := $(foreach c, $(CLASSES_TO_DEBEAN), $(BEANLESS_CLASSES)/$c)
 endif
 
-$(IMAGES_OUTPUTDIR)/lib/rt.jar: $(IMAGES_OUTPUTDIR)/lib/_the.rt.jar.contents $(RT_JAR_MANIFEST_FILE)
-	$(ECHO) Creating rt.jar
+
+RT_JAR_CREATE_OPTIONS := c0fm
+RT_JAR_UPDATE_OPTIONS := u0f
+ifeq ($(COMPRESS_JARS), true)
+    RT_JAR_CREATE_OPTIONS := cfm
+    RT_JAR_UPDATE_OPTIONS := uf
+endif
+
+# This defines a target-specific variables to make the shell logic easier to see.
+# We need to find the Version.class file for the profile currently being built
+$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/rt.jar: \
+  CLASS_FILE = $(if $(PROFILE),$(strip $(foreach class,$(PROFILE_VERSION_CLASS_TARGETS),$(if $(findstring $(PROFILE),$(class)),$(class)))), NO_SUCH_FILE)
+# This is the real target
+$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/rt.jar: $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.rt.jar.contents $(RT_JAR_MANIFEST_FILE) $(PROFILE_VERSION_CLASS_TARGETS) $(BEANLESS_CLASSES_TARGETS)
+	$(ECHO) Creating rt.jar $(PROFILE) Compressed=$(COMPRESS_JARS)
 	$(MKDIR) -p $(@D)
 	$(RM) $@ $@.tmp
 	$(CD) $(JDK_OUTPUTDIR)/classes && \
 	    $(JAR) $(RT_JAR_CREATE_OPTIONS) $@.tmp $(RT_JAR_MANIFEST_FILE) \
-	        @$(IMAGES_OUTPUTDIR)/lib/_the.rt.jar.contents
+	        @$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.rt.jar.contents && \
+	    if [ -f $(CLASS_FILE) ]; then \
+	      $(ECHO)  Updating rt.jar $(PROFILE) && \
+	      $(CD) $(patsubst %$(VERSION_CLASS_PATH),%,$(CLASS_FILE)) && \
+                $(JAR) $(RT_JAR_UPDATE_OPTIONS) $@.tmp $(VERSION_CLASS_PATH); \
+	      $(MKDIR) -p $(BEANLESS_CLASSES)/java/util/jar; \
+	      $(TOOL_REMOVEMETHODS) $(JDK_OUTPUTDIR)/classes/java/util/jar/Pack200\$$Packer.class \
+		$(BEANLESS_CLASSES)/java/util/jar/Pack200\$$Packer.class addPropertyChangeListener removePropertyChangeListener; \
+	      $(TOOL_REMOVEMETHODS) $(JDK_OUTPUTDIR)/classes/java/util/jar/Pack200\$$Unpacker.class \
+		$(BEANLESS_CLASSES)/java/util/jar/Pack200\$$Unpacker.class addPropertyChangeListener removePropertyChangeListener; \
+	      $(CD) $(BEANLESS_CLASSES) && \
+		$(JAR) $(RT_JAR_UPDATE_OPTIONS) $@.tmp $(CLASSES_TO_DEBEAN) java/util/jar/* ; \
+            fi
 	$(MV) $@.tmp $@
 
-$(IMAGES_OUTPUTDIR)/lib/resources.jar: $(IMAGES_OUTPUTDIR)/lib/_the.resources.jar.contents \
+$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/resources.jar: $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.resources.jar.contents \
 				    $(RESOURCE_JAR_MANIFEST_FILE)
 	$(ECHO) Creating resources.jar
 	$(MKDIR) -p $(@D)
 	$(RM) $@ $@.tmp
 	$(CD) $(JDK_OUTPUTDIR)/classes && \
 	    $(JAR) $(RT_JAR_CREATE_OPTIONS) $@.tmp $(RESOURCE_JAR_MANIFEST_FILE) \
-	        @$(IMAGES_OUTPUTDIR)/lib/_the.resources.jar.contents
+	        @$(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the.resources.jar.contents
 	$(MV) $@.tmp $@
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/rt.jar $(IMAGES_OUTPUTDIR)/lib/resources.jar
-
 ##########################################################################################
 
 ifneq ($(OPENJDK_TARGET_OS), windows)
@@ -393,8 +444,6 @@
 		SKIP_METAINF := true, \
                 CHECK_COMPRESS_JAR:=true))
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/charsets.jar
-
 ##########################################################################################
 
 ifndef OPENJDK
@@ -408,7 +457,6 @@
 		MANIFEST:=$(MAINMANIFEST), \
                 CHECK_COMPRESS_JAR:=true))
 
-    JARS+=$(IMAGES_OUTPUTDIR)/lib/jfr.jar
 endif
 endif
 
@@ -425,8 +473,6 @@
 		MANIFEST:=$(MAINMANIFEST), \
                 CHECK_COMPRESS_JAR:=true))
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/jsse.jar
-
 ##########################################################################################
 # Create manifest for security jars
 
@@ -446,7 +492,8 @@
 
 ##########################################################################################
 # For all security jars, always build the jar, but for closed, install the prebuilt signed
-# version instead of the newly built jar. For open, signing is not needed. See SignJars.gmk
+# version instead of the newly built jar. Unsigned jars are treated as intermediate targets
+# and explicitly added to the JARS list. For open, signing is not needed. See SignJars.gmk
 # for more information.
 
 SUNPKCS11_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/sunpkcs11.jar
@@ -472,7 +519,7 @@
 	$(install-file)
 endif
 
-JARS += $(SUNPKCS11_JAR_DST) $(SUNPKCS11_JAR_UNSIGNED)
+JARS += $(SUNPKCS11_JAR_UNSIGNED)
 
 ##########################################################################################
 
@@ -499,7 +546,7 @@
 	$(install-file)
 endif
 
-JARS += $(SUNEC_JAR_DST) $(SUNEC_JAR_UNSIGNED)
+JARS += $(SUNEC_JAR_UNSIGNED)
 
 ##########################################################################################
 
@@ -512,8 +559,6 @@
 		JAR:=$(IMAGES_OUTPUTDIR)/lib/dt.jar,\
 		SKIP_METAINF:=true))
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/dt.jar
-
 ##########################################################################################
 
 SUNJCE_PROVIDER_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/sunjce_provider.jar
@@ -539,7 +584,7 @@
 	$(install-file)
 endif
 
-JARS += $(SUNJCE_PROVIDER_JAR_DST) $(SUNJCE_PROVIDER_JAR_UNSIGNED)
+JARS += $(SUNJCE_PROVIDER_JAR_UNSIGNED)
 
 ##########################################################################################
 
@@ -566,7 +611,7 @@
 	$(install-file)
 endif
 
-JARS += $(JCE_JAR_DST) $(JCE_JAR_UNSIGNED)
+JARS +=  $(JCE_JAR_UNSIGNED)
 
 ##########################################################################################
 
@@ -604,7 +649,7 @@
 	$(install-file)
 endif
 
-JARS += $(US_EXPORT_POLICY_JAR_DST) $(US_EXPORT_POLICY_JAR_UNSIGNED)
+JARS += $(US_EXPORT_POLICY_JAR_UNSIGNED)
 
 ##########################################################################################
 
@@ -647,7 +692,7 @@
 	$(install-file)
 endif
 
-JARS += $(LOCAL_POLICY_JAR_DST) $(LOCAL_POLICY_JAR_UNSIGNED)
+JARS += $(LOCAL_POLICY_JAR_UNSIGNED)
 
 ##########################################################################################
 
@@ -676,7 +721,7 @@
 	$(install-file)
 endif
 
-JARS += $(SUNMSCAPI_JAR_DST) $(SUNMSCAPI_JAR_UNSIGNED)
+JARS += $(SUNMSCAPI_JAR_UNSIGNED)
 
 endif
 
@@ -703,7 +748,7 @@
 	@$(ECHO) $(LOG_INFO) "\n>>>Installing prebuilt OracleUcrypto provider..."
 	$(install-file)
 
-JARS += $(UCRYPTO_JAR_DST) $(UCRYPTO_JAR_UNSIGNED)
+JARS += $(UCRYPTO_JAR_UNSIGNED) 
 
 endif
 endif
@@ -726,8 +771,6 @@
 		EXTRA_MANIFEST_ATTR:=CLDR-Version: $(CLDRVERSION),\
 		SKIP_METAINF:=true))
 
-JARS += $(CLDRDATA_JAR_DST)
-
 ##########################################################################################
 
 TOOLS_JAR_INCLUDES := \
@@ -801,7 +844,6 @@
 		SKIP_METAINF:=true, \
                 CHECK_COMPRESS_JAR:=true))
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/tools.jar
 
 ##########################################################################################
 
@@ -842,6 +884,7 @@
 	    -processor com.sun.tools.javac.sym.CreateSymbols \
 	    -Acom.sun.tools.javac.sym.Jar=$(IMAGES_OUTPUTDIR)/lib/rt.jar \
 	    -Acom.sun.tools.javac.sym.Dest=$(IMAGES_OUTPUTDIR)/symbols/META-INF/sym/rt.jar \
+	    -Acom.sun.tools.javac.sym.Profiles=profile-rtjar-includes.txt \
 	    $(CORE_PKGS) $(NON_CORE_PKGS) $(EXCLUDE_PROPWARN_PKGS) $(EXPORTED_PRIVATE_PKGS)
 	$(TOUCH) $@
 
@@ -852,7 +895,6 @@
 		JAR:=$(IMAGES_OUTPUTDIR)/lib/ct.sym, \
 		CHECK_COMPRESS_JAR:=true))
 
-JARS+=$(IMAGES_OUTPUTDIR)/lib/ct.sym
 
 ##########################################################################################
 
@@ -938,8 +980,6 @@
 		ZIP:=$(IMAGES_OUTPUTDIR)/src.zip,\
 		EXTRA_DEPS:=$(LAUNCHER_ZIP_SRC)))
 
-JARS+=$(IMAGES_OUTPUTDIR)/src.zip
-
 ##########################################################################################
 
 ifndef OPENJDK
@@ -990,15 +1030,11 @@
 $(IMAGES_OUTPUTDIR)/lib/management-agent.jar : $(JDK_TOPDIR)/src/share/classes/sun/management/manifest
 	$(JAR) cfm $@ $<
 
-JARS += $(IMAGES_OUTPUTDIR)/lib/management-agent.jar
-
 ##########################################################################################
 
 $(IMAGES_OUTPUTDIR)/lib/ext/zipfs.jar : $(JDK_OUTPUTDIR)/demo/nio/zipfs/zipfs.jar
 	$(install-file)
 
-JARS += $(IMAGES_OUTPUTDIR)/lib/ext/zipfs.jar
-
 ##########################################################################################
 
 ifeq ($(OPENJDK_TARGET_OS),macosx)
@@ -1006,8 +1042,6 @@
 		SRCS:=$(JDK_OUTPUTDIR)/jobjc_classes,\
 		JAR:=$(IMAGES_OUTPUTDIR)/lib/JObjC.jar, \
 		JARINDEX:=true))
-
-    JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar
 endif
 
 ##########################################################################################
@@ -1017,7 +1051,6 @@
 		SRCS:=$(JDK_OUTPUTDIR)/altclasses_classes,\
 		JAR:=$(IMAGES_OUTPUTDIR)/lib/alt-rt.jar))
 
-    JARS += $(IMAGES_OUTPUTDIR)/lib/alt-rt.jar
 endif
 
 ##########################################################################################
@@ -1028,8 +1061,6 @@
 $(IMAGES_OUTPUTDIR)/lib/sa-jdi.jar: $(JDK_OUTPUTDIR)/lib/sa-jdi.jar
 	$(install-file)
 
-JARS += $(IMAGES_OUTPUTDIR)/lib/sa-jdi.jar
-
 ##########################################################################################
 #
 # sec-bin.zip is used by builds where the corresponding sources are not available
diff --git a/jdk/makefiles/GendataTZDB.gmk b/jdk/makefiles/GendataTZDB.gmk
index 3c608fb..51289dd 100644
--- a/jdk/makefiles/GendataTZDB.gmk
+++ b/jdk/makefiles/GendataTZDB.gmk
@@ -30,7 +30,7 @@
 #
 TZDATA_DIR := $(JDK_TOPDIR)/make/sun/javazic/tzdata
 TZDATA_VER := $(subst tzdata,,$(shell $(GREP) '^tzdata' $(TZDATA_DIR)/VERSION))
-TZDATA_TZFILE := africa antarctica asia australasia europe northamerica southamerica backward etcetera
+TZDATA_TZFILE := africa antarctica asia australasia europe northamerica pacificnew southamerica backward etcetera gmt jdk11_backward
 TZDATA_TZFILES := $(addprefix $(TZDATA_DIR)/,$(TZDATA_TZFILE))
 
 GENDATA_TZDB_DST := $(JDK_OUTPUTDIR)/lib
@@ -39,6 +39,6 @@
 $(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR) : $(TZDATA_TZFILES)
 	$(RM) $(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR)
 	echo building tzdb from version $(TZDATA_VER)
-	$(TOOL_TZDB) -verbose -version $(TZDATA_VER) -srcdir $(TZDATA_DIR) -dstdir $(GENDATA_TZDB_DST) $(TZDATA_TZFILE)
+	$(TOOL_TZDB) -version $(TZDATA_VER) -srcdir $(TZDATA_DIR) -dstdir $(GENDATA_TZDB_DST) $(TZDATA_TZFILE)
 
 GENDATA_TZDB += $(GENDATA_TZDB_DST)/$(GENDATA_TZDB_JAR)
diff --git a/jdk/makefiles/GendataTimeZone.gmk b/jdk/makefiles/GendataTimeZone.gmk
index dcca735..1a482dc 100644
--- a/jdk/makefiles/GendataTimeZone.gmk
+++ b/jdk/makefiles/GendataTimeZone.gmk
@@ -34,7 +34,7 @@
 TZFILE0 := \
     africa antarctica asia australasia europe northamerica \
     pacificnew southamerica backward \
-    etcetera solar87 solar88 solar89 systemv
+    etcetera systemv
 
 TZFILE1 := \
     gmt jdk11_backward
diff --git a/jdk/makefiles/GenerateData.gmk b/jdk/makefiles/GenerateData.gmk
index 7d7e16b..f35cf32 100644
--- a/jdk/makefiles/GenerateData.gmk
+++ b/jdk/makefiles/GenerateData.gmk
@@ -44,9 +44,6 @@
 include GendataFontConfig.gmk
 GENDATA += $(GENDATA_FONT_CONFIG)
 
-include GendataTimeZone.gmk
-GENDATA += $(GENDATA_TIMEZONE)
-
 include GendataTZDB.gmk
 GENDATA += $(GENDATA_TZDB)
 
diff --git a/jdk/makefiles/GensrcMisc.gmk b/jdk/makefiles/GensrcMisc.gmk
index 5b9c06e..72a789b 100644
--- a/jdk/makefiles/GensrcMisc.gmk
+++ b/jdk/makefiles/GensrcMisc.gmk
@@ -23,24 +23,29 @@
 # questions.
 #
 
+include ProfileNames.gmk
+
 ##########################################################################################
 # Install the launcher name, release version string, full version
 # string and the runtime name into the Version.java file.
 # To be printed by java -version
 
-$(JDK_OUTPUTDIR)/gensrc/sun/misc/Version.java: \
-	$(JDK_TOPDIR)/src/share/classes/sun/misc/Version.java.template
+$(JDK_OUTPUTDIR)/gensrc/sun/misc/Version.java \
+$(PROFILE_VERSION_JAVA_TARGETS): \
+		$(JDK_TOPDIR)/src/share/classes/sun/misc/Version.java.template
 	$(MKDIR) -p $(@D)
 	$(RM) $@ $@.tmp
-	$(ECHO) $(LOG_INFO) Generating sun/misc/Version.java
+	$(ECHO) Generating sun/misc/Version.java $(call profile_version_name, $@)
 	$(SED) -e 's/@@launcher_name@@/$(LAUNCHER_NAME)/g' \
 	       -e 's/@@java_version@@/$(RELEASE)/g' \
 	       -e 's/@@java_runtime_version@@/$(FULL_VERSION)/g' \
 	       -e 's/@@java_runtime_name@@/$(RUNTIME_NAME)/g' \
+	       -e 's/@@java_profile_name@@/$(call profile_version_name, $@)/g' \
             $< > $@.tmp
 	$(MV) $@.tmp $@
 
-GENSRC_MISC += $(JDK_OUTPUTDIR)/gensrc/sun/misc/Version.java
+GENSRC_MISC += $(JDK_OUTPUTDIR)/gensrc/sun/misc/Version.java \
+    $(PROFILE_VERSION_JAVA_TARGETS)
 
 ##########################################################################################
 # Version file for jconsole
diff --git a/jdk/makefiles/Images.gmk b/jdk/makefiles/Images.gmk
index 53ea58d..2832267 100644
--- a/jdk/makefiles/Images.gmk
+++ b/jdk/makefiles/Images.gmk
@@ -41,6 +41,8 @@
 
 include Tools.gmk
 
+include Profiles.gmk
+
 # Note: This double-colon rule is intentional, to support
 # custom make file integration.
 images:: jre-image jdk-image
@@ -84,7 +86,7 @@
 ################################################################################
 #
 # Variable prefixes explained:
-# JRE_ refers to files in the j2re-image.
+# JRE_ refers to files in the j2re-*-image.
 # JDK_ refers to files in the j2sdk-image outside of the jre subdir.
 # JDKJRE_ refers to files in the j2sdk-image inside the jre subdir.
 #
@@ -92,7 +94,8 @@
 ################################################################################
 # /bin dir
 
-NOT_JRE_BIN_FILES := \
+ifeq ($(PROFILE),)
+    NOT_JRE_BIN_FILES := \
 	appletviewer$(EXE_SUFFIX) \
 	extcheck$(EXE_SUFFIX) \
 	idlj$(EXE_SUFFIX) \
@@ -125,6 +128,7 @@
         schemagen$(EXE_SUFFIX) \
 	jsadebugd$(EXE_SUFFIX) \
 	jhat$(EXE_SUFFIX)
+endif
 
 WINDOWS_JDK_BIN_FILES = \
 	$(EXE_SUFFIX) \
@@ -196,7 +200,8 @@
 	$(SALIB_NAME)
 endif
 
-NOT_JRE_LIB_FILES := \
+ifeq ($(PROFILE),)
+    NOT_JRE_LIB_FILES := \
 	tools.jar \
 	jconsole.jar \
 	sa-jdi.jar \
@@ -205,8 +210,9 @@
 	ir.idl \
 	ct.sym
 
-ifeq ($(OPENJDK_TARGET_OS), windows)
-    NOT_JRE_LIB_FILES += jawt.lib jvm.lib
+    ifeq ($(OPENJDK_TARGET_OS), windows)
+      NOT_JRE_LIB_FILES += jawt.lib jvm.lib
+    endif
 endif
 
 JDK_LIB_FILES := $(NOT_JRE_LIB_FILES)
@@ -607,6 +613,9 @@
 $(JRE_INFO_FILE): $(OUTPUT_ROOT)/spec.gmk $(OUTPUT_ROOT)/source_tips
 	$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
 	$(call create-info-file)
+ifneq ($(PROFILE),)
+	$(call info-file-item, "JAVA_PROFILE", "$(call profile_name, $(call profile_number, $(PROFILE)))")
+endif
 
 $(JDK_INFO_FILE): $(OUTPUT_ROOT)/spec.gmk $(OUTPUT_ROOT)/source_tips
 	$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
@@ -648,7 +657,7 @@
     EXEC_LIST_OVERLAY:=$(filter $(OVERLAY_FILTER),$(EXEC_LIST_BIN)) $(EXEC_LIST_LIB)
 
     # Filter out non JRE files and convert to unique touch files to depend on
-    JRE_STRIP_LIST:=$(patsubst $(JDK_OUTPUTDIR)/%,$(IMAGES_OUTPUTDIR)/_strip_jre/%.stripped,\
+    JRE_STRIP_LIST:=$(patsubst $(JDK_OUTPUTDIR)/%,$(IMAGES_OUTPUTDIR)/_strip_jre$(PROFILE)/%.stripped,\
 			$(filter-out $(addprefix %,$(NOT_JRE_BIN_FILES) $(NOT_JRE_LIB_FILES) $(JDKJRE_LIB_FILES)),\
 				 $(EXEC_LIST)))
 
@@ -688,7 +697,7 @@
     endef
 
     # Setup a rule for stripping files based on touch files
-    $(IMAGES_OUTPUTDIR)/_strip_jre/%.stripped: $(JRE_IMAGE_DIR)/%
+    $(IMAGES_OUTPUTDIR)/_strip_jre$(PROFILE)/%.stripped: $(JRE_IMAGE_DIR)/%
 	$(call strip-file)
 
     $(IMAGES_OUTPUTDIR)/_strip_jdk/%.stripped: $(JDK_IMAGE_DIR)/%
@@ -728,6 +737,29 @@
 	$(JDK_OVERLAY_DEMO_TARGETS) $(JDK_OVERLAY_INFO_FILE) \
 	$(JDKJRE_OVERLAY_STRIP_LIST) $(JDK_OVERLAY_BIN_STRIP_LIST) 
 
+ifneq ($(PROFILE),)
+# Files in lib$(PROFILE) are excluded from the generic copying routines so
+# we have to add them back in here
+$(foreach f,$(CUSTOM_PROFILE_JARS),\
+    $(eval $(call AddFileToCopy,$(IMAGES_OUTPUTDIR)/lib$(PROFILE),$(JRE_IMAGE_DIR)/lib,$f,JRE_LIB_TARGETS)))
+
+PROFILE_IMAGE_JARS := $(filter %.jar, $(JRE_LIB_TARGETS))
+
+PROFILE_IMAGE_JARS_CHECKED := $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_jars_checked
+
+$(PROFILE_IMAGE_JARS_CHECKED) : $(PROFILE_IMAGE_JARS)
+	$(TOOL_CHECKDEPS) $(JRE_IMAGE_DIR) \
+	    $(call profile_name, $(call profile_number, $(PROFILE)))
+	$(TOUCH) $@
+
+profile-image: $(JRE_BIN_TARGETS) $(JRE_LIB_TARGETS) \
+	$(JRE_IMAGE_DIR)/lib/meta-index $(JRE_IMAGE_DIR)/lib/ext/meta-index \
+	$(JRE_INFO_FILE) $(JRE_STRIP_LIST) $(PROFILE_IMAGE_JARS_CHECKED)
+
+.PHONY: profile-image
+
+endif # Profile
+
 ################################################################################
 
 .PHONY: default images jre-image jdk-image
diff --git a/jdk/makefiles/Import.gmk b/jdk/makefiles/Import.gmk
index 72cfb60..5e99b53 100644
--- a/jdk/makefiles/Import.gmk
+++ b/jdk/makefiles/Import.gmk
@@ -100,33 +100,13 @@
 
 #######
 
-ifeq ($(OPENJDK_TARGET_OS),solaris)
-define do-install-file
-	$(MKDIR) -p '$$(@D)'
-	$(RM) '$$@'
-	$(CP) -r -P '$$<' '$$(@D)'
-endef
-else ifeq ($(OPENJDK_TARGET_OS),macosx)
-define do-install-file
-	$(MKDIR) -p '$$(@D)'
-	$(RM) '$$@'
-	$(CP) -pRP '$$<' '$$@'
-endef
-else
-define do-install-file
-	$(MKDIR) -p '$$(@D)'
-	$(RM) '$$@'
-	$(CP) -P '$$<' '$$@'
-endef
-endif
-
 define CopyDir
         $1_SRC_FILES := $(shell $(FIND) $2 -type f -a \( -name DUMMY $(addprefix -o$(SPACE)-name$(SPACE),$4) \))
         $1_DST_FILES := $$(patsubst $2/%,$3/%,$$($1_SRC_FILES))
         IMPORT_TARGET_FILES += $$($1_DST_FILES)
 $3/% : $2/%
 	$(ECHO) $(LOG_INFO) Copying $$(@F)
-	$(do-install-file)
+	$$(install-file)
 endef
 
 #######
@@ -155,6 +135,12 @@
             IMPORT_TARGET_FILES += $(INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
         endif
     endif
+    ifeq ($(JVM_VARIANT_MINIMAL1), true)
+        IMPORT_TARGET_FILES += $(INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
+        ifneq (,$(JSIG_DEBUGINFO))
+            IMPORT_TARGET_FILES += $(INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+        endif
+    endif
 endif
 
 $(INSTALL_LIBRARIES_HERE)/server/%$(SHARED_LIBRARY_SUFFIX) : $(INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX)
@@ -195,27 +181,24 @@
 	$(RM) $(basename $@).debuginfo
 	$(MV) $@.tmp $@
 
-#######
+$(INSTALL_LIBRARIES_HERE)/minimal/%$(SHARED_LIBRARY_SUFFIX) : $(INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX)
+	$(MKDIR) -p $(@D)
+	$(RM) $@
+	$(LN) -s ../$(@F) $@
 
-ifeq ($(OPENJDK_TARGET_OS),solaris)
-define install-file
-	$(MKDIR) -p '$(@D)'
-	$(RM) '$@'
-	$(CP) -r -P '$<' '$(@D)'
-endef
-else ifeq ($(OPENJDK_TARGET_OS),macosx)
-define install-file
-	$(MKDIR) -p '$(@D)'
-	$(RM) '$@'
-	$(CP) -pRP '$<' '$@'
-endef
-else
-define install-file
-	$(MKDIR) -p '$(@D)'
-	$(RM) '$@'
-	$(CP) -P '$<' '$@'
-endef
-endif
+$(INSTALL_LIBRARIES_HERE)/minimal/%.debuginfo : $(INSTALL_LIBRARIES_HERE)/%.debuginfo
+	$(MKDIR) -p $(@D)
+	$(RM) $@
+	$(LN) -s ../$(@F) $@
+
+$(INSTALL_LIBRARIES_HERE)/minimal/%.diz : $(INSTALL_LIBRARIES_HERE)/%.diz
+	$(MKDIR) -p $(@D)
+	$(RM) $@
+	$(RM) $@.tmp $(basename $@).debuginfo
+	$(LN) -s ../$(basename $(@F)).debuginfo $(basename $@).debuginfo
+	$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo
+	$(RM) $(basename $@).debuginfo
+	$(MV) $@.tmp $@
 
 #######
 
diff --git a/jdk/makefiles/ProfileNames.gmk b/jdk/makefiles/ProfileNames.gmk
new file mode 100644
index 0000000..2e8640a
--- /dev/null
+++ b/jdk/makefiles/ProfileNames.gmk
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2012, 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.  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.
+#
+
+# This was split out from Profiles.gmk to allow GenSrcMisc.gmk to include it
+# without attempting to generate lists for output files that don't exist yet
+
+# These are the external names of each profile
+
+PROFILE_NAMES := compact1 compact2 compact3
+
+# The include files use 1,2,3,4 for simplicity and conciseness. Internally we
+# use profile_1, profile_2 and profile_3. Note that profile_4 is a full JRE so
+# we never have to use it directly.
+
+ALL_PROFILES := profile_1 profile_2 profile_3
+
+# This defines targets to generate per-profile Version.java/class files into
+# distinct locations
+
+VERSION_JAVA_DIR := sun/misc
+VERSION_JAVA_FILE := Version.java
+VERSION_JAVA_PATH := $(VERSION_JAVA_DIR)/$(VERSION_JAVA_FILE)
+VERSION_CLASS_PATH := $(VERSION_JAVA_PATH:.java=.class)
+
+PROFILE_VERSION_JAVA_TARGETS := $(foreach i, $(ALL_PROFILES), $(subst XXX,$i, $(JDK_OUTPUTDIR)/gen_XXX/$(VERSION_JAVA_PATH)))
+
+PROFILE_VERSION_CLASS_TARGETS := $(foreach i, $(PROFILE_VERSION_JAVA_TARGETS), $(i:.java=.class))
+
+# Function to map from profile designator, profile_1 etc, to its number
+profile_number = $(if $(patsubst profile_%,%, $(1)),$(patsubst profile_%,%, $(1)), $(words $(PROFILE_NAMES) extra))
+
+# Function to map from profile number, 1, 2 etc, to the corresponding name
+# An invalid number maps to an empty name
+profile_name = $(word $(1), $(PROFILE_NAMES))
+
+# Function to isolate a profile number from a Version.java target
+# Evaluates to the arg if the arg is not a profile version target
+profile_version_number = $(patsubst $(JDK_OUTPUTDIR)/gen_profile_%/$(VERSION_JAVA_PATH), %, $(1))
+
+# Function to go from a profile Version.java target to profile name. If not 
+# a profile version target then we need a number that maps to an empty name
+profile_version_name = $(word $(if $(filter-out $(call profile_version_number, $(1)), $(1)), $(call profile_version_number, $(1)), $(words $(PROFILE_NAMES) extra)), $(PROFILE_NAMES))
+
diff --git a/jdk/makefiles/Profiles.gmk b/jdk/makefiles/Profiles.gmk
new file mode 100644
index 0000000..864d98b
--- /dev/null
+++ b/jdk/makefiles/Profiles.gmk
@@ -0,0 +1,331 @@
+#
+# Copyright (c) 2012, 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.  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.
+#
+
+include ProfileNames.gmk
+
+# This defines the include lists for each profile, categorized as lib, bin
+# and other. We can use these to define the file lists for each profile
+# directly, rather than constructing a set of files to exclude from the
+# set of all files. But initially we will stick with generating exclude lists
+# as that is how the main build process already works.
+
+include profile-includes.txt
+
+###############################################################################
+# Per profile Jar lists
+#
+# These are the jar files to be built. In some builds these have to be
+# imported (signed jars) rather than built.
+#
+# The incoming lists, eg PROFILE_1_JRE_JARS_FILES, are the jars to be
+# included in this profile. They have the jar name relative to the lib 
+# directory. We have to turn these into targets by adding the 
+# $(IMAGES_OUTPUTDIR)/lib prefix
+#
+# Note that some jars may be optional depending on the type of build (jdk vs.
+# openjdk) and the platform.
+#
+# WARNING: incoming lists are currently validated for linux only!
+###############################################################################
+
+# These are jar files for which the contents vary depending on the profile
+CUSTOM_JARS := rt.jar resources.jar
+# This is used in Images.gmk
+CUSTOM_PROFILE_JARS := $(addprefix $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/, $(CUSTOM_JARS))
+
+# These are the common jar files built for and included with this profile
+# Filter out the custom jars and turn them into targets.
+
+PROFILE_1_JARS :=  \
+    $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(filter-out $(CUSTOM_JARS), $(PROFILE_1_JRE_JAR_FILES)))
+
+PROFILE_2_JARS := \
+    $(if $(PROFILE_2_JRE_JAR_FILES), $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_2_JRE_JAR_FILES))) \
+    $(PROFILE_1_JARS)
+
+ifneq ($(ENABLE_JFR), true)
+  PROFILE_3_JRE_JAR_FILES :=  $(filter-out jfr.jar, $(PROFILE_3_JRE_JAR_FILES))
+endif
+
+PROFILE_3_JARS := \
+    $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \
+    $(PROFILE_2_JARS)
+
+ifdef OPENJDK
+  PROFILE_4_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(PROFILE_4_JRE_JAR_FILES))
+endif
+
+PROFILE_4_JARS := \
+    $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_4_JRE_JAR_FILES)) \
+    $(PROFILE_3_JARS)
+
+# The full set of "jar" files needed for a complete JDK (ct.sym and src.zip
+# are also included.)
+# Note we need to add back the regular form of all the custom profile jars e.g.
+# rt.jar and resources.jar
+
+ALL_JARS := $(PROFILE_4_JARS) \
+        $(IMAGES_OUTPUTDIR)/lib/rt.jar \
+        $(IMAGES_OUTPUTDIR)/lib/resources.jar \
+        $(IMAGES_OUTPUTDIR)/lib/jconsole.jar \
+        $(IMAGES_OUTPUTDIR)/lib/dt.jar \
+        $(IMAGES_OUTPUTDIR)/lib/tools.jar \
+        $(IMAGES_OUTPUTDIR)/lib/ct.sym \
+        $(IMAGES_OUTPUTDIR)/src.zip \
+        $(IMAGES_OUTPUTDIR)/lib/ext/cldrdata.jar \
+        $(IMAGES_OUTPUTDIR)/lib/sa-jdi.jar
+
+ifeq ($(OPENJDK_TARGET_OS),solaris)
+    ifndef OPENJDK
+        ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/ucrypto.jar
+    endif
+endif
+
+ifeq ($(OPENJDK_TARGET_OS),windows)
+    ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar
+endif 
+
+ifeq ($(OPENJDK_TARGET_OS),macosx)
+    ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar
+endif
+
+ifeq ($(PROFILE), profile_1)
+    PROFILE_JARS := $(PROFILE_1_JARS)
+else ifeq ($(PROFILE), profile_2)
+    PROFILE_JARS := $(PROFILE_2_JARS)
+else ifeq ($(PROFILE), profile_3)
+    PROFILE_JARS := $(PROFILE_3_JARS)
+endif
+ifneq ($(PROFILE),)
+    JARS := $(CUSTOM_PROFILE_JARS) $(PROFILE_JARS)
+else
+    JARS := $(ALL_JARS)
+endif
+
+###############################################################################
+# JRE contents
+###############################################################################
+
+
+# we don't need to do anything if not building a profile
+ifneq ($(PROFILE),)
+
+
+# Need all files to generate the exclude lists
+NEW_ALL_BIN_LIST := $(patsubst $(JDK_OUTPUTDIR)/bin/%,%,$(shell $(FIND) $(JDK_OUTPUTDIR)/bin \( -type f -o -type l \) ! -name "sjavac"))
+
+ALL_JRE_BIN_FILES := \
+   $(PROFILE_1_JRE_BIN_FILES) \
+   $(PROFILE_2_JRE_BIN_FILES) \
+   $(PROFILE_3_JRE_BIN_FILES) \
+   $(PROFILE_4_JRE_BIN_FILES) 
+
+NOT_JRE_BIN_FILES := $(filter-out $(ALL_JRE_BIN_FILES), $(NEW_ALL_BIN_LIST))
+
+# Additional exclusions for profile JRE
+ifeq ($(PROFILE), profile_1)
+    NOT_JRE_BIN_FILES += \
+        $(PROFILE_2_JRE_BIN_FILES) \
+        $(PROFILE_3_JRE_BIN_FILES) \
+        $(PROFILE_4_JRE_BIN_FILES) 
+endif
+
+ifeq ($(PROFILE), profile_2)
+    NOT_JRE_BIN_FILES += \
+        $(PROFILE_3_JRE_BIN_FILES) \
+        $(PROFILE_4_JRE_BIN_FILES) 
+endif
+
+ifeq ($(PROFILE), profile_3)
+    NOT_JRE_BIN_FILES += \
+        $(PROFILE_4_JRE_BIN_FILES) 
+endif
+
+NOT_JRE_BIN_FILES := $(addprefix $(JDK_OUTPUTDIR)/bin/, $(NOT_JRE_BIN_FILES))
+
+# Need all files to generate the exclude lists
+NEW_ALL_LIB_LIST := $(patsubst $(JDK_OUTPUTDIR)/lib/%,%,$(shell $(FIND) $(JDK_OUTPUTDIR)/lib \( -type f -o -type l \) -a ! \( -name "_the*" -o -name "javac_state " \) ))
+NEW_ALL_LIB_LIST += $(patsubst $(IMAGES_OUTPUTDIR)/lib/%,%,$(shell $(FIND) $(IMAGES_OUTPUTDIR)/lib \( -type f -o -type l \) -a ! \( -name "_the*" -o -name "javac_state " \) ))
+
+ALL_JRE_LIB_FILES := \
+   $(PROFILE_1_JRE_LIB_FILES) \
+   $(PROFILE_2_JRE_LIB_FILES) \
+   $(PROFILE_3_JRE_LIB_FILES) \
+   $(PROFILE_4_JRE_LIB_FILES) 
+
+NOT_JRE_LIB_FILES := $(filter-out $(ALL_JRE_LIB_FILES), $(NEW_ALL_LIB_LIST))
+
+# Although these are NOT JRE lib files we have to filter them from the list
+# (ie cause them to be added them back in here) because the logic in
+# Images.gmk expects them to be there and handles them differently.
+# If we don't, they end up in the wrong place in the JDK image.
+# This needs fixing.
+NOT_JRE_LIB_FILES := $(filter-out $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)attach$(SHARED_LIBRARY_SUFFIX) $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(SALIB_NAME), $(NOT_JRE_LIB_FILES))
+
+# Additional exclusions for profile JREs
+ifeq ($(PROFILE), profile_1)
+    NOT_JRE_LIB_FILES += \
+        $(PROFILE_2_JRE_LIB_FILES) \
+        $(PROFILE_3_JRE_LIB_FILES) \
+        $(PROFILE_4_JRE_LIB_FILES) 
+endif
+
+ifeq ($(PROFILE), profile_2)
+    NOT_JRE_LIB_FILES += \
+        $(PROFILE_3_JRE_LIB_FILES) \
+        $(PROFILE_4_JRE_LIB_FILES) 
+endif
+
+ifeq ($(PROFILE), profile_3)
+    NOT_JRE_LIB_FILES += \
+        $(PROFILE_4_JRE_LIB_FILES) 
+endif
+
+# Exclude the custom jar files as these will be added back via a special rule
+NOT_JRE_LIB_FILES += $(CUSTOM_JARS)
+
+###############################################################################
+# Customization of rt.jar file contents
+# These are expressed as exclusions from everything found in the 
+# JDK_OUTPUTDIR/classes directory
+###############################################################################
+
+# The main set of excluded types/packages (ie everything not destined to be
+# part of rt.jar or resources.jar is captured in the CreateJars.gmk RT_JAR_EXCLUDES
+# variable. We add to that for the per-profile exclusion lists
+
+# For each profile we have four variables:
+#
+# - PROFILE_n_RTJAR_INCLUDE_PACKAGES
+#
+# This is a package prefix indicating that all classes in that package
+# and conditionally its subpackages are included in rt.jar for this profile.
+# The subpackages will be included as long as they do not appear in the
+# include list of a higher profile
+#
+# - PROFILE_n_RTJAR_INCLUDE_TYPES
+#
+# These are specific types that must be included within a package.
+# There are two cases:
+# - individual types in a package that is otherwise excluded at this 
+#   profile level. The only arises if there are split packages. 
+#
+# - A higher-level package is included in a high profile where a subpackage
+# is included in a lower profile. Including the package in the high profile
+# would exclude it and all subpackages from the lower profile, so instead
+# the classes in the package are listed for that higher profile (as *.class)
+#
+# These types are explicitly added back into the rt.jar content lists.
+#
+# - PROFILE_n_RTJAR_EXCLUDE_TYPES
+#
+# These are specific types that must be excluded even though most of the
+# containing package is include. Again this occurs with split packges.
+#
+# So the exclude list for each profile consists of the include lists
+# for all profiles above it, together with any explicitly excluded types. 
+# This is then combined with the overall RT_JAR_EXCLUDES list (which covers
+# things that go into other jar files).
+#
+# We also have to define the types to be explicitly included. This
+# accumulates up the profiles ie profile 3 has to include the types
+# that profiles 1 and 2 had to include. This is unnecessary if, for example,
+# profile 3 includes the entire package, but it is harmless to add them
+# explicitly, and complex to determine if we still need to include them.
+#
+# Need a way to express: 
+#  for (int i = profile+1; i < 4; i++)
+#     RT_JAR_EXCLUDES += PROFILE_$i_RTJAR_INCLUDE_PACKAGES
+#
+# Do it the long way for now
+#
+# - PROFILE_n_INCLUDE_METAINF_SERVICES
+#
+# These are META-INF/services/ entries found in resources.jar. Together
+# resources.jar and rt.jar hold the contents of the classes directory, (the
+# classes in rt.jar and everything else in resources.jar).Hence the 
+# include/exclude information for resources.jar is tied to that of rt.jar
+
+include profile-rtjar-includes.txt
+
+# Function to expand foo/*.class into the set of classes
+# NOTE: Classfiles with $ in their name are problematic as that is the
+# meta-character for both make and the shell! Hence the \$$$$ substitution.
+# But note that if you echo these values they will NOT display as expected.
+class_list =  $(patsubst $(JDK_OUTPUTDIR)/classes/%,%,\
+     $(foreach i,$(1), $(subst $$,\$$$$, $(wildcard $(JDK_OUTPUTDIR)/classes/$i))))
+
+ifeq ($(PROFILE), profile_1)
+  RT_JAR_EXCLUDES += \
+    $(PROFILE_1_RTJAR_EXCLUDE_TYPES) \
+    $(PROFILE_2_RTJAR_INCLUDE_PACKAGES) \
+    $(call class_list, $(PROFILE_2_RTJAR_INCLUDE_TYPES)) \
+    $(PROFILE_3_RTJAR_INCLUDE_PACKAGES) \
+    $(call class_list, $(PROFILE_3_RTJAR_INCLUDE_TYPES)) \
+    $(PROFILE_4_RTJAR_INCLUDE_PACKAGES) \
+    $(call class_list, $(PROFILE_4_RTJAR_INCLUDE_TYPES))
+  RT_JAR_INCLUDE_TYPES := \
+	$(call class_list, $(PROFILE_1_RTJAR_INCLUDE_TYPES))
+  PROFILE_INCLUDE_METAINF_SERVICES := \
+    $(PROFILE_1_INCLUDE_METAINF_SERVICES)
+endif
+ifeq ($(PROFILE), profile_2)
+  RT_JAR_EXCLUDES += \
+    $(PROFILE_2_RTJAR_EXCLUDE_TYPES) \
+    $(PROFILE_3_RTJAR_INCLUDE_PACKAGES) \
+    $(call class_list, $(PROFILE_3_RTJAR_INCLUDE_TYPES)) \
+    $(PROFILE_4_RTJAR_INCLUDE_PACKAGES) \
+    $(call class_list, $(PROFILE_4_RTJAR_INCLUDE_TYPES))
+  RT_JAR_INCLUDE_TYPES := \
+	$(call class_list, $(PROFILE_1_RTJAR_INCLUDE_TYPES)) \
+	$(call class_list, $(PROFILE_2_RTJAR_INCLUDE_TYPES))
+  PROFILE_INCLUDE_METAINF_SERVICES := \
+    $(PROFILE_1_INCLUDE_METAINF_SERVICES) \
+    $(PROFILE_2_INCLUDE_METAINF_SERVICES)
+endif
+ifeq ($(PROFILE), profile_3)
+  RT_JAR_EXCLUDES += \
+    $(PROFILE_3_RTJAR_EXCLUDE_TYPES) \
+    $(PROFILE_4_RTJAR_INCLUDE_PACKAGES) \
+    $(call class_list, $(PROFILE_4_RTJAR_INCLUDE_TYPES))
+  RT_JAR_INCLUDE_TYPES := \
+	$(call class_list, $(PROFILE_1_RTJAR_INCLUDE_TYPES)) \
+	$(call class_list, $(PROFILE_2_RTJAR_INCLUDE_TYPES)) \
+	$(call class_list, $(PROFILE_3_RTJAR_INCLUDE_TYPES))
+  PROFILE_INCLUDE_METAINF_SERVICES := \
+    $(PROFILE_1_INCLUDE_METAINF_SERVICES) \
+    $(PROFILE_2_INCLUDE_METAINF_SERVICES) \
+    $(PROFILE_3_INCLUDE_METAINF_SERVICES)
+endif
+
+# Filter out non-OpenJDK services
+ifdef OPENJDK
+  EXCLUDED_SERVICES := META-INF/services/javax.script.ScriptEngineFactory 
+  PROFILE_INCLUDE_METAINF_SERVICES := $(filter-out $(EXCLUDED_SERVICES),$(PROFILE_INCLUDE_METAINF_SERVICES))
+endif
+
+
+endif # profile
+
diff --git a/jdk/makefiles/Tools.gmk b/jdk/makefiles/Tools.gmk
index 811dd47..360cbe40 100644
--- a/jdk/makefiles/Tools.gmk
+++ b/jdk/makefiles/Tools.gmk
@@ -53,6 +53,14 @@
 
 BUILD_TOOLS += $(foreach i,$(wildcard $(JDK_TOPDIR)/src/share/classes/javax/swing/plaf/nimbus/*.template),$(JDK_OUTPUTDIR)/btclasses/build/tools/generatenimbus/resources/$(notdir $i))
 
+# Resources used by CheckDeps tool
+$(JDK_OUTPUTDIR)/btclasses/build/tools/deps/% : \
+	$(JDK_TOPDIR)/make/tools/src/build/tools/deps/%
+	$(MKDIR) -p $(@D)
+	$(CP) $< $@
+
+BUILD_TOOLS += $(JDK_OUTPUTDIR)/btclasses/build/tools/deps/refs.allowed
+
 # Add a checksum ("jsum") to the end of a text file. Prevents trivial tampering with class lists.
 TOOL_ADDJSUM=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
 	build.tools.addjsum.AddJsum
@@ -103,9 +111,6 @@
 TOOL_JARSPLIT=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
 	build.tools.jarsplit.JarSplit
 
-TOOL_JAVAZIC=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
-	build.tools.javazic.Main
-
 TOOL_TZDB=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
 	build.tools.tzdb.TzdbZoneRulesCompiler
 
@@ -140,6 +145,14 @@
 TOOL_CLDRCONVERTER=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
 	build.tools.cldrconverter.CLDRConverter
 
+TOOL_REMOVEMETHODS=$(JAVA) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
+    -cp $(JDK_OUTPUTDIR)/btclasses:$(JDK_OUTPUTDIR) \
+        build.tools.classfile.RemoveMethods
+
+TOOL_CHECKDEPS=$(JAVA) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
+    -cp $(JDK_OUTPUTDIR)/btclasses:$(JDK_OUTPUTDIR) \
+        build.tools.deps.CheckDeps
+
 ##########################################################################################
 
 # Tools needed on solaris because OBJCOPY is broken.
diff --git a/jdk/makefiles/profile-includes.txt b/jdk/makefiles/profile-includes.txt
new file mode 100644
index 0000000..2472bae
--- /dev/null
+++ b/jdk/makefiles/profile-includes.txt
@@ -0,0 +1,258 @@
+#
+# Copyright (c) 2012, 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.  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.
+#
+PROFILE_1_JRE_BIN_FILES := \
+    java$(EXE_SUFFIX) \
+    keytool$(EXE_SUFFIX)
+
+PROFILE_1_JRE_LIB_FILES := \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)java$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsig.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)net$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)nio$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)npt$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)npt.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)verify$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)verify.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)zip$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/$(LIBRARY_PREFIX)jsig.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/$(LIBRARY_PREFIX)jvm.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/client/Xusage.txt \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/jli/$(LIBRARY_PREFIX)jli$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/jvm.cfg \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/$(LIBRARY_PREFIX)jsig.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/$(LIBRARY_PREFIX)jvm.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/minimal/Xusage.txt \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jsig.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/Xusage.txt \
+    calendars.properties \
+    classlist \
+    content-types.properties \
+    currency.data \
+    ext/localedata.jar \
+    ext/meta-index \
+    ext/sunjce_provider.jar \
+    jce.jar \
+    jsse.jar \
+    logging.properties \
+    meta-index \
+    net.properties \
+    resources.jar \
+    rt.jar \
+    security/US_export_policy.jar \
+    security/blacklist \
+    security/cacerts \
+    security/java.policy \
+    security/java.security \
+    security/local_policy.jar \
+    security/trusted.libraries \
+    tzdb.jar
+
+PROFILE_1_JRE_OTHER_FILES := \
+    COPYRIGHT \
+    LICENSE \
+    README \
+    THIRDPARTYLICENSEREADME.txt \
+    Welcome.html \
+    release
+
+PROFILE_1_JRE_JAR_FILES := \
+    ext/localedata.jar \
+    ext/sunjce_provider.jar \
+    jce.jar \
+    jsse.jar \
+    resources.jar \
+    rt.jar \
+    security/US_export_policy.jar \
+    security/local_policy.jar \
+    tzdb.jar
+
+
+PROFILE_2_JRE_BIN_FILES := \
+    rmid$(EXE_SUFFIX) \
+    rmiregistry$(EXE_SUFFIX)
+
+PROFILE_2_JRE_LIB_FILES := 
+
+PROFILE_2_JRE_OTHER_FILES := 
+
+PROFILE_2_JRE_JAR_FILES := 
+
+
+PROFILE_3_JRE_BIN_FILES := 
+
+PROFILE_3_JRE_LIB_FILES := \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)hprof$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)hprof.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)instrument$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)instrument.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)j2gss$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)j2pcsc$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jaas_unix$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)java_crw_demo$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)java_crw_demo.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jfr$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsdt$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsdt.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)management$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)management.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)sctp$(SHARED_LIBRARY_SUFFIX) \
+    jfr.jar \
+    jvm.hprof.txt \
+    management-agent.jar \
+    management/jmxremote.access \
+    management/jmxremote.password.template \
+    management/management.properties \
+    management/snmp.acl.template
+
+PROFILE_3_JRE_OTHER_FILES := 
+
+PROFILE_3_JRE_JAR_FILES := \
+    jfr.jar \
+    management-agent.jar
+
+
+PROFILE_4_JRE_BIN_FILES := \
+    orbd$(EXE_SUFFIX) \
+    pack200$(EXE_SUFFIX) \
+    policytool$(EXE_SUFFIX) \
+    servertool$(EXE_SUFFIX) \
+    tnameserv$(EXE_SUFFIX) \
+    unpack200$(EXE_SUFFIX)
+
+PROFILE_4_JRE_LIB_FILES := \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt_headless$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt_xawt$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)dcpr$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)dt_socket$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)dt_socket.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)fontmanager$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)j2pkcs11$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jawt$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jdwp$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jpeg$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsound$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsoundalsa$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)kcms$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)mlib_image$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)splashscreen$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)sunec$(SHARED_LIBRARY_SUFFIX) \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \
+    alt-rt.jar \
+    charsets.jar \
+    cmm/CIEXYZ.pf \
+    cmm/GRAY.pf \
+    cmm/LINEAR_RGB.pf \
+    cmm/PYCC.pf \
+    cmm/sRGB.pf \
+    ext/cldrdata.jar \
+    ext/dnsns.jar \
+    ext/sunec.jar \
+    ext/sunpkcs11.jar \
+    ext/zipfs.jar \
+    flavormap.properties \
+    fontconfig.RedHat.5.bfc \
+    fontconfig.RedHat.5.properties.src \
+    fontconfig.RedHat.6.bfc \
+    fontconfig.RedHat.6.properties.src \
+    fontconfig.SuSE.10.bfc \
+    fontconfig.SuSE.10.properties.src \
+    fontconfig.SuSE.11.bfc \
+    fontconfig.SuSE.11.properties.src \
+    fontconfig.Turbo.bfc \
+    fontconfig.Turbo.properties.src \
+    fontconfig.bfc \
+    fontconfig.properties.src \
+    fonts/LucidaBrightDemiBold.ttf \
+    fonts/LucidaBrightDemiItalic.ttf \
+    fonts/LucidaBrightItalic.ttf \
+    fonts/LucidaBrightRegular.ttf \
+    fonts/LucidaSansDemiBold.ttf \
+    fonts/LucidaSansRegular.ttf \
+    fonts/LucidaTypewriterBold.ttf \
+    fonts/LucidaTypewriterRegular.ttf \
+    fonts/fonts.dir \
+    images/cursors/cursors.properties \
+    images/cursors/invalid32x32.gif \
+    images/cursors/motif_CopyDrop32x32.gif \
+    images/cursors/motif_CopyNoDrop32x32.gif \
+    images/cursors/motif_LinkDrop32x32.gif \
+    images/cursors/motif_LinkNoDrop32x32.gif \
+    images/cursors/motif_MoveDrop32x32.gif \
+    images/cursors/motif_MoveNoDrop32x32.gif \
+    jexec \
+    oblique-fonts/LucidaSansDemiOblique.ttf \
+    oblique-fonts/LucidaSansOblique.ttf \
+    oblique-fonts/LucidaTypewriterBoldOblique.ttf \
+    oblique-fonts/LucidaTypewriterOblique.ttf \
+    oblique-fonts/fonts.dir \
+    psfont.properties.ja \
+    psfontj2d.properties \
+    servicetag/jdk_header.png \
+    sound.properties
+
+PROFILE_4_JRE_OTHER_FILES := \
+    man/ja_JP.UTF-8/man1/java.1 \
+    man/ja_JP.UTF-8/man1/javaws.1 \
+    man/ja_JP.UTF-8/man1/keytool.1 \
+    man/ja_JP.UTF-8/man1/orbd.1 \
+    man/ja_JP.UTF-8/man1/pack200.1 \
+    man/ja_JP.UTF-8/man1/policytool.1 \
+    man/ja_JP.UTF-8/man1/rmid.1 \
+    man/ja_JP.UTF-8/man1/rmiregistry.1 \
+    man/ja_JP.UTF-8/man1/servertool.1 \
+    man/ja_JP.UTF-8/man1/tnameserv.1 \
+    man/ja_JP.UTF-8/man1/unpack200.1 \
+    man/man1/java.1 \
+    man/man1/javaws.1 \
+    man/man1/keytool.1 \
+    man/man1/orbd.1 \
+    man/man1/pack200.1 \
+    man/man1/policytool.1 \
+    man/man1/rmid.1 \
+    man/man1/rmiregistry.1 \
+    man/man1/servertool.1 \
+    man/man1/tnameserv.1 \
+    man/man1/unpack200.1
+
+PROFILE_4_JRE_JAR_FILES := \
+    alt-rt.jar \
+    charsets.jar \
+    ext/cldrdata.jar \
+    ext/dnsns.jar \
+    ext/sunec.jar \
+    ext/sunpkcs11.jar \
+    ext/zipfs.jar
+
+
diff --git a/jdk/makefiles/profile-rtjar-includes.txt b/jdk/makefiles/profile-rtjar-includes.txt
new file mode 100644
index 0000000..4722727
--- /dev/null
+++ b/jdk/makefiles/profile-rtjar-includes.txt
@@ -0,0 +1,926 @@
+#
+# Copyright (c) 2012, 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.  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.
+#
+PROFILE_1_RTJAR_INCLUDE_PACKAGES := \
+    com/sun/demo/jvmti/hprof \
+    com/sun/java/util/jar/pack \
+    com/sun/net/ssl \
+    com/sun/net/ssl/internal/www/protocol/https \
+    com/sun/nio/file \
+    com/sun/security/cert/internal/x509 \
+    java/io \
+    java/lang \
+    java/lang/annotation \
+    java/lang/invoke \
+    java/lang/ref \
+    java/lang/reflect \
+    java/math \
+    java/net \
+    java/nio \
+    java/nio/channels \
+    java/nio/channels/spi \
+    java/nio/charset \
+    java/nio/charset/spi \
+    java/nio/file \
+    java/nio/file/attribute \
+    java/nio/file/spi \
+    java/security \
+    java/security/cert \
+    java/security/interfaces \
+    java/security/spec \
+    java/text \
+    java/text/spi \
+    java/time \
+    java/util \
+    java/util/concurrent \
+    java/util/concurrent/atomic \
+    java/util/concurrent/locks \
+    java/util/function \
+    java/util/jar \
+    java/util/logging \
+    java/util/regex \
+    java/util/spi \
+    java/util/zip \
+    javax/net \
+    javax/net/ssl \
+    javax/security/auth \
+    javax/security/auth/callback \
+    javax/security/auth/login \
+    javax/security/auth/spi \
+    javax/security/auth/x500 \
+    javax/security/cert \
+    jdk/internal \
+    sun/invoke \
+    sun/invoke/anon \
+    sun/invoke/empty \
+    sun/invoke/util \
+    sun/launcher \
+    sun/launcher/resources \
+    sun/misc \
+    sun/misc/resources \
+    sun/net/ \
+    sun/net/idn \
+    sun/net/sdp \
+    sun/net/spi \
+    sun/net/spi/nameservice \
+    sun/net/util \
+    sun/net/www \
+    sun/net/www/http \
+    sun/net/www/protocol/file \
+    sun/net/www/protocol/http/ \
+    sun/net/www/protocol/http/logging \
+    sun/net/www/protocol/https \
+    sun/net/www/protocol/jar \
+    sun/nio \
+    sun/nio/ch \
+    sun/nio/cs \
+    sun/nio/fs \
+    sun/reflect \
+    sun/reflect/annotation \
+    sun/reflect/generics/factory \
+    sun/reflect/generics/parser \
+    sun/reflect/generics/reflectiveObjects \
+    sun/reflect/generics/repository \
+    sun/reflect/generics/scope \
+    sun/reflect/generics/tree \
+    sun/reflect/generics/visitor \
+    sun/reflect/misc \
+    sun/security/action \
+    sun/security/ec \
+    sun/security/jca \
+    sun/security/pkcs \
+    sun/security/pkcs10 \
+    sun/security/pkcs12 \
+    sun/security/provider \
+    sun/security/provider/certpath \
+    sun/security/provider/certpath/ssl \
+    sun/security/rsa \
+    sun/security/timestamp \
+    sun/security/tools \
+    sun/security/tools/keytool \
+    sun/security/util \
+    sun/security/validator \
+    sun/security/x509 \
+    sun/text \
+    sun/text/bidi \
+    sun/text/normalizer \
+    sun/text/resources \
+    sun/usagetracker \
+    sun/util \
+    sun/util/calendar \
+    sun/util/locale \
+    sun/util/logging \
+    sun/util/logging/resources \
+    sun/util/resources
+
+PROFILE_1_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_1_RTJAR_EXCLUDE_TYPES := 
+
+PROFILE_1_INCLUDE_METAINF_SERVICES := 
+
+
+PROFILE_2_RTJAR_INCLUDE_PACKAGES := \
+    com/sun/java_cup/internal/runtime \
+    com/sun/net/httpserver \
+    com/sun/net/httpserver/spi \
+    com/sun/org/apache/bcel/internal \
+    com/sun/org/apache/bcel/internal/classfile \
+    com/sun/org/apache/bcel/internal/generic \
+    com/sun/org/apache/bcel/internal/util \
+    com/sun/org/apache/regexp/internal \
+    com/sun/org/apache/xalan/internal \
+    com/sun/org/apache/xalan/internal/extensions \
+    com/sun/org/apache/xalan/internal/lib \
+    com/sun/org/apache/xalan/internal/res \
+    com/sun/org/apache/xalan/internal/templates \
+    com/sun/org/apache/xalan/internal/utils \
+    com/sun/org/apache/xalan/internal/xslt \
+    com/sun/org/apache/xalan/internal/xsltc \
+    com/sun/org/apache/xalan/internal/xsltc/cmdline \
+    com/sun/org/apache/xalan/internal/xsltc/cmdline/getopt \
+    com/sun/org/apache/xalan/internal/xsltc/compiler \
+    com/sun/org/apache/xalan/internal/xsltc/compiler/util \
+    com/sun/org/apache/xalan/internal/xsltc/dom \
+    com/sun/org/apache/xalan/internal/xsltc/runtime \
+    com/sun/org/apache/xalan/internal/xsltc/runtime/output \
+    com/sun/org/apache/xalan/internal/xsltc/trax \
+    com/sun/org/apache/xalan/internal/xsltc/util \
+    com/sun/org/apache/xerces/internal/dom \
+    com/sun/org/apache/xerces/internal/dom/events \
+    com/sun/org/apache/xerces/internal/impl \
+    com/sun/org/apache/xerces/internal/impl/dtd \
+    com/sun/org/apache/xerces/internal/impl/dtd/models \
+    com/sun/org/apache/xerces/internal/impl/dv \
+    com/sun/org/apache/xerces/internal/impl/dv/dtd \
+    com/sun/org/apache/xerces/internal/impl/dv/util \
+    com/sun/org/apache/xerces/internal/impl/dv/xs \
+    com/sun/org/apache/xerces/internal/impl/io \
+    com/sun/org/apache/xerces/internal/impl/msg \
+    com/sun/org/apache/xerces/internal/impl/validation \
+    com/sun/org/apache/xerces/internal/impl/xpath \
+    com/sun/org/apache/xerces/internal/impl/xpath/regex \
+    com/sun/org/apache/xerces/internal/impl/xs \
+    com/sun/org/apache/xerces/internal/impl/xs/identity \
+    com/sun/org/apache/xerces/internal/impl/xs/models \
+    com/sun/org/apache/xerces/internal/impl/xs/opti \
+    com/sun/org/apache/xerces/internal/impl/xs/traversers \
+    com/sun/org/apache/xerces/internal/impl/xs/util \
+    com/sun/org/apache/xerces/internal/jaxp \
+    com/sun/org/apache/xerces/internal/jaxp/datatype \
+    com/sun/org/apache/xerces/internal/jaxp/validation \
+    com/sun/org/apache/xerces/internal/parsers \
+    com/sun/org/apache/xerces/internal/util \
+    com/sun/org/apache/xerces/internal/utils \
+    com/sun/org/apache/xerces/internal/xinclude \
+    com/sun/org/apache/xerces/internal/xni \
+    com/sun/org/apache/xerces/internal/xni/grammars \
+    com/sun/org/apache/xerces/internal/xni/parser \
+    com/sun/org/apache/xerces/internal/xpointer \
+    com/sun/org/apache/xerces/internal/xs \
+    com/sun/org/apache/xerces/internal/xs/datatypes \
+    com/sun/org/apache/xml/internal/dtm \
+    com/sun/org/apache/xml/internal/dtm/ref \
+    com/sun/org/apache/xml/internal/dtm/ref/dom2dtm \
+    com/sun/org/apache/xml/internal/dtm/ref/sax2dtm \
+    com/sun/org/apache/xml/internal/res \
+    com/sun/org/apache/xml/internal/resolver \
+    com/sun/org/apache/xml/internal/resolver/helpers \
+    com/sun/org/apache/xml/internal/resolver/readers \
+    com/sun/org/apache/xml/internal/resolver/tools \
+    com/sun/org/apache/xml/internal/serialize \
+    com/sun/org/apache/xml/internal/serializer \
+    com/sun/org/apache/xml/internal/serializer/utils \
+    com/sun/org/apache/xml/internal/utils \
+    com/sun/org/apache/xml/internal/utils/res \
+    com/sun/org/apache/xpath/internal \
+    com/sun/org/apache/xpath/internal/axes \
+    com/sun/org/apache/xpath/internal/compiler \
+    com/sun/org/apache/xpath/internal/domapi \
+    com/sun/org/apache/xpath/internal/functions \
+    com/sun/org/apache/xpath/internal/jaxp \
+    com/sun/org/apache/xpath/internal/objects \
+    com/sun/org/apache/xpath/internal/operations \
+    com/sun/org/apache/xpath/internal/patterns \
+    com/sun/org/apache/xpath/internal/res \
+    com/sun/rmi/rmid \
+    com/sun/xml/internal/stream/ \
+    com/sun/xml/internal/stream/dtd \
+    com/sun/xml/internal/stream/dtd/nonvalidating \
+    com/sun/xml/internal/stream/events \
+    com/sun/xml/internal/stream/util \
+    com/sun/xml/internal/stream/writers \
+    java/rmi \
+    java/rmi/activation \
+    java/rmi/dgc \
+    java/rmi/registry \
+    java/rmi/server \
+    java/sql \
+    javax/rmi/ssl \
+    javax/sql \
+    javax/transaction \
+    javax/transaction/xa \
+    javax/xml \
+    javax/xml/datatype \
+    javax/xml/namespace \
+    javax/xml/parsers \
+    javax/xml/stream \
+    javax/xml/stream/events \
+    javax/xml/stream/util \
+    javax/xml/transform \
+    javax/xml/transform/dom \
+    javax/xml/transform/sax \
+    javax/xml/transform/stax \
+    javax/xml/transform/stream \
+    javax/xml/validation \
+    javax/xml/xpath \
+    org/w3c/dom \
+    org/w3c/dom/bootstrap \
+    org/w3c/dom/css \
+    org/w3c/dom/events \
+    org/w3c/dom/html \
+    org/w3c/dom/ls \
+    org/w3c/dom/ranges \
+    org/w3c/dom/stylesheets \
+    org/w3c/dom/traversal \
+    org/w3c/dom/views \
+    org/w3c/dom/xpath \
+    org/xml/sax \
+    org/xml/sax/ext \
+    org/xml/sax/helpers \
+    sun/net/httpserver \
+    sun/rmi/log \
+    sun/rmi/registry \
+    sun/rmi/runtime \
+    sun/rmi/server \
+    sun/rmi/transport \
+    sun/rmi/transport/proxy \
+    sun/rmi/transport/tcp \
+    sun/util/xml
+
+PROFILE_2_RTJAR_INCLUDE_TYPES := 
+
+PROFILE_2_RTJAR_EXCLUDE_TYPES := 
+
+PROFILE_2_INCLUDE_METAINF_SERVICES := \
+    META-INF/services/sun.util.spi.XmlPropertiesProvider
+
+
+PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
+    com/sun/jmx/defaults \
+    com/sun/jmx/interceptor \
+    com/sun/jmx/mbeanserver \
+    com/sun/jmx/remote/internal \
+    com/sun/jmx/remote/protocol/rmi \
+    com/sun/jmx/remote/security \
+    com/sun/jmx/remote/util \
+    com/sun/jmx/snmp \
+    com/sun/jmx/snmp/IPAcl \
+    com/sun/jmx/snmp/agent \
+    com/sun/jmx/snmp/daemon \
+    com/sun/jmx/snmp/defaults \
+    com/sun/jmx/snmp/internal \
+    com/sun/jmx/snmp/mpm \
+    com/sun/jmx/snmp/tasks \
+    com/sun/jmx/trace \
+    com/sun/jndi/dns \
+    com/sun/jndi/ldap \
+    com/sun/jndi/ldap/ext \
+    com/sun/jndi/ldap/pool \
+    com/sun/jndi/ldap/sasl \
+    com/sun/jndi/rmi/registry \
+    com/sun/jndi/toolkit/ctx \
+    com/sun/jndi/toolkit/dir \
+    com/sun/jndi/toolkit/url \
+    com/sun/jndi/url/dns \
+    com/sun/jndi/url/ldap \
+    com/sun/jndi/url/ldaps \
+    com/sun/jndi/url/rmi \
+    com/sun/management \
+    com/sun/management/jmx \
+    com/sun/naming/internal \
+    com/sun/nio/sctp \
+    com/sun/org/apache/xml/internal/security \
+    com/sun/org/apache/xml/internal/security/algorithms \
+    com/sun/org/apache/xml/internal/security/algorithms/implementations \
+    com/sun/org/apache/xml/internal/security/c14n \
+    com/sun/org/apache/xml/internal/security/c14n/helper \
+    com/sun/org/apache/xml/internal/security/c14n/implementations \
+    com/sun/org/apache/xml/internal/security/encryption \
+    com/sun/org/apache/xml/internal/security/exceptions \
+    com/sun/org/apache/xml/internal/security/keys \
+    com/sun/org/apache/xml/internal/security/keys/content \
+    com/sun/org/apache/xml/internal/security/keys/content/keyvalues \
+    com/sun/org/apache/xml/internal/security/keys/content/x509 \
+    com/sun/org/apache/xml/internal/security/keys/keyresolver \
+    com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations \
+    com/sun/org/apache/xml/internal/security/keys/storage \
+    com/sun/org/apache/xml/internal/security/keys/storage/implementations \
+    com/sun/org/apache/xml/internal/security/signature \
+    com/sun/org/apache/xml/internal/security/transforms \
+    com/sun/org/apache/xml/internal/security/transforms/implementations \
+    com/sun/org/apache/xml/internal/security/transforms/params \
+    com/sun/org/apache/xml/internal/security/utils \
+    com/sun/org/apache/xml/internal/security/utils/resolver \
+    com/sun/org/apache/xml/internal/security/utils/resolver/implementations \
+    com/sun/rowset \
+    com/sun/rowset/internal \
+    com/sun/rowset/providers \
+    com/sun/script/javascript \
+    com/sun/script/util \
+    com/sun/security/auth/callback \
+    com/sun/security/auth/login \
+    com/sun/security/auth/module \
+    com/sun/security/jgss \
+    com/sun/security/ntlm \
+    com/sun/security/sasl \
+    com/sun/security/sasl/digest \
+    com/sun/security/sasl/gsskerb \
+    com/sun/security/sasl/ntlm \
+    com/sun/security/sasl/util \
+    com/sun/tracing \
+    com/sun/tracing/dtrace \
+    java/lang/instrument \
+    java/lang/management \
+    java/security/acl \
+    java/util/prefs \
+    javax/annotation/processing \
+    javax/lang/model \
+    javax/lang/model/element \
+    javax/lang/model/type \
+    javax/lang/model/util \
+    javax/management \
+    javax/management/loading \
+    javax/management/modelmbean \
+    javax/management/monitor \
+    javax/management/openmbean \
+    javax/management/relation \
+    javax/management/remote \
+    javax/management/remote/rmi \
+    javax/management/timer \
+    javax/naming \
+    javax/naming/directory \
+    javax/naming/event \
+    javax/naming/ldap \
+    javax/naming/spi \
+    javax/script \
+    javax/security/auth/kerberos \
+    javax/security/sasl \
+    javax/smartcardio \
+    javax/sql/rowset \
+    javax/sql/rowset/serial \
+    javax/sql/rowset/spi \
+    javax/tools \
+    javax/tools/annotation \
+    javax/xml/crypto \
+    javax/xml/crypto/dom \
+    javax/xml/crypto/dsig \
+    javax/xml/crypto/dsig/dom \
+    javax/xml/crypto/dsig/keyinfo \
+    javax/xml/crypto/dsig/spec \
+    org/ietf/jgss \
+    org/jcp/xml/dsig/internal \
+    org/jcp/xml/dsig/internal/dom \
+    sun/instrument \
+    sun/management \
+    sun/management/counter \
+    sun/management/counter/perf \
+    sun/management/jmxremote \
+    sun/management/resources \
+    sun/management/snmp \
+    sun/management/snmp/jvminstr \
+    sun/management/snmp/jvmmib \
+    sun/management/snmp/util \
+    sun/net/dns \
+    sun/net/www/protocol/http/ntlm \
+    sun/net/www/protocol/http/spnego \
+    sun/nio/ch/sctp \
+    sun/org/mozilla/classfile/internal \
+    sun/org/mozilla/javascript/internal \
+    sun/org/mozilla/javascript/internal/annotations \
+    sun/org/mozilla/javascript/internal/ast \
+    sun/org/mozilla/javascript/internal/debug \
+    sun/org/mozilla/javascript/internal/jdk13 \
+    sun/org/mozilla/javascript/internal/jdk15 \
+    sun/org/mozilla/javascript/internal/json \
+    sun/org/mozilla/javascript/internal/optimizer \
+    sun/org/mozilla/javascript/internal/regexp \
+    sun/org/mozilla/javascript/internal/serialize \
+    sun/org/mozilla/javascript/internal/xml \
+    sun/org/mozilla/javascript/internal/xmlimpl \
+    sun/security/acl \
+    sun/security/jgss \
+    sun/security/jgss/krb5 \
+    sun/security/jgss/spi \
+    sun/security/jgss/spnego \
+    sun/security/jgss/wrapper \
+    sun/security/krb5 \
+    sun/security/krb5/internal \
+    sun/security/krb5/internal/ccache \
+    sun/security/krb5/internal/crypto \
+    sun/security/krb5/internal/crypto/dk \
+    sun/security/krb5/internal/ktab \
+    sun/security/krb5/internal/rcache \
+    sun/security/krb5/internal/util \
+    sun/security/provider/certpath/ldap \
+    sun/security/smartcardio \
+    sun/tracing \
+    sun/tracing/dtrace
+
+PROFILE_3_RTJAR_INCLUDE_TYPES := \
+    com/sun/security/auth/*.class
+
+PROFILE_3_RTJAR_EXCLUDE_TYPES := \
+    javax/management/remote/rmi/_RMIConnectionImpl_Tie.class \
+    javax/management/remote/rmi/_RMIConnection_Stub.class \
+    javax/management/remote/rmi/_RMIServerImpl_Tie.class \
+    javax/management/remote/rmi/_RMIServer_Stub.class \
+    com/sun/security/auth/callback/DialogCallbackHandler.class \
+    com/sun/security/auth/callback/DialogCallbackHandler\$$$$1.class \
+    com/sun/security/auth/callback/DialogCallbackHandler\$$$$2.class \
+    com/sun/security/auth/callback/DialogCallbackHandler\$$$$Action.class \
+    com/sun/security/auth/callback/DialogCallbackHandler\$$$$ConfirmationInfo.class
+
+PROFILE_3_INCLUDE_METAINF_SERVICES := \
+    META-INF/services/javax.script.ScriptEngineFactory 
+
+
+PROFILE_4_RTJAR_INCLUDE_PACKAGES := \
+    com/oracle/net \
+    com/oracle/nio \
+    com/oracle/util \
+    com/sun/accessibility/internal/resources \
+    com/sun/activation/registries \
+    com/sun/awt \
+    com/sun/beans \
+    com/sun/beans/decoder \
+    com/sun/beans/finder \
+    com/sun/corba/se/impl/activation \
+    com/sun/corba/se/impl/copyobject \
+    com/sun/corba/se/impl/corba \
+    com/sun/corba/se/impl/dynamicany \
+    com/sun/corba/se/impl/encoding \
+    com/sun/corba/se/impl/interceptors \
+    com/sun/corba/se/impl/io \
+    com/sun/corba/se/impl/ior \
+    com/sun/corba/se/impl/ior/iiop \
+    com/sun/corba/se/impl/javax/rmi \
+    com/sun/corba/se/impl/javax/rmi/CORBA \
+    com/sun/corba/se/impl/legacy/connection \
+    com/sun/corba/se/impl/logging \
+    com/sun/corba/se/impl/monitoring \
+    com/sun/corba/se/impl/naming/cosnaming \
+    com/sun/corba/se/impl/naming/namingutil \
+    com/sun/corba/se/impl/naming/pcosnaming \
+    com/sun/corba/se/impl/oa \
+    com/sun/corba/se/impl/oa/poa \
+    com/sun/corba/se/impl/oa/toa \
+    com/sun/corba/se/impl/orb \
+    com/sun/corba/se/impl/orbutil \
+    com/sun/corba/se/impl/orbutil/closure \
+    com/sun/corba/se/impl/orbutil/concurrent \
+    com/sun/corba/se/impl/orbutil/fsm \
+    com/sun/corba/se/impl/orbutil/graph \
+    com/sun/corba/se/impl/orbutil/threadpool \
+    com/sun/corba/se/impl/presentation/rmi \
+    com/sun/corba/se/impl/protocol \
+    com/sun/corba/se/impl/protocol/giopmsgheaders \
+    com/sun/corba/se/impl/resolver \
+    com/sun/corba/se/impl/transport \
+    com/sun/corba/se/impl/util \
+    com/sun/corba/se/internal/CosNaming \
+    com/sun/corba/se/internal/Interceptors \
+    com/sun/corba/se/internal/POA \
+    com/sun/corba/se/internal/corba \
+    com/sun/corba/se/internal/iiop \
+    com/sun/corba/se/org/omg/CORBA \
+    com/sun/corba/se/pept/broker \
+    com/sun/corba/se/pept/encoding \
+    com/sun/corba/se/pept/protocol \
+    com/sun/corba/se/pept/transport \
+    com/sun/corba/se/spi/activation \
+    com/sun/corba/se/spi/activation/InitialNameServicePackage \
+    com/sun/corba/se/spi/activation/LocatorPackage \
+    com/sun/corba/se/spi/activation/RepositoryPackage \
+    com/sun/corba/se/spi/copyobject \
+    com/sun/corba/se/spi/encoding \
+    com/sun/corba/se/spi/extension \
+    com/sun/corba/se/spi/ior \
+    com/sun/corba/se/spi/ior/iiop \
+    com/sun/corba/se/spi/legacy/connection \
+    com/sun/corba/se/spi/legacy/interceptor \
+    com/sun/corba/se/spi/logging \
+    com/sun/corba/se/spi/monitoring \
+    com/sun/corba/se/spi/oa \
+    com/sun/corba/se/spi/orb \
+    com/sun/corba/se/spi/orbutil/closure \
+    com/sun/corba/se/spi/orbutil/fsm \
+    com/sun/corba/se/spi/orbutil/proxy \
+    com/sun/corba/se/spi/orbutil/threadpool \
+    com/sun/corba/se/spi/presentation/rmi \
+    com/sun/corba/se/spi/protocol \
+    com/sun/corba/se/spi/resolver \
+    com/sun/corba/se/spi/servicecontext \
+    com/sun/corba/se/spi/transport \
+    com/sun/image/codec/jpeg \
+    com/sun/imageio/plugins/bmp \
+    com/sun/imageio/plugins/common \
+    com/sun/imageio/plugins/gif \
+    com/sun/imageio/plugins/jpeg \
+    com/sun/imageio/plugins/png \
+    com/sun/imageio/plugins/wbmp \
+    com/sun/imageio/spi \
+    com/sun/imageio/stream \
+    com/sun/istack/internal \
+    com/sun/istack/internal/localization \
+    com/sun/istack/internal/logging \
+    com/sun/java/browser/dom \
+    com/sun/java/browser/net \
+    com/sun/java/swing \
+    com/sun/java/swing/plaf/gtk \
+    com/sun/java/swing/plaf/gtk/resources \
+    com/sun/java/swing/plaf/motif \
+    com/sun/java/swing/plaf/motif/resources \
+    com/sun/java/swing/plaf/nimbus \
+    com/sun/java/swing/plaf/windows \
+    com/sun/java/swing/plaf/windows/resources \
+    com/sun/jmx/remote/protocol/iiop \
+    com/sun/jndi/cosnaming \
+    com/sun/jndi/toolkit/corba \
+    com/sun/jndi/url/corbaname \
+    com/sun/jndi/url/iiop \
+    com/sun/jndi/url/iiopname \
+    com/sun/media/sound \
+    com/sun/org/glassfish/external/amx \
+    com/sun/org/glassfish/external/arc \
+    com/sun/org/glassfish/external/probe/provider \
+    com/sun/org/glassfish/external/probe/provider/annotations \
+    com/sun/org/glassfish/external/statistics \
+    com/sun/org/glassfish/external/statistics/annotations \
+    com/sun/org/glassfish/external/statistics/impl \
+    com/sun/org/glassfish/gmbal \
+    com/sun/org/glassfish/gmbal/util \
+    com/sun/org/omg/CORBA \
+    com/sun/org/omg/CORBA/ValueDefPackage \
+    com/sun/org/omg/CORBA/portable \
+    com/sun/org/omg/SendingContext \
+    com/sun/org/omg/SendingContext/CodeBasePackage \
+    com/sun/servicetag \
+    com/sun/swing/internal/plaf/basic/resources \
+    com/sun/swing/internal/plaf/metal/resources \
+    com/sun/swing/internal/plaf/synth/resources \
+    com/sun/xml/internal/bind \
+    com/sun/xml/internal/bind/annotation \
+    com/sun/xml/internal/bind/api \
+    com/sun/xml/internal/bind/api/impl \
+    com/sun/xml/internal/bind/marshaller \
+    com/sun/xml/internal/bind/unmarshaller \
+    com/sun/xml/internal/bind/util \
+    com/sun/xml/internal/bind/v2 \
+    com/sun/xml/internal/bind/v2/bytecode \
+    com/sun/xml/internal/bind/v2/model/annotation \
+    com/sun/xml/internal/bind/v2/model/core \
+    com/sun/xml/internal/bind/v2/model/impl \
+    com/sun/xml/internal/bind/v2/model/nav \
+    com/sun/xml/internal/bind/v2/model/runtime \
+    com/sun/xml/internal/bind/v2/runtime \
+    com/sun/xml/internal/bind/v2/runtime/output \
+    com/sun/xml/internal/bind/v2/runtime/property \
+    com/sun/xml/internal/bind/v2/runtime/reflect \
+    com/sun/xml/internal/bind/v2/runtime/reflect/opt \
+    com/sun/xml/internal/bind/v2/runtime/unmarshaller \
+    com/sun/xml/internal/bind/v2/schemagen \
+    com/sun/xml/internal/bind/v2/schemagen/episode \
+    com/sun/xml/internal/bind/v2/schemagen/xmlschema \
+    com/sun/xml/internal/bind/v2/util \
+    com/sun/xml/internal/fastinfoset \
+    com/sun/xml/internal/fastinfoset/algorithm \
+    com/sun/xml/internal/fastinfoset/alphabet \
+    com/sun/xml/internal/fastinfoset/dom \
+    com/sun/xml/internal/fastinfoset/org/apache/xerces/util \
+    com/sun/xml/internal/fastinfoset/sax \
+    com/sun/xml/internal/fastinfoset/stax \
+    com/sun/xml/internal/fastinfoset/stax/events \
+    com/sun/xml/internal/fastinfoset/stax/factory \
+    com/sun/xml/internal/fastinfoset/stax/util \
+    com/sun/xml/internal/fastinfoset/tools \
+    com/sun/xml/internal/fastinfoset/util \
+    com/sun/xml/internal/fastinfoset/vocab \
+    com/sun/xml/internal/messaging/saaj \
+    com/sun/xml/internal/messaging/saaj/client/p2p \
+    com/sun/xml/internal/messaging/saaj/packaging/mime \
+    com/sun/xml/internal/messaging/saaj/packaging/mime/internet \
+    com/sun/xml/internal/messaging/saaj/packaging/mime/util \
+    com/sun/xml/internal/messaging/saaj/soap \
+    com/sun/xml/internal/messaging/saaj/soap/dynamic \
+    com/sun/xml/internal/messaging/saaj/soap/impl \
+    com/sun/xml/internal/messaging/saaj/soap/name \
+    com/sun/xml/internal/messaging/saaj/soap/ver1_1 \
+    com/sun/xml/internal/messaging/saaj/soap/ver1_2 \
+    com/sun/xml/internal/messaging/saaj/util \
+    com/sun/xml/internal/messaging/saaj/util/transform \
+    com/sun/xml/internal/org/jvnet/fastinfoset \
+    com/sun/xml/internal/org/jvnet/fastinfoset/sax \
+    com/sun/xml/internal/org/jvnet/fastinfoset/sax/helpers \
+    com/sun/xml/internal/org/jvnet/fastinfoset/stax \
+    com/sun/xml/internal/org/jvnet/mimepull \
+    com/sun/xml/internal/org/jvnet/staxex \
+    com/sun/xml/internal/org/jvnet/ws \
+    com/sun/xml/internal/org/jvnet/ws/databinding \
+    com/sun/xml/internal/org/jvnet/ws/message \
+    com/sun/xml/internal/stream/buffer \
+    com/sun/xml/internal/stream/buffer/sax \
+    com/sun/xml/internal/stream/buffer/stax \
+    com/sun/xml/internal/txw2 \
+    com/sun/xml/internal/txw2/annotation \
+    com/sun/xml/internal/txw2/output \
+    com/sun/xml/internal/ws/addressing \
+    com/sun/xml/internal/ws/addressing/model \
+    com/sun/xml/internal/ws/addressing/policy \
+    com/sun/xml/internal/ws/addressing/v200408 \
+    com/sun/xml/internal/ws/api \
+    com/sun/xml/internal/ws/api/addressing \
+    com/sun/xml/internal/ws/api/client \
+    com/sun/xml/internal/ws/api/config/management \
+    com/sun/xml/internal/ws/api/config/management/policy \
+    com/sun/xml/internal/ws/api/databinding \
+    com/sun/xml/internal/ws/api/fastinfoset \
+    com/sun/xml/internal/ws/api/ha \
+    com/sun/xml/internal/ws/api/handler \
+    com/sun/xml/internal/ws/api/message \
+    com/sun/xml/internal/ws/api/message/saaj \
+    com/sun/xml/internal/ws/api/message/stream \
+    com/sun/xml/internal/ws/api/model \
+    com/sun/xml/internal/ws/api/model/soap \
+    com/sun/xml/internal/ws/api/model/wsdl \
+    com/sun/xml/internal/ws/api/pipe \
+    com/sun/xml/internal/ws/api/pipe/helper \
+    com/sun/xml/internal/ws/api/policy \
+    com/sun/xml/internal/ws/api/policy/subject \
+    com/sun/xml/internal/ws/api/server \
+    com/sun/xml/internal/ws/api/streaming \
+    com/sun/xml/internal/ws/api/wsdl/parser \
+    com/sun/xml/internal/ws/api/wsdl/writer \
+    com/sun/xml/internal/ws/binding \
+    com/sun/xml/internal/ws/client \
+    com/sun/xml/internal/ws/client/dispatch \
+    com/sun/xml/internal/ws/client/sei \
+    com/sun/xml/internal/ws/config/management/policy \
+    com/sun/xml/internal/ws/db \
+    com/sun/xml/internal/ws/db/glassfish \
+    com/sun/xml/internal/ws/developer \
+    com/sun/xml/internal/ws/encoding \
+    com/sun/xml/internal/ws/encoding/fastinfoset \
+    com/sun/xml/internal/ws/encoding/policy \
+    com/sun/xml/internal/ws/encoding/soap \
+    com/sun/xml/internal/ws/encoding/soap/streaming \
+    com/sun/xml/internal/ws/encoding/xml \
+    com/sun/xml/internal/ws/fault \
+    com/sun/xml/internal/ws/handler \
+    com/sun/xml/internal/ws/message \
+    com/sun/xml/internal/ws/message/jaxb \
+    com/sun/xml/internal/ws/message/saaj \
+    com/sun/xml/internal/ws/message/source \
+    com/sun/xml/internal/ws/message/stream \
+    com/sun/xml/internal/ws/model \
+    com/sun/xml/internal/ws/model/soap \
+    com/sun/xml/internal/ws/model/wsdl \
+    com/sun/xml/internal/ws/org/objectweb/asm \
+    com/sun/xml/internal/ws/policy \
+    com/sun/xml/internal/ws/policy/jaxws \
+    com/sun/xml/internal/ws/policy/jaxws/spi \
+    com/sun/xml/internal/ws/policy/privateutil \
+    com/sun/xml/internal/ws/policy/sourcemodel \
+    com/sun/xml/internal/ws/policy/sourcemodel/attach \
+    com/sun/xml/internal/ws/policy/sourcemodel/wspolicy \
+    com/sun/xml/internal/ws/policy/spi \
+    com/sun/xml/internal/ws/policy/subject \
+    com/sun/xml/internal/ws/protocol/soap \
+    com/sun/xml/internal/ws/protocol/xml \
+    com/sun/xml/internal/ws/resources \
+    com/sun/xml/internal/ws/server \
+    com/sun/xml/internal/ws/server/provider \
+    com/sun/xml/internal/ws/server/sei \
+    com/sun/xml/internal/ws/spi \
+    com/sun/xml/internal/ws/spi/db \
+    com/sun/xml/internal/ws/streaming \
+    com/sun/xml/internal/ws/transport \
+    com/sun/xml/internal/ws/transport/http \
+    com/sun/xml/internal/ws/transport/http/client \
+    com/sun/xml/internal/ws/transport/http/server \
+    com/sun/xml/internal/ws/util \
+    com/sun/xml/internal/ws/util/exception \
+    com/sun/xml/internal/ws/util/localization \
+    com/sun/xml/internal/ws/util/pipe \
+    com/sun/xml/internal/ws/util/xml \
+    com/sun/xml/internal/ws/wsdl \
+    com/sun/xml/internal/ws/wsdl/parser \
+    com/sun/xml/internal/ws/wsdl/writer \
+    com/sun/xml/internal/ws/wsdl/writer/document \
+    com/sun/xml/internal/ws/wsdl/writer/document/http \
+    com/sun/xml/internal/ws/wsdl/writer/document/soap \
+    com/sun/xml/internal/ws/wsdl/writer/document/soap12 \
+    com/sun/xml/internal/ws/wsdl/writer/document/xsd \
+    java/applet \
+    java/awt \
+    java/awt/color \
+    java/awt/datatransfer \
+    java/awt/dnd \
+    java/awt/dnd/peer \
+    java/awt/event \
+    java/awt/font \
+    java/awt/geom \
+    java/awt/im \
+    java/awt/im/spi \
+    java/awt/image \
+    java/awt/image/renderable \
+    java/awt/peer \
+    java/awt/print \
+    java/beans \
+    javax/accessibility \
+    javax/activation \
+    javax/activity \
+    javax/imageio \
+    javax/imageio/event \
+    javax/imageio/metadata \
+    javax/imageio/plugins/bmp \
+    javax/imageio/plugins/jpeg \
+    javax/imageio/spi \
+    javax/imageio/stream \
+    javax/jws \
+    javax/jws/soap \
+    javax/print \
+    javax/print/attribute \
+    javax/print/attribute/standard \
+    javax/print/event \
+    javax/rmi/CORBA \
+    javax/sound/midi \
+    javax/sound/midi/spi \
+    javax/sound/sampled \
+    javax/sound/sampled/spi \
+    javax/swing \
+    javax/swing/border \
+    javax/swing/colorchooser \
+    javax/swing/event \
+    javax/swing/filechooser \
+    javax/swing/plaf \
+    javax/swing/plaf/basic \
+    javax/swing/plaf/metal \
+    javax/swing/plaf/multi \
+    javax/swing/plaf/nimbus \
+    javax/swing/plaf/synth \
+    javax/swing/table \
+    javax/swing/text \
+    javax/swing/text/html \
+    javax/swing/text/html/parser \
+    javax/swing/text/rtf \
+    javax/swing/tree \
+    javax/swing/undo \
+    javax/xml/bind \
+    javax/xml/bind/annotation \
+    javax/xml/bind/annotation/adapters \
+    javax/xml/bind/attachment \
+    javax/xml/bind/helpers \
+    javax/xml/bind/util \
+    javax/xml/soap \
+    javax/xml/ws \
+    javax/xml/ws/handler \
+    javax/xml/ws/handler/soap \
+    javax/xml/ws/http \
+    javax/xml/ws/soap \
+    javax/xml/ws/spi \
+    javax/xml/ws/spi/http \
+    javax/xml/ws/wsaddressing \
+    org/omg/CORBA \
+    org/omg/CORBA/DynAnyPackage \
+    org/omg/CORBA/ORBPackage \
+    org/omg/CORBA/TypeCodePackage \
+    org/omg/CORBA/portable \
+    org/omg/CORBA_2_3 \
+    org/omg/CORBA_2_3/portable \
+    org/omg/CosNaming \
+    org/omg/CosNaming/NamingContextExtPackage \
+    org/omg/CosNaming/NamingContextPackage \
+    org/omg/Dynamic \
+    org/omg/DynamicAny \
+    org/omg/DynamicAny/DynAnyFactoryPackage \
+    org/omg/DynamicAny/DynAnyPackage \
+    org/omg/IOP \
+    org/omg/IOP/CodecFactoryPackage \
+    org/omg/IOP/CodecPackage \
+    org/omg/Messaging \
+    org/omg/PortableInterceptor \
+    org/omg/PortableInterceptor/ORBInitInfoPackage \
+    org/omg/PortableServer \
+    org/omg/PortableServer/CurrentPackage \
+    org/omg/PortableServer/POAManagerPackage \
+    org/omg/PortableServer/POAPackage \
+    org/omg/PortableServer/ServantLocatorPackage \
+    org/omg/PortableServer/portable \
+    org/omg/SendingContext \
+    org/omg/stub/java/rmi \
+    org/omg/stub/javax/management/remote/rmi \
+    sun/applet \
+    sun/applet/resources \
+    sun/audio \
+    sun/awt \
+    sun/awt/X11 \
+    sun/awt/datatransfer \
+    sun/awt/dnd \
+    sun/awt/event \
+    sun/awt/geom \
+    sun/awt/im \
+    sun/awt/image \
+    sun/awt/image/codec \
+    sun/awt/motif \
+    sun/awt/resources \
+    sun/awt/shell \
+    sun/awt/util \
+    sun/awt/windows \
+    sun/beans/editors \
+    sun/beans/infos \
+    sun/corba \
+    sun/dc \
+    sun/dc/path \
+    sun/dc/pr \
+    sun/font \
+    sun/java2d \
+    sun/java2d/cmm \
+    sun/java2d/cmm/kcms \
+    sun/java2d/cmm/lcms \
+    sun/java2d/jules \
+    sun/java2d/loops \
+    sun/java2d/opengl \
+    sun/java2d/pipe \
+    sun/java2d/pipe/hw \
+    sun/java2d/pisces \
+    sun/java2d/x11 \
+    sun/java2d/xr \
+    sun/net/ftp \
+    sun/net/ftp/impl \
+    sun/net/smtp \
+    sun/net/www/content/audio \
+    sun/net/www/content/image \
+    sun/net/www/content/text \
+    sun/net/www/protocol/ftp \
+    sun/net/www/protocol/mailto \
+    sun/net/www/protocol/netdoc \
+    sun/print \
+    sun/print/resources \
+    sun/security/tools/policytool \
+    sun/swing \
+    sun/swing/icon \
+    sun/swing/plaf \
+    sun/swing/plaf/synth \
+    sun/swing/plaf/windows \
+    sun/swing/table \
+    sun/swing/text \
+    sun/swing/text/html \
+    sun/tools/jar \
+    sun/tools/jar/resources
+
+PROFILE_4_RTJAR_INCLUDE_TYPES := \
+    com/sun/xml/internal/ws/*.class \
+    javax/annotation/*.class \
+    javax/rmi/*.class
+
+PROFILE_4_RTJAR_EXCLUDE_TYPES := 
+
+PROFILE_4_INCLUDE_METAINF_SERVICES := \
+    META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin  \
+    META-INF/services/com.sun.tools.internal.xjc.Plugin  \
+    META-INF/services/javax.print.PrintServiceLookup  \
+    META-INF/services/javax.print.StreamPrintServiceFactory  \
+    META-INF/services/javax.sound.midi.spi.MidiDeviceProvider  \
+    META-INF/services/javax.sound.midi.spi.MidiFileReader  \
+    META-INF/services/javax.sound.midi.spi.MidiFileWriter  \
+    META-INF/services/javax.sound.midi.spi.SoundbankReader  \
+    META-INF/services/javax.sound.sampled.spi.AudioFileReader  \
+    META-INF/services/javax.sound.sampled.spi.AudioFileWriter  \
+    META-INF/services/javax.sound.sampled.spi.FormatConversionProvider  \
+    META-INF/services/javax.sound.sampled.spi.MixerProvider  \
+    META-INF/services/sun.java2d.cmm.PCMM  \
+    META-INF/services/sun.java2d.pipe.RenderingEngine 
+
+
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
index 56f5ac7..791182c 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
@@ -30,6 +30,8 @@
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.awt.print.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 import javax.print.*;
 import javax.print.attribute.PrintRequestAttributeSet;
@@ -47,6 +49,8 @@
 
     private static String sShouldNotReachHere = "Should not reach here.";
 
+    private volatile SecondaryLoop printingLoop;
+
     private boolean noDefaultPrinter = false;
 
     private static Font defaultFont;
@@ -160,11 +164,22 @@
 
     volatile boolean onEventThread;
 
+    @Override
+    protected void cancelDoc() throws PrinterAbortException {
+        super.cancelDoc();
+        if (printingLoop != null) {
+            printingLoop.exit();
+        }
+    }
+
     private void completePrintLoop() {
         Runnable r = new Runnable() { public void run() {
             synchronized(this) {
                 performingPrinting = false;
             }
+            if (printingLoop != null) {
+                printingLoop.exit();
+            }
         }};
 
         if (onEventThread) {
@@ -219,17 +234,21 @@
 
                 onEventThread = true;
 
+                printingLoop = AccessController.doPrivileged(new PrivilegedAction<SecondaryLoop>() {
+                    @Override
+                    public SecondaryLoop run() {
+                        return Toolkit.getDefaultToolkit()
+                                .getSystemEventQueue()
+                                .createSecondaryLoop();
+                    }
+                });
+
                 try {
                     // Fire off the print rendering loop on the AppKit thread, and don't have
                     //  it wait and block this thread.
                     if (printLoop(false, firstPage, lastPage)) {
-                        // Fire off the EventConditional that will what until the condition is met,
-                        //  but will still process AWTEvent's as they occur.
-                        new EventDispatchAccess() {
-                            public boolean evaluate() {
-                                return performingPrinting;
-                            }
-                        }.pumpEventsAndWait();
+                        // Start a secondary loop on EDT until printing operation is finished or cancelled
+                        printingLoop.enter();
                     }
                 } catch (Exception e) {
                     e.printStackTrace();
@@ -253,6 +272,9 @@
                 performingPrinting = false;
                 notify();
             }
+            if (printingLoop != null) {
+                printingLoop.exit();
+            }
         }
 
         // Normalize the collated, # copies, numPages, first/last pages. Need to
diff --git a/jdk/src/macosx/lib/flavormap.properties b/jdk/src/macosx/lib/flavormap.properties
index 5e17d6e..4a9f5fe 100644
--- a/jdk/src/macosx/lib/flavormap.properties
+++ b/jdk/src/macosx/lib/flavormap.properties
@@ -1,7 +1,7 @@
 #
 # This properties file is used to initialize the default
-# java.awt.datatransfer.SystemFlavorMap. It contains the X11 platform-specific,
-# default mappings between common X11 selection atoms and platform-independent
+# java.awt.datatransfer.SystemFlavorMap. It contains the Mac OS X platform-specific,
+# default mappings between common Mac OS X selection atoms and platform-independent
 # MIME type strings, which will be converted into
 # java.awt.datatransfer.DataFlavors.
 #
@@ -76,3 +76,5 @@
 text/uri-list=application/x-java-file-list;class=java.util.List
 PNG=image/x-java-image;class=java.awt.Image
 JFIF=image/x-java-image;class=java.awt.Image
+RICH_TEXT=text/rtf
+HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
diff --git a/jdk/src/macosx/native/jobjc/src/core/native/SEL.m b/jdk/src/macosx/native/jobjc/src/core/native/SEL.m
index 970a5d3..ebbcf25 100644
--- a/jdk/src/macosx/native/jobjc/src/core/native/SEL.m
+++ b/jdk/src/macosx/native/jobjc/src/core/native/SEL.m
@@ -34,7 +34,7 @@
     const char *selNameAsChars = (*env)->GetStringUTFChars(env, selName, JNI_FALSE);
     const SEL sel = sel_registerName(selNameAsChars);
     (*env)->ReleaseStringUTFChars(env, selName, selNameAsChars);
-    return ptr_to_jlong(sel);
+    return ptr_to_jlong((void*)sel);
 }
 
 JNIEXPORT jstring JNICALL Java_com_apple_jobjc_SEL_getSelectorName
diff --git a/jdk/src/macosx/native/sun/awt/CPrinterJob.m b/jdk/src/macosx/native/sun/awt/CPrinterJob.m
index 52976f3..3935240 100644
--- a/jdk/src/macosx/native/sun/awt/CPrinterJob.m
+++ b/jdk/src/macosx/native/sun/awt/CPrinterJob.m
@@ -384,31 +384,6 @@
 }
 
 /*
- * Class:     sun_lwawt_macosx_EventDispatchAccess
- * Method:    pumpEventsAndWait
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_lwawt_macosx_EventDispatchAccess_pumpEventsAndWait
-(JNIEnv *env, jobject eda)
-{
-    static JNF_CLASS_CACHE(jc_Thread, "java/lang/Thread");
-    static JNF_STATIC_MEMBER_CACHE(jm_currentThread, jc_Thread, "currentThread", "()Ljava/lang/Thread;");
-    static JNF_CLASS_CACHE(jc_EventDispatchThread, "java/awt/EventDispatchThread");
-    static JNF_MEMBER_CACHE(jm_macosxGetConditional, jc_EventDispatchThread, "_macosxGetConditional", "(Ljava/lang/Object;)Ljava/awt/Conditional;");
-    static JNF_MEMBER_CACHE(jm_pumpEvents, jc_EventDispatchThread, "pumpEvents", "(Ljava/awt/Conditional;)V");
-
-JNF_COCOA_DURING(env);
-
-    jobject thread = JNFCallStaticObjectMethod(env, jm_currentThread);
-    jobject conditional = JNFCallObjectMethod(env, thread, jm_macosxGetConditional, eda);
-    if (conditional != NULL) {
-        JNFCallVoidMethod(env, thread, jm_pumpEvents, conditional);
-    }
-
-JNF_COCOA_HANDLE(env);
-}
-
-/*
  * Class:     sun_lwawt_macosx_CPrinterJob
  * Method:    abortDoc
  * Signature: ()V
diff --git a/jdk/src/share/bin/parse_manifest.c b/jdk/src/share/bin/parse_manifest.c
index ec30149..61b0bbf 100644
--- a/jdk/src/share/bin/parse_manifest.c
+++ b/jdk/src/share/bin/parse_manifest.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -106,8 +106,9 @@
             *size_out = (int)entry->isize;
         }
         return (out);
-    } else
-        return (NULL);
+    }
+    free(in);
+    return (NULL);
 }
 
 static jboolean zip64_present = JNI_FALSE;
@@ -563,7 +564,7 @@
 
     if ((fd = open(jarfile, O_RDONLY
 #ifdef O_LARGEFILE
-        | O_LARGEFILE /* large file mode on solaris */
+        | O_LARGEFILE /* large file mode */
 #endif
 #ifdef O_BINARY
         | O_BINARY /* use binary mode on windows */
@@ -618,6 +619,9 @@
     void    *data = NULL;
 
     fd = open(jarfile, O_RDONLY
+#ifdef O_LARGEFILE
+        | O_LARGEFILE /* large file mode */
+#endif
 #ifdef O_BINARY
         | O_BINARY /* use binary mode on windows */
 #endif
@@ -661,6 +665,9 @@
     int     rc;
 
     if ((fd = open(jarfile, O_RDONLY
+#ifdef O_LARGEFILE
+        | O_LARGEFILE /* large file mode */
+#endif
 #ifdef O_BINARY
         | O_BINARY /* use binary mode on windows */
 #endif
diff --git a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
index 3d1744b..719aeee 100644
--- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
+++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
@@ -52,16 +52,19 @@
  * principal set and private credentials set are updated only when
  * <code>commit</code> is called.
  * When <code>commit</code> is called, the <code>KerberosPrincipal</code>
- * is added to the  <code>Subject</code>'s
- * principal set and <code>KerberosTicket</code> is
+ * is added to the <code>Subject</code>'s principal set (unless the
+ * <code>principal</code> is specified as "*"). If <code>isInitiator</code>
+ * is true, the <code>KerberosTicket</code> is
  * added to the <code>Subject</code>'s private credentials.
  *
  * <p> If the configuration entry for <code>KerberosLoginModule</code>
  * has the option <code>storeKey</code> set to true, then
- * <code>KerberosKey</code> will also be added to the
+ * <code>KerberosKey</code> or <code>KeyTab</code> will also be added to the
  * subject's private credentials. <code>KerberosKey</code>, the principal's
- * key will be either obtained from the keytab or
- * derived from user's password.
+ * key(s) will be derived from user's password, and <code>KeyTab</code> is
+ * the keytab used when <code>useKeyTab</code> is set to true. The
+ * <code>KeyTab</code> object is restricted to be used by the specified
+ * principal unless the principal value is "*".
  *
  * <p> This <code>LoginModule</code> recognizes the <code>doNotPrompt</code>
  * option. If set to true the user will not be prompted for the password.
@@ -75,8 +78,8 @@
  *
  * <p> The principal name can be specified in the configuration entry
  * by using the option <code>principal</code>. The principal name
- * can either be a simple user name or a service name such as
- * <code>host/mission.eng.sun.com</code>. The principal can also
+ * can either be a simple user name, a service name such as
+ * <code>host/mission.eng.sun.com</code>, or "*". The principal can also
  * be set using the system property <code>sun.security.krb5.principal</code>.
  * This property is checked during login. If this property is not set, then
  * the principal name from the configuration is used. In the
@@ -87,11 +90,10 @@
  *
  * <p> The following is a list of configuration options supported
  * for <code>Krb5LoginModule</code>:
- * <dl>
- * <blockquote><dt><b><code>refreshKrb5Config</code></b>:</dt>
+ * <blockquote><dl>
+ * <dt><b><code>refreshKrb5Config</code></b>:</dt>
  * <dd> Set this to true, if you want the configuration
  * to be refreshed before the <code>login</code> method is called.</dd>
- * <P>
  * <dt><b><code>useTicketCache</code></b>:</dt>
  * <dd>Set this to true, if you want the
  * TGT to be obtained
@@ -112,19 +114,16 @@
  * <code>ticketCache</code>.
  * For Windows, if a ticket cannot be retrieved from the file ticket cache,
  * it will use Local Security Authority (LSA) API to get the TGT.
- * <P>
  * <dt><b><code>ticketCache</code></b>:</dt>
  * <dd>Set this to the name of the ticket
  * cache that  contains user's TGT.
  * If this is set,  <code>useTicketCache</code>
  * must also be set to true; Otherwise a configuration error will
  * be returned.</dd>
- *  <P>
  * <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
  * set to true; otherwise a configuration error will be returned.</dd>
- * <p>
  * <dt><b><code>doNotPrompt</code></b>:</dt>
  * <dd>Set this to true if you do not want to be
  * prompted for the password
@@ -132,7 +131,6 @@
  * or through shared state.(Default is false)
  * If set to true, credential must be obtained through cache, keytab,
  * or shared state. Otherwise, authentication will fail.</dd>
- * <P>
  * <dt><b><code>useKeyTab</code></b>:</dt>
  * <dd>Set this to true if you
  * want the module to get the principal's key from the
@@ -144,15 +142,15 @@
  * If it is not specified in the Kerberos configuration file
  * then it will look for the file
  * <code>{user.home}{file.separator}</code>krb5.keytab.</dd>
- * <P>
  * <dt><b><code>keyTab</code></b>:</dt>
  * <dd>Set this to the file name of the
  * keytab to get principal's secret key.</dd>
- * <P>
  * <dt><b><code>storeKey</code></b>:</dt>
- * <dd>Set this to true to if you want the
- * principal's key to be stored in the Subject's private credentials. </dd>
- * <p>
+ * <dd>Set this to true to if you want the keytab or the
+ * principal's key to be stored in the Subject's private credentials.
+ * For <code>isInitiator</code> being false, if <code>principal</code>
+ * is "*", the {@link KeyTab} stored can be used by anyone, otherwise,
+ * it's restricted to be used by the specified principal only.</dd>
  * <dt><b><code>principal</code></b>:</dt>
  * <dd>The name of the principal that should
  * be used. The principal can be a simple username such as
@@ -165,8 +163,13 @@
  * <code>sun.security.krb5.principal</code>. In addition, if this
  * system property is defined, then it will be used. If this property
  * is not set, then the principal name from the configuration will be
- * used.</dd>
- * <P>
+ * used.
+ * The principal name can be set to "*" when <code>isInitiator</code> is false.
+ * In this case, the acceptor is not bound to a single principal. It can
+ * act as any principal an initiator requests if keys for that principal
+ * can be found. When <code>isInitiator</code> is true, the principal name
+ * cannot be set to "*".
+ * </dd>
  * <dt><b><code>isInitiator</code></b>:</dt>
  * <dd>Set this to true, if initiator. Set this to false, if acceptor only.
  * (Default is true).
@@ -177,18 +180,20 @@
  * <code>Configuration</code>
  * options that enable you to share username and passwords across different
  * authentication modules:
- * <pre>
+ * <blockquote><dl>
  *
- *    useFirstPass   if, true, this LoginModule retrieves the
+ *    <dt><b><code>useFirstPass</code></b>:</dt>
+ *                   <dd>if, true, this LoginModule retrieves the
  *                   username and password from the module's shared state,
  *                   using "javax.security.auth.login.name" and
  *                   "javax.security.auth.login.password" as the respective
  *                   keys. The retrieved values are used for authentication.
  *                   If authentication fails, no attempt for a retry
  *                   is made, and the failure is reported back to the
- *                   calling application.
+ *                   calling application.</dd>
  *
- *    tryFirstPass   if, true, this LoginModule retrieves the
+ *    <dt><b><code>tryFirstPass</code></b>:</dt>
+ *                   <dd>if, true, this LoginModule retrieves the
  *                   the username and password from the module's shared
  *                   state using "javax.security.auth.login.name" and
  *                   "javax.security.auth.login.password" as the respective
@@ -198,26 +203,28 @@
  *                   CallbackHandler to retrieve a new username
  *                   and password, and another attempt to authenticate
  *                   is made. If the authentication fails,
- *                   the failure is reported back to the calling application
+ *                   the failure is reported back to the calling application</dd>
  *
- *    storePass      if, true, this LoginModule stores the username and
+ *    <dt><b><code>storePass</code></b>:</dt>
+ *                   <dd>if, true, this LoginModule stores the username and
  *                   password obtained from the CallbackHandler in the
  *                   modules shared state, using
  *                   "javax.security.auth.login.name" and
  *                   "javax.security.auth.login.password" as the respective
  *                   keys.  This is not performed if existing values already
  *                   exist for the username and password in the shared
- *                   state, or if authentication fails.
+ *                   state, or if authentication fails.</dd>
  *
- *    clearPass      if, true, this LoginModule clears the
+ *    <dt><b><code>clearPass</code></b>:</dt>
+ *                   <dd>if, true, this LoginModule clears the
  *                   username and password stored in the module's shared
  *                   state  after both phases of authentication
- *                   (login and commit) have completed.
- * </pre>
+ *                   (login and commit) have completed.</dd>
+ * </dl></blockquote>
  * <p>If the principal system property or key is already provided, the value of
  * "javax.security.auth.login.name" in the shared state is ignored.
  * <p>When multiple mechanisms to retrieve a ticket or key is provided, the
- * preference order looks like this:
+ * preference order is:
  * <ol>
  * <li>ticket cache
  * <li>keytab
@@ -225,7 +232,7 @@
  * <li>user prompt
  * </ol>
  * <p>Note that if any step fails, it will fallback to the next step.
- * There's only one exception, it the shared state step fails and
+ * There's only one exception, if the shared state step fails and
  * <code>useFirstPass</code>=true, no user prompt is made.
  * <p>Examples of some configuration values for Krb5LoginModule in
  * JAAS config file and the results are:
@@ -318,7 +325,7 @@
  * <p> <code>useKeyTab</code> = true
  * <code>keyTab</code>=&lt;keytabname&gt;
  * <code>storeKey</code>=true
- * <code>doNotPrompt</code>=true;
+ * <code>doNotPrompt</code>=false;
  *</ul>
  * <p>The user will be prompted for the service principal name.
  * If the principal's
@@ -328,6 +335,14 @@
  * If successful the TGT will be added to the
  * Subject's private credentials set. Otherwise the authentication will
  * fail.
+ * <ul>
+ * <p> <code>isInitiator</code> = false <code>useKeyTab</code> = true
+ * <code>keyTab</code>=&lt;keytabname&gt;
+ * <code>storeKey</code>=true
+ * <code>principal</code>=*;
+ *</ul>
+ * <p>The acceptor will be an unbound acceptor and it can act as any principal
+ * as long that principal has keys in the keytab.
  *<ul>
  * <p>
  * <code>useTicketCache</code>=true
@@ -409,6 +424,7 @@
     private KerberosTicket kerbTicket = null;
     private KerberosKey[] kerbKeys = null;
     private StringBuffer krb5PrincName = null;
+    private boolean unboundServer = false;
     private char[] password = null;
 
     private static final String NAME = "javax.security.auth.login.name";
@@ -520,8 +536,6 @@
      */
     public boolean login() throws LoginException {
 
-        int len;
-        validateConfiguration();
         if (refreshKrb5Config) {
             try {
                 if (debug) {
@@ -544,6 +558,12 @@
             }
         }
 
+        validateConfiguration();
+
+        if (krb5PrincName != null && krb5PrincName.toString().equals("*")) {
+            unboundServer = true;
+        }
+
         if (tryFirstPass) {
             try {
                 attemptAuthentication(true);
@@ -698,9 +718,17 @@
                  * (encKeys == null) to check.
                  */
                 if (useKeyTab) {
-                    ktab = (keyTabName == null)
-                                ? KeyTab.getInstance()
-                                : KeyTab.getInstance(new File(keyTabName));
+                    if (!unboundServer) {
+                        KerberosPrincipal kp =
+                                new KerberosPrincipal(principal.getName());
+                        ktab = (keyTabName == null)
+                                ? KeyTab.getInstance(kp)
+                                : KeyTab.getInstance(kp, new File(keyTabName));
+                    } else {
+                        ktab = (keyTabName == null)
+                                ? KeyTab.getUnboundInstance()
+                                : KeyTab.getUnboundInstance(new File(keyTabName));
+                    }
                     if (isInitiator) {
                         if (Krb5Util.keysFromJavaxKeyTab(ktab, principal).length
                                 == 0) {
@@ -939,6 +967,13 @@
                 ("Configuration Error"
                  + " - either useTicketCache should be "
                  + " true or renewTGT should be false");
+        if (krb5PrincName != null && krb5PrincName.toString().equals("*")) {
+            if (isInitiator) {
+                throw new LoginException
+                    ("Configuration Error"
+                    + " - principal cannot be * when isInitiator is true");
+            }
+        }
     }
 
     private boolean isCurrent(Credentials creds)
@@ -1052,7 +1087,10 @@
             }
             // Let us add the kerbClientPrinc,kerbTicket and KeyTab/KerbKey (if
             // storeKey is true)
-            if (!princSet.contains(kerbClientPrinc)) {
+
+            // We won't add "*" as a KerberosPrincipal
+            if (!unboundServer &&
+                    !princSet.contains(kerbClientPrinc)) {
                 princSet.add(kerbClientPrinc);
             }
 
diff --git a/jdk/src/share/classes/com/sun/security/ntlm/Client.java b/jdk/src/share/classes/com/sun/security/ntlm/Client.java
index fcad176..7117cdc 100644
--- a/jdk/src/share/classes/com/sun/security/ntlm/Client.java
+++ b/jdk/src/share/classes/com/sun/security/ntlm/Client.java
@@ -138,8 +138,7 @@
             domain = domainFromServer;
         }
         if (domain == null) {
-            throw new NTLMException(NTLMException.NO_DOMAIN_INFO,
-                    "No domain info");
+            domain = "";
         }
 
         int flags = 0x88200 | (inputFlags & 3);
diff --git a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
index f0949b1..b85fcee 100644
--- a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
+++ b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
@@ -136,10 +136,10 @@
 
         int readInt(int offset) throws NTLMException {
             try {
-                return internal[offset] & 0xff +
-                        (internal[offset+1] & 0xff << 8) +
-                        (internal[offset+2] & 0xff << 16) +
-                        (internal[offset+3] & 0xff << 24);
+                return (internal[offset] & 0xff) +
+                        ((internal[offset+1] & 0xff) << 8) +
+                        ((internal[offset+2] & 0xff) << 16) +
+                        ((internal[offset+3] & 0xff) << 24);
             } catch (ArrayIndexOutOfBoundsException ex) {
                 throw new NTLMException(NTLMException.PACKET_READ_ERROR,
                         "Input message incorrect size");
@@ -148,8 +148,8 @@
 
         int readShort(int offset) throws NTLMException {
             try {
-                return internal[offset] & 0xff +
-                        (internal[offset+1] & 0xff << 8);
+                return (internal[offset] & 0xff) +
+                        ((internal[offset+1] & 0xff << 8));
             } catch (ArrayIndexOutOfBoundsException ex) {
                 throw new NTLMException(NTLMException.PACKET_READ_ERROR,
                         "Input message incorrect size");
diff --git a/jdk/src/share/classes/java/awt/EventDispatchThread.java b/jdk/src/share/classes/java/awt/EventDispatchThread.java
index 427ad7e..c707f02 100644
--- a/jdk/src/share/classes/java/awt/EventDispatchThread.java
+++ b/jdk/src/share/classes/java/awt/EventDispatchThread.java
@@ -107,34 +107,6 @@
         }
     }
 
-    // MacOSX change:
-    //  This was added because this class (and java.awt.Conditional) are package private.
-    //  There are certain instances where classes in other packages need to block the
-    //  AWTEventQueue while still allowing it to process events. This uses reflection
-    //  to call back into the caller in order to remove dependencies.
-    //
-    // NOTE: This uses reflection in its implementation, so it is not for performance critical code.
-    //
-    //  cond is an instance of sun.lwawt.macosx.EventDispatchAccess
-    //
-    private Conditional _macosxGetConditional(final Object cond) {
-        try {
-            return new Conditional() {
-                final Method evaluateMethod = Class.forName("sun.lwawt.macosx.EventDispatchAccess").getMethod("evaluate", null);
-                public boolean evaluate() {
-                    try {
-                        return ((Boolean)evaluateMethod.invoke(cond, null)).booleanValue();
-                    } catch (Exception e) {
-                        return false;
-                    }
-                }
-            };
-        } catch (Exception e) {
-            return new Conditional() { public boolean evaluate() { return false; } };
-        }
-    }
-
-
     void pumpEvents(Conditional cond) {
         pumpEvents(ANY_EVENT, cond);
     }
diff --git a/jdk/src/share/classes/java/io/Closeable.java b/jdk/src/share/classes/java/io/Closeable.java
index 26c7ea0..530cde8 100644
--- a/jdk/src/share/classes/java/io/Closeable.java
+++ b/jdk/src/share/classes/java/io/Closeable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -34,7 +34,7 @@
  *
  * @since 1.5
  */
-
+@FunctionalInterface
 public interface Closeable extends AutoCloseable {
 
     /**
diff --git a/jdk/src/share/classes/java/io/FileFilter.java b/jdk/src/share/classes/java/io/FileFilter.java
index 15f00d6..f973d77 100644
--- a/jdk/src/share/classes/java/io/FileFilter.java
+++ b/jdk/src/share/classes/java/io/FileFilter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -35,6 +35,7 @@
  *
  * @since 1.2
  */
+@FunctionalInterface
 public interface FileFilter {
 
     /**
@@ -46,5 +47,4 @@
      *          should be included
      */
     boolean accept(File pathname);
-
 }
diff --git a/jdk/src/share/classes/java/io/FilenameFilter.java b/jdk/src/share/classes/java/io/FilenameFilter.java
index 915adf5..71b88af 100644
--- a/jdk/src/share/classes/java/io/FilenameFilter.java
+++ b/jdk/src/share/classes/java/io/FilenameFilter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -39,8 +39,8 @@
  * @see     java.io.File#list(java.io.FilenameFilter)
  * @since   JDK1.0
  */
-public
-interface FilenameFilter {
+@FunctionalInterface
+public interface FilenameFilter {
     /**
      * Tests if a specified file should be included in a file list.
      *
diff --git a/jdk/src/share/classes/java/io/Flushable.java b/jdk/src/share/classes/java/io/Flushable.java
index e598ea8..8912316 100644
--- a/jdk/src/share/classes/java/io/Flushable.java
+++ b/jdk/src/share/classes/java/io/Flushable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -34,7 +34,7 @@
  *
  * @since 1.5
  */
-
+@FunctionalInterface
 public interface Flushable {
 
     /**
diff --git a/jdk/src/share/classes/java/lang/AutoCloseable.java b/jdk/src/share/classes/java/lang/AutoCloseable.java
index d928a9d..ce0fffe 100644
--- a/jdk/src/share/classes/java/lang/AutoCloseable.java
+++ b/jdk/src/share/classes/java/lang/AutoCloseable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -31,6 +31,7 @@
  * @author Josh Bloch
  * @since 1.7
  */
+@FunctionalInterface
 public interface AutoCloseable {
     /**
      * Closes this resource, relinquishing any underlying resources.
diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java
index dab6c98..671d04a 100644
--- a/jdk/src/share/classes/java/lang/Class.java
+++ b/jdk/src/share/classes/java/lang/Class.java
@@ -3087,7 +3087,8 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
-    public <A extends Annotation> A[] getAnnotations(Class<A> annotationClass) {
+    @Override
+    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
         Objects.requireNonNull(annotationClass);
 
         initAnnotationsIfNecessary();
@@ -3106,6 +3107,7 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
+    @Override
     @SuppressWarnings("unchecked")
     public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
         Objects.requireNonNull(annotationClass);
@@ -3118,7 +3120,8 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
-    public <A extends Annotation> A[] getDeclaredAnnotations(Class<A> annotationClass) {
+    @Override
+    public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
         Objects.requireNonNull(annotationClass);
 
         initAnnotationsIfNecessary();
diff --git a/jdk/src/share/classes/java/lang/Comparable.java b/jdk/src/share/classes/java/lang/Comparable.java
index d853197..123e10a 100644
--- a/jdk/src/share/classes/java/lang/Comparable.java
+++ b/jdk/src/share/classes/java/lang/Comparable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -93,7 +93,7 @@
  * @see java.util.Comparator
  * @since 1.2
  */
-
+@FunctionalInterface
 public interface Comparable<T> {
     /**
      * Compares this object with the specified object for order.  Returns a
diff --git a/jdk/src/share/classes/java/lang/Iterable.java b/jdk/src/share/classes/java/lang/Iterable.java
index 24efc86..a473192 100644
--- a/jdk/src/share/classes/java/lang/Iterable.java
+++ b/jdk/src/share/classes/java/lang/Iterable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -35,6 +35,7 @@
  *
  * @since 1.5
  */
+@FunctionalInterface
 public interface Iterable<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/lang/Package.java b/jdk/src/share/classes/java/lang/Package.java
index 234f807..b9776f4 100644
--- a/jdk/src/share/classes/java/lang/Package.java
+++ b/jdk/src/share/classes/java/lang/Package.java
@@ -389,8 +389,9 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
-    public  <A extends Annotation> A[] getAnnotations(Class<A> annotationClass) {
-        return getPackageInfo().getAnnotations(annotationClass);
+    @Override
+    public  <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
+        return getPackageInfo().getAnnotationsByType(annotationClass);
     }
 
     /**
@@ -404,6 +405,7 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
+    @Override
     public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
         return getPackageInfo().getDeclaredAnnotation(annotationClass);
     }
@@ -412,8 +414,9 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
-    public <A extends Annotation> A[] getDeclaredAnnotations(Class<A> annotationClass) {
-        return getPackageInfo().getDeclaredAnnotations(annotationClass);
+    @Override
+    public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
+        return getPackageInfo().getDeclaredAnnotationsByType(annotationClass);
     }
 
     /**
diff --git a/jdk/src/share/classes/java/lang/Readable.java b/jdk/src/share/classes/java/lang/Readable.java
index 7e4e924..e3d08d3 100644
--- a/jdk/src/share/classes/java/lang/Readable.java
+++ b/jdk/src/share/classes/java/lang/Readable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -34,7 +34,7 @@
  *
  * @since 1.5
  */
-
+@FunctionalInterface
 public interface Readable {
 
     /**
@@ -51,5 +51,4 @@
      * @throws java.nio.ReadOnlyBufferException if cb is a read only buffer
      */
     public int read(java.nio.CharBuffer cb) throws IOException;
-
 }
diff --git a/jdk/src/share/classes/java/lang/Runnable.java b/jdk/src/share/classes/java/lang/Runnable.java
index 6aeb892..b9f1df7 100644
--- a/jdk/src/share/classes/java/lang/Runnable.java
+++ b/jdk/src/share/classes/java/lang/Runnable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -52,8 +52,8 @@
  * @see     java.util.concurrent.Callable
  * @since   JDK1.0
  */
-public
-interface Runnable {
+@FunctionalInterface
+public interface Runnable {
     /**
      * When an object implementing interface <code>Runnable</code> is used
      * to create a thread, starting the thread causes the object's
diff --git a/jdk/src/share/classes/java/lang/Thread.java b/jdk/src/share/classes/java/lang/Thread.java
index 64987bd..8aab573 100644
--- a/jdk/src/share/classes/java/lang/Thread.java
+++ b/jdk/src/share/classes/java/lang/Thread.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -1851,6 +1851,7 @@
      * @see ThreadGroup#uncaughtException
      * @since 1.5
      */
+    @FunctionalInterface
     public interface UncaughtExceptionHandler {
         /**
          * Method invoked when the given thread terminates due to the
diff --git a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java
index 9986aef..d198d93 100644
--- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java
+++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -184,7 +184,8 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
-    public <T extends Annotation> T[] getAnnotations(Class<T> annotationClass) {
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
         throw new AssertionError("All subclasses should override this method");
     }
 
@@ -199,6 +200,7 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
+    @Override
     public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
         // Only annotations on classes are inherited, for all other
         // objects getDeclaredAnnotation is the same as
@@ -210,11 +212,12 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
-    public <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotationClass) {
+    @Override
+    public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
         // Only annotations on classes are inherited, for all other
-        // objects getDeclaredAnnotations is the same as
-        // getAnnotations.
-        return getAnnotations(annotationClass);
+        // objects getDeclaredAnnotationsByType is the same as
+        // getAnnotationsByType.
+        return getAnnotationsByType(annotationClass);
     }
 
     /**
diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java
index 85472ff..d6cffec 100644
--- a/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java
+++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java
@@ -35,22 +35,43 @@
  * arrays returned by accessors for array-valued enum members; it will
  * have no affect on the arrays returned to other callers.
  *
- * <p>An annotation A is <em>directly present</em> on an element E if the
- * RuntimeVisibleAnnotations or RuntimeVisibleParameterAnnotations attribute
- * associated with E either:
+ * <p>The {@link #getAnnotationsByType(Class)} and {@link
+ * #getDeclaredAnnotationsByType(Class)} methods support multiple
+ * annotations of the same type on an element. If the argument to either method
+ * is a repeatable annotation type (JLS 9.6), then the method will "look
+ * through" a container annotation (JLS 9.7) which was generated at
+ * compile-time to wrap multiple annotations of the argument type.
+ *
+ * <p>The terms <em>directly present</em> and <em>present</em> are used
+ * throughout this interface to describe precisely which annotations are
+ * returned by methods:
+ *
  * <ul>
- * <li>contains A; or
- * <li>for invocations of get[Declared]Annotations(Class<T>),
- * contains A or exactly one annotation C whose type is the containing
- * annotation type of A's type (JLS 9.6) and whose value element contains A
+ * <li>An annotation A is <em>directly present</em> on an element E if E is
+ * associated with a RuntimeVisibleAnnotations or
+ * RuntimeVisibleParameterAnnotations attribute, and:
+ *
+ * <ul>
+ * <li>for an invocation of {@code get[Declared]Annotation(Class<T>)} or
+ * {@code get[Declared]Annotations()}, the attribute contains A.
+ *
+ * <li>for an invocation of {@code get[Declared]AnnotationsByType(Class<T>)}, the
+ * attribute either contains A or, if the type of A is repeatable, contains
+ * exactly one annotation whose value element contains A and whose type is the
+ * containing annotation type of A's type (JLS 9.6).
  * </ul>
  *
- * <p>An annotation A is <em>present</em> on an element E if either:
+ * <p>
+ * <li>An annotation A is <em>present</em> on an element E if either:
+ *
  * <ul>
  * <li>A is <em>directly present</em> on E; or
- * <li>There are no annotations of A's type which are <em>directly present</em>
- * on E, and E is a class, and A's type is inheritable (JLS 9.6.3.3), and A is
- * present on the superclass of E
+ *
+ * <li>A is not <em>directly present</em> on E, and E is a class, and A's type
+ * is inheritable (JLS 9.6.3.3), and A is <em>present</em> on the superclass of
+ * E.
+ * </ul>
+ *
  * </ul>
  *
  * <p>If an annotation returned by a method in this interface contains
@@ -119,12 +140,19 @@
     <T extends Annotation> T getAnnotation(Class<T> annotationClass);
 
     /**
-     * Returns an array of all this element's annotations for the
-     * specified type if one or more of such annotation is present,
-     * else an array of length zero.
+     * Returns annotations that are <em>present</em> on this element.
      *
-     * The caller of this method is free to modify the returned array;
-     * it will have no effect on the arrays returned to other callers.
+     * If there are no annotations <em>present</em> on this element, the return
+     * value is an array of length 0.
+     *
+     * The difference between this method and {@link #getAnnotation(Class)}
+     * is that this method detects if its argument is a <em>repeatable
+     * annotation type</em> (JLS 9.6), and if so, attempts to find one or
+     * more annotations of that type by "looking through" a container
+     * annotation.
+     *
+     * The caller of this method is free to modify the returned array; it will
+     * have no effect on the arrays returned to other callers.
      *
      * @param annotationClass the Class object corresponding to the
      *        annotation type
@@ -133,7 +161,7 @@
      * @throws NullPointerException if the given annotation class is null
      * @since 1.8
      */
-    <T extends Annotation> T[] getAnnotations(Class<T> annotationClass);
+    <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass);
 
     /**
      * Returns annotations that are <em>present</em> on this element.
@@ -165,16 +193,21 @@
      */
     <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass);
 
-   /**
-     * Returns an array of all this element's annotations for the
-     * specified type if one or more of such annotation is directly
-     * present, else an array of length zero.
+    /**
+     * Returns annotations that are <em>directly present</em> on this element.
+     * This method ignores inherited annotations.
      *
-     * This method ignores inherited annotations. (Returns
-     * an array of length zero if no annotations are directly present
-     * on this element.)  The caller of this method is free to modify
-     * the returned array; it will have no effect on the arrays
-     * returned to other callers.
+     * If there are no annotations <em>directly present</em> on this element,
+     * the return value is an array of length 0.
+     *
+     * The difference between this method and {@link
+     * #getDeclaredAnnotation(Class)} is that this method detects if its
+     * argument is a <em>repeatable annotation type</em> (JLS 9.6), and if so,
+     * attempts to find one or more annotations of that type by "looking
+     * through" a container annotation.
+     *
+     * The caller of this method is free to modify the returned array; it will
+     * have no effect on the arrays returned to other callers.
      *
      * @param annotationClass the Class object corresponding to the
      *        annotation type
@@ -183,7 +216,7 @@
      * @throws NullPointerException if the given annotation class is null
      * @since 1.8
      */
-    <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotationClass);
+    <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass);
 
     /**
      * Returns annotations that are <em>directly present</em> on this element.
diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java
index ad1a580..83b5e9c 100644
--- a/jdk/src/share/classes/java/lang/reflect/Executable.java
+++ b/jdk/src/share/classes/java/lang/reflect/Executable.java
@@ -278,6 +278,10 @@
      * this object.  Returns an array of length 0 if the executable
      * has no parameters.
      *
+     * The parameters of the underlying executable do not necessarily
+     * have unique names, or names that are legal identifiers in the
+     * Java programming language (JLS 3.8).
+     *
      * @return an array of {@code Parameter} objects representing all
      * the parameters to the executable this object represents
      */
@@ -445,7 +449,8 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
-    public <T extends Annotation> T[] getAnnotations(Class<T> annotationClass) {
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
 
         return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass);
diff --git a/jdk/src/share/classes/java/lang/reflect/Field.java b/jdk/src/share/classes/java/lang/reflect/Field.java
index df38832..be13b07 100644
--- a/jdk/src/share/classes/java/lang/reflect/Field.java
+++ b/jdk/src/share/classes/java/lang/reflect/Field.java
@@ -1029,7 +1029,8 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
-    public <T extends Annotation> T[] getAnnotations(Class<T> annotationClass) {
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
 
         return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass);
diff --git a/jdk/src/share/classes/java/lang/reflect/Modifier.java b/jdk/src/share/classes/java/lang/reflect/Modifier.java
index 24cebe2..8c2b2cc 100644
--- a/jdk/src/share/classes/java/lang/reflect/Modifier.java
+++ b/jdk/src/share/classes/java/lang/reflect/Modifier.java
@@ -342,13 +342,13 @@
     static final int SYNTHETIC = 0x00001000;
     static final int ANNOTATION  = 0x00002000;
     static final int ENUM      = 0x00004000;
-    static final int SYNTHESIZED = 0x00010000;
+    static final int MANDATED  = 0x00008000;
     static boolean isSynthetic(int mod) {
       return (mod & SYNTHETIC) != 0;
     }
 
-    static boolean isSynthesized(int mod) {
-      return (mod & SYNTHESIZED) != 0;
+    static boolean isMandated(int mod) {
+      return (mod & MANDATED) != 0;
     }
 
     /**
diff --git a/jdk/src/share/classes/java/lang/reflect/Parameter.java b/jdk/src/share/classes/java/lang/reflect/Parameter.java
index 04bc274..9c80831 100644
--- a/jdk/src/share/classes/java/lang/reflect/Parameter.java
+++ b/jdk/src/share/classes/java/lang/reflect/Parameter.java
@@ -44,7 +44,7 @@
     private final String name;
     private final int modifiers;
     private final Executable executable;
-    private int index;
+    private final int index;
 
     /**
      * Package-private constructor for {@code Parameter}.
@@ -95,9 +95,14 @@
     }
 
     /**
-     * Returns a string representation of the parameter's modifiers,
-     * its attributes, its type, its name, and a trailing ... if it is
-     * a variadic parameter.
+     * Returns a string describing this parameter.  The format is the
+     * modifiers for the parameter, if any, in canonical order as
+     * recommended by <cite>The Java&trade; Language
+     * Specification</cite>, followed by the fully- qualified type of
+     * the parameter (excluding the last [] if the parameter is
+     * variable arity), followed by "..." if the parameter is variable
+     * arity, followed by a space, followed by the name of the
+     * parameter.
      *
      * @return A string representation of the parameter and associated
      * information.
@@ -118,7 +123,7 @@
             sb.append(typename);
 
         sb.append(" ");
-        sb.append(name);
+        sb.append(getName());
 
         return sb.toString();
     }
@@ -143,11 +148,23 @@
     }
 
     /**
-     * Returns the name of the parameter represented by this
-     * {@code Parameter} object.
+     * Returns the name of the parameter.  The names of the parameters
+     * of a single executable must all the be distinct.  When names
+     * from the originating source are available, they are returned.
+     * Otherwise, an implementation of this method is free to create a
+     * name of this parameter, subject to the unquiness requirments.
      */
     public String getName() {
-        return name;
+        // As per the spec, if a parameter has no name, return argX,
+        // where x is the index.
+        //
+        // Note: spec updates now outlaw empty strings as parameter
+        // names.  The .equals("") is for compatibility with current
+        // JVM behavior.  It may be removed at some point.
+        if(name == null || name.equals(""))
+            return "arg" + index;
+        else
+            return name;
     }
 
     /**
@@ -190,20 +207,21 @@
     private transient volatile Class<?> parameterClassCache = null;
 
     /**
-     * Returns {@code true} if this parameter is a synthesized
-     * construct; returns {@code false} otherwise.
+     * Returns {@code true} if this parameter is implicitly declared
+     * in source code; returns {@code false} otherwise.
      *
-     * @return true if and only if this parameter is a synthesized
-     * construct as defined by
-     * <cite>The Java&trade; Language Specification</cite>.
+     * @return true if and only if this parameter is implicitly
+     * declared as defined by <cite>The Java&trade; Language
+     * Specification</cite>.
      */
-    public boolean isSynthesized() {
-        return Modifier.isSynthesized(getModifiers());
+    public boolean isImplicit() {
+        return Modifier.isMandated(getModifiers());
     }
 
     /**
-     * Returns {@code true} if this parameter is a synthetic
-     * construct; returns {@code false} otherwise.
+     * Returns {@code true} if this parameter is neither implicitly
+     * nor explicitly declared in source code; returns {@code false}
+     * otherwise.
      *
      * @jls 13.1 The Form of a Binary
      * @return true if and only if this parameter is a synthetic
@@ -240,7 +258,8 @@
      * {@inheritDoc}
      * @throws NullPointerException {@inheritDoc}
      */
-    public <T extends Annotation> T[] getAnnotations(Class<T> annotationClass) {
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
 
         return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass);
@@ -266,11 +285,12 @@
     /**
      * @throws NullPointerException {@inheritDoc}
      */
-    public <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotationClass) {
+    @Override
+    public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
         // Only annotations on classes are inherited, for all other
         // objects getDeclaredAnnotations is the same as
         // getAnnotations.
-        return getAnnotations(annotationClass);
+        return getAnnotationsByType(annotationClass);
     }
 
     /**
diff --git a/jdk/src/share/classes/java/net/URLClassLoader.java b/jdk/src/share/classes/java/net/URLClassLoader.java
index fb0fe47..ba611dd 100644
--- a/jdk/src/share/classes/java/net/URLClassLoader.java
+++ b/jdk/src/share/classes/java/net/URLClassLoader.java
@@ -57,6 +57,12 @@
  * <p>
  * The classes that are loaded are by default granted permission only to
  * access the URLs specified when the URLClassLoader was created.
+ * <p>
+ * Where a JAR file contains the {@link Name#PROFILE Profile} attribute
+ * then its value is the name of the Java SE profile that the library
+ * minimally requires. If this runtime does not support the profile then
+ * it causes {@link java.util.jar.UnsupportedProfileException} to be
+ * thrown at some unspecified time.
  *
  * @author  David Connelly
  * @since   1.2
diff --git a/jdk/src/share/classes/java/nio/file/DirectoryStream.java b/jdk/src/share/classes/java/nio/file/DirectoryStream.java
index dd13c9a..48da97e 100644
--- a/jdk/src/share/classes/java/nio/file/DirectoryStream.java
+++ b/jdk/src/share/classes/java/nio/file/DirectoryStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -117,8 +117,7 @@
  */
 
 public interface DirectoryStream<T>
-    extends Closeable, Iterable<T>
-{
+    extends Closeable, Iterable<T> {
     /**
      * An interface that is implemented by objects that decide if a directory
      * entry should be accepted or filtered. A {@code Filter} is passed as the
@@ -130,6 +129,7 @@
      *
      * @since 1.7
      */
+    @FunctionalInterface
     public static interface Filter<T> {
         /**
          * Decides if the given directory entry should be accepted or filtered.
diff --git a/jdk/src/share/classes/java/nio/file/PathMatcher.java b/jdk/src/share/classes/java/nio/file/PathMatcher.java
index ab4b7ce..24e6149 100644
--- a/jdk/src/share/classes/java/nio/file/PathMatcher.java
+++ b/jdk/src/share/classes/java/nio/file/PathMatcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -34,7 +34,7 @@
  * @see FileSystem#getPathMatcher
  * @see Files#newDirectoryStream(Path,String)
  */
-
+@FunctionalInterface
 public interface PathMatcher {
     /**
      * Tells if given path matches this matcher's pattern.
diff --git a/jdk/src/share/classes/java/security/KeyStore.java b/jdk/src/share/classes/java/security/KeyStore.java
index 9656568..75d4057 100644
--- a/jdk/src/share/classes/java/security/KeyStore.java
+++ b/jdk/src/share/classes/java/security/KeyStore.java
@@ -219,6 +219,150 @@
     }
 
     /**
+     * Configuration data that specifies the keystores in a keystore domain.
+     * A keystore domain is a collection of keystores that are presented as a
+     * single logical keystore. The configuration data is used during
+     * {@code KeyStore}
+     * {@link #load(KeyStore.LoadStoreParameter) load} and
+     * {@link #store(KeyStore.LoadStoreParameter) store} operations.
+     * <p>
+     * The following syntax is supported for configuration data:
+     * <pre>
+     *
+     *     domain <domainName> [<property> ...] {
+     *         keystore <keystoreName> [<property> ...] ;
+     *         ...
+     *     };
+     *     ...
+     *
+     * </pre>
+     * where {@code domainName} and {@code keystoreName} are identifiers
+     * and {@code property} is a key/value pairing. The key and value are
+     * separated by an 'equals' symbol and the value is enclosed in double
+     * quotes. A property value may be either a printable string or a binary
+     * string of colon-separated pairs of hexadecimal digits. Multi-valued
+     * properties are represented as a comma-separated list of values,
+     * enclosed in square brackets.
+     * See {@link Arrays#toString(java.lang.Object[])}.
+     * <p>
+     * To ensure that keystore entries are uniquely identified, each
+     * entry's alias is prefixed by its {@code keystoreName} followed
+     * by the entry name separator and each {@code keystoreName} must be
+     * unique within its domain. Entry name prefixes are omitted when
+     * storing a keystore.
+     * <p>
+     * Properties are context-sensitive: properties that apply to
+     * all the keystores in a domain are located in the domain clause,
+     * and properties that apply only to a specific keystore are located
+     * in that keystore's clause.
+     * Unless otherwise specified, a property in a keystore clause overrides
+     * a property of the same name in the domain clause. All property names
+     * are case-insensitive. The following properties are supported:
+     * <dl>
+     * <dt> {@code keystoreType="<type>"} </dt>
+     *     <dd> The keystore type. </dd>
+     * <dt> {@code keystoreURI="<url>"} </dt>
+     *     <dd> The keystore location. </dd>
+     * <dt> {@code keystoreProviderName="<name>"} </dt>
+     *     <dd> The name of the keystore's JCE provider. </dd>
+     * <dt> {@code keystorePasswordEnv="<environment-variable>"} </dt>
+     *     <dd> The environment variable that stores a keystore password.
+     *          Alternatively, passwords may be supplied to the constructor
+     *          method in a {@code Map<String, ProtectionParameter>}. </dd>
+     * <dt> {@code entryNameSeparator="<separator>"} </dt>
+     *     <dd> The separator between a keystore name prefix and an entry name.
+     *          When specified, it applies to all the entries in a domain.
+     *          Its default value is a space. </dd>
+     * </dl>
+     * <p>
+     * For example, configuration data for a simple keystore domain
+     * comprising three keystores is shown below:
+     * <pre>
+     *
+     * domain app1 {
+     *     keystore app1-truststore
+     *         keystoreURI="file:///app1/etc/truststore.jks"
+     *
+     *     keystore system-truststore
+     *         keystoreURI="${java.home}/lib/security/cacerts"
+     *
+     *     keystore app1-keystore
+     *         keystoreType="PKCS12"
+     *         keystoreURI="file:///app1/etc/keystore.p12"
+     * };
+     *
+     * </pre>
+     * @since 1.8
+     */
+    public static final class DomainLoadStoreParameter
+        implements LoadStoreParameter {
+
+        private final URI configuration;
+        private final Map<String,ProtectionParameter> protectionParams;
+
+        /**
+         * Constructs a DomainLoadStoreParameter for a keystore domain with
+         * the parameters used to protect keystore data.
+         *
+         * @param configuration identifier for the domain configuration data.
+         *     The name of the target domain should be specified in the
+         *     {@code java.net.URI} fragment component when it is necessary
+         *     to distinguish between several domain configurations at the
+         *     same location.
+         *
+         * @param protectionParams the map from keystore name to the parameter
+         *     used to protect keystore data.
+         *     A {@code java.util.Collections.EMPTY_MAP} should be used
+         *     when protection parameters are not required or when they have
+         *     been specified by properties in the domain configuration data.
+         *     It is cloned to prevent subsequent modification.
+         *
+         * @exception NullPointerExcetion if {@code configuration} or
+         *     {@code protectionParams} is {@code null}
+         */
+        public DomainLoadStoreParameter(URI configuration,
+            Map<String,ProtectionParameter> protectionParams) {
+            if (configuration == null || protectionParams == null) {
+                throw new NullPointerException("invalid null input");
+            }
+            this.configuration = configuration;
+            this.protectionParams =
+                Collections.unmodifiableMap(new HashMap<>(protectionParams));
+        }
+
+        /**
+         * Gets the identifier for the domain configuration data.
+         *
+         * @return the identifier for the configuration data
+         */
+        public URI getConfiguration() {
+            return configuration;
+        }
+
+        /**
+         * Gets the keystore protection parameters for keystores in this
+         * domain.
+         *
+         * @return an unmodifiable map of keystore names to protection
+         *     parameters
+         */
+        public Map<String,ProtectionParameter> getProtectionParams() {
+            return protectionParams;
+        }
+
+        /**
+         * Gets the keystore protection parameters for this domain.
+         * Keystore domains do not support a protection parameter.
+         *
+         * @return always returns {@code null}
+         */
+        @Override
+        public KeyStore.ProtectionParameter getProtectionParameter() {
+            return null;
+        }
+    }
+
+    /**
      * A marker interface for keystore protection parameters.
      *
      * <p> The information stored in a <code>ProtectionParameter</code>
diff --git a/jdk/src/share/classes/java/sql/Date.java b/jdk/src/share/classes/java/sql/Date.java
index 4c0e6e9..0133fbe 100644
--- a/jdk/src/share/classes/java/sql/Date.java
+++ b/jdk/src/share/classes/java/sql/Date.java
@@ -25,6 +25,9 @@
 
 package java.sql;
 
+import java.time.Instant;
+import java.time.LocalDate;
+
 /**
  * <P>A thin wrapper around a millisecond value that allows
  * JDBC to identify this as an SQL <code>DATE</code> value.  A
@@ -113,7 +116,6 @@
         int firstDash;
         int secondDash;
         Date d = null;
-
         if (s == null) {
             throw new java.lang.IllegalArgumentException();
         }
@@ -255,4 +257,50 @@
     * compatibility.
     */
     static final long serialVersionUID = 1511598038487230103L;
+
+    /**
+     * Obtains an instance of {@code Date} from a {@link LocalDate} object
+     * with the same year, month and day of month value as the given
+     * {@code LocalDate}.
+     * <p>
+     * The provided {@code LocalDate} is interpreted as the local date
+     * in the local time zone.
+     *
+     * @param date a {@code LocalDate} to convert
+     * @return a {@code Date} object
+     * @exception NullPointerException if {@code date} is null
+     * @since 1.8
+     */
+    @SuppressWarnings("deprecation")
+    public static Date valueOf(LocalDate date) {
+        return new Date(date.getYear() - 1900, date.getMonthValue() -1,
+                        date.getDayOfMonth());
+    }
+
+    /**
+     * Converts this {@code Date} object to a {@code LocalDate}
+     * <p>
+     * The conversion creates a {@code LocalDate} that represents the same
+     * date value as this {@code Date} in local time zone
+     *
+     * @return a {@code LocalDate} object representing the same date value
+     *
+     * @since 1.8
+     */
+    @SuppressWarnings("deprecation")
+    public LocalDate toLocalDate() {
+        return LocalDate.of(getYear() + 1900, getMonth() + 1, getDate());
+    }
+
+   /**
+    * This method always throws an UnsupportedOperationException and should
+    * not be used because SQL {@code Date} values do not have a time
+    * component.
+    *
+    * @exception java.lang.UnsupportedOperationException if this method is invoked
+    */
+    @Override
+    public Instant toInstant() {
+        throw new java.lang.UnsupportedOperationException();
+    }
 }
diff --git a/jdk/src/share/classes/java/sql/JDBCType.java b/jdk/src/share/classes/java/sql/JDBCType.java
index f145305..74ee8e0 100644
--- a/jdk/src/share/classes/java/sql/JDBCType.java
+++ b/jdk/src/share/classes/java/sql/JDBCType.java
@@ -190,7 +190,17 @@
     /**
      * Identifies the generic SQL type {@code REF_CURSOR}.
      */
-    REF_CURSOR(Types.REF_CURSOR);
+    REF_CURSOR(Types.REF_CURSOR),
+
+    /**
+     * Identifies the generic SQL type {@code TIME_WITH_TIMEZONE}.
+     */
+    TIME_WITH_TIMEZONE(Types.TIME_WITH_TIMEZONE),
+
+    /**
+     * Identifies the generic SQL type {@code TIMESTAMP_WITH_TIMEZONE}.
+     */
+    TIMESTAMP_WITH_TIMEZONE(Types.TIMESTAMP_WITH_TIMEZONE);
 
     /**
      * The Integer value for the JDBCType.  It maps to a value in
diff --git a/jdk/src/share/classes/java/sql/SQLInput.java b/jdk/src/share/classes/java/sql/SQLInput.java
index c607e83..8d2540d 100644
--- a/jdk/src/share/classes/java/sql/SQLInput.java
+++ b/jdk/src/share/classes/java/sql/SQLInput.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -421,4 +421,38 @@
      */
     RowId readRowId() throws SQLException;
 
+    //--------------------------JDBC 4.2 -----------------------------
+
+    /**
+     * Reads the next attribute in the stream and returns it as an
+     * {@code Object} in the Java programming language. The
+     * actual type of the object returned is determined by the specified
+     * Java data type, and any customizations present in this
+     * stream's type map.
+     *
+     * <P>A type map is registered with the stream by the JDBC driver before the
+     * stream is passed to the application.
+     *
+     * <P>When the attribute at the head of the stream is an SQL {@code NULL}
+     * the method returns {@code null}. If the attribute is an SQL
+     * structured or distinct
+     * type, it determines the SQL type of the attribute at the head of the stream.
+     * If the stream's type map has an entry for that SQL type, the driver
+     * constructs an object of the appropriate class and calls the method
+     * {@code SQLData.readSQL} on that object, which reads additional data from the
+     * stream, using the protocol described for that method.
+     *<p>
+     * The default implementation will throw {@code SQLFeatureNotSupportedException}
+     *
+     * @param type Class representing the Java data type to convert the attribute to.
+     * @return the attribute at the head of the stream as an {@code Object} in the
+     * Java programming language;{@code null} if the attribute is SQL {@code NULL}
+     * @exception SQLException if a database access error occurs
+     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
+     * this method
+     * @since 1.8
+     */
+    default <T> T readObject(Class<T> type) throws SQLException {
+       throw new SQLFeatureNotSupportedException();
+    }
 }
diff --git a/jdk/src/share/classes/java/sql/SQLOutput.java b/jdk/src/share/classes/java/sql/SQLOutput.java
index 8aa1d14..0edfc99 100644
--- a/jdk/src/share/classes/java/sql/SQLOutput.java
+++ b/jdk/src/share/classes/java/sql/SQLOutput.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -272,7 +272,7 @@
    * Otherwise, it calls the <code>SQLData.writeSQL</code>
    * method of the given object, which
    * writes the object's attributes to the stream.
-   * The implementation of the method <code>SQLData.writeSQ</code>
+   * The implementation of the method <code>SQLData.writeSQL</code>
    * calls the appropriate <code>SQLOutput</code> writer method(s)
    * for writing each of the object's attributes in order.
    * The attributes must be read from an <code>SQLInput</code>
@@ -433,5 +433,43 @@
    */
   void writeSQLXML(SQLXML x) throws SQLException;
 
+  //--------------------------JDBC 4.2 -----------------------------
+
+  /**
+   * Writes to the stream the data contained in the given object. The
+   * object will be converted to the specified targetSqlType
+   * before being sent to the stream.
+   *<p>
+   * When the {@code object} is {@code null}, this
+   * method writes an SQL {@code NULL} to the stream.
+   * <p>
+   * If the object has a custom mapping (is of a class implementing the
+   * interface {@code SQLData}),
+   * the JDBC driver should call the method {@code SQLData.writeSQL} to
+   * write it to the SQL data stream.
+   * If, on the other hand, the object is of a class implementing
+   * {@code Ref}, {@code Blob}, {@code Clob},  {@code NClob},
+   *  {@code Struct}, {@code java.net.URL},
+   * or {@code Array}, the driver should pass it to the database as a
+   * value of the corresponding SQL type.
+   *<P>
+   * The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type to be sent to the database.
+   * @exception SQLException if a database access error occurs  or
+   *            if the Java Object specified by x is an InputStream
+   *            or Reader object and the value of the scale parameter is less
+   *            than zero
+   * @exception SQLFeatureNotSupportedException if
+   * the JDBC driver does not support this data type
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  default void writeObject(Object x, SQLType targetSqlType) throws SQLException {
+        throw new SQLFeatureNotSupportedException();
+  }
 
 }
+
diff --git a/jdk/src/share/classes/java/sql/Time.java b/jdk/src/share/classes/java/sql/Time.java
index 01f046a..de187e9 100644
--- a/jdk/src/share/classes/java/sql/Time.java
+++ b/jdk/src/share/classes/java/sql/Time.java
@@ -25,6 +25,9 @@
 
 package java.sql;
 
+import java.time.Instant;
+import java.time.LocalTime;
+
 /**
  * <P>A thin wrapper around the <code>java.util.Date</code> class that allows the JDBC
  * API to identify this as an SQL <code>TIME</code> value. The <code>Time</code>
@@ -246,4 +249,45 @@
     * compatibility.
     */
     static final long serialVersionUID = 8397324403548013681L;
+
+    /**
+     * Obtains an instance of {@code Time} from a {@link LocalTime} object
+     * with the same hour, minute and second time value as the given
+     * {@code LocalTime}.
+     *
+     * @param time a {@code LocalTime} to convert
+     * @return a {@code Time} object
+     * @exception NullPointerException if {@code time} is null
+     * @since 1.8
+     */
+    @SuppressWarnings("deprecation")
+    public static Time valueOf(LocalTime time) {
+        return new Time(time.getHour(), time.getMinute(), time.getSecond());
+    }
+
+    /**
+     * Converts this {@code Time} object to a {@code LocalTime}.
+     * <p>
+     * The conversion creates a {@code LocalTime} that represents the same
+     * hour, minute, and second time value as this {@code Time}.
+     *
+     * @return a {@code LocalTime} object representing the same time value
+     * @since 1.8
+     */
+    @SuppressWarnings("deprecation")
+    public LocalTime toLocalTime() {
+        return LocalTime.of(getHours(), getMinutes(), getSeconds());
+    }
+
+   /**
+    * This method always throws an UnsupportedOperationException and should
+    * not be used because SQL {@code Time} values do not have a date
+    * component.
+    *
+    * @exception java.lang.UnsupportedOperationException if this method is invoked
+    */
+    @Override
+    public Instant toInstant() {
+        throw new java.lang.UnsupportedOperationException();
+    }
 }
diff --git a/jdk/src/share/classes/java/sql/Timestamp.java b/jdk/src/share/classes/java/sql/Timestamp.java
index 18b61ed..afa56ee 100644
--- a/jdk/src/share/classes/java/sql/Timestamp.java
+++ b/jdk/src/share/classes/java/sql/Timestamp.java
@@ -25,6 +25,8 @@
 
 package java.sql;
 
+import java.time.Instant;
+import java.time.LocalDateTime;
 import java.util.StringTokenizer;
 
 /**
@@ -485,7 +487,6 @@
             }
         }
         return i;
-
     }
 
     /**
@@ -530,4 +531,89 @@
 
     static final long serialVersionUID = 2745179027874758501L;
 
+    private static final int MILLIS_PER_SECOND = 1000;
+
+    /**
+     * Obtains an instance of {@code Timestamp} from a {@code LocalDateTime}
+     * object, with the same year, month, day of month, hours, minutes,
+     * seconds and nanos date-time value as the provided {@code LocalDateTime}.
+     * <p>
+     * The provided {@code LocalDateTime} is interpreted as the local
+     * date-time in the local time zone.
+     *
+     * @param dateTime a {@code LocalDateTime} to convert
+     * @return a {@code Timestamp} object
+     * @exception NullPointerException if {@code dateTime} is null.
+     * @since 1.8
+     */
+    @SuppressWarnings("deprecation")
+    public static Timestamp valueOf(LocalDateTime dateTime) {
+        return new Timestamp(dateTime.getYear() - 1900,
+                             dateTime.getMonthValue() - 1,
+                             dateTime.getDayOfMonth(),
+                             dateTime.getHour(),
+                             dateTime.getMinute(),
+                             dateTime.getSecond(),
+                             dateTime.getNano());
+    }
+
+    /**
+     * Converts this {@code Timestamp} object to a {@code LocalDateTime}.
+     * <p>
+     * The conversion creates a {@code LocalDateTime} that represents the
+     * same year, month, day of month, hours, minutes, seconds and nanos
+     * date-time value as this {@code Timestamp} in the local time zone.
+     *
+     * @return a {@code LocalDateTime} object representing the same date-time value
+     * @since 1.8
+     */
+    @SuppressWarnings("deprecation")
+    public LocalDateTime toLocalDateTime() {
+        return LocalDateTime.of(getYear() + 1900,
+                                getMonth() + 1,
+                                getDate(),
+                                getHours(),
+                                getMinutes(),
+                                getSeconds(),
+                                getNanos());
+    }
+
+    /**
+     * Obtains an instance of {@code Timestamp} from an {@link Instant} object.
+     * <p>
+     * {@code Instant} can store points on the time-line further in the future
+     * and further in the past than {@code Date}. In this scenario, this method
+     * will throw an exception.
+     *
+     * @param instant  the instant to convert
+     * @return an {@code Timestamp} representing the same point on the time-line as
+     *  the provided instant
+     * @exception NullPointerException if {@code instant} is null.
+     * @exception IllegalArgumentException if the instant is too large to
+     *  represent as a {@code Timesamp}
+     * @since 1.8
+     */
+    public static Timestamp from(Instant instant) {
+        try {
+            Timestamp stamp = new Timestamp(instant.getEpochSecond() * MILLIS_PER_SECOND);
+            stamp.nanos = instant.getNano();
+            return stamp;
+        } catch (ArithmeticException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+
+    /**
+     * Converts this {@code Timestamp} object to an {@code Instant}.
+     * <p>
+     * The conversion creates an {@code Instant} that represents the same
+     * point on the time-line as this {@code Timestamp}.
+     *
+     * @return an instant representing the same point on the time-line
+     * @since 1.8
+     */
+    @Override
+    public Instant toInstant() {
+        return Instant.ofEpochSecond(super.getTime() / MILLIS_PER_SECOND, nanos);
+    }
 }
diff --git a/jdk/src/share/classes/java/sql/Types.java b/jdk/src/share/classes/java/sql/Types.java
index d6fc80a..f12ff0d 100644
--- a/jdk/src/share/classes/java/sql/Types.java
+++ b/jdk/src/share/classes/java/sql/Types.java
@@ -319,6 +319,24 @@
      */
     public static final int REF_CURSOR = 2012;
 
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * {@code TIME WITH TIMEZONE}.
+     *
+     * @since 1.8
+     */
+    public static final int TIME_WITH_TIMEZONE = 2013;
+
+    /**
+     * The constant in the Java programming language, sometimes referred to
+     * as a type code, that identifies the generic SQL type
+     * {@code TIMESTAMP WITH TIMEZONE}.
+     *
+     * @since 1.8
+     */
+    public static final int TIMESTAMP_WITH_TIMEZONE = 2014;
+
     // Prevent instantiation
     private Types() {}
 }
diff --git a/jdk/src/share/classes/java/time/Clock.java b/jdk/src/share/classes/java/time/Clock.java
index e400607..c0be4b0 100644
--- a/jdk/src/share/classes/java/time/Clock.java
+++ b/jdk/src/share/classes/java/time/Clock.java
@@ -377,60 +377,57 @@
      * an instant on the time-line rather than a raw millisecond value.
      * This method is provided to allow the use of the clock in high performance use cases
      * where the creation of an object would be unacceptable.
+     * <p>
+     * The default implementation currently calls {@link #instant}.
      *
      * @return the current millisecond instant from this clock, measured from
      *  the Java epoch of 1970-01-01T00:00 UTC, not null
      * @throws DateTimeException if the instant cannot be obtained, not thrown by most implementations
      */
-    public abstract long millis();
+    public long millis() {
+        return instant().toEpochMilli();
+    }
 
     //-----------------------------------------------------------------------
     /**
      * Gets the current instant of the clock.
      * <p>
      * This returns an instant representing the current instant as defined by the clock.
-     * <p>
-     * The default implementation currently calls {@link #millis}.
      *
      * @return the current instant from this clock, not null
      * @throws DateTimeException if the instant cannot be obtained, not thrown by most implementations
      */
-    public Instant instant() {
-        return Instant.ofEpochMilli(millis());
-    }
+    public abstract Instant instant();
 
     //-----------------------------------------------------------------------
     /**
      * Checks if this clock is equal to another clock.
      * <p>
-     * Clocks must compare equal based on their state and behavior.
+     * Clocks should override this method to compare equals based on
+     * their state and to meet the contract of {@link Object#equals}.
+     * If not overridden, the behavior is defined by {@link Object#equals}
      *
      * @param obj  the object to check, null returns false
      * @return true if this is equal to the other clock
      */
     @Override
-    public abstract boolean equals(Object obj);
+    public boolean equals(Object obj) {
+        return super.equals(obj);
+    }
 
     /**
      * A hash code for this clock.
+     * <p>
+     * Clocks should override this method based on
+     * their state and to meet the contract of {@link Object#hashCode}.
+     * If not overridden, the behavior is defined by {@link Object#hashCode}
      *
      * @return a suitable hash code
      */
     @Override
-    public abstract int hashCode();
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a string describing this clock.
-     * <p>
-     * Clocks must have a string representation based on their state and behavior.
-     * For example, 'System[Europe/Paris]' could be used to represent the System
-     * clock in the 'Europe/Paris' time-zone.
-     *
-     * @return a string representation of this clock, not null
-     */
-    @Override
-    public abstract String toString();
+    public  int hashCode() {
+        return super.hashCode();
+    }
 
     //-----------------------------------------------------------------------
     /**
@@ -460,6 +457,10 @@
             return System.currentTimeMillis();
         }
         @Override
+        public Instant instant() {
+            return Instant.ofEpochMilli(millis());
+        }
+        @Override
         public boolean equals(Object obj) {
             if (obj instanceof SystemClock) {
                 return zone.equals(((SystemClock) obj).zone);
diff --git a/jdk/src/share/classes/java/time/DayOfWeek.java b/jdk/src/share/classes/java/time/DayOfWeek.java
index 5d1f3f3..c616a31 100644
--- a/jdk/src/share/classes/java/time/DayOfWeek.java
+++ b/jdk/src/share/classes/java/time/DayOfWeek.java
@@ -170,8 +170,9 @@
     /**
      * Obtains an instance of {@code DayOfWeek} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code DayOfWeek}.
+     * This obtains a day-of-week based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code DayOfWeek}.
      * <p>
      * The conversion extracts the {@link ChronoField#DAY_OF_WEEK DAY_OF_WEEK} field.
      * <p>
@@ -206,8 +207,9 @@
     /**
      * Gets the textual representation, such as 'Mon' or 'Friday'.
      * <p>
-     * This returns the textual name used to identify the day-of-week.
-     * The parameters control the length of the returned text and the locale.
+     * This returns the textual name used to identify the day-of-week,
+     * suitable for presentation to the user.
+     * The parameters control the style of the returned text and the locale.
      * <p>
      * If no textual mapping is found then the {@link #getValue() numeric value} is returned.
      *
@@ -215,8 +217,8 @@
      * @param locale  the locale to use, not null
      * @return the text value of the day-of-week, not null
      */
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendText(DAY_OF_WEEK, style).toFormatter(locale).print(this);
+    public String getDisplayName(TextStyle style, Locale locale) {
+        return new DateTimeFormatterBuilder().appendText(DAY_OF_WEEK, style).toFormatter(locale).format(this);
     }
 
     //-----------------------------------------------------------------------
@@ -232,7 +234,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -244,7 +246,7 @@
         if (field instanceof ChronoField) {
             return field == DAY_OF_WEEK;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -260,7 +262,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -289,15 +291,13 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
      * @param field  the field to get, not null
      * @return the value for the field, within the valid range of values
      * @throws DateTimeException if a value for the field cannot be obtained
-     * @throws DateTimeException if the range of valid values for the field exceeds an {@code int}
-     * @throws DateTimeException if the value is outside the range of valid values for the field
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
@@ -320,7 +320,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -336,7 +336,7 @@
         } else if (field instanceof ChronoField) {
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/Duration.java b/jdk/src/share/classes/java/time/Duration.java
index e8d75fa..86e410f 100644
--- a/jdk/src/share/classes/java/time/Duration.java
+++ b/jdk/src/share/classes/java/time/Duration.java
@@ -61,10 +61,14 @@
  */
 package java.time;
 
+import static java.time.LocalTime.NANOS_PER_SECOND;
 import static java.time.LocalTime.SECONDS_PER_DAY;
-import static java.time.temporal.ChronoField.INSTANT_SECONDS;
+import static java.time.LocalTime.SECONDS_PER_HOUR;
+import static java.time.LocalTime.SECONDS_PER_MINUTE;
 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
 import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.NANOS;
+import static java.time.temporal.ChronoUnit.SECONDS;
 
 import java.io.DataInput;
 import java.io.DataOutput;
@@ -79,17 +83,23 @@
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
-import java.time.temporal.TemporalSubtractor;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalUnit;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
- * A duration between two instants on the time-line.
+ * A time-based amount of time, such as '34.5 seconds'.
  * <p>
- * This class models a duration of time and is not tied to any instant.
- * The model is of a directed duration, meaning that the duration may be negative.
+ * This class models a quantity or amount of time in terms of seconds and nanoseconds.
+ * It can be accessed using other duration-based units, such as minutes and hours.
+ * In addition, the {@link ChronoUnit#DAYS DAYS} unit can be used and is treated as
+ * exactly equal to 24 hours, thus ignoring daylight savings effects.
+ * See {@link Period} for the date-based equivalent to this class.
  * <p>
  * A physical duration could be of infinite length.
  * For practicality, the duration is stored with constraints similar to {@link Instant}.
@@ -99,6 +109,7 @@
  * The range of a duration requires the storage of a number larger than a {@code long}.
  * To achieve this, the class stores a {@code long} representing seconds and an {@code int}
  * representing nanosecond-of-second, which will always be between 0 and 999,999,999.
+ * The model is of a directed duration, meaning that the duration may be negative.
  * <p>
  * The duration is measured in "seconds", but these are not necessarily identical to
  * the scientific "SI second" definition based on atomic clocks.
@@ -112,7 +123,7 @@
  * @since 1.8
  */
 public final class Duration
-        implements TemporalAdder, TemporalSubtractor, Comparable<Duration>, Serializable {
+        implements TemporalAmount, Comparable<Duration>, Serializable {
 
     /**
      * Constant for a duration of zero.
@@ -125,11 +136,14 @@
     /**
      * Constant for nanos per second.
      */
-    private static final int NANOS_PER_SECOND = 1000_000_000;
-    /**
-     * Constant for nanos per second.
-     */
     private static final BigInteger BI_NANOS_PER_SECOND = BigInteger.valueOf(NANOS_PER_SECOND);
+    /**
+     * The pattern for parsing.
+     */
+    private final static Pattern PATTERN =
+            Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" +
+                    "(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?",
+                    Pattern.CASE_INSENSITIVE);
 
     /**
      * The number of seconds in the duration.
@@ -143,7 +157,53 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Duration} from a number of seconds.
+     * Obtains a {@code Duration} representing a number of standard 24 hour days.
+     * <p>
+     * The seconds are calculated based on the standard definition of a day,
+     * where each day is 86400 seconds which implies a 24 hour day.
+     * The nanosecond in second field is set to zero.
+     *
+     * @param days  the number of days, positive or negative
+     * @return a {@code Duration}, not null
+     * @throws ArithmeticException if the input days exceeds the capacity of {@code Duration}
+     */
+    public static Duration ofDays(long days) {
+        return create(Math.multiplyExact(days, SECONDS_PER_DAY), 0);
+    }
+
+    /**
+     * Obtains a {@code Duration} representing a number of standard hours.
+     * <p>
+     * The seconds are calculated based on the standard definition of an hour,
+     * where each hour is 3600 seconds.
+     * The nanosecond in second field is set to zero.
+     *
+     * @param hours  the number of hours, positive or negative
+     * @return a {@code Duration}, not null
+     * @throws ArithmeticException if the input hours exceeds the capacity of {@code Duration}
+     */
+    public static Duration ofHours(long hours) {
+        return create(Math.multiplyExact(hours, SECONDS_PER_HOUR), 0);
+    }
+
+    /**
+     * Obtains a {@code Duration} representing a number of standard minutes.
+     * <p>
+     * The seconds are calculated based on the standard definition of a minute,
+     * where each minute is 60 seconds.
+     * The nanosecond in second field is set to zero.
+     *
+     * @param minutes  the number of minutes, positive or negative
+     * @return a {@code Duration}, not null
+     * @throws ArithmeticException if the input minutes exceeds the capacity of {@code Duration}
+     */
+    public static Duration ofMinutes(long minutes) {
+        return create(Math.multiplyExact(minutes, SECONDS_PER_MINUTE), 0);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Obtains a {@code Duration} representing a number of seconds.
      * <p>
      * The nanosecond in second field is set to zero.
      *
@@ -155,8 +215,8 @@
     }
 
     /**
-     * Obtains an instance of {@code Duration} from a number of seconds
-     * and an adjustment in nanoseconds.
+     * Obtains a {@code Duration} representing a number of seconds and an
+     * adjustment in nanoseconds.
      * <p>
      * This method allows an arbitrary number of nanoseconds to be passed in.
      * The factory will alter the values of the second and nanosecond in order
@@ -175,13 +235,13 @@
      */
     public static Duration ofSeconds(long seconds, long nanoAdjustment) {
         long secs = Math.addExact(seconds, Math.floorDiv(nanoAdjustment, NANOS_PER_SECOND));
-        int nos = (int)Math.floorMod(nanoAdjustment, NANOS_PER_SECOND);
+        int nos = (int) Math.floorMod(nanoAdjustment, NANOS_PER_SECOND);
         return create(secs, nos);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Duration} from a number of milliseconds.
+     * Obtains a {@code Duration} representing a number of milliseconds.
      * <p>
      * The seconds and nanoseconds are extracted from the specified milliseconds.
      *
@@ -200,7 +260,7 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Duration} from a number of nanoseconds.
+     * Obtains a {@code Duration} representing a number of nanoseconds.
      * <p>
      * The seconds and nanoseconds are extracted from the specified nanoseconds.
      *
@@ -219,53 +279,7 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Duration} from a number of standard length minutes.
-     * <p>
-     * The seconds are calculated based on the standard definition of a minute,
-     * where each minute is 60 seconds.
-     * The nanosecond in second field is set to zero.
-     *
-     * @param minutes  the number of minutes, positive or negative
-     * @return a {@code Duration}, not null
-     * @throws ArithmeticException if the input minutes exceeds the capacity of {@code Duration}
-     */
-    public static Duration ofMinutes(long minutes) {
-        return create(Math.multiplyExact(minutes, 60), 0);
-    }
-
-    /**
-     * Obtains an instance of {@code Duration} from a number of standard length hours.
-     * <p>
-     * The seconds are calculated based on the standard definition of an hour,
-     * where each hour is 3600 seconds.
-     * The nanosecond in second field is set to zero.
-     *
-     * @param hours  the number of hours, positive or negative
-     * @return a {@code Duration}, not null
-     * @throws ArithmeticException if the input hours exceeds the capacity of {@code Duration}
-     */
-    public static Duration ofHours(long hours) {
-        return create(Math.multiplyExact(hours, 3600), 0);
-    }
-
-    /**
-     * Obtains an instance of {@code Duration} from a number of standard 24 hour days.
-     * <p>
-     * The seconds are calculated based on the standard definition of a day,
-     * where each day is 86400 seconds which implies a 24 hour day.
-     * The nanosecond in second field is set to zero.
-     *
-     * @param days  the number of days, positive or negative
-     * @return a {@code Duration}, not null
-     * @throws ArithmeticException if the input days exceeds the capacity of {@code Duration}
-     */
-    public static Duration ofDays(long days) {
-        return create(Math.multiplyExact(days, 86400), 0);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains an instance of {@code Duration} from a duration in the specified unit.
+     * Obtains a {@code Duration} representing an amount in the specified unit.
      * <p>
      * The parameters represent the two parts of a phrase like '6 Hours'. For example:
      * <pre>
@@ -288,110 +302,139 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Duration} representing the duration between two instants.
+     * Obtains a {@code Duration} representing the duration between two instants.
      * <p>
-     * A {@code Duration} represents a directed distance between two points on the time-line.
-     * As such, this method will return a negative duration if the end is before the start.
-     * To guarantee to obtain a positive duration call {@link #abs()} on the result of this factory.
+     * This calculates the duration between two temporal objects of the same type.
+     * The difference in seconds is calculated using
+     * {@link Temporal#periodUntil(Temporal, TemporalUnit)}.
+     * The difference in nanoseconds is calculated using by querying the
+     * {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} field.
+     * <p>
+     * The result of this method can be a negative period if the end is before the start.
+     * To guarantee to obtain a positive duration call {@link #abs()} on the result.
      *
      * @param startInclusive  the start instant, inclusive, not null
      * @param endExclusive  the end instant, exclusive, not null
      * @return a {@code Duration}, not null
      * @throws ArithmeticException if the calculation exceeds the capacity of {@code Duration}
      */
-    public static Duration between(TemporalAccessor startInclusive, TemporalAccessor endExclusive) {
-        long secs = Math.subtractExact(endExclusive.getLong(INSTANT_SECONDS), startInclusive.getLong(INSTANT_SECONDS));
-        long nanos = endExclusive.getLong(NANO_OF_SECOND) - startInclusive.getLong(NANO_OF_SECOND);
-        secs = Math.addExact(secs, Math.floorDiv(nanos, NANOS_PER_SECOND));
-        nanos = Math.floorMod(nanos, NANOS_PER_SECOND);
-        return create(secs, (int) nanos);  // safe from overflow
+    public static  Duration between(Temporal startInclusive, Temporal endExclusive) {
+        long secs = startInclusive.periodUntil(endExclusive, SECONDS);
+        long nanos;
+        try {
+            nanos = endExclusive.getLong(NANO_OF_SECOND) - startInclusive.getLong(NANO_OF_SECOND);
+        } catch (DateTimeException ex) {
+            nanos = 0;
+        }
+        return ofSeconds(secs, nanos);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Duration} by parsing a text string.
+     * Obtains a {@code Duration} from a text string such as {@code PnDTnHnMn.nS}.
      * <p>
-     * This will parse the string produced by {@link #toString()} which is
-     * the ISO-8601 format {@code PTnS} where {@code n} is
-     * the number of seconds with optional decimal part.
-     * The number must consist of ASCII numerals.
-     * There must only be a negative sign at the start of the number and it can
-     * only be present if the value is less than zero.
-     * There must be at least one digit before any decimal point.
-     * There must be between 1 and 9 inclusive digits after any decimal point.
-     * The letters (P, T and S) will be accepted in upper or lower case.
+     * This will parse a textual representation of a duration, including the
+     * string produced by {@code toString()}. The formats accepted are based
+     * on the ISO-8601 duration format {@code PnDTnHnMn.nS} with days
+     * considered to be exactly 24 hours.
+     * <p>
+     * The string starts with an optional sign, denoted by the ASCII negative
+     * or positive symbol. If negative, the whole period is negated.
+     * The ASCII letter "P" is next in upper or lower case.
+     * There are then four sections, each consisting of a number and a suffix.
+     * The sections have suffixes in ASCII of "D", "H", "M" and "S" for
+     * days, hours, minutes and seconds, accepted in upper or lower case.
+     * The suffixes must occur in order. The ASCII letter "T" must occur before
+     * the first occurrence, if any, of an hour, minute or second section.
+     * At least one of the four sections must be present, and if "T" is present
+     * there must be at least one section after the "T".
+     * The number part of each section must consist of one or more ASCII digits.
+     * The number may be prefixed by the ASCII negative or positive symbol.
+     * The number of days, hours and minutes must parse to an {@code long}.
+     * The number of seconds must parse to an {@code long} with optional fraction.
      * The decimal point may be either a dot or a comma.
+     * The fractional part may have from zero to 9 digits.
+     * <p>
+     * The leading plus/minus sign, and negative values for other units are
+     * not part of the ISO-8601 standard.
+     * <p>
+     * Examples:
+     * <pre>
+     *    "PT20.345S" -> parses as "20.345 seconds"
+     *    "PT15M"     -> parses as "15 minutes" (where a minute is 60 seconds)
+     *    "PT10H"     -> parses as "10 hours" (where an hour is 3600 seconds)
+     *    "P2D"       -> parses as "2 days" (where a day is 24 hours or 86400 seconds)
+     *    "P2DT3H4M"  -> parses as "2 days, 3 hours and 4 minutes"
+     *    "P-6H3M"    -> parses as "-6 hours and +3 minutes"
+     *    "-P6H3M"    -> parses as "-6 hours and -3 minutes"
+     *    "-P-6H+3M"  -> parses as "+6 hours and -3 minutes"
+     * </pre>
      *
      * @param text  the text to parse, not null
-     * @return a {@code Duration}, not null
-     * @throws DateTimeParseException if the text cannot be parsed to a {@code Duration}
+     * @return the parsed duration, not null
+     * @throws DateTimeParseException if the text cannot be parsed to a duration
      */
-    public static Duration parse(final CharSequence text) {
+    public static Duration parse(CharSequence text) {
         Objects.requireNonNull(text, "text");
-        int len = text.length();
-        if (len < 4 ||
-                (text.charAt(0) != 'P' && text.charAt(0) != 'p') ||
-                (text.charAt(1) != 'T' && text.charAt(1) != 't') ||
-                (text.charAt(len - 1) != 'S' && text.charAt(len - 1) != 's') ||
-                (len == 5 && text.charAt(2) == '-' && text.charAt(3) == '0')) {
-            throw new DateTimeParseException("Duration could not be parsed: " + text, text, 0);
-        }
-        String numberText = text.subSequence(2, len - 1).toString().replace(',', '.');
-        if (numberText.charAt(0) == '+') {
-            throw new DateTimeParseException("Duration could not be parsed: " + text, text, 2);
-        }
-        int dot = numberText.indexOf('.');
-        try {
-            if (dot == -1) {
-                // no decimal places
-                if (numberText.startsWith("-0")) {
-                    throw new DateTimeParseException("Duration could not be parsed: " + text, text, 2);
+        Matcher matcher = PATTERN.matcher(text);
+        if (matcher.matches()) {
+            // check for letter T but no time sections
+            if ("T".equals(matcher.group(3)) == false) {
+                boolean negate = "-".equals(matcher.group(1));
+                String dayMatch = matcher.group(2);
+                String hourMatch = matcher.group(4);
+                String minuteMatch = matcher.group(5);
+                String secondMatch = matcher.group(6);
+                String fractionMatch = matcher.group(7);
+                if (dayMatch != null || hourMatch != null || minuteMatch != null || secondMatch != null) {
+                    long daysAsSecs = parseNumber(text, dayMatch, SECONDS_PER_DAY, "days");
+                    long hoursAsSecs = parseNumber(text, hourMatch, SECONDS_PER_HOUR, "hours");
+                    long minsAsSecs = parseNumber(text, minuteMatch, SECONDS_PER_MINUTE, "minutes");
+                    long seconds = parseNumber(text, secondMatch, 1, "seconds");
+                    int nanos = parseFraction(text,  fractionMatch, seconds < 0 ? -1 : 1);
+                    try {
+                        return create(negate, daysAsSecs, hoursAsSecs, minsAsSecs, seconds, nanos);
+                    } catch (ArithmeticException ex) {
+                        throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: overflow", text, 0).initCause(ex);
+                    }
                 }
-                return create(Long.parseLong(numberText), 0);
             }
-            // decimal places
-            boolean negative = false;
-            if (numberText.charAt(0) == '-') {
-                negative = true;
-            }
-            long secs = Long.parseLong(numberText.substring(0, dot));
-            numberText = numberText.substring(dot + 1);
-            len = numberText.length();
-            if (len == 0 || len > 9 || numberText.charAt(0) == '-' || numberText.charAt(0) == '+') {
-                throw new DateTimeParseException("Duration could not be parsed: " + text, text, 2);
-            }
-            int nanos = Integer.parseInt(numberText);
-            switch (len) {
-                case 1:
-                    nanos *= 100000000;
-                    break;
-                case 2:
-                    nanos *= 10000000;
-                    break;
-                case 3:
-                    nanos *= 1000000;
-                    break;
-                case 4:
-                    nanos *= 100000;
-                    break;
-                case 5:
-                    nanos *= 10000;
-                    break;
-                case 6:
-                    nanos *= 1000;
-                    break;
-                case 7:
-                    nanos *= 100;
-                    break;
-                case 8:
-                    nanos *= 10;
-                    break;
-            }
-            return negative ? ofSeconds(secs, -nanos) : create(secs, nanos);
-
-        } catch (ArithmeticException | NumberFormatException ex) {
-            throw new DateTimeParseException("Duration could not be parsed: " + text, text, 2, ex);
         }
+        throw new DateTimeParseException("Text cannot be parsed to a Duration", text, 0);
+    }
+
+    private static long parseNumber(CharSequence text, String parsed, int multiplier, String errorText) {
+        // regex limits to [-+]?[0-9]+
+        if (parsed == null) {
+            return 0;
+        }
+        try {
+            long val = Long.parseLong(parsed);
+            return Math.multiplyExact(val, multiplier);
+        } catch (NumberFormatException | ArithmeticException ex) {
+            throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: " + errorText, text, 0).initCause(ex);
+        }
+    }
+
+    private static int parseFraction(CharSequence text, String parsed, int negate) {
+        // regex limits to [0-9]{0,9}
+        if (parsed == null || parsed.length() == 0) {
+            return 0;
+        }
+        try {
+            parsed = (parsed + "000000000").substring(0, 9);
+            return Integer.parseInt(parsed) * negate;
+        } catch (NumberFormatException | ArithmeticException ex) {
+            throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: fraction", text, 0).initCause(ex);
+        }
+    }
+
+    private static Duration create(boolean negate, long daysAsSecs, long hoursAsSecs, long minsAsSecs, long secs, int nanos) {
+        long seconds = Math.addExact(daysAsSecs, Math.addExact(hoursAsSecs, Math.addExact(minsAsSecs, secs)));
+        if (negate) {
+            return ofSeconds(seconds, nanos).negated();
+        }
+        return ofSeconds(seconds, nanos);
     }
 
     //-----------------------------------------------------------------------
@@ -422,6 +465,56 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Gets the value of the requested unit.
+     * <p>
+     * This returns a value for each of the two supported units,
+     * {@link ChronoUnit#SECONDS SECONDS} and {@link ChronoUnit#NANOS NANOS}.
+     * All other units throw an exception.
+     *
+     * @param unit the {@code TemporalUnit} for which to return the value
+     * @return the long value of the unit
+     * @throws DateTimeException if the unit is not supported
+     */
+    @Override
+    public long get(TemporalUnit unit) {
+        if (unit == SECONDS) {
+            return seconds;
+        } else if (unit == NANOS) {
+            return nanos;
+        } else {
+            throw new DateTimeException("Unsupported unit: " + unit.getName());
+        }
+    }
+
+    /**
+     * Gets the set of units supported by this duration.
+     * <p>
+     * The supported units are {@link ChronoUnit#SECONDS SECONDS},
+     * and {@link ChronoUnit#NANOS NANOS}.
+     * They are returned in the order seconds, nanos.
+     * <p>
+     * This set can be used in conjunction with {@link #get(TemporalUnit)}
+     * to access the entire state of the period.
+     *
+     * @return a list containing the seconds and nanos units, not null
+     */
+    @Override
+    public List<TemporalUnit> getUnits() {
+        return DurationUnits.UNITS;
+    }
+
+    /**
+     * Private class to delay initialization of this list until needed.
+     * The circular dependency between Duration and ChronoUnit prevents
+     * the simple initialization in Duration.
+     */
+    private static class DurationUnits {
+        final static List<TemporalUnit> UNITS =
+                Collections.unmodifiableList(Arrays.<TemporalUnit>asList(SECONDS, NANOS));
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Checks if this duration is zero length.
      * <p>
      * A {@code Duration} represents a directed distance between two points on
@@ -435,19 +528,6 @@
     }
 
     /**
-     * Checks if this duration is positive, excluding zero.
-     * <p>
-     * A {@code Duration} represents a directed distance between two points on
-     * the time-line and can therefore be positive, zero or negative.
-     * This method checks whether the length is greater than zero.
-     *
-     * @return true if this duration has a total length greater than zero
-     */
-    public boolean isPositive() {
-        return seconds >= 0 && ((seconds | nanos) != 0);
-    }
-
-    /**
      * Checks if this duration is negative, excluding zero.
      * <p>
      * A {@code Duration} represents a directed distance between two points on
@@ -499,6 +579,39 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Returns a copy of this duration with the specified amount of seconds.
+     * <p>
+     * This returns a duration with the specified seconds, retaining the
+     * nano-of-second part of this duration.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param seconds  the seconds to represent, may be negative
+     * @return a {@code Duration} based on this period with the requested seconds, not null
+     */
+    public Duration withSeconds(long seconds) {
+        return create(seconds, nanos);
+    }
+
+    /**
+     * Returns a copy of this duration with the specified nano-of-second.
+     * <p>
+     * This returns a duration with the specified nano-of-second, retaining the
+     * seconds part of this duration.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
+     * @return a {@code Duration} based on this period with the requested nano-of-second, not null
+     * @throws DateTimeException if the nano-of-second is invalid
+     */
+    public Duration withNanos(int nanoOfSecond) {
+        NANO_OF_SECOND.checkValidIntValue(nanoOfSecond);
+        return create(seconds, nanoOfSecond);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Returns a copy of this duration with the specified duration added.
      * <p>
      * This instance is immutable and unaffected by this method call.
@@ -552,6 +665,48 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Returns a copy of this duration with the specified duration in standard 24 hour days added.
+     * <p>
+     * The number of days is multiplied by 86400 to obtain the number of seconds to add.
+     * This is based on the standard definition of a day as 24 hours.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param daysToAdd  the days to add, positive or negative
+     * @return a {@code Duration} based on this duration with the specified days added, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Duration plusDays(long daysToAdd) {
+        return plus(Math.multiplyExact(daysToAdd, SECONDS_PER_DAY), 0);
+    }
+
+    /**
+     * Returns a copy of this duration with the specified duration in hours added.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param hoursToAdd  the hours to add, positive or negative
+     * @return a {@code Duration} based on this duration with the specified hours added, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Duration plusHours(long hoursToAdd) {
+        return plus(Math.multiplyExact(hoursToAdd, SECONDS_PER_HOUR), 0);
+    }
+
+    /**
+     * Returns a copy of this duration with the specified duration in minutes added.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param minutesToAdd  the minutes to add, positive or negative
+     * @return a {@code Duration} based on this duration with the specified minutes added, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Duration plusMinutes(long minutesToAdd) {
+        return plus(Math.multiplyExact(minutesToAdd, SECONDS_PER_MINUTE), 0);
+    }
+
+    /**
      * Returns a copy of this duration with the specified duration in seconds added.
      * <p>
      * This instance is immutable and unaffected by this method call.
@@ -651,6 +806,52 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Returns a copy of this duration with the specified duration in standard 24 hour days subtracted.
+     * <p>
+     * The number of days is multiplied by 86400 to obtain the number of seconds to subtract.
+     * This is based on the standard definition of a day as 24 hours.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param daysToSubtract  the days to subtract, positive or negative
+     * @return a {@code Duration} based on this duration with the specified days subtracted, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Duration minusDays(long daysToSubtract) {
+        return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
+    }
+
+    /**
+     * Returns a copy of this duration with the specified duration in hours subtracted.
+     * <p>
+     * The number of hours is multiplied by 3600 to obtain the number of seconds to subtract.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param hoursToSubtract  the hours to subtract, positive or negative
+     * @return a {@code Duration} based on this duration with the specified hours subtracted, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Duration minusHours(long hoursToSubtract) {
+        return (hoursToSubtract == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hoursToSubtract));
+    }
+
+    /**
+     * Returns a copy of this duration with the specified duration in minutes subtracted.
+     * <p>
+     * The number of hours is multiplied by 60 to obtain the number of seconds to subtract.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param minutesToSubtract  the minutes to subtract, positive or negative
+     * @return a {@code Duration} based on this duration with the specified minutes subtracted, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Duration minusMinutes(long minutesToSubtract) {
+        return (minutesToSubtract == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutesToSubtract));
+    }
+
+    /**
      * Returns a copy of this duration with the specified duration in seconds subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
@@ -716,8 +917,7 @@
      *
      * @param divisor  the value to divide the duration by, positive or negative, not zero
      * @return a {@code Duration} based on this duration divided by the specified divisor, not null
-     * @throws ArithmeticException if the divisor is zero
-     * @throws ArithmeticException if numeric overflow occurs
+     * @throws ArithmeticException if the divisor is zero or if numeric overflow occurs
      */
     public Duration dividedBy(long divisor) {
         if (divisor == 0) {
@@ -794,15 +994,15 @@
      * with this duration added.
      * <p>
      * In most cases, it is clearer to reverse the calling pattern by using
-     * {@link Temporal#plus(TemporalAdder)}.
+     * {@link Temporal#plus(TemporalAmount)}.
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
      *   dateTime = thisDuration.addTo(dateTime);
      *   dateTime = dateTime.plus(thisDuration);
      * </pre>
      * <p>
-     * A {@code Duration} can only be added to a {@code Temporal} that
-     * represents an instant and can supply {@link ChronoField#INSTANT_SECONDS}.
+     * The calculation will add the seconds, then nanos.
+     * Only non-zero amounts will be added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -813,13 +1013,13 @@
      */
     @Override
     public Temporal addTo(Temporal temporal) {
-        long instantSecs = temporal.getLong(INSTANT_SECONDS);
-        long instantNanos = temporal.getLong(NANO_OF_SECOND);
-        instantSecs = Math.addExact(instantSecs, seconds);
-        instantNanos = Math.addExact(instantNanos, nanos);
-        instantSecs = Math.addExact(instantSecs, Math.floorDiv(instantNanos, NANOS_PER_SECOND));
-        instantNanos = Math.floorMod(instantNanos, NANOS_PER_SECOND);
-        return temporal.with(INSTANT_SECONDS, instantSecs).with(NANO_OF_SECOND, instantNanos);
+        if (seconds != 0) {
+            temporal = temporal.plus(seconds, SECONDS);
+        }
+        if (nanos != 0) {
+            temporal = temporal.plus(nanos, NANOS);
+        }
+        return temporal;
     }
 
     /**
@@ -829,15 +1029,15 @@
      * with this duration subtracted.
      * <p>
      * In most cases, it is clearer to reverse the calling pattern by using
-     * {@link Temporal#minus(TemporalSubtractor)}.
+     * {@link Temporal#minus(TemporalAmount)}.
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
      *   dateTime = thisDuration.subtractFrom(dateTime);
      *   dateTime = dateTime.minus(thisDuration);
      * </pre>
      * <p>
-     * A {@code Duration} can only be subtracted from a {@code Temporal} that
-     * represents an instant and can supply {@link ChronoField#INSTANT_SECONDS}.
+     * The calculation will subtract the seconds, then nanos.
+     * Only non-zero amounts will be added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -848,17 +1048,60 @@
      */
     @Override
     public Temporal subtractFrom(Temporal temporal) {
-        long instantSecs = temporal.getLong(INSTANT_SECONDS);
-        long instantNanos = temporal.getLong(NANO_OF_SECOND);
-        instantSecs = Math.subtractExact(instantSecs, seconds);
-        instantNanos = Math.subtractExact(instantNanos, nanos);
-        instantSecs = Math.addExact(instantSecs, Math.floorDiv(instantNanos, NANOS_PER_SECOND));
-        instantNanos = Math.floorMod(instantNanos, NANOS_PER_SECOND);
-        return temporal.with(INSTANT_SECONDS, instantSecs).with(NANO_OF_SECOND, instantNanos);
+        if (seconds != 0) {
+            temporal = temporal.minus(seconds, SECONDS);
+        }
+        if (nanos != 0) {
+            temporal = temporal.minus(nanos, NANOS);
+        }
+        return temporal;
     }
 
     //-----------------------------------------------------------------------
     /**
+     * Gets the number of minutes in this duration.
+     * <p>
+     * This returns the total number of minutes in the duration by dividing the
+     * number of seconds by 86400.
+     * This is based on the standard definition of a day as 24 hours.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of minutes in the duration, may be negative
+     */
+    public long toDays() {
+        return seconds / SECONDS_PER_DAY;
+    }
+
+    /**
+     * Gets the number of minutes in this duration.
+     * <p>
+     * This returns the total number of minutes in the duration by dividing the
+     * number of seconds by 3600.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of minutes in the duration, may be negative
+     */
+    public long toHours() {
+        return seconds / SECONDS_PER_HOUR;
+    }
+
+    /**
+     * Gets the number of minutes in this duration.
+     * <p>
+     * This returns the total number of minutes in the duration by dividing the
+     * number of seconds by 60.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of minutes in the duration, may be negative
+     */
+    public long toMinutes() {
+        return seconds / SECONDS_PER_MINUTE;
+    }
+
+    /**
      * Converts this duration to the total length in milliseconds.
      * <p>
      * If this duration is too large to fit in a {@code long} milliseconds, then an
@@ -887,7 +1130,7 @@
      * @throws ArithmeticException if numeric overflow occurs
      */
     public long toNanos() {
-        long millis = Math.multiplyExact(seconds, 1000_000_000);
+        long millis = Math.multiplyExact(seconds, NANOS_PER_SECOND);
         millis = Math.addExact(millis, nanos);
         return millis;
     }
@@ -911,30 +1154,6 @@
         return nanos - otherDuration.nanos;
     }
 
-    /**
-     * Checks if this duration is greater than the specified {@code Duration}.
-     * <p>
-     * The comparison is based on the total length of the durations.
-     *
-     * @param otherDuration  the other duration to compare to, not null
-     * @return true if this duration is greater than the specified duration
-     */
-    public boolean isGreaterThan(Duration otherDuration) {
-        return compareTo(otherDuration) > 0;
-    }
-
-    /**
-     * Checks if this duration is less than the specified {@code Duration}.
-     * <p>
-     * The comparison is based on the total length of the durations.
-     *
-     * @param otherDuration  the other duration to compare to, not null
-     * @return true if this duration is less than the specified duration
-     */
-    public boolean isLessThan(Duration otherDuration) {
-        return compareTo(otherDuration) < 0;
-    }
-
     //-----------------------------------------------------------------------
     /**
      * Checks if this duration is equal to the specified {@code Duration}.
@@ -970,29 +1189,57 @@
     //-----------------------------------------------------------------------
     /**
      * A string representation of this duration using ISO-8601 seconds
-     * based representation, such as {@code PT12.345S}.
+     * based representation, such as {@code PT8H6M12.345S}.
      * <p>
-     * The format of the returned string will be {@code PTnS} where n is
-     * the seconds and fractional seconds of the duration.
+     * The format of the returned string will be {@code PTnHnMnS}, where n is
+     * the relevant hours, minutes or seconds part of the duration.
+     * Any fractional seconds are placed after a decimal point i the seconds section.
+     * If a section has a zero value, it is omitted.
+     * The hours, minutes and seconds will all have the same sign.
+     * <p>
+     * Examples:
+     * <pre>
+     *    "20.345 seconds"                 -> "PT20.345S
+     *    "15 minutes" (15 * 60 seconds)   -> "PT15M"
+     *    "10 hours" (10 * 3600 seconds)   -> "PT10H"
+     *    "2 days" (2 * 86400 seconds)     -> "PT48H"
+     * </pre>
+     * Note that multiples of 24 hours are not output as days to avoid confusion
+     * with {@code Period}.
      *
      * @return an ISO-8601 representation of this duration, not null
      */
     @Override
     public String toString() {
+        if (this == ZERO) {
+            return "PT0S";
+        }
+        long hours = seconds / SECONDS_PER_HOUR;
+        int minutes = (int) ((seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
+        int secs = (int) (seconds % SECONDS_PER_MINUTE);
         StringBuilder buf = new StringBuilder(24);
         buf.append("PT");
-        if (seconds < 0 && nanos > 0) {
-            if (seconds == -1) {
+        if (hours != 0) {
+            buf.append(hours).append('H');
+        }
+        if (minutes != 0) {
+            buf.append(minutes).append('M');
+        }
+        if (secs == 0 && nanos == 0 && buf.length() > 2) {
+            return buf.toString();
+        }
+        if (secs < 0 && nanos > 0) {
+            if (secs == -1) {
                 buf.append("-0");
             } else {
-                buf.append(seconds + 1);
+                buf.append(secs + 1);
             }
         } else {
-            buf.append(seconds);
+            buf.append(secs);
         }
         if (nanos > 0) {
             int pos = buf.length();
-            if (seconds < 0) {
+            if (secs < 0) {
                 buf.append(2 * NANOS_PER_SECOND - nanos);
             } else {
                 buf.append(nanos + NANOS_PER_SECOND);
diff --git a/jdk/src/share/classes/java/time/Instant.java b/jdk/src/share/classes/java/time/Instant.java
index f253eb5..81b74eb 100644
--- a/jdk/src/share/classes/java/time/Instant.java
+++ b/jdk/src/share/classes/java/time/Instant.java
@@ -61,6 +61,7 @@
  */
 package java.time;
 
+import static java.time.LocalTime.NANOS_PER_SECOND;
 import static java.time.LocalTime.SECONDS_PER_DAY;
 import static java.time.LocalTime.SECONDS_PER_HOUR;
 import static java.time.LocalTime.SECONDS_PER_MINUTE;
@@ -76,18 +77,17 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.format.DateTimeFormatters;
+import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
 import java.time.temporal.TemporalUnit;
 import java.time.temporal.ValueRange;
 import java.util.Objects;
@@ -225,10 +225,6 @@
      * Serialization version.
      */
     private static final long serialVersionUID = -665713676816604388L;
-    /**
-     * Constant for nanos per second.
-     */
-    private static final int NANOS_PER_SECOND = 1000_000_000;
 
     /**
      * The number of seconds from the epoch of 1970-01-01T00:00:00Z.
@@ -333,8 +329,9 @@
     /**
      * Obtains an instance of {@code Instant} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code Instant}.
+     * This obtains an instant based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code Instant}.
      * <p>
      * The conversion extracts the {@link ChronoField#INSTANT_SECONDS INSTANT_SECONDS}
      * and {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} fields.
@@ -358,14 +355,14 @@
      * {@code 2007-12-03T10:15:30:00}.
      * <p>
      * The string must represent a valid instant in UTC and is parsed using
-     * {@link DateTimeFormatters#isoInstant()}.
+     * {@link DateTimeFormatter#ISO_INSTANT}.
      *
      * @param text  the text to parse, not null
      * @return the parsed instant, not null
      * @throws DateTimeParseException if the text cannot be parsed
      */
     public static Instant parse(final CharSequence text) {
-        return DateTimeFormatters.isoInstant().parse(text, Instant::from);
+        return DateTimeFormatter.ISO_INSTANT.parse(text, Instant::from);
     }
 
     //-----------------------------------------------------------------------
@@ -418,7 +415,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -430,7 +427,7 @@
         if (field instanceof ChronoField) {
             return field == INSTANT_SECONDS || field == NANO_OF_SECOND || field == MICRO_OF_SECOND || field == MILLI_OF_SECOND;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -447,7 +444,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -475,7 +472,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -495,7 +492,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return range(field).checkValidIntValue(field.doGet(this), field);
+        return range(field).checkValidIntValue(field.getFrom(this), field);
     }
 
     /**
@@ -511,7 +508,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -531,7 +528,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -565,7 +562,7 @@
     /**
      * Returns an adjusted copy of this instant.
      * <p>
-     * This returns a new {@code Instant}, based on this one, with the date adjusted.
+     * This returns an {@code Instant}, based on this one, with the instant adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -588,7 +585,7 @@
     /**
      * Returns a copy of this instant with the specified field set to a new value.
      * <p>
-     * This returns a new {@code Instant}, based on this one, with the value
+     * This returns an {@code Instant}, based on this one, with the value
      * for the specified field changed.
      * If it is not possible to set the value, because the field is not supported or for
      * some other reason, an exception is thrown.
@@ -616,7 +613,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -647,24 +644,130 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this {@code Instant} truncated to the specified unit.
+     * <p>
+     * Truncating the instant returns a copy of the original with fields
+     * smaller than the specified unit set to zero.
+     * The fields are calculated on the basis of using a UTC offset as seen
+     * in {@code toString}.
+     * For example, truncating with the {@link ChronoUnit#MINUTES MINUTES} unit will
+     * round down to the nearest minute, setting the seconds and nanoseconds to zero.
+     * <p>
+     * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+     * that divides into the length of a standard day without remainder.
+     * This includes all supplied time units on {@link ChronoUnit} and
+     * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param unit  the unit to truncate to, not null
+     * @return an {@code Instant} based on this instant with the time truncated, not null
+     * @throws DateTimeException if the unit is invalid for truncation
+     */
+    public Instant truncatedTo(TemporalUnit unit) {
+        if (unit == ChronoUnit.NANOS) {
+            return this;
+        }
+        Duration unitDur = unit.getDuration();
+        if (unitDur.getSeconds() > LocalTime.SECONDS_PER_DAY) {
+            throw new DateTimeException("Unit is too large to be used for truncation");
+        }
+        long dur = unitDur.toNanos();
+        if ((LocalTime.NANOS_PER_DAY % dur) != 0) {
+            throw new DateTimeException("Unit must divide into a standard day without remainder");
+        }
+        long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
+        long result = (nod / dur) * dur;
+        return plusNanos(result - nod);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a copy of this instant with the specified amount added.
+     * <p>
+     * This returns an {@code Instant}, based on this one, with the specified amount added.
+     * The amount is typically {@link Duration} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToAdd  the amount to add, not null
+     * @return an {@code Instant} based on this instant with the addition made, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public Instant plus(TemporalAdder adder) {
-        return (Instant) adder.addTo(this);
+    public Instant plus(TemporalAmount amountToAdd) {
+        return (Instant) amountToAdd.addTo(this);
     }
 
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this instant with the specified amount added.
+     * <p>
+     * This returns an {@code Instant}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented here.
+     * The supported fields behave as follows:
+     * <ul>
+     * <li>{@code NANOS} -
+     *  Returns a {@code Instant} with the specified number of nanoseconds added.
+     *  This is equivalent to {@link #plusNanos(long)}.
+     * <li>{@code MICROS} -
+     *  Returns a {@code Instant} with the specified number of microseconds added.
+     *  This is equivalent to {@link #plusNanos(long)} with the amount
+     *  multiplied by 1,000.
+     * <li>{@code MILLIS} -
+     *  Returns a {@code Instant} with the specified number of milliseconds added.
+     *  This is equivalent to {@link #plusNanos(long)} with the amount
+     *  multiplied by 1,000,000.
+     * <li>{@code SECONDS} -
+     *  Returns a {@code Instant} with the specified number of seconds added.
+     *  This is equivalent to {@link #plusSeconds(long)}.
+     * <li>{@code MINUTES} -
+     *  Returns a {@code Instant} with the specified number of minutes added.
+     *  This is equivalent to {@link #plusSeconds(long)} with the amount
+     *  multiplied by 60.
+     * <li>{@code HOURS} -
+     *  Returns a {@code Instant} with the specified number of hours added.
+     *  This is equivalent to {@link #plusSeconds(long)} with the amount
+     *  multiplied by 3,600.
+     * <li>{@code HALF_DAYS} -
+     *  Returns a {@code Instant} with the specified number of half-days added.
+     *  This is equivalent to {@link #plusSeconds(long)} with the amount
+     *  multiplied by 43,200 (12 hours).
+     * <li>{@code DAYS} -
+     *  Returns a {@code Instant} with the specified number of days added.
+     *  This is equivalent to {@link #plusSeconds(long)} with the amount
+     *  multiplied by 86,400 (24 hours).
+     * </ul>
+     * <p>
+     * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
+     * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToAdd  the amount of the unit to add to the result, may be negative
+     * @param unit  the unit of the amount to add, not null
+     * @return an {@code Instant} based on this instant with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public Instant plus(long amountToAdd, TemporalUnit unit) {
@@ -681,7 +784,7 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
@@ -751,19 +854,47 @@
 
     //-----------------------------------------------------------------------
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this instant with the specified amount subtracted.
+     * <p>
+     * This returns an {@code Instant}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Duration} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToSubtract  the amount to subtract, not null
+     * @return an {@code Instant} based on this instant with the subtraction made, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public Instant minus(TemporalSubtractor subtractor) {
-        return (Instant) subtractor.subtractFrom(this);
+    public Instant minus(TemporalAmount amountToSubtract) {
+        return (Instant) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this instant with the specified amount subtracted.
+     * <p>
+     * This returns a {@code Instant}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
+     * @param unit  the unit of the amount to subtract, not null
+     * @return an {@code Instant} based on this instant with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public Instant minus(long amountToSubtract, TemporalUnit unit) {
@@ -848,7 +979,7 @@
             return (R) NANOS;
         }
         // inline TemporalAccessor.super.query(query) as an optimization
-        if (query == Queries.chrono() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
+        if (query == Queries.chronology() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
             return null;
         }
         return query.queryFrom(this);
@@ -945,7 +1076,7 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.between(this, endInstant).getAmount();
+        return unit.between(this, endInstant);
     }
 
     private long nanosUntil(Instant end) {
@@ -959,6 +1090,43 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Combines this instant with an offset to create an {@code OffsetDateTime}.
+     * <p>
+     * This returns an {@code OffsetDateTime} formed from this instant at the
+     * specified offset from UTC/Greenwich. An exception will be thrown if the
+     * instant is too large to fit into an offset date-time.
+     * <p>
+     * This method is equivalent to
+     * {@link OffsetDateTime#ofInstant(Instant, ZoneId) OffsetDateTime.ofInstant(this, offset)}.
+     *
+     * @param offset  the offset to combine with, not null
+     * @return the offset date-time formed from this instant and the specified offset, not null
+     * @throws DateTimeException if the result exceeds the supported range
+     */
+    public OffsetDateTime atOffset(ZoneOffset offset) {
+        return OffsetDateTime.ofInstant(this, offset);
+    }
+
+    /**
+     * Combines this instant with a time-zone to create a {@code ZonedDateTime}.
+     * <p>
+     * This returns an {@code ZonedDateTime} formed from this instant at the
+     * specified time-zone. An exception will be thrown if the instant is too
+     * large to fit into a zoned date-time.
+     * <p>
+     * This method is equivalent to
+     * {@link ZonedDateTime#ofInstant(Instant, ZoneId) ZonedDateTime.ofInstant(this, zone)}.
+     *
+     * @param zone  the zone to combine with, not null
+     * @return the zoned date-time formed from this instant and the specified zone, not null
+     * @throws DateTimeException if the result exceeds the supported range
+     */
+    public ZonedDateTime atZone(ZoneId zone) {
+        return ZonedDateTime.ofInstant(this, zone);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Converts this instant to the number of milliseconds from the epoch
      * of 1970-01-01T00:00:00Z.
      * <p>
@@ -1059,13 +1227,13 @@
     /**
      * A string representation of this instant using ISO-8601 representation.
      * <p>
-     * The format used is the same as {@link DateTimeFormatters#isoInstant()}.
+     * The format used is the same as {@link DateTimeFormatter#ISO_INSTANT}.
      *
      * @return an ISO-8601 representation of this instant, not null
      */
     @Override
     public String toString() {
-        return DateTimeFormatters.isoInstant().print(this);
+        return DateTimeFormatter.ISO_INSTANT.format(this);
     }
 
     // -----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java
index 8d40f72..6528789 100644
--- a/jdk/src/share/classes/java/time/LocalDate.java
+++ b/jdk/src/share/classes/java/time/LocalDate.java
@@ -80,26 +80,22 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.format.DateTimeBuilder;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Era;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.Era;
-import java.time.temporal.ISOChrono;
-import java.time.temporal.OffsetDate;
+import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
 import java.time.temporal.TemporalUnit;
 import java.time.temporal.ValueRange;
-import java.time.temporal.Year;
 import java.time.zone.ZoneOffsetTransition;
 import java.time.zone.ZoneRules;
 import java.util.Objects;
@@ -131,7 +127,7 @@
  * @since 1.8
  */
 public final class LocalDate
-        implements Temporal, TemporalAdjuster, ChronoLocalDate<ISOChrono>, Serializable {
+        implements Temporal, TemporalAdjuster, ChronoLocalDate<LocalDate>, Serializable {
 
     /**
      * The minimum supported {@code LocalDate}, '-999999999-01-01'.
@@ -216,7 +212,7 @@
      */
     public static LocalDate now(Clock clock) {
         Objects.requireNonNull(clock, "clock");
-        // inline OffsetDate factory to avoid creating object and InstantProvider checks
+        // inline to avoid creating object and Instant checks
         final Instant now = clock.instant();  // called once
         ZoneOffset offset = clock.getZone().getRules().getOffset(now);
         long epochSec = now.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
@@ -228,14 +224,15 @@
     /**
      * Obtains an instance of {@code LocalDate} from a year, month and day.
      * <p>
+     * This returns a {@code LocalDate} with the specified year, month and day-of-month.
      * The day must be valid for the year and month, otherwise an exception will be thrown.
      *
      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
      * @param month  the month-of-year to represent, not null
      * @param dayOfMonth  the day-of-month to represent, from 1 to 31
      * @return the local date, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
      */
     public static LocalDate of(int year, Month month, int dayOfMonth) {
         YEAR.checkValidValue(year);
@@ -247,14 +244,15 @@
     /**
      * Obtains an instance of {@code LocalDate} from a year, month and day.
      * <p>
+     * This returns a {@code LocalDate} with the specified year, month and day-of-month.
      * The day must be valid for the year and month, otherwise an exception will be thrown.
      *
      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
      * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
      * @param dayOfMonth  the day-of-month to represent, from 1 to 31
      * @return the local date, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
      */
     public static LocalDate of(int year, int month, int dayOfMonth) {
         YEAR.checkValidValue(year);
@@ -267,18 +265,19 @@
     /**
      * Obtains an instance of {@code LocalDate} from a year and day-of-year.
      * <p>
+     * This returns a {@code LocalDate} with the specified year and day-of-year.
      * The day-of-year must be valid for the year, otherwise an exception will be thrown.
      *
      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
      * @param dayOfYear  the day-of-year to represent, from 1 to 366
      * @return the local date, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-year is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-year is invalid for the month-year
      */
     public static LocalDate ofYearDay(int year, int dayOfYear) {
         YEAR.checkValidValue(year);
         DAY_OF_YEAR.checkValidValue(dayOfYear);
-        boolean leap = ISOChrono.INSTANCE.isLeapYear(year);
+        boolean leap = IsoChronology.INSTANCE.isLeapYear(year);
         if (dayOfYear == 366 && leap == false) {
             throw new DateTimeException("Invalid date 'DayOfYear 366' as '" + year + "' is not a leap year");
         }
@@ -295,8 +294,9 @@
     /**
      * Obtains an instance of {@code LocalDate} from the epoch day count.
      * <p>
-     * The Epoch Day count is a simple incrementing count of days
-     * where day 0 is 1970-01-01. Negative numbers represent earlier days.
+     * This returns a {@code LocalDate} with the specified epoch-day.
+     * The {@link ChronoField#EPOCH_DAY EPOCH_DAY} is a simple incrementing count
+     * of days where day 0 is 1970-01-01. Negative numbers represent earlier days.
      *
      * @param epochDay  the Epoch Day to convert, based on the epoch 1970-01-01
      * @return the local date, not null
@@ -338,10 +338,12 @@
     /**
      * Obtains an instance of {@code LocalDate} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code LocalDate}.
+     * This obtains a local date based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code LocalDate}.
      * <p>
-     * The conversion extracts the {@link ChronoField#EPOCH_DAY EPOCH_DAY} field.
+     * The conversion uses the {@link Queries#localDate()} query, which relies
+     * on extracting the {@link ChronoField#EPOCH_DAY EPOCH_DAY} field.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
      * allowing it to be used as a query via method reference, {@code LocalDate::from}.
@@ -351,26 +353,11 @@
      * @throws DateTimeException if unable to convert to a {@code LocalDate}
      */
     public static LocalDate from(TemporalAccessor temporal) {
-        if (temporal instanceof LocalDate) {
-            return (LocalDate) temporal;
-        } else if (temporal instanceof LocalDateTime) {
-            return ((LocalDateTime) temporal).getDate();
-        } else if (temporal instanceof ZonedDateTime) {
-            return ((ZonedDateTime) temporal).getDate();
+        LocalDate date = temporal.query(Queries.localDate());
+        if (date == null) {
+            throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " + temporal.getClass());
         }
-        // handle builder as a special case
-        if (temporal instanceof DateTimeBuilder) {
-            DateTimeBuilder builder = (DateTimeBuilder) temporal;
-            LocalDate date = builder.extract(LocalDate.class);
-            if (date != null) {
-                return date;
-            }
-        }
-        try {
-            return ofEpochDay(temporal.getLong(EPOCH_DAY));
-        } catch (DateTimeException ex) {
-            throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " + temporal.getClass(), ex);
-        }
+        return date;
     }
 
     //-----------------------------------------------------------------------
@@ -378,14 +365,14 @@
      * Obtains an instance of {@code LocalDate} from a text string such as {@code 2007-12-03}.
      * <p>
      * The string must represent a valid date and is parsed using
-     * {@link java.time.format.DateTimeFormatters#isoLocalDate()}.
+     * {@link java.time.format.DateTimeFormatter#ISO_LOCAL_DATE}.
      *
      * @param text  the text to parse such as "2007-12-03", not null
      * @return the parsed local date, not null
      * @throws DateTimeParseException if the text cannot be parsed
      */
     public static LocalDate parse(CharSequence text) {
-        return parse(text, DateTimeFormatters.isoLocalDate());
+        return parse(text, DateTimeFormatter.ISO_LOCAL_DATE);
     }
 
     /**
@@ -414,7 +401,7 @@
      * @throws DateTimeException if the day-of-month is invalid for the month-year
      */
     private static LocalDate create(int year, Month month, int dayOfMonth) {
-        if (dayOfMonth > 28 && dayOfMonth > month.length(ISOChrono.INSTANCE.isLeapYear(year))) {
+        if (dayOfMonth > 28 && dayOfMonth > month.length(IsoChronology.INSTANCE.isLeapYear(year))) {
             if (dayOfMonth == 29) {
                 throw new DateTimeException("Invalid date 'February 29' as '" + year + "' is not a leap year");
             } else {
@@ -435,7 +422,7 @@
     private static LocalDate resolvePreviousValid(int year, int month, int day) {
         switch (month) {
             case 2:
-                day = Math.min(day, ISOChrono.INSTANCE.isLeapYear(year) ? 29 : 28);
+                day = Math.min(day, IsoChronology.INSTANCE.isLeapYear(year) ? 29 : 28);
                 break;
             case 4:
             case 6:
@@ -469,8 +456,6 @@
      * {@link #get(TemporalField) get} methods will throw an exception.
      * <p>
      * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return valid
-     * values based on this date-time.
      * The supported fields are:
      * <ul>
      * <li>{@code DAY_OF_WEEK}
@@ -490,7 +475,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -516,7 +501,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -540,7 +525,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     /**
@@ -558,7 +543,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -588,7 +573,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -608,7 +593,7 @@
             }
             return get0(field);
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     private int get0(TemporalField field) {
@@ -638,7 +623,7 @@
     /**
      * Gets the chronology of this date, which is the ISO calendar system.
      * <p>
-     * The {@code Chrono} represents the calendar system in use.
+     * The {@code Chronology} represents the calendar system in use.
      * The ISO-8601 calendar system is the modern civil calendar system used today
      * in most of the world. It is equivalent to the proleptic Gregorian calendar
      * system, in which todays's rules for leap years are applied for all time.
@@ -646,14 +631,14 @@
      * @return the ISO chronology, not null
      */
     @Override
-    public ISOChrono getChrono() {
-        return ISOChrono.INSTANCE;
+    public IsoChronology getChronology() {
+        return IsoChronology.INSTANCE;
     }
 
     /**
      * Gets the era applicable at this date.
      * <p>
-     * The official ISO-8601 standard does not define eras, however {@code ISOChrono} does.
+     * The official ISO-8601 standard does not define eras, however {@code IsoChronology} does.
      * It defines two eras, 'CE' from year one onwards and 'BCE' from year zero backwards.
      * Since dates before the Julian-Gregorian cutover are not in line with history,
      * the cutover between 'BCE' and 'CE' is also not aligned with the commonly used
@@ -664,12 +649,12 @@
      * the Japanese calendar system.
      * <p>
      * The returned era will be a singleton capable of being compared with the constants
-     * in {@link ISOChrono} using the {@code ==} operator.
+     * in {@link IsoChronology} using the {@code ==} operator.
      *
-     * @return the {@code ISOChrono} era constant applicable at this date, not null
+     * @return the {@code IsoChronology} era constant applicable at this date, not null
      */
     @Override // override for Javadoc
-    public Era<ISOChrono> getEra() {
+    public Era getEra() {
         return ChronoLocalDate.super.getEra();
     }
 
@@ -679,7 +664,7 @@
      * This method returns the primitive {@code int} value for the year.
      * <p>
      * The year returned by this method is proleptic as per {@code get(YEAR)}.
-     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
+     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA)}.
      *
      * @return the year, from MIN_YEAR to MAX_YEAR
      */
@@ -777,7 +762,7 @@
      */
     @Override // override for Javadoc and performance
     public boolean isLeapYear() {
-        return ISOChrono.INSTANCE.isLeapYear(year);
+        return IsoChronology.INSTANCE.isLeapYear(year);
     }
 
     /**
@@ -819,7 +804,7 @@
     /**
      * Returns an adjusted copy of this date.
      * <p>
-     * This returns a new {@code LocalDate}, based on this one, with the date adjusted.
+     * This returns a {@code LocalDate}, based on this one, with the date adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -828,7 +813,7 @@
      * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}.
      * These include finding the "last day of the month" and "next Wednesday".
      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
-     * such as {@link Month} and {@link java.time.temporal.MonthDay MonthDay}.
+     * such as {@link Month} and {@link java.time.MonthDay MonthDay}.
      * The adjuster is responsible for handling special cases, such as the varying
      * lengths of month and leap years.
      * <p>
@@ -863,7 +848,7 @@
     /**
      * Returns a copy of this date with the specified field set to a new value.
      * <p>
-     * This returns a new {@code LocalDate}, based on this one, with the value
+     * This returns a {@code LocalDate}, based on this one, with the value
      * for the specified field changed.
      * This can be used to change any supported field, such as the year, month or day-of-month.
      * If it is not possible to set the value, because the field is not supported or for
@@ -951,7 +936,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -985,7 +970,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
@@ -1033,8 +1018,8 @@
      *
      * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
      * @return a {@code LocalDate} based on this date with the requested day, not null
-     * @throws DateTimeException if the day-of-month value is invalid
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the day-of-month value is invalid,
+     *  or if the day-of-month is invalid for the month-year
      */
     public LocalDate withDayOfMonth(int dayOfMonth) {
         if (this.day == dayOfMonth) {
@@ -1051,8 +1036,8 @@
      *
      * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
      * @return a {@code LocalDate} based on this date with the requested day, not null
-     * @throws DateTimeException if the day-of-year value is invalid
-     * @throws DateTimeException if the day-of-year is invalid for the year
+     * @throws DateTimeException if the day-of-year value is invalid,
+     *  or if the day-of-year is invalid for the year
      */
     public LocalDate withDayOfYear(int dayOfYear) {
         if (this.getDayOfYear() == dayOfYear) {
@@ -1063,40 +1048,109 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date with the specified period added.
+     * Returns a copy of this date with the specified amount added.
      * <p>
-     * This method returns a new date based on this date with the specified period added.
-     * The adder is typically {@link Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
+     * This returns a {@code LocalDate}, based on this one, with the specified amount added.
+     * The amount is typically {@link Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return a {@code LocalDate} based on this date with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public LocalDate plus(TemporalAdder adder) {
-        return (LocalDate) adder.addTo(this);
+    public LocalDate plus(TemporalAmount amountToAdd) {
+        return (LocalDate) amountToAdd.addTo(this);
     }
 
     /**
-     * Returns a copy of this date with the specified period added.
+     * Returns a copy of this date with the specified amount added.
      * <p>
-     * This method returns a new date based on this date with the specified period added.
-     * This can be used to add any period that is defined by a unit, for example to add years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns a {@code LocalDate}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * In some cases, adding the amount can cause the resulting date to become invalid.
+     * For example, adding one month to 31st January would result in 31st February.
+     * In cases like this, the unit is responsible for resolving the date.
+     * Typically it will choose the previous valid date, which would be the last valid
+     * day of February in this example.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented here.
+     * The supported fields behave as follows:
+     * <ul>
+     * <li>{@code DAYS} -
+     *  Returns a {@code LocalDate} with the specified number of days added.
+     *  This is equivalent to {@link #plusDays(long)}.
+     * <li>{@code WEEKS} -
+     *  Returns a {@code LocalDate} with the specified number of weeks added.
+     *  This is equivalent to {@link #plusWeeks(long)} and uses a 7 day week.
+     * <li>{@code MONTHS} -
+     *  Returns a {@code LocalDate} with the specified number of months added.
+     *  This is equivalent to {@link #plusMonths(long)}.
+     *  The day-of-month will be unchanged unless it would be invalid for the new
+     *  month and year. In that case, the day-of-month is adjusted to the maximum
+     *  valid value for the new month and year.
+     * <li>{@code YEARS} -
+     *  Returns a {@code LocalDate} with the specified number of years added.
+     *  This is equivalent to {@link #plusYears(long)}.
+     *  The day-of-month will be unchanged unless it would be invalid for the new
+     *  month and year. In that case, the day-of-month is adjusted to the maximum
+     *  valid value for the new month and year.
+     * <li>{@code DECADES} -
+     *  Returns a {@code LocalDate} with the specified number of decades added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 10.
+     *  The day-of-month will be unchanged unless it would be invalid for the new
+     *  month and year. In that case, the day-of-month is adjusted to the maximum
+     *  valid value for the new month and year.
+     * <li>{@code CENTURIES} -
+     *  Returns a {@code LocalDate} with the specified number of centuries added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 100.
+     *  The day-of-month will be unchanged unless it would be invalid for the new
+     *  month and year. In that case, the day-of-month is adjusted to the maximum
+     *  valid value for the new month and year.
+     * <li>{@code MILLENNIA} -
+     *  Returns a {@code LocalDate} with the specified number of millennia added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 1,000.
+     *  The day-of-month will be unchanged unless it would be invalid for the new
+     *  month and year. In that case, the day-of-month is adjusted to the maximum
+     *  valid value for the new month and year.
+     * <li>{@code ERAS} -
+     *  Returns a {@code LocalDate} with the specified number of eras added.
+     *  Only two eras are supported so the amount must be one, zero or minus one.
+     *  If the amount is non-zero then the year is changed such that the year-of-era
+     *  is unchanged.
+     *  The day-of-month will be unchanged unless it would be invalid for the new
+     *  month and year. In that case, the day-of-month is adjusted to the maximum
+     *  valid value for the new month and year.
+     * </ul>
+     * <p>
+     * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
+     * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToAdd  the amount of the unit to add to the result, may be negative
-     * @param unit  the unit of the period to add, not null
-     * @return a {@code LocalDate} based on this date with the specified period added, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to add, not null
+     * @return a {@code LocalDate} based on this date with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public LocalDate plus(long amountToAdd, TemporalUnit unit) {
@@ -1114,7 +1168,7 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
@@ -1221,40 +1275,47 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date with the specified period subtracted.
+     * Returns a copy of this date with the specified amount subtracted.
      * <p>
-     * This method returns a new date based on this date with the specified period subtracted.
-     * The subtractor is typically {@link Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
+     * This returns a {@code LocalDate}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return a {@code LocalDate} based on this date with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public LocalDate minus(TemporalSubtractor subtractor) {
-        return (LocalDate) subtractor.subtractFrom(this);
+    public LocalDate minus(TemporalAmount amountToSubtract) {
+        return (LocalDate) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * Returns a copy of this date with the specified period subtracted.
+     * Returns a copy of this date with the specified amount subtracted.
      * <p>
-     * This method returns a new date based on this date with the specified period subtracted.
-     * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns a {@code LocalDate}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
-     * @param unit  the unit of the period to subtract, not null
-     * @return a {@code LocalDate} based on this date with the specified period subtracted, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to subtract, not null
+     * @return a {@code LocalDate} based on this date with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public LocalDate minus(long amountToSubtract, TemporalUnit unit) {
@@ -1367,8 +1428,12 @@
      * @throws DateTimeException if unable to query (defined by the query)
      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
      */
-    @Override  // override for Javadoc
+    @SuppressWarnings("unchecked")
+    @Override
     public <R> R query(TemporalQuery<R> query) {
+        if (query == Queries.localDate()) {
+            return (R) this;
+        }
         return ChronoLocalDate.super.query(query);
     }
 
@@ -1417,14 +1482,15 @@
      * For example, the period in months between 2012-06-15 and 2012-08-14
      * will only be one month as it is one day short of two months.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, MONTHS);   // this method
-     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MONTHS);
+     *   amount = MONTHS.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code DAYS}, {@code WEEKS}, {@code MONTHS}, {@code YEARS},
@@ -1464,7 +1530,7 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.between(this, endDate).getAmount();
+        return unit.between(this, endDate);
     }
 
     long daysUntil(LocalDate end) {
@@ -1477,14 +1543,64 @@
         return (packed2 - packed1) / 32;
     }
 
+    /**
+     * Calculates the period between this date and another date as a {@code Period}.
+     * <p>
+     * This calculates the period between two dates in terms of years, months and days.
+     * The start and end points are {@code this} and the specified date.
+     * The result will be negative if the end is before the start.
+     * <p>
+     * The calculation is performed using the ISO calendar system.
+     * If necessary, the input date will be converted to ISO.
+     * <p>
+     * The start date is included, but the end date is not.
+     * The period is calculated by removing complete months, then calculating
+     * the remaining number of days, adjusting to ensure that both have the same sign.
+     * The number of months is then normalized into years and months based on a 12 month year.
+     * A month is considered to be complete if the end day-of-month is greater
+     * than or equal to the start day-of-month.
+     * For example, from {@code 2010-01-15} to {@code 2011-03-18} is "1 year, 2 months and 3 days".
+     * <p>
+     * The result of this method can be a negative period if the end is before the start.
+     * The negative sign will be the same in each of year, month and day.
+     * <p>
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link Period#between(LocalDate, LocalDate)}:
+     * <pre>
+     *   // these two lines are equivalent
+     *   period = start.periodUntil(end);
+     *   period = Period.between(start, end);
+     * </pre>
+     * The choice should be made based on which makes the code more readable.
+     *
+     * @param endDate  the end date, exclusive, which may be in any chronology, not null
+     * @return the period between this date and the end date, not null
+     */
+    @Override
+    public Period periodUntil(ChronoLocalDate<?> endDate) {
+        LocalDate end = LocalDate.from(endDate);
+        long totalMonths = end.getEpochMonth() - this.getEpochMonth();  // safe
+        int days = end.day - this.day;
+        if (totalMonths > 0 && days < 0) {
+            totalMonths--;
+            LocalDate calcDate = this.plusMonths(totalMonths);
+            days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
+        } else if (totalMonths < 0 && days > 0) {
+            totalMonths++;
+            days -= end.lengthOfMonth();
+        }
+        long years = totalMonths / 12;  // safe
+        int months = (int) (totalMonths % 12);  // safe
+        return Period.of(Math.toIntExact(years), months, days);
+    }
+
     //-----------------------------------------------------------------------
     /**
-     * Returns a local date-time formed from this date at the specified time.
+     * Combines this date with a time to create a {@code LocalDateTime}.
      * <p>
-     * This combines this date with the specified time to form a {@code LocalDateTime}.
+     * This returns a {@code LocalDateTime} formed from this date at the specified time.
      * All possible combinations of date and time are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param time  the time to combine with, not null
      * @return the local date-time formed from this date and the specified time, not null
@@ -1495,13 +1611,13 @@
     }
 
     /**
-     * Returns a local date-time formed from this date at the specified time.
+     * Combines this date with a time to create a {@code LocalDateTime}.
      * <p>
-     * This combines this date with the specified time to form a {@code LocalDateTime}.
+     * This returns a {@code LocalDateTime} formed from this date at the
+     * specified hour and minute.
+     * The seconds and nanosecond fields will be set to zero.
      * The individual time fields must be within their valid range.
      * All possible combinations of date and time are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param hour  the hour-of-day to use, from 0 to 23
      * @param minute  the minute-of-hour to use, from 0 to 59
@@ -1513,13 +1629,13 @@
     }
 
     /**
-     * Returns a local date-time formed from this date at the specified time.
+     * Combines this date with a time to create a {@code LocalDateTime}.
      * <p>
-     * This combines this date with the specified time to form a {@code LocalDateTime}.
+     * This returns a {@code LocalDateTime} formed from this date at the
+     * specified hour, minute and second.
+     * The nanosecond field will be set to zero.
      * The individual time fields must be within their valid range.
      * All possible combinations of date and time are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param hour  the hour-of-day to use, from 0 to 23
      * @param minute  the minute-of-hour to use, from 0 to 59
@@ -1532,13 +1648,12 @@
     }
 
     /**
-     * Returns a local date-time formed from this date at the specified time.
+     * Combines this date with a time to create a {@code LocalDateTime}.
      * <p>
-     * This combines this date with the specified time to form a {@code LocalDateTime}.
+     * This returns a {@code LocalDateTime} formed from this date at the
+     * specified hour, minute, second and nanosecond.
      * The individual time fields must be within their valid range.
      * All possible combinations of date and time are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param hour  the hour-of-day to use, from 0 to 23
      * @param minute  the minute-of-hour to use, from 0 to 59
@@ -1552,18 +1667,29 @@
     }
 
     /**
-     * Returns an offset date formed from this date and the specified offset.
+     * Combines this date with an offset time to create an {@code OffsetDateTime}.
      * <p>
-     * This combines this date with the specified offset to form an {@code OffsetDate}.
-     * All possible combinations of date and offset are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
+     * This returns an {@code OffsetDateTime} formed from this date at the specified time.
+     * All possible combinations of date and time are valid.
      *
-     * @param offset  the offset to combine with, not null
-     * @return the offset date formed from this date and the specified offset, not null
+     * @param time  the time to combine with, not null
+     * @return the offset date-time formed from this date and the specified time, not null
      */
-    public OffsetDate atOffset(ZoneOffset offset) {
-        return OffsetDate.of(this, offset);
+    public OffsetDateTime atTime(OffsetTime time) {
+        return OffsetDateTime.of(LocalDateTime.of(this, time.toLocalTime()), time.getOffset());
+    }
+
+    /**
+     * Combines this date with the time of midnight to create a {@code LocalDateTime}
+     * at the start of this date.
+     * <p>
+     * This returns a {@code LocalDateTime} formed from this date at the time of
+     * midnight, 00:00, at the start of this date.
+     *
+     * @return the local date-time of midnight at the start of this date, not null
+     */
+    public LocalDateTime atStartOfDay() {
+        return LocalDateTime.of(this, LocalTime.MIDNIGHT);
     }
 
     /**
@@ -1582,8 +1708,6 @@
      * <p>
      * To convert to a specific time in a given time-zone call {@link #atTime(LocalTime)}
      * followed by {@link LocalDateTime#atZone(ZoneId)}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param zone  the zone ID to use, not null
      * @return the zoned date-time formed from this date and the earliest valid time for the zone, not null
@@ -1636,7 +1760,7 @@
      * If all the dates being compared are instances of {@code LocalDate},
      * then the comparison will be entirely based on the date.
      * If some dates being compared are in different chronologies, then the
-     * chronology is also considered, see {@link java.time.temporal.ChronoLocalDate#compareTo}.
+     * chronology is also considered, see {@link java.time.chrono.ChronoLocalDate#compareTo}.
      *
      * @param other  the other date to compare to, not null
      * @return the comparator value, negative if less, positive if greater
@@ -1822,7 +1946,7 @@
      * Outputs this date as a {@code String} using the formatter.
      * <p>
      * This date will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted date string, not null
diff --git a/jdk/src/share/classes/java/time/LocalDateTime.java b/jdk/src/share/classes/java/time/LocalDateTime.java
index 6dff20b..b69e88b 100644
--- a/jdk/src/share/classes/java/time/LocalDateTime.java
+++ b/jdk/src/share/classes/java/time/LocalDateTime.java
@@ -70,6 +70,7 @@
 import static java.time.LocalTime.NANOS_PER_MINUTE;
 import static java.time.LocalTime.NANOS_PER_SECOND;
 import static java.time.LocalTime.SECONDS_PER_DAY;
+import static java.time.temporal.ChronoField.NANO_OF_SECOND;
 
 import java.io.DataInput;
 import java.io.DataOutput;
@@ -77,21 +78,19 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDateTime;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ISOChrono;
-import java.time.temporal.OffsetDateTime;
+import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
 import java.time.temporal.TemporalUnit;
 import java.time.temporal.ValueRange;
 import java.time.zone.ZoneRules;
@@ -127,7 +126,7 @@
  * @since 1.8
  */
 public final class LocalDateTime
-        implements Temporal, TemporalAdjuster, ChronoLocalDateTime<ISOChrono>, Serializable {
+        implements Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>, Serializable {
 
     /**
      * The minimum supported {@code LocalDateTime}, '-999999999-01-01T00:00:00'.
@@ -212,6 +211,8 @@
      * Obtains an instance of {@code LocalDateTime} from year, month,
      * day, hour and minute, setting the second and nanosecond to zero.
      * <p>
+     * This returns a {@code LocalDateTime} with the specified year, month,
+     * day-of-month, hour and minute.
      * The day must be valid for the year and month, otherwise an exception will be thrown.
      * The second and nanosecond fields will be set to zero.
      *
@@ -221,8 +222,8 @@
      * @param hour  the hour-of-day to represent, from 0 to 23
      * @param minute  the minute-of-hour to represent, from 0 to 59
      * @return the local date-time, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
      */
     public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute) {
         LocalDate date = LocalDate.of(year, month, dayOfMonth);
@@ -234,6 +235,8 @@
      * Obtains an instance of {@code LocalDateTime} from year, month,
      * day, hour, minute and second, setting the nanosecond to zero.
      * <p>
+     * This returns a {@code LocalDateTime} with the specified year, month,
+     * day-of-month, hour, minute and second.
      * The day must be valid for the year and month, otherwise an exception will be thrown.
      * The nanosecond field will be set to zero.
      *
@@ -244,8 +247,8 @@
      * @param minute  the minute-of-hour to represent, from 0 to 59
      * @param second  the second-of-minute to represent, from 0 to 59
      * @return the local date-time, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
      */
     public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second) {
         LocalDate date = LocalDate.of(year, month, dayOfMonth);
@@ -257,6 +260,8 @@
      * Obtains an instance of {@code LocalDateTime} from year, month,
      * day, hour, minute, second and nanosecond.
      * <p>
+     * This returns a {@code LocalDateTime} with the specified year, month,
+     * day-of-month, hour, minute, second and nanosecond.
      * The day must be valid for the year and month, otherwise an exception will be thrown.
      *
      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
@@ -267,8 +272,8 @@
      * @param second  the second-of-minute to represent, from 0 to 59
      * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
      * @return the local date-time, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
      */
     public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) {
         LocalDate date = LocalDate.of(year, month, dayOfMonth);
@@ -281,6 +286,8 @@
      * Obtains an instance of {@code LocalDateTime} from year, month,
      * day, hour and minute, setting the second and nanosecond to zero.
      * <p>
+     * This returns a {@code LocalDateTime} with the specified year, month,
+     * day-of-month, hour and minute.
      * The day must be valid for the year and month, otherwise an exception will be thrown.
      * The second and nanosecond fields will be set to zero.
      *
@@ -290,8 +297,8 @@
      * @param hour  the hour-of-day to represent, from 0 to 23
      * @param minute  the minute-of-hour to represent, from 0 to 59
      * @return the local date-time, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
      */
     public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute) {
         LocalDate date = LocalDate.of(year, month, dayOfMonth);
@@ -303,6 +310,8 @@
      * Obtains an instance of {@code LocalDateTime} from year, month,
      * day, hour, minute and second, setting the nanosecond to zero.
      * <p>
+     * This returns a {@code LocalDateTime} with the specified year, month,
+     * day-of-month, hour, minute and second.
      * The day must be valid for the year and month, otherwise an exception will be thrown.
      * The nanosecond field will be set to zero.
      *
@@ -313,8 +322,8 @@
      * @param minute  the minute-of-hour to represent, from 0 to 59
      * @param second  the second-of-minute to represent, from 0 to 59
      * @return the local date-time, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
      */
     public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second) {
         LocalDate date = LocalDate.of(year, month, dayOfMonth);
@@ -326,6 +335,8 @@
      * Obtains an instance of {@code LocalDateTime} from year, month,
      * day, hour, minute, second and nanosecond.
      * <p>
+     * This returns a {@code LocalDateTime} with the specified year, month,
+     * day-of-month, hour, minute, second and nanosecond.
      * The day must be valid for the year and month, otherwise an exception will be thrown.
      *
      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
@@ -336,8 +347,8 @@
      * @param second  the second-of-minute to represent, from 0 to 59
      * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
      * @return the local date-time, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
      */
     public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) {
         LocalDate date = LocalDate.of(year, month, dayOfMonth);
@@ -392,15 +403,17 @@
      * @param nanoOfSecond  the nanosecond within the second, from 0 to 999,999,999
      * @param offset  the zone offset, not null
      * @return the local date-time, not null
-     * @throws DateTimeException if the result exceeds the supported range
+     * @throws DateTimeException if the result exceeds the supported range,
+     *  or if the nano-of-second is invalid
      */
     public static LocalDateTime ofEpochSecond(long epochSecond, int nanoOfSecond, ZoneOffset offset) {
         Objects.requireNonNull(offset, "offset");
+        NANO_OF_SECOND.checkValidValue(nanoOfSecond);
         long localSecond = epochSecond + offset.getTotalSeconds();  // overflow caught later
         long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY);
         int secsOfDay = (int)Math.floorMod(localSecond, SECONDS_PER_DAY);
         LocalDate date = LocalDate.ofEpochDay(localEpochDay);
-        LocalTime time = LocalTime.ofSecondOfDay(secsOfDay, nanoOfSecond);
+        LocalTime time = LocalTime.ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + nanoOfSecond);
         return new LocalDateTime(date, time);
     }
 
@@ -408,10 +421,14 @@
     /**
      * Obtains an instance of {@code LocalDateTime} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code LocalDateTime}.
+     * This obtains an offset time based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code LocalDateTime}.
      * <p>
-     * The conversion extracts and combines {@code LocalDate} and {@code LocalTime}.
+     * The conversion extracts and combines the {@code LocalDate} and the
+     * {@code LocalTime} from the temporal object.
+     * Implementations are permitted to perform optimizations such as accessing
+     * those fields that are equivalent to the relevant objects.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
      * allowing it to be used as a query via method reference, {@code LocalDateTime::from}.
@@ -424,7 +441,9 @@
         if (temporal instanceof LocalDateTime) {
             return (LocalDateTime) temporal;
         } else if (temporal instanceof ZonedDateTime) {
-            return ((ZonedDateTime) temporal).getDateTime();
+            return ((ZonedDateTime) temporal).toLocalDateTime();
+        } else if (temporal instanceof OffsetDateTime) {
+            return ((OffsetDateTime) temporal).toLocalDateTime();
         }
         try {
             LocalDate date = LocalDate.from(temporal);
@@ -440,14 +459,14 @@
      * Obtains an instance of {@code LocalDateTime} from a text string such as {@code 2007-12-03T10:15:30}.
      * <p>
      * The string must represent a valid date-time and is parsed using
-     * {@link java.time.format.DateTimeFormatters#isoLocalDateTime()}.
+     * {@link java.time.format.DateTimeFormatter#ISO_LOCAL_DATE_TIME}.
      *
      * @param text  the text to parse such as "2007-12-03T10:15:30", not null
      * @return the parsed local date-time, not null
      * @throws DateTimeParseException if the text cannot be parsed
      */
     public static LocalDateTime parse(CharSequence text) {
-        return parse(text, DateTimeFormatters.isoLocalDateTime());
+        return parse(text, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
     }
 
     /**
@@ -535,7 +554,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -548,7 +567,7 @@
             ChronoField f = (ChronoField) field;
             return f.isDateField() || f.isTimeField();
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -565,7 +584,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -579,7 +598,7 @@
             ChronoField f = (ChronoField) field;
             return (f.isTimeField() ? time.range(field) : date.range(field));
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     /**
@@ -598,7 +617,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -629,7 +648,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -644,7 +663,7 @@
             ChronoField f = (ChronoField) field;
             return (f.isTimeField() ? time.getLong(field) : date.getLong(field));
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -657,7 +676,7 @@
      * @return the date part of this date-time, not null
      */
     @Override
-    public LocalDate getDate() {
+    public LocalDate toLocalDate() {
         return date;
     }
 
@@ -667,7 +686,7 @@
      * This method returns the primitive {@code int} value for the year.
      * <p>
      * The year returned by this method is proleptic as per {@code get(YEAR)}.
-     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
+     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA)}.
      *
      * @return the year, from MIN_YEAR to MAX_YEAR
      */
@@ -753,7 +772,7 @@
      * @return the time part of this date-time, not null
      */
     @Override
-    public LocalTime getTime() {
+    public LocalTime toLocalTime() {
         return time;
     }
 
@@ -797,7 +816,7 @@
     /**
      * Returns an adjusted copy of this date-time.
      * <p>
-     * This returns a new {@code LocalDateTime}, based on this one, with the date-time adjusted.
+     * This returns a {@code LocalDateTime}, based on this one, with the date-time adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -806,7 +825,7 @@
      * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}.
      * These include finding the "last day of the month" and "next Wednesday".
      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
-     * such as {@link Month} and {@link java.time.temporal.MonthDay MonthDay}.
+     * such as {@link Month} and {@link java.time.MonthDay MonthDay}.
      * The adjuster is responsible for handling special cases, such as the varying
      * lengths of month and leap years.
      * <p>
@@ -852,7 +871,7 @@
     /**
      * Returns a copy of this date-time with the specified field set to a new value.
      * <p>
-     * This returns a new {@code LocalDateTime}, based on this one, with the value
+     * This returns a {@code LocalDateTime}, based on this one, with the value
      * for the specified field changed.
      * This can be used to change any supported field, such as the year, month or day-of-month.
      * If it is not possible to set the value, because the field is not supported or for
@@ -870,7 +889,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -892,7 +911,7 @@
                 return with(date.with(field, newValue), time);
             }
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
@@ -935,8 +954,8 @@
      *
      * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
      * @return a {@code LocalDateTime} based on this date-time with the requested day, not null
-     * @throws DateTimeException if the day-of-month value is invalid
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the day-of-month value is invalid,
+     *  or if the day-of-month is invalid for the month-year
      */
     public LocalDateTime withDayOfMonth(int dayOfMonth) {
         return with(date.withDayOfMonth(dayOfMonth), time);
@@ -950,8 +969,8 @@
      *
      * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
      * @return a {@code LocalDateTime} based on this date with the requested day, not null
-     * @throws DateTimeException if the day-of-year value is invalid
-     * @throws DateTimeException if the day-of-year is invalid for the year
+     * @throws DateTimeException if the day-of-year value is invalid,
+     *  or if the day-of-year is invalid for the year
      */
     public LocalDateTime withDayOfYear(int dayOfYear) {
         return with(date.withDayOfYear(dayOfYear), time);
@@ -1023,8 +1042,10 @@
      * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
      * will set the second-of-minute and nano-of-second field to zero.
      * <p>
-     * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time
-     * units with an exact duration can be used, other units throw an exception.
+     * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+     * that divides into the length of a standard day without remainder.
+     * This includes all supplied time units on {@link ChronoUnit} and
+     * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -1038,40 +1059,54 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date-time with the specified period added.
+     * Returns a copy of this date-time with the specified amount added.
      * <p>
-     * This method returns a new date-time based on this time with the specified period added.
-     * The adder is typically {@link Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
+     * This returns a {@code LocalDateTime}, based on this one, with the specified amount added.
+     * The amount is typically {@link Period} or {@link Duration} but may be
+     * any other type implementing the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return a {@code LocalDateTime} based on this date-time with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public LocalDateTime plus(TemporalAdder adder) {
-        return (LocalDateTime) adder.addTo(this);
+    public LocalDateTime plus(TemporalAmount amountToAdd) {
+        return (LocalDateTime) amountToAdd.addTo(this);
     }
 
     /**
-     * Returns a copy of this date-time with the specified period added.
+     * Returns a copy of this date-time with the specified amount added.
      * <p>
-     * This method returns a new date-time based on this date-time with the specified period added.
-     * This can be used to add any period that is defined by a unit, for example to add years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns a {@code LocalDateTime}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented here.
+     * Date units are added as per {@link LocalDate#plus(long, TemporalUnit)}.
+     * Time units are added as per {@link LocalTime#plus(long, TemporalUnit)} with
+     * any overflow in days added equivalent to using {@link #plusDays(long)}.
+     * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToAdd  the amount of the unit to add to the result, may be negative
-     * @param unit  the unit of the period to add, not null
-     * @return a {@code LocalDateTime} based on this date-time with the specified period added, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to add, not null
+     * @return a {@code LocalDateTime} based on this date-time with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public LocalDateTime plus(long amountToAdd, TemporalUnit unit) {
@@ -1088,7 +1123,7 @@
             }
             return with(date.plus(amountToAdd, unit), time);
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
@@ -1237,40 +1272,47 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date-time with the specified period subtracted.
+     * Returns a copy of this date-time with the specified amount subtracted.
      * <p>
-     * This method returns a new date-time based on this time with the specified period subtracted.
-     * The subtractor is typically {@link Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
+     * This returns a {@code LocalDateTime}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Period} or {@link Duration} but may be
+     * any other type implementing the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return a {@code LocalDateTime} based on this date-time with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public LocalDateTime minus(TemporalSubtractor subtractor) {
-        return (LocalDateTime) subtractor.subtractFrom(this);
+    public LocalDateTime minus(TemporalAmount amountToSubtract) {
+        return (LocalDateTime) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * Returns a copy of this date-time with the specified period subtracted.
+     * Returns a copy of this date-time with the specified amount subtracted.
      * <p>
-     * This method returns a new date-time based on this date-time with the specified period subtracted.
-     * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns a {@code LocalDateTime}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
-     * @param unit  the unit of the period to subtract, not null
-     * @return a {@code LocalDateTime} based on this date-time with the specified period subtracted, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to subtract, not null
+     * @return a {@code LocalDateTime} based on this date-time with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public LocalDateTime minus(long amountToSubtract, TemporalUnit unit) {
@@ -1472,8 +1514,12 @@
      * @throws DateTimeException if unable to query (defined by the query)
      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
      */
+    @SuppressWarnings("unchecked")
     @Override  // override for Javadoc
     public <R> R query(TemporalQuery<R> query) {
+        if (query == Queries.localDate()) {
+            return (R) date;
+        }
         return ChronoLocalDateTime.super.query(query);
     }
 
@@ -1523,14 +1569,15 @@
      * For example, the period in months between 2012-06-15T00:00 and 2012-08-14T23:59
      * will only be one month as it is one minute short of two months.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, MONTHS);   // this method
-     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MONTHS);
+     *   amount = MONTHS.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
@@ -1580,17 +1627,15 @@
             }
             return date.periodUntil(endDate, unit);
         }
-        return unit.between(this, endDateTime).getAmount();
+        return unit.between(this, endDateTime);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns an offset date-time formed from this date-time and the specified offset.
+     * Combines this time with a date to create an {@code OffsetTime}.
      * <p>
-     * This combines this date-time with the specified offset to form an {@code OffsetDateTime}.
+     * This returns an {@code OffsetTime} formed from this time at the specified offset.
      * All possible combinations of date-time and offset are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param offset  the offset to combine with, not null
      * @return the offset date-time formed from this date-time and the specified offset, not null
@@ -1600,9 +1645,10 @@
     }
 
     /**
-     * Returns a zoned date-time formed from this date-time and the specified time-zone.
+     * Combines this time with a time-zone to create a {@code ZonedDateTime}.
      * <p>
-     * This creates a zoned date-time matching the input date-time as closely as possible.
+     * This returns a {@code ZonedDateTime} formed from this date-time at the
+     * specified time-zone. The result will match this date-time as closely as possible.
      * Time-zone rules, such as daylight savings, mean that not every local date-time
      * is valid for the specified zone, thus the local date-time may be adjusted.
      * <p>
@@ -1623,8 +1669,6 @@
      * {@link ZonedDateTime#withLaterOffsetAtOverlap()} on the result of this method.
      * To throw an exception when there is a gap or overlap, use
      * {@link ZonedDateTime#ofStrict(LocalDateTime, ZoneOffset, ZoneId)}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param zone  the time-zone to use, not null
      * @return the zoned date-time formed from this date-time, not null
@@ -1658,9 +1702,9 @@
     }
 
     private int compareTo0(LocalDateTime other) {
-        int cmp = date.compareTo0(other.getDate());
+        int cmp = date.compareTo0(other.toLocalDate());
         if (cmp == 0) {
-            cmp = time.compareTo(other.getTime());
+            cmp = time.compareTo(other.toLocalTime());
         }
         return cmp;
     }
@@ -1810,7 +1854,7 @@
      * Outputs this date-time as a {@code String} using the formatter.
      * <p>
      * This date-time will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted date-time string, not null
diff --git a/jdk/src/share/classes/java/time/LocalTime.java b/jdk/src/share/classes/java/time/LocalTime.java
index 01e74e6..c1884eb 100644
--- a/jdk/src/share/classes/java/time/LocalTime.java
+++ b/jdk/src/share/classes/java/time/LocalTime.java
@@ -76,23 +76,17 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.format.DateTimeBuilder;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDateTime;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ChronoZonedDateTime;
-import java.time.temporal.OffsetTime;
 import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
 import java.time.temporal.TemporalUnit;
 import java.time.temporal.ValueRange;
 import java.util.Objects;
@@ -129,7 +123,7 @@
      */
     public static final LocalTime MIN;
     /**
-     * The minimum supported {@code LocalTime}, '23:59:59.999999999'.
+     * The maximum supported {@code LocalTime}, '23:59:59.999999999'.
      * This is the time just before midnight at the end of the day.
      */
     public static final LocalTime MAX;
@@ -273,21 +267,17 @@
         // inline OffsetTime factory to avoid creating object and InstantProvider checks
         final Instant now = clock.instant();  // called once
         ZoneOffset offset = clock.getZone().getRules().getOffset(now);
-        long secsOfDay = now.getEpochSecond() % SECONDS_PER_DAY;
-        secsOfDay = (secsOfDay + offset.getTotalSeconds()) % SECONDS_PER_DAY;
-        if (secsOfDay < 0) {
-            secsOfDay += SECONDS_PER_DAY;
-        }
-        return LocalTime.ofSecondOfDay(secsOfDay, now.getNano());
+        long localSecond = now.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
+        int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY);
+        return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + now.getNano());
     }
 
     //------------------------get-----------------------------------------------
     /**
      * Obtains an instance of {@code LocalTime} from an hour and minute.
      * <p>
-     * The second and nanosecond fields will be set to zero by this factory method.
-     * <p>
-     * This factory may return a cached value, but applications must not rely on this.
+     * This returns a {@code LocalTime} with the specified hour and minute.
+     * The second and nanosecond fields will be set to zero.
      *
      * @param hour  the hour-of-day to represent, from 0 to 23
      * @param minute  the minute-of-hour to represent, from 0 to 59
@@ -306,9 +296,8 @@
     /**
      * Obtains an instance of {@code LocalTime} from an hour, minute and second.
      * <p>
-     * The nanosecond field will be set to zero by this factory method.
-     * <p>
-     * This factory may return a cached value, but applications must not rely on this.
+     * This returns a {@code LocalTime} with the specified hour, minute and second.
+     * The nanosecond field will be set to zero.
      *
      * @param hour  the hour-of-day to represent, from 0 to 23
      * @param minute  the minute-of-hour to represent, from 0 to 59
@@ -329,7 +318,7 @@
     /**
      * Obtains an instance of {@code LocalTime} from an hour, minute, second and nanosecond.
      * <p>
-     * This factory may return a cached value, but applications must not rely on this.
+     * This returns a {@code LocalTime} with the specified hour, minute, second and nanosecond.
      *
      * @param hour  the hour-of-day to represent, from 0 to 23
      * @param minute  the minute-of-hour to represent, from 0 to 59
@@ -350,7 +339,8 @@
     /**
      * Obtains an instance of {@code LocalTime} from a second-of-day value.
      * <p>
-     * This factory may return a cached value, but applications must not rely on this.
+     * This returns a {@code LocalTime} with the specified second-of-day.
+     * The nanosecond field will be set to zero.
      *
      * @param secondOfDay  the second-of-day, from {@code 0} to {@code 24 * 60 * 60 - 1}
      * @return the local time, not null
@@ -366,30 +356,9 @@
     }
 
     /**
-     * Obtains an instance of {@code LocalTime} from a second-of-day value, with
-     * associated nanos of second.
-     * <p>
-     * This factory may return a cached value, but applications must not rely on this.
-     *
-     * @param secondOfDay  the second-of-day, from {@code 0} to {@code 24 * 60 * 60 - 1}
-     * @param nanoOfSecond  the nano-of-second, from 0 to 999,999,999
-     * @return the local time, not null
-     * @throws DateTimeException if the either input value is invalid
-     */
-    public static LocalTime ofSecondOfDay(long secondOfDay, int nanoOfSecond) {
-        SECOND_OF_DAY.checkValidValue(secondOfDay);
-        NANO_OF_SECOND.checkValidValue(nanoOfSecond);
-        int hours = (int) (secondOfDay / SECONDS_PER_HOUR);
-        secondOfDay -= hours * SECONDS_PER_HOUR;
-        int minutes = (int) (secondOfDay / SECONDS_PER_MINUTE);
-        secondOfDay -= minutes * SECONDS_PER_MINUTE;
-        return create(hours, minutes, (int) secondOfDay, nanoOfSecond);
-    }
-
-    /**
      * Obtains an instance of {@code LocalTime} from a nanos-of-day value.
      * <p>
-     * This factory may return a cached value, but applications must not rely on this.
+     * This returns a {@code LocalTime} with the specified nanosecond-of-day.
      *
      * @param nanoOfDay  the nano of day, from {@code 0} to {@code 24 * 60 * 60 * 1,000,000,000 - 1}
      * @return the local time, not null
@@ -410,10 +379,12 @@
     /**
      * Obtains an instance of {@code LocalTime} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code LocalTime}.
+     * This obtains a local time based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code LocalTime}.
      * <p>
-     * The conversion extracts the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} field.
+     * The conversion uses the {@link Queries#localTime()} query, which relies
+     * on extracting the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} field.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
      * allowing it to be used in queries via method reference, {@code LocalTime::from}.
@@ -423,26 +394,11 @@
      * @throws DateTimeException if unable to convert to a {@code LocalTime}
      */
     public static LocalTime from(TemporalAccessor temporal) {
-        if (temporal instanceof LocalTime) {
-            return (LocalTime) temporal;
-        } else if (temporal instanceof ChronoLocalDateTime) {
-            return ((ChronoLocalDateTime) temporal).getTime();
-        } else if (temporal instanceof ChronoZonedDateTime) {
-            return ((ChronoZonedDateTime) temporal).getTime();
+        LocalTime time = temporal.query(Queries.localTime());
+        if (time == null) {
+            throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass());
         }
-        // handle builder as a special case
-        if (temporal instanceof DateTimeBuilder) {
-            DateTimeBuilder builder = (DateTimeBuilder) temporal;
-            LocalTime time = builder.extract(LocalTime.class);
-            if (time != null) {
-                return time;
-            }
-        }
-        try {
-            return ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
-        } catch (DateTimeException ex) {
-            throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass(), ex);
-        }
+        return time;
     }
 
     //-----------------------------------------------------------------------
@@ -450,14 +406,14 @@
      * Obtains an instance of {@code LocalTime} from a text string such as {@code 10:15}.
      * <p>
      * The string must represent a valid time and is parsed using
-     * {@link java.time.format.DateTimeFormatters#isoLocalTime()}.
+     * {@link java.time.format.DateTimeFormatter#ISO_LOCAL_TIME}.
      *
      * @param text the text to parse such as "10:15:30", not null
      * @return the parsed local time, not null
      * @throws DateTimeParseException if the text cannot be parsed
      */
     public static LocalTime parse(CharSequence text) {
-        return parse(text, DateTimeFormatters.isoLocalTime());
+        return parse(text, DateTimeFormatter.ISO_LOCAL_TIME);
     }
 
     /**
@@ -539,7 +495,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -551,7 +507,7 @@
         if (field instanceof ChronoField) {
             return ((ChronoField) field).isTimeField();
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -568,7 +524,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -596,7 +552,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -626,7 +582,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -646,7 +602,7 @@
             }
             return get0(field);
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     private int get0(TemporalField field) {
@@ -711,7 +667,7 @@
     /**
      * Returns an adjusted copy of this time.
      * <p>
-     * This returns a new {@code LocalTime}, based on this one, with the time adjusted.
+     * This returns a {@code LocalTime}, based on this one, with the time adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -741,7 +697,7 @@
     /**
      * Returns a copy of this time with the specified field set to a new value.
      * <p>
-     * This returns a new {@code LocalTime}, based on this one, with the value
+     * This returns a {@code LocalTime}, based on this one, with the value
      * for the specified field changed.
      * This can be used to change any supported field, such as the hour, minute or second.
      * If it is not possible to set the value, because the field is not supported or for
@@ -807,7 +763,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -843,7 +799,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
@@ -924,8 +880,10 @@
      * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
      * will set the second-of-minute and nano-of-second field to zero.
      * <p>
-     * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time
-     * units with an exact duration can be used, other units throw an exception.
+     * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+     * that divides into the length of a standard day without remainder.
+     * This includes all supplied time units on {@link ChronoUnit} and
+     * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -936,56 +894,98 @@
     public LocalTime truncatedTo(TemporalUnit unit) {
         if (unit == ChronoUnit.NANOS) {
             return this;
-        } else if (unit == ChronoUnit.DAYS) {
-            return MIDNIGHT;
-        } else if (unit.isDurationEstimated()) {
-            throw new DateTimeException("Unit must not have an estimated duration");
+        }
+        Duration unitDur = unit.getDuration();
+        if (unitDur.getSeconds() > SECONDS_PER_DAY) {
+            throw new DateTimeException("Unit is too large to be used for truncation");
+        }
+        long dur = unitDur.toNanos();
+        if ((NANOS_PER_DAY % dur) != 0) {
+            throw new DateTimeException("Unit must divide into a standard day without remainder");
         }
         long nod = toNanoOfDay();
-        long dur = unit.getDuration().toNanos();
-        if (dur >= NANOS_PER_DAY) {
-            throw new DateTimeException("Unit must not be a date unit");
-        }
-        nod = (nod / dur) * dur;
-        return ofNanoOfDay(nod);
+        return ofNanoOfDay((nod / dur) * dur);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date with the specified period added.
+     * Returns a copy of this time with the specified amount added.
      * <p>
-     * This method returns a new time based on this time with the specified period added.
-     * The adder is typically {@link Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
+     * This returns a {@code LocalTime}, based on this one, with the specified amount added.
+     * The amount is typically {@link Duration} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return a {@code LocalTime} based on this time with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public LocalTime plus(TemporalAdder adder) {
-        return (LocalTime) adder.addTo(this);
+    public LocalTime plus(TemporalAmount amountToAdd) {
+        return (LocalTime) amountToAdd.addTo(this);
     }
 
     /**
-     * Returns a copy of this time with the specified period added.
+     * Returns a copy of this time with the specified amount added.
      * <p>
-     * This method returns a new time based on this time with the specified period added.
-     * This can be used to add any period that is defined by a unit, for example to add hours, minutes or seconds.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns a {@code LocalTime}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented here.
+     * The supported fields behave as follows:
+     * <ul>
+     * <li>{@code NANOS} -
+     *  Returns a {@code LocalTime} with the specified number of nanoseconds added.
+     *  This is equivalent to {@link #plusNanos(long)}.
+     * <li>{@code MICROS} -
+     *  Returns a {@code LocalTime} with the specified number of microseconds added.
+     *  This is equivalent to {@link #plusNanos(long)} with the amount
+     *  multiplied by 1,000.
+     * <li>{@code MILLIS} -
+     *  Returns a {@code LocalTime} with the specified number of milliseconds added.
+     *  This is equivalent to {@link #plusNanos(long)} with the amount
+     *  multiplied by 1,000,000.
+     * <li>{@code SECONDS} -
+     *  Returns a {@code LocalTime} with the specified number of seconds added.
+     *  This is equivalent to {@link #plusSeconds(long)}.
+     * <li>{@code MINUTES} -
+     *  Returns a {@code LocalTime} with the specified number of minutes added.
+     *  This is equivalent to {@link #plusMinutes(long)}.
+     * <li>{@code HOURS} -
+     *  Returns a {@code LocalTime} with the specified number of hours added.
+     *  This is equivalent to {@link #plusHours(long)}.
+     * <li>{@code HALF_DAYS} -
+     *  Returns a {@code LocalTime} with the specified number of half-days added.
+     *  This is equivalent to {@link #plusHours(long)} with the amount
+     *  multiplied by 12.
+     * <li>{@code DAYS} -
+     *  Returns a {@code LocalTime} with the specified number of days added.
+     *  This returns {@code this} time.
+     * </ul>
+     * <p>
+     * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
+     * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToAdd  the amount of the unit to add to the result, may be negative
-     * @param unit  the unit of the period to add, not null
-     * @return a {@code LocalTime} based on this time with the specified period added, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to add, not null
+     * @return a {@code LocalTime} based on this time with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public LocalTime plus(long amountToAdd, TemporalUnit unit) {
@@ -1003,7 +1003,7 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
@@ -1107,40 +1107,47 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this time with the specified period subtracted.
+     * Returns a copy of this time with the specified amount subtracted.
      * <p>
-     * This method returns a new time based on this time with the specified period subtracted.
-     * The subtractor is typically {@link Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
+     * This returns a {@code LocalTime}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Duration} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return a {@code LocalTime} based on this time with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public LocalTime minus(TemporalSubtractor subtractor) {
-        return (LocalTime) subtractor.subtractFrom(this);
+    public LocalTime minus(TemporalAmount amountToSubtract) {
+        return (LocalTime) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * Returns a copy of this time with the specified period subtracted.
+     * Returns a copy of this time with the specified amount subtracted.
      * <p>
-     * This method returns a new time based on this time with the specified period subtracted.
-     * This can be used to subtract any period that is defined by a unit, for example to subtract hours, minutes or seconds.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns a {@code LocalTime}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
-     * @param unit  the unit of the period to subtract, not null
-     * @return a {@code LocalTime} based on this time with the specified period subtracted, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to subtract, not null
+     * @return a {@code LocalTime} based on this time with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public LocalTime minus(long amountToSubtract, TemporalUnit unit) {
@@ -1230,13 +1237,17 @@
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.precision()) {
+        if (query == Queries.chronology() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
+            return null;
+        } else if (query == Queries.localTime()) {
+            return (R) this;
+        } else if (query == Queries.localDate()) {
+            return null;
+        } else if (query == Queries.precision()) {
             return (R) NANOS;
         }
         // inline TemporalAccessor.super.query(query) as an optimization
-        if (query == Queries.chrono() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
-            return null;
-        }
+        // non-JDK classes are not permitted to make this optimization
         return query.queryFrom(this);
     }
 
@@ -1285,14 +1296,15 @@
      * For example, the period in hours between 11:30 and 13:29 will only
      * be one hour as it is one minute short of two hours.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, HOURS);   // this method
-     *   dateTime.plus(HOURS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MINUTES);
+     *   amount = MINUTES.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
@@ -1332,17 +1344,15 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.between(this, endTime).getAmount();
+        return unit.between(this, endTime);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a local date-time formed from this time at the specified date.
+     * Combines this time with a date to create a {@code LocalDateTime}.
      * <p>
-     * This combines this time with the specified date to form a {@code LocalDateTime}.
+     * This returns a {@code LocalDateTime} formed from this time at the specified date.
      * All possible combinations of date and time are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param date  the date to combine with, not null
      * @return the local date-time formed from this time and the specified date, not null
@@ -1352,12 +1362,10 @@
     }
 
     /**
-     * Returns an offset time formed from this time and the specified offset.
+     * Combines this time with a date to create an {@code OffsetTime}.
      * <p>
-     * This combines this time with the specified offset to form an {@code OffsetTime}.
+     * This returns an {@code OffsetTime} formed from this time at the specified offset.
      * All possible combinations of time and offset are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param offset  the offset to combine with, not null
      * @return the offset time formed from this time and the specified offset, not null
@@ -1529,7 +1537,7 @@
      * Outputs this time as a {@code String} using the formatter.
      * <p>
      * This time will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted time string, not null
@@ -1537,7 +1545,7 @@
      */
     public String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/Month.java b/jdk/src/share/classes/java/time/Month.java
index db8d053..8b4fe92 100644
--- a/jdk/src/share/classes/java/time/Month.java
+++ b/jdk/src/share/classes/java/time/Month.java
@@ -64,11 +64,11 @@
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoUnit.MONTHS;
 
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.TextStyle;
-import java.time.temporal.Chrono;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
@@ -192,8 +192,9 @@
     /**
      * Obtains an instance of {@code Month} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code Month}.
+     * This obtains a month based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code Month}.
      * <p>
      * The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} field.
      * The extraction is only permitted if the temporal object has an ISO
@@ -211,7 +212,7 @@
             return (Month) temporal;
         }
         try {
-            if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) {
+            if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
                 temporal = LocalDate.from(temporal);
             }
             return of(temporal.get(MONTH_OF_YEAR));
@@ -237,8 +238,9 @@
     /**
      * Gets the textual representation, such as 'Jan' or 'December'.
      * <p>
-     * This returns the textual name used to identify the month-of-year.
-     * The parameters control the length of the returned text and the locale.
+     * This returns the textual name used to identify the month-of-year,
+     * suitable for presentation to the user.
+     * The parameters control the style of the returned text and the locale.
      * <p>
      * If no textual mapping is found then the {@link #getValue() numeric value} is returned.
      *
@@ -246,8 +248,8 @@
      * @param locale  the locale to use, not null
      * @return the text value of the month-of-year, not null
      */
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendText(MONTH_OF_YEAR, style).toFormatter(locale).print(this);
+    public String getDisplayName(TextStyle style, Locale locale) {
+        return new DateTimeFormatterBuilder().appendText(MONTH_OF_YEAR, style).toFormatter(locale).format(this);
     }
 
     //-----------------------------------------------------------------------
@@ -263,7 +265,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -275,7 +277,7 @@
         if (field instanceof ChronoField) {
             return field == MONTH_OF_YEAR;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -291,7 +293,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -320,15 +322,13 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
      * @param field  the field to get, not null
      * @return the value for the field, within the valid range of values
      * @throws DateTimeException if a value for the field cannot be obtained
-     * @throws DateTimeException if the range of valid values for the field exceeds an {@code int}
-     * @throws DateTimeException if the value is outside the range of valid values for the field
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
@@ -351,7 +351,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -367,7 +367,7 @@
         } else if (field instanceof ChronoField) {
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -554,8 +554,8 @@
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) ISOChrono.INSTANCE;
+        if (query == Queries.chronology()) {
+            return (R) IsoChronology.INSTANCE;
         } else if (query == Queries.precision()) {
             return (R) MONTHS;
         }
@@ -599,7 +599,7 @@
      */
     @Override
     public Temporal adjustInto(Temporal temporal) {
-        if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) {
+        if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
             throw new DateTimeException("Adjustment only supported on ISO date-time");
         }
         return temporal.with(MONTH_OF_YEAR, getValue());
diff --git a/jdk/src/share/classes/java/time/temporal/MonthDay.java b/jdk/src/share/classes/java/time/MonthDay.java
similarity index 92%
rename from jdk/src/share/classes/java/time/temporal/MonthDay.java
rename to jdk/src/share/classes/java/time/MonthDay.java
index 7707cd0..33692d0 100644
--- a/jdk/src/share/classes/java/time/temporal/MonthDay.java
+++ b/jdk/src/share/classes/java/time/MonthDay.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time;
 
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
@@ -70,14 +70,19 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.Month;
-import java.time.ZoneId;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.ValueRange;
 import java.util.Objects;
 
 /**
@@ -198,8 +203,8 @@
      * @param month  the month-of-year to represent, not null
      * @param dayOfMonth  the day-of-month to represent, from 1 to 31
      * @return the month-day, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month
      */
     public static MonthDay of(Month month, int dayOfMonth) {
         Objects.requireNonNull(month, "month");
@@ -224,8 +229,8 @@
      * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
      * @param dayOfMonth  the day-of-month to represent, from 1 to 31
      * @return the month-day, not null
-     * @throws DateTimeException if the value of any field is out of range
-     * @throws DateTimeException if the day-of-month is invalid for the month
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month
      */
     public static MonthDay of(int month, int dayOfMonth) {
         return of(Month.of(month), dayOfMonth);
@@ -235,8 +240,9 @@
     /**
      * Obtains an instance of {@code MonthDay} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code MonthDay}.
+     * This obtains a month-day based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code MonthDay}.
      * <p>
      * The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} and
      * {@link ChronoField#DAY_OF_MONTH DAY_OF_MONTH} fields.
@@ -254,7 +260,7 @@
             return (MonthDay) temporal;
         }
         try {
-            if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) {
+            if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
                 temporal = LocalDate.from(temporal);
             }
             return of(temporal.get(MONTH_OF_YEAR), temporal.get(DAY_OF_MONTH));
@@ -314,8 +320,6 @@
      * {@link #get(TemporalField) get} methods will throw an exception.
      * <p>
      * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return valid
-     * values based on this date-time.
      * The supported fields are:
      * <ul>
      * <li>{@code MONTH_OF_YEAR}
@@ -324,7 +328,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -336,7 +340,7 @@
         if (field instanceof ChronoField) {
             return field == MONTH_OF_YEAR || field == DAY_OF_MONTH;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -353,7 +357,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -385,7 +389,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -412,7 +416,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -431,11 +435,25 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
     /**
+     * Gets the month-of-year field from 1 to 12.
+     * <p>
+     * This method returns the month as an {@code int} from 1 to 12.
+     * Application code is frequently clearer if the enum {@link Month}
+     * is used by calling {@link #getMonth()}.
+     *
+     * @return the month-of-year, from 1 to 12
+     * @see #getMonth()
+     */
+    public int getMonthValue() {
+        return month;
+    }
+
+    /**
      * Gets the month-of-year field using the {@code Month} enum.
      * <p>
      * This method returns the enum {@link Month} for the month.
@@ -444,6 +462,7 @@
      * provides the {@link Month#getValue() int value}.
      *
      * @return the month-of-year, not null
+     * @see #getMonthValue()
      */
     public Month getMonth() {
         return Month.of(month);
@@ -524,8 +543,8 @@
      *
      * @param dayOfMonth  the day-of-month to set in the return month-day, from 1 to 31
      * @return a {@code MonthDay} based on this month-day with the requested day, not null
-     * @throws DateTimeException if the day-of-month value is invalid
-     * @throws DateTimeException if the day-of-month is invalid for the month
+     * @throws DateTimeException if the day-of-month value is invalid,
+     *  or if the day-of-month is invalid for the month
      */
     public MonthDay withDayOfMonth(int dayOfMonth) {
         if (dayOfMonth == this.day) {
@@ -556,8 +575,8 @@
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) ISOChrono.INSTANCE;
+        if (query == Queries.chronology()) {
+            return (R) IsoChronology.INSTANCE;
         }
         return TemporalAccessor.super.query(query);
     }
@@ -591,7 +610,7 @@
      */
     @Override
     public Temporal adjustInto(Temporal temporal) {
-        if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) {
+        if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
             throw new DateTimeException("Adjustment only supported on ISO date-time");
         }
         temporal = temporal.with(MONTH_OF_YEAR, month);
@@ -600,9 +619,10 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a date formed from this month-day at the specified year.
+     * Combines this month-day with a year to create a {@code LocalDate}.
      * <p>
-     * This combines this month-day and the specified year to form a {@code LocalDate}.
+     * This returns a {@code LocalDate} formed from this month-day and the specified year.
+     * <p>
      * A month-day of February 29th will be adjusted to February 28th in the resulting
      * date if the year is not a leap year.
      * <p>
@@ -610,7 +630,7 @@
      *
      * @param year  the year to use, from MIN_YEAR to MAX_YEAR
      * @return the local date formed from this month-day and the specified year, not null
-     * @see Year#atMonthDay(MonthDay)
+     * @throws DateTimeException if the year is outside the valid range of years
      */
     public LocalDate atYear(int year) {
         return LocalDate.of(year, month, isValidYear(year) ? day : 28);
@@ -626,6 +646,7 @@
      * @param other  the other month-day to compare to, not null
      * @return the comparator value, negative if less, positive if greater
      */
+    @Override
     public int compareTo(MonthDay other) {
         int cmp = (month - other.month);
         if (cmp == 0) {
@@ -705,7 +726,7 @@
      * Outputs this month-day as a {@code String} using the formatter.
      * <p>
      * This month-day will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted month-day string, not null
@@ -713,7 +734,7 @@
      */
     public String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
     //-----------------------------------------------------------------------
@@ -721,7 +742,7 @@
      * Writes the object using a
      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
      * <pre>
-     *  out.writeByte(6);  // identifies this as a Year
+     *  out.writeByte(13);  // identifies this as a MonthDay
      *  out.writeByte(month);
      *  out.writeByte(day);
      * </pre>
diff --git a/jdk/src/share/classes/java/time/temporal/OffsetDateTime.java b/jdk/src/share/classes/java/time/OffsetDateTime.java
similarity index 86%
rename from jdk/src/share/classes/java/time/temporal/OffsetDateTime.java
rename to jdk/src/share/classes/java/time/OffsetDateTime.java
index c7c2295..aef0a42 100644
--- a/jdk/src/share/classes/java/time/temporal/OffsetDateTime.java
+++ b/jdk/src/share/classes/java/time/OffsetDateTime.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time;
 
 import static java.time.temporal.ChronoField.EPOCH_DAY;
 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
@@ -73,20 +73,20 @@
 import java.io.ObjectOutput;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.DayOfWeek;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.Month;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
 import java.time.zone.ZoneRules;
 import java.util.Comparator;
 import java.util.Objects;
@@ -151,7 +151,7 @@
         public int compare(OffsetDateTime datetime1, OffsetDateTime datetime2) {
             int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond());
             if (cmp == 0) {
-                cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay());
+                cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay());
             }
             return cmp;
         }
@@ -253,18 +253,34 @@
     }
 
     /**
-     * Obtains an instance of {@code OffsetDateTime} from a {@code ZonedDateTime}.
+     * Obtains an instance of {@code OffsetDateTime} from a year, month, day,
+     * hour, minute, second, nanosecond and offset.
      * <p>
-     * This creates an offset date-time with the same local date-time and offset as
-     * the zoned date-time. The result will have the same instant as the input.
+     * This creates an offset date-time with the seven specified fields.
+     * <p>
+     * This method exists primarily for writing test cases.
+     * Non test-code will typically use other methods to create an offset time.
+     * {@code LocalDateTime} has five additional convenience variants of the
+     * equivalent factory method taking fewer arguments.
+     * They are not provided here to reduce the footprint of the API.
      *
-     * @param zonedDateTime  the zoned date-time to convert from, not null
+     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
+     * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
+     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
+     * @param hour  the hour-of-day to represent, from 0 to 23
+     * @param minute  the minute-of-hour to represent, from 0 to 59
+     * @param second  the second-of-minute to represent, from 0 to 59
+     * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
+     * @param offset  the zone offset, not null
      * @return the offset date-time, not null
-     * @throws DateTimeException if the result exceeds the supported range
+     * @throws DateTimeException if the value of any field is out of range, or
+     *  if the day-of-month is invalid for the month-year
      */
-    public static OffsetDateTime of(ZonedDateTime zonedDateTime) {
-        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
-        return new OffsetDateTime(zonedDateTime.getDateTime(), zonedDateTime.getOffset());
+    public static OffsetDateTime of(
+            int year, int month, int dayOfMonth,
+            int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset) {
+        LocalDateTime dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
+        return new OffsetDateTime(dt, offset);
     }
 
     //-----------------------------------------------------------------------
@@ -293,11 +309,16 @@
     /**
      * Obtains an instance of {@code OffsetDateTime} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code OffsetDateTime}.
+     * This obtains an offset date-time based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code OffsetDateTime}.
      * <p>
-     * The conversion extracts and combines {@code LocalDateTime} and {@code ZoneOffset}.
-     * If that fails it will try to extract and combine {@code Instant} and {@code ZoneOffset}.
+     * The conversion will first obtain a {@code ZoneOffset} from the temporal object.
+     * It will then try to obtain a {@code LocalDateTime}, falling back to an {@code Instant} if necessary.
+     * The result will be the combination of {@code ZoneOffset} with either
+     * with {@code LocalDateTime} or {@code Instant}.
+     * Implementations are permitted to perform optimizations such as accessing
+     * those fields that are equivalent to the relevant objects.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
      * allowing it to be used in queries via method reference, {@code OffsetDateTime::from}.
@@ -330,14 +351,14 @@
      * such as {@code 2007-12-03T10:15:30+01:00}.
      * <p>
      * The string must represent a valid date-time and is parsed using
-     * {@link java.time.format.DateTimeFormatters#isoOffsetDateTime()}.
+     * {@link java.time.format.DateTimeFormatter#ISO_OFFSET_DATE_TIME}.
      *
      * @param text  the text to parse such as "2007-12-03T10:15:30+01:00", not null
      * @return the parsed offset date-time, not null
      * @throws DateTimeParseException if the text cannot be parsed
      */
     public static OffsetDateTime parse(CharSequence text) {
-        return parse(text, DateTimeFormatters.isoOffsetDateTime());
+        return parse(text, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
     }
 
     /**
@@ -425,7 +446,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -434,7 +455,7 @@
      */
     @Override
     public boolean isSupported(TemporalField field) {
-        return field instanceof ChronoField || (field != null && field.doIsSupported(this));
+        return field instanceof ChronoField || (field != null && field.isSupportedBy(this));
     }
 
     /**
@@ -451,7 +472,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -467,7 +488,7 @@
             }
             return dateTime.range(field);
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     /**
@@ -486,7 +507,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -520,7 +541,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -538,7 +559,7 @@
             }
             return dateTime.getLong(field);
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -611,7 +632,7 @@
      *
      * @return the local date-time part of this date-time, not null
      */
-    public LocalDateTime getDateTime() {
+    public LocalDateTime toLocalDateTime() {
         return dateTime;
     }
 
@@ -624,8 +645,8 @@
      *
      * @return the date part of this date-time, not null
      */
-    public LocalDate getDate() {
-        return dateTime.getDate();
+    public LocalDate toLocalDate() {
+        return dateTime.toLocalDate();
     }
 
     /**
@@ -634,7 +655,7 @@
      * This method returns the primitive {@code int} value for the year.
      * <p>
      * The year returned by this method is proleptic as per {@code get(YEAR)}.
-     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
+     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA)}.
      *
      * @return the year, from MIN_YEAR to MAX_YEAR
      */
@@ -719,8 +740,8 @@
      *
      * @return the time part of this date-time, not null
      */
-    public LocalTime getTime() {
-        return dateTime.getTime();
+    public LocalTime toLocalTime() {
+        return dateTime.toLocalTime();
     }
 
     /**
@@ -763,7 +784,7 @@
     /**
      * Returns an adjusted copy of this date-time.
      * <p>
-     * This returns a new {@code OffsetDateTime}, based on this one, with the date-time adjusted.
+     * This returns an {@code OffsetDateTime}, based on this one, with the date-time adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -772,7 +793,7 @@
      * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}.
      * These include finding the "last day of the month" and "next Wednesday".
      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
-     * such as {@link Month} and {@link java.time.temporal.MonthDay MonthDay}.
+     * such as {@link Month} and {@link java.time.MonthDay MonthDay}.
      * The adjuster is responsible for handling special cases, such as the varying
      * lengths of month and leap years.
      * <p>
@@ -821,7 +842,7 @@
     /**
      * Returns a copy of this date-time with the specified field set to a new value.
      * <p>
-     * This returns a new {@code OffsetDateTime}, based on this one, with the value
+     * TThis returns an {@code OffsetDateTime}, based on this one, with the value
      * for the specified field changed.
      * This can be used to change any supported field, such as the year, month or day-of-month.
      * If it is not possible to set the value, because the field is not supported or for
@@ -849,7 +870,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -873,7 +894,7 @@
             }
             return with(dateTime.with(field, newValue), offset);
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
@@ -916,8 +937,8 @@
      *
      * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
      * @return an {@code OffsetDateTime} based on this date-time with the requested day, not null
-     * @throws DateTimeException if the day-of-month value is invalid
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the day-of-month value is invalid,
+     *  or if the day-of-month is invalid for the month-year
      */
     public OffsetDateTime withDayOfMonth(int dayOfMonth) {
         return with(dateTime.withDayOfMonth(dayOfMonth), offset);
@@ -931,8 +952,8 @@
      *
      * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
      * @return an {@code OffsetDateTime} based on this date with the requested day, not null
-     * @throws DateTimeException if the day-of-year value is invalid
-     * @throws DateTimeException if the day-of-year is invalid for the year
+     * @throws DateTimeException if the day-of-year value is invalid,
+     *  or if the day-of-year is invalid for the year
      */
     public OffsetDateTime withDayOfYear(int dayOfYear) {
         return with(dateTime.withDayOfYear(dayOfYear), offset);
@@ -1008,8 +1029,10 @@
      * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
      * will set the second-of-minute and nano-of-second field to zero.
      * <p>
-     * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time
-     * units with an exact duration can be used, other units throw an exception.
+     * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+     * that divides into the length of a standard day without remainder.
+     * This includes all supplied time units on {@link ChronoUnit} and
+     * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
      * <p>
      * The offset does not affect the calculation and will be the same in the result.
      * <p>
@@ -1025,49 +1048,60 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date-time with the specified period added.
+     * Returns a copy of this date-time with the specified amount added.
      * <p>
-     * This method returns a new date-time based on this time with the specified period added.
-     * The adder is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
-     * The offset is not part of the calculation and will be unchanged in the result.
+     * This returns an {@code OffsetDateTime}, based on this one, with the specified amount added.
+     * The amount is typically {@link Period} or {@link Duration} but may be
+     * any other type implementing the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return an {@code OffsetDateTime} based on this date-time with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public OffsetDateTime plus(TemporalAdder adder) {
-        return (OffsetDateTime) adder.addTo(this);
+    public OffsetDateTime plus(TemporalAmount amountToAdd) {
+        return (OffsetDateTime) amountToAdd.addTo(this);
     }
 
     /**
-     * Returns a copy of this date-time with the specified period added.
+     * Returns a copy of this date-time with the specified amount added.
      * <p>
-     * This method returns a new date-time based on this date-time with the specified period added.
-     * This can be used to add any period that is defined by a unit, for example to add years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns an {@code OffsetDateTime}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented by
+     * {@link LocalDateTime#plus(long, TemporalUnit)}.
      * The offset is not part of the calculation and will be unchanged in the result.
      * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToAdd  the amount of the unit to add to the result, may be negative
-     * @param unit  the unit of the period to add, not null
-     * @return an {@code OffsetDateTime} based on this date-time with the specified period added, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to add, not null
+     * @return an {@code OffsetDateTime} based on this date-time with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public OffsetDateTime plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             return with(dateTime.plus(amountToAdd, unit), offset);
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
@@ -1211,41 +1245,47 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date-time with the specified period subtracted.
+     * Returns a copy of this date-time with the specified amount subtracted.
      * <p>
-     * This method returns a new date-time based on this time with the specified period subtracted.
-     * The subtractor is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
-     * The offset is not part of the calculation and will be unchanged in the result.
+     * This returns an {@code OffsetDateTime}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Period} or {@link Duration} but may be
+     * any other type implementing the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return an {@code OffsetDateTime} based on this date-time with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public OffsetDateTime minus(TemporalSubtractor subtractor) {
-        return (OffsetDateTime) subtractor.subtractFrom(this);
+    public OffsetDateTime minus(TemporalAmount amountToSubtract) {
+        return (OffsetDateTime) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * Returns a copy of this date-time with the specified period subtracted.
+     * Returns a copy of this date-time with the specified amount subtracted.
      * <p>
-     * This method returns a new date-time based on this date-time with the specified period subtracted.
-     * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
-     * The offset is not part of the calculation and will be unchanged in the result.
+     * This returns an {@code OffsetDateTime}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
-     * @param unit  the unit of the period to subtract, not null
-     * @return an {@code OffsetDateTime} based on this date-time with the specified period subtracted, not null
+     * @param unit  the unit of the amount to subtract, not null
+     * @return an {@code OffsetDateTime} based on this date-time with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) {
@@ -1413,14 +1453,22 @@
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) getDate().getChrono();
+        if (query == Queries.offset() || query == Queries.zone()) {
+            return (R) getOffset();
+        } else if (query == Queries.zoneId()) {
+            return null;
+        } else if (query == Queries.localDate()) {
+            return (R) toLocalDate();
+        } else if (query == Queries.localTime()) {
+            return (R) toLocalTime();
+        } else if (query == Queries.chronology()) {
+            return (R) IsoChronology.INSTANCE;
         } else if (query == Queries.precision()) {
             return (R) NANOS;
-        } else if (query == Queries.offset() || query == Queries.zone()) {
-            return (R) getOffset();
         }
-        return Temporal.super.query(query);
+        // inline TemporalAccessor.super.query(query) as an optimization
+        // non-JDK classes are not permitted to make this optimization
+        return query.queryFrom(this);
     }
 
     /**
@@ -1453,8 +1501,8 @@
     public Temporal adjustInto(Temporal temporal) {
         return temporal
                 .with(OFFSET_SECONDS, getOffset().getTotalSeconds())
-                .with(EPOCH_DAY, getDate().toEpochDay())
-                .with(NANO_OF_DAY, getTime().toNanoOfDay());
+                .with(EPOCH_DAY, toLocalDate().toEpochDay())
+                .with(NANO_OF_DAY, toLocalTime().toNanoOfDay());
     }
 
     /**
@@ -1476,14 +1524,15 @@
      * For example, the period in months between 2012-06-15T00:00Z and 2012-08-14T23:59Z
      * will only be one month as it is one minute short of two months.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, MONTHS);   // this method
-     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MONTHS);
+     *   amount = MONTHS.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
@@ -1516,22 +1565,21 @@
             end = end.withOffsetSameInstant(offset);
             return dateTime.periodUntil(end.dateTime, unit);
         }
-        return unit.between(this, endDateTime).getAmount();
+        return unit.between(this, endDateTime);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a zoned date-time formed from the instant represented by this
-     * date-time and the specified zone ID.
+     * Combines this date-time with a time-zone to create a {@code ZonedDateTime}
+     * ensuring that the result has the same instant.
      * <p>
+     * This returns a {@code ZonedDateTime} formed from this date-time and the specified time-zone.
      * This conversion will ignore the visible local date-time and use the underlying instant instead.
      * This avoids any problems with local time-line gaps or overlaps.
      * The result might have different values for fields such as hour, minute an even day.
      * <p>
      * To attempt to retain the values of the fields, use {@link #atZoneSimilarLocal(ZoneId)}.
      * To use the offset as the zone ID, use {@link #toZonedDateTime()}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param zone  the time-zone to use, not null
      * @return the zoned date-time formed from this date-time, not null
@@ -1541,7 +1589,11 @@
     }
 
     /**
-     * Returns a zoned date-time formed from this date-time and the specified zone ID.
+     * Combines this date-time with a time-zone to create a {@code ZonedDateTime}
+     * trying to keep the same local date and time.
+     * <p>
+     * This returns a {@code ZonedDateTime} formed from this date-time and the specified time-zone.
+     * Where possible, the result will have the same local date-time as this object.
      * <p>
      * Time-zone rules, such as daylight savings, mean that not every time on the
      * local time-line exists. If the local date-time is in a gap or overlap according to
@@ -1556,8 +1608,6 @@
      * To create a zoned date-time at the same instant irrespective of the local time-line,
      * use {@link #atZoneSameInstant(ZoneId)}.
      * To use the offset as the zone ID, use {@link #toZonedDateTime()}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param zone  the time-zone to use, not null
      * @return the zoned date-time formed from this date and the earliest valid time for the zone, not null
@@ -1568,17 +1618,6 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Converts this date-time to an {@code OffsetDate}.
-     * <p>
-     * This returns an offset date with the same local date and offset.
-     *
-     * @return an OffsetDate representing the date and offset, not null
-     */
-    public OffsetDate toOffsetDate() {
-        return OffsetDate.of(dateTime.getDate(), offset);
-    }
-
-    /**
      * Converts this date-time to an {@code OffsetTime}.
      * <p>
      * This returns an offset time with the same local time and offset.
@@ -1586,7 +1625,7 @@
      * @return an OffsetTime representing the time and offset, not null
      */
     public OffsetTime toOffsetTime() {
-        return OffsetTime.of(dateTime.getTime(), offset);
+        return OffsetTime.of(dateTime.toLocalTime(), offset);
     }
 
     /**
@@ -1606,6 +1645,9 @@
 
     /**
      * Converts this date-time to an {@code Instant}.
+     * <p>
+     * This returns an {@code Instant} representing the same point on the
+     * time-line as this date-time.
      *
      * @return an {@code Instant} representing the same instant, not null
      */
@@ -1653,13 +1695,13 @@
     @Override
     public int compareTo(OffsetDateTime other) {
         if (getOffset().equals(other.getOffset())) {
-            return getDateTime().compareTo(other.getDateTime());
+            return toLocalDateTime().compareTo(other.toLocalDateTime());
         }
         int cmp = Long.compare(toEpochSecond(), other.toEpochSecond());
         if (cmp == 0) {
-            cmp = getTime().getNano() - other.getTime().getNano();
+            cmp = toLocalTime().getNano() - other.toLocalTime().getNano();
             if (cmp == 0) {
-                cmp = getDateTime().compareTo(other.getDateTime());
+                cmp = toLocalDateTime().compareTo(other.toLocalDateTime());
             }
         }
         return cmp;
@@ -1680,7 +1722,7 @@
         long thisEpochSec = toEpochSecond();
         long otherEpochSec = other.toEpochSecond();
         return thisEpochSec > otherEpochSec ||
-            (thisEpochSec == otherEpochSec && getTime().getNano() > other.getTime().getNano());
+            (thisEpochSec == otherEpochSec && toLocalTime().getNano() > other.toLocalTime().getNano());
     }
 
     /**
@@ -1697,7 +1739,7 @@
         long thisEpochSec = toEpochSecond();
         long otherEpochSec = other.toEpochSecond();
         return thisEpochSec < otherEpochSec ||
-            (thisEpochSec == otherEpochSec && getTime().getNano() < other.getTime().getNano());
+            (thisEpochSec == otherEpochSec && toLocalTime().getNano() < other.toLocalTime().getNano());
     }
 
     /**
@@ -1712,7 +1754,7 @@
      */
     public boolean isEqual(OffsetDateTime other) {
         return toEpochSecond() == other.toEpochSecond() &&
-                getTime().getNano() == other.getTime().getNano();
+                toLocalTime().getNano() == other.toLocalTime().getNano();
     }
 
     //-----------------------------------------------------------------------
@@ -1774,7 +1816,7 @@
      * Outputs this date-time as a {@code String} using the formatter.
      * <p>
      * This date-time will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted date-time string, not null
@@ -1782,7 +1824,7 @@
      */
     public String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
     //-----------------------------------------------------------------------
@@ -1790,7 +1832,7 @@
      * Writes the object using a
      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
      * <pre>
-     *  out.writeByte(3);  // identifies this as a OffsetDateTime
+     *  out.writeByte(10);  // identifies this as a OffsetDateTime
      *  out.writeObject(dateTime);
      *  out.writeObject(offset);
      * </pre>
diff --git a/jdk/src/share/classes/java/time/temporal/OffsetTime.java b/jdk/src/share/classes/java/time/OffsetTime.java
similarity index 84%
rename from jdk/src/share/classes/java/time/temporal/OffsetTime.java
rename to jdk/src/share/classes/java/time/OffsetTime.java
index 390b1b1..ed60dee 100644
--- a/jdk/src/share/classes/java/time/temporal/OffsetTime.java
+++ b/jdk/src/share/classes/java/time/OffsetTime.java
@@ -59,14 +59,14 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time;
 
+import static java.time.LocalTime.NANOS_PER_HOUR;
+import static java.time.LocalTime.NANOS_PER_MINUTE;
+import static java.time.LocalTime.NANOS_PER_SECOND;
+import static java.time.LocalTime.SECONDS_PER_DAY;
 import static java.time.temporal.ChronoField.NANO_OF_DAY;
 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
-import static java.time.temporal.ChronoLocalDateTimeImpl.NANOS_PER_HOUR;
-import static java.time.temporal.ChronoLocalDateTimeImpl.NANOS_PER_MINUTE;
-import static java.time.temporal.ChronoLocalDateTimeImpl.NANOS_PER_SECOND;
-import static java.time.temporal.ChronoLocalDateTimeImpl.SECONDS_PER_DAY;
 import static java.time.temporal.ChronoUnit.NANOS;
 
 import java.io.IOException;
@@ -75,16 +75,19 @@
 import java.io.ObjectOutput;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
 import java.time.zone.ZoneRules;
 import java.util.Objects;
 
@@ -202,6 +205,29 @@
         return new OffsetTime(time, offset);
     }
 
+    /**
+     * Obtains an instance of {@code OffsetTime} from an hour, minute, second and nanosecond.
+     * <p>
+     * This creates an offset time with the four specified fields.
+     * <p>
+     * This method exists primarily for writing test cases.
+     * Non test-code will typically use other methods to create an offset time.
+     * {@code LocalTime} has two additional convenience variants of the
+     * equivalent factory method taking fewer arguments.
+     * They are not provided here to reduce the footprint of the API.
+     *
+     * @param hour  the hour-of-day to represent, from 0 to 23
+     * @param minute  the minute-of-hour to represent, from 0 to 59
+     * @param second  the second-of-minute to represent, from 0 to 59
+     * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
+     * @param offset  the zone offset, not null
+     * @return the offset time, not null
+     * @throws DateTimeException if the value of any field is out of range
+     */
+    public static OffsetTime of(int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset) {
+        return new OffsetTime(LocalTime.of(hour, minute, second, nanoOfSecond), offset);
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code OffsetTime} from an {@code Instant} and zone ID.
@@ -223,12 +249,9 @@
         Objects.requireNonNull(zone, "zone");
         ZoneRules rules = zone.getRules();
         ZoneOffset offset = rules.getOffset(instant);
-        long secsOfDay = instant.getEpochSecond() % SECONDS_PER_DAY;
-        secsOfDay = (secsOfDay + offset.getTotalSeconds()) % SECONDS_PER_DAY;
-        if (secsOfDay < 0) {
-            secsOfDay += SECONDS_PER_DAY;
-        }
-        LocalTime time = LocalTime.ofSecondOfDay(secsOfDay, instant.getNano());
+        long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
+        int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY);
+        LocalTime time = LocalTime.ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
         return new OffsetTime(time, offset);
     }
 
@@ -236,10 +259,14 @@
     /**
      * Obtains an instance of {@code OffsetTime} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code OffsetTime}.
+     * This obtains an offset time based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code OffsetTime}.
      * <p>
-     * The conversion extracts and combines {@code LocalTime} and {@code ZoneOffset}.
+     * The conversion extracts and combines the {@code ZoneOffset} and the
+     * {@code LocalTime} from the temporal object.
+     * Implementations are permitted to perform optimizations such as accessing
+     * those fields that are equivalent to the relevant objects.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
      * allowing it to be used in queries via method reference, {@code OffsetTime::from}.
@@ -266,14 +293,14 @@
      * Obtains an instance of {@code OffsetTime} from a text string such as {@code 10:15:30+01:00}.
      * <p>
      * The string must represent a valid time and is parsed using
-     * {@link java.time.format.DateTimeFormatters#isoOffsetTime()}.
+     * {@link java.time.format.DateTimeFormatter#ISO_OFFSET_TIME}.
      *
      * @param text  the text to parse such as "10:15:30+01:00", not null
      * @return the parsed local time, not null
      * @throws DateTimeParseException if the text cannot be parsed
      */
     public static OffsetTime parse(CharSequence text) {
-        return parse(text, DateTimeFormatters.isoOffsetTime());
+        return parse(text, DateTimeFormatter.ISO_OFFSET_TIME);
     }
 
     /**
@@ -347,7 +374,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -359,7 +386,7 @@
         if (field instanceof ChronoField) {
             return ((ChronoField) field).isTimeField() || field == OFFSET_SECONDS;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -376,7 +403,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -392,7 +419,7 @@
             }
             return time.range(field);
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     /**
@@ -410,7 +437,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -437,7 +464,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -450,11 +477,11 @@
     public long getLong(TemporalField field) {
         if (field instanceof ChronoField) {
             if (field == OFFSET_SECONDS) {
-                return getOffset().getTotalSeconds();
+                return offset.getTotalSeconds();
             }
             return time.getLong(field);
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -526,7 +553,7 @@
      *
      * @return the time part of this date-time, not null
      */
-    public LocalTime getTime() {
+    public LocalTime toLocalTime() {
         return time;
     }
 
@@ -571,7 +598,7 @@
     /**
      * Returns an adjusted copy of this time.
      * <p>
-     * This returns a new {@code OffsetTime}, based on this one, with the time adjusted.
+     * This returns an {@code OffsetTime}, based on this one, with the time adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -612,7 +639,7 @@
     /**
      * Returns a copy of this time with the specified field set to a new value.
      * <p>
-     * This returns a new {@code OffsetTime}, based on this one, with the value
+     * This returns an {@code OffsetTime}, based on this one, with the value
      * for the specified field changed.
      * This can be used to change any supported field, such as the hour, minute or second.
      * If it is not possible to set the value, because the field is not supported or for
@@ -631,7 +658,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -652,7 +679,7 @@
             }
             return with(time.with(field, newValue), offset);
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
@@ -725,8 +752,10 @@
      * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
      * will set the second-of-minute and nano-of-second field to zero.
      * <p>
-     * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time
-     * units with an exact duration can be used, other units throw an exception.
+     * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+     * that divides into the length of a standard day without remainder.
+     * This includes all supplied time units on {@link ChronoUnit} and
+     * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
      * <p>
      * The offset does not affect the calculation and will be the same in the result.
      * <p>
@@ -742,49 +771,60 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date with the specified period added.
+     * Returns a copy of this time with the specified amount added.
      * <p>
-     * This method returns a new time based on this time with the specified period added.
-     * The adder is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
-     * The offset is not part of the calculation and will be unchanged in the result.
+     * This returns an {@code OffsetTime}, based on this one, with the specified amount added.
+     * The amount is typically {@link Duration} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return an {@code OffsetTime} based on this time with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public OffsetTime plus(TemporalAdder adder) {
-        return (OffsetTime) adder.addTo(this);
+    public OffsetTime plus(TemporalAmount amountToAdd) {
+        return (OffsetTime) amountToAdd.addTo(this);
     }
 
     /**
-     * Returns a copy of this time with the specified period added.
+     * Returns a copy of this time with the specified amount added.
      * <p>
-     * This method returns a new time based on this time with the specified period added.
-     * This can be used to add any period that is defined by a unit, for example to add hours, minutes or seconds.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns an {@code OffsetTime}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented by
+     * {@link LocalTime#plus(long, TemporalUnit)}.
      * The offset is not part of the calculation and will be unchanged in the result.
      * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToAdd  the amount of the unit to add to the result, may be negative
-     * @param unit  the unit of the period to add, not null
-     * @return an {@code OffsetTime} based on this time with the specified period added, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to add, not null
+     * @return an {@code OffsetTime} based on this time with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public OffsetTime plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             return with(time.plus(amountToAdd, unit), offset);
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
@@ -850,42 +890,47 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this time with the specified period subtracted.
+     * Returns a copy of this time with the specified amount subtracted.
      * <p>
-     * This method returns a new time based on this time with the specified period subtracted.
-     * The subtractor is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
-     * The offset is not part of the calculation and will be unchanged in the result.
+     * This returns an {@code OffsetTime}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Duration} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return an {@code OffsetTime} based on this time with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public OffsetTime minus(TemporalSubtractor subtractor) {
-        return (OffsetTime) subtractor.subtractFrom(this);
+    public OffsetTime minus(TemporalAmount amountToSubtract) {
+        return (OffsetTime) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * Returns a copy of this time with the specified period subtracted.
+     * Returns a copy of this time with the specified amount subtracted.
      * <p>
-     * This method returns a new time based on this time with the specified period subtracted.
-     * This can be used to subtract any period that is defined by a unit, for example to subtract hours, minutes or seconds.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
-     * The offset is not part of the calculation and will be unchanged in the result.
+     * This returns an {@code OffsetTime}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
-     * @param unit  the unit of the period to subtract, not null
-     * @return an {@code OffsetTime} based on this time with the specified period subtracted, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to subtract, not null
+     * @return an {@code OffsetTime} based on this time with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public OffsetTime minus(long amountToSubtract, TemporalUnit unit) {
@@ -975,12 +1020,18 @@
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.precision()) {
+        if (query == Queries.offset() || query == Queries.zone()) {
+            return (R) offset;
+        } else if (query == Queries.zoneId() | query == Queries.chronology() || query == Queries.localDate()) {
+            return null;
+        } else if (query == Queries.localTime()) {
+            return (R) time;
+        } else if (query == Queries.precision()) {
             return (R) NANOS;
-        } else if (query == Queries.offset() || query == Queries.zone()) {
-            return (R) getOffset();
         }
-        return Temporal.super.query(query);
+        // inline TemporalAccessor.super.query(query) as an optimization
+        // non-JDK classes are not permitted to make this optimization
+        return query.queryFrom(this);
     }
 
     /**
@@ -1012,7 +1063,7 @@
     @Override
     public Temporal adjustInto(Temporal temporal) {
         return temporal
-                .with(OFFSET_SECONDS, getOffset().getTotalSeconds())
+                .with(OFFSET_SECONDS, offset.getTotalSeconds())
                 .with(NANO_OF_DAY, time.toNanoOfDay());
     }
 
@@ -1035,14 +1086,15 @@
      * For example, the period in hours between 11:30Z and 13:29Z will only
      * be one hour as it is one minute short of two hours.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, HOURS);   // this method
-     *   dateTime.plus(HOURS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MINUTES);
+     *   amount = MINUTES.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
@@ -1082,17 +1134,15 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.between(this, endTime).getAmount();
+        return unit.between(this, endTime);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns an offset date-time formed from this time at the specified date.
+     * Combines this date with a time to create an {@code OffsetDateTime}.
      * <p>
-     * This combines this time with the specified date to form an {@code OffsetDateTime}.
+     * This returns an {@code OffsetDateTime} formed from this time and the specified date.
      * All possible combinations of date and time are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param date  the date to combine with, not null
      * @return the offset date-time formed from this time and the specified date, not null
@@ -1261,7 +1311,7 @@
      * Outputs this time as a {@code String} using the formatter.
      * <p>
      * This time will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted time string, not null
@@ -1269,7 +1319,7 @@
      */
     public String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
     // -----------------------------------------------------------------------
@@ -1277,7 +1327,7 @@
      * Writes the object using a
      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
      * <pre>
-     *  out.writeByte(2);  // identifies this as a OffsetDateTime
+     *  out.writeByte(9);  // identifies this as a OffsetDateTime
      *  out.writeObject(time);
      *  out.writeObject(offset);
      * </pre>
diff --git a/jdk/src/share/classes/java/time/Period.java b/jdk/src/share/classes/java/time/Period.java
index a04aab6a..88efaec 100644
--- a/jdk/src/share/classes/java/time/Period.java
+++ b/jdk/src/share/classes/java/time/Period.java
@@ -61,68 +61,89 @@
  */
 package java.time;
 
-import static java.time.LocalTime.NANOS_PER_DAY;
-import static java.time.LocalTime.NANOS_PER_HOUR;
-import static java.time.LocalTime.NANOS_PER_MINUTE;
-import static java.time.LocalTime.NANOS_PER_SECOND;
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.EPOCH_MONTH;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.NANO_OF_DAY;
-import static java.time.temporal.ChronoField.YEAR;
 import static java.time.temporal.ChronoUnit.DAYS;
 import static java.time.temporal.ChronoUnit.MONTHS;
-import static java.time.temporal.ChronoUnit.NANOS;
 import static java.time.temporal.ChronoUnit.YEARS;
 
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
 import java.io.Serializable;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Chronology;
 import java.time.format.DateTimeParseException;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
-import java.time.temporal.TemporalSubtractor;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalUnit;
 import java.time.temporal.ValueRange;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
- * A period of time, measured using the most common units, such as '3 Months, 4 Days and 7 Hours'.
+ * A date-based amount of time, such as '2 years, 3 months and 4 days'.
  * <p>
- * A {@code Period} represents an amount of time measured in terms of the most commonly used units:
- * <p><ul>
- * <li>{@link ChronoUnit#YEARS YEARS}</li>
- * <li>{@link ChronoUnit#MONTHS MONTHS}</li>
- * <li>{@link ChronoUnit#DAYS DAYS}</li>
- * <li>time units with an {@linkplain TemporalUnit#isDurationEstimated() exact duration}</li>
- * </ul><p>
- * The period may be used with any calendar system with the exception is methods with an "ISO" suffix.
- * The meaning of a "year" or a "month" is only applied when the object is added to a date.
+ * This class models a quantity or amount of time in terms of years, months and days.
+ * See {@link Duration} for the time-based equivalent to this class.
+ * <p>
+ * Durations and period differ in their treatment of daylight savings time
+ * when added to {@link ZonedDateTime}. A {@code Duration} will add an exact
+ * number of seconds, thus a duration of one day is always exactly 24 hours.
+ * By contrast, a {@code Period} will add a conceptual day, trying to maintain
+ * the local time.
+ * <p>
+ * For example, consider adding a period of one day and a duration of one day to
+ * 18:00 on the evening before a daylight savings gap. The {@code Period} will add
+ * the conceptual day and result in a {@code ZonedDateTime} at 18:00 the following day.
+ * By contrast, the {@code Duration} will add exactly 24 hours, resulting in a
+ * {@code ZonedDateTime} at 19:00 the following day (assuming a one hour DST gap).
+ * <p>
+ * The supported units of a period are {@link ChronoUnit#YEARS YEARS},
+ * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
+ * All three fields are always present, but may be set to zero.
+ * <p>
+ * The period may be used with any calendar system.
+ * The meaning of a "year" or "month" is only applied when the object is added to a date.
  * <p>
  * The period is modeled as a directed amount of time, meaning that individual parts of the
  * period may be negative.
+ * <p>
+ * The months and years fields may be {@linkplain #normalized() normalized}.
+ * The normalization assumes a 12 month year, so is not appropriate for all calendar systems.
  *
  * <h3>Specification for implementors</h3>
  * This class is immutable and thread-safe.
- * The maximum number of hours that can be stored is about 2.5 million, limited by storing
- * a single {@code long} nanoseconds for all time units internally.
  *
  * @since 1.8
  */
 public final class Period
-        implements TemporalAdder, TemporalSubtractor, Serializable {
-    // maximum hours is 2,562,047
+        implements TemporalAmount, Serializable {
 
     /**
      * A constant for a period of zero.
      */
-    public static final Period ZERO = new Period(0, 0, 0, 0);
+    public static final Period ZERO = new Period(0, 0, 0);
     /**
      * Serialization version.
      */
-    private static final long serialVersionUID = -8290556941213247973L;
+    private static final long serialVersionUID = -3587258372562876L;
+    /**
+     * The pattern for parsing.
+     */
+    private final static Pattern PATTERN =
+            Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE);
+    /**
+     * The set of supported units.
+     */
+    private final static List<TemporalUnit> SUPPORTED_UNITS =
+            Collections.unmodifiableList(Arrays.<TemporalUnit>asList(YEARS, MONTHS, DAYS));
 
     /**
      * The number of years.
@@ -136,209 +157,60 @@
      * The number of days.
      */
     private final int days;
-    /**
-     * The number of nanoseconds.
-     */
-    private final long nanos;
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains a {@code Period} from date-based and time-based fields.
+     * Obtains a {@code Period} representing a number of years.
      * <p>
-     * This creates an instance based on years, months, days, hours, minutes and seconds.
-     * Within a period, the time fields are always normalized.
+     * The resulting period will have the specified years.
+     * The months and days units will be zero.
      *
-     * @param years  the amount of years, may be negative
-     * @param months  the amount of months, may be negative
-     * @param days  the amount of days, may be negative
-     * @param hours  the amount of hours, may be negative
-     * @param minutes  the amount of minutes, may be negative
-     * @param seconds  the amount of seconds, may be negative
-     * @return the period, not null
+     * @param years  the number of years, positive or negative
+     * @return the period of years, not null
      */
-    public static Period of(int years, int months, int days, int hours, int minutes, int seconds) {
-        return of(years, months, days, hours, minutes, seconds, 0);
+    public static Period ofYears(int years) {
+        return create(years, 0, 0);
     }
 
     /**
-     * Obtains a {@code Period} from date-based and time-based fields.
+     * Obtains a {@code Period} representing a number of months.
      * <p>
-     * This creates an instance based on years, months, days, hours, minutes, seconds and nanoseconds.
-     * Within a period, the time fields are always normalized.
+     * The resulting period will have the specified months.
+     * The years and days units will be zero.
      *
-     * @param years  the amount of years, may be negative
-     * @param months  the amount of months, may be negative
-     * @param days  the amount of days, may be negative
-     * @param hours  the amount of hours, may be negative
-     * @param minutes  the amount of minutes, may be negative
-     * @param seconds  the amount of seconds, may be negative
-     * @param nanos  the amount of nanos, may be negative
-     * @return the period, not null
+     * @param months  the number of months, positive or negative
+     * @return the period of months, not null
      */
-    public static Period of(int years, int months, int days, int hours, int minutes, int seconds, long nanos) {
-        if ((years | months | days | hours | minutes | seconds | nanos) == 0) {
-            return ZERO;
-        }
-        long totSecs = Math.addExact(hours * 3600L, minutes * 60L) + seconds;
-        long totNanos = Math.addExact(Math.multiplyExact(totSecs, 1_000_000_000L), nanos);
-        return create(years, months, days, totNanos);
+    public static Period ofMonths(int months) {
+        return create(0, months, 0);
+    }
+
+    /**
+     * Obtains a {@code Period} representing a number of days.
+     * <p>
+     * The resulting period will have the specified days.
+     * The years and months units will be zero.
+     *
+     * @param days  the number of days, positive or negative
+     * @return the period of days, not null
+     */
+    public static Period ofDays(int days) {
+        return create(0, 0, days);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains a {@code Period} from date-based fields.
+     * Obtains a {@code Period} representing a number of years, months and days.
      * <p>
      * This creates an instance based on years, months and days.
      *
      * @param years  the amount of years, may be negative
      * @param months  the amount of months, may be negative
      * @param days  the amount of days, may be negative
-     * @return the period, not null
+     * @return the period of years, months and days, not null
      */
-    public static Period ofDate(int years, int months, int days) {
-        return of(years, months, days, 0, 0, 0, 0);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains a {@code Period} from time-based fields.
-     * <p>
-     * This creates an instance based on hours, minutes and seconds.
-     * Within a period, the time fields are always normalized.
-     *
-     * @param hours  the amount of hours, may be negative
-     * @param minutes  the amount of minutes, may be negative
-     * @param seconds  the amount of seconds, may be negative
-     * @return the period, not null
-     */
-    public static Period ofTime(int hours, int minutes, int seconds) {
-        return of(0, 0, 0, hours, minutes, seconds, 0);
-    }
-
-    /**
-     * Obtains a {@code Period} from time-based fields.
-     * <p>
-     * This creates an instance based on hours, minutes, seconds and nanoseconds.
-     * Within a period, the time fields are always normalized.
-     *
-     * @param hours  the amount of hours, may be negative
-     * @param minutes  the amount of minutes, may be negative
-     * @param seconds  the amount of seconds, may be negative
-     * @param nanos  the amount of nanos, may be negative
-     * @return the period, not null
-     */
-    public static Period ofTime(int hours, int minutes, int seconds, long nanos) {
-        return of(0, 0, 0, hours, minutes, seconds, nanos);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains an instance of {@code Period} from a period in the specified unit.
-     * <p>
-     * The parameters represent the two parts of a phrase like '6 Days'. For example:
-     * <pre>
-     *  Period.of(3, SECONDS);
-     *  Period.of(5, YEARS);
-     * </pre>
-     * The specified unit must be one of the supported units from {@link ChronoUnit},
-     * {@code YEARS}, {@code MONTHS} or {@code DAYS} or be a time unit with an
-     * {@linkplain TemporalUnit#isDurationEstimated() exact duration}.
-     * Other units throw an exception.
-     *
-     * @param amount  the amount of the period, measured in terms of the unit, positive or negative
-     * @param unit  the unit that the period is measured in, must have an exact duration, not null
-     * @return the period, not null
-     * @throws DateTimeException if the period unit is invalid
-     * @throws ArithmeticException if a numeric overflow occurs
-     */
-    public static Period of(long amount, TemporalUnit unit) {
-        return ZERO.plus(amount, unit);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains a {@code Period} from a {@code Duration}.
-     * <p>
-     * This converts the duration to a period.
-     * Within a period, the time fields are always normalized.
-     * The years, months and days fields will be zero.
-     * <p>
-     * To populate the days field, call {@link #normalizedHoursToDays()} on the created period.
-     *
-     * @param duration  the duration to convert, not null
-     * @return the period, not null
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    public static Period of(Duration duration) {
-        Objects.requireNonNull(duration, "duration");
-        if (duration.isZero()) {
-            return ZERO;
-        }
-        return new Period(0, 0, 0, duration.toNanos());
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a {@code Period} consisting of the number of years, months, days,
-     * hours, minutes, seconds, and nanoseconds between two {@code TemporalAccessor} instances.
-     * <p>
-     * The start date is included, but the end date is not. Only whole years count.
-     * For example, from {@code 2010-01-15} to {@code 2011-03-18} is one year, two months and three days.
-     * <p>
-     * This method examines the {@link ChronoField fields} {@code YEAR}, {@code MONTH_OF_YEAR},
-     * {@code DAY_OF_MONTH} and {@code NANO_OF_DAY}
-     * The difference between each of the fields is calculated independently from the others.
-     * At least one of the four fields must be present.
-     * <p>
-     * The four units are typically retained without normalization.
-     * However, years and months are normalized if the range of months is fixed, as it is with ISO.
-     * <p>
-     * The result of this method can be a negative period if the end is before the start.
-     * The negative sign can be different in each of the four major units.
-     *
-     * @param start  the start date, inclusive, not null
-     * @param end  the end date, exclusive, not null
-     * @return the period between the date-times, not null
-     * @throws DateTimeException if the two date-times do have similar available fields
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    public static Period between(TemporalAccessor start, TemporalAccessor end) {
-        if (Chrono.from(start).equals(Chrono.from(end)) == false) {
-            throw new DateTimeException("Unable to calculate period as date-times have different chronologies");
-        }
-        int years = 0;
-        int months = 0;
-        int days = 0;
-        long nanos = 0;
-        boolean valid = false;
-        if (start.isSupported(YEAR)) {
-            years = Math.toIntExact(Math.subtractExact(end.getLong(YEAR), start.getLong(YEAR)));
-            valid = true;
-        }
-        if (start.isSupported(MONTH_OF_YEAR)) {
-            months = Math.toIntExact(Math.subtractExact(end.getLong(MONTH_OF_YEAR), start.getLong(MONTH_OF_YEAR)));
-            ValueRange startRange = Chrono.from(start).range(MONTH_OF_YEAR);
-            ValueRange endRange = Chrono.from(end).range(MONTH_OF_YEAR);
-            if (startRange.isFixed() && startRange.isIntValue() && startRange.equals(endRange)) {
-                int monthCount = (int) (startRange.getMaximum() - startRange.getMinimum() + 1);
-                long totMonths = ((long) months) + years * monthCount;
-                months = (int) (totMonths % monthCount);
-                years = Math.toIntExact(totMonths / monthCount);
-            }
-            valid = true;
-        }
-        if (start.isSupported(DAY_OF_MONTH)) {
-            days = Math.toIntExact(Math.subtractExact(end.getLong(DAY_OF_MONTH), start.getLong(DAY_OF_MONTH)));
-            valid = true;
-        }
-        if (start.isSupported(NANO_OF_DAY)) {
-            nanos = Math.subtractExact(end.getLong(NANO_OF_DAY), start.getLong(NANO_OF_DAY));
-            valid = true;
-        }
-        if (valid == false) {
-            throw new DateTimeException("Unable to calculate period as date-times do not have any valid fields");
-        }
-        return create(years, months, days, nanos);
+    public static Period of(int years, int months, int days) {
+        return create(years, months, days);
     }
 
     //-----------------------------------------------------------------------
@@ -358,74 +230,70 @@
      *
      * @param startDate  the start date, inclusive, not null
      * @param endDate  the end date, exclusive, not null
-     * @return the period between the dates, not null
-     * @throws ArithmeticException if numeric overflow occurs
+     * @return the period between this date and the end date, not null
+     * @see ChronoLocalDate#periodUntil(ChronoLocalDate)
      */
-    public static Period betweenISO(LocalDate startDate, LocalDate endDate) {
-        long startMonth = startDate.getLong(EPOCH_MONTH);
-        long endMonth = endDate.getLong(EPOCH_MONTH);
-        long totalMonths = endMonth - startMonth;  // safe
-        int days = endDate.getDayOfMonth() - startDate.getDayOfMonth();
-        if (totalMonths > 0 && days < 0) {
-            totalMonths--;
-            LocalDate calcDate = startDate.plusMonths(totalMonths);
-            days = (int) (endDate.toEpochDay() - calcDate.toEpochDay());  // safe
-        } else if (totalMonths < 0 && days > 0) {
-            totalMonths++;
-            days -= endDate.lengthOfMonth();
-        }
-        long years = totalMonths / 12;  // safe
-        int months = (int) (totalMonths % 12);  // safe
-        return ofDate(Math.toIntExact(years), months, days);
+    public static Period between(LocalDate startDate, LocalDate endDate) {
+        return startDate.periodUntil(endDate);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains a {@code Period} consisting of the number of hours, minutes,
-     * seconds and nanoseconds between two times.
-     * <p>
-     * The start time is included, but the end time is not.
-     * The period is calculated from the difference between the nano-of-day values
-     * of the two times. For example, from {@code 13:45:00} to {@code 14:50:30.123456789}
-     * is {@code P1H5M30.123456789S}.
-     * <p>
-     * The result of this method can be a negative period if the end is before the start.
-     *
-     * @param startTime  the start time, inclusive, not null
-     * @param endTime  the end time, exclusive, not null
-     * @return the period between the times, not null
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    public static Period betweenISO(LocalTime startTime, LocalTime endTime) {
-        return create(0, 0, 0, endTime.toNanoOfDay() - startTime.toNanoOfDay());
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains a {@code Period} from a text string such as {@code PnYnMnDTnHnMn.nS}.
+     * Obtains a {@code Period} from a text string such as {@code PnYnMnD}.
      * <p>
      * This will parse the string produced by {@code toString()} which is
-     * a subset of the ISO-8601 period format {@code PnYnMnDTnHnMn.nS}.
+     * based on the ISO-8601 period format {@code PnYnMnD}.
      * <p>
-     * The string consists of a series of numbers with a suffix identifying their meaning.
-     * The values, and suffixes, must be in the sequence year, month, day, hour, minute, second.
-     * Any of the number/suffix pairs may be omitted providing at least one is present.
-     * If the period is zero, the value is normally represented as {@code PT0S}.
-     * The numbers must consist of ASCII digits.
-     * Any of the numbers may be negative. Negative zero is not accepted.
-     * The number of nanoseconds is expressed as an optional fraction of the seconds.
-     * There must be at least one digit before any decimal point.
-     * There must be between 1 and 9 inclusive digits after any decimal point.
-     * The letters will all be accepted in upper or lower case.
-     * The decimal point may be either a dot or a comma.
+     * The string starts with an optional sign, denoted by the ASCII negative
+     * or positive symbol. If negative, the whole period is negated.
+     * The ASCII letter "P" is next in upper or lower case.
+     * There are then three sections, each consisting of a number and a suffix.
+     * At least one of the three sections must be present.
+     * The sections have suffixes in ASCII of "Y", "M" and "D" for
+     * years, months and days, accepted in upper or lower case.
+     * The suffixes must occur in order.
+     * The number part of each section must consist of ASCII digits.
+     * The number may be prefixed by the ASCII negative or positive symbol.
+     * The number must parse to an {@code int}.
+     * <p>
+     * The leading plus/minus sign, and negative values for other units are
+     * not part of the ISO-8601 standard.
      *
      * @param text  the text to parse, not null
      * @return the parsed period, not null
      * @throws DateTimeParseException if the text cannot be parsed to a period
      */
-    public static Period parse(final CharSequence text) {
+    public static Period parse(CharSequence text) {
         Objects.requireNonNull(text, "text");
-        return new PeriodParser(text).parse();
+        Matcher matcher = PATTERN.matcher(text);
+        if (matcher.matches()) {
+            int negate = ("-".equals(matcher.group(1)) ? -1 : 1);
+            String yearMatch = matcher.group(2);
+            String monthMatch = matcher.group(3);
+            String dayMatch = matcher.group(4);
+            if (yearMatch != null || monthMatch != null || dayMatch != null) {
+                try {
+                    return create(parseNumber(text, yearMatch, negate),
+                            parseNumber(text, monthMatch, negate),
+                            parseNumber(text, dayMatch, negate));
+                } catch (NumberFormatException ex) {
+                    throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex);
+                }
+            }
+        }
+        throw new DateTimeParseException("Text cannot be parsed to a Period", text, 0);
+    }
+
+    private static int parseNumber(CharSequence text, String str, int negate) {
+        if (str == null) {
+            return 0;
+        }
+        int val = Integer.parseInt(str);
+        try {
+            return Math.multiplyExact(val, negate);
+        } catch (ArithmeticException ex) {
+            throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex);
+        }
     }
 
     //-----------------------------------------------------------------------
@@ -435,13 +303,12 @@
      * @param years  the amount
      * @param months  the amount
      * @param days  the amount
-     * @param nanos  the amount
      */
-    private static Period create(int years, int months, int days, long nanos) {
-        if ((years | months | days | nanos) == 0) {
+    private static Period create(int years, int months, int days) {
+        if ((years | months | days) == 0) {
             return ZERO;
         }
-        return new Period(years, months, days, nanos);
+        return new Period(years, months, days);
     }
 
     /**
@@ -450,30 +317,61 @@
      * @param years  the amount
      * @param months  the amount
      * @param days  the amount
-     * @param nanos  the amount
      */
-    private Period(int years, int months, int days, long nanos) {
+    private Period(int years, int months, int days) {
         this.years = years;
         this.months = months;
         this.days = days;
-        this.nanos = nanos;
-    }
-
-    /**
-     * Resolves singletons.
-     *
-     * @return the resolved instance
-     */
-    private Object readResolve() {
-        if ((years | months | days | nanos) == 0) {
-            return ZERO;
-        }
-        return this;
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Checks if this period is zero-length.
+     * Gets the value of the requested unit.
+     * <p>
+     * This returns a value for each of the three supported units,
+     * {@link ChronoUnit#YEARS YEARS}, {@link ChronoUnit#MONTHS MONTHS} and
+     * {@link ChronoUnit#DAYS DAYS}.
+     * All other units throw an exception.
+     *
+     * @param unit the {@code TemporalUnit} for which to return the value
+     * @return the long value of the unit
+     * @throws DateTimeException if the unit is not supported
+     */
+    @Override
+    public long get(TemporalUnit unit) {
+        if (unit == ChronoUnit.YEARS) {
+            return getYears();
+        } else if (unit == ChronoUnit.MONTHS) {
+            return getMonths();
+        } else if (unit == ChronoUnit.DAYS) {
+            return getDays();
+        } else {
+            throw new DateTimeException("Unsupported unit: " + unit.getName());
+        }
+    }
+
+    /**
+     * Gets the set of units supported by this period.
+     * <p>
+     * The supported units are {@link ChronoUnit#YEARS YEARS},
+     * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
+     * They are returned in the order years, months, days.
+     * <p>
+     * This set can be used in conjunction with {@link #get(TemporalUnit)}
+     * to access the entire state of the period.
+     *
+     * @return a list containing the years, months and days units, not null
+     */
+    @Override
+    public List<TemporalUnit> getUnits() {
+        return SUPPORTED_UNITS;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Checks if all three units of this period are zero.
+     * <p>
+     * A zero period has the value zero for the years, months and days units.
      *
      * @return true if this period is zero-length
      */
@@ -482,22 +380,27 @@
     }
 
     /**
-     * Checks if this period is fully positive, excluding zero.
+     * Checks if any of the three units of this period are negative.
      * <p>
-     * This checks whether all the amounts in the period are positive,
-     * defined as greater than zero.
+     * This checks whether the years, months or days units are less than zero.
      *
-     * @return true if this period is fully positive excluding zero
+     * @return true if any unit of this period is negative
      */
-    public boolean isPositive() {
-        return ((years | months | days | nanos) > 0);
+    public boolean isNegative() {
+        return years < 0 || months < 0 || days < 0;
     }
 
     //-----------------------------------------------------------------------
     /**
      * Gets the amount of years of this period.
+     * <p>
+     * This returns the years unit.
+     * <p>
+     * The months unit is not normalized with the years unit.
+     * This means that a period of "15 months" is different to a period
+     * of "1 year and 3 months".
      *
-     * @return the amount of years of this period
+     * @return the amount of years of this period, may be negative
      */
     public int getYears() {
         return years;
@@ -505,8 +408,14 @@
 
     /**
      * Gets the amount of months of this period.
+     * <p>
+     * This returns the months unit.
+     * <p>
+     * The months unit is not normalized with the years unit.
+     * This means that a period of "15 months" is different to a period
+     * of "1 year and 3 months".
      *
-     * @return the amount of months of this period
+     * @return the amount of months of this period, may be negative
      */
     public int getMonths() {
         return months;
@@ -514,141 +423,76 @@
 
     /**
      * Gets the amount of days of this period.
+     * <p>
+     * This returns the days unit.
      *
-     * @return the amount of days of this period
+     * @return the amount of days of this period, may be negative
      */
     public int getDays() {
         return days;
     }
 
-    /**
-     * Gets the amount of hours of this period.
-     * <p>
-     * Within a period, the time fields are always normalized.
-     *
-     * @return the amount of hours of this period
-     */
-    public int getHours() {
-        return (int) (nanos / NANOS_PER_HOUR);
-    }
-
-    /**
-     * Gets the amount of minutes within an hour of this period.
-     * <p>
-     * Within a period, the time fields are always normalized.
-     *
-     * @return the amount of minutes within an hour of this period
-     */
-    public int getMinutes() {
-        return (int) ((nanos / NANOS_PER_MINUTE) % 60);
-    }
-
-    /**
-     * Gets the amount of seconds within a minute of this period.
-     * <p>
-     * Within a period, the time fields are always normalized.
-     *
-     * @return the amount of seconds within a minute of this period
-     */
-    public int getSeconds() {
-        return (int) ((nanos / NANOS_PER_SECOND) % 60);
-    }
-
-    /**
-     * Gets the amount of nanoseconds within a second of this period.
-     * <p>
-     * Within a period, the time fields are always normalized.
-     *
-     * @return the amount of nanoseconds within a second of this period
-     */
-    public int getNanos() {
-        return (int) (nanos % NANOS_PER_SECOND);  // safe from overflow
-    }
-
-    /**
-     * Gets the total amount of the time units of this period, measured in nanoseconds.
-     * <p>
-     * Within a period, the time fields are always normalized.
-     *
-     * @return the total amount of time unit nanoseconds of this period
-     */
-    public long getTimeNanos() {
-        return nanos;
-    }
-
     //-----------------------------------------------------------------------
     /**
      * Returns a copy of this period with the specified amount of years.
      * <p>
-     * This method will only affect the years field.
-     * All other units are unaffected.
+     * This sets the amount of the years unit in a copy of this period.
+     * The months and days units are unaffected.
+     * <p>
+     * The months unit is not normalized with the years unit.
+     * This means that a period of "15 months" is different to a period
+     * of "1 year and 3 months".
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param years  the years to represent
+     * @param years  the years to represent, may be negative
      * @return a {@code Period} based on this period with the requested years, not null
      */
     public Period withYears(int years) {
         if (years == this.years) {
             return this;
         }
-        return create(years, months, days, nanos);
+        return create(years, months, days);
     }
 
     /**
      * Returns a copy of this period with the specified amount of months.
      * <p>
-     * This method will only affect the months field.
-     * All other units are unaffected.
+     * This sets the amount of the months unit in a copy of this period.
+     * The years and days units are unaffected.
+     * <p>
+     * The months unit is not normalized with the years unit.
+     * This means that a period of "15 months" is different to a period
+     * of "1 year and 3 months".
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param months  the months to represent
+     * @param months  the months to represent, may be negative
      * @return a {@code Period} based on this period with the requested months, not null
      */
     public Period withMonths(int months) {
         if (months == this.months) {
             return this;
         }
-        return create(years, months, days, nanos);
+        return create(years, months, days);
     }
 
     /**
      * Returns a copy of this period with the specified amount of days.
      * <p>
-     * This method will only affect the days field.
-     * All other units are unaffected.
+     * This sets the amount of the days unit in a copy of this period.
+     * The years and months units are unaffected.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param days  the days to represent
+     * @param days  the days to represent, may be negative
      * @return a {@code Period} based on this period with the requested days, not null
      */
     public Period withDays(int days) {
         if (days == this.days) {
             return this;
         }
-        return create(years, months, days, nanos);
-    }
-
-    /**
-     * Returns a copy of this period with the specified total amount of time units
-     * expressed in nanoseconds.
-     * <p>
-     * Within a period, the time fields are always normalized.
-     * This method will affect all the time units - hours, minutes, seconds and nanos.
-     * The date units are unaffected.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param nanos  the nanoseconds to represent
-     * @return a {@code Period} based on this period with the requested nanoseconds, not null
-     */
-    public Period withTimeNanos(long nanos) {
-        if (nanos == this.nanos) {
-            return this;
-        }
-        return create(years, months, days, nanos);
+        return create(years, months, days);
     }
 
     //-----------------------------------------------------------------------
@@ -658,89 +502,80 @@
      * This operates separately on the years, months, days and the normalized time.
      * There is no further normalization beyond the normalized time.
      * <p>
+     * For example, "1 year, 6 months and 3 days" plus "2 years, 2 months and 2 days"
+     * returns "3 years, 8 months and 5 days".
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param other  the period to add, not null
+     * @param amountToAdd  the period to add, not null
      * @return a {@code Period} based on this period with the requested period added, not null
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public Period plus(Period other) {
+    public Period plus(Period amountToAdd) {
         return create(
-                Math.addExact(years, other.years),
-                Math.addExact(months, other.months),
-                Math.addExact(days, other.days),
-                Math.addExact(nanos, other.nanos));
+                Math.addExact(years, amountToAdd.years),
+                Math.addExact(months, amountToAdd.months),
+                Math.addExact(days, amountToAdd.days));
     }
 
     /**
-     * Returns a copy of this period with the specified period added.
+     * Returns a copy of this period with the specified years added.
      * <p>
-     * The specified unit must be one of the supported units from {@link ChronoUnit},
-     * {@code YEARS}, {@code MONTHS} or {@code DAYS} or be a time unit with an
-     * {@linkplain TemporalUnit#isDurationEstimated() exact duration}.
-     * Other units throw an exception.
+     * This adds the amount to the years unit in a copy of this period.
+     * The months and days units are unaffected.
+     * For example, "1 year, 6 months and 3 days" plus 2 years returns "3 years, 6 months and 3 days".
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param amount  the amount to add, positive or negative
-     * @param unit  the unit that the amount is expressed in, not null
-     * @return a {@code Period} based on this period with the requested amount added, not null
+     * @param yearsToAdd  the years to add, positive or negative
+     * @return a {@code Period} based on this period with the specified years added, not null
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public Period plus(long amount, TemporalUnit unit) {
-        Objects.requireNonNull(unit, "unit");
-        if (unit instanceof ChronoUnit) {
-            if (unit == YEARS || unit == MONTHS || unit == DAYS || unit.isDurationEstimated() == false) {
-                if (amount == 0) {
-                    return this;
-                }
-                switch((ChronoUnit) unit) {
-                    case NANOS: return plusNanos(amount);
-                    case MICROS: return plusNanos(Math.multiplyExact(amount, 1000L));
-                    case MILLIS: return plusNanos(Math.multiplyExact(amount, 1000_000L));
-                    case SECONDS: return plusSeconds(amount);
-                    case MINUTES: return plusMinutes(amount);
-                    case HOURS: return plusHours(amount);
-                    case HALF_DAYS: return plusNanos(Math.multiplyExact(amount, 12 * NANOS_PER_HOUR));
-                    case DAYS: return plusDays(amount);
-                    case MONTHS: return plusMonths(amount);
-                    case YEARS: return plusYears(amount);
-                    default: throw new DateTimeException("Unsupported unit: " + unit.getName());
-                }
-            }
+    public Period plusYears(long yearsToAdd) {
+        if (yearsToAdd == 0) {
+            return this;
         }
-        if (unit.isDurationEstimated()) {
-            throw new DateTimeException("Unsupported unit: " + unit.getName());
+        return create(Math.toIntExact(Math.addExact(years, yearsToAdd)), months, days);
+    }
+
+    /**
+     * Returns a copy of this period with the specified months added.
+     * <p>
+     * This adds the amount to the months unit in a copy of this period.
+     * The years and days units are unaffected.
+     * For example, "1 year, 6 months and 3 days" plus 2 months returns "1 year, 8 months and 3 days".
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param monthsToAdd  the months to add, positive or negative
+     * @return a {@code Period} based on this period with the specified months added, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Period plusMonths(long monthsToAdd) {
+        if (monthsToAdd == 0) {
+            return this;
         }
-        return plusNanos(Duration.of(amount, unit).toNanos());
+        return create(years, Math.toIntExact(Math.addExact(months, monthsToAdd)), days);
     }
 
-    public Period plusYears(long amount) {
-        return create(Math.toIntExact(Math.addExact(years, amount)), months, days, nanos);
-    }
-
-    public Period plusMonths(long amount) {
-        return create(years, Math.toIntExact(Math.addExact(months, amount)), days, nanos);
-    }
-
-    public Period plusDays(long amount) {
-        return create(years, months, Math.toIntExact(Math.addExact(days, amount)), nanos);
-    }
-
-    public Period plusHours(long amount) {
-        return plusNanos(Math.multiplyExact(amount, NANOS_PER_HOUR));
-    }
-
-    public Period plusMinutes(long amount) {
-        return plusNanos(Math.multiplyExact(amount, NANOS_PER_MINUTE));
-    }
-
-    public Period plusSeconds(long amount) {
-        return plusNanos(Math.multiplyExact(amount, NANOS_PER_SECOND));
-    }
-
-    public Period plusNanos(long amount) {
-        return create(years, months, days, Math.addExact(nanos,  amount));
+    /**
+     * Returns a copy of this period with the specified days added.
+     * <p>
+     * This adds the amount to the days unit in a copy of this period.
+     * The years and months units are unaffected.
+     * For example, "1 year, 6 months and 3 days" plus 2 days returns "1 year, 6 months and 5 days".
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param daysToAdd  the days to add, positive or negative
+     * @return a {@code Period} based on this period with the specified days added, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Period plusDays(long daysToAdd) {
+        if (daysToAdd == 0) {
+            return this;
+        }
+        return create(years, months, Math.toIntExact(Math.addExact(days, daysToAdd)));
     }
 
     //-----------------------------------------------------------------------
@@ -750,65 +585,71 @@
      * This operates separately on the years, months, days and the normalized time.
      * There is no further normalization beyond the normalized time.
      * <p>
+     * For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days"
+     * returns "-1 years, 4 months and 1 day".
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param other  the period to subtract, not null
+     * @param amountToSubtract  the period to subtract, not null
      * @return a {@code Period} based on this period with the requested period subtracted, not null
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public Period minus(Period other) {
+    public Period minus(Period amountToSubtract) {
         return create(
-                Math.subtractExact(years, other.years),
-                Math.subtractExact(months, other.months),
-                Math.subtractExact(days, other.days),
-                Math.subtractExact(nanos, other.nanos));
+                Math.subtractExact(years, amountToSubtract.years),
+                Math.subtractExact(months, amountToSubtract.months),
+                Math.subtractExact(days, amountToSubtract.days));
     }
 
     /**
-     * Returns a copy of this period with the specified period subtracted.
+     * Returns a copy of this period with the specified years subtracted.
      * <p>
-     * The specified unit must be one of the supported units from {@link ChronoUnit},
-     * {@code YEARS}, {@code MONTHS} or {@code DAYS} or be a time unit with an
-     * {@linkplain TemporalUnit#isDurationEstimated() exact duration}.
-     * Other units throw an exception.
+     * This subtracts the amount from the years unit in a copy of this period.
+     * The months and days units are unaffected.
+     * For example, "1 year, 6 months and 3 days" minus 2 years returns "-1 years, 6 months and 3 days".
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param amount  the amount to subtract, positive or negative
-     * @param unit  the unit that the amount is expressed in, not null
-     * @return a {@code Period} based on this period with the requested amount subtracted, not null
+     * @param yearsToSubtract  the years to subtract, positive or negative
+     * @return a {@code Period} based on this period with the specified years subtracted, not null
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public Period minus(long amount, TemporalUnit unit) {
-        return (amount == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amount, unit));
+    public Period minusYears(long yearsToSubtract) {
+        return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract));
     }
 
-    public Period minusYears(long amount) {
-        return (amount == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-amount));
+    /**
+     * Returns a copy of this period with the specified months subtracted.
+     * <p>
+     * This subtracts the amount from the months unit in a copy of this period.
+     * The years and days units are unaffected.
+     * For example, "1 year, 6 months and 3 days" minus 2 months returns "1 year, 4 months and 3 days".
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param monthsToSubtract  the years to subtract, positive or negative
+     * @return a {@code Period} based on this period with the specified months subtracted, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Period minusMonths(long monthsToSubtract) {
+        return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract));
     }
 
-    public Period minusMonths(long amount) {
-        return (amount == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-amount));
-    }
-
-    public Period minusDays(long amount) {
-        return (amount == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-amount));
-    }
-
-    public Period minusHours(long amount) {
-        return (amount == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-amount));
-    }
-
-    public Period minusMinutes(long amount) {
-        return (amount == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-amount));
-    }
-
-    public Period minusSeconds(long amount) {
-        return (amount == Long.MIN_VALUE ? plusSeconds(Long.MAX_VALUE).plusSeconds(1) : plusSeconds(-amount));
-    }
-
-    public Period minusNanos(long amount) {
-        return (amount == Long.MIN_VALUE ? plusNanos(Long.MAX_VALUE).plusNanos(1) : plusNanos(-amount));
+    /**
+     * Returns a copy of this period with the specified days subtracted.
+     * <p>
+     * This subtracts the amount from the days unit in a copy of this period.
+     * The years and months units are unaffected.
+     * For example, "1 year, 6 months and 3 days" minus 2 days returns "1 year, 6 months and 1 day".
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param daysToSubtract  the months to subtract, positive or negative
+     * @return a {@code Period} based on this period with the specified days subtracted, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Period minusDays(long daysToSubtract) {
+        return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
     }
 
     //-----------------------------------------------------------------------
@@ -816,8 +657,11 @@
      * Returns a new instance with each element in this period multiplied
      * by the specified scalar.
      * <p>
-     * This simply multiplies each field, years, months, days and normalized time,
-     * by the scalar. No normalization is performed.
+     * This returns a period with each of the years, months and days units
+     * individually multiplied.
+     * For example, a period of "2 years, -3 months and 4 days" multiplied by
+     * 3 will return "6 years, -9 months and 12 days".
+     * No normalization is performed.
      *
      * @param scalar  the scalar to multiply by, not null
      * @return a {@code Period} based on this period with the amounts multiplied by the scalar, not null
@@ -830,15 +674,21 @@
         return create(
                 Math.multiplyExact(years, scalar),
                 Math.multiplyExact(months, scalar),
-                Math.multiplyExact(days, scalar),
-                Math.multiplyExact(nanos, scalar));
+                Math.multiplyExact(days, scalar));
     }
 
     /**
      * Returns a new instance with each amount in this period negated.
+     * <p>
+     * This returns a period with each of the years, months and days units
+     * individually negated.
+     * For example, a period of "2 years, -3 months and 4 days" will be
+     * negated to "-2 years, 3 months and -4 days".
+     * No normalization is performed.
      *
      * @return a {@code Period} based on this period with the amounts negated, not null
-     * @throws ArithmeticException if numeric overflow occurs
+     * @throws ArithmeticException if numeric overflow occurs, which only happens if
+     *  one of the units has the value {@code Long.MIN_VALUE}
      */
     public Period negated() {
         return multipliedBy(-1);
@@ -846,104 +696,49 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this period with the days and hours normalized using a 24 hour day.
+     * Returns a copy of this period with the years and months normalized
+     * using a 12 month year.
      * <p>
-     * This normalizes the days and hours units, leaving years and months unchanged.
-     * The hours unit is adjusted to have an absolute value less than 23,
-     * with the days unit being adjusted to compensate.
-     * For example, a period of {@code P1DT27H} will be normalized to {@code P2DT3H}.
-     * <p>
-     * The sign of the days and hours units will be the same after normalization.
-     * For example, a period of {@code P1DT-51H} will be normalized to {@code P-1DT-3H}.
-     * Since all time units are always normalized, if the hours units changes sign then
-     * other time units will also be affected.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @return a {@code Period} based on this period with excess hours normalized to days, not null
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    public Period normalizedHoursToDays() {
-        // logic uses if statements to normalize signs to avoid unnecessary overflows
-        long totalDays = (nanos / NANOS_PER_DAY) + days;  // no overflow
-        long splitNanos = nanos % NANOS_PER_DAY;
-        if (totalDays > 0 && splitNanos < 0) {
-            splitNanos += NANOS_PER_DAY;
-            totalDays--;
-        } else if (totalDays < 0 && splitNanos > 0) {
-            splitNanos -= NANOS_PER_DAY;
-            totalDays++;
-        }
-        if (totalDays == days && splitNanos == nanos) {
-            return this;
-        }
-        return create(years, months, Math.toIntExact(totalDays), splitNanos);
-    }
-
-    /**
-     * Returns a copy of this period with any days converted to hours using a 24 hour day.
-     * <p>
-     * The days unit is reduced to zero, with the hours unit increased by 24 times the
-     * days unit to compensate. Other units are unaffected.
-     * For example, a period of {@code P2DT4H} will be normalized to {@code PT52H}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @return a {@code Period} based on this period with days normalized to hours, not null
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    public Period normalizedDaysToHours() {
-        if (days == 0) {
-            return this;
-        }
-        return create(years, months, 0, Math.addExact(Math.multiplyExact(days, NANOS_PER_DAY), nanos));
-    }
-
-    /**
-     * Returns a copy of this period with the years and months normalized using a 12 month year.
-     * <p>
-     * This normalizes the years and months units, leaving other units unchanged.
+     * This normalizes the years and months units, leaving the days unit unchanged.
      * The months unit is adjusted to have an absolute value less than 11,
-     * with the years unit being adjusted to compensate.
-     * For example, a period of {@code P1Y15M} will be normalized to {@code P2Y3M}.
+     * with the years unit being adjusted to compensate. For example, a period of
+     * "1 Year and 15 months" will be normalized to "2 years and 3 months".
      * <p>
      * The sign of the years and months units will be the same after normalization.
-     * For example, a period of {@code P1Y-25M} will be normalized to {@code P-1Y-1M}.
+     * For example, a period of "1 year and -25 months" will be normalized to
+     * "-1 year and -1 month".
      * <p>
-     * This normalization uses a 12 month year it is not valid for all calendar systems.
+     * This normalization uses a 12 month year which is not valid for all calendar systems.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @return a {@code Period} based on this period with years and months normalized, not null
+     * @return a {@code Period} based on this period with excess months normalized to years, not null
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public Period normalizedMonthsISO() {
-        long totalMonths = years * 12L + months;  // no overflow
+    public Period normalized() {
+        long totalMonths = toTotalMonths();
         long splitYears = totalMonths / 12;
         int splitMonths = (int) (totalMonths % 12);  // no overflow
         if (splitYears == years && splitMonths == months) {
             return this;
         }
-        return create(Math.toIntExact(splitYears), splitMonths, days, nanos);
+        return create(Math.toIntExact(splitYears), splitMonths, days);
     }
 
-    //-------------------------------------------------------------------------
     /**
-     * Converts this period to one that only has date units.
+     * Gets the total number of months in this period using a 12 month year.
      * <p>
-     * The resulting period will have the same years, months and days as this period
-     * but the time units will all be zero. No normalization occurs in the calculation.
-     * For example, a period of {@code P1Y3MT12H} will be converted to {@code P1Y3M}.
+     * This returns the total number of months in the period by multiplying the
+     * number of years by 12 and adding the number of months.
+     * <p>
+     * This uses a 12 month year which is not valid for all calendar systems.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @return a {@code Period} based on this period with the time units set to zero, not null
+     * @return the total number of months in the period, may be negative
      */
-    public Period toDateOnly() {
-        if (nanos == 0) {
-            return this;
-        }
-        return create(years, months, days, 0);
+    public long toTotalMonths() {
+        return years * 12L + months;  // no overflow
     }
 
     //-------------------------------------------------------------------------
@@ -954,14 +749,14 @@
      * with this period added.
      * <p>
      * In most cases, it is clearer to reverse the calling pattern by using
-     * {@link Temporal#plus(TemporalAdder)}.
+     * {@link Temporal#plus(TemporalAmount)}.
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
      *   dateTime = thisPeriod.addTo(dateTime);
      *   dateTime = dateTime.plus(thisPeriod);
      * </pre>
      * <p>
-     * The calculation will add the years, then months, then days, then nanos.
+     * The calculation will add the years, then months, then days.
      * Only non-zero amounts will be added.
      * If the date-time has a calendar system with a fixed number of months in a
      * year, then the years and months will be combined before being added.
@@ -977,10 +772,9 @@
     public Temporal addTo(Temporal temporal) {
         Objects.requireNonNull(temporal, "temporal");
         if ((years | months) != 0) {
-            ValueRange startRange = Chrono.from(temporal).range(MONTH_OF_YEAR);
-            if (startRange.isFixed() && startRange.isIntValue()) {
-                long monthCount = startRange.getMaximum() - startRange.getMinimum() + 1;
-                temporal = temporal.plus(years * monthCount + months, MONTHS);
+            long monthRange = monthRange(temporal);
+            if (monthRange >= 0) {
+                temporal = temporal.plus(years * monthRange + months, MONTHS);
             } else {
                 if (years != 0) {
                     temporal = temporal.plus(years, YEARS);
@@ -993,9 +787,6 @@
         if (days != 0) {
             temporal = temporal.plus(days, DAYS);
         }
-        if (nanos != 0) {
-            temporal = temporal.plus(nanos, NANOS);
-        }
         return temporal;
     }
 
@@ -1006,14 +797,14 @@
      * with this period subtracted.
      * <p>
      * In most cases, it is clearer to reverse the calling pattern by using
-     * {@link Temporal#minus(TemporalSubtractor)}.
+     * {@link Temporal#minus(TemporalAmount)}.
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
      *   dateTime = thisPeriod.subtractFrom(dateTime);
      *   dateTime = dateTime.minus(thisPeriod);
      * </pre>
      * <p>
-     * The calculation will subtract the years, then months, then days, then nanos.
+     * The calculation will subtract the years, then months, then days.
      * Only non-zero amounts will be subtracted.
      * If the date-time has a calendar system with a fixed number of months in a
      * year, then the years and months will be combined before being subtracted.
@@ -1029,10 +820,9 @@
     public Temporal subtractFrom(Temporal temporal) {
         Objects.requireNonNull(temporal, "temporal");
         if ((years | months) != 0) {
-            ValueRange startRange = Chrono.from(temporal).range(MONTH_OF_YEAR);
-            if (startRange.isFixed() && startRange.isIntValue()) {
-                long monthCount = startRange.getMaximum() - startRange.getMinimum() + 1;
-                temporal = temporal.minus(years * monthCount + months, MONTHS);
+            long monthRange = monthRange(temporal);
+            if (monthRange >= 0) {
+                temporal = temporal.minus(years * monthRange + months, MONTHS);
             } else {
                 if (years != 0) {
                     temporal = temporal.minus(years, YEARS);
@@ -1045,48 +835,21 @@
         if (days != 0) {
             temporal = temporal.minus(days, DAYS);
         }
-        if (nanos != 0) {
-            temporal = temporal.minus(nanos, NANOS);
-        }
         return temporal;
     }
 
-    //-----------------------------------------------------------------------
     /**
-     * Converts this period to one that only has time units.
-     * <p>
-     * The resulting period will have the same time units as this period
-     * but the date units will all be zero. No normalization occurs in the calculation.
-     * For example, a period of {@code P1Y3MT12H} will be converted to {@code PT12H}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
+     * Calculates the range of months based on the temporal.
      *
-     * @return a {@code Period} based on this period with the date units set to zero, not null
+     * @param temporal  the temporal, not null
+     * @return the month range, negative if not fixed range
      */
-    public Period toTimeOnly() {
-        if ((years | months | days) == 0) {
-            return this;
+    private long monthRange(Temporal temporal) {
+        ValueRange startRange = Chronology.from(temporal).range(MONTH_OF_YEAR);
+        if (startRange.isFixed() && startRange.isIntValue()) {
+            return startRange.getMaximum() - startRange.getMinimum() + 1;
         }
-        return create(0, 0, 0, nanos);
-    }
-
-    //-------------------------------------------------------------------------
-    /**
-     * Calculates the duration of this period.
-     * <p>
-     * The calculation uses the hours, minutes, seconds and nanoseconds fields.
-     * If years, months or days are present an exception is thrown.
-     * See {@link #toTimeOnly()} for a way to remove the date units and
-     * {@link #normalizedDaysToHours()} for a way to convert days to hours.
-     *
-     * @return a {@code Duration} equivalent to this period, not null
-     * @throws DateTimeException if the period cannot be converted as it contains years, months or days
-     */
-    public Duration toDuration() {
-        if ((years | months | days) != 0) {
-            throw new DateTimeException("Unable to convert period to duration as years/months/days are present: " + this);
-        }
-        return Duration.ofNanos(nanos);
+        return -1;
     }
 
     //-----------------------------------------------------------------------
@@ -1094,7 +857,9 @@
      * Checks if this period is equal to another period.
      * <p>
      * The comparison is based on the amounts held in the period.
-     * To be equal, the years, months, days and normalized time fields must be equal.
+     * To be equal, the years, months and days units must be individually equal.
+     * Note that this means that a period of "15 Months" is not equal to a period
+     * of "1 Year and 3 Months".
      *
      * @param obj  the object to check, null returns false
      * @return true if this is equal to the other period
@@ -1106,8 +871,9 @@
         }
         if (obj instanceof Period) {
             Period other = (Period) obj;
-            return years == other.years && months == other.months &&
-                    days == other.days && nanos == other.nanos;
+            return years == other.years &&
+                    months == other.months &&
+                    days == other.days;
         }
         return false;
     }
@@ -1119,25 +885,22 @@
      */
     @Override
     public int hashCode() {
-        // ordered such that overflow from one field doesn't immediately affect the next field
-        return ((years << 27) | (years >>> 5)) ^
-                ((days << 21) | (days >>> 11)) ^
-                ((months << 17) | (months >>> 15)) ^
-                ((int) (nanos ^ (nanos >>> 32)));
+        return years + Integer.rotateLeft(months, 8) + Integer.rotateLeft(days, 16);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Outputs this period as a {@code String}, such as {@code P6Y3M1DT12H}.
+     * Outputs this period as a {@code String}, such as {@code P6Y3M1D}.
      * <p>
      * The output will be in the ISO-8601 period format.
+     * A zero period will be represented as zero days, 'P0D'.
      *
      * @return a string representation of this period, not null
      */
     @Override
     public String toString() {
         if (this == ZERO) {
-            return "PT0S";
+            return "P0D";
         } else {
             StringBuilder buf = new StringBuilder();
             buf.append('P');
@@ -1150,38 +913,47 @@
             if (days != 0) {
                 buf.append(days).append('D');
             }
-            if (nanos != 0) {
-                buf.append('T');
-                if (getHours() != 0) {
-                    buf.append(getHours()).append('H');
-                }
-                if (getMinutes() != 0) {
-                    buf.append(getMinutes()).append('M');
-                }
-                int secondPart = getSeconds();
-                int nanoPart = getNanos();
-                int secsNanosOr = secondPart | nanoPart;
-                if (secsNanosOr != 0) {  // if either non-zero
-                    if ((secsNanosOr & Integer.MIN_VALUE) != 0) {  // if either less than zero
-                        buf.append('-');
-                        secondPart = Math.abs(secondPart);
-                        nanoPart = Math.abs(nanoPart);
-                    }
-                    buf.append(secondPart);
-                    if (nanoPart != 0) {
-                        int dotPos = buf.length();
-                        nanoPart += 1000_000_000;
-                        while (nanoPart % 10 == 0) {
-                            nanoPart /= 10;
-                        }
-                        buf.append(nanoPart);
-                        buf.setCharAt(dotPos, '.');
-                    }
-                    buf.append('S');
-                }
-            }
             return buf.toString();
         }
     }
 
+    //-----------------------------------------------------------------------
+    /**
+     * Writes the object using a
+     * <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>.
+     * <pre>
+     *  out.writeByte(14);  // identifies this as a Period
+     *  out.writeInt(years);
+     *  out.writeInt(months);
+     *  out.writeInt(seconds);
+     * </pre>
+     *
+     * @return the instance of {@code Ser}, not null
+     */
+    private Object writeReplace() {
+        return new Ser(Ser.PERIOD_TYPE, this);
+    }
+
+    /**
+     * Defend against malicious streams.
+     * @return never
+     * @throws java.io.InvalidObjectException always
+     */
+    private Object readResolve() throws ObjectStreamException {
+        throw new InvalidObjectException("Deserialization via serialization delegate");
+    }
+
+    void writeExternal(DataOutput out) throws IOException {
+        out.writeInt(years);
+        out.writeInt(months);
+        out.writeInt(days);
+    }
+
+    static Period readExternal(DataInput in) throws IOException {
+        int years = in.readInt();
+        int months = in.readInt();
+        int days = in.readInt();
+        return Period.of(years, months, days);
+    }
+
 }
diff --git a/jdk/src/share/classes/java/time/PeriodParser.java b/jdk/src/share/classes/java/time/PeriodParser.java
deleted file mode 100644
index 6a424ae..0000000
--- a/jdk/src/share/classes/java/time/PeriodParser.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time;
-
-import java.time.format.DateTimeParseException;
-
-/**
- * A period parser that creates an instance of {@code Period} from a string.
- * This parses the ISO-8601 period format {@code PnYnMnDTnHnMn.nS}.
- * <p>
- * This class is mutable and intended for use by a single thread.
- *
- * @since 1.8
- */
-final class PeriodParser {
-
-    /**
-     * Used to validate the correct sequence of tokens.
-     */
-    private static final String TOKEN_SEQUENCE = "PYMDTHMS";
-    /**
-     * The standard string representing a zero period.
-     */
-    private static final String ZERO = "PT0S";
-
-    /**
-     * The number of years.
-     */
-    private int years;
-    /**
-     * The number of months.
-     */
-    private int months;
-    /**
-     * The number of days.
-     */
-    private int days;
-    /**
-     * The number of hours.
-     */
-    private int hours;
-    /**
-     * The number of minutes.
-     */
-    private int minutes;
-    /**
-     * The number of seconds.
-     */
-    private int seconds;
-    /**
-     * The number of nanoseconds.
-     */
-    private long nanos;
-    /**
-     * Whether the seconds were negative.
-     */
-    private boolean negativeSecs;
-    /**
-     * Parser position index.
-     */
-    private int index;
-    /**
-     * Original text.
-     */
-    private CharSequence text;
-
-    /**
-     * Constructor.
-     *
-     * @param text  the text to parse, not null
-     */
-    PeriodParser(CharSequence text) {
-        this.text = text;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Performs the parse.
-     * <p>
-     * This parses the text set in the constructor in the format PnYnMnDTnHnMn.nS.
-     *
-     * @return the created Period, not null
-     * @throws DateTimeParseException if the text cannot be parsed to a Period
-     */
-    Period parse() {
-        // force to upper case and coerce the comma to dot
-
-        String s = text.toString().toUpperCase().replace(',', '.');
-        // check for zero and skip parse
-        if (ZERO.equals(s)) {
-            return Period.ZERO;
-        }
-        if (s.length() < 3 || s.charAt(0) != 'P') {
-            throw new DateTimeParseException("Period could not be parsed: " + text, text, 0);
-        }
-        validateCharactersAndOrdering(s, text);
-
-        // strip off the leading P
-        String[] datetime = s.substring(1).split("T");
-        switch (datetime.length) {
-            case 2:
-                parseDate(datetime[0], 1);
-                parseTime(datetime[1], datetime[0].length() + 2);
-                break;
-            case 1:
-                parseDate(datetime[0], 1);
-                break;
-        }
-        return toPeriod();
-    }
-
-    private void parseDate(String s, int baseIndex) {
-        index = 0;
-        while (index < s.length()) {
-            String value = parseNumber(s);
-            if (index < s.length()) {
-                char c = s.charAt(index);
-                switch(c) {
-                    case 'Y': years = parseInt(value, baseIndex) ; break;
-                    case 'M': months = parseInt(value, baseIndex) ; break;
-                    case 'D': days = parseInt(value, baseIndex) ; break;
-                    default:
-                        throw new DateTimeParseException("Period could not be parsed, unrecognized letter '" +
-                                c + ": " + text, text, baseIndex + index);
-                }
-                index++;
-            }
-        }
-    }
-
-    private void parseTime(String s, int baseIndex) {
-        index = 0;
-        s = prepareTime(s, baseIndex);
-        while (index < s.length()) {
-            String value = parseNumber(s);
-            if (index < s.length()) {
-                char c = s.charAt(index);
-                switch(c) {
-                    case 'H': hours = parseInt(value, baseIndex) ; break;
-                    case 'M': minutes = parseInt(value, baseIndex) ; break;
-                    case 'S': seconds = parseInt(value, baseIndex) ; break;
-                    case 'N': nanos = parseNanos(value, baseIndex); break;
-                    default:
-                        throw new DateTimeParseException("Period could not be parsed, unrecognized letter '" +
-                                c + "': " + text, text, baseIndex + index);
-                }
-                index++;
-            }
-        }
-    }
-
-    private long parseNanos(String s, int baseIndex) {
-        if (s.length() > 9) {
-            throw new DateTimeParseException("Period could not be parsed, nanosecond range exceeded: " +
-                    text, text, baseIndex + index - s.length());
-        }
-        // pad to the right to create 10**9, then trim
-        return Long.parseLong((s + "000000000").substring(0, 9));
-    }
-
-    private String prepareTime(String s, int baseIndex) {
-        if (s.contains(".")) {
-            int i = s.indexOf(".") + 1;
-
-            // verify that the first character after the dot is a digit
-            if (Character.isDigit(s.charAt(i))) {
-                i++;
-            } else {
-                throw new DateTimeParseException("Period could not be parsed, invalid decimal number: " +
-                        text, text, baseIndex + index);
-            }
-
-            // verify that only digits follow the decimal point followed by an S
-            while (i < s.length()) {
-                // || !Character.isDigit(s.charAt(i))
-                char c = s.charAt(i);
-                if (Character.isDigit(c) || c == 'S') {
-                    i++;
-                } else {
-                    throw new DateTimeParseException("Period could not be parsed, invalid decimal number: " +
-                            text, text, baseIndex + index);
-                }
-            }
-            s = s.replace('S', 'N').replace('.', 'S');
-            if (s.contains("-0S")) {
-                negativeSecs = true;
-                s = s.replace("-0S", "0S");
-            }
-        }
-        return s;
-    }
-
-    private int parseInt(String s, int baseIndex) {
-        try {
-            int value = Integer.parseInt(s);
-            if (s.charAt(0) == '-' && value == 0) {
-                throw new DateTimeParseException("Period could not be parsed, invalid number '" +
-                        s + "': " + text, text, baseIndex + index - s.length());
-            }
-            return value;
-        } catch (NumberFormatException ex) {
-            throw new DateTimeParseException("Period could not be parsed, invalid number '" +
-                    s + "': " + text, text, baseIndex + index - s.length());
-        }
-    }
-
-    private String parseNumber(String s) {
-        int start = index;
-        while (index < s.length()) {
-            char c = s.charAt(index);
-            if ((c < '0' || c > '9') && c != '-') {
-                break;
-            }
-            index++;
-        }
-        return s.substring(start, index);
-    }
-
-    private void validateCharactersAndOrdering(String s, CharSequence text) {
-        char[] chars = s.toCharArray();
-        int tokenPos = 0;
-        boolean lastLetter = false;
-        for (int i = 0; i < chars.length; i++) {
-            if (tokenPos >= TOKEN_SEQUENCE.length()) {
-                throw new DateTimeParseException("Period could not be parsed, characters after last 'S': " + text, text, i);
-            }
-            char c = chars[i];
-            if ((c < '0' || c > '9') && c != '-' && c != '.') {
-                tokenPos = TOKEN_SEQUENCE.indexOf(c, tokenPos);
-                if (tokenPos < 0) {
-                    throw new DateTimeParseException("Period could not be parsed, invalid character '" + c + "': " + text, text, i);
-                }
-                tokenPos++;
-                lastLetter = true;
-            } else {
-                lastLetter = false;
-            }
-        }
-        if (lastLetter == false) {
-            throw new DateTimeParseException("Period could not be parsed, invalid last character: " + text, text, s.length() - 1);
-        }
-    }
-
-    private Period toPeriod() {
-        return Period.of(years, months, days, hours, minutes, seconds, negativeSecs || seconds < 0 ? -nanos : nanos);
-    }
-
-}
diff --git a/jdk/src/share/classes/java/time/Ser.java b/jdk/src/share/classes/java/time/Ser.java
index d665ccf..401a7cd 100644
--- a/jdk/src/share/classes/java/time/Ser.java
+++ b/jdk/src/share/classes/java/time/Ser.java
@@ -56,8 +56,6 @@
  */
 package java.time;
 
-import java.io.DataInput;
-import java.io.DataOutput;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.InvalidClassException;
@@ -103,6 +101,12 @@
     static final byte ZONE_DATE_TIME_TYPE = 6;
     static final byte ZONE_REGION_TYPE = 7;
     static final byte ZONE_OFFSET_TYPE = 8;
+    static final byte OFFSET_TIME_TYPE = 9;
+    static final byte OFFSET_DATE_TIME_TYPE = 10;
+    static final byte YEAR_TYPE = 11;
+    static final byte YEAR_MONTH_TYPE = 12;
+    static final byte MONTH_DAY_TYPE = 13;
+    static final byte PERIOD_TYPE = 14;
 
     /** The type being serialized. */
     private byte type;
@@ -132,11 +136,12 @@
      *
      * @param out  the data stream to write to, not null
      */
+    @Override
     public void writeExternal(ObjectOutput out) throws IOException {
         writeInternal(type, object, out);
     }
 
-    static void writeInternal(byte type, Object object, DataOutput out) throws IOException {
+    static void writeInternal(byte type, Object object, ObjectOutput out) throws IOException {
         out.writeByte(type);
         switch (type) {
             case DURATION_TYPE:
@@ -163,6 +168,24 @@
             case ZONE_DATE_TIME_TYPE:
                 ((ZonedDateTime) object).writeExternal(out);
                 break;
+            case OFFSET_TIME_TYPE:
+                ((OffsetTime) object).writeExternal(out);
+                break;
+            case OFFSET_DATE_TIME_TYPE:
+                ((OffsetDateTime) object).writeExternal(out);
+                break;
+            case YEAR_TYPE:
+                ((Year) object).writeExternal(out);
+                break;
+            case YEAR_MONTH_TYPE:
+                ((YearMonth) object).writeExternal(out);
+                break;
+            case MONTH_DAY_TYPE:
+                ((MonthDay) object).writeExternal(out);
+                break;
+            case PERIOD_TYPE:
+                ((Period) object).writeExternal(out);
+                break;
             default:
                 throw new InvalidClassException("Unknown serialized type");
         }
@@ -174,17 +197,17 @@
      *
      * @param in  the data to read, not null
      */
-    public void readExternal(ObjectInput in) throws IOException {
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         type = in.readByte();
         object = readInternal(type, in);
     }
 
-    static Object read(DataInput in) throws IOException {
+    static Object read(ObjectInput in) throws IOException, ClassNotFoundException {
         byte type = in.readByte();
         return readInternal(type, in);
     }
 
-    private static Object readInternal(byte type, DataInput in) throws IOException {
+    private static Object readInternal(byte type, ObjectInput in) throws IOException, ClassNotFoundException {
         switch (type) {
             case DURATION_TYPE: return Duration.readExternal(in);
             case INSTANT_TYPE: return Instant.readExternal(in);
@@ -194,6 +217,12 @@
             case ZONE_DATE_TIME_TYPE: return ZonedDateTime.readExternal(in);
             case ZONE_OFFSET_TYPE: return ZoneOffset.readExternal(in);
             case ZONE_REGION_TYPE: return ZoneRegion.readExternal(in);
+            case OFFSET_TIME_TYPE: return OffsetTime.readExternal(in);
+            case OFFSET_DATE_TIME_TYPE: return OffsetDateTime.readExternal(in);
+            case YEAR_TYPE: return Year.readExternal(in);
+            case YEAR_MONTH_TYPE: return YearMonth.readExternal(in);
+            case MONTH_DAY_TYPE: return MonthDay.readExternal(in);
+            case PERIOD_TYPE: return Period.readExternal(in);
             default:
                 throw new StreamCorruptedException("Unknown serialized type");
         }
diff --git a/jdk/src/share/classes/java/time/temporal/Year.java b/jdk/src/share/classes/java/time/Year.java
similarity index 81%
rename from jdk/src/share/classes/java/time/temporal/Year.java
rename to jdk/src/share/classes/java/time/Year.java
index f54acf7..017b74d 100644
--- a/jdk/src/share/classes/java/time/temporal/Year.java
+++ b/jdk/src/share/classes/java/time/Year.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time;
 
 import static java.time.temporal.ChronoField.ERA;
 import static java.time.temporal.ChronoField.YEAR;
@@ -72,15 +72,23 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.Month;
-import java.time.ZoneId;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
 import java.time.format.SignStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
 import java.util.Objects;
 
 /**
@@ -211,8 +219,9 @@
     /**
      * Obtains an instance of {@code Year} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code Year}.
+     * This obtains a year based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code Year}.
      * <p>
      * The conversion extracts the {@link ChronoField#YEAR year} field.
      * The extraction is only permitted if the temporal object has an ISO
@@ -230,7 +239,7 @@
             return (Year) temporal;
         }
         try {
-            if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) {
+            if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
                 temporal = LocalDate.from(temporal);
             }
             return of(temporal.get(YEAR));
@@ -324,8 +333,6 @@
      * {@link #get(TemporalField) get} methods will throw an exception.
      * <p>
      * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return valid
-     * values based on this date-time.
      * The supported fields are:
      * <ul>
      * <li>{@code YEAR_OF_ERA}
@@ -335,7 +342,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -347,7 +354,7 @@
         if (field instanceof ChronoField) {
             return field == YEAR || field == YEAR_OF_ERA || field == ERA;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -364,7 +371,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -394,7 +401,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -421,7 +428,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -440,7 +447,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -492,7 +499,7 @@
     /**
      * Returns an adjusted copy of this year.
      * <p>
-     * This returns a new {@code Year}, based on this one, with the year adjusted.
+     * This returns a {@code Year}, based on this one, with the year adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -515,7 +522,7 @@
     /**
      * Returns a copy of this year with the specified field set to a new value.
      * <p>
-     * This returns a new {@code Year}, based on this one, with the value
+     * This returns a {@code Year}, based on this one, with the value
      * for the specified field changed.
      * If it is not possible to set the value, because the field is not supported or for
      * some other reason, an exception is thrown.
@@ -540,7 +547,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -564,35 +571,81 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this year with the specified period added.
+     * Returns a copy of this year with the specified amount added.
      * <p>
-     * This method returns a new year based on this year with the specified period added.
-     * The adder is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
+     * This returns a {@code Year}, based on this one, with the specified amount added.
+     * The amount is typically {@link Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return a {@code Year} based on this year with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public Year plus(TemporalAdder adder) {
-        return (Year) adder.addTo(this);
+    public Year plus(TemporalAmount amountToAdd) {
+        return (Year) amountToAdd.addTo(this);
     }
 
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this year with the specified amount added.
+     * <p>
+     * This returns a {@code Year}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented here.
+     * The supported fields behave as follows:
+     * <ul>
+     * <li>{@code YEARS} -
+     *  Returns a {@code Year} with the specified number of years added.
+     *  This is equivalent to {@link #plusYears(long)}.
+     * <li>{@code DECADES} -
+     *  Returns a {@code Year} with the specified number of decades added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 10.
+     * <li>{@code CENTURIES} -
+     *  Returns a {@code Year} with the specified number of centuries added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 100.
+     * <li>{@code MILLENNIA} -
+     *  Returns a {@code Year} with the specified number of millennia added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 1,000.
+     * <li>{@code ERAS} -
+     *  Returns a {@code Year} with the specified number of eras added.
+     *  Only two eras are supported so the amount must be one, zero or minus one.
+     *  If the amount is non-zero then the year is changed such that the year-of-era
+     *  is unchanged.
+     * </ul>
+     * <p>
+     * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
+     * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToAdd  the amount of the unit to add to the result, may be negative
+     * @param unit  the unit of the amount to add, not null
+     * @return a {@code Year} based on this year with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public Year plus(long amountToAdd, TemporalUnit unit) {
@@ -606,7 +659,7 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     /**
@@ -627,30 +680,47 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this year with the specified period subtracted.
+     * Returns a copy of this year with the specified amount subtracted.
      * <p>
-     * This method returns a new year based on this year with the specified period subtracted.
-     * The subtractor is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
+     * This returns a {@code Year}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return a {@code Year} based on this year with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public Year minus(TemporalSubtractor subtractor) {
-        return (Year) subtractor.subtractFrom(this);
+    public Year minus(TemporalAmount amountToSubtract) {
+        return (Year) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this year-month with the specified amount subtracted.
+     * <p>
+     * This returns a {@code YearMonth}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
+     * @param unit  the unit of the amount to subtract, not null
+     * @return a {@code YearMonth} based on this year-month with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public Year minus(long amountToSubtract, TemporalUnit unit) {
@@ -692,8 +762,8 @@
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) ISOChrono.INSTANCE;
+        if (query == Queries.chronology()) {
+            return (R) IsoChronology.INSTANCE;
         } else if (query == Queries.precision()) {
             return (R) YEARS;
         }
@@ -728,7 +798,7 @@
      */
     @Override
     public Temporal adjustInto(Temporal temporal) {
-        if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) {
+        if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
             throw new DateTimeException("Adjustment only supported on ISO date-time");
         }
         return temporal.with(YEAR, year);
@@ -750,14 +820,15 @@
      * For example, the period in decades between 2012 and 2031
      * will only be one decade as it is one year short of two decades.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, YEARS);   // this method
-     *   dateTime.plus(YEARS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, YEARS);
+     *   amount = YEARS.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code YEARS}, {@code DECADES}, {@code CENTURIES},
@@ -795,38 +866,36 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.between(this, endYear).getAmount();
+        return unit.between(this, endYear);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a date formed from this year at the specified day-of-year.
+     * Combines this year with a day-of-year to create a {@code LocalDate}.
      * <p>
-     * This combines this year and the specified day-of-year to form a {@code LocalDate}.
+     * This returns a {@code LocalDate} formed from this year and the specified day-of-year.
+     * <p>
      * The day-of-year value 366 is only valid in a leap year.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param dayOfYear  the day-of-year to use, not null
      * @return the local date formed from this year and the specified date of year, not null
-     * @throws DateTimeException if the day of year is 366 and this is not a leap year
+     * @throws DateTimeException if the day of year is zero or less, 366 or greater or equal
+     *  to 366 and this is not a leap year
      */
     public LocalDate atDay(int dayOfYear) {
         return LocalDate.ofYearDay(year, dayOfYear);
     }
 
     /**
-     * Returns a year-month formed from this year at the specified month.
+     * Combines this year with a month to create a {@code YearMonth}.
      * <p>
-     * This combines this year and the specified month to form a {@code YearMonth}.
+     * This returns a {@code YearMonth} formed from this year and the specified month.
      * All possible combinations of year and month are valid.
      * <p>
      * This method can be used as part of a chain to produce a date:
      * <pre>
      *  LocalDate date = year.atMonth(month).atDay(day);
      * </pre>
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param month  the month-of-year to use, not null
      * @return the year-month formed from this year and the specified month, not null
@@ -836,39 +905,37 @@
     }
 
     /**
-     * Returns a year-month formed from this year at the specified month.
+     * Combines this year with a month to create a {@code YearMonth}.
      * <p>
-     * This combines this year and the specified month to form a {@code YearMonth}.
+     * This returns a {@code YearMonth} formed from this year and the specified month.
      * All possible combinations of year and month are valid.
      * <p>
      * This method can be used as part of a chain to produce a date:
      * <pre>
      *  LocalDate date = year.atMonth(month).atDay(day);
      * </pre>
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param month  the month-of-year to use, from 1 (January) to 12 (December)
      * @return the year-month formed from this year and the specified month, not null
+     * @throws DateTimeException if the month is invalid
      */
     public YearMonth atMonth(int month) {
         return YearMonth.of(year, month);
     }
 
     /**
-     * Returns a date formed from this year at the specified month-day.
+     * Combines this year with a month-day to create a {@code LocalDate}.
      * <p>
-     * This combines this year and the specified month-day to form a {@code LocalDate}.
-     * The month-day value of February 29th is only valid in a leap year.
+     * This returns a {@code LocalDate} formed from this year and the specified month-day.
      * <p>
-     * This instance is immutable and unaffected by this method call.
+     * A month-day of February 29th will be adjusted to February 28th in the resulting
+     * date if the year is not a leap year.
      *
      * @param monthDay  the month-day to use, not null
      * @return the local date formed from this year and the specified month-day, not null
-     * @throws DateTimeException if the month-day is February 29th and this is not a leap year
      */
     public LocalDate atMonthDay(MonthDay monthDay) {
-        return LocalDate.of(year, monthDay.getMonth(), monthDay.getDayOfMonth());
+        return monthDay.atYear(year);
     }
 
     //-----------------------------------------------------------------------
@@ -881,6 +948,7 @@
      * @param other  the other year to compare to, not null
      * @return the comparator value, negative if less, positive if greater
      */
+    @Override
     public int compareTo(Year other) {
         return year - other.year;
     }
@@ -950,7 +1018,7 @@
      * Outputs this year as a {@code String} using the formatter.
      * <p>
      * This year will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted year string, not null
@@ -958,7 +1026,7 @@
      */
     public String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
     //-----------------------------------------------------------------------
@@ -966,7 +1034,7 @@
      * Writes the object using a
      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
      * <pre>
-     *  out.writeByte(4);  // identifies this as a Year
+     *  out.writeByte(11);  // identifies this as a Year
      *  out.writeInt(year);
      * </pre>
      *
diff --git a/jdk/src/share/classes/java/time/temporal/YearMonth.java b/jdk/src/share/classes/java/time/YearMonth.java
similarity index 82%
rename from jdk/src/share/classes/java/time/temporal/YearMonth.java
rename to jdk/src/share/classes/java/time/YearMonth.java
index 2461120..076983f 100644
--- a/jdk/src/share/classes/java/time/temporal/YearMonth.java
+++ b/jdk/src/share/classes/java/time/YearMonth.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time;
 
 import static java.time.temporal.ChronoField.EPOCH_MONTH;
 import static java.time.temporal.ChronoField.ERA;
@@ -74,15 +74,23 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.Month;
-import java.time.ZoneId;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
 import java.time.format.SignStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
 import java.util.Objects;
 
 /**
@@ -212,8 +220,9 @@
     /**
      * Obtains an instance of {@code YearMonth} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code YearMonth}.
+     * This obtains a year-month based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code YearMonth}.
      * <p>
      * The conversion extracts the {@link ChronoField#YEAR YEAR} and
      * {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} fields.
@@ -232,7 +241,7 @@
             return (YearMonth) temporal;
         }
         try {
-            if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) {
+            if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
                 temporal = LocalDate.from(temporal);
             }
             return of(temporal.get(YEAR), temporal.get(MONTH_OF_YEAR));
@@ -308,8 +317,6 @@
      * {@link #get(TemporalField) get} methods will throw an exception.
      * <p>
      * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return valid
-     * values based on this date-time.
      * The supported fields are:
      * <ul>
      * <li>{@code MONTH_OF_YEAR}
@@ -321,7 +328,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -334,7 +341,7 @@
             return field == YEAR || field == MONTH_OF_YEAR ||
                     field == EPOCH_MONTH || field == YEAR_OF_ERA || field == ERA;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -351,7 +358,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -382,7 +389,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -409,7 +416,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -430,7 +437,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     private long getEpochMonth() {
@@ -452,6 +459,20 @@
     }
 
     /**
+     * Gets the month-of-year field from 1 to 12.
+     * <p>
+     * This method returns the month as an {@code int} from 1 to 12.
+     * Application code is frequently clearer if the enum {@link Month}
+     * is used by calling {@link #getMonth()}.
+     *
+     * @return the month-of-year, from 1 to 12
+     * @see #getMonth()
+     */
+    public int getMonthValue() {
+        return month;
+    }
+
+    /**
      * Gets the month-of-year field using the {@code Month} enum.
      * <p>
      * This method returns the enum {@link Month} for the month.
@@ -460,6 +481,7 @@
      * provides the {@link Month#getValue() int value}.
      *
      * @return the month-of-year, not null
+     * @see #getMonthValue()
      */
     public Month getMonth() {
         return Month.of(month);
@@ -485,7 +507,7 @@
      * @return true if the year is leap, false otherwise
      */
     public boolean isLeapYear() {
-        return ISOChrono.INSTANCE.isLeapYear(year);
+        return IsoChronology.INSTANCE.isLeapYear(year);
     }
 
     /**
@@ -528,7 +550,7 @@
     /**
      * Returns an adjusted copy of this year-month.
      * <p>
-     * This returns a new {@code YearMonth}, based on this one, with the year-month adjusted.
+     * This returns a {@code YearMonth}, based on this one, with the year-month adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -555,7 +577,7 @@
     /**
      * Returns a copy of this year-month with the specified field set to a new value.
      * <p>
-     * This returns a new {@code YearMonth}, based on this one, with the value
+     * This returns a {@code YearMonth}, based on this one, with the value
      * for the specified field changed.
      * This can be used to change any supported field, such as the year or month.
      * If it is not possible to set the value, because the field is not supported or for
@@ -587,7 +609,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -613,7 +635,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
@@ -647,30 +669,79 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this year-month with the specified period added.
+     * Returns a copy of this year-month with the specified amount added.
      * <p>
-     * This method returns a new year-month based on this year-month with the specified period added.
-     * The adder is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
+     * This returns a {@code YearMonth}, based on this one, with the specified amount added.
+     * The amount is typically {@link Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return a {@code YearMonth} based on this year-month with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public YearMonth plus(TemporalAdder adder) {
-        return (YearMonth) adder.addTo(this);
+    public YearMonth plus(TemporalAmount amountToAdd) {
+        return (YearMonth) amountToAdd.addTo(this);
     }
 
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this year-month with the specified amount added.
+     * <p>
+     * This returns a {@code YearMonth}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented here.
+     * The supported fields behave as follows:
+     * <ul>
+     * <li>{@code MONTHS} -
+     *  Returns a {@code YearMonth} with the specified number of months added.
+     *  This is equivalent to {@link #plusMonths(long)}.
+     * <li>{@code YEARS} -
+     *  Returns a {@code YearMonth} with the specified number of years added.
+     *  This is equivalent to {@link #plusYears(long)}.
+     * <li>{@code DECADES} -
+     *  Returns a {@code YearMonth} with the specified number of decades added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 10.
+     * <li>{@code CENTURIES} -
+     *  Returns a {@code YearMonth} with the specified number of centuries added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 100.
+     * <li>{@code MILLENNIA} -
+     *  Returns a {@code YearMonth} with the specified number of millennia added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 1,000.
+     * <li>{@code ERAS} -
+     *  Returns a {@code YearMonth} with the specified number of eras added.
+     *  Only two eras are supported so the amount must be one, zero or minus one.
+     *  If the amount is non-zero then the year is changed such that the year-of-era
+     *  is unchanged.
+     * </ul>
+     * <p>
+     * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
+     * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToAdd  the amount of the unit to add to the result, may be negative
+     * @param unit  the unit of the amount to add, not null
+     * @return a {@code YearMonth} based on this year-month with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public YearMonth plus(long amountToAdd, TemporalUnit unit) {
@@ -685,7 +756,7 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     /**
@@ -727,30 +798,47 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this year-month with the specified period subtracted.
+     * Returns a copy of this year-month with the specified amount subtracted.
      * <p>
-     * This method returns a new year-month based on this year-month with the specified period subtracted.
-     * The subtractor is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
+     * This returns a {@code YearMonth}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return a {@code YearMonth} based on this year-month with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public YearMonth minus(TemporalSubtractor subtractor) {
-        return (YearMonth) subtractor.subtractFrom(this);
+    public YearMonth minus(TemporalAmount amountToSubtract) {
+        return (YearMonth) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this year-month with the specified amount subtracted.
+     * <p>
+     * This returns a {@code YearMonth}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
+     * @param unit  the unit of the amount to subtract, not null
+     * @return a {@code YearMonth} based on this year-month with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public YearMonth minus(long amountToSubtract, TemporalUnit unit) {
@@ -805,8 +893,8 @@
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) ISOChrono.INSTANCE;
+        if (query == Queries.chronology()) {
+            return (R) IsoChronology.INSTANCE;
         } else if (query == Queries.precision()) {
             return (R) MONTHS;
         }
@@ -841,7 +929,7 @@
      */
     @Override
     public Temporal adjustInto(Temporal temporal) {
-        if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) {
+        if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
             throw new DateTimeException("Adjustment only supported on ISO date-time");
         }
         return temporal.with(EPOCH_MONTH, getEpochMonth());
@@ -863,14 +951,15 @@
      * For example, the period in decades between 2012-06 and 2032-05
      * will only be one decade as it is one month short of two decades.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, YEARS);   // this method
-     *   dateTime.plus(YEARS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MONTHS);
+     *   amount = MONTHS.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code MONTHS}, {@code YEARS}, {@code DECADES},
@@ -909,32 +998,49 @@
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.between(this, endYearMonth).getAmount();
+        return unit.between(this, endYearMonth);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a date formed from this year-month at the specified day-of-month.
+     * Combines this year-month with a day-of-month to create a {@code LocalDate}.
      * <p>
-     * This combines this year-month and the specified day-of-month to form a {@code LocalDate}.
+     * This returns a {@code LocalDate} formed from this year-month and the specified day-of-month.
+     * <p>
      * The day-of-month value must be valid for the year-month.
      * <p>
      * This method can be used as part of a chain to produce a date:
      * <pre>
      *  LocalDate date = year.atMonth(month).atDay(day);
      * </pre>
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param dayOfMonth  the day-of-month to use, from 1 to 31
      * @return the date formed from this year-month and the specified day, not null
-     * @throws DateTimeException when the day is invalid for the year-month
+     * @throws DateTimeException if the day is invalid for the year-month
      * @see #isValidDay(int)
      */
     public LocalDate atDay(int dayOfMonth) {
         return LocalDate.of(year, month, dayOfMonth);
     }
 
+    /**
+     * Returns a {@code LocalDate} at the end of the month.
+     * <p>
+     * This returns a {@code LocalDate} based on this year-month.
+     * The day-of-month is set to the last valid day of the month, taking
+     * into account leap years.
+     * <p>
+     * This method can be used as part of a chain to produce a date:
+     * <pre>
+     *  LocalDate date = year.atMonth(month).atEndOfMonth();
+     * </pre>
+     *
+     * @return the last valid date of this year-month, not null
+     */
+    public LocalDate atEndOfMonth() {
+        return LocalDate.of(year, month, lengthOfMonth());
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Compares this year-month to another year-month.
@@ -1035,7 +1141,7 @@
      * Outputs this year-month as a {@code String} using the formatter.
      * <p>
      * This year-month will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted year-month string, not null
@@ -1043,7 +1149,7 @@
      */
     public String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
     //-----------------------------------------------------------------------
@@ -1051,7 +1157,7 @@
      * Writes the object using a
      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
      * <pre>
-     *  out.writeByte(5);  // identifies this as a Year
+     *  out.writeByte(12);  // identifies this as a YearMonth
      *  out.writeInt(year);
      *  out.writeByte(month);
      * </pre>
diff --git a/jdk/src/share/classes/java/time/ZoneId.java b/jdk/src/share/classes/java/time/ZoneId.java
index cc7d83c..43283f0 100644
--- a/jdk/src/share/classes/java/time/ZoneId.java
+++ b/jdk/src/share/classes/java/time/ZoneId.java
@@ -71,6 +71,7 @@
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
 import java.time.zone.ZoneRules;
+import java.time.zone.ZoneRulesException;
 import java.time.zone.ZoneRulesProvider;
 import java.util.Collections;
 import java.util.HashMap;
@@ -111,10 +112,11 @@
  * The ID is unique within the system.
  * The formats for offset and region IDs differ.
  * <p>
- * An ID is parsed as an offset ID if it starts with 'UTC', 'GMT', '+' or '-', or
- * is a single letter.
- * For example, 'Z', '+02:00', '-05:00', 'UTC+05' and 'GMT-6' are all valid offset IDs.
- * Note that some IDs, such as 'D' or '+ABC' meet the criteria, but are invalid.
+ * An ID is parsed as an offset ID if it starts with 'UTC', 'GMT', 'UT' '+' or '-', or
+ * is a single letter. For example, 'Z', '+02:00', '-05:00', 'UTC+05', 'GMT-6' and
+ * 'UT+01:00' are all valid offset IDs.
+ * Note that some IDs, such as 'D' or '+ABC' meet the criteria to be parsed as offset IDs,
+ * but have an invalid offset.
  * <p>
  * All other IDs are considered to be region IDs.
  * <p>
@@ -126,11 +128,11 @@
  * The default group is the IANA Time Zone Database (TZDB).
  * Other organizations include IATA (the airline industry body) and Microsoft.
  * <p>
- * Each group defines its own format for region ID.
+ * Each group defines its own format for the region ID it provides.
  * The TZDB group defines IDs such as 'Europe/London' or 'America/New_York'.
  * TZDB IDs take precedence over other groups.
  * <p>
- * It is strongly recommended that the group name is included in all Ids supplied by
+ * It is strongly recommended that the group name is included in all IDs supplied by
  * groups other than TZDB to avoid conflicts. For example, IATA airline time-zone
  * region IDs are typically the same as the three letter airport code.
  * However, the airport of Utrecht has the code 'UTC', which is obviously a conflict.
@@ -140,7 +142,7 @@
  * <h3>Specification for implementors</h3>
  * This abstract class has two implementations, both of which are immutable and thread-safe.
  * One implementation models region-based IDs, the other is {@code ZoneOffset} modelling
- * offset-based IDs.
+ * offset-based IDs. This difference is visible in serialization.
  *
  * @since 1.8
  */
@@ -151,8 +153,8 @@
      * <p>
      * This maps as follows:
      * <p><ul>
-     * <li>EST - America/Indianapolis</li>
-     * <li>MST - America/Phoenix</li>
+     * <li>EST - America/New_York</li>
+     * <li>MST - America/Denver</li>
      * <li>HST - Pacific/Honolulu</li>
      * <li>ACT - Australia/Darwin</li>
      * <li>AET - Australia/Sydney</li>
@@ -248,8 +250,8 @@
         base.put("SST", "Pacific/Guadalcanal");
         base.put("VST", "Asia/Ho_Chi_Minh");
         Map<String, String> pre = new HashMap<>(base);
-        pre.put("EST", "America/Indianapolis");
-        pre.put("MST", "America/Phoenix");
+        pre.put("EST", "America/New_York");
+        pre.put("MST", "America/Denver");
         pre.put("HST", "Pacific/Honolulu");
         OLD_IDS_PRE_2005 = Collections.unmodifiableMap(pre);
         Map<String, String> post = new HashMap<>(base);
@@ -273,7 +275,7 @@
      *
      * @return the zone ID, not null
      * @throws DateTimeException if the converted zone ID has an invalid format
-     * @throws java.time.zone.ZoneRulesException if the converted zone region ID cannot be found
+     * @throws ZoneRulesException if the converted zone region ID cannot be found
      */
     public static ZoneId systemDefault() {
         return ZoneId.of(TimeZone.getDefault().getID(), OLD_IDS_POST_2005);
@@ -294,7 +296,7 @@
      * @param aliasMap  a map of alias zone IDs (typically abbreviations) to real zone IDs, not null
      * @return the zone ID, not null
      * @throws DateTimeException if the zone ID has an invalid format
-     * @throws java.time.zone.ZoneRulesException if the zone region ID cannot be found
+     * @throws ZoneRulesException if the zone ID is a region ID that cannot be found
      */
     public static ZoneId of(String zoneId, Map<String, String> aliasMap) {
         Objects.requireNonNull(zoneId, "zoneId");
@@ -311,22 +313,22 @@
      * This method parses the ID, applies any appropriate normalization, and validates it
      * against the known set of IDs for which rules are available.
      * <p>
-     * An ID is parsed as though it is an offset ID if it starts with 'UTC', 'GMT', '+'
+     * An ID is parsed as though it is an offset ID if it starts with 'UTC', 'GMT', 'UT', '+'
      * or '-', or if it has less then two letters.
-     * The offset of {@link ZoneOffset#UTC zero} may be represented in multiple ways,
-     * including 'Z', 'UTC', 'GMT', 'UTC0' 'GMT0', '+00:00', '-00:00' and 'UTC+00:00'.
+     * The offset of {@linkplain ZoneOffset#UTC zero} may be represented in multiple ways,
+     * including 'Z', 'UTC', 'GMT', 'UT', 'UTC0', 'GMT0', 'UT0', '+00:00', '-00:00' and 'UTC+00:00'.
      * <p>
-     * Eight forms of ID are recognized, where '{offset}' means to parse using {@link ZoneOffset#of(String)}:
+     * Six forms of ID are recognized:
      * <p><ul>
-     * <li><code>{offset}</code> - a {@link ZoneOffset} ID, such as 'Z' or '+02:00'
-     * <li><code>UTC</code> - alternate form of a {@code ZoneOffset} ID equal to 'Z'
-     * <li><code>UTC0</code> - alternate form of a {@code ZoneOffset} ID equal to 'Z'
-     * <li><code>UTC{offset}</code> - alternate form of a {@code ZoneOffset} ID equal to '{offset}'
-     * <li><code>GMT</code> - alternate form of a {@code ZoneOffset} ID equal to 'Z'
-     * <li><code>GMT0</code> - alternate form of a {@code ZoneOffset} ID equal to 'Z'
-     * <li><code>GMT{offset}</code> - alternate form of a {@code ZoneOffset} ID equal to '{offset}'r
+     * <li><code>Z</code> - an offset of zero, which is {@code ZoneOffset.UTC}
+     * <li><code>{offset}</code> - a {@code ZoneOffset} ID, such as '+02:00'
+     * <li><code>{utcPrefix}</code> - a {@code ZoneOffset} ID equal to 'Z'
+     * <li><code>{utcPrefix}0</code> - a {@code ZoneOffset} ID equal to 'Z'
+     * <li><code>{utcPrefix}{offset}</code> - a {@code ZoneOffset} ID equal to '{offset}'
      * <li><code>{regionID}</code> - full region ID, loaded from configuration
      * </ul><p>
+     * The {offset} is a valid format for {@link ZoneOffset#of(String)}, excluding 'Z'.
+     * The {utcPrefix} is 'UTC', 'GMT' or 'UT'.
      * Region IDs must match the regular expression <code>[A-Za-z][A-Za-z0-9~/._+-]+</code>.
      * <p>
      * The detailed format of the region ID depends on the group supplying the data.
@@ -337,25 +339,52 @@
      * @param zoneId  the time-zone ID, not null
      * @return the zone ID, not null
      * @throws DateTimeException if the zone ID has an invalid format
-     * @throws java.time.zone.ZoneRulesException if the zone region ID cannot be found
+     * @throws ZoneRulesException if the zone ID is a region ID that cannot be found
      */
     public static ZoneId of(String zoneId) {
         Objects.requireNonNull(zoneId, "zoneId");
         if (zoneId.length() <= 1 || zoneId.startsWith("+") || zoneId.startsWith("-")) {
             return ZoneOffset.of(zoneId);
         } else if (zoneId.startsWith("UTC") || zoneId.startsWith("GMT")) {
-            if (zoneId.length() == 3 || (zoneId.length() == 4 && zoneId.charAt(3) == '0')) {
-                return ZoneOffset.UTC;
-            }
-            return ZoneOffset.of(zoneId.substring(3));
+            return ofWithPrefix(zoneId, 3);
+        } else if (zoneId.startsWith("UT")) {
+            return ofWithPrefix(zoneId, 2);
         }
         return ZoneRegion.ofId(zoneId, true);
     }
 
+    /**
+     * Parse once a prefix is established.
+     *
+     * @param zoneId  the time-zone ID, not null
+     * @param prefixLength  the length of the prefix, 2 or 3
+     * @return the zone ID, not null
+     * @return the zone ID, not null
+     * @throws DateTimeException if the zone ID has an invalid format
+     */
+    private static ZoneId ofWithPrefix(String zoneId, int prefixLength) {
+        if (zoneId.length() == prefixLength ||
+                (zoneId.length() == prefixLength + 1 && zoneId.charAt(prefixLength) == '0')) {
+            return ZoneOffset.UTC;
+        }
+        if (zoneId.charAt(prefixLength) == '+' || zoneId.charAt(prefixLength) == '-') {
+            try {
+                return ZoneOffset.of(zoneId.substring(prefixLength));
+            } catch (DateTimeException ex) {
+                throw new DateTimeException("Invalid ID for offset-based ZoneId: " + zoneId, ex);
+            }
+        }
+        throw new DateTimeException("Invalid ID for offset-based ZoneId: " + zoneId);
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code ZoneId} from a temporal object.
      * <p>
+     * This obtains a zone based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code ZoneId}.
+     * <p>
      * A {@code TemporalAccessor} represents some form of date and time information.
      * This factory converts the arbitrary temporal object to an instance of {@code ZoneId}.
      * <p>
@@ -417,7 +446,7 @@
      * {@link ZoneOffset} will always return a set of rules where the offset never changes.
      *
      * @return the rules, not null
-     * @throws DateTimeException if no rules are available for this ID
+     * @throws ZoneRulesException if no rules are available for this ID
      */
     public abstract ZoneRules getRules();
 
@@ -426,7 +455,9 @@
      * Gets the textual representation of the zone, such as 'British Time' or
      * '+02:00'.
      * <p>
-     * This returns a textual description for the time-zone ID.
+     * This returns the textual name used to identify the time-zone ID,
+     * suitable for presentation to the user.
+     * The parameters control the style of the returned text and the locale.
      * <p>
      * If no textual mapping is found then the {@link #getId() full ID} is returned.
      *
@@ -434,8 +465,8 @@
      * @param locale  the locale to use, not null
      * @return the text value of the zone, not null
      */
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendZoneText(style).toFormatter(locale).print(new TemporalAccessor() {
+    public String getDisplayName(TextStyle style, Locale locale) {
+        return new DateTimeFormatterBuilder().appendZoneText(style).toFormatter(locale).format(new TemporalAccessor() {
             @Override
             public boolean isSupported(TemporalField field) {
                 return false;
diff --git a/jdk/src/share/classes/java/time/ZoneOffset.java b/jdk/src/share/classes/java/time/ZoneOffset.java
index 5436a71..a468fbc 100644
--- a/jdk/src/share/classes/java/time/ZoneOffset.java
+++ b/jdk/src/share/classes/java/time/ZoneOffset.java
@@ -61,6 +61,9 @@
  */
 package java.time;
 
+import static java.time.LocalTime.MINUTES_PER_HOUR;
+import static java.time.LocalTime.SECONDS_PER_HOUR;
+import static java.time.LocalTime.SECONDS_PER_MINUTE;
 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
 
 import java.io.DataInput;
@@ -126,18 +129,6 @@
     private static final ConcurrentMap<String, ZoneOffset> ID_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);
 
     /**
-     * The number of seconds per hour.
-     */
-    private static final int SECONDS_PER_HOUR = 60 * 60;
-    /**
-     * The number of seconds per minute.
-     */
-    private static final int SECONDS_PER_MINUTE = 60;
-    /**
-     * The number of minutes per hour.
-     */
-    private static final int MINUTES_PER_HOUR = 60;
-    /**
      * The abs maximum seconds.
      */
     private static final int MAX_SECONDS = 18 * SECONDS_PER_HOUR;
@@ -239,11 +230,11 @@
                 seconds = parseNumber(offsetId, 7, true);
                 break;
             default:
-                throw new DateTimeException("Zone offset ID '" + offsetId + "' is invalid");
+                throw new DateTimeException("Invalid ID for ZoneOffset, invalid format: " + offsetId);
         }
         char first = offsetId.charAt(0);
         if (first != '+' && first != '-') {
-            throw new DateTimeException("Zone offset ID '" + offsetId + "' is invalid: Plus/minus not found when expected");
+            throw new DateTimeException("Invalid ID for ZoneOffset, plus/minus not found when expected: " + offsetId);
         }
         if (first == '-') {
             return ofHoursMinutesSeconds(-hours, -minutes, -seconds);
@@ -262,12 +253,12 @@
      */
     private static int parseNumber(CharSequence offsetId, int pos, boolean precededByColon) {
         if (precededByColon && offsetId.charAt(pos - 1) != ':') {
-            throw new DateTimeException("Zone offset ID '" + offsetId + "' is invalid: Colon not found when expected");
+            throw new DateTimeException("Invalid ID for ZoneOffset, colon not found when expected: " + offsetId);
         }
         char ch1 = offsetId.charAt(pos);
         char ch2 = offsetId.charAt(pos + 1);
         if (ch1 < '0' || ch1 > '9' || ch2 < '0' || ch2 > '9') {
-            throw new DateTimeException("Zone offset ID '" + offsetId + "' is invalid: Non numeric characters found");
+            throw new DateTimeException("Invalid ID for ZoneOffset, non numeric characters found: " + offsetId);
         }
         return (ch1 - 48) * 10 + (ch2 - 48);
     }
@@ -324,10 +315,15 @@
     /**
      * Obtains an instance of {@code ZoneOffset} from a temporal object.
      * <p>
+     * This obtains an offset based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code ZoneOffset}.
+     * <p>
      * A {@code TemporalAccessor} represents some form of date and time information.
      * This factory converts the arbitrary temporal object to an instance of {@code ZoneOffset}.
      * <p>
-     * The conversion extracts the {@link ChronoField#OFFSET_SECONDS offset-seconds} field.
+     * The conversion uses the {@link Queries#offset()} query, which relies
+     * on extracting the {@link ChronoField#OFFSET_SECONDS OFFSET_SECONDS} field.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
      * allowing it to be used in queries via method reference, {@code ZoneOffset::from}.
@@ -337,14 +333,11 @@
      * @throws DateTimeException if unable to convert to an {@code ZoneOffset}
      */
     public static ZoneOffset from(TemporalAccessor temporal) {
-        if (temporal instanceof ZoneOffset) {
-            return (ZoneOffset) temporal;
+        ZoneOffset offset = temporal.query(Queries.offset());
+        if (offset == null) {
+            throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " + temporal.getClass());
         }
-        try {
-            return ofTotalSeconds(temporal.get(OFFSET_SECONDS));
-        } catch (DateTimeException ex) {
-            throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " + temporal.getClass(), ex);
-        }
+        return offset;
     }
 
     //-----------------------------------------------------------------------
@@ -515,7 +508,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -527,7 +520,7 @@
         if (field instanceof ChronoField) {
             return field == OFFSET_SECONDS;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -544,7 +537,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -570,7 +563,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -601,7 +594,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -617,7 +610,7 @@
         } else if (field instanceof ChronoField) {
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/ZoneRegion.java b/jdk/src/share/classes/java/time/ZoneRegion.java
index ad93e35..2006703 100644
--- a/jdk/src/share/classes/java/time/ZoneRegion.java
+++ b/jdk/src/share/classes/java/time/ZoneRegion.java
@@ -113,7 +113,7 @@
      * if the time-zone has available rules.
      * <p>
      * This method parses the ID and applies any appropriate normalization.
-     * It does not validate the ID against the known set of IDsfor which rules are available.
+     * It does not validate the ID against the known set of IDs for which rules are available.
      * <p>
      * This method is intended for advanced use cases.
      * For example, consider a system that always retrieves time-zone rules from a remote server.
@@ -135,18 +135,20 @@
      * @param checkAvailable  whether to check if the zone ID is available
      * @return the zone ID, not null
      * @throws DateTimeException if the ID format is invalid
-     * @throws DateTimeException if checking availability and the ID cannot be found
+     * @throws ZoneRulesException if checking availability and the ID cannot be found
      */
     static ZoneRegion ofId(String zoneId, boolean checkAvailable) {
         Objects.requireNonNull(zoneId, "zoneId");
-        if (zoneId.length() < 2 || zoneId.startsWith("UTC") ||
-                zoneId.startsWith("GMT") || (PATTERN.matcher(zoneId).matches() == false)) {
-            throw new DateTimeException("ZoneId format is not a valid region format");
+        if (zoneId.length() < 2 ||
+                zoneId.startsWith("UT") ||  // includes UTC
+                zoneId.startsWith("GMT") ||
+                (PATTERN.matcher(zoneId).matches() == false)) {
+            throw new DateTimeException("Invalid ID for region-based ZoneId, invalid format: " + zoneId);
         }
         ZoneRules rules = null;
         try {
             // always attempt load for better behavior after deserialization
-            rules = ZoneRulesProvider.getRules(zoneId);
+            rules = ZoneRulesProvider.getRules(zoneId, true);
         } catch (ZoneRulesException ex) {
             if (checkAvailable) {
                 throw ex;
@@ -176,8 +178,8 @@
     @Override
     public ZoneRules getRules() {
         // additional query for group provider when null allows for possibility
-        // that the provider was added after the ZoneId was created
-        return (rules != null ? rules : ZoneRulesProvider.getRules(id));
+        // that the provider was updated after the ZoneId was created
+        return (rules != null ? rules : ZoneRulesProvider.getRules(id, false));
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/ZonedDateTime.java b/jdk/src/share/classes/java/time/ZonedDateTime.java
index c6c62fd..d6e439b 100644
--- a/jdk/src/share/classes/java/time/ZonedDateTime.java
+++ b/jdk/src/share/classes/java/time/ZonedDateTime.java
@@ -65,27 +65,24 @@
 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
 
-import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.io.InvalidObjectException;
+import java.io.ObjectInput;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
+import java.time.chrono.ChronoZonedDateTime;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ChronoZonedDateTime;
-import java.time.temporal.ISOChrono;
-import java.time.temporal.OffsetDateTime;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
 import java.time.temporal.TemporalUnit;
 import java.time.temporal.ValueRange;
 import java.time.zone.ZoneOffsetTransition;
@@ -152,7 +149,7 @@
  * @since 1.8
  */
 public final class ZonedDateTime
-        implements Temporal, ChronoZonedDateTime<ISOChrono>, Serializable {
+        implements Temporal, ChronoZonedDateTime<LocalDate>, Serializable {
 
     /**
      * Serialization version.
@@ -226,6 +223,36 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Obtains an instance of {@code ZonedDateTime} from a local date and time.
+     * <p>
+     * This creates a zoned date-time matching the input local date and time as closely as possible.
+     * Time-zone rules, such as daylight savings, mean that not every local date-time
+     * is valid for the specified zone, thus the local date-time may be adjusted.
+     * <p>
+     * The local date time and first combined to form a local date-time.
+     * The local date-time is then resolved to a single instant on the time-line.
+     * This is achieved by finding a valid offset from UTC/Greenwich for the local
+     * date-time as defined by the {@link ZoneRules rules} of the zone ID.
+     *<p>
+     * In most cases, there is only one valid offset for a local date-time.
+     * In the case of an overlap, when clocks are set back, there are two valid offsets.
+     * This method uses the earlier offset typically corresponding to "summer".
+     * <p>
+     * In the case of a gap, when clocks jump forward, there is no valid offset.
+     * Instead, the local date-time is adjusted to be later by the length of the gap.
+     * For a typical one hour daylight savings change, the local date-time will be
+     * moved one hour later into the offset typically corresponding to "summer".
+     *
+     * @param date  the local date, not null
+     * @param time  the local time, not null
+     * @param zone  the time-zone, not null
+     * @return the offset date-time, not null
+     */
+    public static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone) {
+        return of(LocalDateTime.of(date, time), zone);
+    }
+
+    /**
      * Obtains an instance of {@code ZonedDateTime} from a local date-time.
      * <p>
      * This creates a zoned date-time matching the input local date-time as closely as possible.
@@ -254,6 +281,53 @@
     }
 
     /**
+     * Obtains an instance of {@code ZonedDateTime} from a year, month, day,
+     * hour, minute, second, nanosecond and time-zone.
+     * <p>
+     * This creates a zoned date-time matching the local date-time of the seven
+     * specified fields as closely as possible.
+     * Time-zone rules, such as daylight savings, mean that not every local date-time
+     * is valid for the specified zone, thus the local date-time may be adjusted.
+     * <p>
+     * The local date-time is resolved to a single instant on the time-line.
+     * This is achieved by finding a valid offset from UTC/Greenwich for the local
+     * date-time as defined by the {@link ZoneRules rules} of the zone ID.
+     *<p>
+     * In most cases, there is only one valid offset for a local date-time.
+     * In the case of an overlap, when clocks are set back, there are two valid offsets.
+     * This method uses the earlier offset typically corresponding to "summer".
+     * <p>
+     * In the case of a gap, when clocks jump forward, there is no valid offset.
+     * Instead, the local date-time is adjusted to be later by the length of the gap.
+     * For a typical one hour daylight savings change, the local date-time will be
+     * moved one hour later into the offset typically corresponding to "summer".
+     * <p>
+     * This method exists primarily for writing test cases.
+     * Non test-code will typically use other methods to create an offset time.
+     * {@code LocalDateTime} has five additional convenience variants of the
+     * equivalent factory method taking fewer arguments.
+     * They are not provided here to reduce the footprint of the API.
+     *
+     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
+     * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
+     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
+     * @param hour  the hour-of-day to represent, from 0 to 23
+     * @param minute  the minute-of-hour to represent, from 0 to 59
+     * @param second  the second-of-minute to represent, from 0 to 59
+     * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
+     * @param zone  the time-zone, not null
+     * @return the offset date-time, not null
+     * @throws DateTimeException if the value of any field is out of range, or
+     *  if the day-of-month is invalid for the month-year
+     */
+    public static ZonedDateTime of(
+            int year, int month, int dayOfMonth,
+            int hour, int minute, int second, int nanoOfSecond, ZoneId zone) {
+        LocalDateTime dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
+        return ofLocal(dt, zone, null);
+    }
+
+    /**
      * Obtains an instance of {@code ZonedDateTime} from a local date-time
      * using the preferred offset if possible.
      * <p>
@@ -436,13 +510,17 @@
     /**
      * Obtains an instance of {@code ZonedDateTime} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code ZonedDateTime}.
+     * This obtains a zoned date-time based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code ZonedDateTime}.
      * <p>
-     * The conversion will first obtain a {@code ZoneId}. It will then try to obtain an instant.
-     * If that fails it will try to obtain a local date-time.
-     * The zoned date time will either be a combination of {@code ZoneId} and instant,
-     * or {@code ZoneId} and local date-time.
+     * The conversion will first obtain a {@code ZoneId} from the temporal object,
+     * falling back to a {@code ZoneOffset} if necessary. It will then try to obtain
+     * an {@code Instant}, falling back to a {@code LocalDateTime} if necessary.
+     * The result will be either the combination of {@code ZoneId} or {@code ZoneOffset}
+     * with {@code Instant} or {@code LocalDateTime}.
+     * Implementations are permitted to perform optimizations such as accessing
+     * those fields that are equivalent to the relevant objects.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
      * allowing it to be used in queries via method reference, {@code ZonedDateTime::from}.
@@ -477,14 +555,14 @@
      * {@code 2007-12-03T10:15:30+01:00[Europe/Paris]}.
      * <p>
      * The string must represent a valid date-time and is parsed using
-     * {@link java.time.format.DateTimeFormatters#isoZonedDateTime()}.
+     * {@link java.time.format.DateTimeFormatter#ISO_ZONED_DATE_TIME}.
      *
      * @param text  the text to parse such as "2007-12-03T10:15:30+01:00[Europe/Paris]", not null
      * @return the parsed zoned date-time, not null
      * @throws DateTimeParseException if the text cannot be parsed
      */
     public static ZonedDateTime parse(CharSequence text) {
-        return parse(text, DateTimeFormatters.isoZonedDateTime());
+        return parse(text, DateTimeFormatter.ISO_ZONED_DATE_TIME);
     }
 
     /**
@@ -595,7 +673,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -604,7 +682,7 @@
      */
     @Override
     public boolean isSupported(TemporalField field) {
-        return field instanceof ChronoField || (field != null && field.doIsSupported(this));
+        return field instanceof ChronoField || (field != null && field.isSupportedBy(this));
     }
 
     /**
@@ -621,7 +699,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -637,7 +715,7 @@
             }
             return dateTime.range(field);
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     /**
@@ -656,7 +734,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -690,7 +768,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -708,7 +786,7 @@
             }
             return dateTime.getLong(field);
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -770,7 +848,7 @@
      */
     @Override
     public ZonedDateTime withLaterOffsetAtOverlap() {
-        ZoneOffsetTransition trans = getZone().getRules().getTransition(getDateTime());
+        ZoneOffsetTransition trans = getZone().getRules().getTransition(toLocalDateTime());
         if (trans != null) {
             ZoneOffset laterOffset = trans.getOffsetAfter();
             if (laterOffset.equals(offset) == false) {
@@ -859,7 +937,7 @@
      * as most protocols, such as ISO-8601, only handle offsets,
      * and not region-based zone IDs.
      * <p>
-     * This is equivalent to {@code ZonedDateTime.of(zdt.getDateTime(), zdt.getOffset())}.
+     * This is equivalent to {@code ZonedDateTime.of(zdt.toLocalDateTime(), zdt.getOffset())}.
      *
      * @return a {@code ZonedDateTime} with the zone ID set to the offset, not null
      */
@@ -877,7 +955,7 @@
      * @return the local date-time part of this date-time, not null
      */
     @Override  // override for return type
-    public LocalDateTime getDateTime() {
+    public LocalDateTime toLocalDateTime() {
         return dateTime;
     }
 
@@ -891,8 +969,8 @@
      * @return the date part of this date-time, not null
      */
     @Override  // override for return type
-    public LocalDate getDate() {
-        return dateTime.getDate();
+    public LocalDate toLocalDate() {
+        return dateTime.toLocalDate();
     }
 
     /**
@@ -901,7 +979,7 @@
      * This method returns the primitive {@code int} value for the year.
      * <p>
      * The year returned by this method is proleptic as per {@code get(YEAR)}.
-     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
+     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA)}.
      *
      * @return the year, from MIN_YEAR to MAX_YEAR
      */
@@ -987,8 +1065,8 @@
      * @return the time part of this date-time, not null
      */
     @Override  // override for Javadoc and performance
-    public LocalTime getTime() {
-        return dateTime.getTime();
+    public LocalTime toLocalTime() {
+        return dateTime.toLocalTime();
     }
 
     /**
@@ -1031,7 +1109,7 @@
     /**
      * Returns an adjusted copy of this date-time.
      * <p>
-     * This returns a new {@code ZonedDateTime}, based on this one, with the date-time adjusted.
+     * This returns a {@code ZonedDateTime}, based on this one, with the date-time adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
@@ -1040,7 +1118,7 @@
      * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}.
      * These include finding the "last day of the month" and "next Wednesday".
      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
-     * such as {@link Month} and {@link java.time.temporal.MonthDay MonthDay}.
+     * such as {@link Month} and {@link java.time.MonthDay MonthDay}.
      * The adjuster is responsible for handling special cases, such as the varying
      * lengths of month and leap years.
      * <p>
@@ -1084,9 +1162,9 @@
     public ZonedDateTime with(TemporalAdjuster adjuster) {
         // optimizations
         if (adjuster instanceof LocalDate) {
-            return resolveLocal(LocalDateTime.of((LocalDate) adjuster, dateTime.getTime()));
+            return resolveLocal(LocalDateTime.of((LocalDate) adjuster, dateTime.toLocalTime()));
         } else if (adjuster instanceof LocalTime) {
-            return resolveLocal(LocalDateTime.of(dateTime.getDate(), (LocalTime) adjuster));
+            return resolveLocal(LocalDateTime.of(dateTime.toLocalDate(), (LocalTime) adjuster));
         } else if (adjuster instanceof LocalDateTime) {
             return resolveLocal((LocalDateTime) adjuster);
         } else if (adjuster instanceof Instant) {
@@ -1101,7 +1179,7 @@
     /**
      * Returns a copy of this date-time with the specified field set to a new value.
      * <p>
-     * This returns a new {@code ZonedDateTime}, based on this one, with the value
+     * This returns a {@code ZonedDateTime}, based on this one, with the value
      * for the specified field changed.
      * This can be used to change any supported field, such as the year, month or day-of-month.
      * If it is not possible to set the value, because the field is not supported or for
@@ -1139,7 +1217,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
@@ -1164,7 +1242,7 @@
             }
             return resolveLocal(dateTime.with(field, newValue));
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
@@ -1228,8 +1306,8 @@
      *
      * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
      * @return a {@code ZonedDateTime} based on this date-time with the requested day, not null
-     * @throws DateTimeException if the day-of-month value is invalid
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the day-of-month value is invalid,
+     *  or if the day-of-month is invalid for the month-year
      */
     public ZonedDateTime withDayOfMonth(int dayOfMonth) {
         return resolveLocal(dateTime.withDayOfMonth(dayOfMonth));
@@ -1251,8 +1329,8 @@
      *
      * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
      * @return a {@code ZonedDateTime} based on this date with the requested day, not null
-     * @throws DateTimeException if the day-of-year value is invalid
-     * @throws DateTimeException if the day-of-year is invalid for the year
+     * @throws DateTimeException if the day-of-year value is invalid,
+     *  or if the day-of-year is invalid for the year
      */
     public ZonedDateTime withDayOfYear(int dayOfYear) {
         return resolveLocal(dateTime.withDayOfYear(dayOfYear));
@@ -1356,8 +1434,10 @@
      * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
      * will set the second-of-minute and nano-of-second field to zero.
      * <p>
-     * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time
-     * units with an exact duration can be used, other units throw an exception.
+     * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+     * that divides into the length of a standard day without remainder.
+     * This includes all supplied time units on {@link ChronoUnit} and
+     * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
      * <p>
      * This operates on the local time-line,
      * {@link LocalDateTime#truncatedTo(java.time.temporal.TemporalUnit) truncating}
@@ -1380,34 +1460,39 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date-time with the specified period added.
+     * Returns a copy of this date-time with the specified amount added.
      * <p>
-     * This method returns a new date-time based on this time with the specified period added.
-     * The adder is typically {@link Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
+     * This returns a {@code ZonedDateTime}, based on this one, with the specified amount added.
+     * The amount is typically {@link Period} or {@link Duration} but may be
+     * any other type implementing the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return a {@code ZonedDateTime} based on this date-time with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public ZonedDateTime plus(TemporalAdder adder) {
-        return (ZonedDateTime) adder.addTo(this);
+    public ZonedDateTime plus(TemporalAmount amountToAdd) {
+        return (ZonedDateTime) amountToAdd.addTo(this);
     }
 
     /**
-     * Returns a copy of this date-time with the specified period added.
+     * Returns a copy of this date-time with the specified amount added.
      * <p>
-     * This method returns a new date-time based on this date-time with the specified period added.
-     * This can be used to add any period that is defined by a unit, for example to add years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns a {@code ZonedDateTime}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
      * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented here.
+     * The zone is not part of the calculation and will be unchanged in the result.
      * The calculation for date and time units differ.
      * <p>
      * Date units operate on the local time-line.
@@ -1422,12 +1507,18 @@
      * The conversion uses {@link #ofInstant(LocalDateTime, ZoneOffset, ZoneId)}
      * with the offset before the addition.
      * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToAdd  the amount of the unit to add to the result, may be negative
-     * @param unit  the unit of the period to add, not null
-     * @return a {@code ZonedDateTime} based on this date-time with the specified period added, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to add, not null
+     * @return a {@code ZonedDateTime} based on this date-time with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public ZonedDateTime plus(long amountToAdd, TemporalUnit unit) {
@@ -1439,7 +1530,7 @@
                 return resolveInstant(dateTime.plus(amountToAdd, unit));
             }
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
@@ -1616,33 +1707,36 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date-time with the specified period subtracted.
+     * Returns a copy of this date-time with the specified amount subtracted.
      * <p>
-     * This method returns a new date-time based on this time with the specified period subtracted.
-     * The subtractor is typically {@link Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
+     * This returns a {@code ZonedDateTime}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Period} or {@link Duration} but may be
+     * any other type implementing the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return a {@code ZonedDateTime} based on this date-time with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public ZonedDateTime minus(TemporalSubtractor subtractor) {
-        return (ZonedDateTime) subtractor.subtractFrom(this);
+    public ZonedDateTime minus(TemporalAmount amountToSubtract) {
+        return (ZonedDateTime) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * Returns a copy of this date-time with the specified period subtracted.
+     * Returns a copy of this date-time with the specified amount subtracted.
      * <p>
-     * This method returns a new date-time based on this date-time with the specified period subtracted.
-     * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * This returns a {@code ZonedDateTime}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
      * <p>
      * The calculation for date and time units differ.
      * <p>
@@ -1658,12 +1752,16 @@
      * The conversion uses {@link #ofInstant(LocalDateTime, ZoneOffset, ZoneId)}
      * with the offset before the subtraction.
      * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
-     * @param unit  the unit of the period to subtract, not null
-     * @return a {@code ZonedDateTime} based on this date-time with the specified period subtracted, not null
-     * @throws DateTimeException if the unit cannot be added to this type
+     * @param unit  the unit of the amount to subtract, not null
+     * @return a {@code ZonedDateTime} based on this date-time with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public ZonedDateTime minus(long amountToSubtract, TemporalUnit unit) {
@@ -1885,14 +1983,15 @@
      * For example, the period in months between 2012-06-15T00:00Z and 2012-08-14T23:59Z
      * will only be one month as it is one minute short of two months.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, MONTHS);   // this method
-     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MONTHS);
+     *   amount = MONTHS.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
@@ -1944,7 +2043,7 @@
                 return toOffsetDateTime().periodUntil(end.toOffsetDateTime(), unit);
             }
         }
-        return unit.between(this, endDateTime).getAmount();
+        return unit.between(this, endDateTime);
     }
 
     //-----------------------------------------------------------------------
@@ -2018,7 +2117,7 @@
      * Outputs this date-time as a {@code String} using the formatter.
      * <p>
      * This date will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted date-time string, not null
@@ -2061,7 +2160,7 @@
         zone.write(out);
     }
 
-    static ZonedDateTime readExternal(DataInput in) throws IOException {
+    static ZonedDateTime readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         LocalDateTime dateTime = LocalDateTime.readExternal(in);
         ZoneOffset offset = ZoneOffset.readExternal(in);
         ZoneId zone = (ZoneId) Ser.read(in);
diff --git a/jdk/src/share/classes/java/time/calendar/JapaneseDate.java b/jdk/src/share/classes/java/time/calendar/JapaneseDate.java
deleted file mode 100644
index d923c88..0000000
--- a/jdk/src/share/classes/java/time/calendar/JapaneseDate.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.calendar;
-
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.YEAR;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.TemporalField;
-import java.time.temporal.ValueRange;
-import java.util.Calendar;
-import java.util.Objects;
-
-import sun.util.calendar.LocalGregorianCalendar;
-
-/**
- * A date in the Japanese Imperial calendar system.
- * <p>
- * This implements {@code ChronoLocalDate} for the
- * {@linkplain JapaneseChrono Japanese Imperial calendar}.
- *
- * <h3>Specification for implementors</h3>
- * This class is immutable and thread-safe.
- *
- * @since 1.8
- */
-final class JapaneseDate
-        extends ChronoDateImpl<JapaneseChrono>
-        implements ChronoLocalDate<JapaneseChrono>, Serializable {
-    // this class is package-scoped so that future conversion to public
-    // would not change serialization
-
-    /**
-     * Serialization version.
-     */
-    private static final long serialVersionUID = -305327627230580483L;
-
-    /**
-     * The underlying ISO local date.
-     */
-    private transient final LocalDate isoDate;
-    /**
-     * The JapaneseEra of this date.
-     */
-    private transient JapaneseEra era;
-    /**
-     * The Japanese imperial calendar year of this date.
-     */
-    private transient int yearOfEra;
-
-    /**
-     * Obtains an instance of {@code JapaneseDate} from the era, year-of-era,
-     * month-of-year and day-of-month.
-     *
-     * @param era  the era to represent, not null
-     * @param yearOfEra  the year-of-era to represent
-     * @param month  the month-of-year to represent
-     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
-     * @return the Japanese date, never null
-     * @throws DateTimeException if the value of any field is out of range, or
-     *                           if the day-of-month is invalid for the month-year
-     */
-    static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) {
-        Objects.requireNonNull(era, "era");
-        LocalGregorianCalendar.Date jdate = JapaneseChrono.JCAL.newCalendarDate(null);
-        jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth);
-        if (!JapaneseChrono.JCAL.validate(jdate)) {
-            throw new IllegalArgumentException();
-        }
-        LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth);
-        return new JapaneseDate(era, yearOfEra, date);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Creates an instance from an ISO date.
-     *
-     * @param isoDate  the standard local date, validated not null
-     */
-    JapaneseDate(LocalDate isoDate) {
-        LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate);
-        this.era = JapaneseEra.toJapaneseEra(jdate.getEra());
-        this.yearOfEra = jdate.getYear();
-        this.isoDate = isoDate;
-    }
-
-    /**
-     * Constructs a {@code JapaneseDate}. This constructor does NOT validate the given parameters,
-     * and {@code era} and {@code year} must agree with {@code isoDate}.
-     *
-     * @param era  the era, validated not null
-     * @param year  the year-of-era, validated
-     * @param isoDate  the standard local date, validated not null
-     */
-    JapaneseDate(JapaneseEra era, int year, LocalDate isoDate) {
-        this.era = era;
-        this.yearOfEra = year;
-        this.isoDate = isoDate;
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public JapaneseChrono getChrono() {
-        return JapaneseChrono.INSTANCE;
-    }
-
-    @Override
-    public int lengthOfMonth() {
-        return isoDate.lengthOfMonth();
-    }
-
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field instanceof ChronoField) {
-            if (isSupported(field)) {
-                ChronoField f = (ChronoField) field;
-                switch (f) {
-                    case DAY_OF_YEAR:
-                        return actualRange(Calendar.DAY_OF_YEAR);
-                    case YEAR_OF_ERA:
-                        return actualRange(Calendar.YEAR);
-                }
-                return getChrono().range(f);
-            }
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doRange(this);
-    }
-
-    private ValueRange actualRange(int calendarField) {
-        Calendar jcal = Calendar.getInstance(JapaneseChrono.LOCALE);
-        jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET);
-        jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth());
-        return ValueRange.of(jcal.getActualMinimum(calendarField),
-                jcal.getActualMaximum(calendarField));
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        if (field instanceof ChronoField) {
-            switch ((ChronoField) field) {
-                case YEAR_OF_ERA:
-                    return yearOfEra;
-                case ERA:
-                    return era.getValue();
-                case DAY_OF_YEAR: {
-                    LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate);
-                    return JapaneseChrono.JCAL.getDayOfYear(jdate);
-                }
-            }
-            // TODO: review other fields
-            return isoDate.getLong(field);
-        }
-        return field.doGet(this);
-    }
-
-    /**
-     * Returns a {@code LocalGregorianCalendar.Date} converted from the given {@code isoDate}.
-     *
-     * @param isoDate  the local date, not null
-     * @return a {@code LocalGregorianCalendar.Date}, not null
-     */
-    private static LocalGregorianCalendar.Date toPrivateJapaneseDate(LocalDate isoDate) {
-        LocalGregorianCalendar.Date jdate = JapaneseChrono.JCAL.newCalendarDate(null);
-        sun.util.calendar.Era sunEra = JapaneseEra.privateEraFrom(isoDate);
-        int year = isoDate.getYear();
-        if (sunEra != null) {
-            year -= sunEra.getSinceDate().getYear() - 1;
-        }
-        jdate.setEra(sunEra).setYear(year).setMonth(isoDate.getMonthValue()).setDayOfMonth(isoDate.getDayOfMonth());
-        JapaneseChrono.JCAL.normalize(jdate);
-        return jdate;
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public JapaneseDate with(TemporalField field, long newValue) {
-        if (field instanceof ChronoField) {
-            ChronoField f = (ChronoField) field;
-            if (getLong(f) == newValue) {
-                return this;
-            }
-            switch (f) {
-                case YEAR_OF_ERA:
-                case YEAR:
-                case ERA: {
-                    f.checkValidValue(newValue);
-                    int nvalue = (int) newValue;
-                    switch (f) {
-                        case YEAR_OF_ERA:
-                            return this.withYear(nvalue);
-                        case YEAR:
-                            return with(isoDate.withYear(nvalue));
-                        case ERA: {
-                            return this.withYear(JapaneseEra.of(nvalue), yearOfEra);
-                        }
-                    }
-                }
-            }
-            // TODO: review other fields, such as WEEK_OF_YEAR
-            return with(isoDate.with(field, newValue));
-        }
-        return (JapaneseDate) ChronoLocalDate.super.with(field, newValue);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this date with the year altered.
-     * <p>
-     * This method changes the year of the date.
-     * If the month-day is invalid for the year, then the previous valid day
-     * will be selected instead.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param era  the era to set in the result, not null
-     * @param yearOfEra  the year-of-era to set in the returned date
-     * @return a {@code JapaneseDate} based on this date with the requested year, never null
-     * @throws DateTimeException if {@code year} is invalid
-     */
-    private JapaneseDate withYear(JapaneseEra era, int yearOfEra) {
-        int year = JapaneseChrono.INSTANCE.prolepticYear(era, yearOfEra);
-        return with(isoDate.withYear(year));
-    }
-
-    /**
-     * Returns a copy of this date with the year-of-era altered.
-     * <p>
-     * This method changes the year-of-era of the date.
-     * If the month-day is invalid for the year, then the previous valid day
-     * will be selected instead.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param year  the year to set in the returned date
-     * @return a {@code JapaneseDate} based on this date with the requested year-of-era, never null
-     * @throws DateTimeException if {@code year} is invalid
-     */
-    private JapaneseDate withYear(int year) {
-        return withYear((JapaneseEra) getEra(), year);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    JapaneseDate plusYears(long years) {
-        return with(isoDate.plusYears(years));
-    }
-
-    @Override
-    JapaneseDate plusMonths(long months) {
-        return with(isoDate.plusMonths(months));
-    }
-
-    @Override
-    JapaneseDate plusDays(long days) {
-        return with(isoDate.plusDays(days));
-    }
-
-    private JapaneseDate with(LocalDate newDate) {
-        return (newDate.equals(isoDate) ? this : new JapaneseDate(newDate));
-    }
-
-    @Override  // override for performance
-    public long toEpochDay() {
-        return isoDate.toEpochDay();
-    }
-
-    //-------------------------------------------------------------------------
-    @Override  // override for performance
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof JapaneseDate) {
-            JapaneseDate otherDate = (JapaneseDate) obj;
-            return this.isoDate.equals(otherDate.isoDate);
-        }
-        return false;
-    }
-
-    @Override  // override for performance
-    public int hashCode() {
-        return getChrono().getId().hashCode() ^ isoDate.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        if (era == JapaneseEra.SEIREKI) {
-            return getChrono().getId() + " " + isoDate.toString();
-        }
-        return super.toString();
-    }
-
-    //-----------------------------------------------------------------------
-    private Object writeReplace() {
-        return new Ser(Ser.JAPANESE_DATE_TYPE, this);
-    }
-
-    void writeExternal(DataOutput out) throws IOException {
-        // JapaneseChrono is implicit in the JAPANESE_DATE_TYPE
-        out.writeInt(get(YEAR));
-        out.writeByte(get(MONTH_OF_YEAR));
-        out.writeByte(get(DAY_OF_MONTH));
-    }
-
-    static ChronoLocalDate<JapaneseChrono> readExternal(DataInput in) throws IOException {
-        int year = in.readInt();
-        int month = in.readByte();
-        int dayOfMonth = in.readByte();
-        return JapaneseChrono.INSTANCE.date(year, month, dayOfMonth);
-    }
-
-
-}
diff --git a/jdk/src/share/classes/java/time/calendar/MinguoDate.java b/jdk/src/share/classes/java/time/calendar/MinguoDate.java
deleted file mode 100644
index 39981d6..0000000
--- a/jdk/src/share/classes/java/time/calendar/MinguoDate.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.calendar;
-
-import static java.time.calendar.MinguoChrono.YEARS_DIFFERENCE;
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.YEAR;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.io.Serializable;
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.TemporalField;
-import java.time.temporal.ValueRange;
-import java.util.Objects;
-
-/**
- * A date in the Minguo calendar system.
- * <p>
- * This implements {@code ChronoLocalDate} for the {@link MinguoChrono Minguo calendar}.
- *
- * <h3>Specification for implementors</h3>
- * This class is immutable and thread-safe.
- *
- * @since 1.8
- */
-final class MinguoDate
-        extends ChronoDateImpl<MinguoChrono>
-        implements ChronoLocalDate<MinguoChrono>, Serializable {
-    // this class is package-scoped so that future conversion to public
-    // would not change serialization
-
-    /**
-     * Serialization version.
-     */
-    private static final long serialVersionUID = 1300372329181994526L;
-
-    /**
-     * The underlying date.
-     */
-    private final LocalDate isoDate;
-
-    /**
-     * Creates an instance from an ISO date.
-     *
-     * @param isoDate  the standard local date, validated not null
-     */
-    MinguoDate(LocalDate isoDate) {
-        Objects.requireNonNull(isoDate, "isoDate");
-        this.isoDate = isoDate;
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public MinguoChrono getChrono() {
-        return MinguoChrono.INSTANCE;
-    }
-
-    @Override
-    public int lengthOfMonth() {
-        return isoDate.lengthOfMonth();
-    }
-
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field instanceof ChronoField) {
-            if (isSupported(field)) {
-                ChronoField f = (ChronoField) field;
-                switch (f) {
-                    case DAY_OF_MONTH:
-                    case DAY_OF_YEAR:
-                    case ALIGNED_WEEK_OF_MONTH:
-                        return isoDate.range(field);
-                    case YEAR_OF_ERA: {
-                        ValueRange range = YEAR.range();
-                        long max = (getProlepticYear() <= 0 ? -range.getMinimum() + 1 + YEARS_DIFFERENCE : range.getMaximum() - YEARS_DIFFERENCE);
-                        return ValueRange.of(1, max);
-                    }
-                }
-                return getChrono().range(f);
-            }
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doRange(this);
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        if (field instanceof ChronoField) {
-            switch ((ChronoField) field) {
-                case YEAR_OF_ERA: {
-                    int prolepticYear = getProlepticYear();
-                    return (prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear);
-                }
-                case YEAR:
-                    return getProlepticYear();
-                case ERA:
-                    return (getProlepticYear() >= 1 ? 1 : 0);
-            }
-            return isoDate.getLong(field);
-        }
-        return field.doGet(this);
-    }
-
-    private int getProlepticYear() {
-        return isoDate.getYear() - YEARS_DIFFERENCE;
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public MinguoDate with(TemporalField field, long newValue) {
-        if (field instanceof ChronoField) {
-            ChronoField f = (ChronoField) field;
-            if (getLong(f) == newValue) {
-                return this;
-            }
-            switch (f) {
-                case YEAR_OF_ERA:
-                case YEAR:
-                case ERA: {
-                    f.checkValidValue(newValue);
-                    int nvalue = (int) newValue;
-                    switch (f) {
-                        case YEAR_OF_ERA:
-                            return with(isoDate.withYear(getProlepticYear() >= 1 ? nvalue + YEARS_DIFFERENCE : (1 - nvalue)  + YEARS_DIFFERENCE));
-                        case YEAR:
-                            return with(isoDate.withYear(nvalue + YEARS_DIFFERENCE));
-                        case ERA:
-                            return with(isoDate.withYear((1 - getProlepticYear()) + YEARS_DIFFERENCE));
-                    }
-                }
-            }
-            return with(isoDate.with(field, newValue));
-        }
-        return (MinguoDate) ChronoLocalDate.super.with(field, newValue);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    MinguoDate plusYears(long years) {
-        return with(isoDate.plusYears(years));
-    }
-
-    @Override
-    MinguoDate plusMonths(long months) {
-        return with(isoDate.plusMonths(months));
-    }
-
-    @Override
-    MinguoDate plusDays(long days) {
-        return with(isoDate.plusDays(days));
-    }
-
-    private MinguoDate with(LocalDate newDate) {
-        return (newDate.equals(isoDate) ? this : new MinguoDate(newDate));
-    }
-
-    @Override  // override for performance
-    public long toEpochDay() {
-        return isoDate.toEpochDay();
-    }
-
-    //-------------------------------------------------------------------------
-    @Override  // override for performance
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof MinguoDate) {
-            MinguoDate otherDate = (MinguoDate) obj;
-            return this.isoDate.equals(otherDate.isoDate);
-        }
-        return false;
-    }
-
-    @Override  // override for performance
-    public int hashCode() {
-        return getChrono().getId().hashCode() ^ isoDate.hashCode();
-    }
-
-    //-----------------------------------------------------------------------
-    private Object writeReplace() {
-        return new Ser(Ser.MINGUO_DATE_TYPE, this);
-    }
-
-    void writeExternal(DataOutput out) throws IOException {
-        // MinguoChrono is implicit in the MINGUO_DATE_TYPE
-        out.writeInt(get(YEAR));
-        out.writeByte(get(MONTH_OF_YEAR));
-        out.writeByte(get(DAY_OF_MONTH));
-
-    }
-
-    static ChronoLocalDate<MinguoChrono> readExternal(DataInput in) throws IOException {
-        int year = in.readInt();
-        int month = in.readByte();
-        int dayOfMonth = in.readByte();
-        return MinguoChrono.INSTANCE.date(year, month, dayOfMonth);
-    }
-
-
-}
diff --git a/jdk/src/share/classes/java/time/calendar/ThaiBuddhistDate.java b/jdk/src/share/classes/java/time/calendar/ThaiBuddhistDate.java
deleted file mode 100644
index 14723f6..0000000
--- a/jdk/src/share/classes/java/time/calendar/ThaiBuddhistDate.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.calendar;
-
-import static java.time.calendar.ThaiBuddhistChrono.YEARS_DIFFERENCE;
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.YEAR;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.io.Serializable;
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.TemporalField;
-import java.time.temporal.ValueRange;
-import java.util.Objects;
-
-/**
- * A date in the Thai Buddhist calendar system.
- * <p>
- * This implements {@code ChronoLocalDate} for the {@link ThaiBuddhistChrono Thai Buddhist calendar}.
- *
- * <h3>Specification for implementors</h3>
- * This class is immutable and thread-safe.
- *
- * @since 1.8
- */
-final class ThaiBuddhistDate
-        extends ChronoDateImpl<ThaiBuddhistChrono>
-        implements ChronoLocalDate<ThaiBuddhistChrono>, Serializable {
-    // this class is package-scoped so that future conversion to public
-    // would not change serialization
-
-    /**
-     * Serialization version.
-     */
-    private static final long serialVersionUID = -8722293800195731463L;
-
-    /**
-     * The underlying date.
-     */
-    private final LocalDate isoDate;
-
-    /**
-     * Creates an instance from an ISO date.
-     *
-     * @param isoDate  the standard local date, validated not null
-     */
-    ThaiBuddhistDate(LocalDate isoDate) {
-        Objects.requireNonNull(isoDate, "isoDate");
-        this.isoDate = isoDate;
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public ThaiBuddhistChrono getChrono() {
-        return ThaiBuddhistChrono.INSTANCE;
-    }
-
-    @Override
-    public int lengthOfMonth() {
-        return isoDate.lengthOfMonth();
-    }
-
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field instanceof ChronoField) {
-            if (isSupported(field)) {
-                ChronoField f = (ChronoField) field;
-                switch (f) {
-                    case DAY_OF_MONTH:
-                    case DAY_OF_YEAR:
-                    case ALIGNED_WEEK_OF_MONTH:
-                        return isoDate.range(field);
-                    case YEAR_OF_ERA: {
-                        ValueRange range = YEAR.range();
-                        long max = (getProlepticYear() <= 0 ? -(range.getMinimum() + YEARS_DIFFERENCE) + 1 : range.getMaximum() + YEARS_DIFFERENCE);
-                        return ValueRange.of(1, max);
-                    }
-                }
-                return getChrono().range(f);
-            }
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doRange(this);
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        if (field instanceof ChronoField) {
-            switch ((ChronoField) field) {
-                case YEAR_OF_ERA: {
-                    int prolepticYear = getProlepticYear();
-                    return (prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear);
-                }
-                case YEAR:
-                    return getProlepticYear();
-                case ERA:
-                    return (getProlepticYear() >= 1 ? 1 : 0);
-            }
-            return isoDate.getLong(field);
-        }
-        return field.doGet(this);
-    }
-
-    private int getProlepticYear() {
-        return isoDate.getYear() + YEARS_DIFFERENCE;
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public ThaiBuddhistDate with(TemporalField field, long newValue) {
-        if (field instanceof ChronoField) {
-            ChronoField f = (ChronoField) field;
-            if (getLong(f) == newValue) {
-                return this;
-            }
-            switch (f) {
-                case YEAR_OF_ERA:
-                case YEAR:
-                case ERA: {
-                    f.checkValidValue(newValue);
-                    int nvalue = (int) newValue;
-                    switch (f) {
-                        case YEAR_OF_ERA:
-                            return with(isoDate.withYear((getProlepticYear() >= 1 ? nvalue : 1 - nvalue)  - YEARS_DIFFERENCE));
-                        case YEAR:
-                            return with(isoDate.withYear(nvalue - YEARS_DIFFERENCE));
-                        case ERA:
-                            return with(isoDate.withYear((1 - getProlepticYear()) - YEARS_DIFFERENCE));
-                    }
-                }
-            }
-            return with(isoDate.with(field, newValue));
-        }
-        return (ThaiBuddhistDate) ChronoLocalDate.super.with(field, newValue);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    ThaiBuddhistDate plusYears(long years) {
-        return with(isoDate.plusYears(years));
-    }
-
-    @Override
-    ThaiBuddhistDate plusMonths(long months) {
-        return with(isoDate.plusMonths(months));
-    }
-
-    @Override
-    ThaiBuddhistDate plusDays(long days) {
-        return with(isoDate.plusDays(days));
-    }
-
-    private ThaiBuddhistDate with(LocalDate newDate) {
-        return (newDate.equals(isoDate) ? this : new ThaiBuddhistDate(newDate));
-    }
-
-    @Override  // override for performance
-    public long toEpochDay() {
-        return isoDate.toEpochDay();
-    }
-
-    //-------------------------------------------------------------------------
-    @Override  // override for performance
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof ThaiBuddhistDate) {
-            ThaiBuddhistDate otherDate = (ThaiBuddhistDate) obj;
-            return this.isoDate.equals(otherDate.isoDate);
-        }
-        return false;
-    }
-
-    @Override  // override for performance
-    public int hashCode() {
-        return getChrono().getId().hashCode() ^ isoDate.hashCode();
-    }
-
-    //-----------------------------------------------------------------------
-    private Object writeReplace() {
-        return new Ser(Ser.THAIBUDDHIST_DATE_TYPE, this);
-    }
-
-    void writeExternal(DataOutput out) throws IOException {
-        // MinguoChrono is implicit in the THAIBUDDHIST_DATE_TYPE
-        out.writeInt(this.get(YEAR));
-        out.writeByte(this.get(MONTH_OF_YEAR));
-        out.writeByte(this.get(DAY_OF_MONTH));
-    }
-
-    static ChronoLocalDate<ThaiBuddhistChrono> readExternal(DataInput in) throws IOException {
-        int year = in.readInt();
-        int month = in.readByte();
-        int dayOfMonth = in.readByte();
-        return ThaiBuddhistChrono.INSTANCE.date(year, month, dayOfMonth);
-    }
-
-}
diff --git a/jdk/src/share/classes/java/time/calendar/package-info.java b/jdk/src/share/classes/java/time/calendar/package-info.java
deleted file mode 100644
index 49c984e..0000000
--- a/jdk/src/share/classes/java/time/calendar/package-info.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * <p>
- * Support for calendar systems other than the default ISO.
- * </p>
- * <p>
- * The main API is based around the calendar system defined in ISO-8601.
- * This package provides support for alternate systems.
- * </p>
- * <p>
- * The supported calendar systems includes:
- * </p>
- * <ul>
- * <li>{@link java.time.calendar.HijrahChrono Hijrah calendar}</li>
- * <li>{@link java.time.calendar.JapaneseChrono Japanese calendar}</li>
- * <li>{@link java.time.calendar.MinguoChrono Minguo calendar}</li>
- * <li>{@link java.time.calendar.ThaiBuddhistChrono Thai Buddhist calendar}</li>
- * </ul>
- * <p>
- * It is intended that applications use the main API whenever possible,
- * including code to read and write from a persistent data store,
- * such as a database, and to send dates and times across a network.
- * This package is then used at the user interface level to deal with
- * localized input/output.
- * See {@link java.time.temporal.ChronoLocalDate ChronoLocalDate}
- * for a full discussion of the issues.
- * </p>
- *
- * <h3>Example</h3>
- * <p>
- * This example creates and uses a date in a non-ISO calendar system.
- * </p>
- * <pre>
- *   // Print the Thai Buddhist date
- *       ChronoLocalDate&lt;ThaiBuddhistChrono&gt; now1 = ThaiBuddhistChrono.INSTANCE.dateNow();
- *       int day = now1.get(ChronoField.DAY_OF_MONTH);
- *       int dow = now1.get(ChronoField.DAY_OF_WEEK);
- *       int month = now1.get(ChronoField.MONTH_OF_YEAR);
- *       int year = now1.get(ChronoField.YEAR);
- *       System.out.printf("  Today is %s %s %d-%s-%d%n", now1.getChrono().getId(),
- *                 dow, day, month, year);
- *
- *   // Enumerate the list of available calendars and print today for each
- *       Set&lt;Chrono&lt;?&gt;&gt; chronos = Chrono.getAvailableChronologies();
- *       for (Chrono&lt;?&gt; chrono : chronos) {
- *         ChronoLocalDate&lt;?&gt; date = chrono.dateNow();
- *         System.out.printf("   %20s: %s%n", chrono.getId(), date.toString());
- *       }
- *
- *   // Print today's date and the last day of the year for the Thai Buddhist Calendar.
- *       ChronoLocalDate&lt;ThaiBuddhistChrono&gt; first = now1
- *                 .with(ChronoField.DAY_OF_MONTH, 1)
- *                 .with(ChronoField.MONTH_OF_YEAR, 1);
- *       ChronoLocalDate&lt;ThaiBuddhistChrono&gt; last = first
- *                 .plus(1, ChronoUnit.YEARS)
- *                 .minus(1, ChronoUnit.DAYS);
- *       System.out.printf("  %s: 1st of year: %s; end of year: %s%n", last.getChrono().getId(),
- *                 first, last);
- *  </pre>
- *
- * <h3>Package specification</h3>
- * <p>
- * Unless otherwise noted, passing a null argument to a constructor or method in any class or interface
- * in this package will cause a {@link java.lang.NullPointerException NullPointerException} to be thrown.
- * The Javadoc "@param" definition is used to summarise the null-behavior.
- * The "@throws {@link java.lang.NullPointerException}" is not explicitly documented in each method.
- * </p>
- * <p>
- * All calculations should check for numeric overflow and throw either an {@link java.lang.ArithmeticException}
- * or a {@link java.time.DateTimeException}.
- * </p>
- * @since JDK1.8
- */
-package java.time.calendar;
diff --git a/jdk/src/share/classes/java/time/calendar/ChronoDateImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java
similarity index 85%
rename from jdk/src/share/classes/java/time/calendar/ChronoDateImpl.java
rename to jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java
index 9ecd2a2..29544a7 100644
--- a/jdk/src/share/classes/java/time/calendar/ChronoDateImpl.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.ERA;
@@ -65,9 +65,9 @@
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.ChronoLocalDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAdjuster;
@@ -80,7 +80,7 @@
  * For example, the Japanese, Minguo, Thai Buddhist and others.
  * <p>
  * {@code ChronoLocalDate} is built on the generic concepts of year, month and day.
- * The calendar system, represented by a {@link java.time.temporal.Chrono}, expresses the relationship between
+ * The calendar system, represented by a {@link java.time.chrono.Chronology}, expresses the relationship between
  * the fields and this class allows the resulting date to be manipulated.
  * <p>
  * Note that not all calendar systems are suitable for use with this class.
@@ -95,52 +95,52 @@
  * <pre>
  *        System.out.printf("Example()%n");
  *        // Enumerate the list of available calendars and print today for each
- *        Set&lt;Chrono&gt; chronos = Chrono.getAvailableChronologies();
- *        for (Chrono chrono : chronos) {
+ *        Set&lt;Chronology&gt; chronos = Chronology.getAvailableChronologies();
+ *        for (Chronology chrono : chronos) {
  *            ChronoLocalDate<?> date = chrono.dateNow();
  *            System.out.printf("   %20s: %s%n", chrono.getID(), date.toString());
  *        }
  *
  *        // Print the Hijrah date and calendar
- *        ChronoLocalDate<?> date = Chrono.of("Hijrah").dateNow();
+ *        ChronoLocalDate<?> date = Chronology.of("Hijrah").dateNow();
  *        int day = date.get(ChronoField.DAY_OF_MONTH);
  *        int dow = date.get(ChronoField.DAY_OF_WEEK);
  *        int month = date.get(ChronoField.MONTH_OF_YEAR);
  *        int year = date.get(ChronoField.YEAR);
- *        System.out.printf("  Today is %s %s %d-%s-%d%n", date.getChrono().getID(),
+ *        System.out.printf("  Today is %s %s %d-%s-%d%n", date.getChronology().getID(),
  *                dow, day, month, year);
 
  *        // Print today's date and the last day of the year
- *        ChronoLocalDate<?> now1 = Chrono.of("Hijrah").dateNow();
+ *        ChronoLocalDate<?> now1 = Chronology.of("Hijrah").dateNow();
  *        ChronoLocalDate<?> first = now1.with(ChronoField.DAY_OF_MONTH, 1)
  *                .with(ChronoField.MONTH_OF_YEAR, 1);
  *        ChronoLocalDate<?> last = first.plus(1, ChronoUnit.YEARS)
  *                .minus(1, ChronoUnit.DAYS);
- *        System.out.printf("  Today is %s: start: %s; end: %s%n", last.getChrono().getID(),
+ *        System.out.printf("  Today is %s: start: %s; end: %s%n", last.getChronology().getID(),
  *                first, last);
  * </pre>
  *
  * <h3>Adding Calendars</h3>
  * <p> The set of calendars is extensible by defining a subclass of {@link ChronoLocalDate}
- * to represent a date instance and an implementation of {@code Chrono}
+ * to represent a date instance and an implementation of {@code Chronology}
  * to be the factory for the ChronoLocalDate subclass.
  * </p>
  * <p> To permit the discovery of the additional calendar types the implementation of
- * {@code Chrono} must be registered as a Service implementing the {@code Chrono} interface
+ * {@code Chronology} must be registered as a Service implementing the {@code Chronology} interface
  * in the {@code META-INF/Services} file as per the specification of {@link java.util.ServiceLoader}.
- * The subclass must function according to the {@code Chrono} class description and must provide its
- * {@link java.time.temporal.Chrono#getId() chronlogy ID} and {@link Chrono#getCalendarType() calendar type}. </p>
+ * The subclass must function according to the {@code Chronology} class description and must provide its
+ * {@link java.time.chrono.Chronology#getId() chronlogy ID} and {@link Chronology#getCalendarType() calendar type}. </p>
  *
  * <h3>Specification for implementors</h3>
  * This abstract class must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
  *
- * @param <C> the chronology of this date
+ * @param <D> the ChronoLocalDate of this date-time
  * @since 1.8
  */
-abstract class ChronoDateImpl<C extends Chrono<C>>
-        implements ChronoLocalDate<C>, Temporal, TemporalAdjuster, Serializable {
+abstract class ChronoDateImpl<D extends ChronoLocalDate<D>>
+        implements ChronoLocalDate<D>, Temporal, TemporalAdjuster, Serializable {
 
     /**
      * Serialization version.
@@ -155,7 +155,7 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<C> plus(long amountToAdd, TemporalUnit unit) {
+    public D plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             ChronoUnit f = (ChronoUnit) unit;
             switch (f) {
@@ -188,7 +188,7 @@
      * @return a date based on this one with the years added, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    abstract ChronoDateImpl<C> plusYears(long yearsToAdd);
+    abstract D plusYears(long yearsToAdd);
 
     /**
      * Returns a copy of this date with the specified period in months added.
@@ -204,7 +204,7 @@
      * @return a date based on this one with the months added, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    abstract ChronoDateImpl<C> plusMonths(long monthsToAdd);
+    abstract D plusMonths(long monthsToAdd);
 
     /**
      * Returns a copy of this date with the specified period in weeks added.
@@ -221,7 +221,7 @@
      * @return a date based on this one with the weeks added, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    ChronoDateImpl<C> plusWeeks(long weeksToAdd) {
+    D plusWeeks(long weeksToAdd) {
         return plusDays(Math.multiplyExact(weeksToAdd, 7));
     }
 
@@ -236,7 +236,7 @@
      * @return a date based on this one with the days added, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    abstract ChronoDateImpl<C> plusDays(long daysToAdd);
+    abstract D plusDays(long daysToAdd);
 
     //-----------------------------------------------------------------------
     /**
@@ -255,8 +255,8 @@
      * @return a date based on this one with the years subtracted, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    ChronoDateImpl<C> minusYears(long yearsToSubtract) {
-        return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract));
+    D minusYears(long yearsToSubtract) {
+        return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract));
     }
 
     /**
@@ -275,8 +275,8 @@
      * @return a date based on this one with the months subtracted, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    ChronoDateImpl<C> minusMonths(long monthsToSubtract) {
-        return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract));
+    D minusMonths(long monthsToSubtract) {
+        return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract));
     }
 
     /**
@@ -294,8 +294,8 @@
      * @return a date based on this one with the weeks subtracted, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    ChronoDateImpl<C> minusWeeks(long weeksToSubtract) {
-        return (weeksToSubtract == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeksToSubtract));
+    D minusWeeks(long weeksToSubtract) {
+        return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract));
     }
 
     /**
@@ -311,13 +311,8 @@
      * @return a date based on this one with the days subtracted, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    ChronoDateImpl<C> minusDays(long daysToSubtract) {
-        return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
-    }
-
-    @Override
-    public final ChronoLocalDateTime<C> atTime(LocalTime localTime) {
-        return Chrono.dateTime(this, localTime);
+    D minusDays(long daysToSubtract) {
+        return (daysToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract));
     }
 
     //-----------------------------------------------------------------------
@@ -332,13 +327,13 @@
             throw new DateTimeException("Unable to calculate period between objects of two different types");
         }
         ChronoLocalDate<?> end = (ChronoLocalDate<?>) endDateTime;
-        if (getChrono().equals(end.getChrono()) == false) {
+        if (getChronology().equals(end.getChronology()) == false) {
             throw new DateTimeException("Unable to calculate period between two different chronologies");
         }
         if (unit instanceof ChronoUnit) {
             return LocalDate.from(this).periodUntil(end, unit);  // TODO: this is wrong
         }
-        return unit.between(this, endDateTime).getAmount();
+        return unit.between(this, endDateTime);
     }
 
     @Override
@@ -355,7 +350,7 @@
     @Override
     public int hashCode() {
         long epDay = toEpochDay();
-        return getChrono().hashCode() ^ ((int) (epDay ^ (epDay >>> 32)));
+        return getChronology().hashCode() ^ ((int) (epDay ^ (epDay >>> 32)));
     }
 
     @Override
@@ -365,7 +360,7 @@
         long moy = getLong(MONTH_OF_YEAR);
         long dom = getLong(DAY_OF_MONTH);
         StringBuilder buf = new StringBuilder(30);
-        buf.append(getChrono().toString())
+        buf.append(getChronology().toString())
                 .append(" ")
                 .append(getEra())
                 .append(" ")
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java
similarity index 86%
rename from jdk/src/share/classes/java/time/temporal/ChronoLocalDate.java
rename to jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java
index 4701296..1248850 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoLocalDate.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.EPOCH_DAY;
 import static java.time.temporal.ChronoField.ERA;
@@ -69,7 +69,18 @@
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.time.Period;
 import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
 import java.util.Comparator;
 import java.util.Objects;
 
@@ -81,7 +92,7 @@
  * as {@link LocalDate}, not this interface.</b>
  * <p>
  * A {@code ChronoLocalDate} is the abstract representation of a date where the
- * {@code Chrono chronology}, or calendar system, is pluggable.
+ * {@code Chronology chronology}, or calendar system, is pluggable.
  * The date is defined in terms of fields expressed by {@link TemporalField},
  * where most common implementations are defined in {@link ChronoField}.
  * The chronology defines how the calendar system operates and the meaning of
@@ -93,7 +104,7 @@
  * calendar systems. The rationale for this is explored in the following documentation.
  * <p>
  * The primary use case where this interface should be used is where the generic
- * type parameter {@code <C>} is fully defined as a specific chronology.
+ * type parameter {@code <D>} is fully defined as a specific chronology.
  * In that case, the assumptions of that chronology are known at development
  * time and specified in the code.
  * <p>
@@ -229,12 +240,12 @@
  * Subclasses should be Serializable wherever possible.
  * <p>
  * Additional calendar systems may be added to the system.
- * See {@link Chrono} for more details.
+ * See {@link Chronology} for more details.
  *
- * @param <C> the chronology of this date
+ * @param <D> the concrete type for the date
  * @since 1.8
  */
-public interface ChronoLocalDate<C extends Chrono<C>>
+public interface ChronoLocalDate<D extends ChronoLocalDate<D>>
         extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate<?>> {
 
     /**
@@ -262,12 +273,12 @@
     /**
      * Gets the chronology of this date.
      * <p>
-     * The {@code Chrono} represents the calendar system in use.
+     * The {@code Chronology} represents the calendar system in use.
      * The era and other fields in {@link ChronoField} are defined by the chronology.
      *
      * @return the chronology, not null
      */
-    C getChrono();
+    Chronology getChronology();
 
     /**
      * Gets the era, as defined by the chronology.
@@ -275,17 +286,17 @@
      * The era is, conceptually, the largest division of the time-line.
      * Most calendar systems have a single epoch dividing the time-line into two eras.
      * However, some have multiple eras, such as one for the reign of each leader.
-     * The exact meaning is determined by the {@code Chrono}.
+     * The exact meaning is determined by the {@code Chronology}.
      * <p>
      * All correctly implemented {@code Era} classes are singletons, thus it
      * is valid code to write {@code date.getEra() == SomeChrono.ERA_NAME)}.
      * <p>
-     * This default implementation uses {@link Chrono#eraOf(int)}.
+     * This default implementation uses {@link Chronology#eraOf(int)}.
      *
      * @return the chronology specific era constant applicable at this date, not null
      */
-    public default Era<C> getEra() {
-        return getChrono().eraOf(get(ERA));
+    public default Era getEra() {
+        return getChronology().eraOf(get(ERA));
     }
 
     /**
@@ -295,12 +306,12 @@
      * The exact meaning is determined by the chronology with the constraint that
      * a leap-year must imply a year-length longer than a non leap-year.
      * <p>
-     * This default implementation uses {@link Chrono#isLeapYear(long)}.
+     * This default implementation uses {@link Chronology#isLeapYear(long)}.
      *
      * @return true if this date is in a leap year, false otherwise
      */
     public default boolean isLeapYear() {
-        return getChrono().isLeapYear(getLong(YEAR));
+        return getChronology().isLeapYear(getLong(YEAR));
     }
 
     /**
@@ -330,7 +341,7 @@
         if (field instanceof ChronoField) {
             return ((ChronoField) field).isDateField();
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     //-----------------------------------------------------------------------
@@ -341,8 +352,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> with(TemporalAdjuster adjuster) {
-        return getChrono().ensureChronoLocalDate(Temporal.super.with(adjuster));
+    public default D with(TemporalAdjuster adjuster) {
+        return (D) getChronology().ensureChronoLocalDate(Temporal.super.with(adjuster));
     }
 
     /**
@@ -351,11 +362,11 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> with(TemporalField field, long newValue) {
+    public default D with(TemporalField field, long newValue) {
         if (field instanceof ChronoField) {
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return getChrono().ensureChronoLocalDate(field.doWith(this, newValue));
+        return (D) getChronology().ensureChronoLocalDate(field.adjustInto(this, newValue));
     }
 
     /**
@@ -364,8 +375,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> plus(TemporalAdder adder) {
-        return getChrono().ensureChronoLocalDate(Temporal.super.plus(adder));
+    public default D plus(TemporalAmount amount) {
+        return (D) getChronology().ensureChronoLocalDate(Temporal.super.plus(amount));
     }
 
     /**
@@ -374,11 +385,11 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> plus(long amountToAdd, TemporalUnit unit) {
+    public default D plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return getChrono().ensureChronoLocalDate(unit.doPlus(this, amountToAdd));
+        return (D) getChronology().ensureChronoLocalDate(unit.addTo(this, amountToAdd));
     }
 
     /**
@@ -387,8 +398,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> minus(TemporalSubtractor subtractor) {
-        return getChrono().ensureChronoLocalDate(Temporal.super.minus(subtractor));
+    public default D minus(TemporalAmount amount) {
+        return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amount));
     }
 
     /**
@@ -397,8 +408,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> minus(long amountToSubtract, TemporalUnit unit) {
-        return getChrono().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit));
+    public default D minus(long amountToSubtract, TemporalUnit unit) {
+        return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit));
     }
 
     //-----------------------------------------------------------------------
@@ -423,16 +434,17 @@
     @SuppressWarnings("unchecked")
     @Override
     public default <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) getChrono();
-        }
-        if (query == Queries.precision()) {
+        if (query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
+            return null;
+        } else if (query == Queries.localTime()) {
+            return null;
+        } else if (query == Queries.chronology()) {
+            return (R) getChronology();
+        } else if (query == Queries.precision()) {
             return (R) DAYS;
         }
         // inline TemporalAccessor.super.query(query) as an optimization
-        if (query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
-            return null;
-        }
+        // non-JDK classes are not permitted to make this optimization
         return query.queryFrom(this);
     }
 
@@ -479,14 +491,15 @@
      * For example, the period in days between two dates can be calculated
      * using {@code startDate.periodUntil(endDate, DAYS)}.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, MONTHS);   // this method
-     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MONTHS);
+     *   amount = MONTHS.between(start, end);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
      * <p>
      * The calculation is implemented in this method for {@link ChronoUnit}.
      * The units {@code DAYS}, {@code WEEKS}, {@code MONTHS}, {@code YEARS},
@@ -511,22 +524,40 @@
     @Override  // override for Javadoc
     public abstract long periodUntil(Temporal endDate, TemporalUnit unit);
 
-    //-----------------------------------------------------------------------
     /**
-     * Returns a date-time formed from this date at the specified time.
+     * Calculates the period between this date and another date as a {@code Period}.
      * <p>
-     * This merges the two objects - {@code this} and the specified time -
-     * to form an instance of {@code ChronoLocalDateTime}.
+     * This calculates the period between two dates in terms of years, months and days.
+     * The start and end points are {@code this} and the specified date.
+     * The result will be negative if the end is before the start.
+     * <p>
+     * The calculation is performed using the the chronology of this date.
+     * If necessary, the input date will be converted to match.
+     * <p>
+     * The result of this method can be a negative period if the end is before the start.
+     * The negative sign will be the same in each of year, month and day.
      * <p>
      * This instance is immutable and unaffected by this method call.
+     *
+     * @param endDate  the end date, exclusive, which may be in any chronology, not null
+     * @return the period between this date and the end date, not null
+     * @throws DateTimeException if the period cannot be calculated
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public abstract Period periodUntil(ChronoLocalDate<?> endDate);
+
+    //-----------------------------------------------------------------------
+    /**
+     * Combines this date with a time to create a {@code ChronoLocalDateTime}.
      * <p>
-     * This default implementation creates the date-time.
+     * This returns a {@code ChronoLocalDateTime} formed from this date at the specified time.
+     * All possible combinations of date and time are valid.
      *
      * @param localTime  the local time to use, not null
      * @return the local date-time formed from this date and the specified time, not null
      */
-    public default ChronoLocalDateTime<C> atTime(LocalTime localTime) {
-        return Chrono.dateTime(this, localTime);
+    public default ChronoLocalDateTime<D> atTime(LocalTime localTime) {
+        return (ChronoLocalDateTime<D>)ChronoLocalDateTimeImpl.of(this, localTime);
     }
 
     //-----------------------------------------------------------------------
@@ -578,7 +609,7 @@
     public default int compareTo(ChronoLocalDate<?> other) {
         int cmp = Long.compare(toEpochDay(), other.toEpochDay());
         if (cmp == 0) {
-            cmp = getChrono().compareTo(other.getChrono());
+            cmp = getChronology().compareTo(other.getChronology());
         }
         return cmp;
     }
@@ -676,7 +707,7 @@
      * <p>
      * The default implementation must behave as follows:
      * <pre>
-     *  return formatter.print(this);
+     *  return formatter.format(this);
      * </pre>
      *
      * @param formatter  the formatter to use, not null
@@ -685,7 +716,7 @@
      */
     public default String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
 }
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoLocalDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java
similarity index 82%
rename from jdk/src/share/classes/java/time/temporal/ChronoLocalDateTime.java
rename to jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java
index 1fc12d8..f06bd65 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoLocalDateTime.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.EPOCH_DAY;
 import static java.time.temporal.ChronoField.NANO_OF_DAY;
@@ -72,6 +72,15 @@
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
 import java.time.zone.ZoneRules;
 import java.util.Comparator;
 import java.util.Objects;
@@ -84,7 +93,7 @@
  * as {@link LocalDateTime}, not this interface.</b>
  * <p>
  * A {@code ChronoLocalDateTime} is the abstract representation of a local date-time
- * where the {@code Chrono chronology}, or calendar system, is pluggable.
+ * where the {@code Chronology chronology}, or calendar system, is pluggable.
  * The date-time is defined in terms of fields expressed by {@link TemporalField},
  * where most common implementations are defined in {@link ChronoField}.
  * The chronology defines how the calendar system operates and the meaning of
@@ -103,10 +112,10 @@
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
  *
- * @param <C> the chronology of this date-time
+ * @param <D> the concrete type for the date of this date-time
  * @since 1.8
  */
-public interface ChronoLocalDateTime<C extends Chrono<C>>
+public interface ChronoLocalDateTime<D extends ChronoLocalDate<D>>
         extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDateTime<?>> {
 
     /**
@@ -125,9 +134,9 @@
             new Comparator<ChronoLocalDateTime<?>>() {
         @Override
         public int compare(ChronoLocalDateTime<?> datetime1, ChronoLocalDateTime<?> datetime2) {
-            int cmp = Long.compare(datetime1.getDate().toEpochDay(), datetime2.getDate().toEpochDay());
+            int cmp = Long.compare(datetime1.toLocalDate().toEpochDay(), datetime2.toLocalDate().toEpochDay());
             if (cmp == 0) {
-                cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay());
+                cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay());
             }
             return cmp;
         }
@@ -141,7 +150,7 @@
      *
      * @return the date part of this date-time, not null
      */
-    ChronoLocalDate<C> getDate() ;
+    D toLocalDate() ;
 
     /**
      * Gets the local time part of this date-time.
@@ -151,8 +160,10 @@
      *
      * @return the time part of this date-time, not null
      */
-    LocalTime getTime();
+    LocalTime toLocalTime();
 
+    @Override   // Override to provide javadoc
+    public boolean isSupported(TemporalField field);
 
     //-----------------------------------------------------------------------
     // override for covariant return type
@@ -162,8 +173,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDateTime<C> with(TemporalAdjuster adjuster) {
-        return getDate().getChrono().ensureChronoLocalDateTime(Temporal.super.with(adjuster));
+    public default ChronoLocalDateTime<D> with(TemporalAdjuster adjuster) {
+        return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.with(adjuster)));
     }
 
     /**
@@ -172,7 +183,7 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    ChronoLocalDateTime<C> with(TemporalField field, long newValue);
+    ChronoLocalDateTime<D> with(TemporalField field, long newValue);
 
     /**
      * {@inheritDoc}
@@ -180,8 +191,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDateTime<C> plus(TemporalAdder adder) {
-        return getDate().getChrono().ensureChronoLocalDateTime(Temporal.super.plus(adder));
+    public default ChronoLocalDateTime<D> plus(TemporalAmount amount) {
+        return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.plus(amount)));
     }
 
     /**
@@ -190,7 +201,7 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    ChronoLocalDateTime<C> plus(long amountToAdd, TemporalUnit unit);
+    ChronoLocalDateTime<D> plus(long amountToAdd, TemporalUnit unit);
 
     /**
      * {@inheritDoc}
@@ -198,8 +209,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDateTime<C> minus(TemporalSubtractor subtractor) {
-        return getDate().getChrono().ensureChronoLocalDateTime(Temporal.super.minus(subtractor));
+    public default ChronoLocalDateTime<D> minus(TemporalAmount amount) {
+        return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.minus(amount)));
     }
 
     /**
@@ -208,8 +219,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDateTime<C> minus(long amountToSubtract, TemporalUnit unit) {
-        return getDate().getChrono().ensureChronoLocalDateTime(Temporal.super.minus(amountToSubtract, unit));
+    public default ChronoLocalDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
+        return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.minus(amountToSubtract, unit)));
     }
 
     //-----------------------------------------------------------------------
@@ -234,16 +245,17 @@
     @SuppressWarnings("unchecked")
     @Override
     public default <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) getDate().getChrono();
-        }
-        if (query == Queries.precision()) {
+        if (query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
+            return null;
+        } else if (query == Queries.localTime()) {
+            return (R) toLocalTime();
+        } else if (query == Queries.chronology()) {
+            return (R) toLocalDate().getChronology();
+        } else if (query == Queries.precision()) {
             return (R) NANOS;
         }
         // inline TemporalAccessor.super.query(query) as an optimization
-        if (query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
-            return null;
-        }
+        // non-JDK classes are not permitted to make this optimization
         return query.queryFrom(this);
     }
 
@@ -275,15 +287,16 @@
     @Override
     public default Temporal adjustInto(Temporal temporal) {
         return temporal
-                .with(EPOCH_DAY, getDate().toEpochDay())
-                .with(NANO_OF_DAY, getTime().toNanoOfDay());
+                .with(EPOCH_DAY, toLocalDate().toEpochDay())
+                .with(NANO_OF_DAY, toLocalTime().toNanoOfDay());
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a zoned date-time formed from this date-time and the specified time-zone.
+     * Combines this time with a time-zone to create a {@code ChronoZonedDateTime}.
      * <p>
-     * This creates a zoned date-time matching the input date-time as closely as possible.
+     * This returns a {@code ChronoZonedDateTime} formed from this date-time at the
+     * specified time-zone. The result will match this date-time as closely as possible.
      * Time-zone rules, such as daylight savings, mean that not every local date-time
      * is valid for the specified zone, thus the local date-time may be adjusted.
      * <p>
@@ -302,13 +315,11 @@
      * <p>
      * To obtain the later offset during an overlap, call
      * {@link ChronoZonedDateTime#withLaterOffsetAtOverlap()} on the result of this method.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param zone  the time-zone to use, not null
      * @return the zoned date-time formed from this date-time, not null
      */
-    ChronoZonedDateTime<C> atZone(ZoneId zone);
+    ChronoZonedDateTime<D> atZone(ZoneId zone);
 
     //-----------------------------------------------------------------------
     /**
@@ -324,7 +335,7 @@
      * @return an {@code Instant} representing the same instant, not null
      */
     public default Instant toInstant(ZoneOffset offset) {
-        return Instant.ofEpochSecond(toEpochSecond(offset), getTime().getNano());
+        return Instant.ofEpochSecond(toEpochSecond(offset), toLocalTime().getNano());
     }
 
     /**
@@ -343,8 +354,8 @@
      */
     public default long toEpochSecond(ZoneOffset offset) {
         Objects.requireNonNull(offset, "offset");
-        long epochDay = getDate().toEpochDay();
-        long secs = epochDay * 86400 + getTime().toSecondOfDay();
+        long epochDay = toLocalDate().toEpochDay();
+        long secs = epochDay * 86400 + toLocalTime().toSecondOfDay();
         secs -= offset.getTotalSeconds();
         return secs;
     }
@@ -378,11 +389,11 @@
      */
     @Override
     public default int compareTo(ChronoLocalDateTime<?> other) {
-        int cmp = getDate().compareTo(other.getDate());
+        int cmp = toLocalDate().compareTo(other.toLocalDate());
         if (cmp == 0) {
-            cmp = getTime().compareTo(other.getTime());
+            cmp = toLocalTime().compareTo(other.toLocalTime());
             if (cmp == 0) {
-                cmp = getDate().getChrono().compareTo(other.getDate().getChrono());
+                cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology());
             }
         }
         return cmp;
@@ -403,10 +414,10 @@
      * @return true if this is after the specified date-time
      */
     public default boolean isAfter(ChronoLocalDateTime<?> other) {
-        long thisEpDay = this.getDate().toEpochDay();
-        long otherEpDay = other.getDate().toEpochDay();
+        long thisEpDay = this.toLocalDate().toEpochDay();
+        long otherEpDay = other.toLocalDate().toEpochDay();
         return thisEpDay > otherEpDay ||
-            (thisEpDay == otherEpDay && this.getTime().toNanoOfDay() > other.getTime().toNanoOfDay());
+            (thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() > other.toLocalTime().toNanoOfDay());
     }
 
     /**
@@ -424,10 +435,10 @@
      * @return true if this is before the specified date-time
      */
     public default boolean isBefore(ChronoLocalDateTime<?> other) {
-        long thisEpDay = this.getDate().toEpochDay();
-        long otherEpDay = other.getDate().toEpochDay();
+        long thisEpDay = this.toLocalDate().toEpochDay();
+        long otherEpDay = other.toLocalDate().toEpochDay();
         return thisEpDay < otherEpDay ||
-            (thisEpDay == otherEpDay && this.getTime().toNanoOfDay() < other.getTime().toNanoOfDay());
+            (thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() < other.toLocalTime().toNanoOfDay());
     }
 
     /**
@@ -446,8 +457,8 @@
      */
     public default boolean isEqual(ChronoLocalDateTime<?> other) {
         // Do the time check first, it is cheaper than computing EPOCH day.
-        return this.getTime().toNanoOfDay() == other.getTime().toNanoOfDay() &&
-               this.getDate().toEpochDay() == other.getDate().toEpochDay();
+        return this.toLocalTime().toNanoOfDay() == other.toLocalTime().toNanoOfDay() &&
+               this.toLocalDate().toEpochDay() == other.toLocalDate().toEpochDay();
     }
 
     /**
@@ -485,7 +496,7 @@
      * <p>
      * The default implementation must behave as follows:
      * <pre>
-     *  return formatter.print(this);
+     *  return formatter.format(this);
      * </pre>
      *
      * @param formatter  the formatter to use, not null
@@ -494,6 +505,6 @@
      */
     public default String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 }
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java
similarity index 82%
rename from jdk/src/share/classes/java/time/temporal/ChronoLocalDateTimeImpl.java
rename to jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java
index 4baeec0..9875167 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoLocalDateTimeImpl.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.EPOCH_DAY;
 
@@ -72,6 +72,13 @@
 import java.time.DateTimeException;
 import java.time.LocalTime;
 import java.time.ZoneId;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
 import java.util.Objects;
 
 /**
@@ -88,11 +95,11 @@
  * <h3>Specification for implementors</h3>
  * This class is immutable and thread-safe.
  *
- * @param <C> the chronology of this date
+ * @param <D> the concrete type for the date of this date-time
  * @since 1.8
  */
-final class ChronoLocalDateTimeImpl<C extends Chrono<C>>
-        implements  ChronoLocalDateTime<C>, Temporal, TemporalAdjuster, Serializable {
+final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate<D>>
+        implements  ChronoLocalDateTime<D>, Temporal, TemporalAdjuster, Serializable {
 
     /**
      * Serialization version.
@@ -150,7 +157,7 @@
     /**
      * The date part.
      */
-    private final ChronoLocalDate<C> date;
+    private final D date;
     /**
      * The time part.
      */
@@ -164,8 +171,8 @@
      * @param time  the local time, not null
      * @return the local date-time, not null
      */
-    static <R extends Chrono<R>> ChronoLocalDateTimeImpl<R> of(ChronoLocalDate<R> date, LocalTime time) {
-        return new ChronoLocalDateTimeImpl<>(date, time);
+    static ChronoLocalDateTimeImpl<?> of(ChronoLocalDate<?> date, LocalTime time) {
+        return new ChronoLocalDateTimeImpl(date, time);
     }
 
     /**
@@ -174,7 +181,7 @@
      * @param date  the date part of the date-time, not null
      * @param time  the time part of the date-time, not null
      */
-    private ChronoLocalDateTimeImpl(ChronoLocalDate<C> date, LocalTime time) {
+    private ChronoLocalDateTimeImpl(D date, LocalTime time) {
         Objects.requireNonNull(date, "date");
         Objects.requireNonNull(time, "time");
         this.date = date;
@@ -189,23 +196,23 @@
      * @param newTime  the time of the new date-time, not null
      * @return the date-time, not null
      */
-    private ChronoLocalDateTimeImpl<C> with(Temporal newDate, LocalTime newTime) {
+    private ChronoLocalDateTimeImpl<D> with(Temporal newDate, LocalTime newTime) {
         if (date == newDate && time == newTime) {
             return this;
         }
         // Validate that the new Temporal is a ChronoLocalDate (and not something else)
-        ChronoLocalDate<C> cd = date.getChrono().ensureChronoLocalDate(newDate);
-        return new ChronoLocalDateTimeImpl<>(cd, newTime);
+        D cd = (D)date.getChronology().ensureChronoLocalDate(newDate);
+        return new ChronoLocalDateTimeImpl<>((D)cd, newTime);
     }
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<C> getDate() {
+    public D toLocalDate() {
         return date;
     }
 
     @Override
-    public LocalTime getTime() {
+    public LocalTime toLocalTime() {
         return time;
     }
 
@@ -216,7 +223,7 @@
             ChronoField f = (ChronoField) field;
             return f.isDateField() || f.isTimeField();
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     @Override
@@ -225,7 +232,7 @@
             ChronoField f = (ChronoField) field;
             return (f.isTimeField() ? time.range(field) : date.range(field));
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     @Override
@@ -243,26 +250,26 @@
             ChronoField f = (ChronoField) field;
             return (f.isTimeField() ? time.getLong(field) : date.getLong(field));
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
     @SuppressWarnings("unchecked")
     @Override
-    public ChronoLocalDateTimeImpl<C> with(TemporalAdjuster adjuster) {
+    public ChronoLocalDateTimeImpl<D> with(TemporalAdjuster adjuster) {
         if (adjuster instanceof ChronoLocalDate) {
-            // The Chrono is checked in with(date,time)
-            return with((ChronoLocalDate<C>) adjuster, time);
+            // The Chronology is checked in with(date,time)
+            return with((ChronoLocalDate<D>) adjuster, time);
         } else if (adjuster instanceof LocalTime) {
             return with(date, (LocalTime) adjuster);
         } else if (adjuster instanceof ChronoLocalDateTimeImpl) {
-            return date.getChrono().ensureChronoLocalDateTime((ChronoLocalDateTimeImpl<?>) adjuster);
+            return (ChronoLocalDateTimeImpl<D>)(date.getChronology().ensureChronoLocalDateTime((ChronoLocalDateTimeImpl<?>) adjuster));
         }
-        return date.getChrono().ensureChronoLocalDateTime((ChronoLocalDateTimeImpl<?>) adjuster.adjustInto(this));
+        return (ChronoLocalDateTimeImpl<D>)(date.getChronology().ensureChronoLocalDateTime((ChronoLocalDateTimeImpl<?>) adjuster.adjustInto(this)));
     }
 
     @Override
-    public ChronoLocalDateTimeImpl<C> with(TemporalField field, long newValue) {
+    public ChronoLocalDateTimeImpl<D> with(TemporalField field, long newValue) {
         if (field instanceof ChronoField) {
             ChronoField f = (ChronoField) field;
             if (f.isTimeField()) {
@@ -271,12 +278,12 @@
                 return with(date.with(field, newValue), time);
             }
         }
-        return date.getChrono().ensureChronoLocalDateTime(field.doWith(this, newValue));
+        return (ChronoLocalDateTimeImpl<D>)(date.getChronology().ensureChronoLocalDateTime(field.adjustInto(this, newValue)));
     }
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDateTimeImpl<C> plus(long amountToAdd, TemporalUnit unit) {
+    public ChronoLocalDateTimeImpl<D> plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             ChronoUnit f = (ChronoUnit) unit;
             switch (f) {
@@ -290,31 +297,31 @@
             }
             return with(date.plus(amountToAdd, unit), time);
         }
-        return date.getChrono().ensureChronoLocalDateTime(unit.doPlus(this, amountToAdd));
+        return (ChronoLocalDateTimeImpl<D>)(date.getChronology().ensureChronoLocalDateTime(unit.addTo(this, amountToAdd)));
     }
 
-    private ChronoLocalDateTimeImpl<C> plusDays(long days) {
+    private ChronoLocalDateTimeImpl<D> plusDays(long days) {
         return with(date.plus(days, ChronoUnit.DAYS), time);
     }
 
-    private ChronoLocalDateTimeImpl<C> plusHours(long hours) {
+    private ChronoLocalDateTimeImpl<D> plusHours(long hours) {
         return plusWithOverflow(date, hours, 0, 0, 0);
     }
 
-    private ChronoLocalDateTimeImpl<C> plusMinutes(long minutes) {
+    private ChronoLocalDateTimeImpl<D> plusMinutes(long minutes) {
         return plusWithOverflow(date, 0, minutes, 0, 0);
     }
 
-    ChronoLocalDateTimeImpl<C> plusSeconds(long seconds) {
+    ChronoLocalDateTimeImpl<D> plusSeconds(long seconds) {
         return plusWithOverflow(date, 0, 0, seconds, 0);
     }
 
-    private ChronoLocalDateTimeImpl<C> plusNanos(long nanos) {
+    private ChronoLocalDateTimeImpl<D> plusNanos(long nanos) {
         return plusWithOverflow(date, 0, 0, 0, nanos);
     }
 
     //-----------------------------------------------------------------------
-    private ChronoLocalDateTimeImpl<C> plusWithOverflow(ChronoLocalDate<C> newDate, long hours, long minutes, long seconds, long nanos) {
+    private ChronoLocalDateTimeImpl<D> plusWithOverflow(ChronoLocalDate<?> newDate, long hours, long minutes, long seconds, long nanos) {
         // 9223372036854775808 long, 2147483648 int
         if ((hours | minutes | seconds | nanos) == 0) {
             return with(newDate, time);
@@ -337,7 +344,7 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoZonedDateTime<C> atZone(ZoneId zone) {
+    public ChronoZonedDateTime<D> atZone(ZoneId zone) {
         return ChronoZonedDateTimeImpl.ofBest(this, zone, null);
     }
 
@@ -348,8 +355,8 @@
             throw new DateTimeException("Unable to calculate period between objects of two different types");
         }
         @SuppressWarnings("unchecked")
-        ChronoLocalDateTime<C> end = (ChronoLocalDateTime<C>) endDateTime;
-        if (getDate().getChrono().equals(end.getDate().getChrono()) == false) {
+        ChronoLocalDateTime<D> end = (ChronoLocalDateTime<D>) endDateTime;
+        if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) {
             throw new DateTimeException("Unable to calculate period between two different chronologies");
         }
         if (unit instanceof ChronoUnit) {
@@ -365,15 +372,15 @@
                     case HOURS: amount = Math.multiplyExact(amount, HOURS_PER_DAY); break;
                     case HALF_DAYS: amount = Math.multiplyExact(amount, 2); break;
                 }
-                return Math.addExact(amount, time.periodUntil(end.getTime(), unit));
+                return Math.addExact(amount, time.periodUntil(end.toLocalTime(), unit));
             }
-            ChronoLocalDate<C> endDate = end.getDate();
-            if (end.getTime().isBefore(time)) {
-                endDate = endDate.minus(1, ChronoUnit.DAYS);
+            D endDate = end.toLocalDate();
+            if (end.toLocalTime().isBefore(time)) {
+                endDate = (D)endDate.minus(1, ChronoUnit.DAYS);
             }
             return date.periodUntil(endDate, unit);
         }
-        return unit.between(this, endDateTime).getAmount();
+        return unit.between(this, endDateTime);
     }
 
     //-----------------------------------------------------------------------
@@ -396,7 +403,7 @@
     }
 
     static ChronoLocalDateTime<?> readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        ChronoLocalDate<?> date = (ChronoLocalDate<?>) in.readObject();
+        ChronoLocalDate date = (ChronoLocalDate) in.readObject();
         LocalTime time = (LocalTime) in.readObject();
         return date.atTime(time);
     }
@@ -415,12 +422,12 @@
 
     @Override
     public int hashCode() {
-        return getDate().hashCode() ^ getTime().hashCode();
+        return toLocalDate().hashCode() ^ toLocalTime().hashCode();
     }
 
     @Override
     public String toString() {
-        return getDate().toString() + 'T' + getTime().toString();
+        return toLocalDate().toString() + 'T' + toLocalTime().toString();
     }
 
 }
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoZonedDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java
similarity index 83%
rename from jdk/src/share/classes/java/time/temporal/ChronoZonedDateTime.java
rename to jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java
index 9e172ef..92e018b 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoZonedDateTime.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
@@ -72,6 +72,16 @@
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
 import java.util.Comparator;
 import java.util.Objects;
 
@@ -83,7 +93,7 @@
  * as {@link ZonedDateTime}, not this interface.</b>
  * <p>
  * A {@code ChronoZonedDateTime} is the abstract representation of an offset date-time
- * where the {@code Chrono chronology}, or calendar system, is pluggable.
+ * where the {@code Chronology chronology}, or calendar system, is pluggable.
  * The date-time is defined in terms of fields expressed by {@link TemporalField},
  * where most common implementations are defined in {@link ChronoField}.
  * The chronology defines how the calendar system operates and the meaning of
@@ -102,10 +112,10 @@
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
  *
- * @param <C> the chronology of this date-time
+ * @param <D> the concrete type for the date of this date-time
  * @since 1.8
  */
-public interface ChronoZonedDateTime<C extends Chrono<C>>
+public interface ChronoZonedDateTime<D extends ChronoLocalDate<D>>
         extends Temporal, Comparable<ChronoZonedDateTime<?>> {
 
     /**
@@ -125,7 +135,7 @@
         public int compare(ChronoZonedDateTime<?> datetime1, ChronoZonedDateTime<?> datetime2) {
             int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond());
             if (cmp == 0) {
-                cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay());
+                cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay());
             }
             return cmp;
         }
@@ -137,9 +147,9 @@
             if (field == INSTANT_SECONDS || field == OFFSET_SECONDS) {
                 return field.range();
             }
-            return getDateTime().range(field);
+            return toLocalDateTime().range(field);
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     @Override
@@ -149,7 +159,7 @@
                 case INSTANT_SECONDS: throw new DateTimeException("Field too large for an int: " + field);
                 case OFFSET_SECONDS: return getOffset().getTotalSeconds();
             }
-            return getDateTime().get(field);
+            return toLocalDateTime().get(field);
         }
         return Temporal.super.get(field);
     }
@@ -161,9 +171,9 @@
                 case INSTANT_SECONDS: return toEpochSecond();
                 case OFFSET_SECONDS: return getOffset().getTotalSeconds();
             }
-            return getDateTime().getLong(field);
+            return toLocalDateTime().getLong(field);
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     /**
@@ -174,8 +184,8 @@
      *
      * @return the date part of this date-time, not null
      */
-    public default ChronoLocalDate<C> getDate() {
-        return getDateTime().getDate();
+    public default D toLocalDate() {
+        return toLocalDateTime().toLocalDate();
     }
 
     /**
@@ -186,8 +196,8 @@
      *
      * @return the time part of this date-time, not null
      */
-    public default LocalTime getTime() {
-        return getDateTime().getTime();
+    public default LocalTime toLocalTime() {
+        return toLocalDateTime().toLocalTime();
     }
 
     /**
@@ -198,7 +208,7 @@
      *
      * @return the local date-time part of this date-time, not null
      */
-    ChronoLocalDateTime<C> getDateTime();
+    ChronoLocalDateTime<D> toLocalDateTime();
 
     /**
      * Gets the zone offset, such as '+01:00'.
@@ -237,7 +247,7 @@
      * @throws DateTimeException if no rules can be found for the zone
      * @throws DateTimeException if no rules are valid for this date-time
      */
-    ChronoZonedDateTime<C> withEarlierOffsetAtOverlap();
+    ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
 
     /**
      * Returns a copy of this date-time changing the zone offset to the
@@ -257,7 +267,7 @@
      * @throws DateTimeException if no rules can be found for the zone
      * @throws DateTimeException if no rules are valid for this date-time
      */
-    ChronoZonedDateTime<C> withLaterOffsetAtOverlap();
+    ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
 
     /**
      * Returns a copy of this ZonedDateTime with a different time-zone,
@@ -274,7 +284,7 @@
      * @param zone  the time-zone to change to, not null
      * @return a {@code ChronoZonedDateTime} based on this date-time with the requested zone, not null
      */
-    ChronoZonedDateTime<C> withZoneSameLocal(ZoneId zone);
+    ChronoZonedDateTime<D> withZoneSameLocal(ZoneId zone);
 
     /**
      * Returns a copy of this date-time with a different time-zone,
@@ -293,7 +303,10 @@
      * @return a {@code ChronoZonedDateTime} based on this date-time with the requested zone, not null
      * @throws DateTimeException if the result exceeds the supported date range
      */
-    ChronoZonedDateTime<C> withZoneSameInstant(ZoneId zone);
+    ChronoZonedDateTime<D> withZoneSameInstant(ZoneId zone);
+
+    @Override   // Override to provide javadoc
+    public boolean isSupported(TemporalField field);
 
     //-----------------------------------------------------------------------
     // override for covariant return type
@@ -303,8 +316,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoZonedDateTime<C> with(TemporalAdjuster adjuster) {
-        return getDate().getChrono().ensureChronoZonedDateTime(Temporal.super.with(adjuster));
+    public default ChronoZonedDateTime<D> with(TemporalAdjuster adjuster) {
+        return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.with(adjuster)));
     }
 
     /**
@@ -313,7 +326,7 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    ChronoZonedDateTime<C> with(TemporalField field, long newValue);
+    ChronoZonedDateTime<D> with(TemporalField field, long newValue);
 
     /**
      * {@inheritDoc}
@@ -321,8 +334,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoZonedDateTime<C> plus(TemporalAdder adder) {
-        return getDate().getChrono().ensureChronoZonedDateTime(Temporal.super.plus(adder));
+    public default ChronoZonedDateTime<D> plus(TemporalAmount amount) {
+        return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.plus(amount)));
     }
 
     /**
@@ -331,7 +344,7 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    ChronoZonedDateTime<C> plus(long amountToAdd, TemporalUnit unit);
+    ChronoZonedDateTime<D> plus(long amountToAdd, TemporalUnit unit);
 
     /**
      * {@inheritDoc}
@@ -339,8 +352,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoZonedDateTime<C> minus(TemporalSubtractor subtractor) {
-        return getDate().getChrono().ensureChronoZonedDateTime(Temporal.super.minus(subtractor));
+    public default ChronoZonedDateTime<D> minus(TemporalAmount amount) {
+        return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.minus(amount)));
     }
 
     /**
@@ -349,8 +362,8 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoZonedDateTime<C> minus(long amountToSubtract, TemporalUnit unit) {
-        return getDate().getChrono().ensureChronoZonedDateTime(Temporal.super.minus(amountToSubtract, unit));
+    public default ChronoZonedDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
+        return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.minus(amountToSubtract, unit)));
     }
 
     //-----------------------------------------------------------------------
@@ -377,14 +390,17 @@
     public default <R> R query(TemporalQuery<R> query) {
         if (query == Queries.zone() || query == Queries.zoneId()) {
             return (R) getZone();
-        } else if (query == Queries.chrono()) {
-            return (R) getDate().getChrono();
-        } else if (query == Queries.precision()) {
-            return (R) NANOS;
         } else if (query == Queries.offset()) {
             return (R) getOffset();
+        } else if (query == Queries.localTime()) {
+            return (R) toLocalTime();
+        } else if (query == Queries.chronology()) {
+            return (R) toLocalDate().getChronology();
+        } else if (query == Queries.precision()) {
+            return (R) NANOS;
         }
         // inline TemporalAccessor.super.query(query) as an optimization
+        // non-JDK classes are not permitted to make this optimization
         return query.queryFrom(this);
     }
 
@@ -392,20 +408,22 @@
     /**
      * Converts this date-time to an {@code Instant}.
      * <p>
-     * This combines the {@linkplain #getDateTime() local date-time} and
-     * {@linkplain #getOffset() offset} to form an {@code Instant}.
+     * This returns an {@code Instant} representing the same point on the
+     * time-line as this date-time. The calculation combines the
+     * {@linkplain #toLocalDateTime() local date-time} and
+     * {@linkplain #getOffset() offset}.
      *
      * @return an {@code Instant} representing the same instant, not null
      */
     public default Instant toInstant() {
-        return Instant.ofEpochSecond(toEpochSecond(), getTime().getNano());
+        return Instant.ofEpochSecond(toEpochSecond(), toLocalTime().getNano());
     }
 
     /**
      * Converts this date-time to the number of seconds from the epoch
      * of 1970-01-01T00:00:00Z.
      * <p>
-     * This uses the {@linkplain #getDateTime() local date-time} and
+     * This uses the {@linkplain #toLocalDateTime() local date-time} and
      * {@linkplain #getOffset() offset} to calculate the epoch-second value,
      * which is the number of elapsed seconds from 1970-01-01T00:00:00Z.
      * Instants on the time-line after the epoch are positive, earlier are negative.
@@ -413,8 +431,8 @@
      * @return the number of seconds from the epoch of 1970-01-01T00:00:00Z
      */
     public default long toEpochSecond() {
-        long epochDay = getDate().toEpochDay();
-        long secs = epochDay * 86400 + getTime().toSecondOfDay();
+        long epochDay = toLocalDate().toEpochDay();
+        long secs = epochDay * 86400 + toLocalTime().toSecondOfDay();
         secs -= getOffset().getTotalSeconds();
         return secs;
     }
@@ -439,13 +457,13 @@
     public default int compareTo(ChronoZonedDateTime<?> other) {
         int cmp = Long.compare(toEpochSecond(), other.toEpochSecond());
         if (cmp == 0) {
-            cmp = getTime().getNano() - other.getTime().getNano();
+            cmp = toLocalTime().getNano() - other.toLocalTime().getNano();
             if (cmp == 0) {
-                cmp = getDateTime().compareTo(other.getDateTime());
+                cmp = toLocalDateTime().compareTo(other.toLocalDateTime());
                 if (cmp == 0) {
                     cmp = getZone().getId().compareTo(other.getZone().getId());
                     if (cmp == 0) {
-                        cmp = getDate().getChrono().compareTo(other.getDate().getChrono());
+                        cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology());
                     }
                 }
             }
@@ -470,7 +488,7 @@
         long thisEpochSec = toEpochSecond();
         long otherEpochSec = other.toEpochSecond();
         return thisEpochSec < otherEpochSec ||
-            (thisEpochSec == otherEpochSec && getTime().getNano() < other.getTime().getNano());
+            (thisEpochSec == otherEpochSec && toLocalTime().getNano() < other.toLocalTime().getNano());
     }
 
     /**
@@ -490,7 +508,7 @@
         long thisEpochSec = toEpochSecond();
         long otherEpochSec = other.toEpochSecond();
         return thisEpochSec > otherEpochSec ||
-            (thisEpochSec == otherEpochSec && getTime().getNano() > other.getTime().getNano());
+            (thisEpochSec == otherEpochSec && toLocalTime().getNano() > other.toLocalTime().getNano());
     }
 
     /**
@@ -508,7 +526,7 @@
      */
     public default boolean isEqual(ChronoZonedDateTime<?> other) {
         return toEpochSecond() == other.toEpochSecond() &&
-                getTime().getNano() == other.getTime().getNano();
+                toLocalTime().getNano() == other.toLocalTime().getNano();
     }
 
     //-----------------------------------------------------------------------
@@ -549,7 +567,7 @@
      * <p>
      * The default implementation must behave as follows:
      * <pre>
-     *  return formatter.print(this);
+     *  return formatter.format(this);
      * </pre>
      *
      * @param formatter  the formatter to use, not null
@@ -558,7 +576,7 @@
      */
     public default String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
 }
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoZonedDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java
similarity index 82%
rename from jdk/src/share/classes/java/time/temporal/ChronoZonedDateTimeImpl.java
rename to jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java
index 27efde3..0edd114a5 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoZonedDateTimeImpl.java
+++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoUnit.SECONDS;
 
@@ -74,6 +74,11 @@
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
 import java.time.zone.ZoneOffsetTransition;
 import java.time.zone.ZoneRules;
 import java.util.List;
@@ -93,11 +98,11 @@
  * <h3>Specification for implementors</h3>
  * This class is immutable and thread-safe.
  *
- * @param <C> the chronology of this date
+ * @param <D> the concrete type for the date of this date-time
  * @since 1.8
  */
-final class ChronoZonedDateTimeImpl<C extends Chrono<C>>
-        implements ChronoZonedDateTime<C>, Serializable {
+final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate<D>>
+        implements ChronoZonedDateTime<D>, Serializable {
 
     /**
      * Serialization version.
@@ -107,7 +112,7 @@
     /**
      * The local date-time.
      */
-    private final ChronoLocalDateTimeImpl<C> dateTime;
+    private final ChronoLocalDateTimeImpl<D> dateTime;
     /**
      * The zone offset.
      */
@@ -126,12 +131,12 @@
      * @param preferredOffset  the zone offset, null if no preference
      * @return the zoned date-time, not null
      */
-    static <R extends Chrono<R>> ChronoZonedDateTime<R> ofBest(
+    static <R extends ChronoLocalDate<R>> ChronoZonedDateTime<R> ofBest(
             ChronoLocalDateTimeImpl<R> localDateTime, ZoneId zone, ZoneOffset preferredOffset) {
         Objects.requireNonNull(localDateTime, "localDateTime");
         Objects.requireNonNull(zone, "zone");
         if (zone instanceof ZoneOffset) {
-            return new ChronoZonedDateTimeImpl<R>(localDateTime, (ZoneOffset) zone, zone);
+            return new ChronoZonedDateTimeImpl<>(localDateTime, (ZoneOffset) zone, zone);
         }
         ZoneRules rules = zone.getRules();
         LocalDateTime isoLDT = LocalDateTime.from(localDateTime);
@@ -151,7 +156,7 @@
             }
         }
         Objects.requireNonNull(offset, "offset");  // protect against bad ZoneRules
-        return new ChronoZonedDateTimeImpl<R>(localDateTime, offset, zone);
+        return new ChronoZonedDateTimeImpl<>(localDateTime, offset, zone);
     }
 
     /**
@@ -162,13 +167,13 @@
      * @param zone  the zone identifier, not null
      * @return the zoned date-time, not null
      */
-    static <R extends Chrono<R>> ChronoZonedDateTimeImpl<R> ofInstant(Chrono<R> chrono, Instant instant, ZoneId zone) {
+    static ChronoZonedDateTimeImpl<?> ofInstant(Chronology chrono, Instant instant, ZoneId zone) {
         ZoneRules rules = zone.getRules();
         ZoneOffset offset = rules.getOffset(instant);
         Objects.requireNonNull(offset, "offset");  // protect against bad ZoneRules
         LocalDateTime ldt = LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset);
-        ChronoLocalDateTimeImpl<R> cldt = (ChronoLocalDateTimeImpl<R>) chrono.localDateTime(ldt);
-        return new ChronoZonedDateTimeImpl<R>(cldt, offset, zone);
+        ChronoLocalDateTimeImpl<?> cldt = (ChronoLocalDateTimeImpl<?>) chrono.localDateTime(ldt);
+        return new ChronoZonedDateTimeImpl(cldt, offset, zone);
     }
 
     /**
@@ -178,8 +183,8 @@
      * @param zone  the time-zone to use, validated not null
      * @return the zoned date-time, validated not null
      */
-    private ChronoZonedDateTimeImpl<C> create(Instant instant, ZoneId zone) {
-        return ofInstant(getDate().getChrono(), instant, zone);
+    private ChronoZonedDateTimeImpl<D> create(Instant instant, ZoneId zone) {
+        return (ChronoZonedDateTimeImpl<D>)ofInstant(toLocalDate().getChronology(), instant, zone);
     }
 
     //-----------------------------------------------------------------------
@@ -190,7 +195,7 @@
      * @param offset  the zone offset, not null
      * @param zone  the zone ID, not null
      */
-    private ChronoZonedDateTimeImpl(ChronoLocalDateTimeImpl<C> dateTime, ZoneOffset offset, ZoneId zone) {
+    private ChronoZonedDateTimeImpl(ChronoLocalDateTimeImpl<D> dateTime, ZoneOffset offset, ZoneId zone) {
         this.dateTime = Objects.requireNonNull(dateTime, "dateTime");
         this.offset = Objects.requireNonNull(offset, "offset");
         this.zone = Objects.requireNonNull(zone, "zone");
@@ -202,24 +207,24 @@
     }
 
     @Override
-    public ChronoZonedDateTime<C> withEarlierOffsetAtOverlap() {
+    public ChronoZonedDateTime<D> withEarlierOffsetAtOverlap() {
         ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this));
         if (trans != null && trans.isOverlap()) {
             ZoneOffset earlierOffset = trans.getOffsetBefore();
             if (earlierOffset.equals(offset) == false) {
-                return new ChronoZonedDateTimeImpl<C>(dateTime, earlierOffset, zone);
+                return new ChronoZonedDateTimeImpl<D>(dateTime, earlierOffset, zone);
             }
         }
         return this;
     }
 
     @Override
-    public ChronoZonedDateTime<C> withLaterOffsetAtOverlap() {
+    public ChronoZonedDateTime<D> withLaterOffsetAtOverlap() {
         ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this));
         if (trans != null) {
             ZoneOffset offset = trans.getOffsetAfter();
             if (offset.equals(getOffset()) == false) {
-                return new ChronoZonedDateTimeImpl<C>(dateTime, offset, zone);
+                return new ChronoZonedDateTimeImpl<D>(dateTime, offset, zone);
             }
         }
         return this;
@@ -227,7 +232,7 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDateTime<C> getDateTime() {
+    public ChronoLocalDateTime<D> toLocalDateTime() {
         return dateTime;
     }
 
@@ -235,12 +240,12 @@
         return zone;
     }
 
-    public ChronoZonedDateTime<C> withZoneSameLocal(ZoneId zone) {
+    public ChronoZonedDateTime<D> withZoneSameLocal(ZoneId zone) {
         return ofBest(dateTime, zone, offset);
     }
 
     @Override
-    public ChronoZonedDateTime<C> withZoneSameInstant(ZoneId zone) {
+    public ChronoZonedDateTime<D> withZoneSameInstant(ZoneId zone) {
         Objects.requireNonNull(zone, "zone");
         return this.zone.equals(zone) ? this : create(dateTime.toInstant(offset), zone);
     }
@@ -248,12 +253,12 @@
     //-----------------------------------------------------------------------
     @Override
     public boolean isSupported(TemporalField field) {
-        return field instanceof ChronoField || (field != null && field.doIsSupported(this));
+        return field instanceof ChronoField || (field != null && field.isSupportedBy(this));
     }
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoZonedDateTime<C> with(TemporalField field, long newValue) {
+    public ChronoZonedDateTime<D> with(TemporalField field, long newValue) {
         if (field instanceof ChronoField) {
             ChronoField f = (ChronoField) field;
             switch (f) {
@@ -265,16 +270,16 @@
             }
             return ofBest(dateTime.with(field, newValue), zone, offset);
         }
-        return getDate().getChrono().ensureChronoZonedDateTime(field.doWith(this, newValue));
+        return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(field.adjustInto(this, newValue)));
     }
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoZonedDateTime<C> plus(long amountToAdd, TemporalUnit unit) {
+    public ChronoZonedDateTime<D> plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             return with(dateTime.plus(amountToAdd, unit));
         }
-        return getDate().getChrono().ensureChronoZonedDateTime(unit.doPlus(this, amountToAdd));   /// TODO: Generics replacement Risk!
+        return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(unit.addTo(this, amountToAdd)));   /// TODO: Generics replacement Risk!
     }
 
     //-----------------------------------------------------------------------
@@ -284,15 +289,15 @@
             throw new DateTimeException("Unable to calculate period between objects of two different types");
         }
         @SuppressWarnings("unchecked")
-        ChronoZonedDateTime<C> end = (ChronoZonedDateTime<C>) endDateTime;
-        if (getDate().getChrono().equals(end.getDate().getChrono()) == false) {
+        ChronoZonedDateTime<D> end = (ChronoZonedDateTime<D>) endDateTime;
+        if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) {
             throw new DateTimeException("Unable to calculate period between two different chronologies");
         }
         if (unit instanceof ChronoUnit) {
             end = end.withZoneSameInstant(offset);
-            return dateTime.periodUntil(end.getDateTime(), unit);
+            return dateTime.periodUntil(end.toLocalDateTime(), unit);
         }
-        return unit.between(this, endDateTime).getAmount();
+        return unit.between(this, endDateTime);
     }
 
     //-----------------------------------------------------------------------
@@ -337,12 +342,12 @@
 
     @Override
     public int hashCode() {
-        return getDateTime().hashCode() ^ getOffset().hashCode() ^ Integer.rotateLeft(getZone().hashCode(), 3);
+        return toLocalDateTime().hashCode() ^ getOffset().hashCode() ^ Integer.rotateLeft(getZone().hashCode(), 3);
     }
 
     @Override
     public String toString() {
-        String str = getDateTime().toString() + getOffset().toString();
+        String str = toLocalDateTime().toString() + getOffset().toString();
         if (getOffset() != getZone()) {
             str += '[' + getZone().toString() + ']';
         }
diff --git a/jdk/src/share/classes/java/time/temporal/Chrono.java b/jdk/src/share/classes/java/time/chrono/Chronology.java
similarity index 68%
rename from jdk/src/share/classes/java/time/temporal/Chrono.java
rename to jdk/src/share/classes/java/time/chrono/Chronology.java
index ff46608..ed4aacd 100644
--- a/jdk/src/share/classes/java/time/temporal/Chrono.java
+++ b/jdk/src/share/classes/java/time/chrono/Chronology.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
 import java.io.DataInput;
 import java.io.DataOutput;
@@ -72,12 +72,19 @@
 import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.ZoneId;
-import java.time.calendar.HijrahChrono;
-import java.time.calendar.JapaneseChrono;
-import java.time.calendar.MinguoChrono;
-import java.time.calendar.ThaiBuddhistChrono;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.TextStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.ValueRange;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
@@ -95,30 +102,30 @@
  * <p>
  * Most other calendar systems also operate on the shared concepts of year, month and day,
  * linked to the cycles of the Earth around the Sun, and the Moon around the Earth.
- * These shared concepts are defined by {@link ChronoField} and are availalbe
- * for use by any {@code Chrono} implementation:
+ * These shared concepts are defined by {@link ChronoField} and are available
+ * for use by any {@code Chronology} implementation:
  * <pre>
  *   LocalDate isoDate = ...
- *   ChronoLocalDate&lt;ThaiBuddhistChrono&gt; thaiDate = ...
+ *   ChronoLocalDate&lt;ThaiBuddhistChronology&gt; thaiDate = ...
  *   int isoYear = isoDate.get(ChronoField.YEAR);
  *   int thaiYear = thaiDate.get(ChronoField.YEAR);
  * </pre>
  * As shown, although the date objects are in different calendar systems, represented by different
- * {@code Chrono} instances, both can be queried using the same constant on {@code ChronoField}.
+ * {@code Chronology} instances, both can be queried using the same constant on {@code ChronoField}.
  * For a full discussion of the implications of this, see {@link ChronoLocalDate}.
  * In general, the advice is to use the known ISO-based {@code LocalDate}, rather than
  * {@code ChronoLocalDate}.
  * <p>
- * While a {@code Chrono} object typically uses {@code ChronoField} and is based on
+ * While a {@code Chronology} object typically uses {@code ChronoField} and is based on
  * an era, year-of-era, month-of-year, day-of-month model of a date, this is not required.
- * A {@code Chrono} instance may represent a totally different kind of calendar system,
+ * A {@code Chronology} instance may represent a totally different kind of calendar system,
  * such as the Mayan.
  * <p>
- * In practical terms, the {@code Chrono} instance also acts as a factory.
+ * In practical terms, the {@code Chronology} instance also acts as a factory.
  * The {@link #of(String)} method allows an instance to be looked up by identifier,
  * while the {@link #ofLocale(Locale)} method allows lookup by locale.
  * <p>
- * The {@code Chrono} instance provides a set of methods to create {@code ChronoLocalDate} instances.
+ * The {@code Chronology} instance provides a set of methods to create {@code ChronoLocalDate} instances.
  * The date classes are used to manipulate specific dates.
  * <p><ul>
  * <li> {@link #dateNow() dateNow()}
@@ -131,16 +138,16 @@
  * <li> {@link #date(TemporalAccessor) date(TemporalAccessor)}
  * </ul><p>
  *
- * <p id="addcalendars">Adding New Calendars</p>
+ * <h3 id="addcalendars">Adding New Calendars</h3>
  * The set of available chronologies can be extended by applications.
  * Adding a new calendar system requires the writing of an implementation of
- * {@code Chrono}, {@code ChronoLocalDate} and {@code Era}.
+ * {@code Chronology}, {@code ChronoLocalDate} and {@code Era}.
  * The majority of the logic specific to the calendar system will be in
- * {@code ChronoLocalDate}. The {@code Chrono} subclass acts as a factory.
+ * {@code ChronoLocalDate}. The {@code Chronology} subclass acts as a factory.
  * <p>
  * To permit the discovery of additional chronologies, the {@link java.util.ServiceLoader ServiceLoader}
  * is used. A file must be added to the {@code META-INF/services} directory with the
- * name 'java.time.temporal.Chrono' listing the implementation classes.
+ * name 'java.time.chrono.Chronology' listing the implementation classes.
  * See the ServiceLoader for more details on service loading.
  * For lookup by id or calendarType, the system provided calendars are found
  * first followed by application provided calendars.
@@ -155,28 +162,27 @@
  * All implementations that can be instantiated must be final, immutable and thread-safe.
  * Subclasses should be Serializable wherever possible.
  *
- * @param <C> the type of the implementing subclass
  * @since 1.8
  */
-public abstract class Chrono<C extends Chrono<C>> implements Comparable<Chrono<?>> {
+public abstract class Chronology implements Comparable<Chronology> {
 
     /**
      * Map of available calendars by ID.
      */
-    private static final ConcurrentHashMap<String, Chrono<?>> CHRONOS_BY_ID = new ConcurrentHashMap<>();
+    private static final ConcurrentHashMap<String, Chronology> CHRONOS_BY_ID = new ConcurrentHashMap<>();
     /**
      * Map of available calendars by calendar type.
      */
-    private static final ConcurrentHashMap<String, Chrono<?>> CHRONOS_BY_TYPE = new ConcurrentHashMap<>();
+    private static final ConcurrentHashMap<String, Chronology> CHRONOS_BY_TYPE = new ConcurrentHashMap<>();
 
     /**
-     * Register a Chrono by ID and type for lookup by {@link #of(java.lang.String)}.
+     * Register a Chronology by ID and type for lookup by {@link #of(java.lang.String)}.
      * Chronos must not be registered until they are completely constructed.
-     * Specifically, not in the constructor of Chrono.
+     * Specifically, not in the constructor of Chronology.
      * @param chrono the chronology to register; not null
      */
-    private static void registerChrono(Chrono chrono) {
-        Chrono<?> prev = CHRONOS_BY_ID.putIfAbsent(chrono.getId(), chrono);
+    private static void registerChrono(Chronology chrono) {
+        Chronology prev = CHRONOS_BY_ID.putIfAbsent(chrono.getId(), chrono);
         if (prev == null) {
             String type = chrono.getCalendarType();
             if (type != null) {
@@ -186,17 +192,17 @@
     }
 
     /**
-     * Initialization of the maps from id and type to Chrono.
+     * Initialization of the maps from id and type to Chronology.
      * The ServiceLoader is used to find and register any implementations
-     * of {@link javax.time.temporal.Chrono} found in the bootclass loader.
+     * of {@link java.time.chrono.Chronology} found in the bootclass loader.
      * The built-in chronologies are registered explicitly.
      * Calendars configured via the Thread's context classloader are local
      * to that thread and are ignored.
      * <p>
      * The initialization is done only once using the registration
-     * of the ISOChrono as the test and the final step.
+     * of the IsoChronology as the test and the final step.
      * Multiple threads may perform the initialization concurrently.
-     * Only the first registration of each Chrono is retained by the
+     * Only the first registration of each Chronology is retained by the
      * ConcurrentHashMap.
      * @return true if the cache was initialized
      */
@@ -204,19 +210,19 @@
         if (CHRONOS_BY_ID.get("ISO") == null) {
             // Initialization is incomplete
             @SuppressWarnings("rawtypes")
-            ServiceLoader<Chrono> loader =  ServiceLoader.load(Chrono.class, null);
-            for (Chrono<?> chrono : loader) {
+            ServiceLoader<Chronology> loader =  ServiceLoader.load(Chronology.class, null);
+            for (Chronology chrono : loader) {
                 registerChrono(chrono);
             }
 
             // Register these calendars; the ServiceLoader configuration is not used
-            registerChrono(HijrahChrono.INSTANCE);
-            registerChrono(JapaneseChrono.INSTANCE);
-            registerChrono(MinguoChrono.INSTANCE);
-            registerChrono(ThaiBuddhistChrono.INSTANCE);
+            registerChrono(HijrahChronology.INSTANCE);
+            registerChrono(JapaneseChronology.INSTANCE);
+            registerChrono(MinguoChronology.INSTANCE);
+            registerChrono(ThaiBuddhistChronology.INSTANCE);
 
-            // finally, register ISOChrono to mark initialization is complete
-            registerChrono(ISOChrono.INSTANCE);
+            // finally, register IsoChronology to mark initialization is complete
+            registerChrono(IsoChronology.INSTANCE);
             return true;
         }
         return false;
@@ -224,61 +230,89 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Chrono} from a temporal object.
+     * Obtains an instance of {@code Chronology} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code Chrono}.
-     * If the specified temporal object does not have a chronology, {@link ISOChrono} is returned.
+     * This obtains a chronology based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code Chronology}.
      * <p>
-     * The conversion will obtain the chronology using {@link Queries#chrono()}.
+     * The conversion will obtain the chronology using {@link Queries#chronology()}.
+     * If the specified temporal object does not have a chronology, {@link IsoChronology} is returned.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
-     * allowing it to be used in queries via method reference, {@code Chrono::from}.
+     * allowing it to be used in queries via method reference, {@code Chronology::from}.
      *
      * @param temporal  the temporal to convert, not null
      * @return the chronology, not null
-     * @throws DateTimeException if unable to convert to an {@code Chrono}
+     * @throws DateTimeException if unable to convert to an {@code Chronology}
      */
-    public static Chrono<?> from(TemporalAccessor temporal) {
+    public static Chronology from(TemporalAccessor temporal) {
         Objects.requireNonNull(temporal, "temporal");
-        Chrono<?> obj = temporal.query(Queries.chrono());
-        return (obj != null ? obj : ISOChrono.INSTANCE);
+        Chronology obj = temporal.query(Queries.chronology());
+        return (obj != null ? obj : IsoChronology.INSTANCE);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Chrono} from a locale.
+     * Obtains an instance of {@code Chronology} from a locale.
      * <p>
-     * The locale can be used to identify a calendar.
-     * This uses {@link Locale#getUnicodeLocaleType(String)} to obtain the "ca" key
-     * to identify the calendar system.
+     * This returns a {@code Chronology} based on the specified locale,
+     * typically returning {@code IsoChronology}. Other calendar systems
+     * are only returned if they are explicitly selected within the locale.
      * <p>
-     * If the locale does not contain calendar system information, the standard
-     * ISO calendar system is used.
+     * The {@link Locale} class provide access to a range of information useful
+     * for localizing an application. This includes the language and region,
+     * such as "en-GB" for English as used in Great Britain.
+     * <p>
+     * The {@code Locale} class also supports an extension mechanism that
+     * can be used to identify a calendar system. The mechanism is a form
+     * of key-value pairs, where the calendar system has the key "ca".
+     * For example, the locale "en-JP-u-ca-japanese" represents the English
+     * language as used in Japan with the Japanese calendar system.
+     * <p>
+     * This method finds the desired calendar system by in a manner equivalent
+     * to passing "ca" to {@link Locale#getUnicodeLocaleType(String)}.
+     * If the "ca" key is not present, then {@code IsoChronology} is returned.
+     * <p>
+     * Note that the behavior of this method differs from the older
+     * {@link java.util.Calendar#getInstance(Locale)} method.
+     * If that method receives a locale of "th_TH" it will return {@code BuddhistCalendar}.
+     * By contrast, this method will return {@code IsoChronology}.
+     * Passing the locale "th-TH-u-ca-buddhist" into either method will
+     * result in the Thai Buddhist calendar system and is therefore the
+     * recommended approach going forward for Thai calendar system localization.
+     * <p>
+     * A similar, but simpler, situation occurs for the Japanese calendar system.
+     * The locale "jp_JP_JP" has previously been used to access the calendar.
+     * However, unlike the Thai locale, "ja_JP_JP" is automatically converted by
+     * {@code Locale} to the modern and recommended form of "ja-JP-u-ca-japanese".
+     * Thus, there is no difference in behavior between this method and
+     * {@code Calendar#getInstance(Locale)}.
      *
      * @param locale  the locale to use to obtain the calendar system, not null
      * @return the calendar system associated with the locale, not null
      * @throws DateTimeException if the locale-specified calendar cannot be found
      */
-    public static Chrono<?> ofLocale(Locale locale) {
+    public static Chronology ofLocale(Locale locale) {
         Objects.requireNonNull(locale, "locale");
         String type = locale.getUnicodeLocaleType("ca");
-        if (type == null) {
-            return ISOChrono.INSTANCE;
-        } else if ("iso".equals(type) || "iso8601".equals(type)) {
-            return ISOChrono.INSTANCE;
-        } else {
-            Chrono<?> chrono = CHRONOS_BY_TYPE.get(type);
-            if (chrono == null) {
-                throw new DateTimeException("Unknown calendar system: " + type);
-            }
-            return chrono;
+        if (type == null || "iso".equals(type) || "iso8601".equals(type)) {
+            return IsoChronology.INSTANCE;
         }
+        // Not pre-defined; lookup by the type
+        do {
+            Chronology chrono = CHRONOS_BY_TYPE.get(type);
+            if (chrono != null) {
+                return chrono;
+            }
+            // If not found, do the initialization (once) and repeat the lookup
+        } while (initCache());
+        throw new DateTimeException("Unknown calendar system: " + type);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code Chrono} from a chronology ID or
+     * Obtains an instance of {@code Chronology} from a chronology ID or
      * calendar system type.
      * <p>
      * This returns a chronology based on either the ID or the type.
@@ -296,21 +330,21 @@
      * @return the chronology with the identifier requested, not null
      * @throws DateTimeException if the chronology cannot be found
      */
-    public static Chrono<?> of(String id) {
+    public static Chronology of(String id) {
         Objects.requireNonNull(id, "id");
         do {
-            Chrono chrono = of0(id);
+            Chronology chrono = of0(id);
             if (chrono != null) {
                 return chrono;
             }
             // If not found, do the initialization (once) and repeat the lookup
         } while (initCache());
 
-        // Look for a Chrono using ServiceLoader of the Thread's ContextClassLoader
+        // Look for a Chronology using ServiceLoader of the Thread's ContextClassLoader
         // Application provided Chronologies must not be cached
         @SuppressWarnings("rawtypes")
-        ServiceLoader<Chrono> loader = ServiceLoader.load(Chrono.class);
-        for (Chrono<?> chrono : loader) {
+        ServiceLoader<Chronology> loader = ServiceLoader.load(Chronology.class);
+        for (Chronology chrono : loader) {
             if (id.equals(chrono.getId()) || id.equals(chrono.getCalendarType())) {
                 return chrono;
             }
@@ -319,14 +353,14 @@
     }
 
     /**
-     * Obtains an instance of {@code Chrono} from a chronology ID or
+     * Obtains an instance of {@code Chronology} from a chronology ID or
      * calendar system type.
      *
      * @param id  the chronology ID or calendar system type, not null
      * @return the chronology with the identifier requested, or {@code null} if not found
      */
-    private static Chrono<?> of0(String id) {
-        Chrono<?> chrono = CHRONOS_BY_ID.get(id);
+    private static Chronology of0(String id) {
+        Chronology chrono = CHRONOS_BY_ID.get(id);
         if (chrono == null) {
             chrono = CHRONOS_BY_TYPE.get(id);
         }
@@ -336,21 +370,21 @@
     /**
      * Returns the available chronologies.
      * <p>
-     * Each returned {@code Chrono} is available for use in the system.
+     * Each returned {@code Chronology} is available for use in the system.
      * The set of chronologies includes the system chronologies and
      * any chronologies provided by the application via ServiceLoader
      * configuration.
      *
      * @return the independent, modifiable set of the available chronology IDs, not null
      */
-    public static Set<Chrono<?>> getAvailableChronologies() {
+    public static Set<Chronology> getAvailableChronologies() {
         initCache();       // force initialization
-        HashSet<Chrono<?>> chronos = new HashSet<>(CHRONOS_BY_ID.values());
+        HashSet<Chronology> chronos = new HashSet(CHRONOS_BY_ID.values());
 
         /// Add in Chronologies from the ServiceLoader configuration
         @SuppressWarnings("rawtypes")
-        ServiceLoader<Chrono> loader = ServiceLoader.load(Chrono.class);
-        for (Chrono<?> chrono : loader) {
+        ServiceLoader<Chronology> loader = ServiceLoader.load(Chronology.class);
+        for (Chronology chrono : loader) {
             chronos.add(chrono);
         }
         return chronos;
@@ -358,28 +392,9 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains a local date-time from the a date and time.
-     * <p>
-     * This combines a {@link ChronoLocalDate}, which provides the {@code Chrono},
-     * with a {@link LocalTime} to produce a {@link ChronoLocalDateTime}.
-     * <p>
-     * This method is intended for chronology implementations.
-     * It uses a standard implementation that is shared for all chronologies.
-     *
-     * @param <R>  the chronology of the date
-     * @param date  the date, not null
-     * @param time  the time, not null
-     * @return the local date-time combining the input date and time, not null
-     */
-    public static <R extends Chrono<R>> ChronoLocalDateTime<R> dateTime(ChronoLocalDate<R> date, LocalTime time) {
-        return ChronoLocalDateTimeImpl.of(date, time);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
      * Creates an instance.
      */
-    protected Chrono() {
+    protected Chronology() {
     }
 
     //-----------------------------------------------------------------------
@@ -389,13 +404,13 @@
      * @param temporal  a date-time to cast, not null
      * @return the date-time checked and cast to {@code ChronoLocalDate}, not null
      * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDate
-     *  or the chronology is not equal this Chrono
+     *  or the chronology is not equal this Chronology
      */
-    ChronoLocalDate<C> ensureChronoLocalDate(Temporal temporal) {
+    ChronoLocalDate ensureChronoLocalDate(Temporal temporal) {
         @SuppressWarnings("unchecked")
-        ChronoLocalDate<C> other = (ChronoLocalDate<C>) temporal;
-        if (this.equals(other.getChrono()) == false) {
-            throw new ClassCastException("Chrono mismatch, expected: " + getId() + ", actual: " + other.getChrono().getId());
+        ChronoLocalDate other = (ChronoLocalDate) temporal;
+        if (this.equals(other.getChronology()) == false) {
+            throw new ClassCastException("Chronology mismatch, expected: " + getId() + ", actual: " + other.getChronology().getId());
         }
         return other;
     }
@@ -406,14 +421,14 @@
      * @param temporal   a date-time to cast, not null
      * @return the date-time checked and cast to {@code ChronoLocalDateTime}, not null
      * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDateTimeImpl
-     *  or the chronology is not equal this Chrono
+     *  or the chronology is not equal this Chronology
      */
-    ChronoLocalDateTimeImpl<C> ensureChronoLocalDateTime(Temporal temporal) {
+    ChronoLocalDateTimeImpl<?> ensureChronoLocalDateTime(Temporal temporal) {
         @SuppressWarnings("unchecked")
-        ChronoLocalDateTimeImpl<C> other = (ChronoLocalDateTimeImpl<C>) temporal;
-        if (this.equals(other.getDate().getChrono()) == false) {
-            throw new ClassCastException("Chrono mismatch, required: " + getId()
-                    + ", supplied: " + other.getDate().getChrono().getId());
+        ChronoLocalDateTimeImpl<?> other = (ChronoLocalDateTimeImpl<?>) temporal;
+        if (this.equals(other.toLocalDate().getChronology()) == false) {
+            throw new ClassCastException("Chronology mismatch, required: " + getId()
+                    + ", supplied: " + other.toLocalDate().getChronology().getId());
         }
         return other;
     }
@@ -424,14 +439,14 @@
      * @param temporal  a date-time to cast, not null
      * @return the date-time checked and cast to {@code ChronoZonedDateTimeImpl}, not null
      * @throws ClassCastException if the date-time cannot be cast to ChronoZonedDateTimeImpl
-     *  or the chronology is not equal this Chrono
+     *  or the chronology is not equal this Chronology
      */
-    ChronoZonedDateTimeImpl<C> ensureChronoZonedDateTime(Temporal temporal) {
+    ChronoZonedDateTimeImpl<?> ensureChronoZonedDateTime(Temporal temporal) {
         @SuppressWarnings("unchecked")
-        ChronoZonedDateTimeImpl<C> other = (ChronoZonedDateTimeImpl<C>) temporal;
-        if (this.equals(other.getDate().getChrono()) == false) {
-            throw new ClassCastException("Chrono mismatch, required: " + getId()
-                    + ", supplied: " + other.getDate().getChrono().getId());
+        ChronoZonedDateTimeImpl<?> other = (ChronoZonedDateTimeImpl<?>) temporal;
+        if (this.equals(other.toLocalDate().getChronology()) == false) {
+            throw new ClassCastException("Chronology mismatch, required: " + getId()
+                    + ", supplied: " + other.toLocalDate().getChronology().getId());
         }
         return other;
     }
@@ -440,8 +455,8 @@
     /**
      * Gets the ID of the chronology.
      * <p>
-     * The ID uniquely identifies the {@code Chrono}.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * The ID uniquely identifies the {@code Chronology}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      *
      * @return the chronology ID, not null
      * @see #getCalendarType()
@@ -453,7 +468,7 @@
      * <p>
      * The calendar type is an identifier defined by the
      * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      * It can also be used as part of a locale, accessible via
      * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
      *
@@ -474,7 +489,7 @@
      * @return the local date in this chronology, not null
      * @throws DateTimeException if unable to create the date
      */
-    public ChronoLocalDate<C> date(Era<C> era, int yearOfEra, int month, int dayOfMonth) {
+    public ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
         return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
     }
 
@@ -488,7 +503,7 @@
      * @return the local date in this chronology, not null
      * @throws DateTimeException if unable to create the date
      */
-    public abstract ChronoLocalDate<C> date(int prolepticYear, int month, int dayOfMonth);
+    public abstract ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth);
 
     /**
      * Obtains a local date in this chronology from the era, year-of-era and
@@ -500,7 +515,7 @@
      * @return the local date in this chronology, not null
      * @throws DateTimeException if unable to create the date
      */
-    public ChronoLocalDate<C> dateYearDay(Era<C> era, int yearOfEra, int dayOfYear) {
+    public ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
         return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
     }
 
@@ -513,21 +528,7 @@
      * @return the local date in this chronology, not null
      * @throws DateTimeException if unable to create the date
      */
-    public abstract ChronoLocalDate<C> dateYearDay(int prolepticYear, int dayOfYear);
-
-    /**
-     * Obtains a local date in this chronology from another temporal object.
-     * <p>
-     * This creates a date in this chronology based on the specified {@code TemporalAccessor}.
-     * <p>
-     * The standard mechanism for conversion between date types is the
-     * {@link ChronoField#EPOCH_DAY local epoch-day} field.
-     *
-     * @param temporal  the temporal object to convert, not null
-     * @return the local date in this chronology, not null
-     * @throws DateTimeException if unable to create the date
-     */
-    public abstract ChronoLocalDate<C> date(TemporalAccessor temporal);
+    public abstract ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear);
 
     //-----------------------------------------------------------------------
     /**
@@ -544,7 +545,7 @@
      * @return the current local date using the system clock and default time-zone, not null
      * @throws DateTimeException if unable to create the date
      */
-    public ChronoLocalDate<C> dateNow() {
+    public ChronoLocalDate dateNow() {
         return dateNow(Clock.systemDefaultZone());
     }
 
@@ -561,7 +562,7 @@
      * @return the current local date using the system clock, not null
      * @throws DateTimeException if unable to create the date
      */
-    public ChronoLocalDate<C> dateNow(ZoneId zone) {
+    public ChronoLocalDate dateNow(ZoneId zone) {
         return dateNow(Clock.system(zone));
     }
 
@@ -576,27 +577,52 @@
      * @return the current local date, not null
      * @throws DateTimeException if unable to create the date
      */
-    public ChronoLocalDate<C> dateNow(Clock clock) {
+    public ChronoLocalDate dateNow(Clock clock) {
         Objects.requireNonNull(clock, "clock");
         return date(LocalDate.now(clock));
     }
 
     //-----------------------------------------------------------------------
     /**
+     * Obtains a local date in this chronology from another temporal object.
+     * <p>
+     * This creates a date in this chronology based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code ChronoLocalDate}.
+     * <p>
+     * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
+     * field, which is standardized across calendar systems.
+     * <p>
+     * This method matches the signature of the functional interface {@link TemporalQuery}
+     * allowing it to be used as a query via method reference, {@code aChronology::date}.
+     *
+     * @param temporal  the temporal object to convert, not null
+     * @return the local date in this chronology, not null
+     * @throws DateTimeException if unable to create the date
+     */
+    public abstract ChronoLocalDate date(TemporalAccessor temporal);
+
+    /**
      * Obtains a local date-time in this chronology from another temporal object.
      * <p>
-     * This creates a date-time in this chronology based on the specified {@code TemporalAccessor}.
+     * This creates a date-time in this chronology based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code ChronoLocalDateTime}.
      * <p>
-     * The date of the date-time should be equivalent to that obtained by calling
-     * {@link #date(TemporalAccessor)}.
-     * The standard mechanism for conversion between time types is the
-     * {@link ChronoField#NANO_OF_DAY nano-of-day} field.
+     * The conversion extracts and combines the {@code ChronoLocalDate} and the
+     * {@code LocalTime} from the temporal object.
+     * Implementations are permitted to perform optimizations such as accessing
+     * those fields that are equivalent to the relevant objects.
+     * The result uses this chronology.
+     * <p>
+     * This method matches the signature of the functional interface {@link TemporalQuery}
+     * allowing it to be used as a query via method reference, {@code aChronology::localDateTime}.
      *
      * @param temporal  the temporal object to convert, not null
      * @return the local date-time in this chronology, not null
      * @throws DateTimeException if unable to create the date-time
      */
-    public ChronoLocalDateTime<C> localDateTime(TemporalAccessor temporal) {
+    public ChronoLocalDateTime<?> localDateTime(TemporalAccessor temporal) {
         try {
             return date(temporal).atTime(LocalTime.from(temporal));
         } catch (DateTimeException ex) {
@@ -605,19 +631,29 @@
     }
 
     /**
-     * Obtains a zoned date-time in this chronology from another temporal object.
+     * Obtains a {@code ChronoZonedDateTime} in this chronology from another temporal object.
      * <p>
-     * This creates a date-time in this chronology based on the specified {@code TemporalAccessor}.
+     * This creates a zoned date-time in this chronology based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code ChronoZonedDateTime}.
      * <p>
-     * This should obtain a {@code ZoneId} using {@link ZoneId#from(TemporalAccessor)}.
-     * The date-time should be obtained by obtaining an {@code Instant}.
-     * If that fails, the local date-time should be used.
+     * The conversion will first obtain a {@code ZoneId} from the temporal object,
+     * falling back to a {@code ZoneOffset} if necessary. It will then try to obtain
+     * an {@code Instant}, falling back to a {@code ChronoLocalDateTime} if necessary.
+     * The result will be either the combination of {@code ZoneId} or {@code ZoneOffset}
+     * with {@code Instant} or {@code ChronoLocalDateTime}.
+     * Implementations are permitted to perform optimizations such as accessing
+     * those fields that are equivalent to the relevant objects.
+     * The result uses this chronology.
+     * <p>
+     * This method matches the signature of the functional interface {@link TemporalQuery}
+     * allowing it to be used as a query via method reference, {@code aChronology::zonedDateTime}.
      *
      * @param temporal  the temporal object to convert, not null
      * @return the zoned date-time in this chronology, not null
      * @throws DateTimeException if unable to create the date-time
      */
-    public ChronoZonedDateTime<C> zonedDateTime(TemporalAccessor temporal) {
+    public ChronoZonedDateTime<?> zonedDateTime(TemporalAccessor temporal) {
         try {
             ZoneId zone = ZoneId.from(temporal);
             try {
@@ -625,7 +661,7 @@
                 return zonedDateTime(instant, zone);
 
             } catch (DateTimeException ex1) {
-                ChronoLocalDateTimeImpl<C> cldt = ensureChronoLocalDateTime(localDateTime(temporal));
+                ChronoLocalDateTimeImpl cldt = ensureChronoLocalDateTime(localDateTime(temporal));
                 return ChronoZonedDateTimeImpl.ofBest(cldt, zone, null);
             }
         } catch (DateTimeException ex) {
@@ -634,7 +670,7 @@
     }
 
     /**
-     * Obtains a zoned date-time in this chronology from an {@code Instant}.
+     * Obtains a {@code ChronoZonedDateTime} in this chronology from an {@code Instant}.
      * <p>
      * This creates a zoned date-time with the same instant as that specified.
      *
@@ -643,7 +679,7 @@
      * @return the zoned date-time, not null
      * @throws DateTimeException if the result exceeds the supported range
      */
-    public ChronoZonedDateTime<C> zonedDateTime(Instant instant, ZoneId zone) {
+    public ChronoZonedDateTime<?> zonedDateTime(Instant instant, ZoneId zone) {
         return ChronoZonedDateTimeImpl.ofInstant(this, instant, zone);
     }
 
@@ -673,7 +709,7 @@
      * @return the proleptic-year
      * @throws DateTimeException if unable to convert
      */
-    public abstract int prolepticYear(Era<C> era, int yearOfEra);
+    public abstract int prolepticYear(Era era, int yearOfEra);
 
     /**
      * Creates the chronology era object from the numeric value.
@@ -694,7 +730,7 @@
      * @return the calendar system era, not null
      * @throws DateTimeException if unable to create the era
      */
-    public abstract Era<C> eraOf(int eraValue);
+    public abstract Era eraOf(int eraValue);
 
     /**
      * Gets the list of eras for the chronology.
@@ -705,7 +741,7 @@
      *
      * @return the list of eras for the chronology, may be immutable, not null
      */
-    public abstract List<Era<C>> eras();
+    public abstract List<Era> eras();
 
     //-----------------------------------------------------------------------
     /**
@@ -730,15 +766,16 @@
     /**
      * Gets the textual representation of this chronology.
      * <p>
-     * This returns the textual name used to identify the chronology.
+     * This returns the textual name used to identify the chronology,
+     * suitable for presentation to the user.
      * The parameters control the style of the returned text and the locale.
      *
      * @param style  the style of the text required, not null
      * @param locale  the locale to use, not null
      * @return the text value of the chronology, not null
      */
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendChronoText(style).toFormatter(locale).print(new TemporalAccessor() {
+    public String getDisplayName(TextStyle style, Locale locale) {
+        return new DateTimeFormatterBuilder().appendChronologyText(style).toFormatter(locale).format(new TemporalAccessor() {
             @Override
             public boolean isSupported(TemporalField field) {
                 return false;
@@ -750,8 +787,8 @@
             @SuppressWarnings("unchecked")
             @Override
             public <R> R query(TemporalQuery<R> query) {
-                if (query == Queries.chrono()) {
-                    return (R) Chrono.this;
+                if (query == Queries.chronology()) {
+                    return (R) Chronology.this;
                 }
                 return TemporalAccessor.super.query(query);
             }
@@ -773,7 +810,7 @@
      * @return the comparator value, negative if less, positive if greater
      */
     @Override
-    public int compareTo(Chrono<?> other) {
+    public int compareTo(Chronology other) {
         return getId().compareTo(other.getId());
     }
 
@@ -782,7 +819,7 @@
      * <p>
      * The comparison is based on the entire state of the object.
      * <p>
-     * The default implementation checks the type and calls {@link #compareTo(Chrono)}.
+     * The default implementation checks the type and calls {@link #compareTo(Chronology)}.
      *
      * @param obj  the object to check, null returns false
      * @return true if this is equal to the other chronology
@@ -792,8 +829,8 @@
         if (this == obj) {
            return true;
         }
-        if (obj instanceof Chrono) {
-            return compareTo((Chrono<?>) obj) == 0;
+        if (obj instanceof Chronology) {
+            return compareTo((Chronology) obj) == 0;
         }
         return false;
     }
@@ -827,7 +864,7 @@
      * Writes the object using a
      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
      * <pre>
-     *  out.writeByte(7);  // identifies this as a Chrono
+     *  out.writeByte(7);  // identifies this as a Chronology
      * out.writeUTF(chronoId);
      * </pre>
      *
@@ -850,9 +887,9 @@
         out.writeUTF(getId());
     }
 
-    static Chrono<?> readExternal(DataInput in) throws IOException {
+    static Chronology readExternal(DataInput in) throws IOException {
         String id = in.readUTF();
-        return Chrono.of(id);
+        return Chronology.of(id);
     }
 
 }
diff --git a/jdk/src/share/classes/java/time/temporal/Era.java b/jdk/src/share/classes/java/time/chrono/Era.java
similarity index 89%
rename from jdk/src/share/classes/java/time/temporal/Era.java
rename to jdk/src/share/classes/java/time/chrono/Era.java
index e32de74..95254c9 100644
--- a/jdk/src/share/classes/java/time/temporal/Era.java
+++ b/jdk/src/share/classes/java/time/chrono/Era.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.ERA;
 import static java.time.temporal.ChronoUnit.ERAS;
@@ -67,6 +67,14 @@
 import java.time.DateTimeException;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.TextStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.ValueRange;
 import java.util.Locale;
 
 /**
@@ -77,7 +85,7 @@
  * of each leader.
  * In all cases, the era is conceptually the largest division of the time-line.
  * Each chronology defines the Era's that are known Eras and a
- * {@link Chrono#eras Chrono.eras} to get the valid eras.
+ * {@link Chronology#eras Chronology.eras} to get the valid eras.
  * <p>
  * For example, the Thai Buddhist calendar system divides time into two eras,
  * before and after a single date. By contrast, the Japanese calendar system
@@ -90,10 +98,9 @@
  * All implementations must be singletons - final, immutable and thread-safe.
  * It is recommended to use an enum whenever possible.
  *
- * @param <C> the chronology of the era
  * @since 1.8
  */
-public interface Era<C extends Chrono<C>> extends TemporalAccessor, TemporalAdjuster {
+public interface Era extends TemporalAccessor, TemporalAdjuster {
 
     /**
      * Gets the numeric value associated with the era as defined by the chronology.
@@ -116,12 +123,12 @@
     /**
      * Gets the chronology of this era.
      * <p>
-     * The {@code Chrono} represents the calendar system in use.
+     * The {@code Chronology} represents the calendar system in use.
      * This always returns the standard form of the chronology.
      *
      * @return the chronology, not null
      */
-    C getChrono();
+    Chronology getChronology();
 
     //-----------------------------------------------------------------------
     /**
@@ -129,18 +136,18 @@
      * <p>
      * This era is combined with the given date fields to form a date.
      * The year specified must be the year-of-era.
-     * Methods to create a date from the proleptic-year are on {@code Chrono}.
+     * Methods to create a date from the proleptic-year are on {@code Chronology}.
      * This always uses the standard form of the chronology.
      * <p>
-     * This default implementation invokes the factory method on {@link Chrono}.
+     * This default implementation invokes the factory method on {@link Chronology}.
      *
      * @param yearOfEra  the calendar system year-of-era
      * @param month  the calendar system month-of-year
      * @param day  the calendar system day-of-month
      * @return a local date based on this era and the specified year-of-era, month and day
      */
-    public default ChronoLocalDate<C> date(int yearOfEra, int month, int day) {
-        return getChrono().date(this, yearOfEra, month, day);
+    public default ChronoLocalDate date(int yearOfEra, int month, int day) {
+        return getChronology().date(this, yearOfEra, month, day);
     }
 
 
@@ -149,17 +156,17 @@
      * <p>
      * This era is combined with the given date fields to form a date.
      * The year specified must be the year-of-era.
-     * Methods to create a date from the proleptic-year are on {@code Chrono}.
+     * Methods to create a date from the proleptic-year are on {@code Chronology}.
      * This always uses the standard form of the chronology.
      * <p>
-     * This default implementation invokes the factory method on {@link Chrono}.
+     * This default implementation invokes the factory method on {@link Chronology}.
      *
      * @param yearOfEra  the calendar system year-of-era
      * @param dayOfYear  the calendar system day-of-year
      * @return a local date based on this era and the specified year-of-era and day-of-year
      */
-    public default ChronoLocalDate<C> dateYearDay(int yearOfEra, int dayOfYear) {
-        return getChrono().dateYearDay(this, yearOfEra, dayOfYear);
+    public default ChronoLocalDate dateYearDay(int yearOfEra, int dayOfYear) {
+        return getChronology().dateYearDay(this, yearOfEra, dayOfYear);
     }
 
     //-----------------------------------------------------------------------
@@ -175,7 +182,7 @@
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the field is supported is determined by the field.
      *
@@ -187,7 +194,7 @@
         if (field instanceof ChronoField) {
             return field == ERA;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
@@ -203,7 +210,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
@@ -229,7 +236,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -258,7 +265,7 @@
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
@@ -274,7 +281,7 @@
         } else if (field instanceof ChronoField) {
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -299,8 +306,8 @@
     @SuppressWarnings("unchecked")
     @Override
     public default <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) getChrono();
+        if (query == Queries.chronology()) {
+            return (R) getChronology();
         } else if (query == Queries.precision()) {
             return (R) ERAS;
         }
@@ -340,7 +347,8 @@
     /**
      * Gets the textual representation of this era.
      * <p>
-     * This returns the textual name used to identify the era.
+     * This returns the textual name used to identify the era,
+     * suitable for presentation to the user.
      * The parameters control the style of the returned text and the locale.
      * <p>
      * If no textual mapping is found then the {@link #getValue() numeric value} is returned.
@@ -351,8 +359,8 @@
      * @param locale  the locale to use, not null
      * @return the text value of the era, not null
      */
-    public default String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendText(ERA, style).toFormatter(locale).print(this);
+    public default String getDisplayName(TextStyle style, Locale locale) {
+        return new DateTimeFormatterBuilder().appendText(ERA, style).toFormatter(locale).format(this);
     }
 
     // NOTE: methods to convert year-of-era/proleptic-year cannot be here as they may depend on month/day (Japanese)
diff --git a/jdk/src/share/classes/java/time/calendar/HijrahChrono.java b/jdk/src/share/classes/java/time/chrono/HijrahChronology.java
similarity index 93%
rename from jdk/src/share/classes/java/time/calendar/HijrahChrono.java
rename to jdk/src/share/classes/java/time/chrono/HijrahChronology.java
index cc2c8e4..0cd16cf 100644
--- a/jdk/src/share/classes/java/time/calendar/HijrahChrono.java
+++ b/jdk/src/share/classes/java/time/chrono/HijrahChronology.java
@@ -55,18 +55,19 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package java.time.calendar;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.EPOCH_DAY;
 
 import java.io.IOException;
 import java.io.Serializable;
 import java.text.ParseException;
+import java.time.Clock;
 import java.time.DateTimeException;
-import java.time.temporal.Chrono;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.ValueRange;
 import java.util.Arrays;
@@ -175,7 +176,7 @@
  *
  * @since 1.8
  */
-public final class HijrahChrono extends Chrono<HijrahChrono> implements Serializable {
+public final class HijrahChronology extends Chronology implements Serializable {
 
     /**
      * The Hijrah Calendar id.
@@ -191,11 +192,11 @@
      * The singleton instance for the era before the current one - Before Hijrah -
      * which has the value 0.
      */
-    public static final Era<HijrahChrono> ERA_BEFORE_AH = HijrahEra.BEFORE_AH;
+    public static final Era ERA_BEFORE_AH = HijrahEra.BEFORE_AH;
     /**
      * The singleton instance for the current era - Hijrah - which has the value 1.
      */
-    public static final Era<HijrahChrono> ERA_AH = HijrahEra.AH;
+    public static final Era ERA_AH = HijrahEra.AH;
     /**
      * Serialization version.
      */
@@ -419,7 +420,7 @@
      * Singleton instance of the Hijrah chronology.
      * Must be initialized after the rest of the static initialization.
      */
-    public static final HijrahChrono INSTANCE;
+    public static final HijrahChronology INSTANCE;
 
     /**
      * Name data.
@@ -439,10 +440,10 @@
 
         DEFAULT_CYCLE_YEARS = Arrays.copyOf(CYCLEYEAR_START_DATE, CYCLEYEAR_START_DATE.length);
 
-        INSTANCE = new HijrahChrono();
+        INSTANCE = new HijrahChronology();
 
         String extraCalendars = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("java.time.calendar.HijrahCalendars"));
+            new sun.security.action.GetPropertyAction("java.time.chrono.HijrahCalendars"));
         if (extraCalendars != null) {
             try {
                 // Split on whitespace
@@ -451,7 +452,7 @@
                     if (!cal.isEmpty()) {
                         // Split on the delimiter between typeId "-" calendarType
                         String[] type = cal.split("-");
-                        Chrono<?> cal2 = new HijrahChrono(type[0], type.length > 1 ? type[1] : type[0]);
+                        Chronology cal2 = new HijrahChronology(type[0], type.length > 1 ? type[1] : type[0]);
                     }
                 }
             } catch (Exception ex) {
@@ -464,15 +465,15 @@
     /**
      * Restricted constructor.
      */
-    private HijrahChrono() {
+    private HijrahChronology() {
         this("Hijrah", "islamicc");
     }
     /**
-     * Constructor for name and type HijrahChrono.
+     * Constructor for name and type HijrahChronology.
      * @param id the id of the calendar
      * @param calendarType the calendar type
      */
-    private HijrahChrono(String id, String calendarType) {
+    private HijrahChronology(String id, String calendarType) {
         this.typeId = id;
         this.calendarType = calendarType;
 
@@ -507,8 +508,8 @@
     /**
      * Gets the ID of the chronology - 'Hijrah'.
      * <p>
-     * The ID uniquely identifies the {@code Chrono}.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * The ID uniquely identifies the {@code Chronology}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      *
      * @return the chronology ID - 'Hijrah'
      * @see #getCalendarType()
@@ -523,7 +524,7 @@
      * <p>
      * The calendar type is an identifier defined by the
      * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      * It can also be used as part of a locale, accessible via
      * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
      *
@@ -537,23 +538,64 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<HijrahChrono> date(int prolepticYear, int month, int dayOfMonth) {
+    public HijrahDate date(int prolepticYear, int month, int dayOfMonth) {
         return HijrahDate.of(this, prolepticYear, month, dayOfMonth);
     }
 
     @Override
-    public ChronoLocalDate<HijrahChrono> dateYearDay(int prolepticYear, int dayOfYear) {
+    public HijrahDate dateYearDay(int prolepticYear, int dayOfYear) {
         return HijrahDate.of(this, prolepticYear, 1, 1).plusDays(dayOfYear - 1);  // TODO better
     }
 
     @Override
-    public ChronoLocalDate<HijrahChrono> date(TemporalAccessor temporal) {
+    public HijrahDate date(TemporalAccessor temporal) {
         if (temporal instanceof HijrahDate) {
             return (HijrahDate) temporal;
         }
         return HijrahDate.ofEpochDay(this, temporal.getLong(EPOCH_DAY));
     }
 
+    @Override
+    public HijrahDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
+        return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
+
+    }
+
+    @Override
+    public HijrahDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
+        return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
+    }
+
+    @Override
+    public HijrahDate dateNow() {
+        return dateNow(Clock.systemDefaultZone());
+    }
+
+    @Override
+    public HijrahDate dateNow(ZoneId zone) {
+        return dateNow(Clock.system(zone));
+    }
+
+    @Override
+    public HijrahDate dateNow(Clock clock) {
+        return date(LocalDate.now(clock));
+    }
+
+    @Override
+    public ChronoLocalDateTime<HijrahDate> localDateTime(TemporalAccessor temporal) {
+        return (ChronoLocalDateTime<HijrahDate>)super.localDateTime(temporal);
+    }
+
+    @Override
+    public ChronoZonedDateTime<HijrahDate> zonedDateTime(TemporalAccessor temporal) {
+        return (ChronoZonedDateTime<HijrahDate>)super.zonedDateTime(temporal);
+    }
+
+    @Override
+    public ChronoZonedDateTime<HijrahDate> zonedDateTime(Instant instant, ZoneId zone) {
+        return (ChronoZonedDateTime<HijrahDate>)super.zonedDateTime(instant, zone);
+    }
+
     //-----------------------------------------------------------------------
     @Override
     public boolean isLeapYear(long prolepticYear) {
@@ -569,7 +611,7 @@
     }
 
     @Override
-    public int prolepticYear(Era<HijrahChrono> era, int yearOfEra) {
+    public int prolepticYear(Era era, int yearOfEra) {
         if (era instanceof HijrahEra == false) {
             throw new DateTimeException("Era must be HijrahEra");
         }
@@ -577,7 +619,7 @@
     }
 
     @Override
-    public Era<HijrahChrono> eraOf(int eraValue) {
+    public Era eraOf(int eraValue) {
         switch (eraValue) {
             case 0:
                 return HijrahEra.BEFORE_AH;
@@ -589,8 +631,8 @@
     }
 
     @Override
-    public List<Era<HijrahChrono>> eras() {
-        return Arrays.<Era<HijrahChrono>>asList(HijrahEra.values());
+    public List<Era> eras() {
+        return Arrays.<Era>asList(HijrahEra.values());
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/calendar/HijrahDate.java b/jdk/src/share/classes/java/time/chrono/HijrahDate.java
similarity index 65%
rename from jdk/src/share/classes/java/time/calendar/HijrahDate.java
rename to jdk/src/share/classes/java/time/chrono/HijrahDate.java
index c325255..2d98cd4 100644
--- a/jdk/src/share/classes/java/time/calendar/HijrahDate.java
+++ b/jdk/src/share/classes/java/time/chrono/HijrahDate.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
@@ -68,19 +68,27 @@
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.Serializable;
+import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.DayOfWeek;
 import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.Period;
+import java.time.ZoneId;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
 import java.time.temporal.ValueRange;
 import java.util.Objects;
 
 /**
  * A date in the Hijrah calendar system.
  * <p>
- * This implements {@code ChronoLocalDate} for the {@link HijrahChrono Hijrah calendar}.
+ * This date operates using the {@linkplain HijrahChronology Hijrah calendar}.
  * <p>
  * The Hijrah calendar has a different total of days in a year than
  * Gregorian calendar, and a month is based on the period of a complete
@@ -116,11 +124,9 @@
  *
  * @since 1.8
  */
-final class HijrahDate
-        extends ChronoDateImpl<HijrahChrono>
-        implements ChronoLocalDate<HijrahChrono>, Serializable {
-    // this class is package-scoped so that future conversion to public
-    // would not change serialization
+public final class HijrahDate
+        extends ChronoDateImpl<HijrahDate>
+        implements ChronoLocalDate<HijrahDate>, Serializable {
 
     /**
      * Serialization version.
@@ -130,7 +136,7 @@
     /**
      * The Chronology of this HijrahDate.
      */
-    private final HijrahChrono chrono;
+    private final HijrahChronology chrono;
     /**
      * The era.
      */
@@ -177,7 +183,7 @@
      * @return the Hijrah date, never null
      * @throws DateTimeException if the value of any field is out of range
      */
-    static HijrahDate of(HijrahChrono chrono, int prolepticYear, int monthOfYear, int dayOfMonth) {
+    static HijrahDate of(HijrahChronology chrono, int prolepticYear, int monthOfYear, int dayOfMonth) {
         return (prolepticYear >= 1) ?
             HijrahDate.of(chrono, HijrahEra.AH, prolepticYear, monthOfYear, dayOfMonth) :
             HijrahDate.of(chrono, HijrahEra.BEFORE_AH, 1 - prolepticYear, monthOfYear, dayOfMonth);
@@ -194,7 +200,7 @@
      * @return the Hijrah date, never null
      * @throws DateTimeException if the value of any field is out of range
      */
-    private static HijrahDate of(HijrahChrono chrono, HijrahEra era, int yearOfEra, int monthOfYear, int dayOfMonth) {
+    private static HijrahDate of(HijrahChronology chrono, HijrahEra era, int yearOfEra, int monthOfYear, int dayOfMonth) {
         Objects.requireNonNull(era, "era");
         chrono.checkValidYearOfEra(yearOfEra);
         chrono.checkValidMonth(monthOfYear);
@@ -203,28 +209,103 @@
         return new HijrahDate(chrono, gregorianDays);
     }
 
-    /**
-     * Obtains an instance of {@code HijrahDate} from a date.
-     *
-     * @param date  the date to use, not null
-     * @return the Hijrah date, never null
-     * @throws DateTimeException if the year is invalid
-     */
-    private static HijrahDate of(HijrahChrono chrono, LocalDate date) {
-        long gregorianDays = date.toEpochDay();
-        return new HijrahDate(chrono, gregorianDays);
-    }
-
-    static HijrahDate ofEpochDay(HijrahChrono chrono, long epochDay) {
+    static HijrahDate ofEpochDay(HijrahChronology chrono, long epochDay) {
         return new HijrahDate(chrono, epochDay);
     }
 
+    //-----------------------------------------------------------------------
+    /**
+     * Obtains the current {@code HijrahDate} from the system clock in the default time-zone.
+     * <p>
+     * This will query the {@link Clock#systemDefaultZone() system clock} in the default
+     * time-zone to obtain the current date.
+     * <p>
+     * Using this method will prevent the ability to use an alternate clock for testing
+     * because the clock is hard-coded.
+     *
+     * @return the current date using the system clock and default time-zone, not null
+     */
+    public static HijrahDate now() {
+        return now(Clock.systemDefaultZone());
+    }
+
+    /**
+     * Obtains the current {@code HijrahDate} from the system clock in the specified time-zone.
+     * <p>
+     * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
+     * Specifying the time-zone avoids dependence on the default time-zone.
+     * <p>
+     * Using this method will prevent the ability to use an alternate clock for testing
+     * because the clock is hard-coded.
+     *
+     * @param zone  the zone ID to use, not null
+     * @return the current date using the system clock, not null
+     */
+    public static HijrahDate now(ZoneId zone) {
+        return now(Clock.system(zone));
+    }
+
+    /**
+     * Obtains the current {@code HijrahDate} from the specified clock.
+     * <p>
+     * This will query the specified clock to obtain the current date - today.
+     * Using this method allows the use of an alternate clock for testing.
+     * The alternate clock may be introduced using {@linkplain Clock dependency injection}.
+     *
+     * @param clock  the clock to use, not null
+     * @return the current date, not null
+     * @throws DateTimeException if the current date cannot be obtained
+     */
+    public static HijrahDate now(Clock clock) {
+        return HijrahChronology.INSTANCE.date(LocalDate.now(clock));
+    }
+
+    /**
+     * Obtains a {@code HijrahDate} representing a date in the Hijrah calendar
+     * system from the proleptic-year, month-of-year and day-of-month fields.
+     * <p>
+     * This returns a {@code HijrahDate} with the specified fields.
+     * The day must be valid for the year and month, otherwise an exception will be thrown.
+     *
+     * @param prolepticYear  the Hijrah proleptic-year
+     * @param month  the Hijrah month-of-year, from 1 to 12
+     * @param dayOfMonth  the Hijrah day-of-month, from 1 to 30
+     * @return the date in Hijrah calendar system, not null
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
+     */
+    public static HijrahDate of(int prolepticYear, int month, int dayOfMonth) {
+        return HijrahChronology.INSTANCE.date(prolepticYear, month, dayOfMonth);
+    }
+
+    /**
+     * Obtains a {@code HijrahDate} from a temporal object.
+     * <p>
+     * This obtains a date in the Hijrah calendar system based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code HijrahDate}.
+     * <p>
+     * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
+     * field, which is standardized across calendar systems.
+     * <p>
+     * This method matches the signature of the functional interface {@link TemporalQuery}
+     * allowing it to be used as a query via method reference, {@code HijrahDate::from}.
+     *
+     * @param temporal  the temporal object to convert, not null
+     * @return the date in Hijrah calendar system, not null
+     * @throws DateTimeException if unable to convert to a {@code HijrahDate}
+     */
+    public static HijrahDate from(TemporalAccessor temporal) {
+        return HijrahChronology.INSTANCE.date(temporal);
+    }
+
+    //-----------------------------------------------------------------------
     /**
      * Constructs an instance with the specified date.
      *
      * @param gregorianDay  the number of days from 0001/01/01 (Gregorian), caller calculated
      */
-    private HijrahDate(HijrahChrono chrono, long gregorianDay) {
+    private HijrahDate(HijrahChronology chrono, long gregorianDay) {
         this.chrono = chrono;
         int[] dateInfo = chrono.getHijrahDateInfo(gregorianDay);
 
@@ -245,7 +326,7 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public HijrahChrono getChrono() {
+    public HijrahChronology getChronology() {
         return chrono;
     }
 
@@ -260,11 +341,16 @@
                     case ALIGNED_WEEK_OF_MONTH: return ValueRange.of(1, 5);  // TODO
                     case YEAR_OF_ERA: return ValueRange.of(1, 1000);  // TODO
                 }
-                return getChrono().range(f);
+                return getChronology().range(f);
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
+    }
+
+    @Override   // Override for javadoc
+    public int get(TemporalField field) {
+        return super.get(field);
     }
 
     @Override
@@ -286,7 +372,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     @Override
@@ -322,18 +408,42 @@
         return HijrahDate.of(chrono, yearOfEra, month, day);
     }
 
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public  HijrahDate with(TemporalAdjuster adjuster) {
+        return (HijrahDate)super.with(adjuster);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public HijrahDate plus(TemporalAmount amount) {
+        return (HijrahDate)super.plus(amount);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public HijrahDate minus(TemporalAmount amount) {
+        return (HijrahDate)super.minus(amount);
+    }
+
     @Override
     public long toEpochDay() {
          return chrono.getGregorianEpochDay(yearOfEra, monthOfYear, dayOfMonth);
     }
 
     //-----------------------------------------------------------------------
-    @Override
-    public HijrahEra getEra() {
-        return this.era;
-    }
-
-    //-----------------------------------------------------------------------
     /**
      * Checks if the year is a leap year, according to the Hijrah calendar system rules.
      *
@@ -346,7 +456,7 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public HijrahDate plusYears(long years) {
+    HijrahDate plusYears(long years) {
         if (years == 0) {
             return this;
         }
@@ -355,7 +465,7 @@
     }
 
     @Override
-    public HijrahDate plusMonths(long months) {
+    HijrahDate plusMonths(long months) {
         if (months == 0) {
             return this;
         }
@@ -372,10 +482,45 @@
     }
 
     @Override
-    public HijrahDate plusDays(long days) {
+    HijrahDate plusWeeks(long weeksToAdd) {
+        return (HijrahDate)super.plusWeeks(weeksToAdd);
+    }
+
+    @Override
+    HijrahDate plusDays(long days) {
         return new HijrahDate(chrono, this.gregorianEpochDay + days);
     }
 
+    @Override
+    public HijrahDate plus(long amountToAdd, TemporalUnit unit) {
+        return (HijrahDate)super.plus(amountToAdd, unit);
+    }
+
+    @Override
+    public HijrahDate minus(long amountToSubtract, TemporalUnit unit) {
+        return (HijrahDate)super.minus(amountToSubtract, unit);
+    }
+
+    @Override
+    HijrahDate minusYears(long yearsToSubtract) {
+        return (HijrahDate)super.minusYears(yearsToSubtract);
+    }
+
+    @Override
+    HijrahDate minusMonths(long monthsToSubtract) {
+        return (HijrahDate)super.minusMonths(monthsToSubtract);
+    }
+
+    @Override
+    HijrahDate minusWeeks(long weeksToSubtract) {
+        return (HijrahDate)super.minusWeeks(weeksToSubtract);
+    }
+
+    @Override
+    HijrahDate minusDays(long daysToSubtract) {
+        return (HijrahDate)super.minusDays(daysToSubtract);
+    }
+
     /**
      * Returns month days from the beginning of year.
      *
@@ -410,13 +555,37 @@
         return chrono.getYearLength(yearOfEra);  // TODO: proleptic year
     }
 
+    @Override        // for javadoc and covariant return type
+    public final ChronoLocalDateTime<HijrahDate> atTime(LocalTime localTime) {
+        return (ChronoLocalDateTime<HijrahDate>)super.atTime(localTime);
+    }
+
+    @Override
+    public Period periodUntil(ChronoLocalDate<?> endDate) {
+        // TODO: untested
+        HijrahDate end = (HijrahDate) getChronology().date(endDate);
+        long totalMonths = (end.yearOfEra - this.yearOfEra) * 12 + (end.monthOfYear - this.monthOfYear);  // safe
+        int days = end.dayOfMonth - this.dayOfMonth;
+        if (totalMonths > 0 && days < 0) {
+            totalMonths--;
+            HijrahDate calcDate = this.plusMonths(totalMonths);
+            days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
+        } else if (totalMonths < 0 && days > 0) {
+            totalMonths++;
+            days -= end.lengthOfMonth();
+        }
+        long years = totalMonths / 12;  // safe
+        int months = (int) (totalMonths % 12);  // safe
+        return Period.of(Math.toIntExact(years), months, days);
+    }
+
     //-----------------------------------------------------------------------
     private Object writeReplace() {
         return new Ser(Ser.HIJRAH_DATE_TYPE, this);
     }
 
     void writeExternal(ObjectOutput out) throws IOException {
-        // HijrahChrono is implicit in the Hijrah_DATE_TYPE
+        // HijrahChronology is implicit in the Hijrah_DATE_TYPE
         out.writeObject(chrono);
         out.writeInt(get(YEAR));
         out.writeByte(get(MONTH_OF_YEAR));
@@ -434,8 +603,8 @@
         return this;
     }
 
-    static ChronoLocalDate<HijrahChrono> readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        HijrahChrono chrono = (HijrahChrono)in.readObject();
+    static ChronoLocalDate<HijrahDate> readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        HijrahChronology chrono = (HijrahChronology)in.readObject();
         int year = in.readInt();
         int month = in.readByte();
         int dayOfMonth = in.readByte();
diff --git a/jdk/src/share/classes/java/time/calendar/HijrahDeviationReader.java b/jdk/src/share/classes/java/time/chrono/HijrahDeviationReader.java
similarity index 89%
rename from jdk/src/share/classes/java/time/calendar/HijrahDeviationReader.java
rename to jdk/src/share/classes/java/time/chrono/HijrahDeviationReader.java
index 4704483..67495d0 100644
--- a/jdk/src/share/classes/java/time/calendar/HijrahDeviationReader.java
+++ b/jdk/src/share/classes/java/time/chrono/HijrahDeviationReader.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
 
 import java.io.BufferedReader;
@@ -67,9 +67,8 @@
 import java.security.AccessController;
 import java.text.ParseException;
 import java.time.LocalDate;
-import java.time.format.DateTimeFormatters;
+import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
 import java.util.Arrays;
 import java.util.function.Block;
 
@@ -85,7 +84,7 @@
  * The deviation files are named {@code "hijrah_" + ID}.
  * <p>
  * The deviation file for a calendar can be overridden by defining the
- * property {@code java.time.calendar.HijrahChrono.File.hijrah_<ID>}
+ * property {@code java.time.chrono.HijrahChronology.File.hijrah_<ID>}
  * with the full pathname of the deviation file.
  * <p>
  * The deviation file is read line by line:
@@ -133,7 +132,7 @@
      * @throws ParseException if the format of the configuration file is wrong.
      */
     static boolean readDeviation(String typeId, String calendarType,
-            Block<HijrahChrono.Deviation> block) throws IOException, ParseException {
+            Block<HijrahChronology.Deviation> block) throws IOException, ParseException {
         InputStream is = getConfigFileInputStream(typeId);
         if (is != null) {
             try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
@@ -141,7 +140,7 @@
                 int num = 0;
                 while ((line = br.readLine()) != null) {
                     num++;
-                    HijrahChrono.Deviation entry = parseLine(line, num);
+                    HijrahChronology.Deviation entry = parseLine(line, num);
                     if (entry != null) {
                         block.accept(entry);
                     }
@@ -160,7 +159,7 @@
      * @return an Entry or null if the line is empty.
      * @throws ParseException if line has incorrect format.
      */
-    private static HijrahChrono.Deviation parseLine(final String line, final int num) throws ParseException {
+    private static HijrahChronology.Deviation parseLine(final String line, final int num) throws ParseException {
         int hash = line.indexOf("#");
         String nocomment = (hash < 0) ? line : line.substring(0, hash);
         String[] split = nocomment.split("\\s");
@@ -174,16 +173,16 @@
         //element [0] is a date
         //element [1] is the offset
 
-        LocalDate isoDate = DateTimeFormatters.pattern("MMM-dd-yyyy").parse(split[0], LocalDate::from);
+        LocalDate isoDate = DateTimeFormatter.ofPattern("MMM-dd-yyyy").parse(split[0], LocalDate::from);
         int offset = Integer.valueOf(split[1]);
 
         // Convert date to HijrahDate using the default Islamic Calendar
 
-        ChronoLocalDate<HijrahChrono> hijrahDate = HijrahChrono.INSTANCE.date(isoDate);
+        HijrahDate hijrahDate = HijrahChronology.INSTANCE.date(isoDate);
 
         int year = hijrahDate.get(ChronoField.YEAR);
         int month = hijrahDate.get(ChronoField.MONTH_OF_YEAR);
-        return new HijrahChrono.Deviation(year, month, year, month, offset);
+        return new HijrahChronology.Deviation(year, month, year, month, offset);
     }
 
 
@@ -198,8 +197,8 @@
      * </pre> The default location and file name can be overridden by setting
      * following two Java system properties.
      * <pre>
-     *   Location: java.time.calendar.HijrahDate.deviationConfigDir
-     *   File name: java.time.calendar.HijrahDate.File. + typeid
+     *   Location: java.time.chrono.HijrahDate.deviationConfigDir
+     *   File name: java.time.chrono.HijrahDate.File. + typeid
      * </pre> Regarding the file format, see readDeviationConfig() method for
      * details.
      *
@@ -209,10 +208,9 @@
      */
     private static InputStream getConfigFileInputStream(final String typeId) throws IOException {
         try {
-            InputStream stream =
-                    (InputStream)AccessController
-                    .doPrivileged((java.security.PrivilegedExceptionAction) () -> {
-                String propFilename = "java.time.calendar.HijrahChrono.File." + typeId;
+            InputStream stream = AccessController
+                    .doPrivileged((java.security.PrivilegedExceptionAction<InputStream>) () -> {
+                String propFilename = "java.time.chrono.HijrahChronology.File." + typeId;
                 String filename = System.getProperty(propFilename);
                 File file = null;
                 if (filename != null) {
diff --git a/jdk/src/share/classes/java/time/calendar/HijrahEra.java b/jdk/src/share/classes/java/time/chrono/HijrahEra.java
similarity index 71%
rename from jdk/src/share/classes/java/time/calendar/HijrahEra.java
rename to jdk/src/share/classes/java/time/chrono/HijrahEra.java
index 5c622f7..1ac2569 100644
--- a/jdk/src/share/classes/java/time/calendar/HijrahEra.java
+++ b/jdk/src/share/classes/java/time/chrono/HijrahEra.java
@@ -54,23 +54,12 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
-
-import static java.time.temporal.ChronoField.ERA;
+package java.time.chrono;
 
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.time.DateTimeException;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.TextStyle;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalField;
-import java.time.temporal.ValueRange;
-import java.util.Locale;
 
 /**
  * An era in the Hijrah calendar system.
@@ -86,7 +75,7 @@
  *
  * @since 1.8
  */
-enum HijrahEra implements Era<HijrahChrono> {
+enum HijrahEra implements Era {
 
     /**
      * The singleton instance for the era before the current one, 'Before Anno Hegirae',
@@ -135,71 +124,23 @@
     }
 
     @Override
-    public HijrahChrono getChrono() {
-        return HijrahChrono.INSTANCE;
+    public HijrahChronology getChronology() {
+        return HijrahChronology.INSTANCE;
     }
 
     // JDK8 default methods:
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<HijrahChrono> date(int year, int month, int day) {
-        return getChrono().date(this, year, month, day);
+    public HijrahDate date(int year, int month, int day) {
+        return (HijrahDate)(getChronology().date(this, year, month, day));
     }
 
     @Override
-    public ChronoLocalDate<HijrahChrono> dateYearDay(int year, int dayOfYear) {
-        return getChrono().dateYearDay(this, year, dayOfYear);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public boolean isSupported(TemporalField field) {
-        if (field instanceof ChronoField) {
-            return field == ERA;
-        }
-        return field != null && field.doIsSupported(this);
-    }
-
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field == ERA) {
-            return field.range();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doRange(this);
-    }
-
-    @Override
-    public int get(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        }
-        return range(field).checkValidIntValue(getLong(field), field);
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doGet(this);
+    public HijrahDate dateYearDay(int year, int dayOfYear) {
+        return (HijrahDate)(getChronology().dateYearDay(this, year, dayOfYear));
     }
 
     //-------------------------------------------------------------------------
-    @Override
-    public Temporal adjustInto(Temporal temporal) {
-        return temporal.with(ERA, getValue());
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendText(ERA, style).toFormatter(locale).print(this);
-    }
-
     /**
      * Returns the proleptic year from this era and year of era.
      *
diff --git a/jdk/src/share/classes/java/time/temporal/ISOChrono.java b/jdk/src/share/classes/java/time/chrono/IsoChronology.java
similarity index 91%
rename from jdk/src/share/classes/java/time/temporal/ISOChrono.java
rename to jdk/src/share/classes/java/time/chrono/IsoChronology.java
index c290e4e..883db3e 100644
--- a/jdk/src/share/classes/java/time/temporal/ISOChrono.java
+++ b/jdk/src/share/classes/java/time/chrono/IsoChronology.java
@@ -59,7 +59,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
 import java.io.Serializable;
 import java.time.Clock;
@@ -69,6 +69,9 @@
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.ValueRange;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
@@ -102,26 +105,26 @@
  *
  * @since 1.8
  */
-public final class ISOChrono extends Chrono<ISOChrono> implements Serializable {
+public final class IsoChronology extends Chronology implements Serializable {
 
     /**
      * Singleton instance of the ISO chronology.
      */
-    public static final ISOChrono INSTANCE = new ISOChrono();
+    public static final IsoChronology INSTANCE = new IsoChronology();
     /**
      * The singleton instance for the era BCE - 'Before Current Era'.
      * The 'ISO' part of the name emphasizes that this differs from the BCE
      * era in the Gregorian calendar system.
      * This has the numeric value of {@code 0}.
      */
-    public static final Era<ISOChrono> ERA_BCE = ISOEra.BCE;
+    public static final Era ERA_BCE = IsoEra.BCE;
     /**
      * The singleton instance for the era CE - 'Current Era'.
      * The 'ISO' part of the name emphasizes that this differs from the CE
      * era in the Gregorian calendar system.
      * This has the numeric value of {@code 1}.
      */
-    public static final Era<ISOChrono> ERA_CE = ISOEra.CE;
+    public static final Era ERA_CE = IsoEra.CE;
 
     /**
      * Serialization version.
@@ -131,7 +134,7 @@
     /**
      * Restricted constructor.
      */
-    private ISOChrono() {
+    private IsoChronology() {
     }
 
     /**
@@ -147,8 +150,8 @@
     /**
      * Gets the ID of the chronology - 'ISO'.
      * <p>
-     * The ID uniquely identifies the {@code Chrono}.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * The ID uniquely identifies the {@code Chronology}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      *
      * @return the chronology ID - 'ISO'
      * @see #getCalendarType()
@@ -163,7 +166,7 @@
      * <p>
      * The calendar type is an identifier defined by the
      * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      * It can also be used as part of a locale, accessible via
      * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
      *
@@ -188,7 +191,7 @@
      * @throws DateTimeException if unable to create the date
      */
     @Override  // override with covariant return type
-    public LocalDate date(Era<ISOChrono> era, int yearOfEra, int month, int dayOfMonth) {
+    public LocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
         return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
     }
 
@@ -219,7 +222,7 @@
      * @throws DateTimeException if unable to create the date
      */
     @Override  // override with covariant return type
-    public LocalDate dateYearDay(Era<ISOChrono> era, int yearOfEra, int dayOfYear) {
+    public LocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
         return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
     }
 
@@ -291,6 +294,7 @@
      * @return the zoned date-time, not null
      * @throws DateTimeException if the result exceeds the supported range
      */
+    @Override
     public ZonedDateTime zonedDateTime(Instant instant, ZoneId zone) {
         return ZonedDateTime.ofInstant(instant, zone);
     }
@@ -373,21 +377,21 @@
     }
 
     @Override
-    public int prolepticYear(Era<ISOChrono> era, int yearOfEra) {
-        if (era instanceof ISOEra == false) {
-            throw new DateTimeException("Era must be ISOEra");
+    public int prolepticYear(Era era, int yearOfEra) {
+        if (era instanceof IsoEra == false) {
+            throw new DateTimeException("Era must be IsoEra");
         }
-        return (era == ISOEra.CE ? yearOfEra : 1 - yearOfEra);
+        return (era == IsoEra.CE ? yearOfEra : 1 - yearOfEra);
     }
 
     @Override
-    public Era<ISOChrono> eraOf(int eraValue) {
-        return ISOEra.of(eraValue);
+    public Era eraOf(int eraValue) {
+        return IsoEra.of(eraValue);
     }
 
     @Override
-    public List<Era<ISOChrono>> eras() {
-        return Arrays.<Era<ISOChrono>>asList(ISOEra.values());
+    public List<Era> eras() {
+        return Arrays.<Era>asList(IsoEra.values());
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/temporal/ISOEra.java b/jdk/src/share/classes/java/time/chrono/IsoEra.java
similarity index 68%
rename from jdk/src/share/classes/java/time/temporal/ISOEra.java
rename to jdk/src/share/classes/java/time/chrono/IsoEra.java
index 21009f6..8a81067 100644
--- a/jdk/src/share/classes/java/time/temporal/ISOEra.java
+++ b/jdk/src/share/classes/java/time/chrono/IsoEra.java
@@ -59,14 +59,11 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.temporal;
+package java.time.chrono;
 
-import static java.time.temporal.ChronoField.ERA;
 
 import java.time.DateTimeException;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.TextStyle;
-import java.util.Locale;
+import java.time.LocalDate;
 
 /**
  * An era in the ISO calendar system.
@@ -75,7 +72,7 @@
  * A definition has therefore been created with two eras - 'Current era' (CE) for
  * years from 0001-01-01 (ISO) and 'Before current era' (BCE) for years before that.
  * <p>
- * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code ISOEra}.
+ * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code IsoEra}.
  * Use {@code getValue()} instead.</b>
  *
  * <h3>Specification for implementors</h3>
@@ -83,7 +80,7 @@
  *
  * @since 1.8
  */
-enum ISOEra implements Era<ISOChrono> {
+enum IsoEra implements Era {
 
     /**
      * The singleton instance for the era BCE, 'Before Current Era'.
@@ -102,16 +99,16 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains an instance of {@code ISOEra} from an {@code int} value.
+     * Obtains an instance of {@code IsoEra} from an {@code int} value.
      * <p>
-     * {@code ISOEra} is an enum representing the ISO eras of BCE/CE.
+     * {@code IsoEra} is an enum representing the ISO eras of BCE/CE.
      * This factory allows the enum to be obtained from the {@code int} value.
      *
      * @param era  the BCE/CE value to represent, from 0 (BCE) to 1 (CE)
      * @return the era singleton, not null
      * @throws DateTimeException if the value is invalid
      */
-    public static ISOEra of(int era) {
+    public static IsoEra of(int era) {
         switch (era) {
             case 0:
                 return BCE;
@@ -136,69 +133,20 @@
     }
 
     @Override
-    public ISOChrono getChrono() {
-        return ISOChrono.INSTANCE;
+    public IsoChronology getChronology() {
+        return IsoChronology.INSTANCE;
     }
 
     // JDK8 default methods:
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<ISOChrono> date(int year, int month, int day) {
-        return getChrono().date(this, year, month, day);
+    public LocalDate date(int year, int month, int day) {
+        return getChronology().date(this, year, month, day);
     }
 
     @Override
-    public ChronoLocalDate<ISOChrono> dateYearDay(int year, int dayOfYear) {
-        return getChrono().dateYearDay(this, year, dayOfYear);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public boolean isSupported(TemporalField field) {
-        if (field instanceof ChronoField) {
-            return field == ERA;
-        }
-        return field != null && field.doIsSupported(this);
-    }
-
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field == ERA) {
-            return field.range();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doRange(this);
-    }
-
-    @Override
-    public int get(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        }
-        return range(field).checkValidIntValue(getLong(field), field);
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doGet(this);
-    }
-
-    //-------------------------------------------------------------------------
-    @Override
-    public Temporal adjustInto(Temporal temporal) {
-        return temporal.with(ERA, getValue());
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendText(ERA, style).toFormatter(locale).print(this);
+    public LocalDate dateYearDay(int year, int dayOfYear) {
+        return getChronology().dateYearDay(this, year, dayOfYear);
     }
 
 }
diff --git a/jdk/src/share/classes/java/time/calendar/JapaneseChrono.java b/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java
similarity index 80%
rename from jdk/src/share/classes/java/time/calendar/JapaneseChrono.java
rename to jdk/src/share/classes/java/time/chrono/JapaneseChronology.java
index 12073c6..bb16d89 100644
--- a/jdk/src/share/classes/java/time/calendar/JapaneseChrono.java
+++ b/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java
@@ -54,25 +54,22 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
 import java.io.Serializable;
+import java.time.Clock;
 import java.time.DateTimeException;
+import java.time.Instant;
 import java.time.LocalDate;
-import java.time.temporal.Chrono;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.ValueRange;
-import java.time.temporal.Year;
+import java.time.Year;
+import java.time.ZoneId;
 import java.util.Arrays;
 import java.util.Calendar;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 
 import sun.util.calendar.CalendarSystem;
 import sun.util.calendar.LocalGregorianCalendar;
@@ -93,7 +90,7 @@
  *
  * @since 1.8
  */
-public final class JapaneseChrono extends Chrono<JapaneseChrono> implements Serializable {
+public final class JapaneseChronology extends Chronology implements Serializable {
     // TODO: definition for unknown era may break requirement that year-of-era >= 1
 
     static final LocalGregorianCalendar JCAL =
@@ -105,33 +102,33 @@
     /**
      * Singleton instance for Japanese chronology.
      */
-    public static final JapaneseChrono INSTANCE = new JapaneseChrono();
+    public static final JapaneseChronology INSTANCE = new JapaneseChronology();
 
     /**
      * The singleton instance for the before Meiji era ( - 1868-09-07)
      * which has the value -999.
      */
-    public static final Era<JapaneseChrono> ERA_SEIREKI = JapaneseEra.SEIREKI;
+    public static final Era ERA_SEIREKI = JapaneseEra.SEIREKI;
     /**
      * The singleton instance for the Meiji era (1868-09-08 - 1912-07-29)
      * which has the value -1.
      */
-    public static final Era<JapaneseChrono> ERA_MEIJI = JapaneseEra.MEIJI;
+    public static final Era ERA_MEIJI = JapaneseEra.MEIJI;
     /**
      * The singleton instance for the Taisho era (1912-07-30 - 1926-12-24)
      * which has the value 0.
      */
-    public static final Era<JapaneseChrono> ERA_TAISHO = JapaneseEra.TAISHO;
+    public static final Era ERA_TAISHO = JapaneseEra.TAISHO;
     /**
      * The singleton instance for the Showa era (1926-12-25 - 1989-01-07)
      * which has the value 1.
      */
-    public static final Era<JapaneseChrono> ERA_SHOWA = JapaneseEra.SHOWA;
+    public static final Era ERA_SHOWA = JapaneseEra.SHOWA;
     /**
      * The singleton instance for the Heisei era (1989-01-08 - current)
      * which has the value 2.
      */
-    public static final Era<JapaneseChrono> ERA_HEISEI = JapaneseEra.HEISEI;
+    public static final Era ERA_HEISEI = JapaneseEra.HEISEI;
     /**
      * Serialization version.
      */
@@ -141,7 +138,7 @@
     /**
      * Restricted constructor.
      */
-    private JapaneseChrono() {
+    private JapaneseChronology() {
     }
 
     /**
@@ -157,8 +154,8 @@
     /**
      * Gets the ID of the chronology - 'Japanese'.
      * <p>
-     * The ID uniquely identifies the {@code Chrono}.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * The ID uniquely identifies the {@code Chronology}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      *
      * @return the chronology ID - 'Japanese'
      * @see #getCalendarType()
@@ -173,7 +170,7 @@
      * <p>
      * The calendar type is an identifier defined by the
      * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      * It can also be used as part of a locale, accessible via
      * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
      *
@@ -187,7 +184,7 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<JapaneseChrono> date(Era<JapaneseChrono> era, int yearOfEra, int month, int dayOfMonth) {
+    public JapaneseDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
         if (era instanceof JapaneseEra == false) {
             throw new DateTimeException("Era must be JapaneseEra");
         }
@@ -195,24 +192,59 @@
     }
 
     @Override
-    public ChronoLocalDate<JapaneseChrono> date(int prolepticYear, int month, int dayOfMonth) {
+    public JapaneseDate date(int prolepticYear, int month, int dayOfMonth) {
         return new JapaneseDate(LocalDate.of(prolepticYear, month, dayOfMonth));
     }
 
     @Override
-    public ChronoLocalDate<JapaneseChrono> dateYearDay(int prolepticYear, int dayOfYear) {
+    public JapaneseDate dateYearDay(int prolepticYear, int dayOfYear) {
         LocalDate date = LocalDate.ofYearDay(prolepticYear, dayOfYear);
         return date(prolepticYear, date.getMonthValue(), date.getDayOfMonth());
     }
 
     @Override
-    public ChronoLocalDate<JapaneseChrono> date(TemporalAccessor temporal) {
+    public JapaneseDate date(TemporalAccessor temporal) {
         if (temporal instanceof JapaneseDate) {
             return (JapaneseDate) temporal;
         }
         return new JapaneseDate(LocalDate.from(temporal));
     }
 
+    @Override
+    public JapaneseDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
+        return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
+    }
+
+    @Override
+    public JapaneseDate dateNow() {
+        return dateNow(Clock.systemDefaultZone());
+    }
+
+    @Override
+    public JapaneseDate dateNow(ZoneId zone) {
+        return dateNow(Clock.system(zone));
+    }
+
+    @Override
+    public JapaneseDate dateNow(Clock clock) {
+        return date(LocalDate.now(clock));
+    }
+
+    @Override
+    public ChronoLocalDateTime<JapaneseDate> localDateTime(TemporalAccessor temporal) {
+        return (ChronoLocalDateTime<JapaneseDate>)super.localDateTime(temporal);
+    }
+
+    @Override
+    public ChronoZonedDateTime<JapaneseDate> zonedDateTime(TemporalAccessor temporal) {
+        return (ChronoZonedDateTime<JapaneseDate>)super.zonedDateTime(temporal);
+    }
+
+    @Override
+    public ChronoZonedDateTime<JapaneseDate> zonedDateTime(Instant instant, ZoneId zone) {
+        return (ChronoZonedDateTime<JapaneseDate>)super.zonedDateTime(instant, zone);
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Checks if the specified year is a leap year.
@@ -226,11 +258,11 @@
      */
     @Override
     public boolean isLeapYear(long prolepticYear) {
-        return ISOChrono.INSTANCE.isLeapYear(prolepticYear);
+        return IsoChronology.INSTANCE.isLeapYear(prolepticYear);
     }
 
     @Override
-    public int prolepticYear(Era<JapaneseChrono> era, int yearOfEra) {
+    public int prolepticYear(Era era, int yearOfEra) {
         if (era instanceof JapaneseEra == false) {
             throw new DateTimeException("Era must be JapaneseEra");
         }
@@ -261,13 +293,13 @@
      * @throws DateTimeException if {@code eraValue} is invalid
      */
     @Override
-    public Era<JapaneseChrono> eraOf(int eraValue) {
+    public Era eraOf(int eraValue) {
         return JapaneseEra.of(eraValue);
     }
 
     @Override
-    public List<Era<JapaneseChrono>> eras() {
-        return Arrays.<Era<JapaneseChrono>>asList(JapaneseEra.values());
+    public List<Era> eras() {
+        return Arrays.<Era>asList(JapaneseEra.values());
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java
new file mode 100644
index 0000000..75cd0a5
--- /dev/null
+++ b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package java.time.chrono;
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.YEAR;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.Serializable;
+import java.time.Clock;
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
+import java.util.Calendar;
+import java.util.Objects;
+
+import sun.util.calendar.LocalGregorianCalendar;
+
+/**
+ * A date in the Japanese Imperial calendar system.
+ * <p>
+ * This date operates using the {@linkplain JapaneseChronology Japanese Imperial calendar}.
+ * This calendar system is primarily used in Japan.
+ * <p>
+ * The Japanese Imperial calendar system is the same as the ISO calendar system
+ * apart from the era-based year numbering. The proleptic-year is defined to be
+ * equal to the ISO proleptic-year.
+ * <p>
+ * For example, the Japanese year "Heisei 24" corresponds to ISO year "2012".<br>
+ * Calling {@code japaneseDate.get(YEAR_OF_ERA)} will return 24.<br>
+ * Calling {@code japaneseDate.get(YEAR)} will return 2012.<br>
+ * Calling {@code japaneseDate.get(ERA)} will return 2, corresponding to
+ * {@code JapaneseChronology.ERA_HEISEI}.<br>
+ *
+ * <h3>Specification for implementors</h3>
+ * This class is immutable and thread-safe.
+ *
+ * @since 1.8
+ */
+public final class JapaneseDate
+        extends ChronoDateImpl<JapaneseDate>
+        implements ChronoLocalDate<JapaneseDate>, Serializable {
+
+    /**
+     * Serialization version.
+     */
+    private static final long serialVersionUID = -305327627230580483L;
+
+    /**
+     * The underlying ISO local date.
+     */
+    private transient final LocalDate isoDate;
+    /**
+     * The JapaneseEra of this date.
+     */
+    private transient JapaneseEra era;
+    /**
+     * The Japanese imperial calendar year of this date.
+     */
+    private transient int yearOfEra;
+
+    //-----------------------------------------------------------------------
+    /**
+     * Obtains the current {@code JapaneseDate} from the system clock in the default time-zone.
+     * <p>
+     * This will query the {@link Clock#systemDefaultZone() system clock} in the default
+     * time-zone to obtain the current date.
+     * <p>
+     * Using this method will prevent the ability to use an alternate clock for testing
+     * because the clock is hard-coded.
+     *
+     * @return the current date using the system clock and default time-zone, not null
+     */
+    public static JapaneseDate now() {
+        return now(Clock.systemDefaultZone());
+    }
+
+    /**
+     * Obtains the current {@code JapaneseDate} from the system clock in the specified time-zone.
+     * <p>
+     * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
+     * Specifying the time-zone avoids dependence on the default time-zone.
+     * <p>
+     * Using this method will prevent the ability to use an alternate clock for testing
+     * because the clock is hard-coded.
+     *
+     * @param zone  the zone ID to use, not null
+     * @return the current date using the system clock, not null
+     */
+    public static JapaneseDate now(ZoneId zone) {
+        return now(Clock.system(zone));
+    }
+
+    /**
+     * Obtains the current {@code JapaneseDate} from the specified clock.
+     * <p>
+     * This will query the specified clock to obtain the current date - today.
+     * Using this method allows the use of an alternate clock for testing.
+     * The alternate clock may be introduced using {@linkplain Clock dependency injection}.
+     *
+     * @param clock  the clock to use, not null
+     * @return the current date, not null
+     * @throws DateTimeException if the current date cannot be obtained
+     */
+    public static JapaneseDate now(Clock clock) {
+        return JapaneseChronology.INSTANCE.date(LocalDate.now(clock));
+    }
+
+    /**
+     * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
+     * system from the era, year-of-era, month-of-year and day-of-month fields.
+     * <p>
+     * This returns a {@code JapaneseDate} with the specified fields.
+     * The day must be valid for the year and month, otherwise an exception will be thrown.
+     *
+     * @param era  the Japanese era, not null
+     * @param yearOfEra  the Japanese year-of-era
+     * @param month  the Japanese month-of-year, from 1 to 12
+     * @param dayOfMonth  the Japanese day-of-month, from 1 to 31
+     * @return the date in Japanese calendar system, not null
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year,
+     *  or if the date is not a Japanese era
+     */
+    public static JapaneseDate of(Era era, int yearOfEra, int month, int dayOfMonth) {
+        if (era instanceof JapaneseEra == false) {
+            throw new DateTimeException("Era must be JapaneseEra");
+        }
+        return JapaneseDate.of((JapaneseEra) era, yearOfEra, month, dayOfMonth);
+    }
+
+    /**
+     * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
+     * system from the proleptic-year, month-of-year and day-of-month fields.
+     * <p>
+     * This returns a {@code JapaneseDate} with the specified fields.
+     * The day must be valid for the year and month, otherwise an exception will be thrown.
+     *
+     * @param prolepticYear  the Japanese proleptic-year
+     * @param month  the Japanese month-of-year, from 1 to 12
+     * @param dayOfMonth  the Japanese day-of-month, from 1 to 31
+     * @return the date in Japanese calendar system, not null
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
+     */
+    public static JapaneseDate of(int prolepticYear, int month, int dayOfMonth) {
+        return new JapaneseDate(LocalDate.of(prolepticYear, month, dayOfMonth));
+    }
+
+    /**
+     * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
+     * system from the proleptic-year and day-of-year fields.
+     * <p>
+     * This returns a {@code JapaneseDate} with the specified fields.
+     * The day must be valid for the year, otherwise an exception will be thrown.
+     *
+     * @param prolepticYear  the chronology proleptic-year
+     * @param dayOfYear  the chronology day-of-year, from 1 to 366
+     * @return the date in Japanese calendar system, not null
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-year is invalid for the year
+     */
+    public static JapaneseDate ofYearDay(int prolepticYear, int dayOfYear) {
+        LocalDate date = LocalDate.ofYearDay(prolepticYear, dayOfYear);
+        return of(prolepticYear, date.getMonthValue(), date.getDayOfMonth());
+    }
+
+    /**
+     * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
+     * system from the era, year-of-era, month-of-year and day-of-month fields.
+     * <p>
+     * This returns a {@code JapaneseDate} with the specified fields.
+     * The day must be valid for the year and month, otherwise an exception will be thrown.
+     *
+     * @param era  the Japanese era, not null
+     * @param yearOfEra  the Japanese year-of-era
+     * @param month  the Japanese month-of-year, from 1 to 12
+     * @param dayOfMonth  the Japanese day-of-month, from 1 to 31
+     * @return the date in Japanese calendar system, not null
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
+     */
+    static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) {
+        Objects.requireNonNull(era, "era");
+        LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
+        jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth);
+        if (!JapaneseChronology.JCAL.validate(jdate)) {
+            throw new IllegalArgumentException();
+        }
+        LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth);
+        return new JapaneseDate(era, yearOfEra, date);
+    }
+
+    /**
+     * Obtains a {@code JapaneseDate} from a temporal object.
+     * <p>
+     * This obtains a date in the Japanese calendar system based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code JapaneseDate}.
+     * <p>
+     * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
+     * field, which is standardized across calendar systems.
+     * <p>
+     * This method matches the signature of the functional interface {@link TemporalQuery}
+     * allowing it to be used as a query via method reference, {@code JapaneseDate::from}.
+     *
+     * @param temporal  the temporal object to convert, not null
+     * @return the date in Japanese calendar system, not null
+     * @throws DateTimeException if unable to convert to a {@code JapaneseDate}
+     */
+    public static JapaneseDate from(TemporalAccessor temporal) {
+        return JapaneseChronology.INSTANCE.date(temporal);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Creates an instance from an ISO date.
+     *
+     * @param isoDate  the standard local date, validated not null
+     */
+    JapaneseDate(LocalDate isoDate) {
+        LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate);
+        this.era = JapaneseEra.toJapaneseEra(jdate.getEra());
+        this.yearOfEra = jdate.getYear();
+        this.isoDate = isoDate;
+    }
+
+    /**
+     * Constructs a {@code JapaneseDate}. This constructor does NOT validate the given parameters,
+     * and {@code era} and {@code year} must agree with {@code isoDate}.
+     *
+     * @param era  the era, validated not null
+     * @param year  the year-of-era, validated
+     * @param isoDate  the standard local date, validated not null
+     */
+    JapaneseDate(JapaneseEra era, int year, LocalDate isoDate) {
+        this.era = era;
+        this.yearOfEra = year;
+        this.isoDate = isoDate;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public JapaneseChronology getChronology() {
+        return JapaneseChronology.INSTANCE;
+    }
+
+    @Override
+    public int lengthOfMonth() {
+        return isoDate.lengthOfMonth();
+    }
+
+    @Override
+    public ValueRange range(TemporalField field) {
+        if (field instanceof ChronoField) {
+            if (isSupported(field)) {
+                ChronoField f = (ChronoField) field;
+                switch (f) {
+                    case DAY_OF_YEAR:
+                        return actualRange(Calendar.DAY_OF_YEAR);
+                    case YEAR_OF_ERA:
+                        return actualRange(Calendar.YEAR);
+                }
+                return getChronology().range(f);
+            }
+            throw new DateTimeException("Unsupported field: " + field.getName());
+        }
+        return field.rangeRefinedBy(this);
+    }
+
+    private ValueRange actualRange(int calendarField) {
+        Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE);
+        jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET);
+        jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth());
+        return ValueRange.of(jcal.getActualMinimum(calendarField),
+                jcal.getActualMaximum(calendarField));
+    }
+
+    @Override
+    public long getLong(TemporalField field) {
+        if (field instanceof ChronoField) {
+            switch ((ChronoField) field) {
+                case YEAR_OF_ERA:
+                    return yearOfEra;
+                case ERA:
+                    return era.getValue();
+                case DAY_OF_YEAR: {
+                    LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate);
+                    return JapaneseChronology.JCAL.getDayOfYear(jdate);
+                }
+            }
+            // TODO: review other fields
+            return isoDate.getLong(field);
+        }
+        return field.getFrom(this);
+    }
+
+    /**
+     * Returns a {@code LocalGregorianCalendar.Date} converted from the given {@code isoDate}.
+     *
+     * @param isoDate  the local date, not null
+     * @return a {@code LocalGregorianCalendar.Date}, not null
+     */
+    private static LocalGregorianCalendar.Date toPrivateJapaneseDate(LocalDate isoDate) {
+        LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
+        sun.util.calendar.Era sunEra = JapaneseEra.privateEraFrom(isoDate);
+        int year = isoDate.getYear();
+        if (sunEra != null) {
+            year -= sunEra.getSinceDate().getYear() - 1;
+        }
+        jdate.setEra(sunEra).setYear(year).setMonth(isoDate.getMonthValue()).setDayOfMonth(isoDate.getDayOfMonth());
+        JapaneseChronology.JCAL.normalize(jdate);
+        return jdate;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public JapaneseDate with(TemporalField field, long newValue) {
+        if (field instanceof ChronoField) {
+            ChronoField f = (ChronoField) field;
+            if (getLong(f) == newValue) {
+                return this;
+            }
+            switch (f) {
+                case YEAR_OF_ERA:
+                case YEAR:
+                case ERA: {
+                    f.checkValidValue(newValue);
+                    int nvalue = (int) newValue;
+                    switch (f) {
+                        case YEAR_OF_ERA:
+                            return this.withYear(nvalue);
+                        case YEAR:
+                            return with(isoDate.withYear(nvalue));
+                        case ERA: {
+                            return this.withYear(JapaneseEra.of(nvalue), yearOfEra);
+                        }
+                    }
+                }
+            }
+            // TODO: review other fields, such as WEEK_OF_YEAR
+            return with(isoDate.with(field, newValue));
+        }
+        return (JapaneseDate) ChronoLocalDate.super.with(field, newValue);
+    }
+
+    @Override
+    public Era getEra() {
+        return era;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public  JapaneseDate with(TemporalAdjuster adjuster) {
+        return (JapaneseDate)super.with(adjuster);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public JapaneseDate plus(TemporalAmount amount) {
+        return (JapaneseDate)super.plus(amount);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public JapaneseDate minus(TemporalAmount amount) {
+        return (JapaneseDate)super.minus(amount);
+    }
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a copy of this date with the year altered.
+     * <p>
+     * This method changes the year of the date.
+     * If the month-day is invalid for the year, then the previous valid day
+     * will be selected instead.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param era  the era to set in the result, not null
+     * @param yearOfEra  the year-of-era to set in the returned date
+     * @return a {@code JapaneseDate} based on this date with the requested year, never null
+     * @throws DateTimeException if {@code year} is invalid
+     */
+    private JapaneseDate withYear(JapaneseEra era, int yearOfEra) {
+        int year = JapaneseChronology.INSTANCE.prolepticYear(era, yearOfEra);
+        return with(isoDate.withYear(year));
+    }
+
+    /**
+     * Returns a copy of this date with the year-of-era altered.
+     * <p>
+     * This method changes the year-of-era of the date.
+     * If the month-day is invalid for the year, then the previous valid day
+     * will be selected instead.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param year  the year to set in the returned date
+     * @return a {@code JapaneseDate} based on this date with the requested year-of-era, never null
+     * @throws DateTimeException if {@code year} is invalid
+     */
+    private JapaneseDate withYear(int year) {
+        return withYear((JapaneseEra) getEra(), year);
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    JapaneseDate plusYears(long years) {
+        return with(isoDate.plusYears(years));
+    }
+
+    @Override
+    JapaneseDate plusMonths(long months) {
+        return with(isoDate.plusMonths(months));
+    }
+
+    @Override
+    JapaneseDate plusWeeks(long weeksToAdd) {
+        return with(isoDate.plusWeeks(weeksToAdd));
+    }
+
+    @Override
+    JapaneseDate plusDays(long days) {
+        return with(isoDate.plusDays(days));
+    }
+
+    @Override
+    public JapaneseDate plus(long amountToAdd, TemporalUnit unit) {
+        return (JapaneseDate)super.plus(amountToAdd, unit);
+    }
+
+    @Override
+    public JapaneseDate minus(long amountToAdd, TemporalUnit unit) {
+        return (JapaneseDate)super.minus(amountToAdd, unit);
+    }
+
+    @Override
+    JapaneseDate minusYears(long yearsToSubtract) {
+        return (JapaneseDate)super.minusYears(yearsToSubtract);
+    }
+
+    @Override
+    JapaneseDate minusMonths(long monthsToSubtract) {
+        return (JapaneseDate)super.minusMonths(monthsToSubtract);
+    }
+
+    @Override
+    JapaneseDate minusWeeks(long weeksToSubtract) {
+        return (JapaneseDate)super.minusWeeks(weeksToSubtract);
+    }
+
+    @Override
+    JapaneseDate minusDays(long daysToSubtract) {
+        return (JapaneseDate)super.minusDays(daysToSubtract);
+    }
+
+    private JapaneseDate with(LocalDate newDate) {
+        return (newDate.equals(isoDate) ? this : new JapaneseDate(newDate));
+    }
+
+    @Override        // for javadoc and covariant return type
+    public final ChronoLocalDateTime<JapaneseDate> atTime(LocalTime localTime) {
+        return (ChronoLocalDateTime<JapaneseDate>)super.atTime(localTime);
+    }
+
+    @Override
+    public Period periodUntil(ChronoLocalDate<?> endDate) {
+        return isoDate.periodUntil(endDate);
+    }
+
+    @Override  // override for performance
+    public long toEpochDay() {
+        return isoDate.toEpochDay();
+    }
+
+    //-------------------------------------------------------------------------
+    @Override  // override for performance
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof JapaneseDate) {
+            JapaneseDate otherDate = (JapaneseDate) obj;
+            return this.isoDate.equals(otherDate.isoDate);
+        }
+        return false;
+    }
+
+    @Override  // override for performance
+    public int hashCode() {
+        return getChronology().getId().hashCode() ^ isoDate.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        if (era == JapaneseEra.SEIREKI) {
+            return getChronology().getId() + " " + isoDate.toString();
+        }
+        return super.toString();
+    }
+
+    //-----------------------------------------------------------------------
+    private Object writeReplace() {
+        return new Ser(Ser.JAPANESE_DATE_TYPE, this);
+    }
+
+    void writeExternal(DataOutput out) throws IOException {
+        // JapaneseChronology is implicit in the JAPANESE_DATE_TYPE
+        out.writeInt(get(YEAR));
+        out.writeByte(get(MONTH_OF_YEAR));
+        out.writeByte(get(DAY_OF_MONTH));
+    }
+
+    static JapaneseDate readExternal(DataInput in) throws IOException {
+        int year = in.readInt();
+        int month = in.readByte();
+        int dayOfMonth = in.readByte();
+        return JapaneseChronology.INSTANCE.date(year, month, dayOfMonth);
+    }
+
+}
diff --git a/jdk/src/share/classes/java/time/calendar/JapaneseEra.java b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java
similarity index 97%
rename from jdk/src/share/classes/java/time/calendar/JapaneseEra.java
rename to jdk/src/share/classes/java/time/chrono/JapaneseEra.java
index 3bc4fd7..675f0d6 100644
--- a/jdk/src/share/classes/java/time/calendar/JapaneseEra.java
+++ b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
 import java.io.DataInput;
 import java.io.DataOutput;
@@ -64,7 +64,6 @@
 import java.io.Serializable;
 import java.time.DateTimeException;
 import java.time.LocalDate;
-import java.time.temporal.Era;
 import java.util.Arrays;
 
 import sun.util.calendar.CalendarDate;
@@ -86,7 +85,7 @@
  * @since 1.8
  */
 final class JapaneseEra
-        implements Era<JapaneseChrono>, Serializable {
+        implements Era, Serializable {
 
     // The offset value to 0-based index from the era value.
     // i.e., getValue() + ERA_OFFSET == 0-based index; except that -999 is mapped to zero
@@ -133,7 +132,7 @@
     private static final JapaneseEra[] KNOWN_ERAS;
 
     static {
-        sun.util.calendar.Era[] sunEras = JapaneseChrono.JCAL.getEras();
+        sun.util.calendar.Era[] sunEras = JapaneseChronology.JCAL.getEras();
         ERA_CONFIG = new sun.util.calendar.Era[sunEras.length + 1];
         for (int i = 1; i < ERA_CONFIG.length; i++) {
             ERA_CONFIG[i] = sunEras[i - 1];
@@ -292,8 +291,8 @@
     }
 
     @Override
-    public JapaneseChrono getChrono() {
-        return JapaneseChrono.INSTANCE;
+    public JapaneseChronology getChronology() {
+        return JapaneseChronology.INSTANCE;
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/calendar/MinguoChrono.java b/jdk/src/share/classes/java/time/chrono/MinguoChronology.java
similarity index 76%
rename from jdk/src/share/classes/java/time/calendar/MinguoChrono.java
rename to jdk/src/share/classes/java/time/chrono/MinguoChronology.java
index 70fa85a..7dcf8c4 100644
--- a/jdk/src/share/classes/java/time/calendar/MinguoChrono.java
+++ b/jdk/src/share/classes/java/time/chrono/MinguoChronology.java
@@ -54,18 +54,17 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.YEAR;
 
 import java.io.Serializable;
+import java.time.Clock;
 import java.time.DateTimeException;
+import java.time.Instant;
 import java.time.LocalDate;
-import java.time.temporal.Chrono;
+import java.time.ZoneId;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.ValueRange;
 import java.util.Arrays;
@@ -77,7 +76,7 @@
  * <p>
  * This chronology defines the rules of the Minguo calendar system.
  * This calendar system is primarily used in the Republic of China, often known as Taiwan.
- * Dates are aligned such that {@code 0001-01-01 (Minguo)} is {@code 1911-01-01 (ISO)}.
+ * Dates are aligned such that {@code 0001-01-01 (Minguo)} is {@code 1912-01-01 (ISO)}.
  * <p>
  * The fields are defined as follows:
  * <p><ul>
@@ -100,22 +99,22 @@
  *
  * @since 1.8
  */
-public final class MinguoChrono extends Chrono<MinguoChrono> implements Serializable {
+public final class MinguoChronology extends Chronology implements Serializable {
 
     /**
      * Singleton instance for the Minguo chronology.
      */
-    public static final MinguoChrono INSTANCE = new MinguoChrono();
+    public static final MinguoChronology INSTANCE = new MinguoChronology();
 
     /**
      * The singleton instance for the era ROC.
      */
-    public static final Era<MinguoChrono> ERA_ROC = MinguoEra.ROC;
+    public static final Era ERA_ROC = MinguoEra.ROC;
 
     /**
      * The singleton instance for the era BEFORE_ROC.
      */
-    public static final Era<MinguoChrono> ERA_BEFORE_ROC = MinguoEra.BEFORE_ROC;
+    public static final Era ERA_BEFORE_ROC = MinguoEra.BEFORE_ROC;
 
     /**
      * Serialization version.
@@ -129,7 +128,7 @@
     /**
      * Restricted constructor.
      */
-    private MinguoChrono() {
+    private MinguoChronology() {
     }
 
     /**
@@ -145,8 +144,8 @@
     /**
      * Gets the ID of the chronology - 'Minguo'.
      * <p>
-     * The ID uniquely identifies the {@code Chrono}.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * The ID uniquely identifies the {@code Chronology}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      *
      * @return the chronology ID - 'Minguo'
      * @see #getCalendarType()
@@ -161,7 +160,7 @@
      * <p>
      * The calendar type is an identifier defined by the
      * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      * It can also be used as part of a locale, accessible via
      * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
      *
@@ -175,22 +174,62 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<MinguoChrono> date(int prolepticYear, int month, int dayOfMonth) {
+    public MinguoDate date(int prolepticYear, int month, int dayOfMonth) {
         return new MinguoDate(LocalDate.of(prolepticYear + YEARS_DIFFERENCE, month, dayOfMonth));
     }
 
     @Override
-    public ChronoLocalDate<MinguoChrono> dateYearDay(int prolepticYear, int dayOfYear) {
+    public MinguoDate dateYearDay(int prolepticYear, int dayOfYear) {
         return new MinguoDate(LocalDate.ofYearDay(prolepticYear + YEARS_DIFFERENCE, dayOfYear));
     }
 
     @Override
-    public ChronoLocalDate<MinguoChrono> date(TemporalAccessor temporal) {
+    public MinguoDate date(TemporalAccessor temporal) {
         if (temporal instanceof MinguoDate) {
             return (MinguoDate) temporal;
         }
         return new MinguoDate(LocalDate.from(temporal));
     }
+    @Override
+    public MinguoDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
+        return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
+
+    }
+
+    @Override
+    public MinguoDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
+        return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
+    }
+
+    @Override
+    public MinguoDate dateNow() {
+        return dateNow(Clock.systemDefaultZone());
+    }
+
+    @Override
+    public MinguoDate dateNow(ZoneId zone) {
+        return dateNow(Clock.system(zone));
+    }
+
+    @Override
+    public MinguoDate dateNow(Clock clock) {
+        return date(LocalDate.now(clock));
+    }
+
+    @Override
+    public ChronoLocalDateTime<MinguoDate> localDateTime(TemporalAccessor temporal) {
+        return (ChronoLocalDateTime<MinguoDate>)super.localDateTime(temporal);
+    }
+
+    @Override
+    public ChronoZonedDateTime<MinguoDate> zonedDateTime(TemporalAccessor temporal) {
+        return (ChronoZonedDateTime<MinguoDate>)super.zonedDateTime(temporal);
+    }
+
+    @Override
+    public ChronoZonedDateTime<MinguoDate> zonedDateTime(Instant instant, ZoneId zone) {
+        return (ChronoZonedDateTime<MinguoDate>)super.zonedDateTime(instant, zone);
+    }
 
     //-----------------------------------------------------------------------
     /**
@@ -205,11 +244,11 @@
      */
     @Override
     public boolean isLeapYear(long prolepticYear) {
-        return ISOChrono.INSTANCE.isLeapYear(prolepticYear + YEARS_DIFFERENCE);
+        return IsoChronology.INSTANCE.isLeapYear(prolepticYear + YEARS_DIFFERENCE);
     }
 
     @Override
-    public int prolepticYear(Era<MinguoChrono> era, int yearOfEra) {
+    public int prolepticYear(Era era, int yearOfEra) {
         if (era instanceof MinguoEra == false) {
             throw new DateTimeException("Era must be MinguoEra");
         }
@@ -217,13 +256,13 @@
     }
 
     @Override
-    public Era<MinguoChrono> eraOf(int eraValue) {
+    public Era eraOf(int eraValue) {
         return MinguoEra.of(eraValue);
     }
 
     @Override
-    public List<Era<MinguoChrono>> eras() {
-        return Arrays.<Era<MinguoChrono>>asList(MinguoEra.values());
+    public List<Era> eras() {
+        return Arrays.<Era>asList(MinguoEra.values());
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/chrono/MinguoDate.java b/jdk/src/share/classes/java/time/chrono/MinguoDate.java
new file mode 100644
index 0000000..a02bbd2
--- /dev/null
+++ b/jdk/src/share/classes/java/time/chrono/MinguoDate.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package java.time.chrono;
+
+import static java.time.chrono.MinguoChronology.YEARS_DIFFERENCE;
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.YEAR;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.Serializable;
+import java.time.Clock;
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
+import java.util.Objects;
+
+/**
+ * A date in the Minguo calendar system.
+ * <p>
+ * This date operates using the {@linkplain MinguoChronology Minguo calendar}.
+ * This calendar system is primarily used in the Republic of China, often known as Taiwan.
+ * Dates are aligned such that {@code 0001-01-01 (Minguo)} is {@code 1912-01-01 (ISO)}.
+ *
+ * <h3>Specification for implementors</h3>
+ * This class is immutable and thread-safe.
+ *
+ * @since 1.8
+ */
+public final class MinguoDate
+        extends ChronoDateImpl<MinguoDate>
+        implements ChronoLocalDate<MinguoDate>, Serializable {
+
+    /**
+     * Serialization version.
+     */
+    private static final long serialVersionUID = 1300372329181994526L;
+
+    /**
+     * The underlying date.
+     */
+    private final LocalDate isoDate;
+
+    //-----------------------------------------------------------------------
+    /**
+     * Obtains the current {@code MinguoDate} from the system clock in the default time-zone.
+     * <p>
+     * This will query the {@link Clock#systemDefaultZone() system clock} in the default
+     * time-zone to obtain the current date.
+     * <p>
+     * Using this method will prevent the ability to use an alternate clock for testing
+     * because the clock is hard-coded.
+     *
+     * @return the current date using the system clock and default time-zone, not null
+     */
+    public static MinguoDate now() {
+        return now(Clock.systemDefaultZone());
+    }
+
+    /**
+     * Obtains the current {@code MinguoDate} from the system clock in the specified time-zone.
+     * <p>
+     * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
+     * Specifying the time-zone avoids dependence on the default time-zone.
+     * <p>
+     * Using this method will prevent the ability to use an alternate clock for testing
+     * because the clock is hard-coded.
+     *
+     * @param zone  the zone ID to use, not null
+     * @return the current date using the system clock, not null
+     */
+    public static MinguoDate now(ZoneId zone) {
+        return now(Clock.system(zone));
+    }
+
+    /**
+     * Obtains the current {@code MinguoDate} from the specified clock.
+     * <p>
+     * This will query the specified clock to obtain the current date - today.
+     * Using this method allows the use of an alternate clock for testing.
+     * The alternate clock may be introduced using {@linkplain Clock dependency injection}.
+     *
+     * @param clock  the clock to use, not null
+     * @return the current date, not null
+     * @throws DateTimeException if the current date cannot be obtained
+     */
+    public static MinguoDate now(Clock clock) {
+        return MinguoChronology.INSTANCE.date(LocalDate.now(clock));
+    }
+
+    /**
+     * Obtains a {@code MinguoDate} representing a date in the Minguo calendar
+     * system from the proleptic-year, month-of-year and day-of-month fields.
+     * <p>
+     * This returns a {@code MinguoDate} with the specified fields.
+     * The day must be valid for the year and month, otherwise an exception will be thrown.
+     *
+     * @param prolepticYear  the Minguo proleptic-year
+     * @param month  the Minguo month-of-year, from 1 to 12
+     * @param dayOfMonth  the Minguo day-of-month, from 1 to 31
+     * @return the date in Minguo calendar system, not null
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
+     */
+    public static MinguoDate of(int prolepticYear, int month, int dayOfMonth) {
+        return new MinguoDate(LocalDate.of(prolepticYear + YEARS_DIFFERENCE, month, dayOfMonth));
+    }
+
+    /**
+     * Obtains a {@code MinguoDate} from a temporal object.
+     * <p>
+     * This obtains a date in the Minguo calendar system based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code MinguoDate}.
+     * <p>
+     * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
+     * field, which is standardized across calendar systems.
+     * <p>
+     * This method matches the signature of the functional interface {@link TemporalQuery}
+     * allowing it to be used as a query via method reference, {@code MinguoDate::from}.
+     *
+     * @param temporal  the temporal object to convert, not null
+     * @return the date in Minguo calendar system, not null
+     * @throws DateTimeException if unable to convert to a {@code MinguoDate}
+     */
+    public static MinguoDate from(TemporalAccessor temporal) {
+        return MinguoChronology.INSTANCE.date(temporal);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Creates an instance from an ISO date.
+     *
+     * @param isoDate  the standard local date, validated not null
+     */
+    MinguoDate(LocalDate isoDate) {
+        Objects.requireNonNull(isoDate, "isoDate");
+        this.isoDate = isoDate;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public MinguoChronology getChronology() {
+        return MinguoChronology.INSTANCE;
+    }
+
+    @Override
+    public int lengthOfMonth() {
+        return isoDate.lengthOfMonth();
+    }
+
+    @Override
+    public ValueRange range(TemporalField field) {
+        if (field instanceof ChronoField) {
+            if (isSupported(field)) {
+                ChronoField f = (ChronoField) field;
+                switch (f) {
+                    case DAY_OF_MONTH:
+                    case DAY_OF_YEAR:
+                    case ALIGNED_WEEK_OF_MONTH:
+                        return isoDate.range(field);
+                    case YEAR_OF_ERA: {
+                        ValueRange range = YEAR.range();
+                        long max = (getProlepticYear() <= 0 ? -range.getMinimum() + 1 + YEARS_DIFFERENCE : range.getMaximum() - YEARS_DIFFERENCE);
+                        return ValueRange.of(1, max);
+                    }
+                }
+                return getChronology().range(f);
+            }
+            throw new DateTimeException("Unsupported field: " + field.getName());
+        }
+        return field.rangeRefinedBy(this);
+    }
+
+    @Override
+    public long getLong(TemporalField field) {
+        if (field instanceof ChronoField) {
+            switch ((ChronoField) field) {
+                case YEAR_OF_ERA: {
+                    int prolepticYear = getProlepticYear();
+                    return (prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear);
+                }
+                case YEAR:
+                    return getProlepticYear();
+                case ERA:
+                    return (getProlepticYear() >= 1 ? 1 : 0);
+            }
+            return isoDate.getLong(field);
+        }
+        return field.getFrom(this);
+    }
+
+    private int getProlepticYear() {
+        return isoDate.getYear() - YEARS_DIFFERENCE;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public MinguoDate with(TemporalField field, long newValue) {
+        if (field instanceof ChronoField) {
+            ChronoField f = (ChronoField) field;
+            if (getLong(f) == newValue) {
+                return this;
+            }
+            switch (f) {
+                case YEAR_OF_ERA:
+                case YEAR:
+                case ERA: {
+                    f.checkValidValue(newValue);
+                    int nvalue = (int) newValue;
+                    switch (f) {
+                        case YEAR_OF_ERA:
+                            return with(isoDate.withYear(getProlepticYear() >= 1 ? nvalue + YEARS_DIFFERENCE : (1 - nvalue)  + YEARS_DIFFERENCE));
+                        case YEAR:
+                            return with(isoDate.withYear(nvalue + YEARS_DIFFERENCE));
+                        case ERA:
+                            return with(isoDate.withYear((1 - getProlepticYear()) + YEARS_DIFFERENCE));
+                    }
+                }
+            }
+            return with(isoDate.with(field, newValue));
+        }
+        return (MinguoDate) ChronoLocalDate.super.with(field, newValue);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public  MinguoDate with(TemporalAdjuster adjuster) {
+        return (MinguoDate)super.with(adjuster);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public MinguoDate plus(TemporalAmount amount) {
+        return (MinguoDate)super.plus(amount);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public MinguoDate minus(TemporalAmount amount) {
+        return (MinguoDate)super.minus(amount);
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    MinguoDate plusYears(long years) {
+        return with(isoDate.plusYears(years));
+    }
+
+    @Override
+    MinguoDate plusMonths(long months) {
+        return with(isoDate.plusMonths(months));
+    }
+
+    @Override
+    MinguoDate plusDays(long days) {
+        return with(isoDate.plusDays(days));
+    }
+
+    @Override
+    public MinguoDate plus(long amountToAdd, TemporalUnit unit) {
+        return (MinguoDate)super.plus(amountToAdd, unit);
+    }
+
+    @Override
+    public MinguoDate minus(long amountToAdd, TemporalUnit unit) {
+        return (MinguoDate)super.minus(amountToAdd, unit);
+    }
+
+    @Override
+    MinguoDate plusWeeks(long weeksToAdd) {
+        return (MinguoDate)super.plusWeeks(weeksToAdd);
+    }
+
+    @Override
+    MinguoDate minusYears(long yearsToSubtract) {
+        return (MinguoDate)super.minusYears(yearsToSubtract);
+    }
+
+    @Override
+    MinguoDate minusMonths(long monthsToSubtract) {
+        return (MinguoDate)super.minusMonths(monthsToSubtract);
+    }
+
+    @Override
+    MinguoDate minusWeeks(long weeksToSubtract) {
+        return (MinguoDate)super.minusWeeks(weeksToSubtract);
+    }
+
+    @Override
+    MinguoDate minusDays(long daysToSubtract) {
+        return (MinguoDate)super.minusDays(daysToSubtract);
+    }
+
+    private MinguoDate with(LocalDate newDate) {
+        return (newDate.equals(isoDate) ? this : new MinguoDate(newDate));
+    }
+
+    @Override        // for javadoc and covariant return type
+    public final ChronoLocalDateTime<MinguoDate> atTime(LocalTime localTime) {
+        return (ChronoLocalDateTime<MinguoDate>)super.atTime(localTime);
+    }
+
+    @Override
+    public Period periodUntil(ChronoLocalDate<?> endDate) {
+        return isoDate.periodUntil(endDate);
+    }
+
+    @Override  // override for performance
+    public long toEpochDay() {
+        return isoDate.toEpochDay();
+    }
+
+    //-------------------------------------------------------------------------
+    @Override  // override for performance
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof MinguoDate) {
+            MinguoDate otherDate = (MinguoDate) obj;
+            return this.isoDate.equals(otherDate.isoDate);
+        }
+        return false;
+    }
+
+    @Override  // override for performance
+    public int hashCode() {
+        return getChronology().getId().hashCode() ^ isoDate.hashCode();
+    }
+
+    //-----------------------------------------------------------------------
+    private Object writeReplace() {
+        return new Ser(Ser.MINGUO_DATE_TYPE, this);
+    }
+
+    void writeExternal(DataOutput out) throws IOException {
+        // MinguoChronology is implicit in the MINGUO_DATE_TYPE
+        out.writeInt(get(YEAR));
+        out.writeByte(get(MONTH_OF_YEAR));
+        out.writeByte(get(DAY_OF_MONTH));
+    }
+
+    static ChronoLocalDate readExternal(DataInput in) throws IOException {
+        int year = in.readInt();
+        int month = in.readByte();
+        int dayOfMonth = in.readByte();
+        return MinguoChronology.INSTANCE.date(year, month, dayOfMonth);
+    }
+
+}
diff --git a/jdk/src/share/classes/java/time/calendar/MinguoEra.java b/jdk/src/share/classes/java/time/chrono/MinguoEra.java
similarity index 69%
rename from jdk/src/share/classes/java/time/calendar/MinguoEra.java
rename to jdk/src/share/classes/java/time/chrono/MinguoEra.java
index 7cbf430..a3646f7 100644
--- a/jdk/src/share/classes/java/time/calendar/MinguoEra.java
+++ b/jdk/src/share/classes/java/time/chrono/MinguoEra.java
@@ -54,23 +54,12 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
-
-import static java.time.temporal.ChronoField.ERA;
+package java.time.chrono;
 
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.time.DateTimeException;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.TextStyle;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalField;
-import java.time.temporal.ValueRange;
-import java.util.Locale;
 
 /**
  * An era in the Minguo calendar system.
@@ -86,7 +75,7 @@
  *
  * @since 1.8
  */
-enum MinguoEra implements Era<MinguoChrono>  {
+enum MinguoEra implements Era  {
 
     /**
      * The singleton instance for the era BEFORE_ROC, 'Before Republic of China'.
@@ -135,72 +124,23 @@
     }
 
     @Override
-    public MinguoChrono getChrono() {
-        return MinguoChrono.INSTANCE;
+    public MinguoChronology getChronology() {
+        return MinguoChronology.INSTANCE;
     }
 
     // JDK8 default methods:
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<MinguoChrono> date(int year, int month, int day) {
-        return getChrono().date(this, year, month, day);
+    public MinguoDate date(int year, int month, int day) {
+        return (MinguoDate)(getChronology().date(this, year, month, day));
     }
 
     @Override
-    public ChronoLocalDate<MinguoChrono> dateYearDay(int year, int dayOfYear) {
-        return getChrono().dateYearDay(this, year, dayOfYear);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public boolean isSupported(TemporalField field) {
-        if (field instanceof ChronoField) {
-            return field == ERA;
-        }
-        return field != null && field.doIsSupported(this);
-    }
-
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field == ERA) {
-            return field.range();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doRange(this);
-    }
-
-    @Override
-    public int get(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        }
-        return range(field).checkValidIntValue(getLong(field), field);
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doGet(this);
+    public MinguoDate dateYearDay(int year, int dayOfYear) {
+        return (MinguoDate)(getChronology().dateYearDay(this, year, dayOfYear));
     }
 
     //-------------------------------------------------------------------------
-    @Override
-    public Temporal adjustInto(Temporal temporal) {
-        return temporal.with(ERA, getValue());
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendText(ERA, style).toFormatter(locale).print(this);
-    }
-
-    //-----------------------------------------------------------------------
     private Object writeReplace() {
         return new Ser(Ser.MINGUO_ERA_TYPE, this);
     }
diff --git a/jdk/src/share/classes/java/time/calendar/Ser.java b/jdk/src/share/classes/java/time/chrono/Ser.java
similarity index 84%
rename from jdk/src/share/classes/java/time/calendar/Ser.java
rename to jdk/src/share/classes/java/time/chrono/Ser.java
index 48f5c81..5fec32d 100644
--- a/jdk/src/share/classes/java/time/calendar/Ser.java
+++ b/jdk/src/share/classes/java/time/chrono/Ser.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
 import java.io.Externalizable;
 import java.io.IOException;
@@ -72,7 +72,7 @@
  * This class wraps the object being serialized, and takes a byte representing the type of the class to
  * be serialized.  This byte can also be used for versioning the serialization format.  In this case another
  * byte flag would be used in order to specify an alternative version of the type format.
- * For example {@code JAPANESE_DATE_TYPE_VERSION_2 = 21}.
+ * For example {@code CHRONO_TYPE_VERSION_2 = 21}
  * <p>
  * In order to serialise the object it writes its byte and then calls back to the appropriate class where
  * the serialisation is performed.  In order to deserialise the object it read in the type byte, switching
@@ -94,16 +94,19 @@
     /**
      * Serialization version.
      */
-    private static final long serialVersionUID = 7857518227608961174L;
+    private static final long serialVersionUID = -6103370247208168577L;
 
-    static final byte JAPANESE_DATE_TYPE = 1;
-    static final byte JAPANESE_ERA_TYPE = 2;
-    static final byte HIJRAH_DATE_TYPE = 3;
-    static final byte HIJRAH_ERA_TYPE = 4;
-    static final byte MINGUO_DATE_TYPE = 5;
-    static final byte MINGUO_ERA_TYPE = 6;
-    static final byte THAIBUDDHIST_DATE_TYPE = 7;
-    static final byte THAIBUDDHIST_ERA_TYPE = 8;
+    static final byte CHRONO_TYPE = 1;
+    static final byte CHRONO_LOCAL_DATE_TIME_TYPE = 2;
+    static final byte CHRONO_ZONE_DATE_TIME_TYPE = 3;
+    static final byte JAPANESE_DATE_TYPE = 4;
+    static final byte JAPANESE_ERA_TYPE = 5;
+    static final byte HIJRAH_DATE_TYPE = 6;
+    static final byte HIJRAH_ERA_TYPE = 7;
+    static final byte MINGUO_DATE_TYPE = 8;
+    static final byte MINGUO_ERA_TYPE = 9;
+    static final byte THAIBUDDHIST_DATE_TYPE = 10;
+    static final byte THAIBUDDHIST_ERA_TYPE = 11;
 
     /** The type being serialized. */
     private byte type;
@@ -141,6 +144,15 @@
     private static void writeInternal(byte type, Object object, ObjectOutput out) throws IOException {
         out.writeByte(type);
         switch (type) {
+            case CHRONO_TYPE:
+                ((Chronology) object).writeExternal(out);
+                break;
+            case CHRONO_LOCAL_DATE_TIME_TYPE:
+                ((ChronoLocalDateTimeImpl<?>) object).writeExternal(out);
+                break;
+            case CHRONO_ZONE_DATE_TIME_TYPE:
+                ((ChronoZonedDateTimeImpl<?>) object).writeExternal(out);
+                break;
             case JAPANESE_DATE_TYPE:
                 ((JapaneseDate) object).writeExternal(out);
                 break;
@@ -189,6 +201,9 @@
 
     private static Object readInternal(byte type, ObjectInput in) throws IOException, ClassNotFoundException {
         switch (type) {
+            case CHRONO_TYPE: return Chronology.readExternal(in);
+            case CHRONO_LOCAL_DATE_TIME_TYPE: return ChronoLocalDateTimeImpl.readExternal(in);
+            case CHRONO_ZONE_DATE_TIME_TYPE: return ChronoZonedDateTimeImpl.readExternal(in);
             case JAPANESE_DATE_TYPE:  return JapaneseDate.readExternal(in);
             case JAPANESE_ERA_TYPE: return JapaneseEra.readExternal(in);
             case HIJRAH_DATE_TYPE: return HijrahDate.readExternal(in);
@@ -197,8 +212,7 @@
             case MINGUO_ERA_TYPE: return MinguoEra.readExternal(in);
             case THAIBUDDHIST_DATE_TYPE: return ThaiBuddhistDate.readExternal(in);
             case THAIBUDDHIST_ERA_TYPE: return ThaiBuddhistEra.readExternal(in);
-            default:
-                throw new StreamCorruptedException("Unknown serialized type");
+            default: throw new StreamCorruptedException("Unknown serialized type");
         }
     }
 
diff --git a/jdk/src/share/classes/java/time/calendar/ThaiBuddhistChrono.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java
similarity index 79%
rename from jdk/src/share/classes/java/time/calendar/ThaiBuddhistChrono.java
rename to jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java
index 1fadb5e..daf4cf9 100644
--- a/jdk/src/share/classes/java/time/calendar/ThaiBuddhistChrono.java
+++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java
@@ -54,18 +54,17 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
 import static java.time.temporal.ChronoField.YEAR;
 
 import java.io.Serializable;
+import java.time.Clock;
 import java.time.DateTimeException;
+import java.time.Instant;
 import java.time.LocalDate;
-import java.time.temporal.Chrono;
+import java.time.ZoneId;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.ValueRange;
 import java.util.Arrays;
@@ -101,21 +100,21 @@
  *
  * @since 1.8
  */
-public final class ThaiBuddhistChrono extends Chrono<ThaiBuddhistChrono> implements Serializable {
+public final class ThaiBuddhistChronology extends Chronology implements Serializable {
 
     /**
      * Singleton instance of the Buddhist chronology.
      */
-    public static final ThaiBuddhistChrono INSTANCE = new ThaiBuddhistChrono();
+    public static final ThaiBuddhistChronology INSTANCE = new ThaiBuddhistChronology();
     /**
      * The singleton instance for the era before the current one - Before Buddhist -
      * which has the value 0.
      */
-    public static final Era<ThaiBuddhistChrono> ERA_BEFORE_BE = ThaiBuddhistEra.BEFORE_BE;
+    public static final Era ERA_BEFORE_BE = ThaiBuddhistEra.BEFORE_BE;
     /**
      * The singleton instance for the current era - Buddhist - which has the value 1.
      */
-    public static final Era<ThaiBuddhistChrono> ERA_BE = ThaiBuddhistEra.BE;
+    public static final Era ERA_BE = ThaiBuddhistEra.BE;
 
     /**
      * Serialization version.
@@ -164,7 +163,7 @@
     /**
      * Restricted constructor.
      */
-    private ThaiBuddhistChrono() {
+    private ThaiBuddhistChronology() {
     }
 
     /**
@@ -180,8 +179,8 @@
     /**
      * Gets the ID of the chronology - 'ThaiBuddhist'.
      * <p>
-     * The ID uniquely identifies the {@code Chrono}.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * The ID uniquely identifies the {@code Chronology}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      *
      * @return the chronology ID - 'ThaiBuddhist'
      * @see #getCalendarType()
@@ -196,7 +195,7 @@
      * <p>
      * The calendar type is an identifier defined by the
      * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      * It can also be used as part of a locale, accessible via
      * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
      *
@@ -210,22 +209,62 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<ThaiBuddhistChrono> date(int prolepticYear, int month, int dayOfMonth) {
+    public ThaiBuddhistDate date(int prolepticYear, int month, int dayOfMonth) {
         return new ThaiBuddhistDate(LocalDate.of(prolepticYear - YEARS_DIFFERENCE, month, dayOfMonth));
     }
 
     @Override
-    public ChronoLocalDate<ThaiBuddhistChrono> dateYearDay(int prolepticYear, int dayOfYear) {
+    public ThaiBuddhistDate dateYearDay(int prolepticYear, int dayOfYear) {
         return new ThaiBuddhistDate(LocalDate.ofYearDay(prolepticYear - YEARS_DIFFERENCE, dayOfYear));
     }
 
     @Override
-    public ChronoLocalDate<ThaiBuddhistChrono> date(TemporalAccessor temporal) {
+    public ThaiBuddhistDate date(TemporalAccessor temporal) {
         if (temporal instanceof ThaiBuddhistDate) {
             return (ThaiBuddhistDate) temporal;
         }
         return new ThaiBuddhistDate(LocalDate.from(temporal));
     }
+    @Override
+    public ThaiBuddhistDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
+        return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
+
+    }
+
+    @Override
+    public ThaiBuddhistDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
+        return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
+    }
+
+    @Override
+    public ThaiBuddhistDate dateNow() {
+        return dateNow(Clock.systemDefaultZone());
+    }
+
+    @Override
+    public ThaiBuddhistDate dateNow(ZoneId zone) {
+        return dateNow(Clock.system(zone));
+    }
+
+    @Override
+    public ThaiBuddhistDate dateNow(Clock clock) {
+        return date(LocalDate.now(clock));
+    }
+
+    @Override
+    public ChronoLocalDateTime<ThaiBuddhistDate> localDateTime(TemporalAccessor temporal) {
+        return (ChronoLocalDateTime<ThaiBuddhistDate>)super.localDateTime(temporal);
+    }
+
+    @Override
+    public ChronoZonedDateTime<ThaiBuddhistDate> zonedDateTime(TemporalAccessor temporal) {
+        return (ChronoZonedDateTime<ThaiBuddhistDate>)super.zonedDateTime(temporal);
+    }
+
+    @Override
+    public ChronoZonedDateTime<ThaiBuddhistDate> zonedDateTime(Instant instant, ZoneId zone) {
+        return (ChronoZonedDateTime<ThaiBuddhistDate>)super.zonedDateTime(instant, zone);
+    }
 
     //-----------------------------------------------------------------------
     /**
@@ -240,11 +279,11 @@
      */
     @Override
     public boolean isLeapYear(long prolepticYear) {
-        return ISOChrono.INSTANCE.isLeapYear(prolepticYear - YEARS_DIFFERENCE);
+        return IsoChronology.INSTANCE.isLeapYear(prolepticYear - YEARS_DIFFERENCE);
     }
 
     @Override
-    public int prolepticYear(Era<ThaiBuddhistChrono> era, int yearOfEra) {
+    public int prolepticYear(Era era, int yearOfEra) {
         if (era instanceof ThaiBuddhistEra == false) {
             throw new DateTimeException("Era must be BuddhistEra");
         }
@@ -252,13 +291,13 @@
     }
 
     @Override
-    public Era<ThaiBuddhistChrono> eraOf(int eraValue) {
+    public Era eraOf(int eraValue) {
         return ThaiBuddhistEra.of(eraValue);
     }
 
     @Override
-    public List<Era<ThaiBuddhistChrono>> eras() {
-        return Arrays.<Era<ThaiBuddhistChrono>>asList(ThaiBuddhistEra.values());
+    public List<Era> eras() {
+        return Arrays.<Era>asList(ThaiBuddhistEra.values());
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java
new file mode 100644
index 0000000..e1645c5
--- /dev/null
+++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package java.time.chrono;
+
+import static java.time.chrono.ThaiBuddhistChronology.YEARS_DIFFERENCE;
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.YEAR;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.Serializable;
+import java.time.Clock;
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
+import java.util.Objects;
+
+/**
+ * A date in the Thai Buddhist calendar system.
+ * <p>
+ * This date operates using the {@linkplain ThaiBuddhistChronology Thai Buddhist calendar}.
+ * This calendar system is primarily used in Thailand.
+ * Dates are aligned such that {@code 2484-01-01 (Buddhist)} is {@code 1941-01-01 (ISO)}.
+ *
+ * <h3>Specification for implementors</h3>
+ * This class is immutable and thread-safe.
+ *
+ * @since 1.8
+ */
+public final class ThaiBuddhistDate
+        extends ChronoDateImpl<ThaiBuddhistDate>
+        implements ChronoLocalDate<ThaiBuddhistDate>, Serializable {
+
+    /**
+     * Serialization version.
+     */
+    private static final long serialVersionUID = -8722293800195731463L;
+
+    /**
+     * The underlying date.
+     */
+    private final LocalDate isoDate;
+
+    //-----------------------------------------------------------------------
+    /**
+     * Obtains the current {@code ThaiBuddhistDate} from the system clock in the default time-zone.
+     * <p>
+     * This will query the {@link Clock#systemDefaultZone() system clock} in the default
+     * time-zone to obtain the current date.
+     * <p>
+     * Using this method will prevent the ability to use an alternate clock for testing
+     * because the clock is hard-coded.
+     *
+     * @return the current date using the system clock and default time-zone, not null
+     */
+    public static ThaiBuddhistDate now() {
+        return now(Clock.systemDefaultZone());
+    }
+
+    /**
+     * Obtains the current {@code ThaiBuddhistDate} from the system clock in the specified time-zone.
+     * <p>
+     * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
+     * Specifying the time-zone avoids dependence on the default time-zone.
+     * <p>
+     * Using this method will prevent the ability to use an alternate clock for testing
+     * because the clock is hard-coded.
+     *
+     * @param zone  the zone ID to use, not null
+     * @return the current date using the system clock, not null
+     */
+    public static ThaiBuddhistDate now(ZoneId zone) {
+        return now(Clock.system(zone));
+    }
+
+    /**
+     * Obtains the current {@code ThaiBuddhistDate} from the specified clock.
+     * <p>
+     * This will query the specified clock to obtain the current date - today.
+     * Using this method allows the use of an alternate clock for testing.
+     * The alternate clock may be introduced using {@linkplain Clock dependency injection}.
+     *
+     * @param clock  the clock to use, not null
+     * @return the current date, not null
+     * @throws DateTimeException if the current date cannot be obtained
+     */
+    public static ThaiBuddhistDate now(Clock clock) {
+        return ThaiBuddhistChronology.INSTANCE.date(LocalDate.now(clock));
+    }
+
+    /**
+     * Obtains a {@code ThaiBuddhistDate} representing a date in the Thai Buddhist calendar
+     * system from the proleptic-year, month-of-year and day-of-month fields.
+     * <p>
+     * This returns a {@code ThaiBuddhistDate} with the specified fields.
+     * The day must be valid for the year and month, otherwise an exception will be thrown.
+     *
+     * @param prolepticYear  the Thai Buddhist proleptic-year
+     * @param month  the Thai Buddhist month-of-year, from 1 to 12
+     * @param dayOfMonth  the Thai Buddhist day-of-month, from 1 to 31
+     * @return the date in Thai Buddhist calendar system, not null
+     * @throws DateTimeException if the value of any field is out of range,
+     *  or if the day-of-month is invalid for the month-year
+     */
+    public static ThaiBuddhistDate of(int prolepticYear, int month, int dayOfMonth) {
+        return new ThaiBuddhistDate(LocalDate.of(prolepticYear - YEARS_DIFFERENCE, month, dayOfMonth));
+    }
+
+    /**
+     * Obtains a {@code ThaiBuddhistDate} from a temporal object.
+     * <p>
+     * This obtains a date in the Thai Buddhist calendar system based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code ThaiBuddhistDate}.
+     * <p>
+     * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
+     * field, which is standardized across calendar systems.
+     * <p>
+     * This method matches the signature of the functional interface {@link TemporalQuery}
+     * allowing it to be used as a query via method reference, {@code ThaiBuddhistDate::from}.
+     *
+     * @param temporal  the temporal object to convert, not null
+     * @return the date in Thai Buddhist calendar system, not null
+     * @throws DateTimeException if unable to convert to a {@code ThaiBuddhistDate}
+     */
+    public static ThaiBuddhistDate from(TemporalAccessor temporal) {
+        return ThaiBuddhistChronology.INSTANCE.date(temporal);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Creates an instance from an ISO date.
+     *
+     * @param isoDate  the standard local date, validated not null
+     */
+    ThaiBuddhistDate(LocalDate isoDate) {
+        Objects.requireNonNull(isoDate, "isoDate");
+        this.isoDate = isoDate;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public ThaiBuddhistChronology getChronology() {
+        return ThaiBuddhistChronology.INSTANCE;
+    }
+
+    @Override
+    public int lengthOfMonth() {
+        return isoDate.lengthOfMonth();
+    }
+
+    @Override
+    public ValueRange range(TemporalField field) {
+        if (field instanceof ChronoField) {
+            if (isSupported(field)) {
+                ChronoField f = (ChronoField) field;
+                switch (f) {
+                    case DAY_OF_MONTH:
+                    case DAY_OF_YEAR:
+                    case ALIGNED_WEEK_OF_MONTH:
+                        return isoDate.range(field);
+                    case YEAR_OF_ERA: {
+                        ValueRange range = YEAR.range();
+                        long max = (getProlepticYear() <= 0 ? -(range.getMinimum() + YEARS_DIFFERENCE) + 1 : range.getMaximum() + YEARS_DIFFERENCE);
+                        return ValueRange.of(1, max);
+                    }
+                }
+                return getChronology().range(f);
+            }
+            throw new DateTimeException("Unsupported field: " + field.getName());
+        }
+        return field.rangeRefinedBy(this);
+    }
+
+    @Override
+    public long getLong(TemporalField field) {
+        if (field instanceof ChronoField) {
+            switch ((ChronoField) field) {
+                case YEAR_OF_ERA: {
+                    int prolepticYear = getProlepticYear();
+                    return (prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear);
+                }
+                case YEAR:
+                    return getProlepticYear();
+                case ERA:
+                    return (getProlepticYear() >= 1 ? 1 : 0);
+            }
+            return isoDate.getLong(field);
+        }
+        return field.getFrom(this);
+    }
+
+    private int getProlepticYear() {
+        return isoDate.getYear() + YEARS_DIFFERENCE;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public ThaiBuddhistDate with(TemporalField field, long newValue) {
+        if (field instanceof ChronoField) {
+            ChronoField f = (ChronoField) field;
+            if (getLong(f) == newValue) {
+                return this;
+            }
+            switch (f) {
+                case YEAR_OF_ERA:
+                case YEAR:
+                case ERA: {
+                    f.checkValidValue(newValue);
+                    int nvalue = (int) newValue;
+                    switch (f) {
+                        case YEAR_OF_ERA:
+                            return with(isoDate.withYear((getProlepticYear() >= 1 ? nvalue : 1 - nvalue)  - YEARS_DIFFERENCE));
+                        case YEAR:
+                            return with(isoDate.withYear(nvalue - YEARS_DIFFERENCE));
+                        case ERA:
+                            return with(isoDate.withYear((1 - getProlepticYear()) - YEARS_DIFFERENCE));
+                    }
+                }
+            }
+            return with(isoDate.with(field, newValue));
+        }
+        return (ThaiBuddhistDate) ChronoLocalDate.super.with(field, newValue);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public  ThaiBuddhistDate with(TemporalAdjuster adjuster) {
+        return (ThaiBuddhistDate)super.with(adjuster);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public ThaiBuddhistDate plus(TemporalAmount amount) {
+        return (ThaiBuddhistDate)super.plus(amount);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws DateTimeException {@inheritDoc}
+     * @throws ArithmeticException {@inheritDoc}
+     */
+    @Override
+    public ThaiBuddhistDate minus(TemporalAmount amount) {
+        return (ThaiBuddhistDate)super.minus(amount);
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    ThaiBuddhistDate plusYears(long years) {
+        return with(isoDate.plusYears(years));
+    }
+
+    @Override
+    ThaiBuddhistDate plusMonths(long months) {
+        return with(isoDate.plusMonths(months));
+    }
+
+    @Override
+    ThaiBuddhistDate plusWeeks(long weeksToAdd) {
+        return (ThaiBuddhistDate)super.plusWeeks(weeksToAdd);
+    }
+
+    @Override
+    ThaiBuddhistDate plusDays(long days) {
+        return with(isoDate.plusDays(days));
+    }
+
+    @Override
+    public ThaiBuddhistDate plus(long amountToAdd, TemporalUnit unit) {
+        return (ThaiBuddhistDate)super.plus(amountToAdd, unit);
+    }
+
+    @Override
+    public ThaiBuddhistDate minus(long amountToAdd, TemporalUnit unit) {
+        return (ThaiBuddhistDate)super.minus(amountToAdd, unit);
+    }
+
+    @Override
+    ThaiBuddhistDate minusYears(long yearsToSubtract) {
+        return (ThaiBuddhistDate)super.minusYears(yearsToSubtract);
+    }
+
+    @Override
+    ThaiBuddhistDate minusMonths(long monthsToSubtract) {
+        return (ThaiBuddhistDate)super.minusMonths(monthsToSubtract);
+    }
+
+    @Override
+    ThaiBuddhistDate minusWeeks(long weeksToSubtract) {
+        return (ThaiBuddhistDate)super.minusWeeks(weeksToSubtract);
+    }
+
+    @Override
+    ThaiBuddhistDate minusDays(long daysToSubtract) {
+        return (ThaiBuddhistDate)super.minusDays(daysToSubtract);
+    }
+
+    private ThaiBuddhistDate with(LocalDate newDate) {
+        return (newDate.equals(isoDate) ? this : new ThaiBuddhistDate(newDate));
+    }
+
+    @Override        // for javadoc and covariant return type
+    public final ChronoLocalDateTime<ThaiBuddhistDate> atTime(LocalTime localTime) {
+        return (ChronoLocalDateTime<ThaiBuddhistDate>)super.atTime(localTime);
+    }
+
+    @Override
+    public Period periodUntil(ChronoLocalDate<?> endDate) {
+        return isoDate.periodUntil(endDate);
+    }
+
+    @Override  // override for performance
+    public long toEpochDay() {
+        return isoDate.toEpochDay();
+    }
+
+    //-------------------------------------------------------------------------
+    @Override  // override for performance
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ThaiBuddhistDate) {
+            ThaiBuddhistDate otherDate = (ThaiBuddhistDate) obj;
+            return this.isoDate.equals(otherDate.isoDate);
+        }
+        return false;
+    }
+
+    @Override  // override for performance
+    public int hashCode() {
+        return getChronology().getId().hashCode() ^ isoDate.hashCode();
+    }
+
+    //-----------------------------------------------------------------------
+    private Object writeReplace() {
+        return new Ser(Ser.THAIBUDDHIST_DATE_TYPE, this);
+    }
+
+    void writeExternal(DataOutput out) throws IOException {
+        // ThaiBuddhistChronology is implicit in the THAIBUDDHIST_DATE_TYPE
+        out.writeInt(this.get(YEAR));
+        out.writeByte(this.get(MONTH_OF_YEAR));
+        out.writeByte(this.get(DAY_OF_MONTH));
+    }
+
+    static ThaiBuddhistDate readExternal(DataInput in) throws IOException {
+        int year = in.readInt();
+        int month = in.readByte();
+        int dayOfMonth = in.readByte();
+        return ThaiBuddhistChronology.INSTANCE.date(year, month, dayOfMonth);
+    }
+
+}
diff --git a/jdk/src/share/classes/java/time/calendar/ThaiBuddhistEra.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistEra.java
similarity index 68%
rename from jdk/src/share/classes/java/time/calendar/ThaiBuddhistEra.java
rename to jdk/src/share/classes/java/time/chrono/ThaiBuddhistEra.java
index 713d3e6..24c1bb3 100644
--- a/jdk/src/share/classes/java/time/calendar/ThaiBuddhistEra.java
+++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistEra.java
@@ -54,23 +54,13 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package java.time.calendar;
+package java.time.chrono;
 
-import static java.time.temporal.ChronoField.ERA;
 
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.time.DateTimeException;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.TextStyle;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalField;
-import java.time.temporal.ValueRange;
-import java.util.Locale;
 
 /**
  * An era in the Thai Buddhist calendar system.
@@ -85,7 +75,7 @@
  *
  * @since 1.8
  */
-enum ThaiBuddhistEra implements Era<ThaiBuddhistChrono> {
+enum ThaiBuddhistEra implements Era {
 
     /**
      * The singleton instance for the era before the current one, 'Before Buddhist Era',
@@ -134,69 +124,20 @@
     }
 
     @Override
-    public ThaiBuddhistChrono getChrono() {
-        return ThaiBuddhistChrono.INSTANCE;
+    public ThaiBuddhistChronology getChronology() {
+        return ThaiBuddhistChronology.INSTANCE;
     }
 
     // JDK8 default methods:
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<ThaiBuddhistChrono> date(int year, int month, int day) {
-        return getChrono().date(this, year, month, day);
+    public ThaiBuddhistDate date(int year, int month, int day) {
+        return (ThaiBuddhistDate)(getChronology().date(this, year, month, day));
     }
 
     @Override
-    public ChronoLocalDate<ThaiBuddhistChrono> dateYearDay(int year, int dayOfYear) {
-        return getChrono().dateYearDay(this, year, dayOfYear);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public boolean isSupported(TemporalField field) {
-        if (field instanceof ChronoField) {
-            return field == ERA;
-        }
-        return field != null && field.doIsSupported(this);
-    }
-
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field == ERA) {
-            return field.range();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doRange(this);
-    }
-
-    @Override
-    public int get(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        }
-        return range(field).checkValidIntValue(getLong(field), field);
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doGet(this);
-    }
-
-    //-------------------------------------------------------------------------
-    @Override
-    public Temporal adjustInto(Temporal temporal) {
-        return temporal.with(ERA, getValue());
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendText(ERA, style).toFormatter(locale).print(this);
+    public ThaiBuddhistDate dateYearDay(int year, int dayOfYear) {
+        return (ThaiBuddhistDate)(getChronology().dateYearDay(this, year, dayOfYear));
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/chrono/package-info.java b/jdk/src/share/classes/java/time/chrono/package-info.java
new file mode 100644
index 0000000..4f2a3f6
--- /dev/null
+++ b/jdk/src/share/classes/java/time/chrono/package-info.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * <p>
+ * Generic API for calendar systems other than the default ISO.
+ * </p>
+ * <p>
+ * The main API is based around the calendar system defined in ISO-8601.
+ * However, there are other calendar systems, and this package provides basic support for them.
+ * The alternate calendars are provided in the {@link java.time.chrono} package.
+ * </p>
+ * <p>
+ * A calendar system is defined by the {@link java.time.chrono.Chronology} interface,
+ * while a date in a calendar system is defined by the {@link java.time.chrono.ChronoLocalDate} interface.
+ * </p>
+ * <p>
+ * It is intended that applications use the main API whenever possible, including code to read and write
+ * from a persistent data store, such as a database, and to send dates and times across a network.
+ * The "chrono" classes are then used at the user interface level to deal with localized input/output.
+ * See {@link java.time.chrono.ChronoLocalDate ChronoLocalDate}
+ * for a full discussion of the issues.
+ * </p>
+ * <p>
+ * Using non-ISO calendar systems in an application introduces significant extra complexity.
+ * Ensure that the warnings and recommendations in {@code ChronoLocalDate} have been read before
+ * working with the "chrono" interfaces.
+ * </p>
+ * <p>
+ * The supported calendar systems includes:
+ * </p>
+ * <ul>
+ * <li>{@link java.time.chrono.HijrahChronology Hijrah calendar}</li>
+ * <li>{@link java.time.chrono.JapaneseChronology Japanese calendar}</li>
+ * <li>{@link java.time.chrono.MinguoChronology Minguo calendar}</li>
+ * <li>{@link java.time.chrono.ThaiBuddhistChronology Thai Buddhist calendar}</li>
+ * </ul>
+ *
+ * <h3>Example</h3>
+ * <p>
+ * This example lists todays date for all of the available calendars.
+ * </p>
+ * <pre>
+ *   // Enumerate the list of available calendars and print todays date for each.
+ *       Set&lt;Chronology&gt; chronos = Chronology.getAvailableChronologies();
+ *       for (Chronology chrono : chronos) {
+ *           ChronoLocalDate&lt;?&gt; date = chrono.dateNow();
+ *           System.out.printf("   %20s: %s%n", chrono.getId(), date.toString());
+ *       }
+ * </pre>
+ *
+ * <p>
+ * This example creates and uses a date in a named non-ISO calendar system.
+ * </p>
+ * <pre>
+ *   // Print the Thai Buddhist date
+ *       ChronoLocalDate&lt;?&gt; now1 = Chronology.of("ThaiBuddhist").dateNow();
+ *       int day = now1.get(ChronoField.DAY_OF_MONTH);
+ *       int dow = now1.get(ChronoField.DAY_OF_WEEK);
+ *       int month = now1.get(ChronoField.MONTH_OF_YEAR);
+ *       int year = now1.get(ChronoField.YEAR);
+ *       System.out.printf("  Today is %s %s %d-%s-%d%n", now1.getChronology().getId(),
+ *                 dow, day, month, year);
+ *   // Print today's date and the last day of the year for the Thai Buddhist Calendar.
+ *       ChronoLocalDate&lt;?&gt; first = now1
+ *                 .with(ChronoField.DAY_OF_MONTH, 1)
+ *                 .with(ChronoField.MONTH_OF_YEAR, 1);
+ *       ChronoLocalDate&lt;?&gt; last = first
+ *                 .plus(1, ChronoUnit.YEARS)
+ *                 .minus(1, ChronoUnit.DAYS);
+ *       System.out.printf("  %s: 1st of year: %s; end of year: %s%n", last.getChronology().getId(),
+ *                 first, last);
+ *  </pre>
+ *
+ * <p>
+ * This example creates and uses a date in a specific ThaiBuddhist calendar system.
+ * </p>
+ * <pre>
+ *   // Print the Thai Buddhist date
+ *       ThaiBuddhistDate now1 = ThaiBuddhistDate.now();
+ *       int day = now1.get(ChronoField.DAY_OF_MONTH);
+ *       int dow = now1.get(ChronoField.DAY_OF_WEEK);
+ *       int month = now1.get(ChronoField.MONTH_OF_YEAR);
+ *       int year = now1.get(ChronoField.YEAR);
+ *       System.out.printf("  Today is %s %s %d-%s-%d%n", now1.getChronology().getId(),
+ *                 dow, day, month, year);
+ *
+ *   // Print today's date and the last day of the year for the Thai Buddhist Calendar.
+ *       ThaiBuddhistDate first = now1
+ *                 .with(ChronoField.DAY_OF_MONTH, 1)
+ *                 .with(ChronoField.MONTH_OF_YEAR, 1);
+ *       ThaiBuddhistDate last = first
+ *                 .plus(1, ChronoUnit.YEARS)
+ *                 .minus(1, ChronoUnit.DAYS);
+ *       System.out.printf("  %s: 1st of year: %s; end of year: %s%n", last.getChronology().getId(),
+ *                 first, last);
+ *  </pre>
+ *
+ * <h3>Package specification</h3>
+ * <p>
+ * Unless otherwise noted, passing a null argument to a constructor or method in any class or interface
+ * in this package will cause a {@link java.lang.NullPointerException NullPointerException} to be thrown.
+ * The Javadoc "@param" definition is used to summarise the null-behavior.
+ * The "@throws {@link java.lang.NullPointerException}" is not explicitly documented in each method.
+ * </p>
+ * <p>
+ * All calculations should check for numeric overflow and throw either an {@link java.lang.ArithmeticException}
+ * or a {@link java.time.DateTimeException}.
+ * </p>
+ * @since JDK1.8
+ */
+package java.time.chrono;
diff --git a/jdk/src/share/classes/java/time/format/DateTimeBuilder.java b/jdk/src/share/classes/java/time/format/DateTimeBuilder.java
index 32c7084..43f85bb 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeBuilder.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeBuilder.java
@@ -74,9 +74,9 @@
 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
 import static java.time.temporal.ChronoField.EPOCH_DAY;
 import static java.time.temporal.ChronoField.EPOCH_MONTH;
+import static java.time.temporal.ChronoField.ERA;
 import static java.time.temporal.ChronoField.HOUR_OF_AMPM;
 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
-import static java.time.temporal.ChronoField.INSTANT_SECONDS;
 import static java.time.temporal.ChronoField.MICRO_OF_DAY;
 import static java.time.temporal.ChronoField.MICRO_OF_SECOND;
 import static java.time.temporal.ChronoField.MILLI_OF_DAY;
@@ -86,34 +86,33 @@
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.NANO_OF_DAY;
 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
-import static java.time.temporal.ChronoField.OFFSET_SECONDS;
 import static java.time.temporal.ChronoField.SECOND_OF_DAY;
 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
 import static java.time.temporal.ChronoField.YEAR;
+import static java.time.temporal.ChronoField.YEAR_OF_ERA;
 
 import java.time.DateTimeException;
 import java.time.DayOfWeek;
-import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.temporal.Chrono;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Chronology;
+import java.time.chrono.Era;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
 import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
 import java.time.temporal.Queries;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.util.ArrayList;
 import java.util.EnumMap;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Objects;
-import java.util.Set;
 
 /**
  * Builder that can holds date and time fields and related date and time objects.
@@ -121,12 +120,11 @@
  * <b>This class still needs major revision before JDK1.8 ships.</b>
  * <p>
  * The builder is used to hold onto different elements of date and time.
- * It is designed as two separate maps:
+ * It holds two kinds of object:
  * <p><ul>
- * <li>from {@link java.time.temporal.TemporalField} to {@code long} value, where the value may be
- * outside the valid range for the field
- * <li>from {@code Class} to {@link java.time.temporal.TemporalAccessor}, holding larger scale objects
- * like {@code LocalDateTime}.
+ * <li>a {@code Map} from {@link TemporalField} to {@code long} value, where the
+ *  value may be outside the valid range for the field
+ * <li>a list of objects, such as {@code Chronology} or {@code ZoneId}
  * </ul><p>
  *
  * <h3>Specification for implementors</h3>
@@ -135,7 +133,7 @@
  *
  * @since 1.8
  */
-public final class DateTimeBuilder
+final class DateTimeBuilder
         implements TemporalAccessor, Cloneable {
 
     /**
@@ -147,9 +145,21 @@
      */
     private final EnumMap<ChronoField, Long> standardFields = new EnumMap<ChronoField, Long>(ChronoField.class);
     /**
-     * The list of complete date-time objects.
+     * The chronology.
      */
-    private final List<Object> objects = new ArrayList<>(2);
+    private Chronology chrono;
+    /**
+     * The zone.
+     */
+    private ZoneId zone;
+    /**
+     * The date.
+     */
+    private LocalDate date;
+    /**
+     * The time.
+     */
+    private LocalTime time;
 
     //-----------------------------------------------------------------------
     /**
@@ -158,74 +168,7 @@
     public DateTimeBuilder() {
     }
 
-    /**
-     * Creates a new instance of the builder with a single field-value.
-     * <p>
-     * This is equivalent to using {@link #addFieldValue(TemporalField, long)} on an empty builder.
-     *
-     * @param field  the field to add, not null
-     * @param value  the value to add, not null
-     */
-    public DateTimeBuilder(TemporalField field, long value) {
-        addFieldValue(field, value);
-    }
-
-    /**
-     * Creates a new instance of the builder.
-     *
-     * @param zone  the zone, may be null
-     * @param chrono  the chronology, may be null
-     */
-    public DateTimeBuilder(ZoneId zone, Chrono<?> chrono) {
-        if (zone != null) {
-            objects.add(zone);
-        }
-        if (chrono != null) {
-            objects.add(chrono);
-        }
-    }
-
     //-----------------------------------------------------------------------
-    /**
-     * Gets the map of field-value pairs in the builder.
-     *
-     * @return a modifiable copy of the field-value map, not null
-     */
-    public Map<TemporalField, Long> getFieldValueMap() {
-        Map<TemporalField, Long> map = new HashMap<TemporalField, Long>(standardFields);
-        if (otherFields != null) {
-            map.putAll(otherFields);
-        }
-        return map;
-    }
-
-    /**
-     * Checks whether the specified field is present in the builder.
-     *
-     * @param field  the field to find in the field-value map, not null
-     * @return true if the field is present
-     */
-    public boolean containsFieldValue(TemporalField field) {
-        Objects.requireNonNull(field, "field");
-        return standardFields.containsKey(field) || (otherFields != null && otherFields.containsKey(field));
-    }
-
-    /**
-     * Gets the value of the specified field from the builder.
-     *
-     * @param field  the field to query in the field-value map, not null
-     * @return the value of the field, may be out of range
-     * @throws DateTimeException if the field is not present
-     */
-    public long getFieldValue(TemporalField field) {
-        Objects.requireNonNull(field, "field");
-        Long value = getFieldValue0(field);
-        if (value == null) {
-            throw new DateTimeException("Field not found: " + field);
-        }
-        return value;
-    }
-
     private Long getFieldValue0(TemporalField field) {
         if (field instanceof ChronoField) {
             return standardFields.get(field);
@@ -236,18 +179,6 @@
     }
 
     /**
-     * Gets the value of the specified field from the builder ensuring it is valid.
-     *
-     * @param field  the field to query in the field-value map, not null
-     * @return the value of the field, may be out of range
-     * @throws DateTimeException if the field is not present
-     */
-    public long getValidFieldValue(TemporalField field) {
-        long value = getFieldValue(field);
-        return field.range().checkValidValue(value, field);
-    }
-
-    /**
      * Adds a field-value pair to the builder.
      * <p>
      * This adds a field to the builder.
@@ -261,7 +192,7 @@
      * @return {@code this}, for method chaining
      * @throws DateTimeException if the field is already present with a different value
      */
-    public DateTimeBuilder addFieldValue(TemporalField field, long value) {
+    DateTimeBuilder addFieldValue(TemporalField field, long value) {
         Objects.requireNonNull(field, "field");
         Long old = getFieldValue0(field);  // check first for better error message
         if (old != null && old.longValue() != value) {
@@ -282,125 +213,21 @@
         return this;
     }
 
-    /**
-     * Removes a field-value pair from the builder.
-     * <p>
-     * This removes a field, which must exist, from the builder.
-     * See {@link #removeFieldValues(TemporalField...)} for a version which does not throw an exception
-     *
-     * @param field  the field to remove, not null
-     * @return the previous value of the field
-     * @throws DateTimeException if the field is not found
-     */
-    public long removeFieldValue(TemporalField field) {
-        Objects.requireNonNull(field, "field");
-        Long value = null;
-        if (field instanceof ChronoField) {
-            value = standardFields.remove(field);
-        } else if (otherFields != null) {
-            value = otherFields.remove(field);
-        }
-        if (value == null) {
-            throw new DateTimeException("Field not found: " + field);
-        }
-        return value;
-    }
-
     //-----------------------------------------------------------------------
-    /**
-     * Removes a list of fields from the builder.
-     * <p>
-     * This removes the specified fields from the builder.
-     * No exception is thrown if the fields are not present.
-     *
-     * @param fields  the fields to remove, not null
-     */
-    public void removeFieldValues(TemporalField... fields) {
-        for (TemporalField field : fields) {
-            if (field instanceof ChronoField) {
-                standardFields.remove(field);
-            } else if (otherFields != null) {
-                otherFields.remove(field);
-            }
-        }
+    void addObject(Chronology chrono) {
+        this.chrono = chrono;
     }
 
-    /**
-     * Queries a list of fields from the builder.
-     * <p>
-     * This gets the value of the specified fields from the builder into
-     * an array where the positions match the order of the fields.
-     * If a field is not present, the array will contain null in that position.
-     *
-     * @param fields  the fields to query, not null
-     * @return the array of field values, not null
-     */
-    public Long[] queryFieldValues(TemporalField... fields) {
-        Long[] values = new Long[fields.length];
-        int i = 0;
-        for (TemporalField field : fields) {
-            values[i++] = getFieldValue0(field);
-        }
-        return values;
+    void addObject(ZoneId zone) {
+        this.zone = zone;
     }
 
-    //-----------------------------------------------------------------------
-    /**
-     * Gets the list of date-time objects in the builder.
-     * <p>
-     * This map is intended for use with {@link ZoneOffset} and {@link ZoneId}.
-     * The returned map is live and may be edited.
-     *
-     * @return the editable list of date-time objects, not null
-     */
-    public List<Object> getCalendricalList() {
-        return objects;
+    void addObject(LocalDate date) {
+        this.date = date;
     }
 
-    /**
-     * Adds a date-time object to the builder.
-     * <p>
-     * This adds a date-time object to the builder.
-     * If the object is a {@code DateTimeBuilder}, each field is added using {@link #addFieldValue}.
-     * If the object is not already present, then the object is added.
-     * If the object is already present and it is equal to that specified, no action occurs.
-     * If the object is already present and it is not equal to that specified, then an exception is thrown.
-     *
-     * @param object  the object to add, not null
-     * @return {@code this}, for method chaining
-     * @throws DateTimeException if the field is already present with a different value
-     */
-    public DateTimeBuilder addCalendrical(Object object) {
-        Objects.requireNonNull(object, "object");
-        // special case
-        if (object instanceof DateTimeBuilder) {
-            DateTimeBuilder dtb = (DateTimeBuilder) object;
-            for (TemporalField field : dtb.getFieldValueMap().keySet()) {
-                addFieldValue(field, dtb.getFieldValue(field));
-            }
-            return this;
-        }
-        if (object instanceof Instant) {
-            addFieldValue(INSTANT_SECONDS, ((Instant) object).getEpochSecond());
-            addFieldValue(NANO_OF_SECOND, ((Instant) object).getNano());
-        } else {
-            objects.add(object);
-        }
-//      TODO
-//        // preserve state of builder until validated
-//        Class<?> cls = dateTime.extract(Class.class);
-//        if (cls == null) {
-//            throw new DateTimeException("Invalid dateTime, unable to extract Class");
-//        }
-//        Object obj = objects.get(cls);
-//        if (obj != null) {
-//            if (obj.equals(dateTime) == false) {
-//                throw new DateTimeException("Conflict found: " + dateTime.getClass().getSimpleName() + " " + obj + " differs from " + dateTime + ": " + this);
-//            }
-//        } else {
-//            objects.put(cls, dateTime);
-//        }
-        return this;
+    void addObject(LocalTime time) {
+        this.time = time;
     }
 
     //-----------------------------------------------------------------------
@@ -413,21 +240,7 @@
      *
      * @return {@code this}, for method chaining
      */
-    public DateTimeBuilder resolve() {
-        splitObjects();
-        // handle unusual fields
-        if (otherFields != null) {
-            outer:
-            while (true) {
-                Set<Entry<TemporalField, Long>> entrySet = new HashSet<>(otherFields.entrySet());
-                for (Entry<TemporalField, Long> entry : entrySet) {
-                    if (entry.getKey().resolve(this, entry.getValue())) {
-                        continue outer;
-                    }
-                }
-                break;
-            }
-        }
+    DateTimeBuilder resolve() {
         // handle standard fields
         mergeDate();
         mergeTime();
@@ -441,11 +254,39 @@
             return;
         }
 
-        // normalize fields
-        if (standardFields.containsKey(EPOCH_MONTH)) {
-            long em = standardFields.remove(EPOCH_MONTH);
-            addFieldValue(MONTH_OF_YEAR, (em % 12) + 1);
-            addFieldValue(YEAR, (em / 12) + 1970);
+        Era era = null;
+        if (chrono == IsoChronology.INSTANCE) {
+            // normalize fields
+            if (standardFields.containsKey(EPOCH_MONTH)) {
+                long em = standardFields.remove(EPOCH_MONTH);
+                addFieldValue(MONTH_OF_YEAR, (em % 12) + 1);
+                addFieldValue(YEAR, (em / 12) + 1970);
+            }
+        } else {
+            // TODO: revisit EPOCH_MONTH calculation in non-ISO chronology
+            // Handle EPOCH_MONTH here for non-ISO Chronology
+            if (standardFields.containsKey(EPOCH_MONTH)) {
+                long em = standardFields.remove(EPOCH_MONTH);
+                ChronoLocalDate<?> chronoDate = chrono.date(LocalDate.ofEpochDay(0L));
+                chronoDate = chronoDate.plus(em, ChronoUnit.MONTHS);
+                LocalDate date = LocalDate.ofEpochDay(chronoDate.toEpochDay());
+                checkDate(date);
+                return;
+            }
+            List<Era> eras = chrono.eras();
+            if (!eras.isEmpty()) {
+                if (standardFields.containsKey(ERA)) {
+                    long index = standardFields.remove(ERA);
+                    era = chrono.eraOf((int) index);
+                } else {
+                    era = eras.get(eras.size() - 1); // current Era
+                }
+                if (standardFields.containsKey(YEAR_OF_ERA)) {
+                    Long y = standardFields.remove(YEAR_OF_ERA);
+                    putFieldValue0(YEAR, y);
+                }
+            }
+
         }
 
         // build date
@@ -455,7 +296,19 @@
                     int y = Math.toIntExact(standardFields.remove(YEAR));
                     int moy = Math.toIntExact(standardFields.remove(MONTH_OF_YEAR));
                     int dom = Math.toIntExact(standardFields.remove(DAY_OF_MONTH));
-                    checkDate(LocalDate.of(y, moy, dom));
+                    LocalDate date;
+                    if (chrono == IsoChronology.INSTANCE) {
+                        date = LocalDate.of(y, moy, dom);
+                    } else {
+                        ChronoLocalDate<?> chronoDate;
+                        if (era == null) {
+                            chronoDate = chrono.date(y, moy, dom);
+                        } else {
+                            chronoDate = era.date(y, moy, dom);
+                        }
+                        date = LocalDate.ofEpochDay(chronoDate.toEpochDay());
+                    }
+                    checkDate(date);
                     return;
                 }
                 if (standardFields.containsKey(ALIGNED_WEEK_OF_MONTH)) {
@@ -464,7 +317,20 @@
                         int moy = Math.toIntExact(standardFields.remove(MONTH_OF_YEAR));
                         int aw = Math.toIntExact(standardFields.remove(ALIGNED_WEEK_OF_MONTH));
                         int ad = Math.toIntExact(standardFields.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH));
-                        checkDate(LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1)));
+                        LocalDate date;
+                        if (chrono == IsoChronology.INSTANCE) {
+                            date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1));
+                        } else {
+                            ChronoLocalDate<?> chronoDate;
+                            if (era == null) {
+                                chronoDate = chrono.date(y, moy, 1);
+                            } else {
+                                chronoDate = era.date(y, moy, 1);
+                            }
+                            chronoDate = chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS);
+                            date = LocalDate.ofEpochDay(chronoDate.toEpochDay());
+                        }
+                        checkDate(date);
                         return;
                     }
                     if (standardFields.containsKey(DAY_OF_WEEK)) {
@@ -472,7 +338,20 @@
                         int moy = Math.toIntExact(standardFields.remove(MONTH_OF_YEAR));
                         int aw = Math.toIntExact(standardFields.remove(ALIGNED_WEEK_OF_MONTH));
                         int dow = Math.toIntExact(standardFields.remove(DAY_OF_WEEK));
-                        checkDate(LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))));
+                        LocalDate date;
+                        if (chrono == IsoChronology.INSTANCE) {
+                            date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow)));
+                        } else {
+                            ChronoLocalDate<?> chronoDate;
+                            if (era == null) {
+                                chronoDate = chrono.date(y, moy, 1);
+                            } else {
+                                chronoDate = era.date(y, moy, 1);
+                            }
+                            chronoDate = chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow)));
+                            date = LocalDate.ofEpochDay(chronoDate.toEpochDay());
+                        }
+                        checkDate(date);
                         return;
                     }
                 }
@@ -480,7 +359,19 @@
             if (standardFields.containsKey(DAY_OF_YEAR)) {
                 int y = Math.toIntExact(standardFields.remove(YEAR));
                 int doy = Math.toIntExact(standardFields.remove(DAY_OF_YEAR));
-                checkDate(LocalDate.ofYearDay(y, doy));
+                LocalDate date;
+                if (chrono == IsoChronology.INSTANCE) {
+                    date = LocalDate.ofYearDay(y, doy);
+                } else {
+                    ChronoLocalDate<?> chronoDate;
+                    if (era == null) {
+                        chronoDate = chrono.dateYearDay(y, doy);
+                    } else {
+                        chronoDate = era.dateYearDay(y, doy);
+                    }
+                    date = LocalDate.ofEpochDay(chronoDate.toEpochDay());
+                }
+                checkDate(date);
                 return;
             }
             if (standardFields.containsKey(ALIGNED_WEEK_OF_YEAR)) {
@@ -488,14 +379,40 @@
                     int y = Math.toIntExact(standardFields.remove(YEAR));
                     int aw = Math.toIntExact(standardFields.remove(ALIGNED_WEEK_OF_YEAR));
                     int ad = Math.toIntExact(standardFields.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR));
-                    checkDate(LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)));
+                    LocalDate date;
+                    if (chrono == IsoChronology.INSTANCE) {
+                        date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1));
+                    } else {
+                        ChronoLocalDate<?> chronoDate;
+                        if (era == null) {
+                            chronoDate = chrono.dateYearDay(y, 1);
+                        } else {
+                            chronoDate = era.dateYearDay(y, 1);
+                        }
+                        chronoDate = chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS);
+                        date = LocalDate.ofEpochDay(chronoDate.toEpochDay());
+                    }
+                    checkDate(date);
                     return;
                 }
                 if (standardFields.containsKey(DAY_OF_WEEK)) {
                     int y = Math.toIntExact(standardFields.remove(YEAR));
                     int aw = Math.toIntExact(standardFields.remove(ALIGNED_WEEK_OF_YEAR));
                     int dow = Math.toIntExact(standardFields.remove(DAY_OF_WEEK));
-                    checkDate(LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))));
+                    LocalDate date;
+                    if (chrono == IsoChronology.INSTANCE) {
+                        date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow)));
+                    } else {
+                        ChronoLocalDate<?> chronoDate;
+                        if (era == null) {
+                            chronoDate = chrono.dateYearDay(y, 1);
+                        } else {
+                            chronoDate = era.dateYearDay(y, 1);
+                        }
+                        chronoDate = chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow)));
+                        date = LocalDate.ofEpochDay(chronoDate.toEpochDay());
+                    }
+                    checkDate(date);
                     return;
                 }
             }
@@ -503,9 +420,7 @@
     }
 
     private void checkDate(LocalDate date) {
-        // TODO: this doesn't handle aligned weeks over into next month which would otherwise be valid
-
-        addCalendrical(date);
+        addObject(date);
         for (ChronoField field : standardFields.keySet()) {
             long val1;
             try {
@@ -594,96 +509,66 @@
                     int somVal = Math.toIntExact(som);
                     if (nos != null) {
                         int nosVal = Math.toIntExact(nos);
-                        addCalendrical(LocalTime.of(hodVal, mohVal, somVal, nosVal));
+                        addObject(LocalTime.of(hodVal, mohVal, somVal, nosVal));
                     } else {
-                        addCalendrical(LocalTime.of(hodVal, mohVal, somVal));
+                        addObject(LocalTime.of(hodVal, mohVal, somVal));
                     }
                 } else {
-                    addCalendrical(LocalTime.of(hodVal, mohVal));
+                    addObject(LocalTime.of(hodVal, mohVal));
                 }
             } else {
-                addCalendrical(LocalTime.of(hodVal, 0));
-            }
-        }
-    }
-
-    private void splitObjects() {
-        List<Object> objectsToAdd = new ArrayList<>();
-        for (Object object : objects) {
-            if (object instanceof LocalDate || object instanceof LocalTime ||
-                            object instanceof ZoneId || object instanceof Chrono) {
-                continue;
-            }
-            if (object instanceof ZoneOffset || object instanceof Instant) {
-                objectsToAdd.add(object);
-
-            } else if (object instanceof TemporalAccessor) {
-                // TODO
-//                TemporalAccessor dt = (TemporalAccessor) object;
-//                objectsToAdd.add(dt.extract(LocalDate.class));
-//                objectsToAdd.add(dt.extract(LocalTime.class));
-//                objectsToAdd.add(dt.extract(ZoneId.class));
-//                objectsToAdd.add(dt.extract(Chrono.class));
-            }
-        }
-        for (Object object : objectsToAdd) {
-            if (object != null) {
-                addCalendrical(object);
+                addObject(LocalTime.of(hodVal, 0));
             }
         }
     }
 
     //-----------------------------------------------------------------------
     @Override
-    public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.zoneId()) {
-            return (R) extract(ZoneId.class);
+    public boolean isSupported(TemporalField field) {
+        if (field == null) {
+            return false;
         }
-        if (query == Queries.offset()) {
-            ZoneOffset offset = extract(ZoneOffset.class);
-            if (offset == null && standardFields.containsKey(OFFSET_SECONDS)) {
-                offset = ZoneOffset.ofTotalSeconds(Math.toIntExact(standardFields.get(OFFSET_SECONDS)));
+        return standardFields.containsKey(field) ||
+                (otherFields != null && otherFields.containsKey(field)) ||
+                (date != null && date.isSupported(field)) ||
+                (time != null && time.isSupported(field));
+    }
+
+    @Override
+    public long getLong(TemporalField field) {
+        Objects.requireNonNull(field, "field");
+        Long value = getFieldValue0(field);
+        if (value == null) {
+            if (date != null && date.isSupported(field)) {
+                return date.getLong(field);
             }
-            return (R) offset;
+            if (time != null && time.isSupported(field)) {
+                return time.getLong(field);
+            }
+            throw new DateTimeException("Field not found: " + field);
         }
-        if (query == Queries.chrono()) {
-            return extract(Chrono.class);
-        }
-        // incomplete, so no need to handle PRECISION
-        return TemporalAccessor.super.query(query);
+        return value;
     }
 
     @SuppressWarnings("unchecked")
-    public <R> R extract(Class<?> type) {
-        R result = null;
-        for (Object obj : objects) {
-            if (type.isInstance(obj)) {
-                if (result != null && result.equals(obj) == false) {
-                    throw new DateTimeException("Conflict found: " + type.getSimpleName() + " differs " + result + " vs " + obj + ": " + this);
-                }
-                result = (R) obj;
-            }
-        }
-        return result;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Clones this builder, creating a new independent copy referring to the
-     * same map of fields and objects.
-     *
-     * @return the cloned builder, not null
-     */
     @Override
-    public DateTimeBuilder clone() {
-        DateTimeBuilder dtb = new DateTimeBuilder();
-        dtb.objects.addAll(this.objects);
-        dtb.standardFields.putAll(this.standardFields);
-        dtb.standardFields.putAll(this.standardFields);
-        if (this.otherFields != null) {
-            dtb.otherFields.putAll(this.otherFields);
+    public <R> R query(TemporalQuery<R> query) {
+        if (query == Queries.zoneId()) {
+            return (R) zone;
+        } else if (query == Queries.chronology()) {
+            return (R) chrono;
+        } else if (query == Queries.localDate()) {
+            return (R) date;
+        } else if (query == Queries.localTime()) {
+            return (R) time;
+        } else if (query == Queries.zone() || query == Queries.offset()) {
+            return query.queryFrom(this);
+        } else if (query == Queries.precision()) {
+            return null;  // not a complete date/time
         }
-        return dtb;
+        // inline TemporalAccessor.super.query(query) as an optimization
+        // non-JDK classes are not permitted to make this optimization
+        return query.queryFrom(this);
     }
 
     //-----------------------------------------------------------------------
@@ -691,29 +576,20 @@
     public String toString() {
         StringBuilder buf = new StringBuilder(128);
         buf.append("DateTimeBuilder[");
-        Map<TemporalField, Long> fields = getFieldValueMap();
+        Map<TemporalField, Long> fields = new HashMap<>();
+        fields.putAll(standardFields);
+        if (otherFields != null) {
+            fields.putAll(otherFields);
+        }
         if (fields.size() > 0) {
             buf.append("fields=").append(fields);
         }
-        if (objects.size() > 0) {
-            if (fields.size() > 0) {
-                buf.append(", ");
-            }
-            buf.append("objects=").append(objects);
-        }
+        buf.append(", ").append(chrono);
+        buf.append(", ").append(zone);
+        buf.append(", ").append(date);
+        buf.append(", ").append(time);
         buf.append(']');
         return buf.toString();
     }
 
-    //-----------------------------------------------------------------------
-    @Override
-    public boolean isSupported(TemporalField field) {
-        return field != null && containsFieldValue(field);
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        return getFieldValue(field);
-    }
-
 }
diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatStyleProvider.java b/jdk/src/share/classes/java/time/format/DateTimeFormatStyleProvider.java
index e50ce26..eba19f8 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatStyleProvider.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeFormatStyleProvider.java
@@ -61,12 +61,13 @@
  */
 package java.time.format;
 
-import java.text.DateFormat;
 import java.text.SimpleDateFormat;
-import java.time.temporal.Chrono;
+import java.time.chrono.Chronology;
 import java.util.Locale;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.LocaleResources;
 
 /**
  * A provider to obtain date-time formatters for a style.
@@ -110,44 +111,36 @@
      * @throws IllegalArgumentException if both format styles are null or if the locale is not recognized
      */
     public DateTimeFormatter getFormatter(
-            FormatStyle dateStyle, FormatStyle timeStyle, Chrono<?> chrono, Locale locale) {
+            FormatStyle dateStyle, FormatStyle timeStyle, Chronology chrono, Locale locale) {
         if (dateStyle == null && timeStyle == null) {
             throw new IllegalArgumentException("Date and Time style must not both be null");
         }
         String key = chrono.getId() + '|' + locale.toString() + '|' + dateStyle + timeStyle;
         Object cached = FORMATTER_CACHE.get(key);
         if (cached != null) {
-            if (cached.equals("")) {
-                throw new IllegalArgumentException("Unable to convert DateFormat to DateTimeFormatter");
-            }
             return (DateTimeFormatter) cached;
         }
-        DateFormat dateFormat;
-        if (dateStyle != null) {
-            if (timeStyle != null) {
-                dateFormat = DateFormat.getDateTimeInstance(convertStyle(dateStyle), convertStyle(timeStyle), locale);
-            } else {
-                dateFormat = DateFormat.getDateInstance(convertStyle(dateStyle), locale);
-            }
-        } else {
-            dateFormat = DateFormat.getTimeInstance(convertStyle(timeStyle), locale);
-        }
-        if (dateFormat instanceof SimpleDateFormat) {
-            String pattern = ((SimpleDateFormat) dateFormat).toPattern();
-            DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);
-            FORMATTER_CACHE.putIfAbsent(key, formatter);
-            return formatter;
-        }
-        FORMATTER_CACHE.putIfAbsent(key, "");
-        throw new IllegalArgumentException("Unable to convert DateFormat to DateTimeFormatter");
+
+        LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
+                                    .getLocaleResources(locale);
+        String pattern = lr.getCldrDateTimePattern(convertStyle(timeStyle), convertStyle(dateStyle),
+                                                   chrono.getCalendarType());
+        DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);
+        FORMATTER_CACHE.putIfAbsent(key, formatter);
+        return formatter;
     }
 
     /**
-     * Converts the enum style to the old format style.
-     * @param style  the enum style, not null
-     * @return the int style
+     * Converts the enum style to the java.util.Calendar style. Standalone styles
+     * are not supported.
+     *
+     * @param style  the enum style
+     * @return the int style, or -1 if style is null, indicating unrequired
      */
     private int convertStyle(FormatStyle style) {
+        if (style == null) {
+            return -1;
+        }
         return style.ordinal();  // indices happen to align
     }
 
diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatter.java b/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
index 1b9aa2c..58a1c92 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
@@ -61,6 +61,16 @@
  */
 package java.time.format;
 
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.DAY_OF_YEAR;
+import static java.time.temporal.ChronoField.HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.NANO_OF_SECOND;
+import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
+import static java.time.temporal.ChronoField.YEAR;
+
 import java.io.IOException;
 import java.text.FieldPosition;
 import java.text.Format;
@@ -68,21 +78,32 @@
 import java.text.ParsePosition;
 import java.time.DateTimeException;
 import java.time.ZoneId;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatterBuilder.CompositePrinterParser;
-import java.time.temporal.Chrono;
+import java.time.chrono.Chronology;
+import java.time.temporal.ChronoField;
+import java.time.temporal.IsoFields;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalQuery;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Objects;
 
 /**
  * Formatter for printing and parsing date-time objects.
  * <p>
- * This class provides the main application entry point for printing and parsing.
- * Common instances of {@code DateTimeFormatter} are provided by {@link DateTimeFormatters}.
- * For more complex formatters, a {@link DateTimeFormatterBuilder builder} is provided.
+ * This class provides the main application entry point for printing and parsing
+ * and provides common implementations of {@code DateTimeFormatter}:
+ * <p><ul>
+ * <li>Using pattern letters, such as {@code yyyy-MMM-dd}
+ * <li>Using localized styles, such as {@code long} or {@code medium}
+ * <li>Using predefined constants, such as {@code ISO_LOCAL_DATE}
+ * </ul></p>
+ *
  * <p>
- * In most cases, it is not necessary to use this class directly when formatting.
+ * In most cases, provided formatters will be sufficient.
+ * For more complex formatters, a {@link DateTimeFormatterBuilder builder} is provided.
  * The main date-time classes provide two methods - one for printing,
  * {@code toString(DateTimeFormatter formatter)}, and one for parsing,
  * {@code parse(CharSequence text, DateTimeFormatter formatter)}.
@@ -91,7 +112,7 @@
  *  String text = date.toString(formatter);
  *  LocalDate date = LocalDate.parse(text, formatter);
  * </pre>
- * Some aspects of printing and parsing are dependent on the locale.
+ * Some aspects of formatting and parsing are dependent on the locale.
  * The locale can be changed using the {@link #withLocale(Locale)} method
  * which returns a new formatter in the requested locale.
  * <p>
@@ -120,12 +141,781 @@
     /**
      * The chronology to use for formatting, null for no override.
      */
-    private final Chrono<?> chrono;
+    private final Chronology chrono;
     /**
      * The zone to use for formatting, null for no override.
      */
     private final ZoneId zone;
 
+    //-----------------------------------------------------------------------
+    /**
+     * Creates a formatter using the specified pattern.
+     * <p>
+     * This method will create a formatter based on a simple pattern of letters and symbols.
+     * For example, {@code d MMM yyyy} will format 2011-12-03 as '3 Dec 2011'.
+     * <p>
+     * The returned formatter will use the default locale, but this can be changed
+     * using {@link DateTimeFormatter#withLocale(Locale)}.
+     * <p>
+     * All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters.
+     * The following pattern letters are defined:
+     * <pre>
+     *  Symbol  Meaning                     Presentation      Examples
+     *  ------  -------                     ------------      -------
+     *   G       era                         text              A; AD; Anno Domini
+     *   y       year                        year              2004; 04
+     *   D       day-of-year                 number            189
+     *   M       month-of-year               number/text       7; 07; Jul; July; J
+     *   d       day-of-month                number            10
+     *
+     *   Q       quarter-of-year             number/text       3; 03; Q3
+     *   Y       week-based-year             year              1996; 96
+     *   w       week-of-year                number            27
+     *   W       week-of-month               number            27
+     *   e       localized day-of-week       number            2; Tue; Tuesday; T
+     *   E       day-of-week                 number/text       2; Tue; Tuesday; T
+     *   F       week-of-month               number            3
+     *
+     *   a       am-pm-of-day                text              PM
+     *   h       clock-hour-of-am-pm (1-12)  number            12
+     *   K       hour-of-am-pm (0-11)        number            0
+     *   k       clock-hour-of-am-pm (1-24)  number            0
+     *
+     *   H       hour-of-day (0-23)          number            0
+     *   m       minute-of-hour              number            30
+     *   s       second-of-minute            number            55
+     *   S       fraction-of-second          fraction          978
+     *   A       milli-of-day                number            1234
+     *   n       nano-of-second              number            987654321
+     *   N       nano-of-day                 number            1234000000
+     *
+     *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
+     *   z       time-zone name              zone-name         Pacific Standard Time; PST
+     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
+     *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
+     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
+     *
+     *   p       pad next                    pad modifier      1
+     *
+     *   '       escape for text             delimiter
+     *   ''      single quote                literal           '
+     *   [       optional section start
+     *   ]       optional section end
+     *   {}      reserved for future use
+     * </pre>
+     * <p>
+     * The count of pattern letters determine the format.
+     * <p>
+     * <b>Text</b>: The text style is determined based on the number of pattern letters used.
+     * Less than 4 pattern letters will use the {@link TextStyle#SHORT short form}.
+     * Exactly 4 pattern letters will use the {@link TextStyle#FULL full form}.
+     * Exactly 5 pattern letters will use the {@link TextStyle#NARROW narrow form}.
+     * <p>
+     * <b>Number</b>: If the count of letters is one, then the value is output using the minimum number
+     * of digits and without padding as per {@link DateTimeFormatterBuilder#appendValue(java.time.temporal.TemporalField)}.
+     * Otherwise, the count of digits is used as the width of the output field as per
+     * {@link DateTimeFormatterBuilder#appendValue(java.time.temporal.TemporalField, int)}.
+     * <p>
+     * <b>Number/Text</b>: If the count of pattern letters is 3 or greater, use the Text rules above.
+     * Otherwise use the Number rules above.
+     * <p>
+     * <b>Fraction</b>: Outputs the nano-of-second field as a fraction-of-second.
+     * The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9.
+     * If it is less than 9, then the nano-of-second value is truncated, with only the most
+     * significant digits being output.
+     * When parsing in strict mode, the number of parsed digits must match the count of pattern letters.
+     * When parsing in lenient mode, the number of parsed digits must be at least the count of pattern
+     * letters, up to 9 digits.
+     * <p>
+     * <b>Year</b>: The count of letters determines the minimum field width below which padding is used.
+     * If the count of letters is two, then a {@link DateTimeFormatterBuilder#appendValueReduced reduced}
+     * two digit form is used.
+     * For printing, this outputs the rightmost two digits. For parsing, this will parse using the
+     * base value of 2000, resulting in a year within the range 2000 to 2099 inclusive.
+     * If the count of letters is less than four (but not two), then the sign is only output for negative
+     * years as per {@link SignStyle#NORMAL}.
+     * Otherwise, the sign is output if the pad width is exceeded, as per {@link SignStyle#EXCEEDS_PAD}
+     * <p>
+     * <b>ZoneId</b>: This outputs the time-zone ID, such as 'Europe/Paris'.
+     * If the count of letters is two, then the time-zone ID is output.
+     * Any other count of letters throws {@code IllegalArgumentException}.
+     * <p>
+     * <b>Zone names</b>: This outputs the display name of the time-zone ID.
+     * If the count of letters is one, two or three, then the short name is output.
+     * If the count of letters is four, then the full name is output.
+     * Five or more letters throws {@code IllegalArgumentException}.
+     * <p>
+     * <b>Offset X and x</b>: This formats the offset based on the number of pattern letters.
+     * One letter outputs just the hour', such as '+01', unless the minute is non-zero
+     * in which case the minute is also output, such as '+0130'.
+     * Two letters outputs the hour and minute, without a colon, such as '+0130'.
+     * Three letters outputs the hour and minute, with a colon, such as '+01:30'.
+     * Four letters outputs the hour and minute and optional second, without a colon, such as '+013015'.
+     * Five letters outputs the hour and minute and optional second, with a colon, such as '+01:30:15'.
+     * Six or more letters throws {@code IllegalArgumentException}.
+     * Pattern letter 'X' (upper case) will output 'Z' when the offset to be output would be zero,
+     * whereas pattern letter 'x' (lower case) will output '+00', '+0000', or '+00:00'.
+     * <p>
+     * <b>Offset Z</b>: This formats the offset based on the number of pattern letters.
+     * One, two or three letters outputs the hour and minute, without a colon, such as '+0130'.
+     * Four or more letters throws {@code IllegalArgumentException}.
+     * The output will be '+0000' when the offset is zero.
+     * <p>
+     * <b>Optional section</b>: The optional section markers work exactly like calling
+     * {@link DateTimeFormatterBuilder#optionalStart()} and {@link DateTimeFormatterBuilder#optionalEnd()}.
+     * <p>
+     * <b>Pad modifier</b>: Modifies the pattern that immediately follows to be padded with spaces.
+     * The pad width is determined by the number of pattern letters.
+     * This is the same as calling {@link DateTimeFormatterBuilder#padNext(int)}.
+     * <p>
+     * For example, 'ppH' outputs the hour-of-day padded on the left with spaces to a width of 2.
+     * <p>
+     * Any unrecognized letter is an error.
+     * Any non-letter character, other than '[', ']', '{', '}' and the single quote will be output directly.
+     * Despite this, it is recommended to use single quotes around all characters that you want to
+     * output directly to ensure that future changes do not break your application.
+     *
+     * @param pattern  the pattern to use, not null
+     * @return the formatter based on the pattern, not null
+     * @throws IllegalArgumentException if the pattern is invalid
+     * @see DateTimeFormatterBuilder#appendPattern(String)
+     */
+    public static DateTimeFormatter ofPattern(String pattern) {
+        return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
+    }
+
+    /**
+     * Creates a formatter using the specified pattern.
+     * <p>
+     * This method will create a formatter based on a simple pattern of letters and symbols.
+     * For example, {@code d MMM yyyy} will format 2011-12-03 as '3 Dec 2011'.
+     * <p>
+     * See {@link #ofPattern(String)} for details of the pattern.
+     * <p>
+     * The returned formatter will use the specified locale, but this can be changed
+     * using {@link DateTimeFormatter#withLocale(Locale)}.
+     *
+     * @param pattern  the pattern to use, not null
+     * @param locale  the locale to use, not null
+     * @return the formatter based on the pattern, not null
+     * @throws IllegalArgumentException if the pattern is invalid
+     * @see DateTimeFormatterBuilder#appendPattern(String)
+     */
+    public static DateTimeFormatter ofPattern(String pattern, Locale locale) {
+        return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a locale specific date format.
+     * <p>
+     * This returns a formatter that will format or parse a date.
+     * The exact format pattern used varies by locale.
+     * <p>
+     * The locale is determined from the formatter. The formatter returned directly by
+     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
+     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
+     * on the result of this method.
+     * <p>
+     * Note that the localized pattern is looked up lazily.
+     * This {@code DateTimeFormatter} holds the style required and the locale,
+     * looking up the pattern required on demand.
+     *
+     * @param dateStyle  the formatter style to obtain, not null
+     * @return the date formatter, not null
+     */
+    public static DateTimeFormatter ofLocalizedDate(FormatStyle dateStyle) {
+        Objects.requireNonNull(dateStyle, "dateStyle");
+        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, null).toFormatter();
+    }
+
+    /**
+     * Returns a locale specific time format.
+     * <p>
+     * This returns a formatter that will format or parse a time.
+     * The exact format pattern used varies by locale.
+     * <p>
+     * The locale is determined from the formatter. The formatter returned directly by
+     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
+     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
+     * on the result of this method.
+     * <p>
+     * Note that the localized pattern is looked up lazily.
+     * This {@code DateTimeFormatter} holds the style required and the locale,
+     * looking up the pattern required on demand.
+     *
+     * @param timeStyle  the formatter style to obtain, not null
+     * @return the time formatter, not null
+     */
+    public static DateTimeFormatter ofLocalizedTime(FormatStyle timeStyle) {
+        Objects.requireNonNull(timeStyle, "timeStyle");
+        return new DateTimeFormatterBuilder().appendLocalized(null, timeStyle).toFormatter();
+    }
+
+    /**
+     * Returns a locale specific date-time formatter, which is typically of short length.
+     * <p>
+     * This returns a formatter that will format or parse a date-time.
+     * The exact format pattern used varies by locale.
+     * <p>
+     * The locale is determined from the formatter. The formatter returned directly by
+     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
+     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
+     * on the result of this method.
+     * <p>
+     * Note that the localized pattern is looked up lazily.
+     * This {@code DateTimeFormatter} holds the style required and the locale,
+     * looking up the pattern required on demand.
+     *
+     * @param dateTimeStyle  the formatter style to obtain, not null
+     * @return the date-time formatter, not null
+     */
+    public static DateTimeFormatter ofLocalizedDateTime(FormatStyle dateTimeStyle) {
+        Objects.requireNonNull(dateTimeStyle, "dateTimeStyle");
+        return new DateTimeFormatterBuilder().appendLocalized(dateTimeStyle, dateTimeStyle).toFormatter();
+    }
+
+    /**
+     * Returns a locale specific date and time format.
+     * <p>
+     * This returns a formatter that will format or parse a date-time.
+     * The exact format pattern used varies by locale.
+     * <p>
+     * The locale is determined from the formatter. The formatter returned directly by
+     * this method will use the {@link Locale#getDefault() default FORMAT locale}.
+     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
+     * on the result of this method.
+     * <p>
+     * Note that the localized pattern is looked up lazily.
+     * This {@code DateTimeFormatter} holds the style required and the locale,
+     * looking up the pattern required on demand.
+     *
+     * @param dateStyle  the date formatter style to obtain, not null
+     * @param timeStyle  the time formatter style to obtain, not null
+     * @return the date, time or date-time formatter, not null
+     */
+    public static DateTimeFormatter ofLocalizedDateTime(FormatStyle dateStyle, FormatStyle timeStyle) {
+        Objects.requireNonNull(dateStyle, "dateStyle");
+        Objects.requireNonNull(timeStyle, "timeStyle");
+        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, timeStyle).toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses a date without an offset,
+     * such as '2011-12-03'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended local date format.
+     * The format consists of:
+     * <p><ul>
+     * <li>Four digits or more for the {@link ChronoField#YEAR year}.
+     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
+     * Years outside that range will have a prefixed positive or negative symbol.
+     * <li>A dash
+     * <li>Two digits for the {@link ChronoField#MONTH_OF_YEAR month-of-year}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>A dash
+     * <li>Two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
+     *  This is pre-padded by zero to ensure two digits.
+     * </ul></p>
+     */
+    public static final DateTimeFormatter ISO_LOCAL_DATE;
+    static {
+        ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
+            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
+            .appendLiteral('-')
+            .appendValue(MONTH_OF_YEAR, 2)
+            .appendLiteral('-')
+            .appendValue(DAY_OF_MONTH, 2)
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses a date with an offset,
+     * such as '2011-12-03+01:00'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended offset date format.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_LOCAL_DATE}
+     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
+     *  they will be handled even though this is not part of the ISO-8601 standard.
+     *  Parsing is case insensitive.
+     * </ul></p>
+     */
+    public static final DateTimeFormatter ISO_OFFSET_DATE;
+    static {
+        ISO_OFFSET_DATE = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .append(ISO_LOCAL_DATE)
+            .appendOffsetId()
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses a date with the
+     * offset if available, such as '2011-12-03' or '2011-12-03+01:00'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended date format.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_LOCAL_DATE}
+     * <li>If the offset is not available then the format is complete.
+     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
+     *  they will be handled even though this is not part of the ISO-8601 standard.
+     *  Parsing is case insensitive.
+     * </ul></p>
+     * <p>
+     * As this formatter has an optional element, it may be necessary to parse using
+     * {@link DateTimeFormatter#parseBest}.
+     */
+    public static final DateTimeFormatter ISO_DATE;
+    static {
+        ISO_DATE = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .append(ISO_LOCAL_DATE)
+            .optionalStart()
+            .appendOffsetId()
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO time formatter that formats or parses a time without an offset,
+     * such as '10:15' or '10:15:30'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended local time format.
+     * The format consists of:
+     * <p><ul>
+     * <li>Two digits for the {@link ChronoField#HOUR_OF_DAY hour-of-day}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>A colon
+     * <li>Two digits for the {@link ChronoField#MINUTE_OF_HOUR minute-of-hour}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>If the second-of-minute is not available then the format is complete.
+     * <li>A colon
+     * <li>Two digits for the {@link ChronoField#SECOND_OF_MINUTE second-of-minute}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>If the nano-of-second is zero or not available then the format is complete.
+     * <li>A decimal point
+     * <li>One to nine digits for the {@link ChronoField#NANO_OF_SECOND nano-of-second}.
+     *  As many digits will be output as required.
+     * </ul></p>
+     */
+    public static final DateTimeFormatter ISO_LOCAL_TIME;
+    static {
+        ISO_LOCAL_TIME = new DateTimeFormatterBuilder()
+            .appendValue(HOUR_OF_DAY, 2)
+            .appendLiteral(':')
+            .appendValue(MINUTE_OF_HOUR, 2)
+            .optionalStart()
+            .appendLiteral(':')
+            .appendValue(SECOND_OF_MINUTE, 2)
+            .optionalStart()
+            .appendFraction(NANO_OF_SECOND, 0, 9, true)
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO time formatter that formats or parses a time with an offset,
+     * such as '10:15+01:00' or '10:15:30+01:00'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended offset time format.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_LOCAL_TIME}
+     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
+     *  they will be handled even though this is not part of the ISO-8601 standard.
+     *  Parsing is case insensitive.
+     * </ul></p>
+     */
+    public static final DateTimeFormatter ISO_OFFSET_TIME;
+    static {
+        ISO_OFFSET_TIME = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .append(ISO_LOCAL_TIME)
+            .appendOffsetId()
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO time formatter that formats or parses a time, with the
+     * offset if available, such as '10:15', '10:15:30' or '10:15:30+01:00'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended offset time format.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_LOCAL_TIME}
+     * <li>If the offset is not available then the format is complete.
+     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
+     *  they will be handled even though this is not part of the ISO-8601 standard.
+     *  Parsing is case insensitive.
+     * </ul></p>
+     * <p>
+     * As this formatter has an optional element, it may be necessary to parse using
+     * {@link DateTimeFormatter#parseBest}.
+     */
+    public static final DateTimeFormatter ISO_TIME;
+    static {
+        ISO_TIME = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .append(ISO_LOCAL_TIME)
+            .optionalStart()
+            .appendOffsetId()
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses a date-time
+     * without an offset, such as '2011-12-03T10:15:30'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended offset date-time format.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_LOCAL_DATE}
+     * <li>The letter 'T'. Parsing is case insensitive.
+     * <li>The {@link #ISO_LOCAL_TIME}
+     * </ul></p>
+     */
+    public static final DateTimeFormatter ISO_LOCAL_DATE_TIME;
+    static {
+        ISO_LOCAL_DATE_TIME = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .append(ISO_LOCAL_DATE)
+            .appendLiteral('T')
+            .append(ISO_LOCAL_TIME)
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses a date-time
+     * with an offset, such as '2011-12-03T10:15:30+01:00'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended offset date-time format.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_LOCAL_DATE_TIME}
+     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
+     *  they will be handled even though this is not part of the ISO-8601 standard.
+     *  Parsing is case insensitive.
+     * </ul></p>
+     */
+    public static final DateTimeFormatter ISO_OFFSET_DATE_TIME;
+    static {
+        ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .append(ISO_LOCAL_DATE_TIME)
+            .appendOffsetId()
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses a date-time with
+     * offset and zone, such as '2011-12-03T10:15:30+01:00[Europe/Paris]'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * a format that extends the ISO-8601 extended offset date-time format
+     * to add the time-zone.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_OFFSET_DATE_TIME}
+     * <li>If the zone ID is not available or is a {@code ZoneOffset} then the format is complete.
+     * <li>An open square bracket '['.
+     * <li>The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard.
+     *  Parsing is case sensitive.
+     * <li>A close square bracket ']'.
+     * </ul></p>
+     */
+    public static final DateTimeFormatter ISO_ZONED_DATE_TIME;
+    static {
+        ISO_ZONED_DATE_TIME = new DateTimeFormatterBuilder()
+            .append(ISO_OFFSET_DATE_TIME)
+            .optionalStart()
+            .appendLiteral('[')
+            .parseCaseSensitive()
+            .appendZoneRegionId()
+            .appendLiteral(']')
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses a date-time
+     * with the offset and zone if available, such as '2011-12-03T10:15:30',
+     * '2011-12-03T10:15:30+01:00' or '2011-12-03T10:15:30+01:00[Europe/Paris]'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended offset date-time format.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_LOCAL_DATE_TIME}
+     * <li>If the offset is not available to format or parse then the format is complete.
+     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
+     *  they will be handled even though this is not part of the ISO-8601 standard.
+     * <li>If the zone ID is not available or is a {@code ZoneOffset} then the format is complete.
+     * <li>An open square bracket '['.
+     * <li>The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard.
+     *  Parsing is case sensitive.
+     * <li>A close square bracket ']'.
+     * </ul></p>
+     * <p>
+     * As this formatter has an optional element, it may be necessary to parse using
+     * {@link DateTimeFormatter#parseBest}.
+     */
+    public static final DateTimeFormatter ISO_DATE_TIME;
+    static {
+        ISO_DATE_TIME = new DateTimeFormatterBuilder()
+            .append(ISO_LOCAL_DATE_TIME)
+            .optionalStart()
+            .appendOffsetId()
+            .optionalStart()
+            .appendLiteral('[')
+            .parseCaseSensitive()
+            .appendZoneRegionId()
+            .appendLiteral(']')
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses the ordinal date
+     * without an offset, such as '2012-337'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended ordinal date format.
+     * The format consists of:
+     * <p><ul>
+     * <li>Four digits or more for the {@link ChronoField#YEAR year}.
+     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
+     * Years outside that range will have a prefixed positive or negative symbol.
+     * <li>A dash
+     * <li>Three digits for the {@link ChronoField#DAY_OF_YEAR day-of-year}.
+     *  This is pre-padded by zero to ensure three digits.
+     * <li>If the offset is not available to format or parse then the format is complete.
+     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
+     *  they will be handled even though this is not part of the ISO-8601 standard.
+     *  Parsing is case insensitive.
+     * </ul></p>
+     * <p>
+     * As this formatter has an optional element, it may be necessary to parse using
+     * {@link DateTimeFormatter#parseBest}.
+     */
+    public static final DateTimeFormatter ISO_ORDINAL_DATE;
+    static {
+        ISO_ORDINAL_DATE = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
+            .appendLiteral('-')
+            .appendValue(DAY_OF_YEAR, 3)
+            .optionalStart()
+            .appendOffsetId()
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses the week-based date
+     * without an offset, such as '2012-W48-6'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 extended week-based date format.
+     * The format consists of:
+     * <p><ul>
+     * <li>Four digits or more for the {@link IsoFields#WEEK_BASED_YEAR week-based-year}.
+     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
+     * Years outside that range will have a prefixed positive or negative symbol.
+     * <li>A dash
+     * <li>The letter 'W'. Parsing is case insensitive.
+     * <li>Two digits for the {@link IsoFields#WEEK_OF_WEEK_BASED_YEAR week-of-week-based-year}.
+     *  This is pre-padded by zero to ensure three digits.
+     * <li>A dash
+     * <li>One digit for the {@link ChronoField#DAY_OF_WEEK day-of-week}.
+     *  The value run from Monday (1) to Sunday (7).
+     * <li>If the offset is not available to format or parse then the format is complete.
+     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
+     *  they will be handled even though this is not part of the ISO-8601 standard.
+     *  Parsing is case insensitive.
+     * </ul></p>
+     * <p>
+     * As this formatter has an optional element, it may be necessary to parse using
+     * {@link DateTimeFormatter#parseBest}.
+     */
+    public static final DateTimeFormatter ISO_WEEK_DATE;
+    static {
+        ISO_WEEK_DATE = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .appendValue(IsoFields.WEEK_BASED_YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
+            .appendLiteral("-W")
+            .appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
+            .appendLiteral('-')
+            .appendValue(DAY_OF_WEEK, 1)
+            .optionalStart()
+            .appendOffsetId()
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO instant formatter that formats or parses an instant in UTC.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 instant format.
+     * The format consists of:
+     * <p><ul>
+     * <li>The {@link #ISO_OFFSET_DATE_TIME} where the instant is converted from
+     *  {@link ChronoField#INSTANT_SECONDS} and {@link ChronoField#NANO_OF_SECOND}
+     *  using the {@code UTC} offset. Parsing is case insensitive.
+     * </ul></p>
+     */
+    public static final DateTimeFormatter ISO_INSTANT;
+    static {
+        ISO_INSTANT = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .appendInstant()
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the ISO date formatter that formats or parses a date without an offset,
+     * such as '20111203'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * the ISO-8601 basic local date format.
+     * The format consists of:
+     * <p><ul>
+     * <li>Four digits for the {@link ChronoField#YEAR year}.
+     *  Only years in the range 0000 to 9999 are supported.
+     * <li>Two digits for the {@link ChronoField#MONTH_OF_YEAR month-of-year}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>Two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>If the offset is not available to format or parse then the format is complete.
+     * <li>The {@link ZoneOffset#getId() offset ID} without colons. If the offset has
+     *  seconds then they will be handled even though this is not part of the ISO-8601 standard.
+     *  Parsing is case insensitive.
+     * </ul></p>
+     * <p>
+     * As this formatter has an optional element, it may be necessary to parse using
+     * {@link DateTimeFormatter#parseBest}.
+     */
+    public static final DateTimeFormatter BASIC_ISO_DATE;
+    static {
+        BASIC_ISO_DATE = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .appendValue(YEAR, 4)
+            .appendValue(MONTH_OF_YEAR, 2)
+            .appendValue(DAY_OF_MONTH, 2)
+            .optionalStart()
+            .appendOffset("+HHMMss", "Z")
+            .toFormatter();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * The RFC-1123 date-time formatter, such as 'Tue, 3 Jun 2008 11:05:30 GMT'.
+     * <p>
+     * This returns an immutable formatter capable of formatting and parsing
+     * most of the RFC-1123 format.
+     * RFC-1123 updates RFC-822 changing the year from two digits to four.
+     * This implementation requires a four digit year.
+     * This implementation also does not handle North American or military zone
+     * names, only 'GMT' and offset amounts.
+     * <p>
+     * The format consists of:
+     * <p><ul>
+     * <li>If the day-of-week is not available to format or parse then jump to day-of-month.
+     * <li>Three letter {@link ChronoField#DAY_OF_WEEK day-of-week} in English.
+     * <li>A comma
+     * <li>A space
+     * <li>One or two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
+     * <li>A space
+     * <li>Three letter {@link ChronoField#MONTH_OF_YEAR month-of-year} in English.
+     * <li>A space
+     * <li>Four digits for the {@link ChronoField#YEAR year}.
+     *  Only years in the range 0000 to 9999 are supported.
+     * <li>A space
+     * <li>Two digits for the {@link ChronoField#HOUR_OF_DAY hour-of-day}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>A colon
+     * <li>Two digits for the {@link ChronoField#MINUTE_OF_HOUR minute-of-hour}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>If the second-of-minute is not available then jump to the next space.
+     * <li>A colon
+     * <li>Two digits for the {@link ChronoField#SECOND_OF_MINUTE second-of-minute}.
+     *  This is pre-padded by zero to ensure two digits.
+     * <li>A space
+     * <li>The {@link ZoneOffset#getId() offset ID} without colons or seconds.
+     *  An offset of zero uses "GMT". North American zone names and military zone names are not handled.
+     * </ul></p>
+     * <p>
+     * Parsing is case insensitive.
+     */
+    public static final DateTimeFormatter RFC_1123_DATE_TIME;
+    static {
+        // manually code maps to ensure correct data always used
+        // (locale data can be changed by application code)
+        Map<Long, String> dow = new HashMap<>();
+        dow.put(1L, "Mon");
+        dow.put(2L, "Tue");
+        dow.put(3L, "Wed");
+        dow.put(4L, "Thu");
+        dow.put(5L, "Fri");
+        dow.put(6L, "Sat");
+        dow.put(7L, "Sun");
+        Map<Long, String> moy = new HashMap<>();
+        moy.put(1L, "Jan");
+        moy.put(2L, "Feb");
+        moy.put(3L, "Mar");
+        moy.put(4L, "Apr");
+        moy.put(5L, "May");
+        moy.put(6L, "Jun");
+        moy.put(7L, "Jul");
+        moy.put(8L, "Aug");
+        moy.put(9L, "Sep");
+        moy.put(10L, "Oct");
+        moy.put(11L, "Nov");
+        moy.put(12L, "Dec");
+        RFC_1123_DATE_TIME = new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .parseLenient()
+            .optionalStart()
+            .appendText(DAY_OF_WEEK, dow)
+            .appendLiteral(", ")
+            .optionalEnd()
+            .appendValue(DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE)
+            .appendLiteral(' ')
+            .appendText(MONTH_OF_YEAR, moy)
+            .appendLiteral(' ')
+            .appendValue(YEAR, 4)  // 2 digit year not handled
+            .appendLiteral(' ')
+            .appendValue(HOUR_OF_DAY, 2)
+            .appendLiteral(':')
+            .appendValue(MINUTE_OF_HOUR, 2)
+            .optionalStart()
+            .appendLiteral(':')
+            .appendValue(SECOND_OF_MINUTE, 2)
+            .optionalEnd()
+            .appendLiteral(' ')
+            .appendOffset("+HHMM", "GMT")  // should handle UT/Z/EST/EDT/CST/CDT/MST/MDT/PST/MDT
+            .toFormatter();
+    }
+
     /**
      * Constructor.
      *
@@ -136,7 +926,7 @@
      * @param zone  the zone to use, null for no override
      */
     DateTimeFormatter(CompositePrinterParser printerParser, Locale locale,
-                      DateTimeFormatSymbols symbols, Chrono chrono, ZoneId zone) {
+                      DateTimeFormatSymbols symbols, Chronology chrono, ZoneId zone) {
         this.printerParser = Objects.requireNonNull(printerParser, "printerParser");
         this.locale = Objects.requireNonNull(locale, "locale");
         this.symbols = Objects.requireNonNull(symbols, "symbols");
@@ -206,11 +996,11 @@
      * <p>
      * This returns the override chronology, used to convert dates.
      * By default, a formatter has no override chronology, returning null.
-     * See {@link #withChrono(Chrono)} for more details on overriding.
+     * See {@link #withChronology(Chronology)} for more details on overriding.
      *
      * @return the chronology of this formatter, null if no override
      */
-    public Chrono<?> getChrono() {
+    public Chronology getChronology() {
         return chrono;
     }
 
@@ -221,9 +1011,9 @@
      * with the override chronology set.
      * By default, a formatter has no override chronology, returning null.
      * <p>
-     * If an override is added, then any date that is printed or parsed will be affected.
+     * If an override is added, then any date that is formatted or parsed will be affected.
      * <p>
-     * When printing, if the {@code Temporal} object contains a date then it will
+     * When formatting, if the {@code Temporal} object contains a date then it will
      * be converted to a date in the override chronology.
      * Any time or zone will be retained unless overridden.
      * The converted result will behave in a manner equivalent to an implementation
@@ -238,7 +1028,7 @@
      * @param chrono  the new chronology, not null
      * @return a formatter based on this formatter with the requested override chronology, not null
      */
-    public DateTimeFormatter withChrono(Chrono chrono) {
+    public DateTimeFormatter withChronology(Chronology chrono) {
         if (Objects.equals(this.chrono, chrono)) {
             return this;
         }
@@ -266,9 +1056,9 @@
      * with the override zone set.
      * By default, a formatter has no override zone, returning null.
      * <p>
-     * If an override is added, then any instant that is printed or parsed will be affected.
+     * If an override is added, then any instant that is formatted or parsed will be affected.
      * <p>
-     * When printing, if the {@code Temporal} object contains an instant then it will
+     * When formatting, if the {@code Temporal} object contains an instant then it will
      * be converted to a zoned date-time using the override zone.
      * If the input has a chronology then it will be retained unless overridden.
      * If the input does not have a chronology, such as {@code Instant}, then
@@ -294,53 +1084,120 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Prints a date-time object using this formatter.
+     * Formats a date-time object using this formatter.
      * <p>
-     * This prints the date-time to a String using the rules of the formatter.
+     * This formats the date-time to a String using the rules of the formatter.
      *
-     * @param temporal  the temporal object to print, not null
-     * @return the printed string, not null
-     * @throws DateTimeException if an error occurs during printing
+     * @param temporal  the temporal object to format, not null
+     * @return the formatted string, not null
+     * @throws DateTimeException if an error occurs during formatting
      */
-    public String print(TemporalAccessor temporal) {
+    public String format(TemporalAccessor temporal) {
         StringBuilder buf = new StringBuilder(32);
-        printTo(temporal, buf);
+        formatTo(temporal, buf);
         return buf.toString();
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Prints a date-time object to an {@code Appendable} using this formatter.
+     * Formats a date-time object to an {@code Appendable} using this formatter.
      * <p>
-     * This prints the date-time to the specified destination.
+     * This outputs the formatted date-time to the specified destination.
      * {@link Appendable} is a general purpose interface that is implemented by all
      * key character output classes including {@code StringBuffer}, {@code StringBuilder},
      * {@code PrintStream} and {@code Writer}.
      * <p>
      * Although {@code Appendable} methods throw an {@code IOException}, this method does not.
      * Instead, any {@code IOException} is wrapped in a runtime exception.
-     * See {@link DateTimePrintException#rethrowIOException()} for a means
-     * to extract the {@code IOException}.
      *
-     * @param temporal  the temporal object to print, not null
-     * @param appendable  the appendable to print to, not null
-     * @throws DateTimeException if an error occurs during printing
+     * @param temporal  the temporal object to format, not null
+     * @param appendable  the appendable to format to, not null
+     * @throws DateTimeException if an error occurs during formatting
      */
-    public void printTo(TemporalAccessor temporal, Appendable appendable) {
+    public void formatTo(TemporalAccessor temporal, Appendable appendable) {
         Objects.requireNonNull(temporal, "temporal");
         Objects.requireNonNull(appendable, "appendable");
         try {
             DateTimePrintContext context = new DateTimePrintContext(temporal, this);
             if (appendable instanceof StringBuilder) {
-                printerParser.print(context, (StringBuilder) appendable);
+                printerParser.format(context, (StringBuilder) appendable);
             } else {
                 // buffer output to avoid writing to appendable in case of error
                 StringBuilder buf = new StringBuilder(32);
-                printerParser.print(context, buf);
+                printerParser.format(context, buf);
                 appendable.append(buf);
             }
         } catch (IOException ex) {
-            throw new DateTimePrintException(ex.getMessage(), ex);
+            throw new DateTimeException(ex.getMessage(), ex);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Fully parses the text producing a temporal object.
+     * <p>
+     * This parses the entire text producing a temporal object.
+     * It is typically more useful to use {@link #parse(CharSequence, TemporalQuery)}.
+     * The result of this method is {@code TemporalAccessor} which has been resolved,
+     * applying basic validation checks to help ensure a valid date-time.
+     * <p>
+     * If the parse completes without reading the entire length of the text,
+     * or a problem occurs during parsing or merging, then an exception is thrown.
+     *
+     * @param text  the text to parse, not null
+     * @return the parsed temporal object, not null
+     * @throws DateTimeParseException if unable to parse the requested result
+     */
+    public TemporalAccessor parse(CharSequence text) {
+        Objects.requireNonNull(text, "text");
+        try {
+            return parseToBuilder(text, null).resolve();
+        } catch (DateTimeParseException ex) {
+            throw ex;
+        } catch (RuntimeException ex) {
+            throw createError(text, ex);
+        }
+    }
+
+    /**
+     * Parses the text using this formatter, providing control over the text position.
+     * <p>
+     * This parses the text without requiring the parse to start from the beginning
+     * of the string or finish at the end.
+     * The result of this method is {@code TemporalAccessor} which has been resolved,
+     * applying basic validation checks to help ensure a valid date-time.
+     * <p>
+     * The text will be parsed from the specified start {@code ParsePosition}.
+     * The entire length of the text does not have to be parsed, the {@code ParsePosition}
+     * will be updated with the index at the end of parsing.
+     * <p>
+     * The operation of this method is slightly different to similar methods using
+     * {@code ParsePosition} on {@code java.text.Format}. That class will return
+     * errors using the error index on the {@code ParsePosition}. By contrast, this
+     * method will throw a {@link DateTimeParseException} if an error occurs, with
+     * the exception containing the error index.
+     * This change in behavior is necessary due to the increased complexity of
+     * parsing and resolving dates/times in this API.
+     * <p>
+     * If the formatter parses the same field more than once with different values,
+     * the result will be an error.
+     *
+     * @param text  the text to parse, not null
+     * @param position  the position to parse from, updated with length parsed
+     *  and the index of any error, not null
+     * @return the parsed temporal object, not null
+     * @throws DateTimeParseException if unable to parse the requested result
+     * @throws IndexOutOfBoundsException if the position is invalid
+     */
+    public TemporalAccessor parse(CharSequence text, ParsePosition position) {
+        Objects.requireNonNull(text, "text");
+        Objects.requireNonNull(position, "position");
+        try {
+            return parseToBuilder(text, position).resolve();
+        } catch (DateTimeParseException | IndexOutOfBoundsException ex) {
+            throw ex;
+        } catch (RuntimeException ex) {
+            throw createError(text, ex);
         }
     }
 
@@ -362,19 +1219,18 @@
      * @param text  the text to parse, not null
      * @param query  the query defining the type to parse to, not null
      * @return the parsed date-time, not null
-     * @throws DateTimeParseException if the parse fails
+     * @throws DateTimeParseException if unable to parse the requested result
      */
     public <T> T parse(CharSequence text, TemporalQuery<T> query) {
         Objects.requireNonNull(text, "text");
         Objects.requireNonNull(query, "query");
-        String str = text.toString();  // parsing whole String, so this makes sense
         try {
-            DateTimeBuilder builder = parseToBuilder(str).resolve();
+            DateTimeBuilder builder = parseToBuilder(text, null).resolve();
             return builder.query(query);
         } catch (DateTimeParseException ex) {
             throw ex;
         } catch (RuntimeException ex) {
-            throw createError(str, ex);
+            throw createError(text, ex);
         }
     }
 
@@ -382,8 +1238,8 @@
      * Fully parses the text producing an object of one of the specified types.
      * <p>
      * This parse method is convenient for use when the parser can handle optional elements.
-     * For example, a pattern of 'yyyy-MM[-dd[Z]]' can be fully parsed to an {@code OffsetDate},
-     * or partially parsed to a {@code LocalDate} or a {@code YearMonth}.
+     * For example, a pattern of 'yyyy-MM-dd HH.mm[Z]]' can be fully parsed to a {@code ZonedDateTime},
+     * or partially parsed to a {@code LocalDateTime}.
      * The queries must be specified in order, starting from the best matching full-parse option
      * and ending with the worst matching minimal parse option.
      * The query is typically a method reference to a {@code from(TemporalAccessor)} method.
@@ -392,8 +1248,8 @@
      * Normally, applications will use {@code instanceof} to check the result.
      * For example:
      * <pre>
-     *  TemporalAccessor dt = parser.parseBest(str, OffsetDate::from, LocalDate::from);
-     *  if (dt instanceof OffsetDate) {
+     *  TemporalAccessor dt = parser.parseBest(str, ZonedDateTime::from, LocalDateTime::from);
+     *  if (dt instanceof ZonedDateTime) {
      *   ...
      *  } else {
      *   ...
@@ -407,8 +1263,7 @@
      *  must implement {@code TemporalAccessor}, not null
      * @return the parsed date-time, not null
      * @throws IllegalArgumentException if less than 2 types are specified
-     * @throws DateTimeException if none of the queries can be parsed from the input
-     * @throws DateTimeParseException if the parse fails
+     * @throws DateTimeParseException if unable to parse the requested result
      */
     public TemporalAccessor parseBest(CharSequence text, TemporalQuery<?>... queries) {
         Objects.requireNonNull(text, "text");
@@ -416,9 +1271,8 @@
         if (queries.length < 2) {
             throw new IllegalArgumentException("At least two queries must be specified");
         }
-        String str = text.toString();  // parsing whole String, so this makes sense
         try {
-            DateTimeBuilder builder = parseToBuilder(str).resolve();
+            DateTimeBuilder builder = parseToBuilder(text, null).resolve();
             for (TemporalQuery<?> query : queries) {
                 try {
                     return (TemporalAccessor) builder.query(query);
@@ -430,16 +1284,18 @@
         } catch (DateTimeParseException ex) {
             throw ex;
         } catch (RuntimeException ex) {
-            throw createError(str, ex);
+            throw createError(text, ex);
         }
     }
 
-    private DateTimeParseException createError(String str, RuntimeException ex) {
-        String abbr = str;
-        if (abbr.length() > 64) {
-            abbr = abbr.substring(0, 64) + "...";
+    private DateTimeParseException createError(CharSequence text, RuntimeException ex) {
+        String abbr = "";
+        if (text.length() > 64) {
+            abbr = text.subSequence(0, 64).toString() + "...";
+        } else {
+            abbr = text.toString();
         }
-        return new DateTimeParseException("Text '" + abbr + "' could not be parsed: " + ex.getMessage(), str, 0, ex);
+        return new DateTimeParseException("Text '" + abbr + "' could not be parsed: " + ex.getMessage(), text, 0, ex);
     }
 
     //-----------------------------------------------------------------------
@@ -451,60 +1307,87 @@
      * some other {@code DateTimeException} if another date/time problem occurs.
      *
      * @param text  the text to parse, not null
+     * @param position  the position to parse from, updated with length parsed
+     *  and the index of any error, null if parsing whole string
      * @return the engine representing the result of the parse, not null
      * @throws DateTimeParseException if the parse fails
      */
-    public DateTimeBuilder parseToBuilder(CharSequence text) {
-        Objects.requireNonNull(text, "text");
-        String str = text.toString();  // parsing whole String, so this makes sense
-        ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder result = parseToBuilder(str, pos);
-        if (result == null || pos.getErrorIndex() >= 0 || pos.getIndex() < str.length()) {
-            String abbr = str;
-            if (abbr.length() > 64) {
-                abbr = abbr.substring(0, 64) + "...";
+    private DateTimeBuilder parseToBuilder(final CharSequence text, final ParsePosition position) {
+        ParsePosition pos = (position != null ? position : new ParsePosition(0));
+        DateTimeParseContext result = parseUnresolved0(text, pos);
+        if (result == null || pos.getErrorIndex() >= 0 || (position == null && pos.getIndex() < text.length())) {
+            String abbr = "";
+            if (text.length() > 64) {
+                abbr = text.subSequence(0, 64).toString() + "...";
+            } else {
+                abbr = text.toString();
             }
             if (pos.getErrorIndex() >= 0) {
                 throw new DateTimeParseException("Text '" + abbr + "' could not be parsed at index " +
-                        pos.getErrorIndex(), str, pos.getErrorIndex());
+                        pos.getErrorIndex(), text, pos.getErrorIndex());
             } else {
                 throw new DateTimeParseException("Text '" + abbr + "' could not be parsed, unparsed text found at index " +
-                        pos.getIndex(), str, pos.getIndex());
+                        pos.getIndex(), text, pos.getIndex());
             }
         }
-        return result;
+        return result.resolveFields().toBuilder();
     }
 
     /**
-     * Parses the text to a builder.
+     * Parses the text using this formatter, without resolving the result, intended
+     * for advanced use cases.
      * <p>
-     * This parses to a {@code DateTimeBuilder} but does not require the input to be fully parsed.
+     * Parsing is implemented as a two-phase operation.
+     * First, the text is parsed using the layout defined by the formatter, producing
+     * a {@code Map} of field to value, a {@code ZoneId} and a {@code Chronology}.
+     * Second, the parsed data is <em>resolved</em>, by validating, combining and
+     * simplifying the various fields into more useful ones.
+     * This method performs the parsing stage but not the resolving stage.
      * <p>
-     * This method does not throw {@link DateTimeParseException}.
-     * Instead, errors are returned within the state of the specified parse position.
+     * The result of this method is {@code TemporalAccessor} which represents the
+     * data as seen in the input. Values are not validated, thus parsing a date string
+     * of '2012-00-65' would result in a temporal with three fields - year of '2012',
+     * month of '0' and day-of-month of '65'.
+     * <p>
+     * The text will be parsed from the specified start {@code ParsePosition}.
+     * The entire length of the text does not have to be parsed, the {@code ParsePosition}
+     * will be updated with the index at the end of parsing.
+     * <p>
+     * Errors are returned using the error index field of the {@code ParsePosition}
+     * instead of {@code DateTimeParseException}.
+     * The returned error index will be set to an index indicative of the error.
      * Callers must check for errors before using the context.
      * <p>
-     * This method may throw some other {@code DateTimeException} if a date/time problem occurs.
+     * If the formatter parses the same field more than once with different values,
+     * the result will be an error.
+     * <p>
+     * This method is intended for advanced use cases that need access to the
+     * internal state during parsing. Typical application code should use
+     * {@link #parse(CharSequence, TemporalQuery)} or the parse method on the target type.
      *
      * @param text  the text to parse, not null
      * @param position  the position to parse from, updated with length parsed
      *  and the index of any error, not null
-     * @return the parsed text, null only if the parse results in an error
+     * @return the parsed text, null if the parse results in an error
      * @throws DateTimeException if some problem occurs during parsing
      * @throws IndexOutOfBoundsException if the position is invalid
      */
-    public DateTimeBuilder parseToBuilder(CharSequence text, ParsePosition position) {
+    public TemporalAccessor parseUnresolved(CharSequence text, ParsePosition position) {
+        return parseUnresolved0(text, position);
+    }
+
+    private DateTimeParseContext parseUnresolved0(CharSequence text, ParsePosition position) {
         Objects.requireNonNull(text, "text");
         Objects.requireNonNull(position, "position");
         DateTimeParseContext context = new DateTimeParseContext(this);
         int pos = position.getIndex();
         pos = printerParser.parse(context, text, pos);
         if (pos < 0) {
-            position.setErrorIndex(~pos);
+            position.setErrorIndex(~pos);  // index not updated from input
             return null;
         }
-        position.setIndex(pos);
-        return context.toBuilder();
+        position.setIndex(pos);  // errorIndex not updated from input
+        return context;
     }
 
     //-----------------------------------------------------------------------
@@ -521,8 +1404,8 @@
     /**
      * Returns this formatter as a {@code java.text.Format} instance.
      * <p>
-     * The returned {@link Format} instance will print any {@link java.time.temporal.TemporalAccessor}
-     * and parses to a resolved {@link DateTimeBuilder}.
+     * The returned {@link Format} instance will format any {@link TemporalAccessor}
+     * and parses to a resolved {@link TemporalAccessor}.
      * <p>
      * Exceptions will follow the definitions of {@code Format}, see those methods
      * for details about {@code IllegalArgumentException} during formatting and
@@ -539,7 +1422,7 @@
      * Returns this formatter as a {@code java.text.Format} instance that will
      * parse using the specified query.
      * <p>
-     * The returned {@link Format} instance will print any {@link java.time.temporal.TemporalAccessor}
+     * The returned {@link Format} instance will format any {@link TemporalAccessor}
      * and parses to the type specified.
      * The type must be one that is supported by {@link #parse}.
      * <p>
@@ -602,7 +1485,7 @@
             pos.setBeginIndex(0);
             pos.setEndIndex(0);
             try {
-                formatter.printTo((TemporalAccessor) obj, toAppendTo);
+                formatter.formatTo((TemporalAccessor) obj, toAppendTo);
             } catch (RuntimeException ex) {
                 throw new IllegalArgumentException(ex.getMessage(), ex);
             }
@@ -612,10 +1495,10 @@
         public Object parseObject(String text) throws ParseException {
             Objects.requireNonNull(text, "text");
             try {
-                if (parseType != null) {
-                    return formatter.parse(text, parseType);
+                if (parseType == null) {
+                    return formatter.parseToBuilder(text, null).resolve();
                 }
-                return formatter.parseToBuilder(text);
+                return formatter.parse(text, parseType);
             } catch (DateTimeParseException ex) {
                 throw new ParseException(ex.getMessage(), ex.getErrorIndex());
             } catch (RuntimeException ex) {
@@ -625,26 +1508,27 @@
         @Override
         public Object parseObject(String text, ParsePosition pos) {
             Objects.requireNonNull(text, "text");
-            DateTimeBuilder builder;
+            DateTimeParseContext unresolved;
             try {
-                builder = formatter.parseToBuilder(text, pos);
+                unresolved = formatter.parseUnresolved0(text, pos);
             } catch (IndexOutOfBoundsException ex) {
                 if (pos.getErrorIndex() < 0) {
                     pos.setErrorIndex(0);
                 }
                 return null;
             }
-            if (builder == null) {
+            if (unresolved == null) {
                 if (pos.getErrorIndex() < 0) {
                     pos.setErrorIndex(0);
                 }
                 return null;
             }
-            if (parseType == null) {
-                return builder;
-            }
             try {
-                return builder.resolve().query(parseType);
+                DateTimeBuilder builder = unresolved.resolveFields().toBuilder().resolve();
+                if (parseType == null) {
+                    return builder;
+                }
+                return builder.query(parseType);
             } catch (RuntimeException ex) {
                 pos.setErrorIndex(0);
                 return null;
diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java
index 9ad63a6..f2ed231 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java
@@ -81,11 +81,12 @@
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
 import java.time.format.DateTimeTextProvider.LocaleStore;
-import java.time.temporal.Chrono;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ISOChrono;
-import java.time.temporal.ISOFields;
+import java.time.temporal.IsoFields;
 import java.time.temporal.Queries;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
@@ -99,6 +100,7 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -289,10 +291,10 @@
      * Appends the value of a date-time field to the formatter using a normal
      * output style.
      * <p>
-     * The value of the field will be output during a print.
+     * The value of the field will be output during a format.
      * If the value cannot be obtained then an exception will be thrown.
      * <p>
-     * The value will be printed as per the normal print of an integer value.
+     * The value will be printed as per the normal format of an integer value.
      * Only negative numbers will be signed. No padding will be added.
      * <p>
      * The parser for a variable width value such as this normally behaves greedily,
@@ -313,12 +315,12 @@
      * Appends the value of a date-time field to the formatter using a fixed
      * width, zero-padded approach.
      * <p>
-     * The value of the field will be output during a print.
+     * The value of the field will be output during a format.
      * If the value cannot be obtained then an exception will be thrown.
      * <p>
      * The value will be zero-padded on the left. If the size of the value
      * means that it cannot be printed within the width then an exception is thrown.
-     * If the value of the field is negative then an exception is thrown during printing.
+     * If the value of the field is negative then an exception is thrown during formatting.
      * <p>
      * This method supports a special technique of parsing known as 'adjacent value parsing'.
      * This technique solves the problem where a variable length value is followed by one or more
@@ -368,9 +370,9 @@
 
     /**
      * Appends the value of a date-time field to the formatter providing full
-     * control over printing.
+     * control over formatting.
      * <p>
-     * The value of the field will be output during a print.
+     * The value of the field will be output during a format.
      * If the value cannot be obtained then an exception will be thrown.
      * <p>
      * This method provides full control of the numeric formatting, including
@@ -386,7 +388,7 @@
      * <p>
      * If this method is invoked with equal minimum and maximum widths and a sign style of
      * {@code NOT_NEGATIVE} then it delegates to {@code appendValue(TemporalField,int)}.
-     * In this scenario, the printing and parsing behavior described there occur.
+     * In this scenario, the formatting and parsing behavior described there occur.
      *
      * @param field  the field to append, not null
      * @param minWidth  the minimum field width of the printed field, from 1 to 19
@@ -425,11 +427,11 @@
     /**
      * Appends the reduced value of a date-time field to the formatter.
      * <p>
-     * This is typically used for printing and parsing a two digit year.
+     * This is typically used for formatting and parsing a two digit year.
      * The {@code width} is the printed and parsed width.
      * The {@code baseValue} is used during parsing to determine the valid range.
      * <p>
-     * For printing, the width is used to determine the number of characters to print.
+     * For formatting, the width is used to determine the number of characters to format.
      * The rightmost characters are output to match the width, left padding with zero.
      * <p>
      * For parsing, exactly the number of characters specified by the width are parsed.
@@ -525,12 +527,12 @@
      * Appends the text of a date-time field to the formatter using the full
      * text style.
      * <p>
-     * The text of the field will be output during a print.
+     * The text of the field will be output during a format.
      * The value must be within the valid range of the field.
      * If the value cannot be obtained then an exception will be thrown.
      * If the field has no textual representation, then the numeric value will be used.
      * <p>
-     * The value will be printed as per the normal print of an integer value.
+     * The value will be printed as per the normal format of an integer value.
      * Only negative numbers will be signed. No padding will be added.
      *
      * @param field  the field to append, not null
@@ -543,12 +545,12 @@
     /**
      * Appends the text of a date-time field to the formatter.
      * <p>
-     * The text of the field will be output during a print.
+     * The text of the field will be output during a format.
      * The value must be within the valid range of the field.
      * If the value cannot be obtained then an exception will be thrown.
      * If the field has no textual representation, then the numeric value will be used.
      * <p>
-     * The value will be printed as per the normal print of an integer value.
+     * The value will be printed as per the normal format of an integer value.
      * Only negative numbers will be signed. No padding will be added.
      *
      * @param field  the field to append, not null
@@ -568,10 +570,10 @@
      * <p>
      * The standard text outputting methods use the localized text in the JDK.
      * This method allows that text to be specified directly.
-     * The supplied map is not validated by the builder to ensure that printing or
+     * The supplied map is not validated by the builder to ensure that formatting or
      * parsing is possible, thus an invalid map may throw an error during later use.
      * <p>
-     * Supplying the map of text provides considerable flexibility in printing and parsing.
+     * Supplying the map of text provides considerable flexibility in formatting and parsing.
      * For example, a legacy application might require or supply the months of the
      * year as "JNY", "FBY", "MCH" etc. These do not match the standard set of text
      * for localized month names. Using this method, a map can be created which
@@ -588,7 +590,7 @@
      * Other uses might be to output the value with a suffix, such as "1st", "2nd", "3rd",
      * or as Roman numerals "I", "II", "III", "IV".
      * <p>
-     * During printing, the value is obtained and checked that it is in the valid range.
+     * During formatting, the value is obtained and checked that it is in the valid range.
      * If text is not available for the value then it is output as a number.
      * During parsing, the parser will match against the map of text and numeric values.
      *
@@ -624,7 +626,7 @@
      * They are converted to a date-time with a zone-offset of UTC and printed
      * using the standard ISO-8601 format.
      * <p>
-     * An alternative to this method is to print/parse the instant as a single
+     * An alternative to this method is to format/parse the instant as a single
      * epoch-seconds value. That is achieved using {@code appendValue(INSTANT_SECONDS)}.
      *
      * @return this, for chaining, not null
@@ -637,22 +639,22 @@
     /**
      * Appends the zone offset, such as '+01:00', to the formatter.
      * <p>
-     * This appends an instruction to print/parse the offset ID to the builder.
+     * This appends an instruction to format/parse the offset ID to the builder.
      * This is equivalent to calling {@code appendOffset("HH:MM:ss", "Z")}.
      *
      * @return this, for chaining, not null
      */
     public DateTimeFormatterBuilder appendOffsetId() {
-        appendInternal(OffsetIdPrinterParser.INSTANCE_ID);
+        appendInternal(OffsetIdPrinterParser.INSTANCE_ID_Z);
         return this;
     }
 
     /**
      * Appends the zone offset, such as '+01:00', to the formatter.
      * <p>
-     * This appends an instruction to print/parse the offset ID to the builder.
+     * This appends an instruction to format/parse the offset ID to the builder.
      * <p>
-     * During printing, the offset is obtained using a mechanism equivalent
+     * During formatting, the offset is obtained using a mechanism equivalent
      * to querying the temporal with {@link Queries#offset()}.
      * It will be printed using the format defined below.
      * If the offset cannot be obtained then an exception is thrown unless the
@@ -665,15 +667,18 @@
      * The format of the offset is controlled by a pattern which must be one
      * of the following:
      * <p><ul>
-     * <li>{@code +HH} - hour only, ignoring any minute
-     * <li>{@code +HHMM} - hour and minute, no colon
-     * <li>{@code +HH:MM} - hour and minute, with colon
-     * <li>{@code +HHMMss} - hour and minute, with second if non-zero and no colon
-     * <li>{@code +HH:MM:ss} - hour and minute, with second if non-zero and colon
+     * <li>{@code +HH} - hour only, ignoring minute and second
+     * <li>{@code +HHmm} - hour, with minute if non-zero, ignoring second, no colon
+     * <li>{@code +HH:mm} - hour, with minute if non-zero, ignoring second, with colon
+     * <li>{@code +HHMM} - hour and minute, ignoring second, no colon
+     * <li>{@code +HH:MM} - hour and minute, ignoring second, with colon
+     * <li>{@code +HHMMss} - hour and minute, with second if non-zero, no colon
+     * <li>{@code +HH:MM:ss} - hour and minute, with second if non-zero, with colon
      * <li>{@code +HHMMSS} - hour, minute and second, no colon
      * <li>{@code +HH:MM:SS} - hour, minute and second, with colon
      * </ul><p>
-     * The "no offset" text controls what text is printed when the offset is zero.
+     * The "no offset" text controls what text is printed when the total amount of
+     * the offset fields to be output is zero.
      * Example values would be 'Z', '+00:00', 'UTC' or 'GMT'.
      * Three formats are accepted for parsing UTC - the "no offset" text, and the
      * plus and minus versions of zero defined by the pattern.
@@ -683,7 +688,7 @@
      * @return this, for chaining, not null
      */
     public DateTimeFormatterBuilder appendOffset(String pattern, String noOffsetText) {
-        appendInternal(new OffsetIdPrinterParser(noOffsetText, pattern));
+        appendInternal(new OffsetIdPrinterParser(pattern, noOffsetText));
         return this;
     }
 
@@ -691,20 +696,48 @@
     /**
      * Appends the time-zone ID, such as 'Europe/Paris' or '+02:00', to the formatter.
      * <p>
-     * This appends an instruction to print/parse the zone ID to the builder.
+     * This appends an instruction to format/parse the zone ID to the builder.
      * The zone ID is obtained in a strict manner suitable for {@code ZonedDateTime}.
      * By contrast, {@code OffsetDateTime} does not have a zone ID suitable
      * for use with this method, see {@link #appendZoneOrOffsetId()}.
      * <p>
-     * During printing, the zone is obtained using a mechanism equivalent
+     * During formatting, the zone is obtained using a mechanism equivalent
      * to querying the temporal with {@link Queries#zoneId()}.
      * It will be printed using the result of {@link ZoneId#getId()}.
      * If the zone cannot be obtained then an exception is thrown unless the
      * section of the formatter is optional.
      * <p>
-     * During parsing, the zone is parsed and must match a known zone or offset.
-     * If the zone cannot be parsed then an exception is thrown unless the
-     * section of the formatter is optional.
+     * During parsing, the text must match a known zone or offset.
+     * There are two types of zone ID, offset-based, such as '+01:30' and
+     * region-based, such as 'Europe/London'. These are parsed differently.
+     * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser
+     * expects an offset-based zone and will not match region-based zones.
+     * The offset ID, such as '+02:30', may be at the start of the parse,
+     * or prefixed by  'UT', 'UTC' or 'GMT'. The offset ID parsing is
+     * equivalent to using {@link #appendOffset(String, String)} using the
+     * arguments 'HH:MM:ss' and the no offset string '0'.
+     * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot
+     * match a following offset ID, then {@link ZoneOffset#UTC} is selected.
+     * In all other cases, the list of known region-based zones is used to
+     * find the longest available match. If no match is found, and the parse
+     * starts with 'Z', then {@code ZoneOffset.UTC} is selected.
+     * The parser uses the {@linkplain #parseCaseInsensitive() case sensitive} setting.
+     * <p>
+     * For example, the following will parse:
+     * <pre>
+     *   "Europe/London"           -> ZoneId.of("Europe/London")
+     *   "Z"                       -> ZoneOffset.UTC
+     *   "UT"                      -> ZoneOffset.UTC
+     *   "UTC"                     -> ZoneOffset.UTC
+     *   "GMT"                     -> ZoneOffset.UTC
+     *   "UT0"                     -> ZoneOffset.UTC
+     *   "UTC0"                    -> ZoneOffset.UTC
+     *   "GMT0"                    -> ZoneOffset.UTC
+     *   "+01:30"                  -> ZoneOffset.of("+01:30")
+     *   "UT+01:30"                -> ZoneOffset.of("+01:30")
+     *   "UTC+01:30"               -> ZoneOffset.of("+01:30")
+     *   "GMT+01:30"               -> ZoneOffset.of("+01:30")
+     * </pre>
      *
      * @return this, for chaining, not null
      * @see #appendZoneRegionId()
@@ -718,21 +751,52 @@
      * Appends the time-zone region ID, such as 'Europe/Paris', to the formatter,
      * rejecting the zone ID if it is a {@code ZoneOffset}.
      * <p>
-     * This appends an instruction to print/parse the zone ID to the builder
+     * This appends an instruction to format/parse the zone ID to the builder
      * only if it is a region-based ID.
      * <p>
-     * During printing, the zone is obtained using a mechanism equivalent
+     * During formatting, the zone is obtained using a mechanism equivalent
      * to querying the temporal with {@link Queries#zoneId()}.
      * If the zone is a {@code ZoneOffset} or it cannot be obtained then
      * an exception is thrown unless the section of the formatter is optional.
      * If the zone is not an offset, then the zone will be printed using
      * the zone ID from {@link ZoneId#getId()}.
      * <p>
-     * During parsing, the zone is parsed and must match a known zone or offset.
-     * If the zone cannot be parsed then an exception is thrown unless the
-     * section of the formatter is optional.
-     * Note that parsing accepts offsets, whereas printing will never produce
-     * one, thus parsing is equivalent to {@code appendZoneId}.
+     * During parsing, the text must match a known zone or offset.
+     * There are two types of zone ID, offset-based, such as '+01:30' and
+     * region-based, such as 'Europe/London'. These are parsed differently.
+     * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser
+     * expects an offset-based zone and will not match region-based zones.
+     * The offset ID, such as '+02:30', may be at the start of the parse,
+     * or prefixed by  'UT', 'UTC' or 'GMT'. The offset ID parsing is
+     * equivalent to using {@link #appendOffset(String, String)} using the
+     * arguments 'HH:MM:ss' and the no offset string '0'.
+     * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot
+     * match a following offset ID, then {@link ZoneOffset#UTC} is selected.
+     * In all other cases, the list of known region-based zones is used to
+     * find the longest available match. If no match is found, and the parse
+     * starts with 'Z', then {@code ZoneOffset.UTC} is selected.
+     * The parser uses the {@linkplain #parseCaseInsensitive() case sensitive} setting.
+     * <p>
+     * For example, the following will parse:
+     * <pre>
+     *   "Europe/London"           -> ZoneId.of("Europe/London")
+     *   "Z"                       -> ZoneOffset.UTC
+     *   "UT"                      -> ZoneOffset.UTC
+     *   "UTC"                     -> ZoneOffset.UTC
+     *   "GMT"                     -> ZoneOffset.UTC
+     *   "UT0"                     -> ZoneOffset.UTC
+     *   "UTC0"                    -> ZoneOffset.UTC
+     *   "GMT0"                    -> ZoneOffset.UTC
+     *   "+01:30"                  -> ZoneOffset.of("+01:30")
+     *   "UT+01:30"                -> ZoneOffset.of("+01:30")
+     *   "UTC+01:30"               -> ZoneOffset.of("+01:30")
+     *   "GMT+01:30"               -> ZoneOffset.of("+01:30")
+     * </pre>
+     * <p>
+     * Note that this method is is identical to {@code appendZoneId()} except
+     * in the mechanism used to obtain the zone.
+     * Note also that parsing accepts offsets, whereas formatting will never
+     * produce one.
      *
      * @return this, for chaining, not null
      * @see #appendZoneId()
@@ -746,24 +810,52 @@
      * Appends the time-zone ID, such as 'Europe/Paris' or '+02:00', to
      * the formatter, using the best available zone ID.
      * <p>
-     * This appends an instruction to print/parse the best available
+     * This appends an instruction to format/parse the best available
      * zone or offset ID to the builder.
      * The zone ID is obtained in a lenient manner that first attempts to
      * find a true zone ID, such as that on {@code ZonedDateTime}, and
      * then attempts to find an offset, such as that on {@code OffsetDateTime}.
      * <p>
-     * During printing, the zone is obtained using a mechanism equivalent
+     * During formatting, the zone is obtained using a mechanism equivalent
      * to querying the temporal with {@link Queries#zone()}.
      * It will be printed using the result of {@link ZoneId#getId()}.
      * If the zone cannot be obtained then an exception is thrown unless the
      * section of the formatter is optional.
      * <p>
-     * During parsing, the zone is parsed and must match a known zone or offset.
-     * If the zone cannot be parsed then an exception is thrown unless the
-     * section of the formatter is optional.
+     * During parsing, the text must match a known zone or offset.
+     * There are two types of zone ID, offset-based, such as '+01:30' and
+     * region-based, such as 'Europe/London'. These are parsed differently.
+     * If the parse starts with '+', '-', 'UT', 'UTC' or 'GMT', then the parser
+     * expects an offset-based zone and will not match region-based zones.
+     * The offset ID, such as '+02:30', may be at the start of the parse,
+     * or prefixed by  'UT', 'UTC' or 'GMT'. The offset ID parsing is
+     * equivalent to using {@link #appendOffset(String, String)} using the
+     * arguments 'HH:MM:ss' and the no offset string '0'.
+     * If the parse starts with 'UT', 'UTC' or 'GMT', and the parser cannot
+     * match a following offset ID, then {@link ZoneOffset#UTC} is selected.
+     * In all other cases, the list of known region-based zones is used to
+     * find the longest available match. If no match is found, and the parse
+     * starts with 'Z', then {@code ZoneOffset.UTC} is selected.
+     * The parser uses the {@linkplain #parseCaseInsensitive() case sensitive} setting.
      * <p>
-     * This method is is identical to {@code appendZoneId()} except in the
-     * mechanism used to obtain the zone.
+     * For example, the following will parse:
+     * <pre>
+     *   "Europe/London"           -> ZoneId.of("Europe/London")
+     *   "Z"                       -> ZoneOffset.UTC
+     *   "UT"                      -> ZoneOffset.UTC
+     *   "UTC"                     -> ZoneOffset.UTC
+     *   "GMT"                     -> ZoneOffset.UTC
+     *   "UT0"                     -> ZoneOffset.UTC
+     *   "UTC0"                    -> ZoneOffset.UTC
+     *   "GMT0"                    -> ZoneOffset.UTC
+     *   "+01:30"                  -> ZoneOffset.of("+01:30")
+     *   "UT+01:30"                -> ZoneOffset.of("+01:30")
+     *   "UTC+01:30"               -> ZoneOffset.of("+01:30")
+     *   "GMT+01:30"               -> ZoneOffset.of("+01:30")
+     * </pre>
+     * <p>
+     * Note that this method is is identical to {@code appendZoneId()} except
+     * in the mechanism used to obtain the zone.
      *
      * @return this, for chaining, not null
      * @see #appendZoneId()
@@ -776,9 +868,10 @@
     /**
      * Appends the time-zone name, such as 'British Summer Time', to the formatter.
      * <p>
-     * This appends an instruction to print the textual name of the zone to the builder.
+     * This appends an instruction to format/parse the textual name of the zone to
+     * the builder.
      * <p>
-     * During printing, the zone is obtained using a mechanism equivalent
+     * During formatting, the zone is obtained using a mechanism equivalent
      * to querying the temporal with {@link Queries#zoneId()}.
      * If the zone is a {@code ZoneOffset} it will be printed using the
      * result of {@link ZoneOffset#getId()}.
@@ -791,31 +884,87 @@
      * If the zone cannot be obtained then an exception is thrown unless the
      * section of the formatter is optional.
      * <p>
-     * Parsing is not currently supported.
+     * During parsing, either the textual zone name, the zone ID or the offset
+     * is accepted. Many textual zone names are not unique, such as CST can be
+     * for both "Central Standard Time" and "China Standard Time". In this
+     * situation, the zone id will be determined by the region information from
+     * formatter's  {@link DateTimeFormatter#getLocale() locale} and the standard
+     * zone id for that area, for example, America/New_York for the America Eastern
+     * zone. The {@link #appendZoneText(TextStyle, Set)} may be used
+     * to specify a set of preferred {@link ZoneId} in this situation.
      *
      * @param textStyle  the text style to use, not null
      * @return this, for chaining, not null
      */
     public DateTimeFormatterBuilder appendZoneText(TextStyle textStyle) {
-        // TODO: parsing of zone text?
-//        * During parsing, either the textual zone name, the zone ID or the offset
-//        * is accepted.
-//        * If the zone cannot be parsed then an exception is thrown unless the
-//        * section of the formatter is optional.
-        appendInternal(new ZoneTextPrinterParser(textStyle));
+        appendInternal(new ZoneTextPrinterParser(textStyle, null));
+        return this;
+    }
+
+    /**
+     * Appends the time-zone name, such as 'British Summer Time', to the formatter.
+     * <p>
+     * This appends an instruction to format/parse the textual name of the zone to
+     * the builder.
+     * <p>
+     * During formatting, the zone is obtained using a mechanism equivalent
+     * to querying the temporal with {@link Queries#zoneId()}.
+     * If the zone is a {@code ZoneOffset} it will be printed using the
+     * result of {@link ZoneOffset#getId()}.
+     * If the zone is not an offset, the textual name will be looked up
+     * for the locale set in the {@link DateTimeFormatter}.
+     * If the temporal object being printed represents an instant, then the text
+     * will be the summer or winter time text as appropriate.
+     * If the lookup for text does not find any suitable reuslt, then the
+     * {@link ZoneId#getId() ID} will be printed instead.
+     * If the zone cannot be obtained then an exception is thrown unless the
+     * section of the formatter is optional.
+     * <p>
+     * During parsing, either the textual zone name, the zone ID or the offset
+     * is accepted. Many textual zone names are not unique, such as CST can be
+     * for both "Central Standard Time" and "China Standard Time". In this
+     * situation, the zone id will be determined by the region information from
+     * formatter's  {@link DateTimeFormatter#getLocale() locale} and the standard
+     * zone id for that area, for example, America/New_York for the America Eastern
+     * zone. This method also allows a set of preferred {@link ZoneId} to be
+     * specified for parsing. The matched preferred zone id will be used if the
+     * textural zone name being parsed is not unique.
+     *
+     * If the zone cannot be parsed then an exception is thrown unless the
+     * section of the formatter is optional.
+     *
+     * @param textStyle  the text style to use, not null
+     * @param preferredZones  the set of preferred zone ids, not null
+     * @return this, for chaining, not null
+     */
+    public DateTimeFormatterBuilder appendZoneText(TextStyle textStyle,
+                                                   Set<ZoneId> preferredZones) {
+        Objects.requireNonNull(preferredZones, "preferredZones");
+        appendInternal(new ZoneTextPrinterParser(textStyle, preferredZones));
         return this;
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Appends the chronology ID to the formatter.
+     * Appends the chronology ID, such as 'ISO' or 'ThaiBuddhist', to the formatter.
      * <p>
-     * The chronology ID will be output during a print.
-     * If the chronology cannot be obtained then an exception will be thrown.
+     * This appends an instruction to format/parse the chronology ID to the builder.
+     * <p>
+     * During formatting, the chronology is obtained using a mechanism equivalent
+     * to querying the temporal with {@link Queries#chronology()}.
+     * It will be printed using the result of {@link Chronology#getId()}.
+     * If the chronology cannot be obtained then an exception is thrown unless the
+     * section of the formatter is optional.
+     * <p>
+     * During parsing, the chronology is parsed and must match one of the chronologies
+     * in {@link Chronology#getAvailableChronologies()}.
+     * If the chronology cannot be parsed then an exception is thrown unless the
+     * section of the formatter is optional.
+     * The parser uses the {@linkplain #parseCaseInsensitive() case sensitive} setting.
      *
      * @return this, for chaining, not null
      */
-    public DateTimeFormatterBuilder appendChronoId() {
+    public DateTimeFormatterBuilder appendChronologyId() {
         appendInternal(new ChronoPrinterParser(null));
         return this;
     }
@@ -823,14 +972,14 @@
     /**
      * Appends the chronology name to the formatter.
      * <p>
-     * The calendar system name will be output during a print.
+     * The calendar system name will be output during a format.
      * If the chronology cannot be obtained then an exception will be thrown.
      * The calendar system name is obtained from the formatting symbols.
      *
      * @param textStyle  the text style to use, not null
      * @return this, for chaining, not null
      */
-    public DateTimeFormatterBuilder appendChronoText(TextStyle textStyle) {
+    public DateTimeFormatterBuilder appendChronologyText(TextStyle textStyle) {
         Objects.requireNonNull(textStyle, "textStyle");
         appendInternal(new ChronoPrinterParser(textStyle));
         return this;
@@ -840,39 +989,36 @@
     /**
      * Appends a localized date-time pattern to the formatter.
      * <p>
-     * The pattern is resolved lazily using the locale being used during the print/parse
-     * (stored in {@link DateTimeFormatter}.
+     * This appends a localized section to the builder, suitable for outputting
+     * a date, time or date-time combination. The format of the localized
+     * section is lazily looked up based on four items:
+     * <p><ul>
+     * <li>the {@code dateStyle} specified to this method
+     * <li>the {@code timeStyle} specified to this method
+     * <li>the {@code Locale} of the {@code DateTimeFormatter}
+     * <li>the {@code Chronology}, selecting the best available
+     * </ul><p>
+     * During formatting, the chronology is obtained from the temporal object
+     * being formatted, which may have been overridden by
+     * {@link DateTimeFormatter#withChronology(Chronology)}.
      * <p>
-     * The pattern can vary by chronology, although typically it doesn't.
-     * This method uses the standard ISO chronology patterns.
+     * During parsing, if a chronology has already been parsed, then it is used.
+     * Otherwise the default from {@code DateTimeFormatter.withChronology(Chronology)}
+     * is used, with {@code IsoChronology} as the fallback.
+     * <p>
+     * Note that this method provides similar functionality to methods on
+     * {@code DateFormat} such as {@link DateFormat#getDateTimeInstance(int, int)}.
      *
      * @param dateStyle  the date style to use, null means no date required
      * @param timeStyle  the time style to use, null means no time required
      * @return this, for chaining, not null
+     * @throws IllegalArgumentException if both the date and time styles are null
      */
     public DateTimeFormatterBuilder appendLocalized(FormatStyle dateStyle, FormatStyle timeStyle) {
-        return appendLocalized(dateStyle, timeStyle, ISOChrono.INSTANCE);
-    }
-
-    /**
-     * Appends a localized date-time pattern to the formatter.
-     * <p>
-     * The pattern is resolved lazily using the locale being used during the print/parse,
-     * stored in {@link DateTimeFormatter}.
-     * <p>
-     * The pattern can vary by chronology, although typically it doesn't.
-     * This method allows the chronology to be specified.
-     *
-     * @param dateStyle  the date style to use, null means no date required
-     * @param timeStyle  the time style to use, null means no time required
-     * @param chrono  the chronology to use, not null
-     * @return this, for chaining, not null
-     */
-    public DateTimeFormatterBuilder appendLocalized(FormatStyle dateStyle, FormatStyle timeStyle, Chrono<?> chrono) {
-        Objects.requireNonNull(chrono, "chrono");
-        if (dateStyle != null || timeStyle != null) {
-            appendInternal(new LocalizedPrinterParser(dateStyle, timeStyle, chrono));
+        if (dateStyle == null && timeStyle == null) {
+            throw new IllegalArgumentException("Either the date or time style must be non-null");
         }
+        appendInternal(new LocalizedPrinterParser(dateStyle, timeStyle));
         return this;
     }
 
@@ -880,7 +1026,7 @@
     /**
      * Appends a character literal to the formatter.
      * <p>
-     * This character will be output during a print.
+     * This character will be output during a format.
      *
      * @param literal  the literal to append, not null
      * @return this, for chaining, not null
@@ -893,7 +1039,7 @@
     /**
      * Appends a string literal to the formatter.
      * <p>
-     * This string will be output during a print.
+     * This string will be output during a format.
      * <p>
      * If the literal is empty, nothing is added to the formatter.
      *
@@ -929,13 +1075,13 @@
     }
 
     /**
-     * Appends a formatter to the builder which will optionally print/parse.
+     * Appends a formatter to the builder which will optionally format/parse.
      * <p>
      * This method has the same effect as appending each of the constituent
      * parts directly to this builder surrounded by an {@link #optionalStart()} and
      * {@link #optionalEnd()}.
      * <p>
-     * The formatter will print if data is available for all the fields contained within it.
+     * The formatter will format if data is available for all the fields contained within it.
      * The formatter will parse if the string matches, otherwise no error is returned.
      *
      * @param formatter  the formatter to add, not null
@@ -958,7 +1104,7 @@
      * <pre>
      *  Symbol  Meaning                     Presentation      Examples
      *  ------  -------                     ------------      -------
-     *   G       era                         number/text       1; 01; AD; Anno Domini
+     *   G       era                         text              A; AD; Anno Domini
      *   y       year                        year              2004; 04
      *   D       day-of-year                 number            189
      *   M       month-of-year               number/text       7; 07; Jul; July; J
@@ -985,10 +1131,11 @@
      *   n       nano-of-second              number            987654321
      *   N       nano-of-day                 number            1234000000
      *
-     *   I       time-zone ID                zoneId            America/Los_Angeles
-     *   z       time-zone name              text              Pacific Standard Time; PST
-     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
+     *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
+     *   z       time-zone name              zone-name         Pacific Standard Time; PST
      *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
+     *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
+     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
      *
      *   p       pad next                    pad modifier      1
      *
@@ -1023,26 +1170,66 @@
      * <p>
      * <b>Year</b>: The count of letters determines the minimum field width below which padding is used.
      * If the count of letters is two, then a {@link #appendValueReduced reduced} two digit form is used.
-     * For printing, this outputs the rightmost two digits. For parsing, this will parse using the
+     * For formatting, this outputs the rightmost two digits. For parsing, this will parse using the
      * base value of 2000, resulting in a year within the range 2000 to 2099 inclusive.
      * If the count of letters is less than four (but not two), then the sign is only output for negative
      * years as per {@link SignStyle#NORMAL}.
      * Otherwise, the sign is output if the pad width is exceeded, as per {@link SignStyle#EXCEEDS_PAD}
      * <p>
-     * <b>ZoneId</b>: 'I' outputs the zone ID, such as 'Europe/Paris'.
+     * <b>ZoneId</b>: This outputs the time-zone ID, such as 'Europe/Paris'.
+     * If the count of letters is two, then the time-zone ID is output.
+     * Any other count of letters throws {@code IllegalArgumentException}.
+     * <pre>
+     *  Pattern     Equivalent builder methods
+     *   VV          appendZoneId()
+     * </pre>
      * <p>
-     * <b>Offset X</b>: This formats the offset using 'Z' when the offset is zero.
-     * One letter outputs just the hour', such as '+01'
+     * <b>Zone names</b>: This outputs the display name of the time-zone ID.
+     * If the count of letters is one, two or three, then the short name is output.
+     * If the count of letters is four, then the full name is output.
+     * Five or more letters throws {@code IllegalArgumentException}.
+     * <pre>
+     *  Pattern     Equivalent builder methods
+     *   z           appendZoneText(TextStyle.SHORT)
+     *   zz          appendZoneText(TextStyle.SHORT)
+     *   zzz         appendZoneText(TextStyle.SHORT)
+     *   zzzz        appendZoneText(TextStyle.FULL)
+     * </pre>
+     * <p>
+     * <b>Offset X and x</b>: This formats the offset based on the number of pattern letters.
+     * One letter outputs just the hour', such as '+01', unless the minute is non-zero
+     * in which case the minute is also output, such as '+0130'.
      * Two letters outputs the hour and minute, without a colon, such as '+0130'.
      * Three letters outputs the hour and minute, with a colon, such as '+01:30'.
      * Four letters outputs the hour and minute and optional second, without a colon, such as '+013015'.
      * Five letters outputs the hour and minute and optional second, with a colon, such as '+01:30:15'.
+     * Six or more letters throws {@code IllegalArgumentException}.
+     * Pattern letter 'X' (upper case) will output 'Z' when the offset to be output would be zero,
+     * whereas pattern letter 'x' (lower case) will output '+00', '+0000', or '+00:00'.
+     * <pre>
+     *  Pattern     Equivalent builder methods
+     *   X           appendOffset("+HHmm","Z")
+     *   XX          appendOffset("+HHMM","Z")
+     *   XXX         appendOffset("+HH:MM","Z")
+     *   XXXX        appendOffset("+HHMMss","Z")
+     *   XXXXX       appendOffset("+HH:MM:ss","Z")
+     *   x           appendOffset("+HHmm","+00")
+     *   xx          appendOffset("+HHMM","+0000")
+     *   xxx         appendOffset("+HH:MM","+00:00")
+     *   xxxx        appendOffset("+HHMMss","+0000")
+     *   xxxxx       appendOffset("+HH:MM:ss","+00:00")
+     * </pre>
      * <p>
-     * <b>Offset Z</b>: This formats the offset using '+0000' or '+00:00' when the offset is zero.
-     * One or two letters outputs the hour and minute, without a colon, such as '+0130'.
-     * Three letters outputs the hour and minute, with a colon, such as '+01:30'.
-     * <p>
-     * <b>Zone names</b>: Time zone names ('z') cannot be parsed.
+     * <b>Offset Z</b>: This formats the offset based on the number of pattern letters.
+     * One, two or three letters outputs the hour and minute, without a colon, such as '+0130'.
+     * Four or more letters throws {@code IllegalArgumentException}.
+     * The output will be '+0000' when the offset is zero.
+     * <pre>
+     *  Pattern     Equivalent builder methods
+     *   Z           appendOffset("+HHMM","+0000")
+     *   ZZ          appendOffset("+HHMM","+0000")
+     *   ZZZ         appendOffset("+HHMM","+0000")
+     * </pre>
      * <p>
      * <b>Optional section</b>: The optional section markers work exactly like calling {@link #optionalStart()}
      * and {@link #optionalEnd()}.
@@ -1058,14 +1245,15 @@
      * Despite this, it is recommended to use single quotes around all characters that you want to
      * output directly to ensure that future changes do not break your application.
      * <p>
-     * The pattern string is similar, but not identical, to {@link java.text.SimpleDateFormat SimpleDateFormat}.
+     * Note that the pattern string is similar, but not identical, to
+     * {@link java.text.SimpleDateFormat SimpleDateFormat}.
+     * The pattern string is also similar, but not identical, to that defined by the
+     * Unicode Common Locale Data Repository (CLDR/LDML).
      * Pattern letters 'E' and 'u' are merged, which changes the meaning of "E" and "EE" to be numeric.
-     * Pattern letters 'Z' and 'X' are extended.
+     * Pattern letters 'X' is aligned with Unicode CLDR/LDML, which affects pattern 'X'.
      * Pattern letter 'y' and 'Y' parse years of two digits and more than 4 digits differently.
      * Pattern letters 'n', 'A', 'N', 'I' and 'p' are added.
      * Number types will reject large numbers.
-     * The pattern string is also similar, but not identical, to that defined by the
-     * Unicode Common Locale Data Repository (CLDR).
      *
      * @param pattern  the pattern to add, not null
      * @return this, for chaining, not null
@@ -1107,27 +1295,34 @@
                 if (field != null) {
                     parseField(cur, count, field);
                 } else if (cur == 'z') {
-                    if (count < 4) {
-                        appendZoneText(TextStyle.SHORT);
-                    } else {
+                    if (count > 4) {
+                        throw new IllegalArgumentException("Too many pattern letters: " + cur);
+                    } else if (count == 4) {
                         appendZoneText(TextStyle.FULL);
+                    } else {
+                        appendZoneText(TextStyle.SHORT);
                     }
-                } else if (cur == 'I') {
+                } else if (cur == 'V') {
+                    if (count != 2) {
+                        throw new IllegalArgumentException("Pattern letter count must be 2: " + cur);
+                    }
                     appendZoneId();
                 } else if (cur == 'Z') {
                     if (count > 3) {
                         throw new IllegalArgumentException("Too many pattern letters: " + cur);
                     }
-                    if (count < 3) {
-                        appendOffset("+HHMM", "+0000");
-                    } else {
-                        appendOffset("+HH:MM", "+00:00");
-                    }
+                    appendOffset("+HHMM", "+0000");
                 } else if (cur == 'X') {
                     if (count > 5) {
                         throw new IllegalArgumentException("Too many pattern letters: " + cur);
                     }
-                    appendOffset(OffsetIdPrinterParser.PATTERNS[count - 1], "Z");
+                    appendOffset(OffsetIdPrinterParser.PATTERNS[count + (count == 1 ? 0 : 1)], "Z");
+                } else if (cur == 'x') {
+                    if (count > 5) {
+                        throw new IllegalArgumentException("Too many pattern letters: " + cur);
+                    }
+                    String zero = (count == 1 ? "+00" : (count % 2 == 0 ? "+0000" : "+00:00"));
+                    appendOffset(OffsetIdPrinterParser.PATTERNS[count + (count == 1 ? 0 : 1)], zero);
                 } else if (cur == 'w' || cur == 'e') {
                     // Fields defined by Locale
                     if (count > 1) {
@@ -1196,7 +1391,6 @@
                     appendValue(field, count, 19, SignStyle.EXCEEDS_PAD);
                 }
                 break;
-            case 'G':
             case 'M':
             case 'Q':
             case 'E':
@@ -1220,6 +1414,7 @@
                         throw new IllegalArgumentException("Too many pattern letters: " + cur);
                 }
                 break;
+            case 'G':
             case 'a':
                 switch (count) {
                     case 1:
@@ -1253,44 +1448,44 @@
     /** Map of letters to fields. */
     private static final Map<Character, TemporalField> FIELD_MAP = new HashMap<>();
     static {
-        FIELD_MAP.put('G', ChronoField.ERA);                       // Java, CLDR (different to both for 1/2 chars)
-        FIELD_MAP.put('y', ChronoField.YEAR);                      // CLDR
-        // FIELD_MAP.put('y', ChronoField.YEAR_OF_ERA);            // Java, CLDR  // TODO redefine from above
-        // FIELD_MAP.put('u', ChronoField.YEAR);                   // CLDR  // TODO
-        // FIELD_MAP.put('Y', ISODateTimeField.WEEK_BASED_YEAR);          // Java7, CLDR (needs localized week number)  // TODO
-        FIELD_MAP.put('Q', ISOFields.QUARTER_OF_YEAR);             // CLDR (removed quarter from 310)
-        FIELD_MAP.put('M', ChronoField.MONTH_OF_YEAR);             // Java, CLDR
-        // FIELD_MAP.put('w', WeekFields.weekOfYear());            // Java, CLDR (needs localized week number)
-        // FIELD_MAP.put('W', WeekFields.weekOfMonth());           // Java, CLDR (needs localized week number)
-        FIELD_MAP.put('D', ChronoField.DAY_OF_YEAR);               // Java, CLDR
-        FIELD_MAP.put('d', ChronoField.DAY_OF_MONTH);              // Java, CLDR
-        FIELD_MAP.put('F', ChronoField.ALIGNED_WEEK_OF_MONTH);     // Java, CLDR
-        FIELD_MAP.put('E', ChronoField.DAY_OF_WEEK);               // Java, CLDR (different to both for 1/2 chars)
-        // FIELD_MAP.put('e', WeekFields.dayOfWeek());             // CLDR (needs localized week number)
-        FIELD_MAP.put('a', ChronoField.AMPM_OF_DAY);               // Java, CLDR
-        FIELD_MAP.put('H', ChronoField.HOUR_OF_DAY);               // Java, CLDR
-        FIELD_MAP.put('k', ChronoField.CLOCK_HOUR_OF_DAY);         // Java, CLDR
-        FIELD_MAP.put('K', ChronoField.HOUR_OF_AMPM);              // Java, CLDR
-        FIELD_MAP.put('h', ChronoField.CLOCK_HOUR_OF_AMPM);        // Java, CLDR
-        FIELD_MAP.put('m', ChronoField.MINUTE_OF_HOUR);            // Java, CLDR
-        FIELD_MAP.put('s', ChronoField.SECOND_OF_MINUTE);          // Java, CLDR
-        FIELD_MAP.put('S', ChronoField.NANO_OF_SECOND);            // CLDR (Java uses milli-of-second number)
-        FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);              // CLDR
-        FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);            // 310
-        FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);               // 310
-        // reserved - z,Z,X,I,p
-        // Java - X - compatible, but extended to 4 and 5 letters
-        // Java - u - clashes with CLDR, go with CLDR (year-proleptic) here
-        // CLDR - U - cycle year name, not supported by 310 yet
-        // CLDR - l - deprecated
-        // CLDR - j - not relevant
-        // CLDR - g - modified-julian-day
-        // CLDR - z - time-zone names  // TODO properly
-        // CLDR - Z - different approach here  // TODO bring 310 in line with CLDR
-        // CLDR - v,V - extended time-zone names
-        // CLDR - q/c/L - standalone quarter/day-of-week/month
-        //  310 - I - time-zone id
-        //  310 - p - prefix for padding
+        FIELD_MAP.put('G', ChronoField.ERA);                       // Java, LDML (different to both for 1/2 chars)
+        FIELD_MAP.put('y', ChronoField.YEAR);                      // LDML
+        // FIELD_MAP.put('y', ChronoField.YEAR_OF_ERA);            // Java, LDML  // TODO redefine from above
+        // FIELD_MAP.put('u', ChronoField.YEAR);                   // LDML  // TODO
+        // FIELD_MAP.put('Y', IsoFields.WEEK_BASED_YEAR);          // Java7, LDML (needs localized week number)  // TODO
+        FIELD_MAP.put('Q', IsoFields.QUARTER_OF_YEAR);             // LDML (removed quarter from 310)
+        FIELD_MAP.put('M', ChronoField.MONTH_OF_YEAR);             // Java, LDML
+        // FIELD_MAP.put('w', WeekFields.weekOfYear());            // Java, LDML (needs localized week number)
+        // FIELD_MAP.put('W', WeekFields.weekOfMonth());           // Java, LDML (needs localized week number)
+        FIELD_MAP.put('D', ChronoField.DAY_OF_YEAR);               // Java, LDML
+        FIELD_MAP.put('d', ChronoField.DAY_OF_MONTH);              // Java, LDML
+        FIELD_MAP.put('F', ChronoField.ALIGNED_WEEK_OF_MONTH);     // Java, LDML
+        FIELD_MAP.put('E', ChronoField.DAY_OF_WEEK);               // Java, LDML (different to both for 1/2 chars)
+        // FIELD_MAP.put('e', WeekFields.dayOfWeek());             // LDML (needs localized week number)
+        FIELD_MAP.put('a', ChronoField.AMPM_OF_DAY);               // Java, LDML
+        FIELD_MAP.put('H', ChronoField.HOUR_OF_DAY);               // Java, LDML
+        FIELD_MAP.put('k', ChronoField.CLOCK_HOUR_OF_DAY);         // Java, LDML
+        FIELD_MAP.put('K', ChronoField.HOUR_OF_AMPM);              // Java, LDML
+        FIELD_MAP.put('h', ChronoField.CLOCK_HOUR_OF_AMPM);        // Java, LDML
+        FIELD_MAP.put('m', ChronoField.MINUTE_OF_HOUR);            // Java, LDML
+        FIELD_MAP.put('s', ChronoField.SECOND_OF_MINUTE);          // Java, LDML
+        FIELD_MAP.put('S', ChronoField.NANO_OF_SECOND);            // LDML (Java uses milli-of-second number)
+        FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);              // LDML
+        FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);            // 310 (proposed for LDML)
+        FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);               // 310 (proposed for LDML)
+        // 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4
+        // 310 - Z - matches SimpleDateFormat and LDML
+        // 310 - V - time-zone id, matches proposed LDML
+        // 310 - p - prefix for padding
+        // 310 - X - matches proposed LDML, almost matches JavaSDF for 1, exact match 2&3, extended 4&5
+        // 310 - x - matches proposed LDML
+        // Java - u - clashes with LDML, go with LDML (year-proleptic) here
+        // LDML - U - cycle year name, not supported by 310 yet
+        // LDML - l - deprecated
+        // LDML - j - not relevant
+        // LDML - g - modified-julian-day
+        // LDML - v,V - extended time-zone names
+        // LDML - q/c/L - standalone quarter/day-of-week/month
     }
 
     //-----------------------------------------------------------------------
@@ -1299,8 +1494,15 @@
      * <p>
      * This padding will pad to a fixed width using spaces.
      * <p>
-     * An exception will be thrown during printing if the pad width
-     * is exceeded.
+     * During formatting, the decorated element will be output and then padded
+     * to the specified width. An exception will be thrown during formatting if
+     * the pad width is exceeded.
+     * <p>
+     * During parsing, the padding and decorated element are parsed.
+     * If parsing is lenient, then the pad width is treated as a maximum.
+     * If parsing is case insensitive, then the pad character is matched ignoring case.
+     * The padding is parsed greedily. Thus, if the decorated element starts with
+     * the pad character, it will not be parsed.
      *
      * @param padWidth  the pad width, 1 or greater
      * @return this, for chaining, not null
@@ -1316,8 +1518,15 @@
      * This padding is intended for padding other than zero-padding.
      * Zero-padding should be achieved using the appendValue methods.
      * <p>
-     * An exception will be thrown during printing if the pad width
-     * is exceeded.
+     * During formatting, the decorated element will be output and then padded
+     * to the specified width. An exception will be thrown during formatting if
+     * the pad width is exceeded.
+     * <p>
+     * During parsing, the padding and decorated element are parsed.
+     * If parsing is lenient, then the pad width is treated as a maximum.
+     * If parsing is case insensitive, then the pad character is matched ignoring case.
+     * The padding is parsed greedily. Thus, if the decorated element starts with
+     * the pad character, it will not be parsed.
      *
      * @param padWidth  the pad width, 1 or greater
      * @param padChar  the pad character
@@ -1338,19 +1547,19 @@
     /**
      * Mark the start of an optional section.
      * <p>
-     * The output of printing can include optional sections, which may be nested.
+     * The output of formatting can include optional sections, which may be nested.
      * An optional section is started by calling this method and ended by calling
      * {@link #optionalEnd()} or by ending the build process.
      * <p>
      * All elements in the optional section are treated as optional.
-     * During printing, the section is only output if data is available in the
+     * During formatting, the section is only output if data is available in the
      * {@code TemporalAccessor} for all the elements in the section.
      * During parsing, the whole section may be missing from the parsed string.
      * <p>
      * For example, consider a builder setup as
      * {@code builder.appendValue(HOUR_OF_DAY,2).optionalStart().appendValue(MINUTE_OF_HOUR,2)}.
      * The optional section ends automatically at the end of the builder.
-     * During printing, the minute will only be output if its value can be obtained from the date-time.
+     * During formatting, the minute will only be output if its value can be obtained from the date-time.
      * During parsing, the input will be successfully parsed whether the minute is present or not.
      *
      * @return this, for chaining, not null
@@ -1364,7 +1573,7 @@
     /**
      * Ends an optional section.
      * <p>
-     * The output of printing can include optional sections, which may be nested.
+     * The output of formatting can include optional sections, which may be nested.
      * An optional section is started by calling {@link #optionalStart()} and ended
      * using this method (or at the end of the builder).
      * <p>
@@ -1374,13 +1583,13 @@
      * on the formatter other than ending the (empty) optional section.
      * <p>
      * All elements in the optional section are treated as optional.
-     * During printing, the section is only output if data is available in the
+     * During formatting, the section is only output if data is available in the
      * {@code TemporalAccessor} for all the elements in the section.
      * During parsing, the whole section may be missing from the parsed string.
      * <p>
      * For example, consider a builder setup as
      * {@code builder.appendValue(HOUR_OF_DAY,2).optionalStart().appendValue(MINUTE_OF_HOUR,2).optionalEnd()}.
-     * During printing, the minute will only be output if its value can be obtained from the date-time.
+     * During formatting, the minute will only be output if its value can be obtained from the date-time.
      * During parsing, the input will be successfully parsed whether the minute is present or not.
      *
      * @return this, for chaining, not null
@@ -1466,18 +1675,17 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Strategy for printing/parsing date-time information.
+     * Strategy for formatting/parsing date-time information.
      * <p>
-     * The printer may print any part, or the whole, of the input date-time object.
-     * Typically, a complete print is constructed from a number of smaller
+     * The printer may format any part, or the whole, of the input date-time object.
+     * Typically, a complete format is constructed from a number of smaller
      * units, each outputting a single field.
      * <p>
      * The parser may parse any piece of text from the input, storing the result
      * in the context. Typically, each individual parser will just parse one
      * field, such as the day-of-month, storing the value in the context.
-     * Once the parse is complete, the caller will then convert the context
-     * to a {@link DateTimeBuilder} to merge the parsed values to create the
-     * desired object, such as a {@code LocalDate}.
+     * Once the parse is complete, the caller will then resolve the parsed values
+     * to create the desired object, such as a {@code LocalDate}.
      * <p>
      * The parse position will be updated during the parse. Parsing will start at
      * the specified index and the return value specifies the new parse position
@@ -1489,7 +1697,7 @@
      * All implementations that can be instantiated must be final, immutable and thread-safe.
      * <p>
      * The context is not a thread-safe object and a new instance will be created
-     * for each print that occurs. The context must not be stored in an instance
+     * for each format that occurs. The context must not be stored in an instance
      * variable or shared with any other threads.
      */
     interface DateTimePrinterParser {
@@ -1497,17 +1705,17 @@
         /**
          * Prints the date-time object to the buffer.
          * <p>
-         * The context holds information to use during the print.
+         * The context holds information to use during the format.
          * It also contains the date-time information to be printed.
          * <p>
          * The buffer must not be mutated beyond the content controlled by the implementation.
          *
-         * @param context  the context to print using, not null
+         * @param context  the context to format using, not null
          * @param buf  the buffer to append to, not null
          * @return false if unable to query the value from the date-time, true otherwise
          * @throws DateTimeException if the date-time cannot be printed successfully
          */
-        boolean print(DateTimePrintContext context, StringBuilder buf);
+        boolean format(DateTimePrintContext context, StringBuilder buf);
 
         /**
          * Parses text into date-time information.
@@ -1557,14 +1765,14 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             int length = buf.length();
             if (optional) {
                 context.startOptional();
             }
             try {
                 for (DateTimePrinterParser pp : printerParsers) {
-                    if (pp.print(context, buf) == false) {
+                    if (pp.format(context, buf) == false) {
                         buf.setLength(length);  // reset buffer
                         return true;
                     }
@@ -1640,14 +1848,14 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             int preLen = buf.length();
-            if (printerParser.print(context, buf) == false) {
+            if (printerParser.format(context, buf) == false) {
                 return false;
             }
             int len = buf.length() - preLen;
             if (len > padWidth) {
-                throw new DateTimePrintException(
+                throw new DateTimeException(
                     "Cannot print as output of " + len + " characters exceeds pad width of " + padWidth);
             }
             for (int i = 0; i < padWidth - len; i++) {
@@ -1658,37 +1866,32 @@
 
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
+            // cache context before changed by decorated parser
+            final boolean strict = context.isStrict();
+            // parse
             if (position > text.length()) {
                 throw new IndexOutOfBoundsException();
             }
+            if (position == text.length()) {
+                return ~position;  // no more characters in the string
+            }
             int endPos = position + padWidth;
             if (endPos > text.length()) {
-                return ~position;  // not enough characters in the string to meet the parse width
+                if (strict) {
+                    return ~position;  // not enough characters in the string to meet the parse width
+                }
+                endPos = text.length();
             }
             int pos = position;
-            while (pos < endPos && text.charAt(pos) == padChar) {
+            while (pos < endPos && context.charEquals(text.charAt(pos), padChar)) {
                 pos++;
             }
             text = text.subSequence(0, endPos);
-            int firstError = 0;
-            while (pos >= position) {
-                int resultPos = printerParser.parse(context, text, pos);
-                if (resultPos < 0) {
-                    // parse of decorated field had an error
-                    if (firstError == 0) {
-                        firstError = resultPos;
-                    }
-                    // loop around in case the decorated parser can handle the padChar at the start
-                    pos--;
-                    continue;
-                }
-                if (resultPos != endPos) {
-                    return ~position;  // parse of decorated field didn't parse to the end
-                }
-                return resultPos;
+            int resultPos = printerParser.parse(context, text, pos);
+            if (resultPos != endPos && strict) {
+                return ~(position + pos);  // parse of decorated field didn't parse to the end
             }
-            // loop runs at least once, so firstError must be set by the time we get here
-            return firstError;  // return error from first parse of decorated field
+            return resultPos;
         }
 
         @Override
@@ -1708,7 +1911,7 @@
         LENIENT;
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             return true;  // nothing to do here
         }
 
@@ -1749,7 +1952,7 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             buf.append(literal);
             return true;
         }
@@ -1792,7 +1995,7 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             buf.append(literal);
             return true;
         }
@@ -1847,7 +2050,7 @@
         /**
          * Constructor.
          *
-         * @param field  the field to print, not null
+         * @param field  the field to format, not null
          * @param minWidth  the minimum field width, from 1 to 19
          * @param maxWidth  the maximum field width, from minWidth to 19
          * @param signStyle  the positive/negative sign style, not null
@@ -1864,7 +2067,7 @@
         /**
          * Constructor.
          *
-         * @param field  the field to print, not null
+         * @param field  the field to format, not null
          * @param minWidth  the minimum field width, from 1 to 19
          * @param maxWidth  the maximum field width, from minWidth to 19
          * @param signStyle  the positive/negative sign style, not null
@@ -1900,8 +2103,14 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
-            Long valueLong = context.getValue(field);
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
+            Chronology chrono = context.getTemporal().query(Queries.chronology());
+            Long valueLong;
+            if (chrono == JapaneseChronology.INSTANCE && field == ChronoField.YEAR) {
+                valueLong = context.getValue(ChronoField.YEAR_OF_ERA);
+            } else {
+                valueLong = context.getValue(field);
+            }
             if (valueLong == null) {
                 return false;
             }
@@ -1909,7 +2118,7 @@
             DateTimeFormatSymbols symbols = context.getSymbols();
             String str = (value == Long.MIN_VALUE ? "9223372036854775808" : Long.toString(Math.abs(value)));
             if (str.length() > maxWidth) {
-                throw new DateTimePrintException("Field " + field.getName() +
+                throw new DateTimeException("Field " + field.getName() +
                     " cannot be printed as the value " + value +
                     " exceeds the maximum print width of " + maxWidth);
             }
@@ -1934,7 +2143,7 @@
                         buf.append(symbols.getNegativeSign());
                         break;
                     case NOT_NEGATIVE:
-                        throw new DateTimePrintException("Field " + field.getName() +
+                        throw new DateTimeException("Field " + field.getName() +
                             " cannot be printed as the value " + value +
                             " cannot be negative according to the SignStyle");
                 }
@@ -2057,11 +2266,9 @@
                     totalBig = totalBig.divide(BigInteger.TEN);
                     pos--;
                 }
-                setValue(context, totalBig.longValue());
-            } else {
-                setValue(context, total);
+                return setValue(context, totalBig.longValue(), position, pos);
             }
-            return pos;
+            return setValue(context, total, position, pos);
         }
 
         /**
@@ -2069,9 +2276,19 @@
          *
          * @param context  the context to store into, not null
          * @param value  the value
+         * @param errorPos  the position of the field being parsed
+         * @param successPos  the position after the field being parsed
+         * @return the new position
          */
-        void setValue(DateTimeParseContext context, long value) {
-            context.setParsedField(field, value);
+        int setValue(DateTimeParseContext context, long value, int errorPos, int successPos) {
+            TemporalField f = field;
+            if (field == ChronoField.YEAR) {
+                Chronology chrono = context.getEffectiveChronology();
+                if (chrono == JapaneseChronology.INSTANCE) {
+                    f = ChronoField.YEAR_OF_ERA;
+                }
+            }
+            return context.setParsedField(f, value, errorPos, successPos);
         }
 
         @Override
@@ -2097,7 +2314,7 @@
         /**
          * Constructor.
          *
-         * @param field  the field to print, validated not null
+         * @param field  the field to format, validated not null
          * @param width  the field width, from 1 to 18
          * @param baseValue  the base value
          */
@@ -2122,7 +2339,7 @@
         }
 
         @Override
-        void setValue(DateTimeParseContext context, long value) {
+        int setValue(DateTimeParseContext context, long value, int errorPos, int successPos) {
             int lastPart = baseValue % range;
             if (baseValue > 0) {
                 value = baseValue - lastPart + value;
@@ -2132,7 +2349,7 @@
             if (value < baseValue) {
                 value += range;
             }
-            context.setParsedField(field, value);
+            return context.setParsedField(field, value, errorPos, successPos);
         }
 
         @Override
@@ -2191,7 +2408,7 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             Long value = context.getValue(field);
             if (value == null) {
                 return false;
@@ -2257,8 +2474,7 @@
             }
             BigDecimal fraction = new BigDecimal(total).movePointLeft(pos - position);
             long value = convertFromFraction(fraction);
-            context.setParsedField(field, value);
-            return pos;
+            return context.setParsedField(field, value, position, pos);
         }
 
         /**
@@ -2348,23 +2564,20 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             Long value = context.getValue(field);
             if (value == null) {
                 return false;
             }
-            String text = null;
-            if (field == ChronoField.ERA) {
-                Chrono chrono = context.getTemporal().query(Queries.chrono());
-                if (chrono == null) {
-                    chrono = ISOChrono.INSTANCE;
-                }
-                text = provider.getEraText(chrono, value, textStyle, context.getLocale());
-            } else {
+            String text;
+            Chronology chrono = context.getTemporal().query(Queries.chronology());
+            if (chrono == null || chrono == IsoChronology.INSTANCE) {
                 text = provider.getText(field, value, textStyle, context.getLocale());
+            } else {
+                text = provider.getText(chrono, field, value, textStyle, context.getLocale());
             }
             if (text == null) {
-                return numberPrinterParser().print(context, buf);
+                return numberPrinterParser().format(context, buf);
             }
             buf.append(text);
             return true;
@@ -2377,14 +2590,19 @@
                 throw new IndexOutOfBoundsException();
             }
             TextStyle style = (context.isStrict() ? textStyle : null);
-            Iterator<Entry<String, Long>> it = provider.getTextIterator(field, style, context.getLocale());
+            Chronology chrono = context.getEffectiveChronology();
+            Iterator<Entry<String, Long>> it;
+            if (chrono == null || chrono == IsoChronology.INSTANCE) {
+                it = provider.getTextIterator(field, style, context.getLocale());
+            } else {
+                it = provider.getTextIterator(chrono, field, style, context.getLocale());
+            }
             if (it != null) {
                 while (it.hasNext()) {
                     Entry<String, Long> entry = it.next();
                     String itText = entry.getKey();
                     if (context.subSequenceEquals(itText, 0, parseText, position, itText.length())) {
-                        context.setParsedField(field, entry.getValue());
-                        return position + itText.length();
+                        return context.setParsedField(field, entry.getValue(), position, position + itText.length());
                     }
                 }
                 if (context.isStrict()) {
@@ -2426,15 +2644,15 @@
         private static final long SECONDS_0000_TO_1970 = ((146097L * 5L) - (30L * 365L + 7L)) * 86400L;
         private static final CompositePrinterParser PARSER = new DateTimeFormatterBuilder()
                     .parseCaseInsensitive()
-                    .append(DateTimeFormatters.isoLocalDate()).appendLiteral('T')
-                    .append(DateTimeFormatters.isoLocalTime()).appendLiteral('Z')
+                    .append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T')
+                    .append(DateTimeFormatter.ISO_LOCAL_TIME).appendLiteral('Z')
                     .toFormatter().toPrinterParser(false);
 
         InstantPrinterParser() {
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             // use INSTANT_SECONDS, thus this code is not bound by Instant.MAX
             Long inSecs = context.getValue(INSTANT_SECONDS);
             Long inNanos = context.getValue(NANO_OF_SECOND);
@@ -2502,9 +2720,9 @@
             } catch (RuntimeException ex) {
                 return ~position;
             }
-            context.setParsedField(INSTANT_SECONDS, instantSecs);
-            context.setParsedField(NANO_OF_SECOND, nano);
-            return text.length();
+            int successPos = text.length();
+            successPos = context.setParsedField(INSTANT_SECONDS, instantSecs, position, successPos);
+            return context.setParsedField(NANO_OF_SECOND, nano, position, successPos);
         }
 
         @Override
@@ -2519,9 +2737,10 @@
      */
     static final class OffsetIdPrinterParser implements DateTimePrinterParser {
         static final String[] PATTERNS = new String[] {
-            "+HH", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
+            "+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
         };  // order used in pattern builder
-        static final OffsetIdPrinterParser INSTANCE_ID = new OffsetIdPrinterParser("Z", "+HH:MM:ss");
+        static final OffsetIdPrinterParser INSTANCE_ID_Z = new OffsetIdPrinterParser("+HH:MM:ss", "Z");
+        static final OffsetIdPrinterParser INSTANCE_ID_ZERO = new OffsetIdPrinterParser("+HH:MM:ss", "0");
 
         private final String noOffsetText;
         private final int type;
@@ -2529,14 +2748,14 @@
         /**
          * Constructor.
          *
-         * @param noOffsetText  the text to use for UTC, not null
          * @param pattern  the pattern
+         * @param noOffsetText  the text to use for UTC, not null
          */
-        OffsetIdPrinterParser(String noOffsetText, String pattern) {
-            Objects.requireNonNull(noOffsetText, "noOffsetText");
+        OffsetIdPrinterParser(String pattern, String noOffsetText) {
             Objects.requireNonNull(pattern, "pattern");
-            this.noOffsetText = noOffsetText;
+            Objects.requireNonNull(noOffsetText, "noOffsetText");
             this.type = checkPattern(pattern);
+            this.noOffsetText = noOffsetText;
         }
 
         private int checkPattern(String pattern) {
@@ -2549,7 +2768,7 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             Long offsetSecs = context.getValue(OFFSET_SECONDS);
             if (offsetSecs == null) {
                 return false;
@@ -2561,16 +2780,24 @@
                 int absHours = Math.abs((totalSecs / 3600) % 100);  // anything larger than 99 silently dropped
                 int absMinutes = Math.abs((totalSecs / 60) % 60);
                 int absSeconds = Math.abs(totalSecs % 60);
+                int bufPos = buf.length();
+                int output = absHours;
                 buf.append(totalSecs < 0 ? "-" : "+")
                     .append((char) (absHours / 10 + '0')).append((char) (absHours % 10 + '0'));
-                if (type >= 1) {
+                if (type >= 3 || (type >= 1 && absMinutes > 0)) {
                     buf.append((type % 2) == 0 ? ":" : "")
                         .append((char) (absMinutes / 10 + '0')).append((char) (absMinutes % 10 + '0'));
-                    if (type >= 5 || (type >= 3 && absSeconds > 0)) {
+                    output += absMinutes;
+                    if (type >= 7 || (type >= 5 && absSeconds > 0)) {
                         buf.append((type % 2) == 0 ? ":" : "")
                             .append((char) (absSeconds / 10 + '0')).append((char) (absSeconds % 10 + '0'));
+                        output += absSeconds;
                     }
                 }
+                if (output == 0) {
+                    buf.setLength(bufPos);
+                    buf.append(noOffsetText);
+                }
             }
             return true;
         }
@@ -2581,16 +2808,14 @@
             int noOffsetLen = noOffsetText.length();
             if (noOffsetLen == 0) {
                 if (position == length) {
-                    context.setParsedField(OFFSET_SECONDS, 0);
-                    return position;
+                    return context.setParsedField(OFFSET_SECONDS, 0, position, position);
                 }
             } else {
                 if (position == length) {
                     return ~position;
                 }
                 if (context.subSequenceEquals(text, position, noOffsetText, 0, noOffsetLen)) {
-                    context.setParsedField(OFFSET_SECONDS, 0);
-                    return position + noOffsetLen;
+                    return context.setParsedField(OFFSET_SECONDS, 0, position, position + noOffsetLen);
                 }
             }
 
@@ -2601,22 +2826,19 @@
                 int negative = (sign == '-' ? -1 : 1);
                 int[] array = new int[4];
                 array[0] = position + 1;
-                if (parseNumber(array, 1, text, true) ||
-                        parseNumber(array, 2, text, type > 0) ||
-                        parseNumber(array, 3, text, false)) {
-                    return ~position;
+                if ((parseNumber(array, 1, text, true) ||
+                        parseNumber(array, 2, text, type >=3) ||
+                        parseNumber(array, 3, text, false)) == false) {
+                    // success
+                    long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
+                    return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]);
                 }
-                long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
-                context.setParsedField(OFFSET_SECONDS, offsetSecs);
-                return array[0];
-            } else {
-                // handle special case of empty no offset text
-                if (noOffsetLen == 0) {
-                    context.setParsedField(OFFSET_SECONDS, 0);
-                    return position + noOffsetLen;
-                }
-                return ~position;
             }
+            // handle special case of empty no offset text
+            if (noOffsetLen == 0) {
+                return context.setParsedField(OFFSET_SECONDS, 0, position, position + noOffsetLen);
+            }
+            return ~position;
         }
 
         /**
@@ -2659,7 +2881,7 @@
         @Override
         public String toString() {
             String converted = noOffsetText.replace("'", "''");
-            return "Offset('" + converted + "'," + PATTERNS[type] + ")";
+            return "Offset(" + PATTERNS[type] + ",'" + converted + "')";
         }
     }
 
@@ -2667,29 +2889,38 @@
     /**
      * Prints or parses a zone ID.
      */
-    static final class ZoneTextPrinterParser implements DateTimePrinterParser {
+    static final class ZoneTextPrinterParser extends ZoneIdPrinterParser {
 
         /** The text style to output. */
         private final TextStyle textStyle;
 
-        ZoneTextPrinterParser(TextStyle textStyle) {
+        /** The preferred zoneid map */
+        private Set<String> preferredZones;
+
+        ZoneTextPrinterParser(TextStyle textStyle, Set<ZoneId> preferredZones) {
+            super(Queries.zone(), "ZoneText(" + textStyle + ")");
             this.textStyle = Objects.requireNonNull(textStyle, "textStyle");
+            if (preferredZones != null && preferredZones.size() != 0) {
+                this.preferredZones = new HashSet<>();
+                for (ZoneId id : preferredZones) {
+                    this.preferredZones.add(id.getId());
+                }
+            }
         }
 
         private static final int STD = 0;
         private static final int DST = 1;
         private static final int GENERIC = 2;
-
         private static final Map<String, SoftReference<Map<Locale, String[]>>> cache =
             new ConcurrentHashMap<>();
 
-        private static String getDisplayName(String id, int type, TextStyle style, Locale locale) {
-            if (style == TextStyle.NARROW) {
+        private String getDisplayName(String id, int type, Locale locale) {
+            if (textStyle == TextStyle.NARROW) {
                 return null;
             }
             String[] names;
             SoftReference<Map<Locale, String[]>> ref = cache.get(id);
-            Map<Locale, String[]> perLocale;
+            Map<Locale, String[]> perLocale = null;
             if (ref == null || (perLocale = ref.get()) == null ||
                 (names = perLocale.get(locale)) == null) {
                 names = TimeZoneNameUtility.retrieveDisplayNames(id, locale);
@@ -2707,55 +2938,99 @@
                 if (names[6] == null) {
                     names[6] = names[0];
                 }
-                perLocale = new ConcurrentHashMap<>();
+                if (perLocale == null) {
+                    perLocale = new ConcurrentHashMap<>();
+                }
                 perLocale.put(locale, names);
-                ref = new SoftReference<>(perLocale);
-                cache.put(id, ref);
+                cache.put(id, new SoftReference<>(perLocale));
             }
             switch (type) {
             case STD:
-                return names[style.ordinal() + 1];
+                return names[textStyle.ordinal() + 1];
             case DST:
-                return names[style.ordinal() + 3];
+                return names[textStyle.ordinal() + 3];
             }
-            return names[style.ordinal() + 5];
+            return names[textStyle.ordinal() + 5];
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             ZoneId zone = context.getValue(Queries.zoneId());
             if (zone == null) {
                 return false;
             }
-            if (zone instanceof ZoneOffset) {
-                buf.append(zone.getId());
-            } else {
+            String zname = zone.getId();
+            if (!(zone instanceof ZoneOffset)) {
                 TemporalAccessor dt = context.getTemporal();
-                Instant instant = null;
-                if (dt.isSupported(ChronoField.INSTANT_SECONDS)) {
-                    instant = Instant.from(dt);
-                }
-                String name = getDisplayName(zone.getId(),
-                                             instant == null ? GENERIC
-                                                             : (zone.getRules().isDaylightSavings(instant) ? DST : STD),
-                    textStyle, context.getLocale());
+                String name = getDisplayName(zname,
+                                             dt.isSupported(ChronoField.INSTANT_SECONDS)
+                                             ? (zone.getRules().isDaylightSavings(Instant.from(dt)) ? DST : STD)
+                                             : GENERIC,
+                                             context.getLocale());
                 if (name != null) {
-                    buf.append(name);
-                } else {
-                    buf.append(zone.getId());
+                    zname = name;
                 }
             }
+            buf.append(zname);
             return true;
         }
 
-        @Override
-        public int parse(DateTimeParseContext context, CharSequence text, int position) {
-            throw new UnsupportedOperationException();
-        }
+        // cache per instance for now
+        private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
+            cachedTree = new HashMap<>();
+        private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
+            cachedTreeCI = new HashMap<>();
 
         @Override
-        public String toString() {
-            return "ZoneText(" + textStyle + ")";
+        protected PrefixTree getTree(DateTimeParseContext context) {
+            if (textStyle == TextStyle.NARROW) {
+                return super.getTree(context);
+            }
+            Locale locale = context.getLocale();
+            boolean isCaseSensitive = context.isCaseSensitive();
+            Set<String> regionIds = ZoneRulesProvider.getAvailableZoneIds();
+            int regionIdsSize = regionIds.size();
+
+            Map<Locale, Entry<Integer, SoftReference<PrefixTree>>> cached =
+                isCaseSensitive ? cachedTree : cachedTreeCI;
+
+            Entry<Integer, SoftReference<PrefixTree>> entry = null;
+            PrefixTree tree = null;
+            String[][] zoneStrings = null;
+            if ((entry = cached.get(locale)) == null ||
+                (entry.getKey() != regionIdsSize ||
+                (tree = entry.getValue().get()) == null)) {
+                tree = PrefixTree.newTree(context);
+                zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
+                for (String[] names : zoneStrings) {
+                    String zid = names[0];
+                    if (!regionIds.contains(zid)) {
+                        continue;
+                    }
+                    tree.add(zid, zid);    // don't convert zid -> metazone
+                    zid = ZoneName.toZid(zid, locale);
+                    int i = textStyle == TextStyle.FULL ? 1 : 2;
+                    for (; i < names.length; i += 2) {
+                        tree.add(names[i], zid);
+                    }
+                }
+                // if we have a set of preferred zones, need a copy and
+                // add the preferred zones again to overwrite
+                if (preferredZones != null) {
+                    for (String[] names : zoneStrings) {
+                        String zid = names[0];
+                        if (!preferredZones.contains(zid) || !regionIds.contains(zid)) {
+                            continue;
+                        }
+                        int i = textStyle == TextStyle.FULL ? 1 : 2;
+                        for (; i < names.length; i += 2) {
+                            tree.add(names[i], zid);
+                       }
+                    }
+                }
+                cached.put(locale, new SimpleImmutableEntry<>(regionIdsSize, new SoftReference<>(tree)));
+            }
+            return tree;
         }
     }
 
@@ -2763,7 +3038,7 @@
     /**
      * Prints or parses a zone ID.
      */
-    static final class ZoneIdPrinterParser implements DateTimePrinterParser {
+    static class ZoneIdPrinterParser implements DateTimePrinterParser {
         private final TemporalQuery<ZoneId> query;
         private final String description;
 
@@ -2772,9 +3047,8 @@
             this.description = description;
         }
 
-        //-----------------------------------------------------------------------
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
             ZoneId zone = context.getValue(query);
             if (zone == null) {
                 return false;
@@ -2783,13 +3057,34 @@
             return true;
         }
 
-        //-----------------------------------------------------------------------
         /**
          * The cached tree to speed up parsing.
          */
         private static volatile Entry<Integer, PrefixTree> cachedPrefixTree;
         private static volatile Entry<Integer, PrefixTree> cachedPrefixTreeCI;
 
+        protected PrefixTree getTree(DateTimeParseContext context) {
+            // prepare parse tree
+            Set<String> regionIds = ZoneRulesProvider.getAvailableZoneIds();
+            final int regionIdsSize = regionIds.size();
+            Entry<Integer, PrefixTree> cached = context.isCaseSensitive()
+                                                ? cachedPrefixTree : cachedPrefixTreeCI;
+            if (cached == null || cached.getKey() != regionIdsSize) {
+                synchronized (this) {
+                    cached = context.isCaseSensitive() ? cachedPrefixTree : cachedPrefixTreeCI;
+                    if (cached == null || cached.getKey() != regionIdsSize) {
+                        cached = new SimpleImmutableEntry<>(regionIdsSize, PrefixTree.newTree(regionIds, context));
+                        if (context.isCaseSensitive()) {
+                            cachedPrefixTree = cached;
+                        } else {
+                            cachedPrefixTreeCI = cached;
+                        }
+                    }
+                }
+            }
+            return cached.getValue();
+        }
+
         /**
          * This implementation looks for the longest matching string.
          * For example, parsing Etc/GMT-2 will return Etc/GMC-2 rather than just
@@ -2801,58 +3096,57 @@
             if (position > length) {
                 throw new IndexOutOfBoundsException();
             }
+            if (position == length) {
+                return ~position;
+            }
 
             // handle fixed time-zone IDs
-            if ((text.length() - position) >= 1) {
-                char nextChar = text.charAt(position);
-                if (nextChar == '+' || nextChar == '-') {
-                    DateTimeParseContext newContext = context.copy();
-                    int endPos = OffsetIdPrinterParser.INSTANCE_ID.parse(newContext, text, position);
-                    if (endPos < 0) {
-                        return endPos;
+            char nextChar = text.charAt(position);
+            if (nextChar == '+' || nextChar == '-') {
+                return parseOffsetBased(context, text, position, OffsetIdPrinterParser.INSTANCE_ID_Z);
+            } else if (length >= position + 2) {
+                char nextNextChar = text.charAt(position + 1);
+                if (context.charEquals(nextChar, 'U') && context.charEquals(nextNextChar, 'T')) {
+                    if (length >= position + 3 && context.charEquals(text.charAt(position + 2), 'C')) {
+                        return parseOffsetBased(context, text, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO);
                     }
-                    int offset = (int) (long) newContext.getParsed(OFFSET_SECONDS);
-                    ZoneId zone = ZoneOffset.ofTotalSeconds(offset);
-                    context.setParsed(zone);
-                    return endPos;
+                    return parseOffsetBased(context, text, position + 2, OffsetIdPrinterParser.INSTANCE_ID_ZERO);
+                } else if (context.charEquals(nextChar, 'G') && length >= position + 3 &&
+                        context.charEquals(nextNextChar, 'M') && context.charEquals(text.charAt(position + 2), 'T')) {
+                    return parseOffsetBased(context, text, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO);
                 }
             }
 
-            // prepare parse tree
-            Set<String> regionIds = ZoneRulesProvider.getAvailableZoneIds();
-            final int regionIdsSize = regionIds.size();
-            Entry<Integer, PrefixTree> cached = context.isCaseSensitive()
-                                                ? cachedPrefixTree : cachedPrefixTreeCI;
-            if (cached == null || cached.getKey() != regionIdsSize) {
-                synchronized (this) {
-                    cached = context.isCaseSensitive() ? cachedPrefixTree : cachedPrefixTreeCI;
-                    if (cached == null || cached.getKey() != regionIdsSize) {
-                        cached = new SimpleImmutableEntry<>(regionIdsSize,
-                            PrefixTree.newTree(regionIds, context.isCaseSensitive()
-                                                          ? PrefixTree.STRICT : PrefixTree.CASE_INSENSITIVE));
-                        if (context.isCaseSensitive()) {
-                            cachedPrefixTree = cached;
-                        } else {
-                            cachedPrefixTreeCI = cached;
-                        }
-                    }
-                }
-            }
-            PrefixTree tree = cached.getValue();
-
             // parse
-            String parsedZoneId = tree.match(text, position, length);
-            if (parsedZoneId == null || regionIds.contains(parsedZoneId) == false) {
-                if (text.charAt(position) == 'Z') {
+            PrefixTree tree = getTree(context);
+            ParsePosition ppos = new ParsePosition(position);
+            String parsedZoneId = tree.match(text, ppos);
+            if (parsedZoneId == null) {
+                if (context.charEquals(nextChar, 'Z')) {
                     context.setParsed(ZoneOffset.UTC);
                     return position + 1;
                 }
                 return ~position;
             }
             context.setParsed(ZoneId.of(parsedZoneId));
-            return position + parsedZoneId.length();
+            return ppos.getIndex();
         }
 
+        private int parseOffsetBased(DateTimeParseContext context, CharSequence text, int position, OffsetIdPrinterParser parser) {
+            DateTimeParseContext newContext = context.copy();
+            int endPos = parser.parse(newContext, text, position);
+            if (endPos < 0) {
+                if (parser == OffsetIdPrinterParser.INSTANCE_ID_Z) {
+                    return ~position;
+                }
+                context.setParsed(ZoneOffset.UTC);
+                return position;
+            }
+            int offset = (int) newContext.getParsed(OFFSET_SECONDS).longValue();
+            ZoneId zone = ZoneOffset.ofTotalSeconds(offset);
+            context.setParsed(zone);
+            return endPos;
+        }
 
         @Override
         public String toString() {
@@ -2872,10 +3166,6 @@
         protected PrefixTree child;
         protected PrefixTree sibling;
 
-        static final int STRICT = 1;
-        static final int CASE_INSENSITIVE = 2;
-        static final int LENIENT = 3;
-
         private PrefixTree(String k, String v, PrefixTree child) {
             this.key = k;
             this.value = v;
@@ -2888,40 +3178,30 @@
         }
 
         /**
-         * Creates a new prefix parsing tree.
+         * Creates a new prefix parsing tree based on parse context.
          *
-         * @param type  the type of the prefix tree. One of the three supported
-         *  types, STRICT, CASE_INSENSITIVE and LENIENT
+         * @param context  the parse context
          * @return the tree, not null
          */
-        public static PrefixTree newTree(int type) {
-            PrefixTree tree;
-            switch(type) {
-                case STRICT:
-                    tree = new PrefixTree("", null, null);
-                    break;
-                case CASE_INSENSITIVE:
-                    tree = new CI("", null, null);
-                    break;
-                case LENIENT:
-                    tree = new LENIENT("", null, null);
-                    break;
-                default:
-                    throw new IllegalArgumentException("Unknown type");
+        public static PrefixTree newTree(DateTimeParseContext context) {
+            //if (!context.isStrict()) {
+            //    return new LENIENT("", null, null);
+            //}
+            if (context.isCaseSensitive()) {
+                return new PrefixTree("", null, null);
             }
-            return tree;
+            return new CI("", null, null);
         }
 
         /**
          * Creates a new prefix parsing tree.
          *
          * @param keys  a set of strings to build the prefix parsing tree, not null
-         * @param type  the type of the prefix tree. One of the three supported
-         *  types, STRICT, CASE_INSENSITIVE and LENIENT
+         * @param context  the parse context
          * @return the tree, not null
          */
-        public static  PrefixTree newTree(Set<String> keys, int type) {
-            PrefixTree tree = newTree(type);
+        public static  PrefixTree newTree(Set<String> keys, DateTimeParseContext context) {
+            PrefixTree tree = newTree(context);
             for (String k : keys) {
                 tree.add0(k, k);
             }
@@ -2929,6 +3209,21 @@
         }
 
         /**
+         * Clone a copy of this tree
+         */
+        public PrefixTree copyTree() {
+            PrefixTree copy = new PrefixTree(key, value, null);
+            if (child != null) {
+                copy.child = child.copyTree();
+            }
+            if (sibling != null) {
+                copy.sibling = sibling.copyTree();
+            }
+            return copy;
+        }
+
+
+        /**
          * Adds a pair of {key, value} into the prefix tree.
          *
          * @param k  the key, not null
@@ -2958,10 +3253,10 @@
                     child = c;
                     return true;
                 }
-                // have an existing <key, value> already, keep it.
-                if (value != null) {
-                    return false;
-                }
+                // have an existing <key, value> already, overwrite it
+                // if (value != null) {
+                //    return false;
+                //}
                 value = v;
                 return true;
             }
@@ -3097,9 +3392,7 @@
 
             @Override
             protected boolean isEqual(char c1, char c2) {
-                return c1 == c2 ||
-                       Character.toUpperCase(c1) == Character.toUpperCase(c2) ||
-                       Character.toLowerCase(c1) == Character.toLowerCase(c2);
+                return DateTimeParseContext.charEqualsIgnoreCase(c1, c2);
             }
 
             @Override
@@ -3213,8 +3506,8 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
-            Chrono<?> chrono = context.getValue(Queries.chrono());
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
+            Chronology chrono = context.getValue(Queries.chronology());
             if (chrono == null) {
                 return false;
             }
@@ -3228,7 +3521,26 @@
 
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
-            return ~position;  // TODO, including case insensitive
+            // simple looping parser to find the chronology
+            if (position < 0 || position > text.length()) {
+                throw new IndexOutOfBoundsException();
+            }
+            Set<Chronology> chronos = Chronology.getAvailableChronologies();
+            Chronology bestMatch = null;
+            int matchLen = -1;
+            for (Chronology chrono : chronos) {
+                String id = chrono.getId();
+                int idLen = id.length();
+                if (idLen > matchLen && context.subSequenceEquals(text, position, id, 0, idLen)) {
+                    bestMatch = chrono;
+                    matchLen = idLen;
+                }
+            }
+            if (bestMatch == null) {
+                return ~position;
+            }
+            context.setParsed(bestMatch);
+            return position + matchLen;
         }
     }
 
@@ -3239,40 +3551,40 @@
     static final class LocalizedPrinterParser implements DateTimePrinterParser {
         private final FormatStyle dateStyle;
         private final FormatStyle timeStyle;
-        private final Chrono<?> chrono;
 
         /**
          * Constructor.
          *
          * @param dateStyle  the date style to use, may be null
          * @param timeStyle  the time style to use, may be null
-         * @param chrono  the chronology to use, not null
          */
-        LocalizedPrinterParser(FormatStyle dateStyle, FormatStyle timeStyle, Chrono<?> chrono) {
+        LocalizedPrinterParser(FormatStyle dateStyle, FormatStyle timeStyle) {
             // validated by caller
             this.dateStyle = dateStyle;
             this.timeStyle = timeStyle;
-            this.chrono = chrono;
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
-            return formatter(context.getLocale()).toPrinterParser(false).print(context, buf);
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
+            Chronology chrono = Chronology.from(context.getTemporal());
+            return formatter(context.getLocale(), chrono).toPrinterParser(false).format(context, buf);
         }
 
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
-            return formatter(context.getLocale()).toPrinterParser(false).parse(context, text, position);
+            Chronology chrono = context.getEffectiveChronology();
+            return formatter(context.getLocale(), chrono).toPrinterParser(false).parse(context, text, position);
         }
 
         /**
          * Gets the formatter to use.
          *
          * @param locale  the locale to use, not null
+         * @param chrono  the chronology to use, not null
          * @return the formatter, not null
          * @throws IllegalArgumentException if the formatter cannot be found
          */
-        private DateTimeFormatter formatter(Locale locale) {
+        private DateTimeFormatter formatter(Locale locale, Chronology chrono) {
             return DateTimeFormatStyleProvider.getInstance()
                                               .getFormatter(dateStyle, timeStyle, chrono, locale);
         }
@@ -3280,7 +3592,7 @@
         @Override
         public String toString() {
             return "Localized(" + (dateStyle != null ? dateStyle : "") + "," +
-                (timeStyle != null ? timeStyle : "") + "," + chrono.getId() + ")";
+                (timeStyle != null ? timeStyle : "") + ")";
         }
     }
 
@@ -3309,8 +3621,8 @@
         }
 
         @Override
-        public boolean print(DateTimePrintContext context, StringBuilder buf) {
-            return printerParser(context.getLocale()).print(context, buf);
+        public boolean format(DateTimePrintContext context, StringBuilder buf) {
+            return printerParser(context.getLocale()).format(context, buf);
         }
 
         @Override
diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatters.java b/jdk/src/share/classes/java/time/format/DateTimeFormatters.java
deleted file mode 100644
index d1d6efd..0000000
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatters.java
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.format;
-
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.DAY_OF_WEEK;
-import static java.time.temporal.ChronoField.DAY_OF_YEAR;
-import static java.time.temporal.ChronoField.HOUR_OF_DAY;
-import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.NANO_OF_SECOND;
-import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
-import static java.time.temporal.ChronoField.YEAR;
-
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ISOFields;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Provides common implementations of {@code DateTimeFormatter}.
- * <p>
- * This utility class provides three different ways to obtain a formatter.
- * <p><ul>
- * <li>Using pattern letters, such as {@code yyyy-MMM-dd}
- * <li>Using localized styles, such as {@code long} or {@code medium}
- * <li>Using predefined constants, such as {@code isoLocalDate()}
- * </ul><p>
- *
- * <h3>Specification for implementors</h3>
- * This is a thread-safe utility class.
- * All returned formatters are immutable and thread-safe.
- *
- * @since 1.8
- */
-public final class DateTimeFormatters {
-
-    /**
-     * Private constructor since this is a utility class.
-     */
-    private DateTimeFormatters() {
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Creates a formatter using the specified pattern.
-     * <p>
-     * This method will create a formatter based on a simple pattern of letters and symbols.
-     * For example, {@code d MMM yyyy} will format 2011-12-03 as '3 Dec 2011'.
-     * <p>
-     * The returned formatter will use the default locale, but this can be changed
-     * using {@link DateTimeFormatter#withLocale(Locale)}.
-     * <p>
-     * All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters.
-     * The following pattern letters are defined:
-     * <pre>
-     *  Symbol  Meaning                     Presentation      Examples
-     *  ------  -------                     ------------      -------
-     *   G       era                         number/text       1; 01; AD; Anno Domini
-     *   y       year                        year              2004; 04
-     *   D       day-of-year                 number            189
-     *   M       month-of-year               number/text       7; 07; Jul; July; J
-     *   d       day-of-month                number            10
-     *
-     *   Q       quarter-of-year             number/text       3; 03; Q3
-     *   Y       week-based-year             year              1996; 96
-     *   w       week-of-year                number            27
-     *   W       week-of-month               number            27
-     *   e       localized day-of-week       number            2; Tue; Tuesday; T
-     *   E       day-of-week                 number/text       2; Tue; Tuesday; T
-     *   F       week-of-month               number            3
-     *
-     *   a       am-pm-of-day                text              PM
-     *   h       clock-hour-of-am-pm (1-12)  number            12
-     *   K       hour-of-am-pm (0-11)        number            0
-     *   k       clock-hour-of-am-pm (1-24)  number            0
-     *
-     *   H       hour-of-day (0-23)          number            0
-     *   m       minute-of-hour              number            30
-     *   s       second-of-minute            number            55
-     *   S       fraction-of-second          fraction          978
-     *   A       milli-of-day                number            1234
-     *   n       nano-of-second              number            987654321
-     *   N       nano-of-day                 number            1234000000
-     *
-     *   I       time-zone ID                zoneId            America/Los_Angeles
-     *   z       time-zone name              text              Pacific Standard Time; PST
-     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
-     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
-     *
-     *   p       pad next                    pad modifier      1
-     *
-     *   '       escape for text             delimiter
-     *   ''      single quote                literal           '
-     *   [       optional section start
-     *   ]       optional section end
-     *   {}      reserved for future use
-     * </pre>
-     * <p>
-     * The count of pattern letters determine the format.
-     * <p>
-     * <b>Text</b>: The text style is determined based on the number of pattern letters used.
-     * Less than 4 pattern letters will use the {@link TextStyle#SHORT short form}.
-     * Exactly 4 pattern letters will use the {@link TextStyle#FULL full form}.
-     * Exactly 5 pattern letters will use the {@link TextStyle#NARROW narrow form}.
-     * <p>
-     * <b>Number</b>: If the count of letters is one, then the value is printed using the minimum number
-     * of digits and without padding as per {@link DateTimeFormatterBuilder#appendValue(java.time.temporal.TemporalField)}.
-     * Otherwise, the count of digits is used as the width of the output field as per
-     * {@link DateTimeFormatterBuilder#appendValue(java.time.temporal.TemporalField, int)}.
-     * <p>
-     * <b>Number/Text</b>: If the count of pattern letters is 3 or greater, use the Text rules above.
-     * Otherwise use the Number rules above.
-     * <p>
-     * <b>Fraction</b>: Outputs the nano-of-second field as a fraction-of-second.
-     * The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9.
-     * If it is less than 9, then the nano-of-second value is truncated, with only the most
-     * significant digits being output.
-     * When parsing in strict mode, the number of parsed digits must match the count of pattern letters.
-     * When parsing in lenient mode, the number of parsed digits must be at least the count of pattern
-     * letters, up to 9 digits.
-     * <p>
-     * <b>Year</b>: The count of letters determines the minimum field width below which padding is used.
-     * If the count of letters is two, then a {@link DateTimeFormatterBuilder#appendValueReduced reduced}
-     * two digit form is used.
-     * For printing, this outputs the rightmost two digits. For parsing, this will parse using the
-     * base value of 2000, resulting in a year within the range 2000 to 2099 inclusive.
-     * If the count of letters is less than four (but not two), then the sign is only output for negative
-     * years as per {@link SignStyle#NORMAL}.
-     * Otherwise, the sign is output if the pad width is exceeded, as per {@link SignStyle#EXCEEDS_PAD}
-     * <p>
-     * <b>ZoneId</b>: 'I' outputs the zone ID, such as 'Europe/Paris'.
-     * <p>
-     * <b>Offset X</b>: This formats the offset using 'Z' when the offset is zero.
-     * One letter outputs just the hour', such as '+01'
-     * Two letters outputs the hour and minute, without a colon, such as '+0130'.
-     * Three letters outputs the hour and minute, with a colon, such as '+01:30'.
-     * Four letters outputs the hour and minute and optional second, without a colon, such as '+013015'.
-     * Five letters outputs the hour and minute and optional second, with a colon, such as '+01:30:15'.
-     * <p>
-     * <b>Offset Z</b>: This formats the offset using '+0000' or '+00:00' when the offset is zero.
-     * One or two letters outputs the hour and minute, without a colon, such as '+0130'.
-     * Three letters outputs the hour and minute, with a colon, such as '+01:30'.
-     * <p>
-     * <b>Zone names</b>: Time zone names ('z') cannot be parsed.
-     * <p>
-     * <b>Optional section</b>: The optional section markers work exactly like calling
-     * {@link DateTimeFormatterBuilder#optionalStart()} and {@link DateTimeFormatterBuilder#optionalEnd()}.
-     * <p>
-     * <b>Pad modifier</b>: Modifies the pattern that immediately follows to be padded with spaces.
-     * The pad width is determined by the number of pattern letters.
-     * This is the same as calling {@link DateTimeFormatterBuilder#padNext(int)}.
-     * <p>
-     * For example, 'ppH' outputs the hour-of-day padded on the left with spaces to a width of 2.
-     * <p>
-     * Any unrecognized letter is an error.
-     * Any non-letter character, other than '[', ']', '{', '}' and the single quote will be output directly.
-     * Despite this, it is recommended to use single quotes around all characters that you want to
-     * output directly to ensure that future changes do not break your application.
-     * <p>
-     * The pattern string is similar, but not identical, to {@link java.text.SimpleDateFormat SimpleDateFormat}.
-     * Pattern letters 'E' and 'u' are merged, which changes the meaning of "E" and "EE" to be numeric.
-     * Pattern letters 'Z' and 'X' are extended.
-     * Pattern letter 'y' and 'Y' parse years of two digits and more than 4 digits differently.
-     * Pattern letters 'n', 'A', 'N', 'I' and 'p' are added.
-     * Number types will reject large numbers.
-     * The pattern string is also similar, but not identical, to that defined by the
-     * Unicode Common Locale Data Repository (CLDR).
-     *
-     * @param pattern  the pattern to use, not null
-     * @return the formatter based on the pattern, not null
-     * @throws IllegalArgumentException if the pattern is invalid
-     * @see DateTimeFormatterBuilder#appendPattern(String)
-     */
-    public static DateTimeFormatter pattern(String pattern) {
-        return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
-    }
-
-    /**
-     * Creates a formatter using the specified pattern.
-     * <p>
-     * This method will create a formatter based on a simple pattern of letters and symbols.
-     * For example, {@code d MMM yyyy} will format 2011-12-03 as '3 Dec 2011'.
-     * <p>
-     * See {@link #pattern(String)} for details of the pattern.
-     * <p>
-     * The returned formatter will use the specified locale, but this can be changed
-     * using {@link DateTimeFormatter#withLocale(Locale)}.
-     *
-     * @param pattern  the pattern to use, not null
-     * @param locale  the locale to use, not null
-     * @return the formatter based on the pattern, not null
-     * @throws IllegalArgumentException if the pattern is invalid
-     * @see DateTimeFormatterBuilder#appendPattern(String)
-     */
-    public static DateTimeFormatter pattern(String pattern, Locale locale) {
-        return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a locale specific date format.
-     * <p>
-     * This returns a formatter that will print/parse a date.
-     * The exact format pattern used varies by locale.
-     * <p>
-     * The locale is determined from the formatter. The formatter returned directly by
-     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
-     * on the result of this method.
-     * <p>
-     * Note that the localized pattern is looked up lazily.
-     * This {@code DateTimeFormatter} holds the style required and the locale,
-     * looking up the pattern required on demand.
-     *
-     * @param dateStyle  the formatter style to obtain, not null
-     * @return the date formatter, not null
-     */
-    public static DateTimeFormatter localizedDate(FormatStyle dateStyle) {
-        Objects.requireNonNull(dateStyle, "dateStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, null).toFormatter();
-    }
-
-    /**
-     * Returns a locale specific time format.
-     * <p>
-     * This returns a formatter that will print/parse a time.
-     * The exact format pattern used varies by locale.
-     * <p>
-     * The locale is determined from the formatter. The formatter returned directly by
-     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
-     * on the result of this method.
-     * <p>
-     * Note that the localized pattern is looked up lazily.
-     * This {@code DateTimeFormatter} holds the style required and the locale,
-     * looking up the pattern required on demand.
-     *
-     * @param timeStyle  the formatter style to obtain, not null
-     * @return the time formatter, not null
-     */
-    public static DateTimeFormatter localizedTime(FormatStyle timeStyle) {
-        Objects.requireNonNull(timeStyle, "timeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(null, timeStyle).toFormatter();
-    }
-
-    /**
-     * Returns a locale specific date-time format, which is typically of short length.
-     * <p>
-     * This returns a formatter that will print/parse a date-time.
-     * The exact format pattern used varies by locale.
-     * <p>
-     * The locale is determined from the formatter. The formatter returned directly by
-     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
-     * on the result of this method.
-     * <p>
-     * Note that the localized pattern is looked up lazily.
-     * This {@code DateTimeFormatter} holds the style required and the locale,
-     * looking up the pattern required on demand.
-     *
-     * @param dateTimeStyle  the formatter style to obtain, not null
-     * @return the date-time formatter, not null
-     */
-    public static DateTimeFormatter localizedDateTime(FormatStyle dateTimeStyle) {
-        Objects.requireNonNull(dateTimeStyle, "dateTimeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateTimeStyle, dateTimeStyle).toFormatter();
-    }
-
-    /**
-     * Returns a locale specific date and time format.
-     * <p>
-     * This returns a formatter that will print/parse a date-time.
-     * The exact format pattern used varies by locale.
-     * <p>
-     * The locale is determined from the formatter. The formatter returned directly by
-     * this method will use the {@link Locale#getDefault() default FORMAT locale}.
-     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
-     * on the result of this method.
-     * <p>
-     * Note that the localized pattern is looked up lazily.
-     * This {@code DateTimeFormatter} holds the style required and the locale,
-     * looking up the pattern required on demand.
-     *
-     * @param dateStyle  the date formatter style to obtain, not null
-     * @param timeStyle  the time formatter style to obtain, not null
-     * @return the date, time or date-time formatter, not null
-     */
-    public static DateTimeFormatter localizedDateTime(FormatStyle dateStyle, FormatStyle timeStyle) {
-        Objects.requireNonNull(dateStyle, "dateStyle");
-        Objects.requireNonNull(timeStyle, "timeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, timeStyle).toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date without an offset,
-     * such as '2011-12-03'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended local date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Four digits or more for the {@link ChronoField#YEAR year}.
-     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
-     * Years outside that range will have a prefixed positive or negative symbol.
-     * <li>A dash
-     * <li>Two digits for the {@link ChronoField#MONTH_OF_YEAR month-of-year}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>A dash
-     * <li>Two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
-     *  This is pre-padded by zero to ensure two digits.
-     * </ul><p>
-     *
-     * @return the ISO local date formatter, not null
-     */
-    public static DateTimeFormatter isoLocalDate() {
-        return ISO_LOCAL_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_LOCAL_DATE;
-    static {
-        ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
-            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
-            .appendLiteral('-')
-            .appendValue(MONTH_OF_YEAR, 2)
-            .appendLiteral('-')
-            .appendValue(DAY_OF_MONTH, 2)
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date with an offset,
-     * such as '2011-12-03+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDate()}
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     *
-     * @return the ISO offset date formatter, not null
-     */
-    public static DateTimeFormatter isoOffsetDate() {
-        return ISO_OFFSET_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_OFFSET_DATE;
-    static {
-        ISO_OFFSET_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_DATE)
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date with the
-     * offset if available, such as '2011-12-03' or '2011-12-03+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDate()}
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO date formatter, not null
-     */
-    public static DateTimeFormatter isoDate() {
-        return ISO_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_DATE;
-    static {
-        ISO_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_DATE)
-            .optionalStart()
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO time formatter that prints/parses a time without an offset,
-     * such as '10:15' or '10:15:30'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended local time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Two digits for the {@link ChronoField#HOUR_OF_DAY hour-of-day}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>A colon
-     * <li>Two digits for the {@link ChronoField#MINUTE_OF_HOUR minute-of-hour}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>If the second-of-minute is not available to print/parse then the format is complete.
-     * <li>A colon
-     * <li>Two digits for the {@link ChronoField#SECOND_OF_MINUTE second-of-minute}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>If the nano-of-second is zero or not available to print/parse then the format is complete.
-     * <li>A decimal point
-     * <li>One to nine digits for the {@link ChronoField#NANO_OF_SECOND nano-of-second}.
-     *  As many digits will be printed as required.
-     * </ul><p>
-     *
-     * @return the ISO local time formatter, not null
-     */
-    public static DateTimeFormatter isoLocalTime() {
-        return ISO_LOCAL_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_LOCAL_TIME;
-    static {
-        ISO_LOCAL_TIME = new DateTimeFormatterBuilder()
-            .appendValue(HOUR_OF_DAY, 2)
-            .appendLiteral(':')
-            .appendValue(MINUTE_OF_HOUR, 2)
-            .optionalStart()
-            .appendLiteral(':')
-            .appendValue(SECOND_OF_MINUTE, 2)
-            .optionalStart()
-            .appendFraction(NANO_OF_SECOND, 0, 9, true)
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO time formatter that prints/parses a time with an offset,
-     * such as '10:15+01:00' or '10:15:30+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalTime()}
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     *
-     * @return the ISO offset time formatter, not null
-     */
-    public static DateTimeFormatter isoOffsetTime() {
-        return ISO_OFFSET_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_OFFSET_TIME;
-    static {
-        ISO_OFFSET_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_TIME)
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO time formatter that prints/parses a time, with the
-     * offset if available, such as '10:15', '10:15:30' or '10:15:30+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalTime()}
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO time formatter, not null
-     */
-    public static DateTimeFormatter isoTime() {
-        return ISO_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_TIME;
-    static {
-        ISO_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_TIME)
-            .optionalStart()
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date-time
-     * without an offset, such as '2011-12-03T10:15:30'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset date-time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDate()}
-     * <li>The letter 'T'. Parsing is case insensitive.
-     * <li>The {@link #isoLocalTime()}
-     * </ul><p>
-     *
-     * @return the ISO local date-time formatter, not null
-     */
-    public static DateTimeFormatter isoLocalDateTime() {
-        return ISO_LOCAL_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_LOCAL_DATE_TIME;
-    static {
-        ISO_LOCAL_DATE_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_DATE)
-            .appendLiteral('T')
-            .append(ISO_LOCAL_TIME)
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date-time
-     * with an offset, such as '2011-12-03T10:15:30+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset date-time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDateTime()}
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     *
-     * @return the ISO offset date-time formatter, not null
-     */
-    public static DateTimeFormatter isoOffsetDateTime() {
-        return ISO_OFFSET_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_OFFSET_DATE_TIME;
-    static {
-        ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_DATE_TIME)
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date-time with
-     * offset and zone, such as '2011-12-03T10:15:30+01:00[Europe/Paris]'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * a format that extends the ISO-8601 extended offset date-time format
-     * to add the time-zone.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoOffsetDateTime()}
-     * <li>If the zone ID is not available or is a {@code ZoneOffset} then the format is complete.
-     * <li>An open square bracket '['.
-     * <li>The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard.
-     *  Parsing is case sensitive.
-     * <li>A close square bracket ']'.
-     * </ul><p>
-     *
-     * @return the ISO zoned date-time formatter, not null
-     */
-    public static DateTimeFormatter isoZonedDateTime() {
-        return ISO_ZONED_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_ZONED_DATE_TIME;
-    static {
-        ISO_ZONED_DATE_TIME = new DateTimeFormatterBuilder()
-            .append(ISO_OFFSET_DATE_TIME)
-            .optionalStart()
-            .appendLiteral('[')
-            .parseCaseSensitive()
-            .appendZoneRegionId()
-            .appendLiteral(']')
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date-time
-     * with the offset and zone if available, such as '2011-12-03T10:15:30',
-     * '2011-12-03T10:15:30+01:00' or '2011-12-03T10:15:30+01:00[Europe/Paris]'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset date-time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDateTime()}
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     * <li>If the zone ID is not available or is a {@code ZoneOffset} then the format is complete.
-     * <li>An open square bracket '['.
-     * <li>The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard.
-     *  Parsing is case sensitive.
-     * <li>A close square bracket ']'.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO date-time formatter, not null
-     */
-    public static DateTimeFormatter isoDateTime() {
-        return ISO_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_DATE_TIME;
-    static {
-        ISO_DATE_TIME = new DateTimeFormatterBuilder()
-            .append(ISO_LOCAL_DATE_TIME)
-            .optionalStart()
-            .appendOffsetId()
-            .optionalStart()
-            .appendLiteral('[')
-            .parseCaseSensitive()
-            .appendZoneRegionId()
-            .appendLiteral(']')
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses the ordinal date
-     * without an offset, such as '2012-337'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended ordinal date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Four digits or more for the {@link ChronoField#YEAR year}.
-     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
-     * Years outside that range will have a prefixed positive or negative symbol.
-     * <li>A dash
-     * <li>Three digits for the {@link ChronoField#DAY_OF_YEAR day-of-year}.
-     *  This is pre-padded by zero to ensure three digits.
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO ordinal date formatter, not null
-     */
-    public static DateTimeFormatter isoOrdinalDate() {
-        return ISO_ORDINAL_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_ORDINAL_DATE;
-    static {
-        ISO_ORDINAL_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
-            .appendLiteral('-')
-            .appendValue(DAY_OF_YEAR, 3)
-            .optionalStart()
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses the week-based date
-     * without an offset, such as '2012-W48-6'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended week-based date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Four digits or more for the {@link ISOFields#WEEK_BASED_YEAR week-based-year}.
-     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
-     * Years outside that range will have a prefixed positive or negative symbol.
-     * <li>A dash
-     * <li>The letter 'W'. Parsing is case insensitive.
-     * <li>Two digits for the {@link ISOFields#WEEK_OF_WEEK_BASED_YEAR week-of-week-based-year}.
-     *  This is pre-padded by zero to ensure three digits.
-     * <li>A dash
-     * <li>One digit for the {@link ChronoField#DAY_OF_WEEK day-of-week}.
-     *  The value run from Monday (1) to Sunday (7).
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO week-based date formatter, not null
-     */
-    public static DateTimeFormatter isoWeekDate() {
-        return ISO_WEEK_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_WEEK_DATE;
-    static {
-        ISO_WEEK_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendValue(ISOFields.WEEK_BASED_YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
-            .appendLiteral("-W")
-            .appendValue(ISOFields.WEEK_OF_WEEK_BASED_YEAR, 2)
-            .appendLiteral('-')
-            .appendValue(DAY_OF_WEEK, 1)
-            .optionalStart()
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO instant formatter that prints/parses an instant in UTC.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 instant format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoOffsetDateTime()} where the instant is converted from
-     *  {@link ChronoField#INSTANT_SECONDS} and {@link ChronoField#NANO_OF_SECOND}
-     *  using the {@code UTC} offset. Parsing is case insensitive.
-     * </ul><p>
-     *
-     * @return the ISO instant formatter, not null
-     */
-    public static DateTimeFormatter isoInstant() {
-        return ISO_INSTANT;
-    }
-
-    /** Singleton formatter. */
-    private static final DateTimeFormatter ISO_INSTANT;
-    static {
-        ISO_INSTANT = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendInstant()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date without an offset,
-     * such as '20111203'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 basic local date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Four digits for the {@link ChronoField#YEAR year}.
-     *  Only years in the range 0000 to 9999 are supported.
-     * <li>Two digits for the {@link ChronoField#MONTH_OF_YEAR month-of-year}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>Two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID} without colons. If the offset has
-     *  seconds then they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO basic local date formatter, not null
-     */
-    public static DateTimeFormatter basicIsoDate() {
-        return BASIC_ISO_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter BASIC_ISO_DATE;
-    static {
-        BASIC_ISO_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendValue(YEAR, 4)
-            .appendValue(MONTH_OF_YEAR, 2)
-            .appendValue(DAY_OF_MONTH, 2)
-            .optionalStart()
-            .appendOffset("+HHMMss", "Z")
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the RFC-1123 date-time formatter, such as 'Tue, 3 Jun 2008 11:05:30 GMT'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * most of the RFC-1123 format.
-     * RFC-1123 updates RFC-822 changing the year from two digits to four.
-     * This implementation requires a four digit year.
-     * This implementation also does not handle North American or military zone
-     * names, only 'GMT' and offset amounts.
-     * <p>
-     * The format consists of:
-     * <p><ul>
-     * <li>If the day-of-week is not available to print/parse then jump to day-of-month.
-     * <li>Three letter {@link ChronoField#DAY_OF_WEEK day-of-week} in English.
-     * <li>A comma
-     * <li>A space
-     * <li>One or two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
-     * <li>A space
-     * <li>Three letter {@link ChronoField#MONTH_OF_YEAR month-of-year} in English.
-     * <li>A space
-     * <li>Four digits for the {@link ChronoField#YEAR year}.
-     *  Only years in the range 0000 to 9999 are supported.
-     * <li>A space
-     * <li>Two digits for the {@link ChronoField#HOUR_OF_DAY hour-of-day}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>A colon
-     * <li>Two digits for the {@link ChronoField#MINUTE_OF_HOUR minute-of-hour}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>If the second-of-minute is not available to print/parse then jump to the next space.
-     * <li>A colon
-     * <li>Two digits for the {@link ChronoField#SECOND_OF_MINUTE second-of-minute}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>A space
-     * <li>The {@link ZoneOffset#getId() offset ID} without colons or seconds.
-     *  An offset of zero uses "GMT". North American zone names and military zone names are not handled.
-     * </ul><p>
-     * Parsing is case insensitive.
-     *
-     * @return the RFC-1123 formatter, not null
-     */
-    public static DateTimeFormatter rfc1123() {
-        return RFC_1123_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter RFC_1123_DATE_TIME;
-    static {
-        // manually code maps to ensure correct data always used
-        // (locale data can be changed by application code)
-        Map<Long, String> dow = new HashMap<>();
-        dow.put(1L, "Mon");
-        dow.put(2L, "Tue");
-        dow.put(3L, "Wed");
-        dow.put(4L, "Thu");
-        dow.put(5L, "Fri");
-        dow.put(6L, "Sat");
-        dow.put(7L, "Sun");
-        Map<Long, String> moy = new HashMap<>();
-        moy.put(1L, "Jan");
-        moy.put(2L, "Feb");
-        moy.put(3L, "Mar");
-        moy.put(4L, "Apr");
-        moy.put(5L, "May");
-        moy.put(6L, "Jun");
-        moy.put(7L, "Jul");
-        moy.put(8L, "Aug");
-        moy.put(9L, "Sep");
-        moy.put(10L, "Oct");
-        moy.put(11L, "Nov");
-        moy.put(12L, "Dec");
-        RFC_1123_DATE_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .parseLenient()
-            .optionalStart()
-            .appendText(DAY_OF_WEEK, dow)
-            .appendLiteral(", ")
-            .optionalEnd()
-            .appendValue(DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE)
-            .appendLiteral(' ')
-            .appendText(MONTH_OF_YEAR, moy)
-            .appendLiteral(' ')
-            .appendValue(YEAR, 4)  // 2 digit year not handled
-            .appendLiteral(' ')
-            .appendValue(HOUR_OF_DAY, 2)
-            .appendLiteral(':')
-            .appendValue(MINUTE_OF_HOUR, 2)
-            .optionalStart()
-            .appendLiteral(':')
-            .appendValue(SECOND_OF_MINUTE, 2)
-            .optionalEnd()
-            .appendLiteral(' ')
-            .appendOffset("+HHMM", "GMT")  // should handle UT/Z/EST/EDT/CST/CDT/MST/MDT/PST/MDT
-            .toFormatter();
-    }
-
-}
diff --git a/jdk/src/share/classes/java/time/format/DateTimeParseContext.java b/jdk/src/share/classes/java/time/format/DateTimeParseContext.java
index 6da730e..62f80db 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeParseContext.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeParseContext.java
@@ -61,10 +61,19 @@
  */
 package java.time.format;
 
+import java.time.DateTimeException;
+import java.time.ZoneId;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
 import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -84,7 +93,7 @@
  *
  * @since 1.8
  */
-final class DateTimeParseContext {
+final class DateTimeParseContext implements TemporalAccessor {
 
     /**
      * The formatter, not null.
@@ -130,7 +139,7 @@
      *
      * @return the locale, not null
      */
-    public Locale getLocale() {
+    Locale getLocale() {
         return formatter.getLocale();
     }
 
@@ -141,17 +150,33 @@
      *
      * @return the formatting symbols, not null
      */
-    public DateTimeFormatSymbols getSymbols() {
+    DateTimeFormatSymbols getSymbols() {
         return formatter.getSymbols();
     }
 
+    /**
+     * Gets the effective chronology during parsing.
+     *
+     * @return the effective parsing chronology, not null
+     */
+    Chronology getEffectiveChronology() {
+        Chronology chrono = currentParsed().chrono;
+        if (chrono == null) {
+            chrono = formatter.getChronology();
+            if (chrono == null) {
+                chrono = IsoChronology.INSTANCE;
+            }
+        }
+        return chrono;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Checks if parsing is case sensitive.
      *
      * @return true if parsing is case sensitive, false if case insensitive
      */
-    public boolean isCaseSensitive() {
+    boolean isCaseSensitive() {
         return caseSensitive;
     }
 
@@ -160,10 +185,11 @@
      *
      * @param caseSensitive  changes the parsing to be case sensitive or not from now on
      */
-    public void setCaseSensitive(boolean caseSensitive) {
+    void setCaseSensitive(boolean caseSensitive) {
         this.caseSensitive = caseSensitive;
     }
 
+    //-----------------------------------------------------------------------
     /**
      * Helper to compare two {@code CharSequence} instances.
      * This uses {@link #isCaseSensitive()}.
@@ -175,7 +201,7 @@
      * @param length  the length to check, valid
      * @return true if equal
      */
-    public boolean subSequenceEquals(CharSequence cs1, int offset1, CharSequence cs2, int offset2, int length) {
+    boolean subSequenceEquals(CharSequence cs1, int offset1, CharSequence cs2, int offset2, int length) {
         if (offset1 + length > cs1.length() || offset2 + length > cs2.length()) {
             return false;
         }
@@ -200,6 +226,34 @@
         return true;
     }
 
+    /**
+     * Helper to compare two {@code char}.
+     * This uses {@link #isCaseSensitive()}.
+     *
+     * @param ch1  the first character
+     * @param ch2  the second character
+     * @return true if equal
+     */
+    boolean charEquals(char ch1, char ch2) {
+        if (isCaseSensitive()) {
+            return ch1 == ch2;
+        }
+        return charEqualsIgnoreCase(ch1, ch2);
+    }
+
+    /**
+     * Compares two characters ignoring case.
+     *
+     * @param c1  the first
+     * @param c2  the second
+     * @return true if equal
+     */
+    static boolean charEqualsIgnoreCase(char c1, char c2) {
+        return c1 == c2 ||
+                Character.toUpperCase(c1) == Character.toUpperCase(c2) ||
+                Character.toLowerCase(c1) == Character.toLowerCase(c2);
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Checks if parsing is strict.
@@ -208,7 +262,7 @@
      *
      * @return true if parsing is strict, false if lenient
      */
-    public boolean isStrict() {
+    boolean isStrict() {
         return strict;
     }
 
@@ -217,7 +271,7 @@
      *
      * @param strict  changes the parsing to be strict or lenient from now on
      */
-    public void setStrict(boolean strict) {
+    void setStrict(boolean strict) {
         this.strict = strict;
     }
 
@@ -264,45 +318,8 @@
      * @param field  the field to query from the map, null returns null
      * @return the value mapped to the specified field, null if field was not parsed
      */
-    public Long getParsed(TemporalField field) {
-        for (Object obj : currentParsed().parsed) {
-            if (obj instanceof FieldValue) {
-                FieldValue fv = (FieldValue) obj;
-                if (fv.field.equals(field)) {
-                    return fv.value;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Gets the first value that was parsed for the specified type.
-     * <p>
-     * This searches the results of the parse, returning the first date-time found
-     * of the specified type. No attempt is made to derive a value.
-     *
-     * @param clazz  the type to query from the map, not null
-     * @return the temporal object, null if it was not parsed
-     */
-    @SuppressWarnings("unchecked")
-    public <T> T getParsed(Class<T> clazz) {
-        for (Object obj : currentParsed().parsed) {
-            if (clazz.isInstance(obj)) {
-                return (T) obj;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Gets the list of parsed temporal information.
-     *
-     * @return the list of parsed temporal objects, not null, no nulls
-     */
-    List<Object> getParsed() {
-        // package scoped for testing
-        return currentParsed().parsed;
+    Long getParsed(TemporalField field) {
+        return currentParsed().fieldValues.get(field);
     }
 
     /**
@@ -313,23 +330,40 @@
      *
      * @param field  the field to set in the field-value map, not null
      * @param value  the value to set in the field-value map
+     * @param errorPos  the position of the field being parsed
+     * @param successPos  the position after the field being parsed
+     * @return the new position
      */
-    public void setParsedField(TemporalField field, long value) {
+    int setParsedField(TemporalField field, long value, int errorPos, int successPos) {
         Objects.requireNonNull(field, "field");
-        currentParsed().parsed.add(new FieldValue(field, value));
+        Long old = currentParsed().fieldValues.put(field, value);
+        return (old != null && old.longValue() != value) ? ~errorPos : successPos;
     }
 
     /**
-     * Stores the parsed complete object.
+     * Stores the parsed chronology.
      * <p>
-     * This stores a complete object that has been parsed.
-     * No validation is performed on the date-time other than ensuring it is not null.
+     * This stores the chronology that has been parsed.
+     * No validation is performed other than ensuring it is not null.
      *
-     * @param object  the parsed object, not null
+     * @param chrono  the parsed chronology, not null
      */
-    public <T> void setParsed(Object object) {
-        Objects.requireNonNull(object, "object");
-        currentParsed().parsed.add(object);
+    void setParsed(Chronology chrono) {
+        Objects.requireNonNull(chrono, "chrono");
+        currentParsed().chrono = chrono;
+    }
+
+    /**
+     * Stores the parsed zone.
+     * <p>
+     * This stores the zone that has been parsed.
+     * No validation is performed other than ensuring it is not null.
+     *
+     * @param zone  the parsed zone, not null
+     */
+    void setParsed(ZoneId zone) {
+        Objects.requireNonNull(zone, "zone");
+        currentParsed().zone = zone;
     }
 
     //-----------------------------------------------------------------------
@@ -345,20 +379,98 @@
      *
      * @return a new builder with the results of the parse, not null
      */
-    public DateTimeBuilder toBuilder() {
-        List<Object> cals = currentParsed().parsed;
+    DateTimeBuilder toBuilder() {
+        Parsed parsed = currentParsed();
         DateTimeBuilder builder = new DateTimeBuilder();
-        for (Object obj : cals) {
-            if (obj instanceof FieldValue) {
-                FieldValue fv = (FieldValue) obj;
-                builder.addFieldValue(fv.field, fv.value);
-            } else {
-                builder.addCalendrical(obj);
-            }
+        for (Map.Entry<TemporalField, Long> fv : parsed.fieldValues.entrySet()) {
+            builder.addFieldValue(fv.getKey(), fv.getValue());
+        }
+        builder.addObject(getEffectiveChronology());
+        if (parsed.zone != null) {
+            builder.addObject(parsed.zone);
         }
         return builder;
     }
 
+    /**
+     * Resolves the fields in this context.
+     *
+     * @return this, for method chaining
+     * @throws DateTimeException if resolving one field results in a value for
+     *  another field that is in conflict
+     */
+    DateTimeParseContext resolveFields() {
+        Parsed data = currentParsed();
+        outer:
+        while (true) {
+            for (Map.Entry<TemporalField, Long> entry : data.fieldValues.entrySet()) {
+                TemporalField targetField = entry.getKey();
+                Map<TemporalField, Long> changes = targetField.resolve(this, entry.getValue());
+                if (changes != null) {
+                    resolveMakeChanges(data, targetField, changes);
+                    data.fieldValues.remove(targetField);  // helps avoid infinite loops
+                    continue outer;  // have to restart to avoid concurrent modification
+                }
+            }
+            break;
+        }
+        return this;
+    }
+
+    private void resolveMakeChanges(Parsed data, TemporalField targetField, Map<TemporalField, Long> changes) {
+        for (Map.Entry<TemporalField, Long> change : changes.entrySet()) {
+            TemporalField changeField = change.getKey();
+            Long changeValue = change.getValue();
+            Objects.requireNonNull(changeField, "changeField");
+            if (changeValue != null) {
+                Long old = currentParsed().fieldValues.put(changeField, changeValue);
+                if (old != null && old.longValue() != changeValue.longValue()) {
+                    throw new DateTimeException("Conflict found: " + changeField + " " + old +
+                            " differs from " + changeField + " " + changeValue +
+                            " while resolving  " + targetField);
+                }
+            } else {
+                data.fieldValues.remove(changeField);
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    // TemporalAccessor methods
+    // should only to be used once parsing is complete
+    @Override
+    public boolean isSupported(TemporalField field) {
+        if (currentParsed().fieldValues.containsKey(field)) {
+            return true;
+        }
+        return (field instanceof ChronoField == false) && field.isSupportedBy(this);
+    }
+
+    @Override
+    public long getLong(TemporalField field) {
+        Long value = currentParsed().fieldValues.get(field);
+        if (value != null) {
+            return value;
+        }
+        if (field instanceof ChronoField) {
+            throw new DateTimeException("Unsupported field: " + field.getName());
+        }
+        return field.getFrom(this);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <R> R query(TemporalQuery<R> query) {
+        if (query == Queries.chronology()) {
+            return (R) currentParsed().chrono;
+        } else if (query == Queries.zoneId()) {
+            return (R) currentParsed().zone;
+        } else if (query == Queries.precision()) {
+            return null;
+        }
+        return query.queryFrom(this);
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Returns a string version of the context for debugging.
@@ -375,34 +487,21 @@
      * Temporary store of parsed data.
      */
     private static final class Parsed {
-        final List<Object> parsed = new ArrayList<>();
+        Chronology chrono = null;
+        ZoneId zone = null;
+        final Map<TemporalField, Long> fieldValues = new HashMap<>();
         private Parsed() {
         }
         protected Parsed copy() {
             Parsed cloned = new Parsed();
-            cloned.parsed.addAll(this.parsed);
+            cloned.chrono = this.chrono;
+            cloned.zone = this.zone;
+            cloned.fieldValues.putAll(this.fieldValues);
             return cloned;
         }
         @Override
         public String toString() {
-            return parsed.toString();
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Temporary store of a field-value pair.
-     */
-    private static final class FieldValue {
-        final TemporalField field;
-        final long value;
-        private FieldValue(TemporalField field, long value) {
-            this.field = field;
-            this.value = value;
-        }
-        @Override
-        public String toString() {
-            return field.getName() + ' ' + value;
+            return fieldValues.toString() + "," + chrono + "," + zone;
         }
     }
 
diff --git a/jdk/src/share/classes/java/time/format/DateTimePrintContext.java b/jdk/src/share/classes/java/time/format/DateTimePrintContext.java
index 6314c0d..060d8dd 100644
--- a/jdk/src/share/classes/java/time/format/DateTimePrintContext.java
+++ b/jdk/src/share/classes/java/time/format/DateTimePrintContext.java
@@ -67,9 +67,9 @@
 import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.ZoneId;
-import java.time.temporal.Chrono;
+import java.time.chrono.Chronology;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDate;
 import java.time.temporal.Queries;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
@@ -81,12 +81,12 @@
 /**
  * Context object used during date and time printing.
  * <p>
- * This class provides a single wrapper to items used in the print.
+ * This class provides a single wrapper to items used in the format.
  *
  * <h3>Specification for implementors</h3>
  * This class is a mutable context intended for use from a single thread.
  * Usage of the class is thread-safe within standard printing as the framework creates
- * a new instance of the class for each print and printing is single-threaded.
+ * a new instance of the class for each format and printing is single-threaded.
  *
  * @since 1.8
  */
@@ -109,7 +109,7 @@
      * Creates a new instance of the context.
      *
      * @param temporal  the temporal object being output, not null
-     * @param formatter  the formatter controlling the print, not null
+     * @param formatter  the formatter controlling the format, not null
      */
     DateTimePrintContext(TemporalAccessor temporal, DateTimeFormatter formatter) {
         super();
@@ -119,14 +119,14 @@
 
     private static TemporalAccessor adjust(final TemporalAccessor temporal, DateTimeFormatter formatter) {
         // normal case first
-        Chrono<?> overrideChrono = formatter.getChrono();
+        Chronology overrideChrono = formatter.getChronology();
         ZoneId overrideZone = formatter.getZone();
         if (overrideChrono == null && overrideZone == null) {
             return temporal;
         }
 
         // ensure minimal change
-        Chrono<?> temporalChrono = Chrono.from(temporal);  // default to ISO, handles Instant
+        Chronology temporalChrono = Chronology.from(temporal);  // default to ISO, handles Instant
         ZoneId temporalZone = temporal.query(Queries.zone());  // zone then offset, handles OffsetDateTime
         if (temporal.isSupported(EPOCH_DAY) == false || Objects.equals(overrideChrono, temporalChrono)) {
             overrideChrono = null;
@@ -144,8 +144,8 @@
         } else if (overrideZone != null) {
             return temporalChrono.zonedDateTime(Instant.from(temporal), overrideZone);
         } else {  // overrideChrono != null
-            // need class here to handle non-standard cases like OffsetDate
-            final ChronoLocalDate<?> date = overrideChrono.date(temporal);
+            // need class here to handle non-standard cases
+            final ChronoLocalDate date = overrideChrono.date(temporal);
             return new TemporalAccessor() {
                 @Override
                 public boolean isSupported(TemporalField field) {
@@ -160,7 +160,7 @@
                             return temporal.range(field);
                         }
                     }
-                    return field.doRange(this);
+                    return field.rangeRefinedBy(this);
                 }
                 @Override
                 public long getLong(TemporalField field) {
@@ -171,11 +171,15 @@
                             return temporal.getLong(field);
                         }
                     }
-                    return field.doGet(this);
+                    return field.getFrom(this);
                 }
+                @SuppressWarnings("unchecked")
                 @Override
                 public <R> R query(TemporalQuery<R> query) {
-                    if (query == Queries.zoneId() || query == Queries.chrono() || query == Queries.precision()) {
+                    if (query == Queries.chronology()) {
+                        return (R) date.getChronology();
+                    }
+                    if (query == Queries.zoneId() || query == Queries.precision()) {
                         return temporal.query(query);
                     }
                     return query.queryFrom(this);
@@ -197,7 +201,7 @@
     /**
      * Gets the locale.
      * <p>
-     * This locale is used to control localization in the print output except
+     * This locale is used to control localization in the format output except
      * where localization is controlled by the symbols.
      *
      * @return the locale, not null
diff --git a/jdk/src/share/classes/java/time/format/DateTimePrintException.java b/jdk/src/share/classes/java/time/format/DateTimePrintException.java
deleted file mode 100644
index e03a3e5..0000000
--- a/jdk/src/share/classes/java/time/format/DateTimePrintException.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.format;
-
-import java.io.IOException;
-import java.time.DateTimeException;
-
-/**
- * An exception thrown when an error occurs during printing.
- * <p>
- * This will be triggered by violations specific to printing or an IO exception.
- *
- * <h3>Specification for implementors</h3>
- * This class is intended for use in a single thread.
- *
- * @since 1.8
- */
-public class DateTimePrintException extends DateTimeException {
-
-    /**
-     * Serialization version.
-     */
-    private static final long serialVersionUID = 2263939197574006408L;
-
-    /**
-     * Constructs a new exception with the specified message.
-     *
-     * @param message  the message to use for this exception, may be null
-     */
-    public DateTimePrintException(String message) {
-        super(message, null);
-    }
-
-    /**
-     * Constructs a new exception with the specified message and cause.
-     *
-     * @param message  the message to use for this exception, may be null
-     * @param cause  the cause of the exception, may be null
-     */
-    public DateTimePrintException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks if the cause of this exception was an IOException, and if so
-     * re-throws it
-     * <p>
-     * This method is useful if you call a printer with an open stream or
-     * writer and want to ensure that IOExceptions are not lost.
-     * <pre>
-     * try {
-     *   printer.print(writer, dateTime);
-     * } catch (DateTimePrintException ex) {
-     *   ex.rethrowIOException();
-     *   // if code reaches here exception was caused by date-time issues
-     * }
-     * </pre>
-     * Note that calling this method will re-throw the original IOException,
-     * causing this DateTimePrintException to be lost.
-     *
-     * @throws IOException if the cause of this exception is an IOException
-     */
-    public void rethrowIOException() throws IOException {
-        if (getCause() instanceof IOException) {
-            throw (IOException) getCause();
-        }
-    }
-
-}
diff --git a/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java b/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java
index 042b613..5127f0c 100644
--- a/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java
+++ b/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java
@@ -63,12 +63,13 @@
 
 import static java.time.temporal.ChronoField.AMPM_OF_DAY;
 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.ERA;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 
-import java.time.temporal.Chrono;
-import java.time.temporal.ISOChrono;
-import java.time.calendar.JapaneseChrono;
-import java.time.calendar.ThaiBuddhistChrono;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalField;
 import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.ArrayList;
@@ -83,9 +84,7 @@
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.spi.CalendarNameProvider;
 
-import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.CalendarDataUtility;
 
 /**
@@ -122,7 +121,7 @@
 
     /**
      * Gets the text for the specified field, locale and style
-     * for the purpose of printing.
+     * for the purpose of formatting.
      * <p>
      * The text associated with the value is returned.
      * The null return value should be used if there is no applicable text, or
@@ -152,37 +151,57 @@
     }
 
     /**
-     * Gets the era text for the specified chrono, value, style and locale
-     * for the purpose of printing.
+     * Gets the text for the specified chrono, field, locale and style
+     * for the purpose of formatting.
      * <p>
-     * The era text associated with the value is returned.
+     * The text associated with the value is returned.
      * The null return value should be used if there is no applicable text, or
      * if the text would be a numeric representation of the value.
      *
-     * @param chrono the chrono to get text for, not null
+     * @param chrono the Chronology to get text for, not null
+     * @param field  the field to get text for, not null
      * @param value  the field value to get text for, not null
      * @param style  the style to get text for, not null
      * @param locale  the locale to get text for, not null
-     * @return the era text for the value, null if no text found
+     * @return the text for the field value, null if no text found
      */
-    public String getEraText(Chrono chrono, long value, TextStyle style, Locale locale) {
-        String type = null;
-        if (chrono == ISOChrono.INSTANCE) {
-            type = "gregory";
-        } else if (chrono == JapaneseChrono.INSTANCE) {
-            type = "japanese";
-            if (value == -999) {
-                value = 0;
+    public String getText(Chronology chrono, TemporalField field, long value,
+                                    TextStyle style, Locale locale) {
+        if (chrono == IsoChronology.INSTANCE
+                || !(field instanceof ChronoField)) {
+            return getText(field, value, style, locale);
+        }
+
+        int fieldIndex;
+        int fieldValue;
+        if (field == ERA) {
+            fieldIndex = Calendar.ERA;
+            if (chrono == JapaneseChronology.INSTANCE) {
+                if (value == -999) {
+                    fieldValue = 0;
+                } else {
+                    fieldValue = (int) value + 2;
+                }
             } else {
-                value += 2;
+                fieldValue = (int) value;
             }
-        } else if (chrono == ThaiBuddhistChrono.INSTANCE) {
-            type = "buddhist";
+        } else if (field == MONTH_OF_YEAR) {
+            fieldIndex = Calendar.MONTH;
+            fieldValue = (int) value - 1;
+        } else if (field == DAY_OF_WEEK) {
+            fieldIndex = Calendar.DAY_OF_WEEK;
+            fieldValue = (int) value + 1;
+            if (fieldValue > 7) {
+                fieldValue = Calendar.SUNDAY;
+            }
+        } else if (field == AMPM_OF_DAY) {
+            fieldIndex = Calendar.AM_PM;
+            fieldValue = (int) value;
         } else {
             return null;
         }
-        return CalendarDataUtility.retrieveFieldValueName(
-            type, Calendar.ERA, (int)value, toStyle(style), locale);
+        return CalendarDataUtility.retrieveCldrFieldValueName(
+                chrono.getCalendarType(), fieldIndex, fieldValue, toStyle(style), locale);
     }
 
     /**
@@ -209,6 +228,88 @@
         return null;
     }
 
+    /**
+     * Gets an iterator of text to field for the specified chrono, field, locale and style
+     * for the purpose of parsing.
+     * <p>
+     * The iterator must be returned in order from the longest text to the shortest.
+     * <p>
+     * The null return value should be used if there is no applicable parsable text, or
+     * if the text would be a numeric representation of the value.
+     * Text can only be parsed if all the values for that field-style-locale combination are unique.
+     *
+     * @param chrono the Chronology to get text for, not null
+     * @param field  the field to get text for, not null
+     * @param style  the style to get text for, null for all parsable text
+     * @param locale  the locale to get text for, not null
+     * @return the iterator of text to field pairs, in order from longest text to shortest text,
+     *  null if the field or style is not parsable
+     */
+    public Iterator<Entry<String, Long>> getTextIterator(Chronology chrono, TemporalField field,
+                                                         TextStyle style, Locale locale) {
+        if (chrono == IsoChronology.INSTANCE
+                || !(field instanceof ChronoField)) {
+            return getTextIterator(field, style, locale);
+        }
+
+        int fieldIndex;
+        switch ((ChronoField)field) {
+        case ERA:
+            fieldIndex = Calendar.ERA;
+            break;
+        case MONTH_OF_YEAR:
+            fieldIndex = Calendar.MONTH;
+            break;
+        case DAY_OF_WEEK:
+            fieldIndex = Calendar.DAY_OF_WEEK;
+            break;
+        case AMPM_OF_DAY:
+            fieldIndex = Calendar.AM_PM;
+            break;
+        default:
+            return null;
+        }
+
+        Map<String, Integer> map = CalendarDataUtility.retrieveCldrFieldValueNames(
+                chrono.getCalendarType(), fieldIndex, toStyle(style), locale);
+        if (map == null) {
+            return null;
+        }
+
+        List<Entry<String, Long>> list = new ArrayList<>(map.size());
+        switch (fieldIndex) {
+        case Calendar.ERA:
+            for (String key : map.keySet()) {
+                int era = map.get(key);
+                if (chrono == JapaneseChronology.INSTANCE) {
+                    if (era == 0) {
+                        era = -999;
+                    } else {
+                        era -= 2;
+                    }
+                }
+                list.add(createEntry(key, (long) era));
+            }
+            break;
+        case Calendar.MONTH:
+            for (String key : map.keySet()) {
+                list.add(createEntry(key, (long)(map.get(key) + 1)));
+            }
+            break;
+        case Calendar.DAY_OF_WEEK:
+            for (String key : map.keySet()) {
+                list.add(createEntry(key, (long)toWeekDay(map.get(key))));
+            }
+            break;
+        default:
+            for (String key : map.keySet()) {
+                list.add(createEntry(key, (long)map.get(key)));
+            }
+            break;
+        }
+        return list.iterator();
+    }
+
     private Object findStore(TemporalField field, Locale locale) {
         Entry<TemporalField, Locale> key = createEntry(field, locale);
         Object store = CACHE.get(key);
@@ -229,67 +330,91 @@
     }
 
     private Object createStore(TemporalField field, Locale locale) {
-        CalendarNameProvider provider = LocaleProviderAdapter.getAdapter(CalendarNameProvider.class, locale)
-                                                             .getCalendarNameProvider();
         Map<TextStyle, Map<Long, String>> styleMap = new HashMap<>();
+        if (field == ERA) {
+            for (TextStyle textStyle : TextStyle.values()) {
+                Map<Long, String> map = new HashMap<>();
+                for (Entry<String, Integer> entry :
+                        CalendarDataUtility.retrieveCldrFieldValueNames(
+                        "gregory", Calendar.ERA, toStyle(textStyle), locale).entrySet()) {
+                    map.put((long) entry.getValue(), entry.getKey());
+                }
+                if (!map.isEmpty()) {
+                    styleMap.put(textStyle, map);
+                }
+            }
+            return new LocaleStore(styleMap);
+        }
+
         if (field == MONTH_OF_YEAR) {
             Map<Long, String> map = new HashMap<>();
             for (Entry<String, Integer> entry :
-                 provider.getDisplayNames("gregory", Calendar.MONTH, Calendar.LONG_FORMAT, locale).entrySet()) {
-                map.put((long)(entry.getValue() + 1), entry.getKey());
+                    CalendarDataUtility.retrieveCldrFieldValueNames(
+                    "gregory", Calendar.MONTH, Calendar.LONG_FORMAT, locale).entrySet()) {
+                map.put((long) (entry.getValue() + 1), entry.getKey());
             }
             styleMap.put(TextStyle.FULL, map);
 
             map = new HashMap<>();
             for (Entry<String, Integer> entry :
-                 provider.getDisplayNames("gregory", Calendar.MONTH, Calendar.SHORT_FORMAT, locale).entrySet()) {
-                map.put((long)(entry.getValue() + 1), entry.getKey());
+                    CalendarDataUtility.retrieveCldrFieldValueNames(
+                    "gregory", Calendar.MONTH, Calendar.SHORT_FORMAT, locale).entrySet()) {
+                map.put((long) (entry.getValue() + 1), entry.getKey());
             }
             styleMap.put(TextStyle.SHORT, map);
 
             map = new HashMap<>();
             for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
-                String name = provider.getDisplayName("gregory", Calendar.MONTH, month, Calendar.NARROW_STANDALONE, locale);
+                String name;
+                name = CalendarDataUtility.retrieveCldrFieldValueName(
+                        "gregory", Calendar.MONTH, month, Calendar.NARROW_STANDALONE, locale);
                 if (name != null) {
                     map.put((long)(month + 1), name);
                 }
             }
-            if (map.size() != 0) {
+            if (!map.isEmpty()) {
                 styleMap.put(TextStyle.NARROW, map);
             }
             return new LocaleStore(styleMap);
         }
+
         if (field == DAY_OF_WEEK) {
             Map<Long, String> map = new HashMap<>();
             for (Entry<String, Integer> entry :
-                 provider.getDisplayNames("gregory", Calendar.DAY_OF_WEEK, Calendar.LONG_FORMAT, locale).entrySet()) {
+                 CalendarDataUtility.retrieveCldrFieldValueNames(
+                    "gregory", Calendar.DAY_OF_WEEK, Calendar.LONG_FORMAT, locale).entrySet()) {
                 map.put((long)toWeekDay(entry.getValue()), entry.getKey());
             }
             styleMap.put(TextStyle.FULL, map);
             map = new HashMap<>();
             for (Entry<String, Integer> entry :
-                 provider.getDisplayNames("gregory", Calendar.DAY_OF_WEEK, Calendar.SHORT_FORMAT, locale).entrySet()) {
-                map.put((long)toWeekDay(entry.getValue()), entry.getKey());
+                    CalendarDataUtility.retrieveCldrFieldValueNames(
+                    "gregory", Calendar.DAY_OF_WEEK, Calendar.SHORT_FORMAT, locale).entrySet()) {
+                map.put((long) toWeekDay(entry.getValue()), entry.getKey());
             }
             styleMap.put(TextStyle.SHORT, map);
             map = new HashMap<>();
             for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
-                map.put((long)toWeekDay(wday),
-                        provider.getDisplayName("gregory", Calendar.DAY_OF_WEEK, wday, Calendar.NARROW_FORMAT, locale));
+                map.put((long) toWeekDay(wday),
+                        CalendarDataUtility.retrieveCldrFieldValueName(
+                        "gregory", Calendar.DAY_OF_WEEK, wday, Calendar.NARROW_FORMAT, locale));
             }
             styleMap.put(TextStyle.NARROW, map);
             return new LocaleStore(styleMap);
         }
+
         if (field == AMPM_OF_DAY) {
             Map<Long, String> map = new HashMap<>();
             for (Entry<String, Integer> entry :
-                 provider.getDisplayNames("gregory", Calendar.AM_PM, Calendar.LONG_FORMAT, locale).entrySet()) {
-                map.put((long)entry.getValue(), entry.getKey());
+                    CalendarDataUtility.retrieveCldrFieldValueNames(
+                    "gregory", Calendar.AM_PM, Calendar.LONG_FORMAT, locale).entrySet()) {
+                map.put((long) entry.getValue(), entry.getKey());
             }
             styleMap.put(TextStyle.FULL, map);
             styleMap.put(TextStyle.SHORT, map);  // re-use, as we don't have different data
             return new LocaleStore(styleMap);
         }
+
         return "";  // null marker for map
     }
 
diff --git a/jdk/src/share/classes/java/time/format/FormatStyle.java b/jdk/src/share/classes/java/time/format/FormatStyle.java
index 58cebe4..0be538e 100644
--- a/jdk/src/share/classes/java/time/format/FormatStyle.java
+++ b/jdk/src/share/classes/java/time/format/FormatStyle.java
@@ -65,7 +65,7 @@
  * Enumeration of the style of a localized date, time or date-time formatter.
  * <p>
  * These styles are used when obtaining a date-time style from configuration.
- * See {@link DateTimeFormatters} and {@link DateTimeFormatterBuilder} for usage.
+ * See {@link DateTimeFormatter} and {@link DateTimeFormatterBuilder} for usage.
  *
  * <h3>Specification for implementors</h3>
  * This is an immutable and thread-safe enum.
diff --git a/jdk/src/share/classes/java/time/format/ZoneName.java b/jdk/src/share/classes/java/time/format/ZoneName.java
new file mode 100644
index 0000000..f1f6170
--- /dev/null
+++ b/jdk/src/share/classes/java/time/format/ZoneName.java
@@ -0,0 +1,800 @@
+/*
+ * 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.  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 java.time.format;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * A helper class to map a zone name to metazone and back to the
+ * appropriate zone id for the particular locale.
+ * <p>
+ * The zid<->metazone mappings are based on CLDR metaZones.xml.
+ * The alias mappings are based on Link entries in tzdb data files.
+ */
+class ZoneName {
+
+    public static String toZid(String zid, Locale locale) {
+        String mzone = zidToMzone.get(zid);
+        if (mzone == null && aliases.containsKey(zid)) {
+            zid = aliases.get(zid);
+            mzone = zidToMzone.get(zid);
+        }
+        if (mzone != null) {
+            Map<String, String> map = mzoneToZidL.get(mzone);
+            if (map != null && map.containsKey(locale.getCountry())) {
+                zid = map.get(locale.getCountry());
+            } else {
+                zid = mzoneToZid.get(mzone);
+            }
+        }
+        return toZid(zid);
+    }
+
+    public static String toZid(String zid) {
+        if (aliases.containsKey(zid)) {
+            return aliases.get(zid);
+        }
+        return zid;
+    }
+
+    private static final String[] zidMap = new String[] {
+        "Pacific/Rarotonga", "Cook", "Pacific/Rarotonga",
+        "Europe/Tirane", "Europe_Central", "Europe/Paris",
+        "America/Recife", "Brasilia", "America/Sao_Paulo",
+        "America/Argentina/San_Juan", "Argentina", "America/Buenos_Aires",
+        "Asia/Kolkata", "India", "Asia/Calcutta",
+        "America/Guayaquil", "Ecuador", "America/Guayaquil",
+        "Europe/Samara", "Moscow", "Europe/Moscow",
+        "Indian/Antananarivo", "Africa_Eastern", "Africa/Nairobi",
+        "America/Santa_Isabel", "America_Pacific", "America/Los_Angeles",
+        "America/Montserrat", "Atlantic", "America/Halifax",
+        "Pacific/Port_Moresby", "Papua_New_Guinea", "Pacific/Port_Moresby",
+        "Europe/Paris", "Europe_Central", "Europe/Paris",
+        "America/Argentina/Salta", "Argentina", "America/Buenos_Aires",
+        "Asia/Omsk", "Omsk", "Asia/Omsk",
+        "Africa/Ceuta", "Europe_Central", "Europe/Paris",
+        "America/Argentina/San_Luis", "Argentina_Western", "America/Argentina/San_Luis",
+        "America/Atikokan", "America_Eastern", "America/New_York",
+        "Asia/Vladivostok", "Vladivostok", "Asia/Vladivostok",
+        "America/Argentina/Jujuy", "Argentina", "America/Buenos_Aires",
+        "Asia/Almaty", "Kazakhstan_Eastern", "Asia/Almaty",
+        "Atlantic/Canary", "Europe_Western", "Atlantic/Canary",
+        "Asia/Bangkok", "Indochina", "Asia/Saigon",
+        "America/Caracas", "Venezuela", "America/Caracas",
+        "Australia/Hobart", "Australia_Eastern", "Australia/Sydney",
+        "America/Havana", "Cuba", "America/Havana",
+        "Africa/Malabo", "Africa_Western", "Africa/Lagos",
+        "Australia/Lord_Howe", "Lord_Howe", "Australia/Lord_Howe",
+        "Pacific/Fakaofo", "Tokelau", "Pacific/Fakaofo",
+        "America/Matamoros", "America_Central", "America/Chicago",
+        "America/Guadeloupe", "Atlantic", "America/Halifax",
+        "Europe/Helsinki", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Calcutta", "India", "Asia/Calcutta",
+        "Africa/Kinshasa", "Africa_Western", "Africa/Lagos",
+        "America/Miquelon", "Pierre_Miquelon", "America/Miquelon",
+        "Europe/Athens", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Novosibirsk", "Novosibirsk", "Asia/Novosibirsk",
+        "Indian/Cocos", "Cocos", "Indian/Cocos",
+        "Africa/Bujumbura", "Africa_Central", "Africa/Maputo",
+        "Europe/Mariehamn", "Europe_Eastern", "Europe/Bucharest",
+        "America/Winnipeg", "America_Central", "America/Chicago",
+        "America/Buenos_Aires", "Argentina", "America/Buenos_Aires",
+        "America/Yellowknife", "America_Mountain", "America/Denver",
+        "Pacific/Midway", "Samoa", "Pacific/Apia",
+        "Africa/Dar_es_Salaam", "Africa_Eastern", "Africa/Nairobi",
+        "Pacific/Tahiti", "Tahiti", "Pacific/Tahiti",
+        "Asia/Gaza", "Europe_Eastern", "Europe/Bucharest",
+        "Australia/Lindeman", "Australia_Eastern", "Australia/Sydney",
+        "Europe/Kaliningrad", "Europe_Eastern", "Europe/Bucharest",
+        "Europe/Bucharest", "Europe_Eastern", "Europe/Bucharest",
+        "America/Lower_Princes", "Atlantic", "America/Halifax",
+        "Pacific/Chuuk", "Truk", "Pacific/Truk",
+        "America/Anchorage", "Alaska", "America/Juneau",
+        "America/Rankin_Inlet", "America_Central", "America/Chicago",
+        "America/Marigot", "Atlantic", "America/Halifax",
+        "Africa/Juba", "Africa_Eastern", "Africa/Nairobi",
+        "Africa/Algiers", "Europe_Central", "Europe/Paris",
+        "Europe/Kiev", "Europe_Eastern", "Europe/Bucharest",
+        "America/Santarem", "Brasilia", "America/Sao_Paulo",
+        "Africa/Brazzaville", "Africa_Western", "Africa/Lagos",
+        "Asia/Choibalsan", "Choibalsan", "Asia/Choibalsan",
+        "Indian/Christmas", "Christmas", "Indian/Christmas",
+        "America/Nassau", "America_Eastern", "America/New_York",
+        "Africa/Tunis", "Europe_Central", "Europe/Paris",
+        "Pacific/Noumea", "New_Caledonia", "Pacific/Noumea",
+        "Africa/El_Aaiun", "Europe_Western", "Atlantic/Canary",
+        "Europe/Sarajevo", "Europe_Central", "Europe/Paris",
+        "America/Campo_Grande", "Amazon", "America/Manaus",
+        "America/Puerto_Rico", "Atlantic", "America/Halifax",
+        "Antarctica/Mawson", "Mawson", "Antarctica/Mawson",
+        "Pacific/Galapagos", "Galapagos", "Pacific/Galapagos",
+        "Asia/Tehran", "Iran", "Asia/Tehran",
+        "America/Port-au-Prince", "America_Eastern", "America/New_York",
+        "America/Scoresbysund", "Greenland_Eastern", "America/Scoresbysund",
+        "Africa/Harare", "Africa_Central", "Africa/Maputo",
+        "America/Dominica", "Atlantic", "America/Halifax",
+        "Europe/Chisinau", "Europe_Eastern", "Europe/Bucharest",
+        "America/Chihuahua", "America_Mountain", "America/Denver",
+        "America/La_Paz", "Bolivia", "America/La_Paz",
+        "Indian/Chagos", "Indian_Ocean", "Indian/Chagos",
+        "Australia/Broken_Hill", "Australia_Central", "Australia/Adelaide",
+        "America/Grenada", "Atlantic", "America/Halifax",
+        "America/North_Dakota/New_Salem", "America_Central", "America/Chicago",
+        "Pacific/Majuro", "Marshall_Islands", "Pacific/Majuro",
+        "Australia/Adelaide", "Australia_Central", "Australia/Adelaide",
+        "Europe/Warsaw", "Europe_Central", "Europe/Paris",
+        "Europe/Vienna", "Europe_Central", "Europe/Paris",
+        "Atlantic/Cape_Verde", "Cape_Verde", "Atlantic/Cape_Verde",
+        "America/Mendoza", "Argentina", "America/Buenos_Aires",
+        "Pacific/Gambier", "Gambier", "Pacific/Gambier",
+        "Europe/Istanbul", "Europe_Eastern", "Europe/Bucharest",
+        "America/Kentucky/Monticello", "America_Eastern", "America/New_York",
+        "America/Chicago", "America_Central", "America/Chicago",
+        "Asia/Ulaanbaatar", "Mongolia", "Asia/Ulaanbaatar",
+        "Indian/Maldives", "Maldives", "Indian/Maldives",
+        "America/Mexico_City", "America_Central", "America/Chicago",
+        "Africa/Asmara", "Africa_Eastern", "Africa/Nairobi",
+        "Asia/Chongqing", "China", "Asia/Shanghai",
+        "America/Argentina/La_Rioja", "Argentina", "America/Buenos_Aires",
+        "America/Tijuana", "America_Pacific", "America/Los_Angeles",
+        "Asia/Harbin", "China", "Asia/Shanghai",
+        "Pacific/Honolulu", "Hawaii_Aleutian", "Pacific/Honolulu",
+        "Atlantic/Azores", "Azores", "Atlantic/Azores",
+        "Indian/Mayotte", "Africa_Eastern", "Africa/Nairobi",
+        "America/Guatemala", "America_Central", "America/Chicago",
+        "America/Indianapolis", "America_Eastern", "America/New_York",
+        "America/Halifax", "Atlantic", "America/Halifax",
+        "America/Resolute", "America_Central", "America/Chicago",
+        "Europe/London", "GMT", "Atlantic/Reykjavik",
+        "America/Hermosillo", "America_Mountain", "America/Denver",
+        "Atlantic/Madeira", "Europe_Western", "Atlantic/Canary",
+        "Europe/Zagreb", "Europe_Central", "Europe/Paris",
+        "America/Boa_Vista", "Amazon", "America/Manaus",
+        "America/Regina", "America_Central", "America/Chicago",
+        "America/Cordoba", "Argentina", "America/Buenos_Aires",
+        "America/Shiprock", "America_Mountain", "America/Denver",
+        "Europe/Luxembourg", "Europe_Central", "Europe/Paris",
+        "America/Cancun", "America_Central", "America/Chicago",
+        "Pacific/Enderbury", "Phoenix_Islands", "Pacific/Enderbury",
+        "Africa/Bissau", "GMT", "Atlantic/Reykjavik",
+        "Antarctica/Vostok", "Vostok", "Antarctica/Vostok",
+        "Pacific/Apia", "Samoa", "Pacific/Apia",
+        "Australia/Perth", "Australia_Western", "Australia/Perth",
+        "America/Juneau", "Alaska", "America/Juneau",
+        "Africa/Mbabane", "Africa_Southern", "Africa/Johannesburg",
+        "Pacific/Niue", "Niue", "Pacific/Niue",
+        "Europe/Zurich", "Europe_Central", "Europe/Paris",
+        "America/Rio_Branco", "Amazon", "America/Manaus",
+        "Africa/Ndjamena", "Africa_Western", "Africa/Lagos",
+        "Asia/Macau", "China", "Asia/Shanghai",
+        "America/Lima", "Peru", "America/Lima",
+        "Africa/Windhoek", "Africa_Western", "Africa/Lagos",
+        "America/Sitka", "Alaska", "America/Juneau",
+        "America/Mazatlan", "America_Mountain", "America/Denver",
+        "Asia/Saigon", "Indochina", "Asia/Saigon",
+        "Asia/Kamchatka", "Magadan", "Asia/Magadan",
+        "America/Menominee", "America_Central", "America/Chicago",
+        "America/Belize", "America_Central", "America/Chicago",
+        "America/Sao_Paulo", "Brasilia", "America/Sao_Paulo",
+        "America/Barbados", "Atlantic", "America/Halifax",
+        "America/Porto_Velho", "Amazon", "America/Manaus",
+        "America/Costa_Rica", "America_Central", "America/Chicago",
+        "Europe/Monaco", "Europe_Central", "Europe/Paris",
+        "Europe/Riga", "Europe_Eastern", "Europe/Bucharest",
+        "Europe/Vatican", "Europe_Central", "Europe/Paris",
+        "Europe/Madrid", "Europe_Central", "Europe/Paris",
+        "Africa/Dakar", "GMT", "Atlantic/Reykjavik",
+        "Asia/Damascus", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Hong_Kong", "Hong_Kong", "Asia/Hong_Kong",
+        "America/Adak", "Hawaii_Aleutian", "Pacific/Honolulu",
+        "Europe/Vilnius", "Europe_Eastern", "Europe/Bucharest",
+        "America/Indiana/Indianapolis", "America_Eastern", "America/New_York",
+        "Africa/Freetown", "GMT", "Atlantic/Reykjavik",
+        "Atlantic/Reykjavik", "GMT", "Atlantic/Reykjavik",
+        "Asia/Ho_Chi_Minh", "Indochina", "Asia/Saigon",
+        "America/St_Kitts", "Atlantic", "America/Halifax",
+        "America/Martinique", "Atlantic", "America/Halifax",
+        "America/Thule", "Atlantic", "America/Halifax",
+        "America/Asuncion", "Paraguay", "America/Asuncion",
+        "Africa/Luanda", "Africa_Western", "Africa/Lagos",
+        "America/Monterrey", "America_Central", "America/Chicago",
+        "Pacific/Fiji", "Fiji", "Pacific/Fiji",
+        "Africa/Banjul", "GMT", "Atlantic/Reykjavik",
+        "America/Grand_Turk", "America_Eastern", "America/New_York",
+        "Pacific/Pitcairn", "Pitcairn", "Pacific/Pitcairn",
+        "America/Montevideo", "Uruguay", "America/Montevideo",
+        "America/Bahia_Banderas", "America_Central", "America/Chicago",
+        "America/Cayman", "America_Eastern", "America/New_York",
+        "Pacific/Norfolk", "Norfolk", "Pacific/Norfolk",
+        "Africa/Ouagadougou", "GMT", "Atlantic/Reykjavik",
+        "America/Maceio", "Brasilia", "America/Sao_Paulo",
+        "Pacific/Guam", "Chamorro", "Pacific/Saipan",
+        "Africa/Monrovia", "GMT", "Atlantic/Reykjavik",
+        "Africa/Bamako", "GMT", "Atlantic/Reykjavik",
+        "Asia/Colombo", "India", "Asia/Calcutta",
+        "Asia/Urumqi", "China", "Asia/Shanghai",
+        "Asia/Kabul", "Afghanistan", "Asia/Kabul",
+        "America/Yakutat", "Alaska", "America/Juneau",
+        "America/Phoenix", "America_Mountain", "America/Denver",
+        "Asia/Nicosia", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Phnom_Penh", "Indochina", "Asia/Saigon",
+        "America/Rainy_River", "America_Central", "America/Chicago",
+        "Europe/Uzhgorod", "Europe_Eastern", "Europe/Bucharest",
+        "Pacific/Saipan", "Chamorro", "Pacific/Saipan",
+        "America/St_Vincent", "Atlantic", "America/Halifax",
+        "Europe/Rome", "Europe_Central", "Europe/Paris",
+        "America/Nome", "Alaska", "America/Juneau",
+        "Africa/Mogadishu", "Africa_Eastern", "Africa/Nairobi",
+        "Europe/Zaporozhye", "Europe_Eastern", "Europe/Bucharest",
+        "Pacific/Funafuti", "Tuvalu", "Pacific/Funafuti",
+        "Atlantic/South_Georgia", "South_Georgia", "Atlantic/South_Georgia",
+        "Europe/Skopje", "Europe_Central", "Europe/Paris",
+        "Asia/Yekaterinburg", "Yekaterinburg", "Asia/Yekaterinburg",
+        "Australia/Melbourne", "Australia_Eastern", "Australia/Sydney",
+        "America/Argentina/Cordoba", "Argentina", "America/Buenos_Aires",
+        "Africa/Kigali", "Africa_Central", "Africa/Maputo",
+        "Africa/Blantyre", "Africa_Central", "Africa/Maputo",
+        "Africa/Tripoli", "Europe_Eastern", "Europe/Bucharest",
+        "Africa/Gaborone", "Africa_Central", "Africa/Maputo",
+        "Asia/Kuching", "Malaysia", "Asia/Kuching",
+        "Pacific/Nauru", "Nauru", "Pacific/Nauru",
+        "America/Aruba", "Atlantic", "America/Halifax",
+        "America/Antigua", "Atlantic", "America/Halifax",
+        "Europe/Volgograd", "Volgograd", "Europe/Volgograd",
+        "Africa/Djibouti", "Africa_Eastern", "Africa/Nairobi",
+        "America/Catamarca", "Argentina", "America/Buenos_Aires",
+        "Asia/Manila", "Philippines", "Asia/Manila",
+        "Pacific/Kiritimati", "Line_Islands", "Pacific/Kiritimati",
+        "Asia/Shanghai", "China", "Asia/Shanghai",
+        "Pacific/Truk", "Truk", "Pacific/Truk",
+        "Pacific/Tarawa", "Gilbert_Islands", "Pacific/Tarawa",
+        "Africa/Conakry", "GMT", "Atlantic/Reykjavik",
+        "Asia/Bishkek", "Kyrgystan", "Asia/Bishkek",
+        "Europe/Gibraltar", "Europe_Central", "Europe/Paris",
+        "Asia/Rangoon", "Myanmar", "Asia/Rangoon",
+        "Asia/Baku", "Azerbaijan", "Asia/Baku",
+        "America/Santiago", "Chile", "America/Santiago",
+        "America/El_Salvador", "America_Central", "America/Chicago",
+        "America/Noronha", "Noronha", "America/Noronha",
+        "America/St_Thomas", "Atlantic", "America/Halifax",
+        "Atlantic/St_Helena", "GMT", "Atlantic/Reykjavik",
+        "Asia/Krasnoyarsk", "Krasnoyarsk", "Asia/Krasnoyarsk",
+        "America/Vancouver", "America_Pacific", "America/Los_Angeles",
+        "Europe/Belgrade", "Europe_Central", "Europe/Paris",
+        "America/St_Barthelemy", "Atlantic", "America/Halifax",
+        "Asia/Pontianak", "Indonesia_Western", "Asia/Jakarta",
+        "Africa/Lusaka", "Africa_Central", "Africa/Maputo",
+        "America/Godthab", "Greenland_Western", "America/Godthab",
+        "Asia/Dhaka", "Bangladesh", "Asia/Dhaka",
+        "Asia/Dubai", "Gulf", "Asia/Dubai",
+        "Europe/Moscow", "Moscow", "Europe/Moscow",
+        "America/Louisville", "America_Eastern", "America/New_York",
+        "Australia/Darwin", "Australia_Central", "Australia/Adelaide",
+        "America/Santo_Domingo", "Atlantic", "America/Halifax",
+        "America/Argentina/Ushuaia", "Argentina", "America/Buenos_Aires",
+        "America/Tegucigalpa", "America_Central", "America/Chicago",
+        "Asia/Aden", "Arabian", "Asia/Riyadh",
+        "America/Inuvik", "America_Mountain", "America/Denver",
+        "Asia/Beirut", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Qatar", "Arabian", "Asia/Riyadh",
+        "Europe/Oslo", "Europe_Central", "Europe/Paris",
+        "Asia/Anadyr", "Magadan", "Asia/Magadan",
+        "Pacific/Palau", "Palau", "Pacific/Palau",
+        "Arctic/Longyearbyen", "Europe_Central", "Europe/Paris",
+        "America/Anguilla", "Atlantic", "America/Halifax",
+        "Asia/Aqtau", "Kazakhstan_Western", "Asia/Aqtobe",
+        "Asia/Yerevan", "Armenia", "Asia/Yerevan",
+        "Africa/Lagos", "Africa_Western", "Africa/Lagos",
+        "America/Denver", "America_Mountain", "America/Denver",
+        "Antarctica/Palmer", "Chile", "America/Santiago",
+        "Europe/Stockholm", "Europe_Central", "Europe/Paris",
+        "America/Bahia", "Brasilia", "America/Sao_Paulo",
+        "America/Danmarkshavn", "GMT", "Atlantic/Reykjavik",
+        "Indian/Mauritius", "Mauritius", "Indian/Mauritius",
+        "Pacific/Chatham", "Chatham", "Pacific/Chatham",
+        "Europe/Prague", "Europe_Central", "Europe/Paris",
+        "America/Blanc-Sablon", "Atlantic", "America/Halifax",
+        "America/Bogota", "Colombia", "America/Bogota",
+        "America/Managua", "America_Central", "America/Chicago",
+        "Pacific/Auckland", "New_Zealand", "Pacific/Auckland",
+        "Atlantic/Faroe", "Europe_Western", "Atlantic/Canary",
+        "America/Cambridge_Bay", "America_Mountain", "America/Denver",
+        "America/Los_Angeles", "America_Pacific", "America/Los_Angeles",
+        "Africa/Khartoum", "Africa_Eastern", "Africa/Nairobi",
+        "Europe/Simferopol", "Europe_Eastern", "Europe/Bucharest",
+        "Australia/Currie", "Australia_Eastern", "Australia/Sydney",
+        "Europe/Guernsey", "GMT", "Atlantic/Reykjavik",
+        "Asia/Thimphu", "Bhutan", "Asia/Thimphu",
+        "America/Eirunepe", "Amazon", "America/Manaus",
+        "Africa/Nairobi", "Africa_Eastern", "Africa/Nairobi",
+        "Asia/Yakutsk", "Yakutsk", "Asia/Yakutsk",
+        "America/Goose_Bay", "Atlantic", "America/Halifax",
+        "Africa/Maseru", "Africa_Southern", "Africa/Johannesburg",
+        "America/Swift_Current", "America_Central", "America/Chicago",
+        "America/Guyana", "Guyana", "America/Guyana",
+        "Asia/Tokyo", "Japan", "Asia/Tokyo",
+        "Indian/Kerguelen", "French_Southern", "Indian/Kerguelen",
+        "America/Belem", "Brasilia", "America/Sao_Paulo",
+        "Pacific/Wallis", "Wallis", "Pacific/Wallis",
+        "America/Whitehorse", "America_Pacific", "America/Los_Angeles",
+        "America/North_Dakota/Beulah", "America_Central", "America/Chicago",
+        "Asia/Jerusalem", "Israel", "Asia/Jerusalem",
+        "Antarctica/Syowa", "Syowa", "Antarctica/Syowa",
+        "America/Thunder_Bay", "America_Eastern", "America/New_York",
+        "Asia/Brunei", "Brunei", "Asia/Brunei",
+        "America/Metlakatla", "America_Pacific", "America/Los_Angeles",
+        "Asia/Dushanbe", "Tajikistan", "Asia/Dushanbe",
+        "Pacific/Kosrae", "Kosrae", "Pacific/Kosrae",
+        "America/Coral_Harbour", "America_Eastern", "America/New_York",
+        "America/Tortola", "Atlantic", "America/Halifax",
+        "Asia/Karachi", "Pakistan", "Asia/Karachi",
+        "Indian/Reunion", "Reunion", "Indian/Reunion",
+        "America/Detroit", "America_Eastern", "America/New_York",
+        "Australia/Eucla", "Australia_CentralWestern", "Australia/Eucla",
+        "Asia/Seoul", "Korea", "Asia/Seoul",
+        "Asia/Singapore", "Singapore", "Asia/Singapore",
+        "Africa/Casablanca", "Europe_Western", "Atlantic/Canary",
+        "Asia/Dili", "East_Timor", "Asia/Dili",
+        "America/Indiana/Vincennes", "America_Eastern", "America/New_York",
+        "Europe/Dublin", "GMT", "Atlantic/Reykjavik",
+        "America/St_Johns", "Newfoundland", "America/St_Johns",
+        "Antarctica/Macquarie", "Macquarie", "Antarctica/Macquarie",
+        "America/Port_of_Spain", "Atlantic", "America/Halifax",
+        "Europe/Budapest", "Europe_Central", "Europe/Paris",
+        "America/Fortaleza", "Brasilia", "America/Sao_Paulo",
+        "Australia/Brisbane", "Australia_Eastern", "Australia/Sydney",
+        "Atlantic/Bermuda", "Atlantic", "America/Halifax",
+        "Asia/Amman", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Tashkent", "Uzbekistan", "Asia/Tashkent",
+        "Antarctica/DumontDUrville", "DumontDUrville", "Antarctica/DumontDUrville",
+        "Antarctica/Casey", "Australia_Western", "Australia/Perth",
+        "Asia/Vientiane", "Indochina", "Asia/Saigon",
+        "Pacific/Johnston", "Hawaii_Aleutian", "Pacific/Honolulu",
+        "America/Jamaica", "America_Eastern", "America/New_York",
+        "Africa/Addis_Ababa", "Africa_Eastern", "Africa/Nairobi",
+        "Pacific/Ponape", "Ponape", "Pacific/Ponape",
+        "Europe/Jersey", "GMT", "Atlantic/Reykjavik",
+        "Africa/Lome", "GMT", "Atlantic/Reykjavik",
+        "America/Manaus", "Amazon", "America/Manaus",
+        "Africa/Niamey", "Africa_Western", "Africa/Lagos",
+        "Asia/Kashgar", "China", "Asia/Shanghai",
+        "Pacific/Tongatapu", "Tonga", "Pacific/Tongatapu",
+        "Europe/Minsk", "Europe_Eastern", "Europe/Bucharest",
+        "America/Edmonton", "America_Mountain", "America/Denver",
+        "Asia/Baghdad", "Arabian", "Asia/Riyadh",
+        "Asia/Kathmandu", "Nepal", "Asia/Katmandu",
+        "America/Ojinaga", "America_Mountain", "America/Denver",
+        "Africa/Abidjan", "GMT", "Atlantic/Reykjavik",
+        "America/Indiana/Winamac", "America_Eastern", "America/New_York",
+        "Asia/Qyzylorda", "Kazakhstan_Eastern", "Asia/Almaty",
+        "Australia/Sydney", "Australia_Eastern", "Australia/Sydney",
+        "Asia/Ashgabat", "Turkmenistan", "Asia/Ashgabat",
+        "Europe/Amsterdam", "Europe_Central", "Europe/Paris",
+        "America/Dawson_Creek", "America_Mountain", "America/Denver",
+        "Africa/Cairo", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Pyongyang", "Korea", "Asia/Seoul",
+        "Africa/Kampala", "Africa_Eastern", "Africa/Nairobi",
+        "America/Araguaina", "Brasilia", "America/Sao_Paulo",
+        "Asia/Novokuznetsk", "Novosibirsk", "Asia/Novosibirsk",
+        "Pacific/Kwajalein", "Marshall_Islands", "Pacific/Majuro",
+        "Africa/Lubumbashi", "Africa_Central", "Africa/Maputo",
+        "Asia/Sakhalin", "Sakhalin", "Asia/Sakhalin",
+        "America/Indiana/Vevay", "America_Eastern", "America/New_York",
+        "Africa/Maputo", "Africa_Central", "Africa/Maputo",
+        "Atlantic/Faeroe", "Europe_Western", "Atlantic/Canary",
+        "America/North_Dakota/Center", "America_Central", "America/Chicago",
+        "Pacific/Wake", "Wake", "Pacific/Wake",
+        "Pacific/Pago_Pago", "Samoa", "Pacific/Apia",
+        "America/Moncton", "Atlantic", "America/Halifax",
+        "Africa/Sao_Tome", "GMT", "Atlantic/Reykjavik",
+        "America/Glace_Bay", "Atlantic", "America/Halifax",
+        "Asia/Jakarta", "Indonesia_Western", "Asia/Jakarta",
+        "Africa/Asmera", "Africa_Eastern", "Africa/Nairobi",
+        "Europe/Lisbon", "Europe_Western", "Atlantic/Canary",
+        "America/Dawson", "America_Pacific", "America/Los_Angeles",
+        "America/Cayenne", "French_Guiana", "America/Cayenne",
+        "Asia/Bahrain", "Arabian", "Asia/Riyadh",
+        "Europe/Malta", "Europe_Central", "Europe/Paris",
+        "America/Indiana/Tell_City", "America_Central", "America/Chicago",
+        "America/Indiana/Petersburg", "America_Eastern", "America/New_York",
+        "Antarctica/Rothera", "Rothera", "Antarctica/Rothera",
+        "Asia/Aqtobe", "Kazakhstan_Western", "Asia/Aqtobe",
+        "Europe/Vaduz", "Europe_Central", "Europe/Paris",
+        "America/Indiana/Marengo", "America_Eastern", "America/New_York",
+        "Europe/Brussels", "Europe_Central", "Europe/Paris",
+        "Europe/Andorra", "Europe_Central", "Europe/Paris",
+        "America/Indiana/Knox", "America_Central", "America/Chicago",
+        "Pacific/Easter", "Easter", "Pacific/Easter",
+        "America/Argentina/Rio_Gallegos", "Argentina", "America/Buenos_Aires",
+        "Asia/Oral", "Kazakhstan_Western", "Asia/Aqtobe",
+        "Europe/Copenhagen", "Europe_Central", "Europe/Paris",
+        "Africa/Johannesburg", "Africa_Southern", "Africa/Johannesburg",
+        "Pacific/Pohnpei", "Ponape", "Pacific/Ponape",
+        "America/Argentina/Tucuman", "Argentina", "America/Buenos_Aires",
+        "America/Toronto", "America_Eastern", "America/New_York",
+        "Asia/Makassar", "Indonesia_Central", "Asia/Makassar",
+        "Europe/Berlin", "Europe_Central", "Europe/Paris",
+        "America/Argentina/Mendoza", "Argentina", "America/Buenos_Aires",
+        "America/Cuiaba", "Amazon", "America/Manaus",
+        "America/Creston", "America_Mountain", "America/Denver",
+        "Asia/Samarkand", "Uzbekistan", "Asia/Tashkent",
+        "Asia/Hovd", "Hovd", "Asia/Hovd",
+        "Europe/Bratislava", "Europe_Central", "Europe/Paris",
+        "Africa/Accra", "GMT", "Atlantic/Reykjavik",
+        "Africa/Douala", "Africa_Western", "Africa/Lagos",
+        "Africa/Nouakchott", "GMT", "Atlantic/Reykjavik",
+        "Europe/Sofia", "Europe_Eastern", "Europe/Bucharest",
+        "Antarctica/Davis", "Davis", "Antarctica/Davis",
+        "Antarctica/McMurdo", "New_Zealand", "Pacific/Auckland",
+        "Europe/San_Marino", "Europe_Central", "Europe/Paris",
+        "Africa/Porto-Novo", "Africa_Western", "Africa/Lagos",
+        "Asia/Jayapura", "Indonesia_Eastern", "Asia/Jayapura",
+        "America/St_Lucia", "Atlantic", "America/Halifax",
+        "America/Nipigon", "America_Eastern", "America/New_York",
+        "America/Argentina/Catamarca", "Argentina", "America/Buenos_Aires",
+        "Europe/Isle_of_Man", "GMT", "Atlantic/Reykjavik",
+        "America/Kentucky/Louisville", "America_Eastern", "America/New_York",
+        "America/Merida", "America_Central", "America/Chicago",
+        "Pacific/Marquesas", "Marquesas", "Pacific/Marquesas",
+        "Asia/Magadan", "Magadan", "Asia/Magadan",
+        "Africa/Libreville", "Africa_Western", "Africa/Lagos",
+        "Pacific/Efate", "Vanuatu", "Pacific/Efate",
+        "Asia/Kuala_Lumpur", "Malaysia", "Asia/Kuching",
+        "America/Iqaluit", "America_Eastern", "America/New_York",
+        "Indian/Comoro", "Africa_Eastern", "Africa/Nairobi",
+        "America/Panama", "America_Eastern", "America/New_York",
+        "Asia/Hebron", "Europe_Eastern", "Europe/Bucharest",
+        "America/Jujuy", "Argentina", "America/Buenos_Aires",
+        "America/Pangnirtung", "America_Eastern", "America/New_York",
+        "Asia/Tbilisi", "Georgia", "Asia/Tbilisi",
+        "Europe/Podgorica", "Europe_Central", "Europe/Paris",
+        "America/Boise", "America_Mountain", "America/Denver",
+        "Asia/Muscat", "Gulf", "Asia/Dubai",
+        "Indian/Mahe", "Seychelles", "Indian/Mahe",
+        "America/Montreal", "America_Eastern", "America/New_York",
+        "Africa/Bangui", "Africa_Western", "Africa/Lagos",
+        "America/Curacao", "Atlantic", "America/Halifax",
+        "Asia/Taipei", "Taipei", "Asia/Taipei",
+        "Europe/Ljubljana", "Europe_Central", "Europe/Paris",
+        "Atlantic/Stanley", "Falkland", "Atlantic/Stanley",
+        "Pacific/Guadalcanal", "Solomon", "Pacific/Guadalcanal",
+        "Asia/Kuwait", "Arabian", "Asia/Riyadh",
+        "Asia/Riyadh", "Arabian", "Asia/Riyadh",
+        "Europe/Tallinn", "Europe_Eastern", "Europe/Bucharest",
+        "America/New_York", "America_Eastern", "America/New_York",
+        "America/Paramaribo", "Suriname", "America/Paramaribo",
+        "America/Argentina/Buenos_Aires", "Argentina", "America/Buenos_Aires",
+        "Asia/Irkutsk", "Irkutsk", "Asia/Irkutsk",
+        "Asia/Katmandu", "Nepal", "Asia/Katmandu",
+        "America/Kralendijk", "Atlantic", "America/Halifax",
+    };
+    private static final String[] mzoneMap = new String[] {
+        "GMT", "ST", "Africa/Sao_Tome",
+        "GMT", "ML", "Africa/Bamako",
+        "GMT", "IE", "Europe/Dublin",
+        "GMT", "SN", "Africa/Dakar",
+        "GMT", "GH", "Africa/Accra",
+        "GMT", "CI", "Africa/Abidjan",
+        "GMT", "BF", "Africa/Ouagadougou",
+        "GMT", "MR", "Africa/Nouakchott",
+        "GMT", "GM", "Africa/Banjul",
+        "GMT", "SL", "Africa/Freetown",
+        "GMT", "GN", "Africa/Conakry",
+        "GMT", "SH", "Atlantic/St_Helena",
+        "GMT", "GB", "Europe/London",
+        "GMT", "LR", "Africa/Monrovia",
+        "GMT", "TG", "Africa/Lome",
+        "Africa_Western", "CF", "Africa/Bangui",
+        "Africa_Western", "NE", "Africa/Niamey",
+        "Africa_Western", "CM", "Africa/Douala",
+        "Africa_Western", "CD", "Africa/Kinshasa",
+        "Africa_Western", "CG", "Africa/Brazzaville",
+        "Africa_Western", "GA", "Africa/Libreville",
+        "Africa_Western", "TD", "Africa/Ndjamena",
+        "Africa_Western", "AO", "Africa/Luanda",
+        "Africa_Western", "GQ", "Africa/Malabo",
+        "Africa_Eastern", "YT", "Indian/Mayotte",
+        "Africa_Eastern", "UG", "Africa/Kampala",
+        "Africa_Eastern", "ET", "Africa/Addis_Ababa",
+        "Africa_Eastern", "MG", "Indian/Antananarivo",
+        "Africa_Eastern", "TZ", "Africa/Dar_es_Salaam",
+        "Africa_Eastern", "SO", "Africa/Mogadishu",
+        "Africa_Eastern", "ER", "Africa/Asmera",
+        "Africa_Eastern", "KM", "Indian/Comoro",
+        "Africa_Eastern", "DJ", "Africa/Djibouti",
+        "Europe_Central", "GI", "Europe/Gibraltar",
+        "Europe_Central", "DK", "Europe/Copenhagen",
+        "Europe_Central", "SE", "Europe/Stockholm",
+        "Europe_Central", "CH", "Europe/Zurich",
+        "Europe_Central", "AL", "Europe/Tirane",
+        "Europe_Central", "RS", "Europe/Belgrade",
+        "Europe_Central", "HU", "Europe/Budapest",
+        "Europe_Central", "MT", "Europe/Malta",
+        "Europe_Central", "PL", "Europe/Warsaw",
+        "Europe_Central", "ME", "Europe/Podgorica",
+        "Europe_Central", "ES", "Europe/Madrid",
+        "Europe_Central", "CZ", "Europe/Prague",
+        "Europe_Central", "IT", "Europe/Rome",
+        "Europe_Central", "SI", "Europe/Ljubljana",
+        "Europe_Central", "LI", "Europe/Vaduz",
+        "Europe_Central", "AT", "Europe/Vienna",
+        "Europe_Central", "VA", "Europe/Vatican",
+        "Europe_Central", "DE", "Europe/Berlin",
+        "Europe_Central", "NO", "Europe/Oslo",
+        "Europe_Central", "SK", "Europe/Bratislava",
+        "Europe_Central", "AD", "Europe/Andorra",
+        "Europe_Central", "SM", "Europe/San_Marino",
+        "Europe_Central", "MK", "Europe/Skopje",
+        "Europe_Central", "TN", "Africa/Tunis",
+        "Europe_Central", "HR", "Europe/Zagreb",
+        "Europe_Central", "NL", "Europe/Amsterdam",
+        "Europe_Central", "BE", "Europe/Brussels",
+        "Europe_Central", "MC", "Europe/Monaco",
+        "Europe_Central", "LU", "Europe/Luxembourg",
+        "Europe_Central", "BA", "Europe/Sarajevo",
+        "China", "MO", "Asia/Macau",
+        "America_Pacific", "MX", "America/Tijuana",
+        "America_Pacific", "CA", "America/Vancouver",
+        "Indochina", "LA", "Asia/Vientiane",
+        "Indochina", "KH", "Asia/Phnom_Penh",
+        "Indochina", "TH", "Asia/Bangkok",
+        "Korea", "KP", "Asia/Pyongyang",
+        "America_Mountain", "MX", "America/Hermosillo",
+        "America_Mountain", "CA", "America/Edmonton",
+        "Africa_Southern", "LS", "Africa/Maseru",
+        "Africa_Southern", "SZ", "Africa/Mbabane",
+        "Chile", "AQ", "Antarctica/Palmer",
+        "New_Zealand", "AQ", "Antarctica/McMurdo",
+        "Gulf", "OM", "Asia/Muscat",
+        "Europe_Western", "FO", "Atlantic/Faeroe",
+        "America_Eastern", "TC", "America/Grand_Turk",
+        "America_Eastern", "CA", "America/Toronto",
+        "America_Eastern", "BS", "America/Nassau",
+        "America_Eastern", "PA", "America/Panama",
+        "America_Eastern", "JM", "America/Jamaica",
+        "America_Eastern", "KY", "America/Cayman",
+        "Africa_Central", "BI", "Africa/Bujumbura",
+        "Africa_Central", "ZM", "Africa/Lusaka",
+        "Africa_Central", "ZW", "Africa/Harare",
+        "Africa_Central", "CD", "Africa/Lubumbashi",
+        "Africa_Central", "BW", "Africa/Gaborone",
+        "Africa_Central", "RW", "Africa/Kigali",
+        "Africa_Central", "MW", "Africa/Blantyre",
+        "America_Central", "MX", "America/Mexico_City",
+        "America_Central", "HN", "America/Tegucigalpa",
+        "America_Central", "CA", "America/Winnipeg",
+        "America_Central", "GT", "America/Guatemala",
+        "America_Central", "SV", "America/El_Salvador",
+        "America_Central", "CR", "America/Costa_Rica",
+        "America_Central", "BZ", "America/Belize",
+        "Atlantic", "MS", "America/Montserrat",
+        "Atlantic", "AG", "America/Antigua",
+        "Atlantic", "TT", "America/Port_of_Spain",
+        "Atlantic", "MQ", "America/Martinique",
+        "Atlantic", "DM", "America/Dominica",
+        "Atlantic", "KN", "America/St_Kitts",
+        "Atlantic", "BM", "Atlantic/Bermuda",
+        "Atlantic", "PR", "America/Puerto_Rico",
+        "Atlantic", "AW", "America/Aruba",
+        "Atlantic", "VG", "America/Tortola",
+        "Atlantic", "GD", "America/Grenada",
+        "Atlantic", "GL", "America/Thule",
+        "Atlantic", "BB", "America/Barbados",
+        "Atlantic", "BQ", "America/Kralendijk",
+        "Atlantic", "SX", "America/Lower_Princes",
+        "Atlantic", "VI", "America/St_Thomas",
+        "Atlantic", "MF", "America/Marigot",
+        "Atlantic", "AI", "America/Anguilla",
+        "Atlantic", "AN", "America/Curacao",
+        "Atlantic", "LC", "America/St_Lucia",
+        "Atlantic", "GP", "America/Guadeloupe",
+        "Atlantic", "VC", "America/St_Vincent",
+        "Arabian", "QA", "Asia/Qatar",
+        "Arabian", "YE", "Asia/Aden",
+        "Arabian", "KW", "Asia/Kuwait",
+        "Arabian", "BH", "Asia/Bahrain",
+        "Arabian", "IQ", "Asia/Baghdad",
+        "India", "LK", "Asia/Colombo",
+        "Europe_Eastern", "SY", "Asia/Damascus",
+        "Europe_Eastern", "BG", "Europe/Sofia",
+        "Europe_Eastern", "GR", "Europe/Athens",
+        "Europe_Eastern", "JO", "Asia/Amman",
+        "Europe_Eastern", "CY", "Asia/Nicosia",
+        "Europe_Eastern", "AX", "Europe/Mariehamn",
+        "Europe_Eastern", "LB", "Asia/Beirut",
+        "Europe_Eastern", "FI", "Europe/Helsinki",
+        "Europe_Eastern", "EG", "Africa/Cairo",
+        "Chamorro", "GU", "Pacific/Guam",
+    };
+    private static final String[] aliasMap = new String[] {
+        "Brazil/Acre", "America/Rio_Branco",
+        "US/Indiana-Starke", "America/Indiana/Knox",
+        "America/Atka", "America/Adak",
+        "America/St_Barthelemy", "America/Guadeloupe",
+        "Australia/North", "Australia/Darwin",
+        "Europe/Zagreb", "Europe/Belgrade",
+        "Etc/Universal", "Etc/UTC",
+        "NZ-CHAT", "Pacific/Chatham",
+        "Asia/Macao", "Asia/Macau",
+        "Pacific/Yap", "Pacific/Chuuk",
+        "Egypt", "Africa/Cairo",
+        "US/Central", "America/Chicago",
+        "Canada/Atlantic", "America/Halifax",
+        "Brazil/East", "America/Sao_Paulo",
+        "America/Cordoba", "America/Argentina/Cordoba",
+        "US/Hawaii", "Pacific/Honolulu",
+        "America/Louisville", "America/Kentucky/Louisville",
+        "America/Shiprock", "America/Denver",
+        "Australia/Canberra", "Australia/Sydney",
+        "Asia/Chungking", "Asia/Chongqing",
+        "Universal", "Etc/UTC",
+        "US/Alaska", "America/Anchorage",
+        "Asia/Ujung_Pandang", "Asia/Makassar",
+        "Japan", "Asia/Tokyo",
+        "Atlantic/Faeroe", "Atlantic/Faroe",
+        "Asia/Istanbul", "Europe/Istanbul",
+        "US/Pacific", "America/Los_Angeles",
+        "Mexico/General", "America/Mexico_City",
+        "Poland", "Europe/Warsaw",
+        "Africa/Asmera", "Africa/Asmara",
+        "Asia/Saigon", "Asia/Ho_Chi_Minh",
+        "US/Michigan", "America/Detroit",
+        "America/Argentina/ComodRivadavia", "America/Argentina/Catamarca",
+        "W-SU", "Europe/Moscow",
+        "Australia/ACT", "Australia/Sydney",
+        "Asia/Calcutta", "Asia/Kolkata",
+        "Arctic/Longyearbyen", "Europe/Oslo",
+        "America/Knox_IN", "America/Indiana/Knox",
+        "ROC", "Asia/Taipei",
+        "Zulu", "Etc/UTC",
+        "Australia/Yancowinna", "Australia/Broken_Hill",
+        "Australia/West", "Australia/Perth",
+        "Singapore", "Asia/Singapore",
+        "Europe/Mariehamn", "Europe/Helsinki",
+        "ROK", "Asia/Seoul",
+        "America/Porto_Acre", "America/Rio_Branco",
+        "Etc/Zulu", "Etc/UTC",
+        "Canada/Yukon", "America/Whitehorse",
+        "Europe/Vatican", "Europe/Rome",
+        "Africa/Timbuktu", "Africa/Bamako",
+        "America/Buenos_Aires", "America/Argentina/Buenos_Aires",
+        "Canada/Pacific", "America/Vancouver",
+        "US/Pacific-New", "America/Los_Angeles",
+        "Mexico/BajaNorte", "America/Tijuana",
+        "Europe/Guernsey", "Europe/London",
+        "Asia/Tel_Aviv", "Asia/Jerusalem",
+        "Chile/Continental", "America/Santiago",
+        "Jamaica", "America/Jamaica",
+        "Mexico/BajaSur", "America/Mazatlan",
+        "Canada/Eastern", "America/Toronto",
+        "Australia/Tasmania", "Australia/Hobart",
+        "NZ", "Pacific/Auckland",
+        "America/Lower_Princes", "America/Curacao",
+        "GMT-", "Etc/GMT",
+        "America/Rosario", "America/Argentina/Cordoba",
+        "Libya", "Africa/Tripoli",
+        "Asia/Ashkhabad", "Asia/Ashgabat",
+        "Australia/NSW", "Australia/Sydney",
+        "America/Marigot", "America/Guadeloupe",
+        "Europe/Bratislava", "Europe/Prague",
+        "Portugal", "Europe/Lisbon",
+        "Etc/GMT-", "Etc/GMT",
+        "Europe/San_Marino", "Europe/Rome",
+        "Europe/Sarajevo", "Europe/Belgrade",
+        "Antarctica/South_Pole", "Antarctica/McMurdo",
+        "Canada/Central", "America/Winnipeg",
+        "Etc/GMT", "Etc/GMT",
+        "Europe/Isle_of_Man", "Europe/London",
+        "America/Fort_Wayne", "America/Indiana/Indianapolis",
+        "Eire", "Europe/Dublin",
+        "America/Coral_Harbour", "America/Atikokan",
+        "Europe/Nicosia", "Asia/Nicosia",
+        "US/Samoa", "Pacific/Pago_Pago",
+        "Hongkong", "Asia/Hong_Kong",
+        "Canada/Saskatchewan", "America/Regina",
+        "Asia/Thimbu", "Asia/Thimphu",
+        "Kwajalein", "Pacific/Kwajalein",
+        "GB", "Europe/London",
+        "Chile/EasterIsland", "Pacific/Easter",
+        "US/East-Indiana", "America/Indiana/Indianapolis",
+        "Australia/LHI", "Australia/Lord_Howe",
+        "Cuba", "America/Havana",
+        "America/Jujuy", "America/Argentina/Jujuy",
+        "US/Mountain", "America/Denver",
+        "Atlantic/Jan_Mayen", "Europe/Oslo",
+        "Europe/Tiraspol", "Europe/Chisinau",
+        "Europe/Podgorica", "Europe/Belgrade",
+        "US/Arizona", "America/Phoenix",
+        "Navajo", "America/Denver",
+        "Etc/Greenwich", "Etc/GMT",
+        "Canada/Mountain", "America/Edmonton",
+        "Iceland", "Atlantic/Reykjavik",
+        "Australia/Victoria", "Australia/Melbourne",
+        "Australia/South", "Australia/Adelaide",
+        "Brazil/West", "America/Manaus",
+        "Pacific/Ponape", "Pacific/Pohnpei",
+        "Europe/Ljubljana", "Europe/Belgrade",
+        "Europe/Jersey", "Europe/London",
+        "Australia/Queensland", "Australia/Brisbane",
+        "UTC", "Etc/UTC",
+        "Canada/Newfoundland", "America/St_Johns",
+        "Europe/Skopje", "Europe/Belgrade",
+        "Canada/East-Saskatchewan", "America/Regina",
+        "PRC", "Asia/Shanghai",
+        "UCT", "Etc/UCT",
+        "America/Mendoza", "America/Argentina/Mendoza",
+        "Israel", "Asia/Jerusalem",
+        "US/Eastern", "America/New_York",
+        "Asia/Ulan_Bator", "Asia/Ulaanbaatar",
+        "Turkey", "Europe/Istanbul",
+        "GMT", "Etc/GMT",
+        "US/Aleutian", "America/Adak",
+        "Brazil/DeNoronha", "America/Noronha",
+        "GB-Eire", "Europe/London",
+        "Asia/Dacca", "Asia/Dhaka",
+        "America/Ensenada", "America/Tijuana",
+        "America/Catamarca", "America/Argentina/Catamarca",
+        "Iran", "Asia/Tehran",
+        "Greenwich", "Etc/GMT",
+        "Pacific/Truk", "Pacific/Chuuk",
+        "Pacific/Samoa", "Pacific/Pago_Pago",
+        "America/Virgin", "America/St_Thomas",
+        "Asia/Katmandu", "Asia/Kathmandu",
+        "America/Indianapolis", "America/Indiana/Indianapolis",
+        "Europe/Belfast", "Europe/London",
+        "America/Kralendijk", "America/Curacao",
+    };
+
+    private static final Map<String, String> zidToMzone = new HashMap<>();
+    private static final Map<String, String> mzoneToZid = new HashMap<>();
+    private static final Map<String, Map<String, String>> mzoneToZidL = new HashMap<>();
+    private static final Map<String, String> aliases = new HashMap<>();
+
+    static {
+        for (int i = 0; i < zidMap.length; i += 3) {
+            zidToMzone.put(zidMap[i], zidMap[i + 1]);
+            mzoneToZid.put(zidMap[i + 1], zidMap[i + 2]);
+        }
+
+        for (int i = 0; i < mzoneMap.length; i += 3) {
+            String mzone = mzoneMap[i];
+            Map<String, String> map = mzoneToZidL.get(mzone);
+            if (map == null) {
+                map = new HashMap<>();
+                mzoneToZidL.put(mzone, map);
+            }
+            map.put(mzoneMap[i + 1], mzoneMap[i + 2]);
+        }
+
+        for (int i = 0; i < aliasMap.length; i += 2) {
+            aliases.put(aliasMap[i], aliasMap[i + 1]);
+        }
+    }
+}
diff --git a/jdk/src/share/classes/java/time/format/package-info.java b/jdk/src/share/classes/java/time/format/package-info.java
index 9f96532..94a0600 100644
--- a/jdk/src/share/classes/java/time/format/package-info.java
+++ b/jdk/src/share/classes/java/time/format/package-info.java
@@ -68,7 +68,7 @@
  * Printing and parsing is based around the
  * {@link java.time.format.DateTimeFormatter DateTimeFormatter} class.
  * Instances are generally obtained from
- * {@link java.time.format.DateTimeFormatters DateTimeFormatters}, however
+ * {@link java.time.format.DateTimeFormatter DateTimeFormatter}, however
  * {@link java.time.format.DateTimeFormatterBuilder DateTimeFormatterBuilder}
  * can be used if more power is needed.
  * </p>
diff --git a/jdk/src/share/classes/java/time/overview.html b/jdk/src/share/classes/java/time/overview.html
index c522c4b..ef102f8 100644
--- a/jdk/src/share/classes/java/time/overview.html
+++ b/jdk/src/share/classes/java/time/overview.html
@@ -88,12 +88,6 @@
         The set of supported units and fields can be extended by applications if desired.
     </p>
     <p>
-        It also contains the basic part of the calendar neutral API.
-        This is intended for use by applications that need to use localized calendars.
-        Ensure that you read the class documentation of {@link java.time.temporal.ChronoLocalDate}
-        before using non-ISO calendar systems.
-    </p>
-    <p>
         {@link java.time.format} contains the API to print and parse fields into date-time
         objects and to customize parsing and printing.
         Formatters can be created in a variety of ways, including constants, patterns,
@@ -105,7 +99,8 @@
         Detailed information is made available about the rules of each time-zone.
     </p>
     <p>
-        The {@link java.time.calendar} package contains alternate calendar systems.
+        {@link java.time.chrono} contains the basic part of the calendar neutral API
+        and alternate calendar systems.
         This is intended for use by applications that need to use localized calendars.
         Support is provided for the Hijrah, Japanese, Minguo, and Thai Buddhist Calendars.
     </p>
@@ -136,7 +131,7 @@
         excessively complicated the API. Notably, there would be additional combinations at the offset
         and date-time levels, such as offset-date-hour-minute.
         To avoid this explosion of types, {@link java.time.LocalTime} is used for all precisions of time.
-        By contrast, some additional classes were used for dates, such as {@link java.time.temporal.YearMonth}.
+        By contrast, some additional classes were used for dates, such as {@link java.time.YearMonth}.
         This proved necessary, as the API for year-month is significantly different to that for a date, whereas
         an absence of nanoseconds in a time can be approximated by returning zero.
     </p>
@@ -161,7 +156,7 @@
     <p>
         There are, however, some limited use cases where users believe they need to store and use
         dates in arbitrary calendar systems throughout the application.
-        This is supported by {@link java.time.temporal.ChronoLocalDate}, however it is vital to read
+        This is supported by {@link java.time.chrono.ChronoLocalDate}, however it is vital to read
         all the associated warnings in the Javadoc of that interface before using it.
         In summary, applications that require general interoperation between multiple calendar systems
         typically need to be written in a very different way to those only using the ISO calendar,
diff --git a/jdk/src/share/classes/java/time/package-info.java b/jdk/src/share/classes/java/time/package-info.java
index 9d06ff9..5bc4283 100644
--- a/jdk/src/share/classes/java/time/package-info.java
+++ b/jdk/src/share/classes/java/time/package-info.java
@@ -79,13 +79,13 @@
  * Refer to the {@code java.time.format} package for customization options.
  * </p>
  * <p>
- * The {@code java.time.temporal} package also contains the calendar neutral API
- * {@link java.time.temporal.ChronoLocalDate ChronoLocalDate},
- * {@link java.time.temporal.ChronoLocalDateTime ChronoLocalDateTime},
- * {@link java.time.temporal.ChronoZonedDateTime ChronoZonedDateTime} and
- * {@link java.time.temporal.Era Era}.
+ * The {@code java.time.chrono} package contains the calendar neutral API
+ * {@link java.time.chrono.ChronoLocalDate ChronoLocalDate},
+ * {@link java.time.chrono.ChronoLocalDateTime ChronoLocalDateTime},
+ * {@link java.time.chrono.ChronoZonedDateTime ChronoZonedDateTime} and
+ * {@link java.time.chrono.Era Era}.
  * This is intended for use by applications that need to use localized calendars.
- * It is recommended that applications use the ISO-8601 dates and time classes from
+ * It is recommended that applications use the ISO-8601 date and time classes from
  * this package across system boundaries, such as to the database or across the network.
  * The calendar neutral API should be reserved for interactions with users.
  * </p>
@@ -135,29 +135,25 @@
  * This stores a single day-of-week in isolation, such as 'TUESDAY'.
  * </p>
  * <p>
- * {@link java.time.temporal.Year} stores a year on its own.
+ * {@link java.time.Year} stores a year on its own.
  * This stores a single year in isolation, such as '2010'.
  * </p>
  * <p>
- * {@link java.time.temporal.YearMonth} stores a year and month without a day or time.
+ * {@link java.time.YearMonth} stores a year and month without a day or time.
  * This stores a year and month, such as '2010-12' and could be used for a credit card expiry.
  * </p>
  * <p>
- * {@link java.time.temporal.MonthDay} stores a month and day without a year or time.
+ * {@link java.time.MonthDay} stores a month and day without a year or time.
  * This stores a month and day-of-month, such as '--12-03' and
  * could be used to store an annual event like a birthday without storing the year.
  * </p>
  * <p>
- * {@link java.time.temporal.OffsetTime} stores a time and offset from UTC without a date.
+ * {@link java.time.OffsetTime} stores a time and offset from UTC without a date.
  * This stores a date like '11:30+01:00'.
  * The {@link java.time.ZoneOffset ZoneOffset} is of the form '+01:00'.
  * </p>
  * <p>
- * {@link java.time.temporal.OffsetDate} stores a date and offset from UTC without a time.
- * This stores a time like '2010-12-03+01:00'.
- * </p>
- * <p>
- * {@link java.time.temporal.OffsetDateTime} stores a date and time and offset from UTC.
+ * {@link java.time.OffsetDateTime} stores a date and time and offset from UTC.
  * This stores a date-time like '2010-12-03T11:30+01:00'.
  * This is sometimes found in XML messages and other forms of persistence,
  * but contains less information than a full time-zone.
@@ -206,7 +202,7 @@
  * with the time-zone added at the user interface (UI) layer.
  * </p>
  * <p>
- * The offset-based date-time types, {@code OffsetDate}, {@code OffsetTime} and {@code OffsetDateTime},
+ * The offset-based date-time types {@code OffsetTime} and {@code OffsetDateTime},
  * are intended primarily for use with network protocols and database access.
  * For example, most databases cannot automatically store a time-zone like 'Europe/Paris', but
  * they can store an offset like '+02:00'.
@@ -261,7 +257,7 @@
  * <p>
  * There are, however, some limited use cases where users believe they need to store and use
  * dates in arbitrary calendar systems throughout the application.
- * This is supported by {@link java.time.temporal.ChronoLocalDate}, however it is vital to read
+ * This is supported by {@link java.time.chrono.ChronoLocalDate}, however it is vital to read
  * all the associated warnings in the Javadoc of that interface before using it.
  * In summary, applications that require general interoperation between multiple calendar systems
  * typically need to be written in a very different way to those only using the ISO calendar,
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoField.java b/jdk/src/share/classes/java/time/temporal/ChronoField.java
index f163654..2a42115 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoField.java
+++ b/jdk/src/share/classes/java/time/temporal/ChronoField.java
@@ -72,8 +72,10 @@
 
 import java.time.DayOfWeek;
 import java.time.Instant;
+import java.time.Year;
 import java.time.ZoneOffset;
-import java.time.format.DateTimeBuilder;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Chronology;
 
 /**
  * A standard set of fields.
@@ -521,6 +523,23 @@
         return rangeUnit;
     }
 
+    /**
+     * Gets the range of valid values for the field.
+     * <p>
+     * All fields can be expressed as a {@code long} integer.
+     * This method returns an object that describes the valid range for that value.
+     * <p>
+     * This method returns the range of the field in the ISO-8601 calendar system.
+     * This range may be incorrect for other calendar systems.
+     * Use {@link Chronology#range(ChronoField)} to access the correct range
+     * for a different calendar system.
+     * <p>
+     * Note that the result only describes the minimum and maximum valid values
+     * and it is important not to read too much into them. For example, there
+     * could be values within the range that are invalid for the field.
+     *
+     * @return the range of valid values for the field, not null
+     */
     @Override
     public ValueRange range() {
         return range;
@@ -551,6 +570,11 @@
      * <p>
      * This validates that the value is within the outer range of valid values
      * returned by {@link #range()}.
+     * <p>
+     * This method checks against the range of the field in the ISO-8601 calendar system.
+     * This range may be incorrect for other calendar systems.
+     * Use {@link Chronology#range(ChronoField)} to access the correct range
+     * for a different calendar system.
      *
      * @param value  the value to check
      * @return the value that was passed in
@@ -565,6 +589,11 @@
      * This validates that the value is within the outer range of valid values
      * returned by {@link #range()}.
      * It also checks that all valid values are within the bounds of an {@code int}.
+     * <p>
+     * This method checks against the range of the field in the ISO-8601 calendar system.
+     * This range may be incorrect for other calendar systems.
+     * Use {@link Chronology#range(ChronoField)} to access the correct range
+     * for a different calendar system.
      *
      * @param value  the value to check
      * @return the value that was passed in
@@ -575,34 +604,28 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public boolean doIsSupported(TemporalAccessor temporal) {
+    public boolean isSupportedBy(TemporalAccessor temporal) {
         return temporal.isSupported(this);
     }
 
     @Override
-    public ValueRange doRange(TemporalAccessor temporal) {
+    public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
         return temporal.range(this);
     }
 
     @Override
-    public long doGet(TemporalAccessor temporal) {
+    public long getFrom(TemporalAccessor temporal) {
         return temporal.getLong(this);
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public <R extends Temporal> R doWith(R temporal, long newValue) {
+    public <R extends Temporal> R adjustInto(R temporal, long newValue) {
         return (R) temporal.with(this, newValue);
     }
 
     //-----------------------------------------------------------------------
     @Override
-    public boolean resolve(DateTimeBuilder builder, long value) {
-        return false;  // resolve implemented in builder
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
     public String toString() {
         return getName();
     }
diff --git a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java
index 33f1318..0551858 100644
--- a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java
+++ b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java
@@ -57,6 +57,9 @@
 package java.time.temporal;
 
 import java.time.Duration;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
 
 /**
  * A standard set of date periods units.
@@ -254,7 +257,7 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public boolean isSupported(Temporal temporal) {
+    public boolean isSupportedBy(Temporal temporal) {
         if (this == FOREVER) {
             return false;
         }
@@ -264,19 +267,19 @@
         if (temporal instanceof ChronoLocalDateTime || temporal instanceof ChronoZonedDateTime) {
             return true;
         }
-        return TemporalUnit.super.isSupported(temporal);
+        return TemporalUnit.super.isSupportedBy(temporal);
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) {
-        return (R) dateTime.plus(periodToAdd, this);
+    public <R extends Temporal> R addTo(R temporal, long amount) {
+        return (R) temporal.plus(amount, this);
     }
 
     //-----------------------------------------------------------------------
     @Override
-    public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) {
-        return new SimplePeriod(dateTime1.periodUntil(dateTime2, this), this);
+    public long between(Temporal temporal1, Temporal temporal2) {
+        return temporal1.periodUntil(temporal2, this);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/src/share/classes/java/time/temporal/ISOFields.java b/jdk/src/share/classes/java/time/temporal/IsoFields.java
similarity index 76%
rename from jdk/src/share/classes/java/time/temporal/ISOFields.java
rename to jdk/src/share/classes/java/time/temporal/IsoFields.java
index 548d1d5..5e03c1c 100644
--- a/jdk/src/share/classes/java/time/temporal/ISOFields.java
+++ b/jdk/src/share/classes/java/time/temporal/IsoFields.java
@@ -72,7 +72,10 @@
 import java.time.DateTimeException;
 import java.time.Duration;
 import java.time.LocalDate;
-import java.time.format.DateTimeBuilder;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Fields and units specific to the ISO-8601 calendar system,
@@ -143,7 +146,7 @@
  *
  * @since 1.8
  */
-public final class ISOFields {
+public final class IsoFields {
 
     /**
      * The field that represents the day-of-quarter.
@@ -216,7 +219,7 @@
     /**
      * Restricted constructor.
      */
-    private ISOFields() {
+    private IsoFields() {
         throw new AssertionError("Not instantiable");
     }
 
@@ -243,19 +246,19 @@
                 return ValueRange.of(1, 90, 92);
             }
             @Override
-            public boolean doIsSupported(TemporalAccessor temporal) {
+            public boolean isSupportedBy(TemporalAccessor temporal) {
                 return temporal.isSupported(DAY_OF_YEAR) && temporal.isSupported(MONTH_OF_YEAR) &&
-                        temporal.isSupported(YEAR) && Chrono.from(temporal).equals(ISOChrono.INSTANCE);
+                        temporal.isSupported(YEAR) && isIso(temporal);
             }
             @Override
-            public ValueRange doRange(TemporalAccessor temporal) {
-                if (doIsSupported(temporal) == false) {
+            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+                if (isSupportedBy(temporal) == false) {
                     throw new DateTimeException("Unsupported field: DayOfQuarter");
                 }
                 long qoy = temporal.getLong(QUARTER_OF_YEAR);
                 if (qoy == 1) {
                     long year = temporal.getLong(YEAR);
-                    return (ISOChrono.INSTANCE.isLeapYear(year) ? ValueRange.of(1, 91) : ValueRange.of(1, 90));
+                    return (IsoChronology.INSTANCE.isLeapYear(year) ? ValueRange.of(1, 91) : ValueRange.of(1, 90));
                 } else if (qoy == 2) {
                     return ValueRange.of(1, 91);
                 } else if (qoy == 3 || qoy == 4) {
@@ -264,20 +267,37 @@
                 return range();
             }
             @Override
-            public long doGet(TemporalAccessor temporal) {
-                if (doIsSupported(temporal) == false) {
+            public long getFrom(TemporalAccessor temporal) {
+                if (isSupportedBy(temporal) == false) {
                     throw new DateTimeException("Unsupported field: DayOfQuarter");
                 }
                 int doy = temporal.get(DAY_OF_YEAR);
                 int moy = temporal.get(MONTH_OF_YEAR);
                 long year = temporal.getLong(YEAR);
-                return doy - QUARTER_DAYS[((moy - 1) / 3) + (ISOChrono.INSTANCE.isLeapYear(year) ? 4 : 0)];
+                return doy - QUARTER_DAYS[((moy - 1) / 3) + (IsoChronology.INSTANCE.isLeapYear(year) ? 4 : 0)];
+            }
+            @SuppressWarnings("unchecked")
+            @Override
+            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+                // calls getFrom() to check if supported
+                long curValue = getFrom(temporal);
+                range().checkValidValue(newValue, this);  // leniently check from 1 to 92 TODO: check
+                return (R) temporal.with(DAY_OF_YEAR, temporal.getLong(DAY_OF_YEAR) + (newValue - curValue));
             }
             @Override
-            public <R extends Temporal> R doWith(R temporal, long newValue) {
-                long curValue = doGet(temporal);
-                range().checkValidValue(newValue, this);
-                return (R) temporal.with(DAY_OF_YEAR, temporal.getLong(DAY_OF_YEAR) + (newValue - curValue));
+            public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long value) {
+                if ((temporal.isSupported(YEAR) && temporal.isSupported(DAY_OF_QUARTER)) == false) {
+                    return null;
+                }
+                int y = temporal.get(YEAR);
+                int qoy = temporal.get(QUARTER_OF_YEAR);
+                range().checkValidValue(value, this);  // leniently check from 1 to 92 TODO: check
+                LocalDate date = LocalDate.of(y, ((qoy - 1) * 3) + 1, 1).plusDays(value - 1);
+                Map<TemporalField, Long> result = new HashMap<>(4, 1.0f);
+                result.put(EPOCH_DAY, date.toEpochDay());
+                result.put(YEAR, null);
+                result.put(QUARTER_OF_YEAR, null);
+                return result;
             }
         },
         QUARTER_OF_YEAR {
@@ -298,36 +318,25 @@
                 return ValueRange.of(1, 4);
             }
             @Override
-            public boolean doIsSupported(TemporalAccessor temporal) {
-                return temporal.isSupported(MONTH_OF_YEAR) && Chrono.from(temporal).equals(ISOChrono.INSTANCE);
+            public boolean isSupportedBy(TemporalAccessor temporal) {
+                return temporal.isSupported(MONTH_OF_YEAR) && isIso(temporal);
             }
             @Override
-            public long doGet(TemporalAccessor temporal) {
-                if (doIsSupported(temporal) == false) {
-                    throw new DateTimeException("Unsupported field: DayOfQuarter");
+            public long getFrom(TemporalAccessor temporal) {
+                if (isSupportedBy(temporal) == false) {
+                    throw new DateTimeException("Unsupported field: QuarterOfYear");
                 }
                 long moy = temporal.getLong(MONTH_OF_YEAR);
                 return ((moy + 2) / 3);
             }
+            @SuppressWarnings("unchecked")
             @Override
-            public <R extends Temporal> R doWith(R temporal, long newValue) {
-                long curValue = doGet(temporal);
-                range().checkValidValue(newValue, this);
+            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+                // calls getFrom() to check if supported
+                long curValue = getFrom(temporal);
+                range().checkValidValue(newValue, this);  // strictly check from 1 to 4
                 return (R) temporal.with(MONTH_OF_YEAR, temporal.getLong(MONTH_OF_YEAR) + (newValue - curValue) * 3);
             }
-            @Override
-            public boolean resolve(DateTimeBuilder builder, long value) {
-                Long[] values = builder.queryFieldValues(YEAR, QUARTER_OF_YEAR, DAY_OF_QUARTER);
-                if (values[0] != null && values[1] != null && values[2] != null) {
-                    int y = YEAR.range().checkValidIntValue(values[0], YEAR);
-                    int qoy = QUARTER_OF_YEAR.range().checkValidIntValue(values[1], QUARTER_OF_YEAR);
-                    int doq = DAY_OF_QUARTER.range().checkValidIntValue(values[2], DAY_OF_QUARTER);
-                    LocalDate date = LocalDate.of(y, ((qoy - 1) * 3) + 1, 1).plusDays(doq - 1);
-                    builder.addFieldValue(EPOCH_DAY, date.toEpochDay());
-                    builder.removeFieldValues(QUARTER_OF_YEAR, DAY_OF_QUARTER);
-                }
-                return false;
-            }
         },
         WEEK_OF_WEEK_BASED_YEAR {
             @Override
@@ -347,21 +356,44 @@
                 return ValueRange.of(1, 52, 53);
             }
             @Override
-            public boolean doIsSupported(TemporalAccessor temporal) {
-                return temporal.isSupported(EPOCH_DAY);
+            public boolean isSupportedBy(TemporalAccessor temporal) {
+                return temporal.isSupported(EPOCH_DAY) && isIso(temporal);
             }
             @Override
-            public ValueRange doRange(TemporalAccessor temporal) {
+            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+                if (isSupportedBy(temporal) == false) {
+                    throw new DateTimeException("Unsupported field: WeekOfWeekBasedYear");
+                }
                 return getWeekRange(LocalDate.from(temporal));
             }
             @Override
-            public long doGet(TemporalAccessor temporal) {
+            public long getFrom(TemporalAccessor temporal) {
+                if (isSupportedBy(temporal) == false) {
+                    throw new DateTimeException("Unsupported field: WeekOfWeekBasedYear");
+                }
                 return getWeek(LocalDate.from(temporal));
             }
+            @SuppressWarnings("unchecked")
             @Override
-            public <R extends Temporal> R doWith(R temporal, long newValue) {
-                ValueRange.of(1, 53).checkValidValue(newValue, this);
-                return (R) temporal.plus(Math.subtractExact(newValue, doGet(temporal)), WEEKS);
+            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+                // calls getFrom() to check if supported
+                range().checkValidValue(newValue, this);  // lenient range
+                return (R) temporal.plus(Math.subtractExact(newValue, getFrom(temporal)), WEEKS);
+            }
+            @Override
+            public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long value) {
+                if ((temporal.isSupported(WEEK_BASED_YEAR) && temporal.isSupported(DAY_OF_WEEK)) == false) {
+                    return null;
+                }
+                int wby = temporal.get(WEEK_BASED_YEAR);
+                int dow = temporal.get(DAY_OF_WEEK);
+                range().checkValidValue(value, this);  // lenient range
+                LocalDate date = LocalDate.of(wby, 1, 4).plusWeeks(value - 1).with(DAY_OF_WEEK, dow);
+                Map<TemporalField, Long> result = new HashMap<>(2, 1.0f);
+                result.put(EPOCH_DAY, date.toEpochDay());
+                result.put(WEEK_BASED_YEAR, null);
+                result.put(DAY_OF_WEEK, null);
+                return result;
             }
         },
         WEEK_BASED_YEAR {
@@ -382,47 +414,36 @@
                 return YEAR.range();
             }
             @Override
-            public boolean doIsSupported(TemporalAccessor temporal) {
-                return temporal.isSupported(EPOCH_DAY);
+            public boolean isSupportedBy(TemporalAccessor temporal) {
+                return temporal.isSupported(EPOCH_DAY) && isIso(temporal);
             }
             @Override
-            public long doGet(TemporalAccessor temporal) {
+            public long getFrom(TemporalAccessor temporal) {
+                if (isSupportedBy(temporal) == false) {
+                    throw new DateTimeException("Unsupported field: WeekBasedYear");
+                }
                 return getWeekBasedYear(LocalDate.from(temporal));
             }
+            @SuppressWarnings("unchecked")
             @Override
-            public <R extends Temporal> R doWith(R temporal, long newValue) {
-                int newVal = range().checkValidIntValue(newValue, WEEK_BASED_YEAR);
+            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+                if (isSupportedBy(temporal) == false) {
+                    throw new DateTimeException("Unsupported field: WeekBasedYear");
+                }
+                int newVal = range().checkValidIntValue(newValue, WEEK_BASED_YEAR);  // strict check
                 LocalDate date = LocalDate.from(temporal);
                 int week = getWeek(date);
                 date = date.withDayOfYear(180).withYear(newVal).with(WEEK_OF_WEEK_BASED_YEAR, week);
                 return (R) date.with(date);
             }
-            @Override
-            public boolean resolve(DateTimeBuilder builder, long value) {
-                Long[] values = builder.queryFieldValues(WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, DAY_OF_WEEK);
-                if (values[0] != null && values[1] != null && values[2] != null) {
-                    int wby = WEEK_BASED_YEAR.range().checkValidIntValue(values[0], WEEK_BASED_YEAR);
-                    int week = WEEK_OF_WEEK_BASED_YEAR.range().checkValidIntValue(values[1], WEEK_OF_WEEK_BASED_YEAR);
-                    int dow = DAY_OF_WEEK.range().checkValidIntValue(values[2], DAY_OF_WEEK);
-                    LocalDate date = LocalDate.of(wby, 2, 1).with(WEEK_OF_WEEK_BASED_YEAR, week).with(DAY_OF_WEEK, dow);
-                    builder.addFieldValue(EPOCH_DAY, date.toEpochDay());
-                    builder.removeFieldValues(WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, DAY_OF_WEEK);
-                }
-                return false;
-            }
         };
 
         @Override
-        public ValueRange doRange(TemporalAccessor temporal) {
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
             return range();
         }
 
         @Override
-        public boolean resolve(DateTimeBuilder builder, long value) {
-            return false;
-        }
-
-        @Override
         public String toString() {
             return getName();
         }
@@ -430,6 +451,10 @@
         //-------------------------------------------------------------------------
         private static final int[] QUARTER_DAYS = {0, 90, 181, 273, 0, 91, 182, 274};
 
+        private static boolean isIso(TemporalAccessor temporal) {
+            return Chronology.from(temporal).equals(IsoChronology.INSTANCE);
+        }
+
         private static ValueRange getWeekRange(LocalDate date) {
             int wby = getWeekBasedYear(date);
             date = date.withDayOfYear(1).withYear(wby);
@@ -520,36 +545,34 @@
         }
 
         @Override
-        public boolean isSupported(Temporal temporal) {
+        public boolean isSupportedBy(Temporal temporal) {
             return temporal.isSupported(EPOCH_DAY);
         }
 
+        @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) {
+        public <R extends Temporal> R addTo(R temporal, long amount) {
             switch(this) {
                 case WEEK_BASED_YEARS:
-                    return (R) dateTime.with(WEEK_BASED_YEAR,
-                            Math.addExact(dateTime.get(WEEK_BASED_YEAR), periodToAdd));
+                    return (R) temporal.with(WEEK_BASED_YEAR,
+                            Math.addExact(temporal.get(WEEK_BASED_YEAR), amount));
                 case QUARTER_YEARS:
                     // no overflow (256 is multiple of 4)
-                    return (R) dateTime.plus(periodToAdd / 256, YEARS)
-                            .plus((periodToAdd % 256) * 3, MONTHS);
+                    return (R) temporal.plus(amount / 256, YEARS)
+                            .plus((amount % 256) * 3, MONTHS);
                 default:
                     throw new IllegalStateException("Unreachable");
             }
         }
 
         @Override
-        public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) {
+        public long between(Temporal temporal1, Temporal temporal2) {
             switch(this) {
                 case WEEK_BASED_YEARS:
-                    long period = Math.subtractExact(dateTime2.getLong(WEEK_BASED_YEAR),
-                            dateTime1.getLong(WEEK_BASED_YEAR));
-                    return new SimplePeriod(period, WEEK_BASED_YEARS);
+                    return Math.subtractExact(temporal2.getLong(WEEK_BASED_YEAR),
+                            temporal1.getLong(WEEK_BASED_YEAR));
                 case QUARTER_YEARS:
-                    long period2 = Math.subtractExact(dateTime2.getLong(QUARTER_OF_YEAR),
-                            dateTime1.getLong(QUARTER_OF_YEAR));
-                    return new SimplePeriod(period2, QUARTER_YEARS);
+                    return temporal1.periodUntil(temporal2, MONTHS) / 3;
                 default:
                     throw new IllegalStateException("Unreachable");
             }
diff --git a/jdk/src/share/classes/java/time/temporal/JulianFields.java b/jdk/src/share/classes/java/time/temporal/JulianFields.java
index 79a9e96..d0a9d87 100644
--- a/jdk/src/share/classes/java/time/temporal/JulianFields.java
+++ b/jdk/src/share/classes/java/time/temporal/JulianFields.java
@@ -65,11 +65,9 @@
 import static java.time.temporal.ChronoUnit.DAYS;
 import static java.time.temporal.ChronoUnit.FOREVER;
 
-import java.io.InvalidObjectException;
-import java.io.Serializable;
 import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.format.DateTimeBuilder;
+import java.util.Collections;
+import java.util.Map;
 
 /**
  * A set of date fields that provide access to Julian Days.
@@ -77,6 +75,10 @@
  * The Julian Day is a standard way of expressing date and time commonly used in the scientific community.
  * It is expressed as a decimal number of whole days where days start at midday.
  * This class represents variations on Julian Days that count whole days from midnight.
+ * <p>
+ * The fields are implemented relative to {@link ChronoField#EPOCH_DAY EPOCH_DAY}.
+ * The fields are supported, and can be queried and set if {@code EPOCH_DAY} is available.
+ * The fields work with all chronologies.
  *
  * <h3>Specification for implementors</h3>
  * This is an immutable and thread-safe class.
@@ -99,10 +101,10 @@
      * The field  has "JulianDay" as 'name', and 'DAYS' as 'baseUnit'.
      * The field always refers to the local date-time, ignoring the offset or zone.
      * <p>
-     * For date-times, 'JULIAN_DAY.doGet()' assumes the same value from
+     * For date-times, 'JULIAN_DAY.getFrom()' assumes the same value from
      * midnight until just before the next midnight.
-     * When 'JULIAN_DAY.doWith()' is applied to a date-time, the time of day portion remains unaltered.
-     * 'JULIAN_DAY.doWith()' and 'JULIAN_DAY.doGet()' only apply to {@code Temporal} objects that
+     * When 'JULIAN_DAY.adjustInto()' is applied to a date-time, the time of day portion remains unaltered.
+     * 'JULIAN_DAY.adjustInto()' and 'JULIAN_DAY.getFrom()' only apply to {@code Temporal} objects that
      * can be converted into {@link ChronoField#EPOCH_DAY}.
      * A {@link DateTimeException} is thrown for any other type of object.
      * <p>
@@ -129,7 +131,7 @@
      * implementation always uses the Julian Day number for the local date,
      * regardless of the offset or time-zone.
      */
-    public static final TemporalField JULIAN_DAY = new Field("JulianDay", DAYS, FOREVER, JULIAN_DAY_OFFSET);
+    public static final TemporalField JULIAN_DAY = Field.JULIAN_DAY;
 
     /**
      * Modified Julian Day field.
@@ -140,10 +142,10 @@
      * Each Modified Julian Day runs from midnight to midnight.
      * The field always refers to the local date-time, ignoring the offset or zone.
      * <p>
-     * For date-times, 'MODIFIED_JULIAN_DAY.doGet()' assumes the same value from
+     * For date-times, 'MODIFIED_JULIAN_DAY.getFrom()' assumes the same value from
      * midnight until just before the next midnight.
-     * When 'MODIFIED_JULIAN_DAY.doWith()' is applied to a date-time, the time of day portion remains unaltered.
-     * 'MODIFIED_JULIAN_DAY.doWith()' and 'MODIFIED_JULIAN_DAY.doGet()' only apply to {@code Temporal} objects
+     * When 'MODIFIED_JULIAN_DAY.adjustInto()' is applied to a date-time, the time of day portion remains unaltered.
+     * 'MODIFIED_JULIAN_DAY.adjustInto()' and 'MODIFIED_JULIAN_DAY.getFrom()' only apply to {@code Temporal} objects
      * that can be converted into {@link ChronoField#EPOCH_DAY}.
      * A {@link DateTimeException} is thrown for any other type of object.
      * <p>
@@ -165,7 +167,7 @@
      * implementation always uses the Modified Julian Day for the local date,
      * regardless of the offset or time-zone.
      */
-    public static final TemporalField MODIFIED_JULIAN_DAY = new Field("ModifiedJulianDay", DAYS, FOREVER, 40587L);
+    public static final TemporalField MODIFIED_JULIAN_DAY = Field.MODIFIED_JULIAN_DAY;
 
     /**
      * Rata Die field.
@@ -173,14 +175,14 @@
      * Rata Die counts whole days continuously starting day 1 at midnight at the beginning of 0001-01-01 (ISO).
      * The field always refers to the local date-time, ignoring the offset or zone.
      * <p>
-     * For date-times, 'RATA_DIE.doGet()' assumes the same value from
+     * For date-times, 'RATA_DIE.getFrom()' assumes the same value from
      * midnight until just before the next midnight.
-     * When 'RATA_DIE.doWith()' is applied to a date-time, the time of day portion remains unaltered.
-     * 'MODIFIED_JULIAN_DAY.doWith()' and 'RATA_DIE.doGet()' only apply to {@code Temporal} objects
+     * When 'RATA_DIE.adjustInto()' is applied to a date-time, the time of day portion remains unaltered.
+     * 'RATA_DIE.adjustInto()' and 'RATA_DIE.getFrom()' only apply to {@code Temporal} objects
      * that can be converted into {@link ChronoField#EPOCH_DAY}.
      * A {@link DateTimeException} is thrown for any other type of object.
      */
-    public static final TemporalField RATA_DIE = new Field("RataDie", DAYS, FOREVER, 719163L);
+    public static final TemporalField RATA_DIE = Field.RATA_DIE;
 
     /**
      * Restricted constructor.
@@ -190,13 +192,16 @@
     }
 
     /**
-     * implementation of JulianFields.  Each instance is a singleton.
+     * Implementation of JulianFields.  Each instance is a singleton.
      */
-    private static class Field implements TemporalField, Serializable {
+    private static enum Field implements TemporalField {
+        JULIAN_DAY("JulianDay", DAYS, FOREVER, JULIAN_DAY_OFFSET),
+        MODIFIED_JULIAN_DAY("ModifiedJulianDay", DAYS, FOREVER, 40587L),
+        RATA_DIE("RataDie", DAYS, FOREVER, 719163L);
 
         private static final long serialVersionUID = -7501623920830201812L;
 
-        private final String name;
+        private final transient String name;
         private final transient TemporalUnit baseUnit;
         private final transient TemporalUnit rangeUnit;
         private final transient ValueRange range;
@@ -210,25 +215,6 @@
             this.offset = offset;
         }
 
-
-        /**
-         * Resolve the object from the stream to the appropriate singleton.
-         * @return one of the singleton objects {@link #JULIAN_DAY},
-         *     {@link #MODIFIED_JULIAN_DAY}, or {@link #RATA_DIE}.
-         * @throws InvalidObjectException if the object in the stream is not one of the singletons.
-         */
-        private Object readResolve() throws InvalidObjectException {
-            if (JULIAN_DAY.getName().equals(name)) {
-                return JULIAN_DAY;
-            } else if (MODIFIED_JULIAN_DAY.getName().equals(name)) {
-                return MODIFIED_JULIAN_DAY;
-            } else if (RATA_DIE.getName().equals(name)) {
-                return RATA_DIE;
-            } else {
-                throw new InvalidObjectException("Not one of the singletons");
-            }
-        }
-
         //-----------------------------------------------------------------------
         @Override
         public String getName() {
@@ -252,25 +238,26 @@
 
         //-----------------------------------------------------------------------
         @Override
-        public boolean doIsSupported(TemporalAccessor temporal) {
+        public boolean isSupportedBy(TemporalAccessor temporal) {
             return temporal.isSupported(EPOCH_DAY);
         }
 
         @Override
-        public ValueRange doRange(TemporalAccessor temporal) {
-            if (doIsSupported(temporal) == false) {
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+            if (isSupportedBy(temporal) == false) {
                 throw new DateTimeException("Unsupported field: " + this);
             }
             return range();
         }
 
         @Override
-        public long doGet(TemporalAccessor temporal) {
+        public long getFrom(TemporalAccessor temporal) {
             return temporal.getLong(EPOCH_DAY) + offset;
         }
 
+        @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doWith(R temporal, long newValue) {
+        public <R extends Temporal> R adjustInto(R temporal, long newValue) {
             if (range().isValidValue(newValue) == false) {
                 throw new DateTimeException("Invalid value: " + name + " " + newValue);
             }
@@ -279,27 +266,14 @@
 
         //-----------------------------------------------------------------------
         @Override
-        public boolean resolve(DateTimeBuilder builder, long value) {
-            boolean changed = false;
-            changed = resolve0(JULIAN_DAY, builder, changed);
-            changed = resolve0(MODIFIED_JULIAN_DAY, builder, changed);
-            changed = resolve0(RATA_DIE, builder, changed);
-            return changed;
-        }
-
-        private boolean resolve0(TemporalField field, DateTimeBuilder builder, boolean changed) {
-            if (builder.containsFieldValue(field)) {
-                builder.addCalendrical(LocalDate.ofEpochDay(Math.subtractExact(builder.getFieldValue(JULIAN_DAY), JULIAN_DAY_OFFSET)));
-                builder.removeFieldValue(JULIAN_DAY);
-                changed = true;
-            }
-            return changed;
+        public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long value) {
+            return Collections.<TemporalField, Long>singletonMap(EPOCH_DAY, Math.subtractExact(value, offset));
         }
 
         //-----------------------------------------------------------------------
         @Override
         public String toString() {
-            return getName();
+            return name;
         }
     }
 }
diff --git a/jdk/src/share/classes/java/time/temporal/OffsetDate.java b/jdk/src/share/classes/java/time/temporal/OffsetDate.java
deleted file mode 100644
index 2503de9..0000000
--- a/jdk/src/share/classes/java/time/temporal/OffsetDate.java
+++ /dev/null
@@ -1,1351 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.temporal;
-
-import static java.time.temporal.ChronoField.EPOCH_DAY;
-import static java.time.temporal.ChronoField.OFFSET_SECONDS;
-import static java.time.temporal.ChronoLocalDateTimeImpl.SECONDS_PER_DAY;
-import static java.time.temporal.ChronoUnit.DAYS;
-
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.DayOfWeek;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.Month;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
-import java.time.format.DateTimeParseException;
-import java.time.zone.ZoneRules;
-import java.util.Objects;
-
-/**
- * A date with an offset from UTC/Greenwich in the ISO-8601 calendar system,
- * such as {@code 2007-12-03+01:00}.
- * <p>
- * {@code OffsetDate} is an immutable date-time object that represents a date, often viewed
- * as year-month-day-offset. This object can also access other date fields such as
- * day-of-year, day-of-week and week-of-year.
- * <p>
- * This class does not store or represent a time.
- * For example, the value "2nd October 2007 +02:00" can be stored
- * in an {@code OffsetDate}.
- *
- * <h3>Specification for implementors</h3>
- * This class is immutable and thread-safe.
- *
- * @since 1.8
- */
-public final class OffsetDate
-        implements Temporal, TemporalAdjuster, Comparable<OffsetDate>, Serializable {
-
-    /**
-     * The minimum supported {@code OffsetDate}, '-999999999-01-01+18:00'.
-     * This is the minimum local date in the maximum offset
-     * (larger offsets are earlier on the time-line).
-     * This combines {@link LocalDate#MIN} and {@link ZoneOffset#MAX}.
-     * This could be used by an application as a "far past" date.
-     */
-    public static final OffsetDate MIN = LocalDate.MIN.atOffset(ZoneOffset.MAX);
-    /**
-     * The maximum supported {@code OffsetDate}, '+999999999-12-31-18:00'.
-     * This is the maximum local date in the minimum offset
-     * (larger negative offsets are later on the time-line).
-     * This combines {@link LocalDate#MAX} and {@link ZoneOffset#MIN}.
-     * This could be used by an application as a "far future" date.
-     */
-    public static final OffsetDate MAX = LocalDate.MAX.atOffset(ZoneOffset.MIN);
-
-    /**
-     * Serialization version.
-     */
-    private static final long serialVersionUID = -4382054179074397774L;
-
-    /**
-     * The local date.
-     */
-    private final LocalDate date;
-    /**
-     * The offset from UTC/Greenwich.
-     */
-    private final ZoneOffset offset;
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains the current date from the system clock in the default time-zone.
-     * <p>
-     * This will query the {@link java.time.Clock#systemDefaultZone() system clock} in the default
-     * time-zone to obtain the current date.
-     * The offset will be calculated from the time-zone in the clock.
-     * <p>
-     * Using this method will prevent the ability to use an alternate clock for testing
-     * because the clock is hard-coded.
-     *
-     * @return the current date using the system clock, not null
-     */
-    public static OffsetDate now() {
-        return now(Clock.systemDefaultZone());
-    }
-
-    /**
-     * Obtains the current date from the system clock in the specified time-zone.
-     * <p>
-     * This will query the {@link Clock#system(java.time.ZoneId) system clock} to obtain the current date.
-     * Specifying the time-zone avoids dependence on the default time-zone.
-     * The offset will be calculated from the specified time-zone.
-     * <p>
-     * Using this method will prevent the ability to use an alternate clock for testing
-     * because the clock is hard-coded.
-     *
-     * @param zone  the zone ID to use, not null
-     * @return the current date using the system clock, not null
-     */
-    public static OffsetDate now(ZoneId zone) {
-        return now(Clock.system(zone));
-    }
-
-    /**
-     * Obtains the current date from the specified clock.
-     * <p>
-     * This will query the specified clock to obtain the current date - today.
-     * The offset will be calculated from the time-zone in the clock.
-     * <p>
-     * Using this method allows the use of an alternate clock for testing.
-     * The alternate clock may be introduced using {@link Clock dependency injection}.
-     *
-     * @param clock  the clock to use, not null
-     * @return the current date, not null
-     */
-    public static OffsetDate now(Clock clock) {
-        Objects.requireNonNull(clock, "clock");
-        final Instant now = clock.instant();  // called once
-        return ofInstant(now, clock.getZone().getRules().getOffset(now));
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains an instance of {@code OffsetDate} from a local date and an offset.
-     *
-     * @param date  the local date, not null
-     * @param offset  the zone offset, not null
-     * @return the offset date, not null
-     */
-    public static OffsetDate of(LocalDate date, ZoneOffset offset) {
-        return new OffsetDate(date, offset);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains an instance of {@code OffsetDate} from an {@code Instant} and zone ID.
-     * <p>
-     * This creates an offset date with the same instant as midnight at the
-     * start of day of the instant specified.
-     * Finding the offset from UTC/Greenwich is simple as there is only one valid
-     * offset for each instant.
-     *
-     * @param instant  the instant to create the time from, not null
-     * @param zone  the time-zone, which may be an offset, not null
-     * @return the offset time, not null
-     */
-    public static OffsetDate ofInstant(Instant instant, ZoneId zone) {
-        Objects.requireNonNull(instant, "instant");
-        Objects.requireNonNull(zone, "zone");
-        ZoneRules rules = zone.getRules();
-        ZoneOffset offset = rules.getOffset(instant);
-        long epochSec = instant.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
-        long epochDay = Math.floorDiv(epochSec, SECONDS_PER_DAY);
-        LocalDate date = LocalDate.ofEpochDay(epochDay);
-        return new OffsetDate(date, offset);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains an instance of {@code OffsetDate} from a temporal object.
-     * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code OffsetDate}.
-     * <p>
-     * The conversion extracts and combines {@code LocalDate} and {@code ZoneOffset}.
-     * <p>
-     * This method matches the signature of the functional interface {@link TemporalQuery}
-     * allowing it to be used in queries via method reference, {@code OffsetDate::from}.
-     *
-     * @param temporal  the temporal object to convert, not null
-     * @return the offset date, not null
-     * @throws DateTimeException if unable to convert to an {@code OffsetDate}
-     */
-    public static OffsetDate from(TemporalAccessor temporal) {
-        if (temporal instanceof OffsetDate) {
-            return (OffsetDate) temporal;
-        }
-        try {
-            LocalDate date = LocalDate.from(temporal);
-            ZoneOffset offset = ZoneOffset.from(temporal);
-            return new OffsetDate(date, offset);
-        } catch (DateTimeException ex) {
-            throw new DateTimeException("Unable to obtain OffsetDate from TemporalAccessor: " + temporal.getClass(), ex);
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains an instance of {@code OffsetDate} from a text string such as {@code 2007-12-03+01:00}.
-     * <p>
-     * The string must represent a valid date and is parsed using
-     * {@link java.time.format.DateTimeFormatters#isoOffsetDate()}.
-     *
-     * @param text  the text to parse such as "2007-12-03+01:00", not null
-     * @return the parsed offset date, not null
-     * @throws DateTimeParseException if the text cannot be parsed
-     */
-    public static OffsetDate parse(CharSequence text) {
-        return parse(text, DateTimeFormatters.isoOffsetDate());
-    }
-
-    /**
-     * Obtains an instance of {@code OffsetDate} from a text string using a specific formatter.
-     * <p>
-     * The text is parsed using the formatter, returning a date.
-     *
-     * @param text  the text to parse, not null
-     * @param formatter  the formatter to use, not null
-     * @return the parsed offset date, not null
-     * @throws DateTimeParseException if the text cannot be parsed
-     */
-    public static OffsetDate parse(CharSequence text, DateTimeFormatter formatter) {
-        Objects.requireNonNull(formatter, "formatter");
-        return formatter.parse(text, OffsetDate::from);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Constructor.
-     *
-     * @param date  the local date, not null
-     * @param offset  the zone offset, not null
-     */
-    private OffsetDate(LocalDate date, ZoneOffset offset) {
-        this.date = Objects.requireNonNull(date, "date");
-        this.offset = Objects.requireNonNull(offset, "offset");
-    }
-
-    /**
-     * Returns a new date based on this one, returning {@code this} where possible.
-     *
-     * @param date  the date to create with, not null
-     * @param offset  the zone offset to create with, not null
-     */
-    private OffsetDate with(LocalDate date, ZoneOffset offset) {
-        if (this.date == date && this.offset.equals(offset)) {
-            return this;
-        }
-        return new OffsetDate(date, offset);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks if the specified field is supported.
-     * <p>
-     * This checks if this date can be queried for the specified field.
-     * If false, then calling the {@link #range(TemporalField) range} and
-     * {@link #get(TemporalField) get} methods will throw an exception.
-     * <p>
-     * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return valid
-     * values based on this date-time.
-     * The supported fields are:
-     * <ul>
-     * <li>{@code DAY_OF_WEEK}
-     * <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH}
-     * <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR}
-     * <li>{@code DAY_OF_MONTH}
-     * <li>{@code DAY_OF_YEAR}
-     * <li>{@code EPOCH_DAY}
-     * <li>{@code ALIGNED_WEEK_OF_MONTH}
-     * <li>{@code ALIGNED_WEEK_OF_YEAR}
-     * <li>{@code MONTH_OF_YEAR}
-     * <li>{@code EPOCH_MONTH}
-     * <li>{@code YEAR_OF_ERA}
-     * <li>{@code YEAR}
-     * <li>{@code ERA}
-     * <li>{@code OFFSET_SECONDS}
-     * </ul>
-     * All other {@code ChronoField} instances will return false.
-     * <p>
-     * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
-     * passing {@code this} as the argument.
-     * Whether the field is supported is determined by the field.
-     *
-     * @param field  the field to check, null returns false
-     * @return true if the field is supported on this date, false if not
-     */
-    @Override
-    public boolean isSupported(TemporalField field) {
-        if (field instanceof ChronoField) {
-            return ((ChronoField) field).isDateField() || field == OFFSET_SECONDS;
-        }
-        return field != null && field.doIsSupported(this);
-    }
-
-    /**
-     * Gets the range of valid values for the specified field.
-     * <p>
-     * The range object expresses the minimum and maximum valid values for a field.
-     * This date is used to enhance the accuracy of the returned range.
-     * If it is not possible to return the range, because the field is not supported
-     * or for some other reason, an exception is thrown.
-     * <p>
-     * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return
-     * appropriate range instances.
-     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
-     * <p>
-     * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
-     * passing {@code this} as the argument.
-     * Whether the range can be obtained is determined by the field.
-     *
-     * @param field  the field to query the range for, not null
-     * @return the range of valid values for the field, not null
-     * @throws DateTimeException if the range for the field cannot be obtained
-     */
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field instanceof ChronoField) {
-            if (field == OFFSET_SECONDS) {
-                return field.range();
-            }
-            return date.range(field);
-        }
-        return field.doRange(this);
-    }
-
-    /**
-     * Gets the value of the specified field from this date as an {@code int}.
-     * <p>
-     * This queries this date for the value for the specified field.
-     * The returned value will always be within the valid range of values for the field.
-     * If it is not possible to return the value, because the field is not supported
-     * or for some other reason, an exception is thrown.
-     * <p>
-     * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return valid
-     * values based on this date, except {@code EPOCH_DAY} and {@code EPOCH_MONTH}
-     * which are too large to fit in an {@code int} and throw a {@code DateTimeException}.
-     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
-     * <p>
-     * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
-     * passing {@code this} as the argument. Whether the value can be obtained,
-     * and what the value represents, is determined by the field.
-     *
-     * @param field  the field to get, not null
-     * @return the value for the field
-     * @throws DateTimeException if a value for the field cannot be obtained
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override  // override for Javadoc
-    public int get(TemporalField field) {
-        return Temporal.super.get(field);
-    }
-
-    /**
-     * Gets the value of the specified field from this date as a {@code long}.
-     * <p>
-     * This queries this date for the value for the specified field.
-     * If it is not possible to return the value, because the field is not supported
-     * or for some other reason, an exception is thrown.
-     * <p>
-     * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return valid
-     * values based on this date.
-     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
-     * <p>
-     * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
-     * passing {@code this} as the argument. Whether the value can be obtained,
-     * and what the value represents, is determined by the field.
-     *
-     * @param field  the field to get, not null
-     * @return the value for the field
-     * @throws DateTimeException if a value for the field cannot be obtained
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public long getLong(TemporalField field) {
-        if (field instanceof ChronoField) {
-            if (field == OFFSET_SECONDS) {
-                return getOffset().getTotalSeconds();
-            }
-            return date.getLong(field);
-        }
-        return field.doGet(this);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets the zone offset, such as '+01:00'.
-     * <p>
-     * This is the offset of the local date from UTC/Greenwich.
-     *
-     * @return the zone offset, not null
-     */
-    public ZoneOffset getOffset() {
-        return offset;
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified offset.
-     * <p>
-     * This method returns an object with the same {@code LocalDate} and the specified {@code ZoneOffset}.
-     * No calculation is needed or performed.
-     * For example, if this time represents {@code 2007-12-03+02:00} and the offset specified is
-     * {@code +03:00}, then this method will return {@code 2007-12-03+03:00}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param offset  the zone offset to change to, not null
-     * @return an {@code OffsetDate} based on this date with the requested offset, not null
-     */
-    public OffsetDate withOffset(ZoneOffset offset) {
-        Objects.requireNonNull(offset, "offset");
-        return with(date, offset);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets the {@code LocalDate} part of this date-time.
-     * <p>
-     * This returns a {@code LocalDate} with the same year, month and day
-     * as this date-time.
-     *
-     * @return the date part of this date-time, not null
-     */
-    public LocalDate getDate() {
-        return date;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets the year field.
-     * <p>
-     * This method returns the primitive {@code int} value for the year.
-     * <p>
-     * The year returned by this method is proleptic as per {@code get(YEAR)}.
-     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
-     *
-     * @return the year, from MIN_YEAR to MAX_YEAR
-     */
-    public int getYear() {
-        return date.getYear();
-    }
-
-    /**
-     * Gets the month-of-year field from 1 to 12.
-     * <p>
-     * This method returns the month as an {@code int} from 1 to 12.
-     * Application code is frequently clearer if the enum {@link Month}
-     * is used by calling {@link #getMonth()}.
-     *
-     * @return the month-of-year, from 1 to 12
-     * @see #getMonth()
-     */
-    public int getMonthValue() {
-        return date.getMonthValue();
-    }
-
-    /**
-     * Gets the month-of-year field using the {@code Month} enum.
-     * <p>
-     * This method returns the enum {@link Month} for the month.
-     * This avoids confusion as to what {@code int} values mean.
-     * If you need access to the primitive {@code int} value then the enum
-     * provides the {@link Month#getValue() int value}.
-     *
-     * @return the month-of-year, not null
-     * @see #getMonthValue()
-     */
-    public Month getMonth() {
-        return date.getMonth();
-    }
-
-    /**
-     * Gets the day-of-month field.
-     * <p>
-     * This method returns the primitive {@code int} value for the day-of-month.
-     *
-     * @return the day-of-month, from 1 to 31
-     */
-    public int getDayOfMonth() {
-        return date.getDayOfMonth();
-    }
-
-    /**
-     * Gets the day-of-year field.
-     * <p>
-     * This method returns the primitive {@code int} value for the day-of-year.
-     *
-     * @return the day-of-year, from 1 to 365, or 366 in a leap year
-     */
-    public int getDayOfYear() {
-        return date.getDayOfYear();
-    }
-
-    /**
-     * Gets the day-of-week field, which is an enum {@code DayOfWeek}.
-     * <p>
-     * This method returns the enum {@link java.time.DayOfWeek} for the day-of-week.
-     * This avoids confusion as to what {@code int} values mean.
-     * If you need access to the primitive {@code int} value then the enum
-     * provides the {@link java.time.DayOfWeek#getValue() int value}.
-     * <p>
-     * Additional information can be obtained from the {@code DayOfWeek}.
-     * This includes textual names of the values.
-     *
-     * @return the day-of-week, not null
-     */
-    public DayOfWeek getDayOfWeek() {
-        return date.getDayOfWeek();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns an adjusted copy of this date.
-     * <p>
-     * This returns a new {@code OffsetDate}, based on this one, with the date adjusted.
-     * The adjustment takes place using the specified adjuster strategy object.
-     * Read the documentation of the adjuster to understand what adjustment will be made.
-     * <p>
-     * A simple adjuster might simply set the one of the fields, such as the year field.
-     * A more complex adjuster might set the date to the last day of the month.
-     * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}.
-     * These include finding the "last day of the month" and "next Wednesday".
-     * Key date-time classes also implement the {@code TemporalAdjuster} interface,
-     * such as {@link Month} and {@link java.time.temporal.MonthDay MonthDay}.
-     * The adjuster is responsible for handling special cases, such as the varying
-     * lengths of month and leap years.
-     * <p>
-     * For example this code returns a date on the last day of July:
-     * <pre>
-     *  import static java.time.Month.*;
-     *  import static java.time.temporal.Adjusters.*;
-     *
-     *  result = offsetDate.with(JULY).with(lastDayOfMonth());
-     * </pre>
-     * <p>
-     * The classes {@link LocalDate} and {@link ZoneOffset} implement {@code TemporalAdjuster},
-     * thus this method can be used to change the date or offset:
-     * <pre>
-     *  result = offsetDate.with(date);
-     *  result = offsetDate.with(offset);
-     * </pre>
-     * <p>
-     * The result of this method is obtained by invoking the
-     * {@link TemporalAdjuster#adjustInto(Temporal)} method on the
-     * specified adjuster passing {@code this} as the argument.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param adjuster the adjuster to use, not null
-     * @return an {@code OffsetDate} based on {@code this} with the adjustment made, not null
-     * @throws DateTimeException if the adjustment cannot be made
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public OffsetDate with(TemporalAdjuster adjuster) {
-        // optimizations
-        if (adjuster instanceof LocalDate) {
-            return with((LocalDate) adjuster, offset);
-        } else if (adjuster instanceof ZoneOffset) {
-            return with(date, (ZoneOffset) adjuster);
-        } else if (adjuster instanceof OffsetDate) {
-            return (OffsetDate) adjuster;
-        }
-        return (OffsetDate) adjuster.adjustInto(this);
-    }
-
-    /**
-     * Returns a copy of this date with the specified field set to a new value.
-     * <p>
-     * This returns a new {@code OffsetDate}, based on this one, with the value
-     * for the specified field changed.
-     * This can be used to change any supported field, such as the year, month or day-of-month.
-     * If it is not possible to set the value, because the field is not supported or for
-     * some other reason, an exception is thrown.
-     * <p>
-     * In some cases, changing the specified field can cause the resulting date to become invalid,
-     * such as changing the month from 31st January to February would make the day-of-month invalid.
-     * In cases like this, the field is responsible for resolving the date. Typically it will choose
-     * the previous valid date, which would be the last valid day of February in this example.
-     * <p>
-     * If the field is a {@link ChronoField} then the adjustment is implemented here.
-     * <p>
-     * The {@code OFFSET_SECONDS} field will return a date with the specified offset.
-     * The local date is unaltered. If the new offset value is outside the valid range
-     * then a {@code DateTimeException} will be thrown.
-     * <p>
-     * The other {@link #isSupported(TemporalField) supported fields} will behave as per
-     * the matching method on {@link LocalDate#with(TemporalField, long)} LocalDate}.
-     * In this case, the offset is not part of the calculation and will be unchanged.
-     * <p>
-     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
-     * <p>
-     * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
-     * passing {@code this} as the argument. In this case, the field determines
-     * whether and how to adjust the instant.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param field  the field to set in the result, not null
-     * @param newValue  the new value of the field in the result
-     * @return an {@code OffsetDate} based on {@code this} with the specified field set, not null
-     * @throws DateTimeException if the field cannot be set
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public OffsetDate with(TemporalField field, long newValue) {
-        if (field instanceof ChronoField) {
-            if (field == OFFSET_SECONDS) {
-                ChronoField f = (ChronoField) field;
-                return with(date, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue)));
-            }
-            return with(date.with(field, newValue), offset);
-        }
-        return field.doWith(this, newValue);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this {@code OffsetDate} with the year altered.
-     * The offset does not affect the calculation and will be the same in the result.
-     * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param year  the year to set in the result, from MIN_YEAR to MAX_YEAR
-     * @return an {@code OffsetDate} based on this date with the requested year, not null
-     * @throws DateTimeException if the year value is invalid
-     */
-    public OffsetDate withYear(int year) {
-        return with(date.withYear(year), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the month-of-year altered.
-     * The offset does not affect the calculation and will be the same in the result.
-     * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param month  the month-of-year to set in the result, from 1 (January) to 12 (December)
-     * @return an {@code OffsetDate} based on this date with the requested month, not null
-     * @throws DateTimeException if the month-of-year value is invalid
-     */
-    public OffsetDate withMonth(int month) {
-        return with(date.withMonth(month), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the day-of-month altered.
-     * If the resulting date is invalid, an exception is thrown.
-     * The offset does not affect the calculation and will be the same in the result.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
-     * @return an {@code OffsetDate} based on this date with the requested day, not null
-     * @throws DateTimeException if the day-of-month value is invalid
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
-     */
-    public OffsetDate withDayOfMonth(int dayOfMonth) {
-        return with(date.withDayOfMonth(dayOfMonth), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the day-of-year altered.
-     * If the resulting date is invalid, an exception is thrown.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
-     * @return an {@code OffsetDate} based on this date with the requested day, not null
-     * @throws DateTimeException if the day-of-year value is invalid
-     * @throws DateTimeException if the day-of-year is invalid for the year
-     */
-    public OffsetDate withDayOfYear(int dayOfYear) {
-        return with(date.withDayOfYear(dayOfYear), offset);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this date with the specified period added.
-     * <p>
-     * This method returns a new date based on this date with the specified period added.
-     * The adder is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
-     * The offset is not part of the calculation and will be unchanged in the result.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param adder  the adder to use, not null
-     * @return an {@code OffsetDate} based on this date with the addition made, not null
-     * @throws DateTimeException if the addition cannot be made
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public OffsetDate plus(TemporalAdder adder) {
-        return (OffsetDate) adder.addTo(this);
-    }
-
-    /**
-     * Returns a copy of this date with the specified period added.
-     * <p>
-     * This method returns a new date based on this date with the specified period added.
-     * This can be used to add any period that is defined by a unit, for example to add years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
-     * The offset is not part of the calculation and will be unchanged in the result.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param amountToAdd  the amount of the unit to add to the result, may be negative
-     * @param unit  the unit of the period to add, not null
-     * @return an {@code OffsetDate} based on this date with the specified period added, not null
-     * @throws DateTimeException if the unit cannot be added to this type
-     */
-    @Override
-    public OffsetDate plus(long amountToAdd, TemporalUnit unit) {
-        if (unit instanceof ChronoUnit) {
-            return with(date.plus(amountToAdd, unit), offset);
-        }
-        return unit.doPlus(this, amountToAdd);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified period in years added.
-     * <p>
-     * This method adds the specified amount to the years field in three steps:
-     * <ol>
-     * <li>Add the input years to the year field</li>
-     * <li>Check if the resulting date would be invalid</li>
-     * <li>Adjust the day-of-month to the last valid day if necessary</li>
-     * </ol>
-     * <p>
-     * For example, 2008-02-29 (leap year) plus one year would result in the
-     * invalid date 2009-02-29 (standard year). Instead of returning an invalid
-     * result, the last valid day of the month, 2009-02-28, is selected instead.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param years  the years to add, may be negative
-     * @return an {@code OffsetDate} based on this date with the years added, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    public OffsetDate plusYears(long years) {
-        return with(date.plusYears(years), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified period in months added.
-     * <p>
-     * This method adds the specified amount to the months field in three steps:
-     * <ol>
-     * <li>Add the input months to the month-of-year field</li>
-     * <li>Check if the resulting date would be invalid</li>
-     * <li>Adjust the day-of-month to the last valid day if necessary</li>
-     * </ol>
-     * <p>
-     * For example, 2007-03-31 plus one month would result in the invalid date
-     * 2007-04-31. Instead of returning an invalid result, the last valid day
-     * of the month, 2007-04-30, is selected instead.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param months  the months to add, may be negative
-     * @return an {@code OffsetDate} based on this date with the months added, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    public OffsetDate plusMonths(long months) {
-        return with(date.plusMonths(months), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified period in weeks added.
-     * <p>
-     * This method adds the specified amount in weeks to the days field incrementing
-     * the month and year fields as necessary to ensure the result remains valid.
-     * The result is only invalid if the maximum/minimum year is exceeded.
-     * <p>
-     * For example, 2008-12-31 plus one week would result in 2009-01-07.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param weeks  the weeks to add, may be negative
-     * @return an {@code OffsetDate} based on this date with the weeks added, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    public OffsetDate plusWeeks(long weeks) {
-        return with(date.plusWeeks(weeks), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified period in days added.
-     * <p>
-     * This method adds the specified amount to the days field incrementing the
-     * month and year fields as necessary to ensure the result remains valid.
-     * The result is only invalid if the maximum/minimum year is exceeded.
-     * <p>
-     * For example, 2008-12-31 plus one day would result in 2009-01-01.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param days  the days to add, may be negative
-     * @return an {@code OffsetDate} based on this date with the days added, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    public OffsetDate plusDays(long days) {
-        return with(date.plusDays(days), offset);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this date with the specified period subtracted.
-     * <p>
-     * This method returns a new date based on this date with the specified period subtracted.
-     * The subtractor is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
-     * The offset is not part of the calculation and will be unchanged in the result.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param subtractor  the subtractor to use, not null
-     * @return an {@code OffsetDate} based on this date with the subtraction made, not null
-     * @throws DateTimeException if the subtraction cannot be made
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public OffsetDate minus(TemporalSubtractor subtractor) {
-        return (OffsetDate) subtractor.subtractFrom(this);
-    }
-
-    /**
-     * Returns a copy of this date with the specified period subtracted.
-     * <p>
-     * This method returns a new date based on this date with the specified period subtracted.
-     * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
-     * The offset is not part of the calculation and will be unchanged in the result.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
-     * @param unit  the unit of the period to subtract, not null
-     * @return an {@code OffsetDate} based on this date with the specified period subtracted, not null
-     * @throws DateTimeException if the unit cannot be added to this type
-     */
-    @Override
-    public OffsetDate minus(long amountToSubtract, TemporalUnit unit) {
-        return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified period in years subtracted.
-     * <p>
-     * This method subtracts the specified amount from the years field in three steps:
-     * <ol>
-     * <li>Subtract the input years to the year field</li>
-     * <li>Check if the resulting date would be invalid</li>
-     * <li>Adjust the day-of-month to the last valid day if necessary</li>
-     * </ol>
-     * <p>
-     * For example, 2008-02-29 (leap year) minus one year would result in the
-     * invalid date 2007-02-29 (standard year). Instead of returning an invalid
-     * result, the last valid day of the month, 2007-02-28, is selected instead.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param years  the years to subtract, may be negative
-     * @return an {@code OffsetDate} based on this date with the years subtracted, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    public OffsetDate minusYears(long years) {
-        return with(date.minusYears(years), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified period in months subtracted.
-     * <p>
-     * This method subtracts the specified amount from the months field in three steps:
-     * <ol>
-     * <li>Subtract the input months to the month-of-year field</li>
-     * <li>Check if the resulting date would be invalid</li>
-     * <li>Adjust the day-of-month to the last valid day if necessary</li>
-     * </ol>
-     * <p>
-     * For example, 2007-03-31 minus one month would result in the invalid date
-     * 2007-02-31. Instead of returning an invalid result, the last valid day
-     * of the month, 2007-02-28, is selected instead.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param months  the months to subtract, may be negative
-     * @return an {@code OffsetDate} based on this date with the months subtracted, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    public OffsetDate minusMonths(long months) {
-        return with(date.minusMonths(months), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified period in weeks subtracted.
-     * <p>
-     * This method subtracts the specified amount in weeks from the days field decrementing
-     * the month and year fields as necessary to ensure the result remains valid.
-     * The result is only invalid if the maximum/minimum year is exceeded.
-     * <p>
-     * For example, 2009-01-07 minus one week would result in 2008-12-31.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param weeks  the weeks to subtract, may be negative
-     * @return an {@code OffsetDate} based on this date with the weeks subtracted, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    public OffsetDate minusWeeks(long weeks) {
-        return with(date.minusWeeks(weeks), offset);
-    }
-
-    /**
-     * Returns a copy of this {@code OffsetDate} with the specified number of days subtracted.
-     * <p>
-     * This method subtracts the specified amount from the days field decrementing the
-     * month and year fields as necessary to ensure the result remains valid.
-     * The result is only invalid if the maximum/minimum year is exceeded.
-     * <p>
-     * For example, 2009-01-01 minus one day would result in 2008-12-31.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param days  the days to subtract, may be negative
-     * @return an {@code OffsetDate} based on this date with the days subtracted, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    public OffsetDate minusDays(long days) {
-        return with(date.minusDays(days), offset);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Queries this date using the specified query.
-     * <p>
-     * This queries this date using the specified query strategy object.
-     * The {@code TemporalQuery} object defines the logic to be used to
-     * obtain the result. Read the documentation of the query to understand
-     * what the result of this method will be.
-     * <p>
-     * The result of this method is obtained by invoking the
-     * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
-     * specified query passing {@code this} as the argument.
-     *
-     * @param <R> the type of the result
-     * @param query  the query to invoke, not null
-     * @return the query result, null may be returned (defined by the query)
-     * @throws DateTimeException if unable to query (defined by the query)
-     * @throws ArithmeticException if numeric overflow occurs (defined by the query)
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) ISOChrono.INSTANCE;
-        } else if (query == Queries.precision()) {
-            return (R) DAYS;
-        } else if (query == Queries.offset() || query == Queries.zone()) {
-            return (R) getOffset();
-        }
-        return Temporal.super.query(query);
-    }
-
-    /**
-     * Adjusts the specified temporal object to have the same offset and date
-     * as this object.
-     * <p>
-     * This returns a temporal object of the same observable type as the input
-     * with the offset and date changed to be the same as this.
-     * <p>
-     * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
-     * twice, passing {@link ChronoField#OFFSET_SECONDS} and
-     * {@link ChronoField#EPOCH_DAY} as the fields.
-     * <p>
-     * In most cases, it is clearer to reverse the calling pattern by using
-     * {@link Temporal#with(TemporalAdjuster)}:
-     * <pre>
-     *   // these two lines are equivalent, but the second approach is recommended
-     *   temporal = thisOffsetDate.adjustInto(temporal);
-     *   temporal = temporal.with(thisOffsetDate);
-     * </pre>
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param temporal  the target object to be adjusted, not null
-     * @return the adjusted object, not null
-     * @throws DateTimeException if unable to make the adjustment
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public Temporal adjustInto(Temporal temporal) {
-        return temporal
-                .with(OFFSET_SECONDS, getOffset().getTotalSeconds())
-                .with(EPOCH_DAY, getDate().toEpochDay());
-    }
-
-    /**
-     * Calculates the period between this date and another date in
-     * terms of the specified unit.
-     * <p>
-     * This calculates the period between two dates in terms of a single unit.
-     * The start and end points are {@code this} and the specified date.
-     * The result will be negative if the end is before the start.
-     * For example, the period in days between two dates can be calculated
-     * using {@code startDate.periodUntil(endDate, DAYS)}.
-     * <p>
-     * The {@code Temporal} passed to this method must be an {@code OffsetDate}.
-     * If the offset differs between the two times, then the specified
-     * end time is normalized to have the same offset as this time.
-     * <p>
-     * The calculation returns a whole number, representing the number of
-     * complete units between the two dates.
-     * For example, the period in months between 2012-06-15Z and 2012-08-14Z
-     * will only be one month as it is one day short of two months.
-     * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
-     * <pre>
-     *   long period = start.periodUntil(end, MONTHS);   // this method
-     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
-     * </pre>
-     * <p>
-     * The calculation is implemented in this method for {@link ChronoUnit}.
-     * The units {@code DAYS}, {@code WEEKS}, {@code MONTHS}, {@code YEARS},
-     * {@code DECADES}, {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS}
-     * are supported. Other {@code ChronoUnit} values will throw an exception.
-     * <p>
-     * If the unit is not a {@code ChronoUnit}, then the result of this method
-     * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param endDate  the end date, which must be an {@code OffsetDate}, not null
-     * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this date and the end date
-     * @throws DateTimeException if the period cannot be calculated
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public long periodUntil(Temporal endDate, TemporalUnit unit) {
-        if (endDate instanceof OffsetDate == false) {
-            Objects.requireNonNull(endDate, "endDate");
-            throw new DateTimeException("Unable to calculate period between objects of two different types");
-        }
-        if (unit instanceof ChronoUnit) {
-            OffsetDate end = (OffsetDate) endDate;
-            long offsetDiff = end.offset.getTotalSeconds() - offset.getTotalSeconds();
-            LocalDate endLocal = end.date.plusDays(Math.floorDiv(-offsetDiff, SECONDS_PER_DAY));
-            return date.periodUntil(endLocal, unit);
-        }
-        return unit.between(this, endDate).getAmount();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns an offset date-time formed from this date at the specified time.
-     * <p>
-     * This combines this date with the specified time to form an {@code OffsetDateTime}.
-     * All possible combinations of date and time are valid.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param time  the time to combine with, not null
-     * @return the offset date-time formed from this date and the specified time, not null
-     */
-    public OffsetDateTime atTime(LocalTime time) {
-        return OffsetDateTime.of(date, time, offset);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Converts this date to midnight at the start of day in epoch seconds.
-     *
-     * @return the epoch seconds value
-     */
-    private long toEpochSecond() {
-        long epochDay = date.toEpochDay();
-        long secs = epochDay * SECONDS_PER_DAY;
-        return secs - offset.getTotalSeconds();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Compares this {@code OffsetDate} to another date.
-     * <p>
-     * The comparison is based first on the UTC equivalent instant, then on the local date.
-     * It is "consistent with equals", as defined by {@link Comparable}.
-     * <p>
-     * For example, the following is the comparator order:
-     * <ol>
-     * <li>2008-06-29-11:00</li>
-     * <li>2008-06-29-12:00</li>
-     * <li>2008-06-30+12:00</li>
-     * <li>2008-06-29-13:00</li>
-     * </ol>
-     * Values #2 and #3 represent the same instant on the time-line.
-     * When two values represent the same instant, the local date is compared
-     * to distinguish them. This step is needed to make the ordering
-     * consistent with {@code equals()}.
-     * <p>
-     * To compare the underlying local date of two {@code TemporalAccessor} instances,
-     * use {@link ChronoField#EPOCH_DAY} as a comparator.
-     *
-     * @param other  the other date to compare to, not null
-     * @return the comparator value, negative if less, positive if greater
-     */
-    @Override
-    public int compareTo(OffsetDate other) {
-        if (offset.equals(other.offset)) {
-            return date.compareTo(other.date);
-        }
-        int compare = Long.compare(toEpochSecond(), other.toEpochSecond());
-        if (compare == 0) {
-            compare = date.compareTo(other.date);
-        }
-        return compare;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks if the instant of midnight at the start of this {@code OffsetDate}
-     * is after midnight at the start of the specified date.
-     * <p>
-     * This method differs from the comparison in {@link #compareTo} in that it
-     * only compares the instant of the date. This is equivalent to using
-     * {@code date1.toEpochSecond().isAfter(date2.toEpochSecond())}.
-     *
-     * @param other  the other date to compare to, not null
-     * @return true if this is after the instant of the specified date
-     */
-    public boolean isAfter(OffsetDate other) {
-        return toEpochSecond() > other.toEpochSecond();
-    }
-
-    /**
-     * Checks if the instant of midnight at the start of this {@code OffsetDate}
-     * is before midnight at the start of the specified date.
-     * <p>
-     * This method differs from the comparison in {@link #compareTo} in that it
-     * only compares the instant of the date. This is equivalent to using
-     * {@code date1.toEpochSecond().isBefore(date2.toEpochSecond())}.
-     *
-     * @param other  the other date to compare to, not null
-     * @return true if this is before the instant of the specified date
-     */
-    public boolean isBefore(OffsetDate other) {
-        return toEpochSecond() < other.toEpochSecond();
-    }
-
-    /**
-     * Checks if the instant of midnight at the start of this {@code OffsetDate}
-     * equals midnight at the start of the specified date.
-     * <p>
-     * This method differs from the comparison in {@link #compareTo} and {@link #equals}
-     * in that it only compares the instant of the date. This is equivalent to using
-     * {@code date1.toEpochSecond().equals(date2.toEpochSecond())}.
-     *
-     * @param other  the other date to compare to, not null
-     * @return true if the instant equals the instant of the specified date
-     */
-    public boolean isEqual(OffsetDate other) {
-        return toEpochSecond() == other.toEpochSecond();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks if this date is equal to another date.
-     * <p>
-     * The comparison is based on the local-date and the offset.
-     * To compare for the same instant on the time-line, use {@link #isEqual(OffsetDate)}.
-     * <p>
-     * Only objects of type {@code OffsetDate} are compared, other types return false.
-     * To compare the underlying local date of two {@code TemporalAccessor} instances,
-     * use {@link ChronoField#EPOCH_DAY} as a comparator.
-     *
-     * @param obj  the object to check, null returns false
-     * @return true if this is equal to the other date
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof OffsetDate) {
-            OffsetDate other = (OffsetDate) obj;
-            return date.equals(other.date) && offset.equals(other.offset);
-        }
-        return false;
-    }
-
-    /**
-     * A hash code for this date.
-     *
-     * @return a suitable hash code
-     */
-    @Override
-    public int hashCode() {
-        return date.hashCode() ^ offset.hashCode();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Outputs this date as a {@code String}, such as {@code 2007-12-03+01:00}.
-     * <p>
-     * The output will be in the ISO-8601 format {@code yyyy-MM-ddXXXXX}.
-     *
-     * @return a string representation of this date, not null
-     */
-    @Override
-    public String toString() {
-        return date.toString() + offset.toString();
-    }
-
-    /**
-     * Outputs this date as a {@code String} using the formatter.
-     * <p>
-     * This date will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
-     *
-     * @param formatter  the formatter to use, not null
-     * @return the formatted date string, not null
-     * @throws DateTimeException if an error occurs during printing
-     */
-    public String toString(DateTimeFormatter formatter) {
-        Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Writes the object using a
-     * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
-     * <pre>
-     *  out.writeByte(1);  // identifies this as a OffsetDateTime
-     *  out.writeObject(date);
-     *  out.writeObject(offset);
-     * </pre>
-     *
-     * @return the instance of {@code Ser}, not null
-     */
-    private Object writeReplace() {
-        return new Ser(Ser.OFFSET_DATE_TYPE, this);
-    }
-
-    /**
-     * Defend against malicious streams.
-     * @return never
-     * @throws InvalidObjectException always
-     */
-    private Object readResolve() throws ObjectStreamException {
-        throw new InvalidObjectException("Deserialization via serialization delegate");
-    }
-
-    void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(date);
-        out.writeObject(offset);
-    }
-
-    static OffsetDate readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        LocalDate date = (LocalDate) in.readObject();
-        ZoneOffset offset = (ZoneOffset) in.readObject();
-        return OffsetDate.of(date, offset);
-    }
-
-}
diff --git a/jdk/src/share/classes/java/time/temporal/Queries.java b/jdk/src/share/classes/java/time/temporal/Queries.java
index 74b8f1a..a4c0a42 100644
--- a/jdk/src/share/classes/java/time/temporal/Queries.java
+++ b/jdk/src/share/classes/java/time/temporal/Queries.java
@@ -61,10 +61,17 @@
  */
 package java.time.temporal;
 
+import static java.time.temporal.ChronoField.EPOCH_DAY;
+import static java.time.temporal.ChronoField.NANO_OF_DAY;
 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
 
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.chrono.Chronology;
 
 /**
  * Common implementations of {@code TemporalQuery}.
@@ -116,9 +123,8 @@
      * This queries a {@code TemporalAccessor} for the zone.
      * The zone is only returned if the date-time conceptually contains a {@code ZoneId}.
      * It will not be returned if the date-time only conceptually has an {@code ZoneOffset}.
-     * Thus a {@link java.time.ZonedDateTime ZonedDateTime} will return the result of
-     * {@code getZone()}, but an {@link java.time.temporal.OffsetDateTime OffsetDateTime} will
-     * return null.
+     * Thus a {@link ZonedDateTime} will return the result of {@code getZone()},
+     * but an {@link OffsetDateTime} will return null.
      * <p>
      * In most cases, applications should use {@link #ZONE} as this query is too strict.
      * <p>
@@ -127,7 +133,6 @@
      * {@code LocalTime} returns null<br>
      * {@code LocalDateTime} returns null<br>
      * {@code ZonedDateTime} returns the associated zone<br>
-     * {@code OffsetDate} returns null<br>
      * {@code OffsetTime} returns null<br>
      * {@code OffsetDateTime} returns null<br>
      * {@code ChronoLocalDate} returns null<br>
@@ -141,20 +146,18 @@
      * {@code MonthDay} returns null<br>
      * {@code ZoneOffset} returns null<br>
      * {@code Instant} returns null<br>
-     * @return a ZoneId, may be null
+     *
+     * @return a query that can obtain the zone ID of a temporal, not null
      */
     public static final TemporalQuery<ZoneId> zoneId() {
         return ZONE_ID;
     }
-    static final TemporalQuery<ZoneId> ZONE_ID = new TemporalQuery<ZoneId>() {
-        @Override
-        public ZoneId queryFrom(TemporalAccessor temporal) {
-            return temporal.query(this);
-        }
+    static final TemporalQuery<ZoneId> ZONE_ID = (temporal) -> {
+        return temporal.query(ZONE_ID);
     };
 
     /**
-     * A query for the {@code Chrono}.
+     * A query for the {@code Chronology}.
      * <p>
      * This queries a {@code TemporalAccessor} for the chronology.
      * If the target {@code TemporalAccessor} represents a date, or part of a date,
@@ -163,39 +166,36 @@
      * {@code LocalTime}, will return null.
      * <p>
      * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br>
-     * {@code LocalDate} returns {@code ISOChrono.INSTANCE}<br>
+     * {@code LocalDate} returns {@code IsoChronology.INSTANCE}<br>
      * {@code LocalTime} returns null (does not represent a date)<br>
-     * {@code LocalDateTime} returns {@code ISOChrono.INSTANCE}<br>
-     * {@code ZonedDateTime} returns {@code ISOChrono.INSTANCE}<br>
-     * {@code OffsetDate} returns {@code ISOChrono.INSTANCE}<br>
+     * {@code LocalDateTime} returns {@code IsoChronology.INSTANCE}<br>
+     * {@code ZonedDateTime} returns {@code IsoChronology.INSTANCE}<br>
      * {@code OffsetTime} returns null (does not represent a date)<br>
-     * {@code OffsetDateTime} returns {@code ISOChrono.INSTANCE}<br>
+     * {@code OffsetDateTime} returns {@code IsoChronology.INSTANCE}<br>
      * {@code ChronoLocalDate} returns the associated chronology<br>
      * {@code ChronoLocalDateTime} returns the associated chronology<br>
      * {@code ChronoZonedDateTime} returns the associated chronology<br>
      * {@code Era} returns the associated chronology<br>
      * {@code DayOfWeek} returns null (shared across chronologies)<br>
-     * {@code Month} returns {@code ISOChrono.INSTANCE}<br>
-     * {@code Year} returns {@code ISOChrono.INSTANCE}<br>
-     * {@code YearMonth} returns {@code ISOChrono.INSTANCE}<br>
-     * {@code MonthDay} returns null {@code ISOChrono.INSTANCE}<br>
+     * {@code Month} returns {@code IsoChronology.INSTANCE}<br>
+     * {@code Year} returns {@code IsoChronology.INSTANCE}<br>
+     * {@code YearMonth} returns {@code IsoChronology.INSTANCE}<br>
+     * {@code MonthDay} returns null {@code IsoChronology.INSTANCE}<br>
      * {@code ZoneOffset} returns null (does not represent a date)<br>
      * {@code Instant} returns null (does not represent a date)<br>
      * <p>
-     * The method {@link Chrono#from(TemporalAccessor)} can be used as a
-     * {@code TemporalQuery} via a method reference, {@code Chrono::from}.
+     * The method {@link Chronology#from(TemporalAccessor)} can be used as a
+     * {@code TemporalQuery} via a method reference, {@code Chronology::from}.
      * That method is equivalent to this query, except that it throws an
      * exception if a chronology cannot be obtained.
-     * @return a Chrono, may be null
+     *
+     * @return a query that can obtain the chronology of a temporal, not null
      */
-    public static final TemporalQuery<Chrono<?>> chrono() {
+    public static final TemporalQuery<Chronology> chronology() {
         return CHRONO;
     }
-    static final TemporalQuery<Chrono<?>> CHRONO = new TemporalQuery<Chrono<?>>() {
-        @Override
-        public Chrono<?> queryFrom(TemporalAccessor temporal) {
-            return temporal.query(this);
-        }
+    static final TemporalQuery<Chronology> CHRONO = (temporal) -> {
+        return temporal.query(CHRONO);
     };
 
     /**
@@ -215,7 +215,6 @@
      * {@code LocalTime} returns {@code NANOS}<br>
      * {@code LocalDateTime} returns {@code NANOS}<br>
      * {@code ZonedDateTime} returns {@code NANOS}<br>
-     * {@code OffsetDate} returns {@code DAYS}<br>
      * {@code OffsetTime} returns {@code NANOS}<br>
      * {@code OffsetDateTime} returns {@code NANOS}<br>
      * {@code ChronoLocalDate} returns {@code DAYS}<br>
@@ -229,16 +228,14 @@
      * {@code MonthDay} returns null (does not represent a complete date or time)<br>
      * {@code ZoneOffset} returns null (does not represent a date or time)<br>
      * {@code Instant} returns {@code NANOS}<br>
-     * @return a ChronoUnit, may be null
+     *
+     * @return a query that can obtain the precision of a temporal, not null
      */
-    public static final TemporalQuery<ChronoUnit> precision() {
+    public static final TemporalQuery<TemporalUnit> precision() {
         return PRECISION;
     }
-    static final TemporalQuery<ChronoUnit> PRECISION = new TemporalQuery<ChronoUnit>() {
-        @Override
-        public ChronoUnit queryFrom(TemporalAccessor temporal) {
-            return temporal.query(this);
-        }
+    static final TemporalQuery<TemporalUnit> PRECISION = (temporal) -> {
+        return temporal.query(PRECISION);
     };
 
     //-----------------------------------------------------------------------
@@ -249,54 +246,111 @@
      * This queries a {@code TemporalAccessor} for the zone.
      * It first tries to obtain the zone, using {@link #zoneId()}.
      * If that is not found it tries to obtain the {@link #offset()}.
+     * Thus a {@link ZonedDateTime} will return the result of {@code getZone()},
+     * while an {@link OffsetDateTime} will return the result of {@code getOffset()}.
      * <p>
      * In most cases, applications should use this query rather than {@code #zoneId()}.
      * <p>
-     * This query examines the {@link java.time.temporal.ChronoField#OFFSET_SECONDS offset-seconds}
-     * field and uses it to create a {@code ZoneOffset}.
-     * <p>
      * The method {@link ZoneId#from(TemporalAccessor)} can be used as a
      * {@code TemporalQuery} via a method reference, {@code ZoneId::from}.
      * That method is equivalent to this query, except that it throws an
      * exception if a zone cannot be obtained.
-     * @return a ZoneId, may be null
+     *
+     * @return a query that can obtain the zone ID or offset of a temporal, not null
      */
     public static final TemporalQuery<ZoneId> zone() {
         return ZONE;
     }
-    static final TemporalQuery<ZoneId> ZONE = new TemporalQuery<ZoneId>() {
-        @Override
-        public ZoneId queryFrom(TemporalAccessor temporal) {
-            ZoneId zone = temporal.query(ZONE_ID);
-            return (zone != null ? zone : temporal.query(OFFSET));
-        }
+    static final TemporalQuery<ZoneId> ZONE = (temporal) -> {
+        ZoneId zone = temporal.query(ZONE_ID);
+        return (zone != null ? zone : temporal.query(OFFSET));
     };
 
     /**
-     * A query for the {@code ZoneOffset}.
+     * A query for {@code ZoneOffset} returning null if not found.
      * <p>
-     * This queries a {@code TemporalAccessor} for the offset.
+     * This returns a {@code TemporalQuery} that can be used to query a temporal
+     * object for the offset. The query will return null if the temporal
+     * object cannot supply an offset.
      * <p>
-     * This query examines the {@link java.time.temporal.ChronoField#OFFSET_SECONDS offset-seconds}
+     * The query implementation examines the {@link ChronoField#OFFSET_SECONDS OFFSET_SECONDS}
      * field and uses it to create a {@code ZoneOffset}.
      * <p>
      * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a
      * {@code TemporalQuery} via a method reference, {@code ZoneOffset::from}.
-     * That method is equivalent to this query, except that it throws an
-     * exception if an offset cannot be obtained.
-     * @return a ZoneOffset, may be null
+     * This query and {@code ZoneOffset::from} will return the same result if the
+     * temporal object contains an offset. If the temporal object does not contain
+     * an offset, then the method reference will throw an exception, whereas this
+     * query will return null.
+     *
+     * @return a query that can obtain the offset of a temporal, not null
      */
     public static final TemporalQuery<ZoneOffset> offset() {
         return OFFSET;
     }
-    static final TemporalQuery<ZoneOffset> OFFSET = new TemporalQuery<ZoneOffset>() {
-        @Override
-        public ZoneOffset queryFrom(TemporalAccessor temporal) {
-            if (temporal.isSupported(OFFSET_SECONDS)) {
-                return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
-            }
-            return null;
+    static final TemporalQuery<ZoneOffset> OFFSET = (temporal) -> {
+        if (temporal.isSupported(OFFSET_SECONDS)) {
+            return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
         }
+        return null;
+    };
+
+    /**
+     * A query for {@code LocalDate} returning null if not found.
+     * <p>
+     * This returns a {@code TemporalQuery} that can be used to query a temporal
+     * object for the local date. The query will return null if the temporal
+     * object cannot supply a local date.
+     * <p>
+     * The query implementation examines the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
+     * field and uses it to create a {@code LocalDate}.
+     * <p>
+     * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a
+     * {@code TemporalQuery} via a method reference, {@code LocalDate::from}.
+     * This query and {@code LocalDate::from} will return the same result if the
+     * temporal object contains a date. If the temporal object does not contain
+     * a date, then the method reference will throw an exception, whereas this
+     * query will return null.
+     *
+     * @return a query that can obtain the date of a temporal, not null
+     */
+    public static final TemporalQuery<LocalDate> localDate() {
+        return LOCAL_DATE;
+    }
+    static final TemporalQuery<LocalDate> LOCAL_DATE = (temporal) -> {
+        if (temporal.isSupported(EPOCH_DAY)) {
+            return LocalDate.ofEpochDay(temporal.getLong(EPOCH_DAY));
+        }
+        return null;
+    };
+
+    /**
+     * A query for {@code LocalTime} returning null if not found.
+     * <p>
+     * This returns a {@code TemporalQuery} that can be used to query a temporal
+     * object for the local time. The query will return null if the temporal
+     * object cannot supply a local time.
+     * <p>
+     * The query implementation examines the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY}
+     * field and uses it to create a {@code LocalTime}.
+     * <p>
+     * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a
+     * {@code TemporalQuery} via a method reference, {@code LocalTime::from}.
+     * This query and {@code LocalTime::from} will return the same result if the
+     * temporal object contains a time. If the temporal object does not contain
+     * a time, then the method reference will throw an exception, whereas this
+     * query will return null.
+     *
+     * @return a query that can obtain the time of a temporal, not null
+     */
+    public static final TemporalQuery<LocalTime> localTime() {
+        return LOCAL_TIME;
+    }
+    static final TemporalQuery<LocalTime> LOCAL_TIME = (temporal) -> {
+        if (temporal.isSupported(NANO_OF_DAY)) {
+            return LocalTime.ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
+        }
+        return null;
     };
 
 }
diff --git a/jdk/src/share/classes/java/time/temporal/Ser.java b/jdk/src/share/classes/java/time/temporal/Ser.java
deleted file mode 100644
index 2f182e0..0000000
--- a/jdk/src/share/classes/java/time/temporal/Ser.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.temporal;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.InvalidClassException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.StreamCorruptedException;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-
-/**
- * The shared serialization delegate for this package.
- *
- * <h3>Implementation notes</h3>
- * This class wraps the object being serialized, and takes a byte representing the type of the class to
- * be serialized.  This byte can also be used for versioning the serialization format.  In this case another
- * byte flag would be used in order to specify an alternative version of the type format.
- * For example {@code CHRONO_TYPE_VERSION_2 = 21}
- * <p>
- * In order to serialise the object it writes its byte and then calls back to the appropriate class where
- * the serialisation is performed.  In order to deserialise the object it read in the type byte, switching
- * in order to select which class to call back into.
- * <p>
- * The serialisation format is determined on a per class basis.  In the case of field based classes each
- * of the fields is written out with an appropriate size format in descending order of the field's size.  For
- * example in the case of {@link LocalDate} year is written before month.  Composite classes, such as
- * {@link LocalDateTime} are serialised as one object.  Enum classes are serialised using the index of their
- * element.
- * <p>
- * This class is mutable and should be created once per serialization.
- *
- * @serial include
- * @since 1.8
- */
-final class Ser implements Externalizable {
-
-    /**
-     * Serialization version.
-     */
-    private static final long serialVersionUID = -6103370247208168577L;
-
-    static final byte OFFSET_DATE_TYPE = 1;
-    static final byte OFFSET_TIME_TYPE = 2;
-    static final byte OFFSET_DATE_TIME_TYPE = 3;
-    static final byte YEAR_TYPE = 4;
-    static final byte YEAR_MONTH_TYPE = 5;
-    static final byte MONTH_DAY_TYPE = 6;
-    static final byte CHRONO_TYPE = 7;
-    static final byte CHRONO_LOCAL_DATE_TIME_TYPE = 8;
-    static final byte CHRONO_ZONE_DATE_TIME_TYPE = 9;
-    static final byte SIMPLE_PERIOD_TYPE = 10;
-
-    /** The type being serialized. */
-    private byte type;
-    /** The object being serialized. */
-    private Object object;
-
-    /**
-     * Constructor for deserialization.
-     */
-    public Ser() {
-    }
-
-    /**
-     * Creates an instance for serialization.
-     *
-     * @param type  the type
-     * @param object  the object
-     */
-    Ser(byte type, Object object) {
-        this.type = type;
-        this.object = object;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Implements the {@code Externalizable} interface to write the object.
-     *
-     * @param out  the data stream to write to, not null
-     */
-    @Override
-    public void writeExternal(ObjectOutput out) throws IOException {
-        writeInternal(type, object, out);
-    }
-
-    private static void writeInternal(byte type, Object object, ObjectOutput out) throws IOException {
-        out.writeByte(type);
-        switch (type) {
-            case OFFSET_DATE_TYPE:
-                ((OffsetDate) object).writeExternal(out);
-                break;
-            case OFFSET_TIME_TYPE:
-                ((OffsetTime) object).writeExternal(out);
-                break;
-            case OFFSET_DATE_TIME_TYPE:
-                ((OffsetDateTime) object).writeExternal(out);
-                break;
-            case YEAR_TYPE:
-                ((Year) object).writeExternal(out);
-                break;
-            case YEAR_MONTH_TYPE:
-                ((YearMonth) object).writeExternal(out);
-                break;
-            case MONTH_DAY_TYPE:
-                ((MonthDay) object).writeExternal(out);
-                break;
-            case CHRONO_TYPE:
-                ((Chrono<?>) object).writeExternal(out);
-                break;
-            case CHRONO_LOCAL_DATE_TIME_TYPE:
-                ((ChronoLocalDateTimeImpl<?>) object).writeExternal(out);
-                break;
-            case CHRONO_ZONE_DATE_TIME_TYPE:
-                ((ChronoZonedDateTimeImpl<?>) object).writeExternal(out);
-                break;
-            case SIMPLE_PERIOD_TYPE:
-                ((SimplePeriod) object).writeExternal(out);
-                break;
-            default:
-                throw new InvalidClassException("Unknown serialized type");
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Implements the {@code Externalizable} interface to read the object.
-     *
-     * @param in  the data to read, not null
-     */
-    @Override
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        type = in.readByte();
-        object = readInternal(type, in);
-    }
-
-    static Object read(ObjectInput in) throws IOException, ClassNotFoundException {
-        byte type = in.readByte();
-        return readInternal(type, in);
-    }
-
-    private static Object readInternal(byte type, ObjectInput in) throws IOException, ClassNotFoundException {
-        switch (type) {
-            case OFFSET_DATE_TYPE: return OffsetDate.readExternal(in);
-            case OFFSET_TIME_TYPE: return OffsetTime.readExternal(in);
-            case OFFSET_DATE_TIME_TYPE: return OffsetDateTime.readExternal(in);
-            case YEAR_TYPE: return Year.readExternal(in);
-            case YEAR_MONTH_TYPE: return YearMonth.readExternal(in);
-            case MONTH_DAY_TYPE: return MonthDay.readExternal(in);
-            case CHRONO_TYPE: return Chrono.readExternal(in);
-            case CHRONO_LOCAL_DATE_TIME_TYPE: return ChronoLocalDateTimeImpl.readExternal(in);
-            case CHRONO_ZONE_DATE_TIME_TYPE: return ChronoZonedDateTimeImpl.readExternal(in);
-            case SIMPLE_PERIOD_TYPE: return SimplePeriod.readExternal(in);
-            default: throw new StreamCorruptedException("Unknown serialized type");
-        }
-    }
-
-    /**
-     * Returns the object that will replace this one.
-     *
-     * @return the read object, should never be null
-     */
-    private Object readResolve() {
-         return object;
-    }
-
-}
diff --git a/jdk/src/share/classes/java/time/temporal/SimplePeriod.java b/jdk/src/share/classes/java/time/temporal/SimplePeriod.java
deleted file mode 100644
index 5eb60f5..0000000
--- a/jdk/src/share/classes/java/time/temporal/SimplePeriod.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.temporal;
-
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.time.DateTimeException;
-import java.util.Objects;
-
-/**
- * A period of time, measured as an amount of a single unit, such as '3 Months'.
- * <p>
- * A {@code SimplePeriod} represents an amount of time measured in terms of a
- * single {@link TemporalUnit unit}. Any unit may be used with this class.
- * An alternative period implementation is {@link java.time.Period Period}, which
- * allows a combination of date and time units.
- * <p>
- * This class is the return type from {@link TemporalUnit#between}.
- * It can be used more generally, but is designed to enable the following code:
- * <pre>
- *  date = date.minus(MONTHS.between(start, end));
- * </pre>
- * The unit determines which calendar systems it can be added to.
- * <p>
- * The period is modeled as a directed amount of time, meaning that the period may
- * be negative. See {@link #abs()} to ensure the period is positive.
- *
- * <h3>Specification for implementors</h3>
- * This class is immutable and thread-safe, providing that the unit is immutable,
- * which it is required to be.
- *
- * @since 1.8
- */
-public final class SimplePeriod
-        implements TemporalAdder, TemporalSubtractor, Comparable<SimplePeriod>, Serializable {
-
-    /**
-     * Serialization version.
-     */
-    private static final long serialVersionUID = 3752975649629L;
-
-    /**
-     * The amount of the unit.
-     */
-    private final long amount;
-    /**
-     * The unit.
-     */
-    private final TemporalUnit unit;
-
-    //-----------------------------------------------------------------------
-    /**
-     * Obtains an instance of {@code SimplePeriod} from a period in the specified unit.
-     * <p>
-     * The parameters represent the two parts of a phrase like '6 Days'. For example:
-     * <pre>
-     *  SimplePeriod.of(3, SECONDS);
-     *  SimplePeriod.of(5, YEARS);
-     * </pre>
-     *
-     * @param amount  the amount of the period, measured in terms of the unit, positive or negative
-     * @param unit  the unit that the period is measured in, not null
-     * @return the period, not null
-     */
-    public static SimplePeriod of(long amount, TemporalUnit unit) {
-        Objects.requireNonNull(unit, "unit");
-        return new SimplePeriod(amount, unit);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Constructor.
-     *
-     * @param amount  the amount of the period, measured in terms of the unit, positive or negative
-     * @param unit  the unit that the period is measured in, not null
-     */
-    SimplePeriod(long amount, TemporalUnit unit) {
-        this.amount = amount;
-        this.unit = unit;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets the amount of this period.
-     * <p>
-     * In the phrase "2 Months", the amount is 2.
-     *
-     * @return the amount of the period, may be negative
-     */
-    public long getAmount() {
-        return amount;
-    }
-
-    /**
-     * Gets the unit of this period.
-     * <p>
-     * In the phrase "2 Months", the unit is "Months".
-     *
-     * @return the unit of the period, not null
-     */
-    public TemporalUnit getUnit() {
-        return unit;
-    }
-
-    //-------------------------------------------------------------------------
-    /**
-     * Adds this period to the specified temporal object.
-     * <p>
-     * This returns a temporal object of the same observable type as the input
-     * with this period added.
-     * <p>
-     * In most cases, it is clearer to reverse the calling pattern by using
-     * {@link Temporal#plus(TemporalAdder)}.
-     * <pre>
-     *   // these two lines are equivalent, but the second approach is recommended
-     *   dateTime = thisPeriod.addTo(dateTime);
-     *   dateTime = dateTime.plus(thisPeriod);
-     * </pre>
-     * <p>
-     * The calculation is equivalent to invoking {@link Temporal#plus(long, TemporalUnit)}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param temporal  the temporal object to adjust, not null
-     * @return an object of the same type with the adjustment made, not null
-     * @throws DateTimeException if unable to add
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public Temporal addTo(Temporal temporal) {
-        return temporal.plus(amount, unit);
-    }
-
-    /**
-     * Subtracts this period to the specified temporal object.
-     * <p>
-     * This returns a temporal object of the same observable type as the input
-     * with this period subtracted.
-     * <p>
-     * In most cases, it is clearer to reverse the calling pattern by using
-     * {@link Temporal#plus(TemporalAdder)}.
-     * <pre>
-     *   // these two lines are equivalent, but the second approach is recommended
-     *   dateTime = thisPeriod.subtractFrom(dateTime);
-     *   dateTime = dateTime.minus(thisPeriod);
-     * </pre>
-     * <p>
-     * The calculation is equivalent to invoking {@link Temporal#minus(long, TemporalUnit)}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param temporal  the temporal object to adjust, not null
-     * @return an object of the same type with the adjustment made, not null
-     * @throws DateTimeException if unable to subtract
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    @Override
-    public Temporal subtractFrom(Temporal temporal) {
-        return temporal.minus(amount, unit);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this period with a positive amount.
-     * <p>
-     * This returns a period with the absolute value of the amount and the same unit.
-     * If the amount of this period is positive or zero, then this period is returned.
-     * If the amount of this period is negative, then a period with the negated
-     * amount is returned. If the amount equals {@code Long.MIN_VALUE},
-     * an {@code ArithmeticException} is thrown
-     * <p>
-     * This is useful to convert the result of {@link TemporalUnit#between} to
-     * a positive amount when you do not know which date is the earlier and
-     * which is the later.
-     *
-     * @return a period with a positive amount and the same unit, not null
-     * @throws ArithmeticException if the amount is {@code Long.MIN_VALUE}
-     */
-    public SimplePeriod abs() {
-        if (amount == Long.MIN_VALUE) {
-            throw new ArithmeticException("Unable to call abs() on MIN_VALUE");
-        }
-        return (amount >= 0 ? this : new SimplePeriod(-amount, unit));
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Compares this {@code SimplePeriod} to another period.
-     * <p>
-     * The comparison is based on the amount within the unit.
-     * Only two periods with the same unit can be compared.
-     *
-     * @param other  the other period to compare to, not null
-     * @return the comparator value, negative if less, positive if greater
-     * @throws IllegalArgumentException if the units do not match
-     */
-    @Override
-    public int compareTo(SimplePeriod other) {
-        if (unit.equals(other.unit) == false) {
-            throw new IllegalArgumentException("Unable to compare periods with different units");
-        }
-        return Long.compare(amount, other.amount);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks if this period is equal to another period.
-     * <p>
-     * The comparison is based on the amount and unit.
-     *
-     * @param obj  the object to check, null returns false
-     * @return true if this is equal to the other period
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof SimplePeriod) {
-            SimplePeriod other = (SimplePeriod) obj;
-            return amount == other.amount && unit.equals(other.unit);
-        }
-        return false;
-    }
-
-    /**
-     * A hash code for this period.
-     *
-     * @return a suitable hash code
-     */
-    @Override
-    public int hashCode() {
-        return unit.hashCode() ^ (int) (amount ^ (amount >>> 32));
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Outputs this period as a {@code String}, such as {@code 2 Months}.
-     * <p>
-     * The string consists of the amount, then a space, then the unit name.
-     *
-     * @return a string representation of this period, not null
-     */
-    @Override
-    public String toString() {
-        return amount + " " + unit.getName();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Writes the object using a
-     * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
-     * <pre>
-     *  out.writeByte(10);  // identifies this as a SimplePeriod
-     *  out.writeLong(amount);
-     *  out.writeObject(unit);
-     * </pre>
-     *
-     * @return the instance of {@code Ser}, not null
-     */
-    private Object writeReplace() {
-        return new Ser(Ser.SIMPLE_PERIOD_TYPE, this);
-    }
-
-    /**
-     * Defend against malicious streams.
-     * @return never
-     * @throws InvalidObjectException always
-     */
-    private Object readResolve() throws ObjectStreamException {
-        throw new InvalidObjectException("Deserialization via serialization delegate");
-    }
-
-    void writeExternal(ObjectOutput out) throws IOException {
-        out.writeLong(amount);
-        out.writeObject(unit);
-    }
-
-    static SimplePeriod readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        long amount = in.readLong();
-        TemporalUnit unit = (TemporalUnit) in.readObject();
-        return SimplePeriod.of(amount, unit);
-    }
-
-}
diff --git a/jdk/src/share/classes/java/time/temporal/Temporal.java b/jdk/src/share/classes/java/time/temporal/Temporal.java
index 0eddf27..3eeed90 100644
--- a/jdk/src/share/classes/java/time/temporal/Temporal.java
+++ b/jdk/src/share/classes/java/time/temporal/Temporal.java
@@ -81,7 +81,7 @@
  * See {@link ChronoField} for the standard set of fields.
  * <p>
  * Two pieces of date/time information cannot be represented by numbers,
- * the {@linkplain Chrono chronology} and the {@linkplain ZoneId time-zone}.
+ * the {@linkplain java.time.chrono.Chronology chronology} and the {@linkplain ZoneId time-zone}.
  * These can be accessed via {@link #query(TemporalQuery) queries} using
  * the static methods defined on {@link Queries}.
  * <p>
@@ -90,7 +90,7 @@
  * around instances of concrete types, such as {@code LocalDate}.
  * There are many reasons for this, part of which is that implementations
  * of this interface may be in calendar systems other than ISO.
- * See {@link ChronoLocalDate} for a fuller discussion of the issues.
+ * See {@link java.time.chrono.ChronoLocalDate} for a fuller discussion of the issues.
  *
  * <h3>When to implement</h3>
  * <p>
@@ -183,7 +183,7 @@
      * If unsupported, then a {@code DateTimeException} must be thrown.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the first argument.
      * <p>
      * Implementations must not alter either this object or the specified temporal object.
@@ -202,9 +202,9 @@
     /**
      * Returns an object of the same type as this object with an amount added.
      * <p>
-     * This adjusts this temporal, adding according to the rules of the specified adder.
-     * The adder is typically a {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface, such as {@link java.time.Duration}.
+     * This adjusts this temporal, adding according to the rules of the specified amount.
+     * The amount is typically a {@link java.time.Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface, such as {@link java.time.Duration}.
      * <p>
      * Some example code indicating how and why this method is used:
      * <pre>
@@ -224,16 +224,16 @@
      * <p>
      * The default implementation must behave equivalent to this code:
      * <pre>
-     *  return adder.addTo(this);
+     *  return amount.addTo(this);
      * </pre>
      *
-     * @param adder  the adder to use, not null
+     * @param amount  the amount to add, not null
      * @return an object of the same type with the specified adjustment made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public default Temporal plus(TemporalAdder adder) {
-        return adder.addTo(this);
+    public default Temporal plus(TemporalAmount amount) {
+        return amount.addTo(this);
     }
 
     /**
@@ -258,7 +258,7 @@
      * If unsupported, then a {@code DateTimeException} must be thrown.
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
-     * is obtained by invoking {@code TemporalUnit.doPlus(Temporal, long)}
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
      * passing {@code this} as the first argument.
      * <p>
      * Implementations must not alter either this object or the specified temporal object.
@@ -277,9 +277,9 @@
     /**
      * Returns an object of the same type as this object with an amount subtracted.
      * <p>
-     * This adjusts this temporal, subtracting according to the rules of the specified subtractor.
-     * The subtractor is typically a {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface, such as {@link java.time.Duration}.
+     * This adjusts this temporal, subtracting according to the rules of the specified amount.
+     * The amount is typically a {@link java.time.Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface, such as {@link java.time.Duration}.
      * <p>
      * Some example code indicating how and why this method is used:
      * <pre>
@@ -299,16 +299,16 @@
      * <p>
      * The default implementation must behave equivalent to this code:
      * <pre>
-     *  return subtractor.subtractFrom(this);
+     *  return amount.subtractFrom(this);
      * </pre>
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amount  the amount to subtract, not null
      * @return an object of the same type with the specified adjustment made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public default Temporal minus(TemporalSubtractor subtractor) {
-        return subtractor.subtractFrom(this);
+    public default Temporal minus(TemporalAmount amount) {
+        return amount.subtractFrom(this);
     }
 
     /**
@@ -366,13 +366,22 @@
      * For example, the period in hours between the times 11:30 and 13:29
      * will only be one hour as it is one minute short of two hours.
      * <p>
-     * This method operates in association with {@link TemporalUnit#between}.
-     * The result of this method is a {@code long} representing the amount of
-     * the specified unit. By contrast, the result of {@code between} is an
-     * object that can be used directly in addition/subtraction:
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method directly.
+     * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
      * <pre>
-     *   long period = start.periodUntil(end, HOURS);   // this method
-     *   dateTime.plus(HOURS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   temporal = start.periodUntil(end, unit);
+     *   temporal = unit.between(start, end);
+     * </pre>
+     * The choice should be made based on which makes the code more readable.
+     * <p>
+     * For example, this method allows the number of days between two dates to
+     * be calculated:
+     * <pre>
+     *  long daysBetween = start.periodUntil(end, DAYS);
+     *  // or alternatively
+     *  long daysBetween = DAYS.between(start, end);
      * </pre>
      *
      * <h3>Specification for implementors</h3>
@@ -394,14 +403,16 @@
      *    // if unit is supported, then calculate and return result
      *    // else throw DateTimeException for unsupported units
      *  }
-     *  return unit.between(this, endTime).getAmount();
+     *  return unit.between(this, endTemporal);
      * </pre>
      * <p>
-     * The target object must not be altered by this method.
+     * Neither this object, nor the specified temporal, may be altered.
      *
      * @param endTemporal  the end temporal, of the same type as this object, not null
      * @param unit  the unit to measure the period in, not null
-     * @return the amount of the period between this and the end
+     * @return the period between this temporal object and the specified one in terms of
+     *  the unit; positive if the specified object is later than this one, negative if
+     *  it is earlier than this one
      * @throws DateTimeException if the period cannot be calculated
      * @throws ArithmeticException if numeric overflow occurs
      */
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java b/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java
index 2f88fa7..cd09573 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java
@@ -79,7 +79,7 @@
  * See {@link ChronoField} for the standard set of fields.
  * <p>
  * Two pieces of date/time information cannot be represented by numbers,
- * the {@linkplain Chrono chronology} and the {@linkplain ZoneId time-zone}.
+ * the {@linkplain java.time.chrono.Chronology chronology} and the {@linkplain ZoneId time-zone}.
  * These can be accessed via {@link #query(TemporalQuery) queries} using
  * the static methods defined on {@link Queries}.
  * <p>
@@ -91,7 +91,7 @@
  * around instances of concrete types, such as {@code LocalDate}.
  * There are many reasons for this, part of which is that implementations
  * of this interface may be in calendar systems other than ISO.
- * See {@link ChronoLocalDate} for a fuller discussion of the issues.
+ * See {@link java.time.chrono.ChronoLocalDate} for a fuller discussion of the issues.
  *
  * <h3>Specification for implementors</h3>
  * This interface places no restrictions on the mutability of implementations,
@@ -113,7 +113,7 @@
      * If the field is supported, then true is returned, otherwise false
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * <p>
      * Implementations must not alter either this object.
@@ -142,7 +142,7 @@
      * If unsupported, then a {@code DateTimeException} must be thrown.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessorl)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessorl)}
      * passing {@code this} as the argument.
      * <p>
      * Implementations must not alter either this object.
@@ -155,7 +155,7 @@
      *    }
      *    throw new DateTimeException("Unsupported field: " + field.getName());
      *  }
-     *  return field.doRange(this);
+     *  return field.rangeRefinedBy(this);
      * </pre>
      *
      * @param field  the field to query the range for, not null
@@ -169,7 +169,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     /**
@@ -187,7 +187,7 @@
      * If unsupported, then a {@code DateTimeException} must be thrown.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument.
      * <p>
      * Implementations must not alter either this object.
@@ -222,7 +222,7 @@
      * If unsupported, then a {@code DateTimeException} must be thrown.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument.
      * <p>
      * Implementations must not alter either this object.
@@ -253,7 +253,7 @@
      * <h3>Specification for implementors</h3>
      * The default implementation must behave equivalent to this code:
      * <pre>
-     *  if (query == Queries.zoneId() || query == Queries.chrono() || query == Queries.precision()) {
+     *  if (query == Queries.zoneId() || query == Queries.chronology() || query == Queries.precision()) {
      *    return null;
      *  }
      *  return query.queryFrom(this);
@@ -283,7 +283,7 @@
      * @throws ArithmeticException if numeric overflow occurs
      */
     public default <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.zoneId() || query == Queries.chrono() || query == Queries.precision()) {
+        if (query == Queries.zoneId() || query == Queries.chronology() || query == Queries.precision()) {
             return null;
         }
         return query.queryFrom(this);
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalAdder.java b/jdk/src/share/classes/java/time/temporal/TemporalAdder.java
deleted file mode 100644
index fad2db4..0000000
--- a/jdk/src/share/classes/java/time/temporal/TemporalAdder.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.temporal;
-
-import java.time.DateTimeException;
-import java.time.Duration;
-import java.time.Period;
-
-/**
- * Strategy for adding to a temporal object.
- * <p>
- * Adders are a key tool for modifying temporal objects.
- * They exist to externalize the process of addition, permitting different
- * approaches, as per the strategy design pattern.
- * <p>
- * There are two equivalent ways of using a {@code TemporalAdder}.
- * The first is to invoke the method on this interface directly.
- * The second is to use {@link Temporal#plus(TemporalAdder)}:
- * <pre>
- *   // these two lines are equivalent, but the second approach is recommended
- *   dateTime = adder.addTo(dateTime);
- *   dateTime = dateTime.plus(adder);
- * </pre>
- * It is recommended to use the second approach, {@code plus(TemporalAdder)},
- * as it is a lot clearer to read in code.
- * <p>
- * The {@link Period} and {@link Duration} classes implement this interface.
- * Adders may also be defined by applications.
- *
- * <h3>Specification for implementors</h3>
- * This interface places no restrictions on the mutability of implementations,
- * however immutability is strongly recommended.
- *
- * @since 1.8
- */
-public interface TemporalAdder {
-
-    /**
-     * Adds to the specified temporal object.
-     * <p>
-     * This adds to the specified temporal object using the logic
-     * encapsulated in the implementing class.
-     * <p>
-     * There are two equivalent ways of using this method.
-     * The first is to invoke this method directly.
-     * The second is to use {@link Temporal#plus(TemporalAdder)}:
-     * <pre>
-     *   // these two lines are equivalent, but the second approach is recommended
-     *   dateTime = adder.addTo(dateTime);
-     *   dateTime = dateTime.plus(adder);
-     * </pre>
-     * It is recommended to use the second approach, {@code plus(TemporalAdder)},
-     * as it is a lot clearer to read in code.
-     *
-     * <h3>Specification for implementors</h3>
-     * The implementation must take the input object and add to it.
-     * The implementation defines the logic of the addition and is responsible for
-     * documenting that logic. It may use any method on {@code Temporal} to
-     * query the temporal object and perform the addition.
-     * The returned object must have the same observable type as the input object
-     * <p>
-     * The input object must not be altered.
-     * Instead, an adjusted copy of the original must be returned.
-     * This provides equivalent, safe behavior for immutable and mutable temporal objects.
-     * <p>
-     * The input temporal object may be in a calendar system other than ISO.
-     * Implementations may choose to document compatibility with other calendar systems,
-     * or reject non-ISO temporal objects by {@link Queries#chrono() querying the chronology}.
-     * <p>
-     * This method may be called from multiple threads in parallel.
-     * It must be thread-safe when invoked.
-     *
-     * @param temporal  the temporal object to adjust, not null
-     * @return an object of the same observable type with the addition made, not null
-     * @throws DateTimeException if unable to add
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    Temporal addTo(Temporal temporal);
-
-}
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalAdjuster.java b/jdk/src/share/classes/java/time/temporal/TemporalAdjuster.java
index 4a6f03d..2b808b6 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalAdjuster.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalAdjuster.java
@@ -93,6 +93,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface TemporalAdjuster {
 
     /**
@@ -127,7 +128,7 @@
      * <p>
      * The input temporal object may be in a calendar system other than ISO.
      * Implementations may choose to document compatibility with other calendar systems,
-     * or reject non-ISO temporal objects by {@link Queries#chrono() querying the chronology}.
+     * or reject non-ISO temporal objects by {@link Queries#chronology() querying the chronology}.
      * <p>
      * This method may be called from multiple threads in parallel.
      * It must be thread-safe when invoked.
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalAmount.java b/jdk/src/share/classes/java/time/temporal/TemporalAmount.java
new file mode 100644
index 0000000..6fa4e47
--- /dev/null
+++ b/jdk/src/share/classes/java/time/temporal/TemporalAmount.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2012, 2013 Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package java.time.temporal;
+
+import java.time.DateTimeException;
+import java.time.Duration;
+import java.time.Period;
+import java.util.List;
+
+/**
+ * Framework-level interface defining an amount of time, such as
+ * "6 hours", "8 days" or "2 years and 3 months".
+ * <p>
+ * This is the base interface type for amounts of time.
+ * An amount is distinct from a date or time-of-day in that it is not tied
+ * to any specific point on the time-line.
+ * <p>
+ * The amount can be thought of as a {@code Map} of {@link TemporalUnit} to
+ * {@code long}, exposed via {@link #getUnits()}and {@link #get(TemporalUnit)}.
+ * A simple case might have a single unit-value pair, such as "6 hours".
+ * A more complex case may have multiple unit-value pairs, such as
+ * "7 years, 3 months and 5 days".
+ * <p>
+ * There are two common implementations.
+ * {@link Period} is a date-based implementation, storing years, months and days.
+ * {@link Duration} is a time-based implementation, storing seconds and nanoseconds,
+ * but providing some access using other duration based units such as minutes,
+ * hours and fixed 24-hour days.
+ * <p>
+ * This interface is a framework-level interface that should not be widely
+ * used in application code. Instead, applications should create and pass
+ * around instances of concrete types, such as {@code Period} and {@code Duration}.
+ *
+ * <h3>Specification for implementors</h3>
+ * This interface places no restrictions on the mutability of implementations,
+ * however immutability is strongly recommended.
+ *
+ * @since 1.8
+ */
+public interface TemporalAmount {
+
+    /**
+     * Returns the value of the requested unit.
+     * The units returned from {@link #getUnits()} uniquely define the
+     * value of the {@code TemporalAmount}.  A value must be returned
+     * for each unit listed in {@code getUnits}.
+     *
+     * <h3>Specification for implementors</h3>
+     * Implementations may declare support for units not listed by {@link #getUnits()}.
+     * Typically, the implementation would define additional units
+     * as conversions for the convenience of developers.
+     *
+     * @param unit the {@code TemporalUnit} for which to return the value
+     * @return the long value of the unit
+     * @throws DateTimeException if the {@code unit} is not supported
+     */
+    public long get(TemporalUnit unit);
+
+    /**
+     * Returns the list of units uniquely defining the value of this TemporalAmount.
+     * The list of {@code TemporalUnits} is defined by the implementation class.
+     * The list is a snapshot of the units at the time {@code getUnits}
+     * is called and is not mutable.
+     * The units are ordered from longest duration to the shortest duration
+     * of the unit.
+     *
+     * <h3>Specification for implementors</h3>
+     * The list of units completely and uniquely represents the
+     * state of the object without omissions, overlaps or duplication.
+     * The units are in order from longest duration to shortest.
+     *
+     * @return the List of {@code TemporalUnits}; not null
+     */
+    public List<TemporalUnit> getUnits();
+
+    /**
+     * Adds to the specified temporal object.
+     * <p>
+     * Adds the amount to the specified temporal object using the logic
+     * encapsulated in the implementing class.
+     * <p>
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method directly.
+     * The second is to use {@link Temporal#plus(TemporalAmount)}:
+     * <pre>
+     *   // These two lines are equivalent, but the second approach is recommended
+     *   dateTime = amount.addTo(dateTime);
+     *   dateTime = dateTime.plus(adder);
+     * </pre>
+     * It is recommended to use the second approach, {@code plus(TemporalAmount)},
+     * as it is a lot clearer to read in code.
+     *
+     * <h3>Specification for implementors</h3>
+     * The implementation must take the input object and add to it.
+     * The implementation defines the logic of the addition and is responsible for
+     * documenting that logic. It may use any method on {@code Temporal} to
+     * query the temporal object and perform the addition.
+     * The returned object must have the same observable type as the input object
+     * <p>
+     * The input object must not be altered.
+     * Instead, an adjusted copy of the original must be returned.
+     * This provides equivalent, safe behavior for immutable and mutable temporal objects.
+     * <p>
+     * The input temporal object may be in a calendar system other than ISO.
+     * Implementations may choose to document compatibility with other calendar systems,
+     * or reject non-ISO temporal objects by {@link Queries#chronology() querying the chronology}.
+     * <p>
+     * This method may be called from multiple threads in parallel.
+     * It must be thread-safe when invoked.
+     *
+     * @param temporal  the temporal object to add the amount to, not null
+     * @return an object of the same observable type with the addition made, not null
+     * @throws DateTimeException if unable to add
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Temporal addTo(Temporal temporal);
+
+    /**
+     * Subtracts this object from the specified temporal object.
+     * <p>
+     * Subtracts the amount from the specified temporal object using the logic
+     * encapsulated in the implementing class.
+     * <p>
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method directly.
+     * The second is to use {@link Temporal#minus(TemporalAmount)}:
+     * <pre>
+     *   // these two lines are equivalent, but the second approach is recommended
+     *   dateTime = amount.subtractFrom(dateTime);
+     *   dateTime = dateTime.minus(amount);
+     * </pre>
+     * It is recommended to use the second approach, {@code minus(TemporalAmount)},
+     * as it is a lot clearer to read in code.
+     *
+     * <h3>Specification for implementors</h3>
+     * The implementation must take the input object and subtract from it.
+     * The implementation defines the logic of the subtraction and is responsible for
+     * documenting that logic. It may use any method on {@code Temporal} to
+     * query the temporal object and perform the subtraction.
+     * The returned object must have the same observable type as the input object
+     * <p>
+     * The input object must not be altered.
+     * Instead, an adjusted copy of the original must be returned.
+     * This provides equivalent, safe behavior for immutable and mutable temporal objects.
+     * <p>
+     * The input temporal object may be in a calendar system other than ISO.
+     * Implementations may choose to document compatibility with other calendar systems,
+     * or reject non-ISO temporal objects by {@link Queries#chronology() querying the chronology}.
+     * <p>
+     * This method may be called from multiple threads in parallel.
+     * It must be thread-safe when invoked.
+     *
+     * @param temporal  the temporal object to subtract the amount from, not null
+     * @return an object of the same observable type with the subtraction made, not null
+     * @throws DateTimeException if unable to subtract
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    public Temporal subtractFrom(Temporal temporal);
+}
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalField.java b/jdk/src/share/classes/java/time/temporal/TemporalField.java
index 187d9e9..c456f56 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalField.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalField.java
@@ -62,8 +62,8 @@
 package java.time.temporal;
 
 import java.time.DateTimeException;
-import java.time.format.DateTimeBuilder;
 import java.util.Comparator;
+import java.util.Map;
 
 /**
  * A field of date-time, such as month-of-year or hour-of-minute.
@@ -72,7 +72,7 @@
  * meaningful for humans. Implementations of this interface represent those fields.
  * <p>
  * The most commonly used units are defined in {@link ChronoField}.
- * Further fields are supplied in {@link ISOFields}, {@link WeekFields} and {@link JulianFields}.
+ * Further fields are supplied in {@link IsoFields}, {@link WeekFields} and {@link JulianFields}.
  * Fields can also be written by application code by implementing this interface.
  * <p>
  * The field works using double dispatch. Client code calls methods on a date-time like
@@ -83,7 +83,8 @@
  * <h3>Specification for implementors</h3>
  * This interface must be implemented with care to ensure other classes operate correctly.
  * All implementations that can be instantiated must be final, immutable and thread-safe.
- * It is recommended to use an enum where possible.
+ * Implementations should be {@code Serializable} where possible.
+ * An enum is as effective implementation choice.
  *
  * @since 1.8
  */
@@ -174,7 +175,7 @@
      * The second is to use {@link TemporalAccessor#isSupported(TemporalField)}:
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
-     *   temporal = thisField.doIsSupported(temporal);
+     *   temporal = thisField.isSupportedBy(temporal);
      *   temporal = temporal.isSupported(thisField);
      * </pre>
      * It is recommended to use the second approach, {@code isSupported(TemporalField)},
@@ -186,7 +187,7 @@
      * @param temporal  the temporal object to query, not null
      * @return true if the date-time can be queried for this field, false if not
      */
-    boolean doIsSupported(TemporalAccessor temporal);
+    boolean isSupportedBy(TemporalAccessor temporal);
 
     /**
      * Get the range of valid values for this field using the temporal object to
@@ -204,7 +205,7 @@
      * The second is to use {@link TemporalAccessor#range(TemporalField)}:
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
-     *   temporal = thisField.doRange(temporal);
+     *   temporal = thisField.rangeRefinedBy(temporal);
      *   temporal = temporal.range(thisField);
      * </pre>
      * It is recommended to use the second approach, {@code range(TemporalField)},
@@ -218,7 +219,7 @@
      * @return the range of valid values for this field, not null
      * @throws DateTimeException if the range for the field cannot be obtained
      */
-    ValueRange doRange(TemporalAccessor temporal);
+    ValueRange rangeRefinedBy(TemporalAccessor temporal);
 
     /**
      * Gets the value of this field from the specified temporal object.
@@ -231,7 +232,7 @@
      * (or {@link TemporalAccessor#get(TemporalField)}):
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
-     *   temporal = thisField.doGet(temporal);
+     *   temporal = thisField.getFrom(temporal);
      *   temporal = temporal.getLong(thisField);
      * </pre>
      * It is recommended to use the second approach, {@code getLong(TemporalField)},
@@ -244,8 +245,9 @@
      * @param temporal  the temporal object to query, not null
      * @return the value of this field, not null
      * @throws DateTimeException if a value for the field cannot be obtained
+     * @throws ArithmeticException if numeric overflow occurs
      */
-    long doGet(TemporalAccessor temporal);
+    long getFrom(TemporalAccessor temporal);
 
     /**
      * Returns a copy of the specified temporal object with the value of this field set.
@@ -266,7 +268,7 @@
      * The second is to use {@link Temporal#with(TemporalField, long)}:
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
-     *   temporal = thisField.doWith(temporal);
+     *   temporal = thisField.adjustInto(temporal);
      *   temporal = temporal.with(thisField);
      * </pre>
      * It is recommended to use the second approach, {@code with(TemporalField)},
@@ -285,21 +287,45 @@
      * @param newValue the new value of the field
      * @return the adjusted temporal object, not null
      * @throws DateTimeException if the field cannot be set
+     * @throws ArithmeticException if numeric overflow occurs
      */
-    <R extends Temporal> R doWith(R temporal, long newValue);
+    <R extends Temporal> R adjustInto(R temporal, long newValue);
 
     /**
-     * Resolves the date/time information in the builder
+     * Resolves this field to provide a simpler alternative.
      * <p>
-     * This method is invoked during the resolve of the builder.
-     * Implementations should combine the associated field with others to form
-     * objects like {@code LocalDate}, {@code LocalTime} and {@code LocalDateTime}
+     * This method is invoked during the resolve phase of parsing.
+     * It is designed to allow application defined fields to be simplified into
+     * more standard fields, such as those on {@code ChronoField}.
+     * <p>
+     * The method will only be invoked if the specified temporal supports this field.
+     * The value of this field is provided.
+     * <p>
+     * The temporal must be queried using the methods of {@code TemporalAccessor},
+     * not using {@code getFrom}, {@code isSupportedBy} or {@code rangeRefinedBy}.
+     * Before querying any field, implementations must ensure it is supported, as
+     * exceptions of this type would negatively affect the calculation of a parsed result.
+     * <p>
+     * If this field can resolve, it must return a map, if not it must return null.
+     * The returned map contains the changes to be made to the temporal, expressed
+     * as field-value pairs. If the value for a field is null, the field is to be
+     * removed from the temporal. A null key must not be added to the result map.
+     * <p>
+     * If the result is non-null, this field will be removed from the temporal.
+     * This field should not be added to the result map.
+     * <p>
+     * The default implementation must return null.
      *
-     * @param builder  the builder to resolve, not null
-     * @param value  the value of the associated field
-     * @return true if builder has been changed, false otherwise
-     * @throws DateTimeException if unable to resolve
+     * @param temporal  the temporal to resolve, not null
+     * @param value  the value of this field
+     * @return a map of fields to update in the temporal, with a mapping to null
+     *  indicating a deletion. The whole map must be null if no resolving occurred
+     * @throws DateTimeException if resolving results in an error. This must not be thrown
+     *  by querying a field on the temporal without first checking if it is supported
+     * @throws ArithmeticException if numeric overflow occurs
      */
-    boolean resolve(DateTimeBuilder builder, long value);
+    public default Map<TemporalField, Long> resolve(TemporalAccessor temporal, long value) {
+        return null;
+    }
 
 }
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalQuery.java b/jdk/src/share/classes/java/time/temporal/TemporalQuery.java
index a319645..40b3943 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalQuery.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalQuery.java
@@ -98,6 +98,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface TemporalQuery<R> {
 
     /**
@@ -128,7 +129,7 @@
      * <p>
      * The input temporal object may be in a calendar system other than ISO.
      * Implementations may choose to document compatibility with other calendar systems,
-     * or reject non-ISO temporal objects by {@link Queries#chrono() querying the chronology}.
+     * or reject non-ISO temporal objects by {@link Queries#chronology() querying the chronology}.
      * <p>
      * This method may be called from multiple threads in parallel.
      * It must be thread-safe when invoked.
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalSubtractor.java b/jdk/src/share/classes/java/time/temporal/TemporalSubtractor.java
deleted file mode 100644
index 4da8f30..0000000
--- a/jdk/src/share/classes/java/time/temporal/TemporalSubtractor.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.temporal;
-
-import java.time.DateTimeException;
-import java.time.Duration;
-import java.time.Period;
-
-/**
- * Strategy for subtracting from a temporal object.
- * <p>
- * Subtractors are a key tool for modifying temporal objects.
- * They exist to externalize the process of subtraction, permitting different
- * approaches, as per the strategy design pattern.
- * <p>
- * There are two equivalent ways of using a {@code TemporalSubtractor}.
- * The first is to invoke the method on this interface directly.
- * The second is to use {@link Temporal#minus(TemporalSubtractor)}:
- * <pre>
- *   // these two lines are equivalent, but the second approach is recommended
- *   dateTime = subtractor.subtractFrom(dateTime);
- *   dateTime = dateTime.minus(subtractor);
- * </pre>
- * It is recommended to use the second approach, {@code minus(TemporalSubtractor)},
- * as it is a lot clearer to read in code.
- * <p>
- * The {@link Period} and {@link Duration} classes implement this interface.
- * Subtractors may also be defined by applications.
- *
- * <h3>Specification for implementors</h3>
- * This interface places no restrictions on the mutability of implementations,
- * however immutability is strongly recommended.
- *
- * @since 1.8
- */
-public interface TemporalSubtractor {
-
-    /**
-     * Subtracts this object from the specified temporal object.
-     * <p>
-     * This adds to the specified temporal object using the logic
-     * encapsulated in the implementing class.
-     * <p>
-     * There are two equivalent ways of using this method.
-     * The first is to invoke this method directly.
-     * The second is to use {@link Temporal#minus(TemporalSubtractor)}:
-     * <pre>
-     *   // these two lines are equivalent, but the second approach is recommended
-     *   dateTime = subtractor.subtractFrom(dateTime);
-     *   dateTime = dateTime.minus(subtractor);
-     * </pre>
-     * It is recommended to use the second approach, {@code minus(TemporalSubtractor)},
-     * as it is a lot clearer to read in code.
-     *
-     * <h3>Specification for implementors</h3>
-     * The implementation must take the input object and subtract from it.
-     * The implementation defines the logic of the subtraction and is responsible for
-     * documenting that logic. It may use any method on {@code Temporal} to
-     * query the temporal object and perform the subtraction.
-     * The returned object must have the same observable type as the input object
-     * <p>
-     * The input object must not be altered.
-     * Instead, an adjusted copy of the original must be returned.
-     * This provides equivalent, safe behavior for immutable and mutable temporal objects.
-     * <p>
-     * The input temporal object may be in a calendar system other than ISO.
-     * Implementations may choose to document compatibility with other calendar systems,
-     * or reject non-ISO temporal objects by {@link Queries#chrono() querying the chronology}.
-     * <p>
-     * This method may be called from multiple threads in parallel.
-     * It must be thread-safe when invoked.
-     *
-     * @param temporal  the temporal object to adjust, not null
-     * @return an object of the same observable type with the subtraction made, not null
-     * @throws DateTimeException if unable to subtract
-     * @throws ArithmeticException if numeric overflow occurs
-     */
-    Temporal subtractFrom(Temporal temporal);
-
-}
diff --git a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java
index 7c8a32b..2f117fc 100644
--- a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java
+++ b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java
@@ -75,7 +75,7 @@
  * See {@link Period} for a class that represents an amount in terms of the common units.
  * <p>
  * The most commonly used units are defined in {@link ChronoUnit}.
- * Further units are supplied in {@link ISOFields}.
+ * Further units are supplied in {@link IsoFields}.
  * Units can also be written by application code by implementing this interface.
  * <p>
  * The unit works using double dispatch. Client code calls methods on a date-time like
@@ -105,6 +105,7 @@
      * Gets the duration of this unit, which may be an estimate.
      * <p>
      * All units return a duration measured in standard nanoseconds from this method.
+     * The duration will be positive and non-zero.
      * For example, an hour has a duration of {@code 60 * 60 * 1,000,000,000ns}.
      * <p>
      * Some units may return an accurate duration while others return an estimate.
@@ -142,7 +143,7 @@
      * @param temporal  the temporal object to check, not null
      * @return true if the unit is supported
      */
-    public default boolean isSupported(Temporal temporal) {
+    public default boolean isSupportedBy(Temporal temporal) {
         try {
             temporal.plus(1, this);
             return true;
@@ -169,7 +170,7 @@
      * The second is to use {@link Temporal#plus(long, TemporalUnit)}:
      * <pre>
      *   // these two lines are equivalent, but the second approach is recommended
-     *   temporal = thisUnit.doPlus(temporal);
+     *   temporal = thisUnit.addTo(temporal);
      *   temporal = temporal.plus(thisUnit);
      * </pre>
      * It is recommended to use the second approach, {@code plus(TemporalUnit)},
@@ -177,42 +178,68 @@
      * <p>
      * Implementations should perform any queries or calculations using the units
      * available in {@link ChronoUnit} or the fields available in {@link ChronoField}.
-     * If the field is not supported a {@code DateTimeException} must be thrown.
+     * If the unit is not supported a {@code DateTimeException} must be thrown.
      * <p>
      * Implementations must not alter the specified temporal object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
      *
      * @param <R>  the type of the Temporal object
-     * @param dateTime  the temporal object to adjust, not null
-     * @param periodToAdd  the period of this unit to add, positive or negative
+     * @param temporal  the temporal object to adjust, not null
+     * @param amount  the amount of this unit to add, positive or negative
      * @return the adjusted temporal object, not null
      * @throws DateTimeException if the period cannot be added
      */
-    <R extends Temporal> R doPlus(R dateTime, long periodToAdd);
+    <R extends Temporal> R addTo(R temporal, long amount);
 
     //-----------------------------------------------------------------------
     /**
-     * Calculates the period in terms of this unit between two temporal objects of the same type.
+     * Calculates the period in terms of this unit between two temporal objects
+     * of the same type.
      * <p>
-     * The period will be positive if the second date-time is after the first, and
-     * negative if the second date-time is before the first.
-     * Call {@link SimplePeriod#abs() abs()} on the result to ensure that the result
-     * is always positive.
+     * This calculates the period between two temporals in terms of this unit.
+     * The start and end points are supplied as temporal objects and must be
+     * of the same type.
+     * The result will be negative if the end is before the start.
+     * For example, the period in hours between two temporal objects can be
+     * calculated using {@code HOURS.between(startTime, endTime)}.
      * <p>
-     * The result can be queried for the {@link SimplePeriod#getAmount() amount}, the
-     * {@link SimplePeriod#getUnit() unit} and used directly in addition/subtraction:
+     * The calculation returns a whole number, representing the number of
+     * complete units between the two temporals.
+     * For example, the period in hours between the times 11:30 and 13:29
+     * will only be one hour as it is one minute short of two hours.
+     * <p>
+     * There are two equivalent ways of using this method.
+     * The first is to invoke this method directly.
+     * The second is to use {@link Temporal#periodUntil(Temporal, TemporalUnit)}:
      * <pre>
-     *  date = date.minus(MONTHS.between(start, end));
+     *   // these two lines are equivalent
+     *   temporal = thisUnit.between(start, end);
+     *   temporal = start.periodUntil(end, thisUnit);
      * </pre>
+     * The choice should be made based on which makes the code more readable.
+     * <p>
+     * For example, this method allows the number of days between two dates to
+     * be calculated:
+     * <pre>
+     *  long daysBetween = DAYS.between(start, end);
+     *  // or alternatively
+     *  long daysBetween = start.periodUntil(end, DAYS);
+     * </pre>
+     * <p>
+     * Implementations should perform any queries or calculations using the units
+     * available in {@link ChronoUnit} or the fields available in {@link ChronoField}.
+     * If the unit is not supported a {@code DateTimeException} must be thrown.
+     * Implementations must not alter the specified temporal objects.
      *
-     * @param <R>  the type of the Temporal object; the two date-times must be of the same type
-     * @param dateTime1  the base temporal object, not null
-     * @param dateTime2  the other temporal object, not null
+     * @param temporal1  the base temporal object, not null
+     * @param temporal2  the other temporal object, not null
      * @return the period between datetime1 and datetime2 in terms of this unit;
-     *      positive if datetime2 is later than datetime1, not null
+     *  positive if datetime2 is later than datetime1, negative if earlier
+     * @throws DateTimeException if the period cannot be calculated
+     * @throws ArithmeticException if numeric overflow occurs
      */
-    <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2);
+    long between(Temporal temporal1, Temporal temporal2);
 
     //-----------------------------------------------------------------------
     /**
diff --git a/jdk/src/share/classes/java/time/temporal/WeekFields.java b/jdk/src/share/classes/java/time/temporal/WeekFields.java
index 364aa91..b9d7c15 100644
--- a/jdk/src/share/classes/java/time/temporal/WeekFields.java
+++ b/jdk/src/share/classes/java/time/temporal/WeekFields.java
@@ -61,15 +61,30 @@
  */
 package java.time.temporal;
 
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.DAY_OF_YEAR;
+import static java.time.temporal.ChronoField.EPOCH_DAY;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.YEAR;
+import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.MONTHS;
+import static java.time.temporal.ChronoUnit.WEEKS;
+import static java.time.temporal.ChronoUnit.YEARS;
+
 import java.io.InvalidObjectException;
 import java.io.Serializable;
 import java.time.DayOfWeek;
-import java.time.format.DateTimeBuilder;
-import java.util.GregorianCalendar;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Chronology;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import sun.util.locale.provider.CalendarDataUtility;
 
 /**
  * Localized definitions of the day-of-week, week-of-month and week-of-year fields.
@@ -135,8 +150,8 @@
     // implementation notes
     // querying week-of-month or week-of-year should return the week value bound within the month/year
     // however, setting the week value should be lenient (use plus/minus weeks)
-    // allow week-of-month outer range [0 to 5]
-    // allow week-of-year outer range [0 to 53]
+    // allow week-of-month outer range [0 to 6]
+    // allow week-of-year outer range [0 to 54]
     // this is because callers shouldn't be expected to know the details of validity
 
     /**
@@ -209,12 +224,9 @@
         Objects.requireNonNull(locale, "locale");
         locale = new Locale(locale.getLanguage(), locale.getCountry());  // elminate variants
 
-        // obtain these from GregorianCalendar for now
-        // TODO: consider getting them directly from the spi
-        GregorianCalendar gcal = new GregorianCalendar(locale);
-        int calDow = gcal.getFirstDayOfWeek();
+        int calDow = CalendarDataUtility.retrieveFirstDayOfWeek(locale);
         DayOfWeek dow = DayOfWeek.SUNDAY.plus(calDow - 1);
-        int minDays = gcal.getMinimalDaysInFirstWeek();
+        int minDays = CalendarDataUtility.retrieveMinimalDaysInFirstWeek(locale);
         return WeekFields.of(dow, minDays);
     }
 
@@ -437,8 +449,7 @@
          * the ISO DAY_OF_WEEK field to compute week boundaries.
          */
         static ComputedDayOfField ofDayOfWeekField(WeekFields weekDef) {
-            return new ComputedDayOfField("DayOfWeek", weekDef,
-                    ChronoUnit.DAYS, ChronoUnit.WEEKS, DAY_OF_WEEK_RANGE);
+            return new ComputedDayOfField("DayOfWeek", weekDef, DAYS, WEEKS, DAY_OF_WEEK_RANGE);
         }
 
         /**
@@ -447,8 +458,7 @@
          * @see WeekFields#weekOfMonth()
          */
         static ComputedDayOfField ofWeekOfMonthField(WeekFields weekDef) {
-            return new ComputedDayOfField("WeekOfMonth", weekDef,
-                    ChronoUnit.WEEKS, ChronoUnit.MONTHS, WEEK_OF_MONTH_RANGE);
+            return new ComputedDayOfField("WeekOfMonth", weekDef, WEEKS, MONTHS, WEEK_OF_MONTH_RANGE);
         }
 
         /**
@@ -457,8 +467,7 @@
          * @see WeekFields#weekOfYear()
          */
         static ComputedDayOfField ofWeekOfYearField(WeekFields weekDef) {
-            return new ComputedDayOfField("WeekOfYear", weekDef,
-                    ChronoUnit.WEEKS, ChronoUnit.YEARS, WEEK_OF_YEAR_RANGE);
+            return new ComputedDayOfField("WeekOfYear", weekDef, WEEKS, YEARS, WEEK_OF_YEAR_RANGE);
         }
         private final String name;
         private final WeekFields weekDef;
@@ -475,31 +484,43 @@
         }
 
         private static final ValueRange DAY_OF_WEEK_RANGE = ValueRange.of(1, 7);
-        private static final ValueRange WEEK_OF_MONTH_RANGE = ValueRange.of(0, 1, 4, 5);
-        private static final ValueRange WEEK_OF_YEAR_RANGE = ValueRange.of(0, 1, 52, 53);
+        private static final ValueRange WEEK_OF_MONTH_RANGE = ValueRange.of(0, 1, 4, 6);
+        private static final ValueRange WEEK_OF_YEAR_RANGE = ValueRange.of(0, 1, 52, 54);
 
         @Override
-        public long doGet(TemporalAccessor temporal) {
+        public long getFrom(TemporalAccessor temporal) {
             // Offset the ISO DOW by the start of this week
             int sow = weekDef.getFirstDayOfWeek().getValue();
-            int isoDow = temporal.get(ChronoField.DAY_OF_WEEK);
-            int dow = Math.floorMod(isoDow - sow, 7) + 1;
+            int dow = localizedDayOfWeek(temporal, sow);
 
-            if (rangeUnit == ChronoUnit.WEEKS) {
+            if (rangeUnit == WEEKS) {  // day-of-week
                 return dow;
-            } else if (rangeUnit == ChronoUnit.MONTHS) {
-                int dom = temporal.get(ChronoField.DAY_OF_MONTH);
-                int offset = startOfWeekOffset(dom, dow);
-                return computeWeek(offset, dom);
-            } else if (rangeUnit == ChronoUnit.YEARS) {
-                int doy = temporal.get(ChronoField.DAY_OF_YEAR);
-                int offset = startOfWeekOffset(doy, dow);
-                return computeWeek(offset, doy);
+            } else if (rangeUnit == MONTHS) {  // week-of-month
+                return localizedWeekOfMonth(temporal, dow);
+            } else if (rangeUnit == YEARS) {  // week-of-year
+                return localizedWeekOfYear(temporal, dow);
             } else {
                 throw new IllegalStateException("unreachable");
             }
         }
 
+        private int localizedDayOfWeek(TemporalAccessor temporal, int sow) {
+            int isoDow = temporal.get(DAY_OF_WEEK);
+            return Math.floorMod(isoDow - sow, 7) + 1;
+        }
+
+        private long localizedWeekOfMonth(TemporalAccessor temporal, int dow) {
+            int dom = temporal.get(DAY_OF_MONTH);
+            int offset = startOfWeekOffset(dom, dow);
+            return computeWeek(offset, dom);
+        }
+
+        private long localizedWeekOfYear(TemporalAccessor temporal, int dow) {
+            int doy = temporal.get(DAY_OF_YEAR);
+            int offset = startOfWeekOffset(doy, dow);
+            return computeWeek(offset, doy);
+        }
+
         /**
          * Returns an offset to align week start with a day of month or day of year.
          *
@@ -530,59 +551,62 @@
             return ((7 + offset + (day - 1)) / 7);
         }
 
+        @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doWith(R temporal, long newValue) {
+        public <R extends Temporal> R adjustInto(R temporal, long newValue) {
             // Check the new value and get the old value of the field
-            int newVal = range.checkValidIntValue(newValue, this);
+            int newVal = range.checkValidIntValue(newValue, this);  // lenient check range
             int currentVal = temporal.get(this);
             if (newVal == currentVal) {
                 return temporal;
             }
             // Compute the difference and add that using the base using of the field
-            int delta = newVal - currentVal;
-            return (R) temporal.plus(delta, baseUnit);
+            return (R) temporal.plus(newVal - currentVal, baseUnit);
         }
 
         @Override
-        public boolean resolve(DateTimeBuilder builder, long value) {
+        public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long value) {
             int newValue = range.checkValidIntValue(value, this);
-            // DOW and YEAR are necessary for all fields; Chrono defaults to ISO if not present
             int sow = weekDef.getFirstDayOfWeek().getValue();
-            int dow = builder.get(weekDef.dayOfWeek());
-            int year = builder.get(ChronoField.YEAR);
-            Chrono chrono = Chrono.from(builder);
-
-            // The WOM and WOY fields are the critical values
-            if (rangeUnit == ChronoUnit.MONTHS) {
-                // Process WOM value by combining with DOW and MONTH, YEAR
-                int month = builder.get(ChronoField.MONTH_OF_YEAR);
-                ChronoLocalDate cd = chrono.date(year, month, 1);
-                int offset = startOfWeekOffset(1, cd.get(weekDef.dayOfWeek()));
-                offset += dow - 1;    // offset to desired day of week
-                offset += 7 * (newValue - 1);    // offset by week number
-                ChronoLocalDate result = cd.plus(offset, ChronoUnit.DAYS);
-                builder.addFieldValue(ChronoField.DAY_OF_MONTH, result.get(ChronoField.DAY_OF_MONTH));
-                builder.removeFieldValue(this);
-                builder.removeFieldValue(weekDef.dayOfWeek());
-                return true;
-            } else if (rangeUnit == ChronoUnit.YEARS) {
-                // Process WOY
-                ChronoLocalDate cd = chrono.date(year, 1, 1);
-                int offset = startOfWeekOffset(1, cd.get(weekDef.dayOfWeek()));
-                offset += dow - 1;    // offset to desired day of week
-                offset += 7 * (newValue - 1);    // offset by week number
-                ChronoLocalDate result = cd.plus(offset, ChronoUnit.DAYS);
-                builder.addFieldValue(ChronoField.DAY_OF_MONTH, result.get(ChronoField.DAY_OF_MONTH));
-                builder.addFieldValue(ChronoField.MONTH_OF_YEAR, result.get(ChronoField.MONTH_OF_YEAR));
-                builder.removeFieldValue(this);
-                builder.removeFieldValue(weekDef.dayOfWeek());
-                return true;
+            if (rangeUnit == WEEKS) {  // day-of-week
+                int isoDow = Math.floorMod((sow - 1) + (newValue - 1), 7) + 1;
+                return Collections.<TemporalField, Long>singletonMap(DAY_OF_WEEK, (long) isoDow);
+            }
+            if ((temporal.isSupported(YEAR) && temporal.isSupported(DAY_OF_WEEK)) == false) {
+                return null;
+            }
+            int dow = localizedDayOfWeek(temporal, sow);
+            int year = temporal.get(YEAR);
+            Chronology chrono = Chronology.from(temporal);  // defaults to ISO
+            if (rangeUnit == MONTHS) {  // week-of-month
+                if (temporal.isSupported(MONTH_OF_YEAR) == false) {
+                    return null;
+                }
+                int month = temporal.get(ChronoField.MONTH_OF_YEAR);
+                ChronoLocalDate date = chrono.date(year, month, 1);
+                int dateDow = localizedDayOfWeek(date, sow);
+                long weeks = newValue - localizedWeekOfMonth(date, dateDow);
+                int days = dow - dateDow;
+                date = date.plus(weeks * 7 + days, DAYS);
+                Map<TemporalField, Long> result = new HashMap<>(4, 1.0f);
+                result.put(EPOCH_DAY, date.toEpochDay());
+                result.put(YEAR, null);
+                result.put(MONTH_OF_YEAR, null);
+                result.put(DAY_OF_WEEK, null);
+                return result;
+            } else if (rangeUnit == YEARS) {  // week-of-year
+                ChronoLocalDate date = chrono.date(year, 1, 1);
+                int dateDow = localizedDayOfWeek(date, sow);
+                long weeks = newValue - localizedWeekOfYear(date, dateDow);
+                int days = dow - dateDow;
+                date = date.plus(weeks * 7 + days, DAYS);
+                Map<TemporalField, Long> result = new HashMap<>(4, 1.0f);
+                result.put(EPOCH_DAY, date.toEpochDay());
+                result.put(YEAR, null);
+                result.put(DAY_OF_WEEK, null);
+                return result;
             } else {
-                // ignore DOW of WEEK field; the value will be processed by WOM or WOY
-                int isoDow = Math.floorMod((sow - 1) + (dow - 1), 7) + 1;
-                builder.addFieldValue(ChronoField.DAY_OF_WEEK, isoDow);
-                // Not removed, the week-of-xxx fields need this value
-                return true;
+                throw new IllegalStateException("unreachable");
             }
         }
 
@@ -607,46 +631,39 @@
             return range;
         }
 
-        //-------------------------------------------------------------------------
-        @Override
-        public int compare(TemporalAccessor temporal1, TemporalAccessor temporal2) {
-            return Long.compare(temporal1.getLong(this), temporal2.getLong(this));
-        }
-
         //-----------------------------------------------------------------------
         @Override
-        public boolean doIsSupported(TemporalAccessor temporal) {
-            if (temporal.isSupported(ChronoField.DAY_OF_WEEK)) {
-                if (rangeUnit == ChronoUnit.WEEKS) {
+        public boolean isSupportedBy(TemporalAccessor temporal) {
+            if (temporal.isSupported(DAY_OF_WEEK)) {
+                if (rangeUnit == WEEKS) {  // day-of-week
                     return true;
-                } else if (rangeUnit == ChronoUnit.MONTHS) {
-                    return temporal.isSupported(ChronoField.DAY_OF_MONTH);
-                } else if (rangeUnit == ChronoUnit.YEARS) {
-                    return temporal.isSupported(ChronoField.DAY_OF_YEAR);
+                } else if (rangeUnit == MONTHS) {  // week-of-month
+                    return temporal.isSupported(DAY_OF_MONTH);
+                } else if (rangeUnit == YEARS) {  // week-of-year
+                    return temporal.isSupported(DAY_OF_YEAR);
                 }
             }
             return false;
         }
 
         @Override
-        public ValueRange doRange(TemporalAccessor temporal) {
-            if (rangeUnit == ChronoUnit.WEEKS) {
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+            if (rangeUnit == ChronoUnit.WEEKS) {  // day-of-week
                 return range;
             }
 
             TemporalField field = null;
-            if (rangeUnit == ChronoUnit.MONTHS) {
-                field = ChronoField.DAY_OF_MONTH;
-            } else if (rangeUnit == ChronoUnit.YEARS) {
-                field = ChronoField.DAY_OF_YEAR;
+            if (rangeUnit == MONTHS) {  // week-of-month
+                field = DAY_OF_MONTH;
+            } else if (rangeUnit == YEARS) {  // week-of-year
+                field = DAY_OF_YEAR;
             } else {
                 throw new IllegalStateException("unreachable");
             }
 
             // Offset the ISO DOW by the start of this week
             int sow = weekDef.getFirstDayOfWeek().getValue();
-            int isoDow = temporal.get(ChronoField.DAY_OF_WEEK);
-            int dow = Math.floorMod(isoDow - sow, 7) + 1;
+            int dow = localizedDayOfWeek(temporal, sow);
 
             int offset = startOfWeekOffset(temporal.get(field), dow);
             ValueRange fieldRange = temporal.range(field);
diff --git a/jdk/src/share/classes/java/time/temporal/package-info.java b/jdk/src/share/classes/java/time/temporal/package-info.java
index da9a4b7..d769120 100644
--- a/jdk/src/share/classes/java/time/temporal/package-info.java
+++ b/jdk/src/share/classes/java/time/temporal/package-info.java
@@ -62,8 +62,7 @@
 
 /**
  * <p>
- * Access to date and time using fields and units, additional value type classes and
- * base support for calendar systems other than the default ISO.
+ * Access to date and time using fields and units, and date time adjusters.
  * </p>
  * <p>
  * This package expands on the base package to provide additional functionality for
@@ -74,8 +73,6 @@
  * <li>Fields of date-time, such as month-of-year, day-of-week or hour-of-day</li>
  * <li>Date-time adjustment functions</li>
  * <li>Different definitions of weeks</li>
- * <li>Alternate calendar systems</li>
- * <li>Additional value types</li>
  * </ul>
  *
  * <h3>Fields and Units</h3>
@@ -91,7 +88,7 @@
  * All fields implement {@link java.time.temporal.TemporalField}.
  * The set of well known fields are defined in {@link java.time.temporal.ChronoField}, such as {@code HOUR_OF_DAY}.
  * Additional fields are defined by {@link java.time.temporal.JulianFields}, {@link java.time.temporal.WeekFields}
- * and {@link java.time.temporal.ISOFields}.
+ * and {@link java.time.temporal.IsoFields}.
  * The field interface is designed to allow applications defined fields.
  * </p>
  * <p>
@@ -122,8 +119,7 @@
  * Applications can also define adjusters by implementing {@code TemporalAdjuster}.
  * </p>
  * <p>
- * There are additional interfaces to model addition to and subtraction from a date-time.
- * These are {@link java.time.temporal.TemporalAdder} and {@link java.time.temporal.TemporalSubtractor}.
+ * The {@link java.time.temporal.TemporalAmount} interface models amounts of relative time.
  * </p>
  * <p>
  * In addition to adjusting a date-time, an interface is provided to enable querying -
@@ -144,60 +140,9 @@
  * <p>
  * The ISO calendar system defines an additional week-based division of years.
  * This defines a year based on whole Monday to Monday weeks.
- * This is modeled in {@link java.time.temporal.ISOFields}.
+ * This is modeled in {@link java.time.temporal.IsoFields}.
  * </p>
  *
- * <h3>Alternate calendar systems</h3>
- * <p>
- * The main API is based around the calendar system defined in ISO-8601.
- * However, there are other calendar systems, and this package provides basic support for them.
- * The alternate calendars are provided in the {@code java.time.calendar} package.
- * </p>
- * <p>
- * A calendar system is defined by the {@link java.time.temporal.Chrono} interface,
- * while a date in a calendar system is defined by the {@link java.time.temporal.ChronoLocalDate} interface.
- * </p>
- * <p>
- * It is intended that applications use the main API whenever possible, including code to read and write
- * from a persistent data store, such as a database, and to send dates and times across a network.
- * The "chrono" classes are then used at the user interface level to deal with localized input/output.
- * </p>
- * <p>
- * Using non-ISO calendar systems in an application introduces significant extra complexity.
- * Ensure that the warnings and recommendations in {@code ChronoLocalDate} have been read before
- * working with the "chrono" interfaces.
- * </p>
- * <p>
- * This example creates and uses a date in a non-ISO calendar system.
- * </p>
- * <pre>
- *   // Print the Thai Buddhist date
- *       ChronoLocalDate&lt;ThaiBuddhistChrono&gt; now1 = ThaiBuddhistChrono.INSTANCE.dateNow();
- *       int day = now1.get(ChronoField.DAY_OF_MONTH);
- *       int dow = now1.get(ChronoField.DAY_OF_WEEK);
- *       int month = now1.get(ChronoField.MONTH_OF_YEAR);
- *       int year = now1.get(ChronoField.YEAR);
- *       System.out.printf("  Today is %s %s %d-%s-%d%n", now1.getChrono().getId(),
- *                 dow, day, month, year);
- *
- *   // Enumerate the list of available calendars and print today for each
- *       Set&lt;Chrono&lt;?&gt;&gt; chronos = Chrono.getAvailableChronologies();
- *       for (Chrono&lt;?&gt; chrono : chronos) {
- *         ChronoLocalDate&lt;?&gt; date = chrono.dateNow();
- *         System.out.printf("   %20s: %s%n", chrono.getId(), date.toString());
- *       }
- *
- *   // Print today's date and the last day of the year for the Thai Buddhist Calendar.
- *       ChronoLocalDate&lt;ThaiBuddhistChrono&gt; first = now1
- *                 .with(ChronoField.DAY_OF_MONTH, 1)
- *                 .with(ChronoField.MONTH_OF_YEAR, 1);
- *       ChronoLocalDate&lt;ThaiBuddhistChrono&gt; last = first
- *                 .plus(1, ChronoUnit.YEARS)
- *                 .minus(1, ChronoUnit.DAYS);
- *       System.out.printf("  %s: 1st of year: %s; end of year: %s%n", last.getChrono().getId(),
- *                 first, last);
- *  </pre>
- *
  * <h3>Package specification</h3>
  * <p>
  * Unless otherwise noted, passing a null argument to a constructor or method in any class or interface
diff --git a/jdk/src/share/classes/java/time/zone/TzdbZoneRulesProvider.java b/jdk/src/share/classes/java/time/zone/TzdbZoneRulesProvider.java
index ed81a06..22f6ffd 100644
--- a/jdk/src/share/classes/java/time/zone/TzdbZoneRulesProvider.java
+++ b/jdk/src/share/classes/java/time/zone/TzdbZoneRulesProvider.java
@@ -66,43 +66,36 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.StreamCorruptedException;
-import java.nio.file.FileSystems;
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.time.DateTimeException;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.NavigableMap;
 import java.util.Objects;
 import java.util.Set;
 import java.util.TreeMap;
-import java.util.concurrent.ConcurrentNavigableMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.zip.ZipFile;
 
 /**
  * Loads time-zone rules for 'TZDB'.
- * <p>
- * This class is public for the service loader to access.
- *
- * <h3>Specification for implementors</h3>
- * This class is immutable and thread-safe.
  *
  * @since 1.8
  */
 final class TzdbZoneRulesProvider extends ZoneRulesProvider {
-    // service loader seems to need it to be public
 
     /**
      * All the regions that are available.
      */
-    private final Set<String> regionIds = new CopyOnWriteArraySet<>();
+    private List<String> regionIds;
     /**
-     * All the versions that are available.
+     * Version Id of this tzdb rules
      */
-    private final ConcurrentNavigableMap<String, Version> versions = new ConcurrentSkipListMap<>();
+    private String versionId;
+    /**
+     * Region to rules mapping
+     */
+    private final Map<String, Object> regionToRules = new ConcurrentHashMap<>();
 
     /**
      * Creates an instance.
@@ -111,94 +104,61 @@
      * @throws ZoneRulesException if unable to load
      */
     public TzdbZoneRulesProvider() {
-        super();
-        if (load(ClassLoader.getSystemClassLoader()) == false) {
-            throw new ZoneRulesException("No time-zone rules found for 'TZDB'");
+        try {
+            String libDir = System.getProperty("java.home") + File.separator + "lib";
+            File tzdbJar = new File(libDir, "tzdb.jar");
+            try (ZipFile zf = new ZipFile(tzdbJar);
+                 DataInputStream dis = new DataInputStream(
+                     zf.getInputStream(zf.getEntry("TZDB.dat")))) {
+                load(dis);
+            }
+        } catch (Exception ex) {
+            throw new ZoneRulesException("Unable to load TZDB time-zone rules", ex);
         }
     }
 
-    //-----------------------------------------------------------------------
     @Override
     protected Set<String> provideZoneIds() {
         return new HashSet<>(regionIds);
     }
 
     @Override
-    protected ZoneRules provideRules(String zoneId) {
-        Objects.requireNonNull(zoneId, "zoneId");
-        ZoneRules rules = versions.lastEntry().getValue().getRules(zoneId);
-        if (rules == null) {
+    protected ZoneRules provideRules(String zoneId, boolean forCaching) {
+        // forCaching flag is ignored because this is not a dynamic provider
+        Object obj = regionToRules.get(zoneId);
+        if (obj == null) {
             throw new ZoneRulesException("Unknown time-zone ID: " + zoneId);
         }
-        return rules;
+        try {
+            if (obj instanceof byte[]) {
+                byte[] bytes = (byte[]) obj;
+                DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
+                obj = Ser.read(dis);
+                regionToRules.put(zoneId, obj);
+            }
+            return (ZoneRules) obj;
+        } catch (Exception ex) {
+            throw new ZoneRulesException("Invalid binary time-zone data: TZDB:" + zoneId + ", version: " + versionId, ex);
+        }
     }
 
     @Override
     protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
         TreeMap<String, ZoneRules> map = new TreeMap<>();
-        for (Version version : versions.values()) {
-            ZoneRules rules = version.getRules(zoneId);
-            if (rules != null) {
-                map.put(version.versionId, rules);
-            }
+        ZoneRules rules = getRules(zoneId, false);
+        if (rules != null) {
+            map.put(versionId, rules);
         }
         return map;
     }
 
-    //-------------------------------------------------------------------------
-    /**
-     * Loads the rules.
-     *
-     * @param classLoader  the class loader to use, not null
-     * @return true if updated
-     * @throws ZoneRulesException if unable to load
-     */
-    private boolean load(ClassLoader classLoader) {
-        Object updated = Boolean.FALSE;
-        try {
-            updated = AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                public Object run() throws IOException, ClassNotFoundException {
-                    File tzdbJar = null;
-                    // TBD: workaround for now, so test/java/time tests can be
-                    //      run against Java runtime that does not have tzdb
-                    String tzdbProp = System.getProperty("java.time.zone.tzdbjar");
-                    if (tzdbProp != null) {
-                        tzdbJar = new File(tzdbProp);
-                    } else {
-                        String libDir = System.getProperty("java.home") + File.separator + "lib";
-                        try {
-                            libDir = FileSystems.getDefault().getPath(libDir).toRealPath().toString();
-                        } catch(Exception e) {}
-                        tzdbJar = new File(libDir, "tzdb.jar");
-                    }
-                    try (ZipFile zf = new ZipFile(tzdbJar);
-                         DataInputStream dis = new DataInputStream(
-                             zf.getInputStream(zf.getEntry("TZDB.dat")))) {
-                        Iterable<Version> loadedVersions = load(dis);
-                        for (Version loadedVersion : loadedVersions) {
-                            if (versions.putIfAbsent(loadedVersion.versionId, loadedVersion) != null) {
-                                throw new DateTimeException(
-                                    "Data already loaded for TZDB time-zone rules version: " +
-                                    loadedVersion.versionId);
-                            }
-                        }
-                    }
-                    return Boolean.TRUE;
-                }
-            });
-        } catch (Exception ex) {
-            throw new ZoneRulesException("Unable to load TZDB time-zone rules", ex);
-        }
-        return updated == Boolean.TRUE;
-    }
-
     /**
      * Loads the rules from a DateInputStream, often in a jar file.
      *
      * @param dis  the DateInputStream to load, not null
      * @throws Exception if an error occurs
      */
-    private Iterable<Version> load(DataInputStream dis) throws ClassNotFoundException, IOException {
+    private void load(DataInputStream dis) throws Exception {
         if (dis.readByte() != 1) {
             throw new StreamCorruptedException("File format not recognised");
         }
@@ -209,9 +169,8 @@
         }
         // versions
         int versionCount = dis.readShort();
-        String[] versionArray = new String[versionCount];
         for (int i = 0; i < versionCount; i++) {
-            versionArray[i] = dis.readUTF();
+            versionId = dis.readUTF();
         }
         // regions
         int regionCount = dis.readShort();
@@ -219,7 +178,7 @@
         for (int i = 0; i < regionCount; i++) {
             regionArray[i] = dis.readUTF();
         }
-        regionIds.addAll(Arrays.asList(regionArray));
+        regionIds = Arrays.asList(regionArray);
         // rules
         int ruleCount = dis.readShort();
         Object[] ruleArray = new Object[ruleCount];
@@ -228,71 +187,20 @@
             dis.readFully(bytes);
             ruleArray[i] = bytes;
         }
-        AtomicReferenceArray<Object> ruleData = new AtomicReferenceArray<>(ruleArray);
         // link version-region-rules
-        Set<Version> versionSet = new HashSet<Version>(versionCount);
         for (int i = 0; i < versionCount; i++) {
             int versionRegionCount = dis.readShort();
-            String[] versionRegionArray = new String[versionRegionCount];
-            short[] versionRulesArray = new short[versionRegionCount];
+            regionToRules.clear();
             for (int j = 0; j < versionRegionCount; j++) {
-                versionRegionArray[j] = regionArray[dis.readShort()];
-                versionRulesArray[j] = dis.readShort();
+                String region = regionArray[dis.readShort()];
+                Object rule = ruleArray[dis.readShort() & 0xffff];
+                regionToRules.put(region, rule);
             }
-            versionSet.add(new Version(versionArray[i], versionRegionArray, versionRulesArray, ruleData));
         }
-        return versionSet;
     }
 
     @Override
     public String toString() {
-        return "TZDB";
+        return "TZDB[" + versionId + "]";
     }
-
-    //-----------------------------------------------------------------------
-    /**
-     * A version of the TZDB rules.
-     */
-    static class Version {
-        private final String versionId;
-        private final String[] regionArray;
-        private final short[] ruleIndices;
-        private final AtomicReferenceArray<Object> ruleData;
-
-        Version(String versionId, String[] regionIds, short[] ruleIndices, AtomicReferenceArray<Object> ruleData) {
-            this.ruleData = ruleData;
-            this.versionId = versionId;
-            this.regionArray = regionIds;
-            this.ruleIndices = ruleIndices;
-        }
-
-        ZoneRules getRules(String regionId) {
-            int regionIndex = Arrays.binarySearch(regionArray, regionId);
-            if (regionIndex < 0) {
-                return null;
-            }
-            try {
-                return createRule(ruleIndices[regionIndex]);
-            } catch (Exception ex) {
-                throw new ZoneRulesException("Invalid binary time-zone data: TZDB:" + regionId + ", version: " + versionId, ex);
-            }
-        }
-
-        ZoneRules createRule(short index) throws Exception {
-            Object obj = ruleData.get(index);
-            if (obj instanceof byte[]) {
-                byte[] bytes = (byte[]) obj;
-                DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
-                obj = Ser.read(dis);
-                ruleData.set(index, obj);
-            }
-            return (ZoneRules) obj;
-        }
-
-        @Override
-        public String toString() {
-            return versionId;
-        }
-    }
-
 }
diff --git a/jdk/src/share/classes/java/time/zone/ZoneOffsetTransitionRule.java b/jdk/src/share/classes/java/time/zone/ZoneOffsetTransitionRule.java
index 4b6f7e9..5275d184 100644
--- a/jdk/src/share/classes/java/time/zone/ZoneOffsetTransitionRule.java
+++ b/jdk/src/share/classes/java/time/zone/ZoneOffsetTransitionRule.java
@@ -74,7 +74,7 @@
 import java.time.LocalTime;
 import java.time.Month;
 import java.time.ZoneOffset;
-import java.time.temporal.ISOChrono;
+import java.time.chrono.IsoChronology;
 import java.util.Objects;
 
 /**
@@ -430,7 +430,7 @@
     public ZoneOffsetTransition createTransition(int year) {
         LocalDate date;
         if (dom < 0) {
-            date = LocalDate.of(year, month, month.length(ISOChrono.INSTANCE.isLeapYear(year)) + 1 + dom);
+            date = LocalDate.of(year, month, month.length(IsoChronology.INSTANCE.isLeapYear(year)) + 1 + dom);
             if (dow != null) {
                 date = date.with(previousOrSame(dow));
             }
diff --git a/jdk/src/share/classes/java/time/zone/ZoneRules.java b/jdk/src/share/classes/java/time/zone/ZoneRules.java
index 159d6e0..fa7498c 100644
--- a/jdk/src/share/classes/java/time/zone/ZoneRules.java
+++ b/jdk/src/share/classes/java/time/zone/ZoneRules.java
@@ -71,7 +71,7 @@
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
-import java.time.temporal.Year;
+import java.time.Year;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
diff --git a/jdk/src/share/classes/java/time/zone/ZoneRulesProvider.java b/jdk/src/share/classes/java/time/zone/ZoneRulesProvider.java
index 2c187a7..d3e906d 100644
--- a/jdk/src/share/classes/java/time/zone/ZoneRulesProvider.java
+++ b/jdk/src/share/classes/java/time/zone/ZoneRulesProvider.java
@@ -61,11 +61,11 @@
  */
 package java.time.zone;
 
-import java.time.DateTimeException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -85,6 +85,25 @@
  * The static methods provide the public API that can be used to manage the providers.
  * The abstract methods provide the SPI that allows rules to be provided.
  * <p>
+ * ZoneRulesProvider may be installed in an instance of the Java Platform as
+ * extension classes, that is, jar files placed into any of the usual extension
+ * directories. Installed providers are loaded using the service-provider loading
+ * facility defined by the {@link ServiceLoader} class. A ZoneRulesProvider
+ * identifies itself with a provider configuration file named
+ * {@code java.time.zone.ZoneRulesProvider} in the resource directory
+ * {@code META-INF/services}. The file should contain a line that specifies the
+ * fully qualified concrete zonerules-provider class name.
+ * Providers may also be made available by adding them to the class path or by
+ * registering themselves via {@link #registerProvider} method.
+ * <p>
+ * The Java virtual machine has a default provider that provides zone rules
+ * for the time-zones defined by IANA Time Zone Database (TZDB). If the system
+ * property {@code java.time.zone.DefaultZoneRulesProvider} is defined then
+ * it is taken to be the fully-qualified name of a concrete ZoneRulesProvider
+ * class to be loaded as the default provider, using the system class loader.
+ * If this system property is not defined, a system-default provider will be
+ * loaded to serve as the default provider.
+ * <p>
  * Rules are looked up primarily by zone ID, as used by {@link ZoneId}.
  * Only zone region IDs may be used, zone offset IDs are not used here.
  * <p>
@@ -99,6 +118,8 @@
  * Providers must ensure that once a rule has been seen by the application, the
  * rule must continue to be available.
  * <p>
+*  Providers are encouraged to implement a meaningful {@code toString} method.
+ * <p>
  * Many systems would like to update time-zone rules dynamically without stopping the JVM.
  * When examined in detail, this is a complex problem.
  * Providers may choose to handle dynamic updates, however the default provider does not.
@@ -112,13 +133,34 @@
      */
     private static final CopyOnWriteArrayList<ZoneRulesProvider> PROVIDERS = new CopyOnWriteArrayList<>();
     /**
-     * The lookup from zone region ID to provider.
+     * The lookup from zone ID to provider.
      */
     private static final ConcurrentMap<String, ZoneRulesProvider> ZONES = new ConcurrentHashMap<>(512, 0.75f, 2);
+
     static {
-        registerProvider(new TzdbZoneRulesProvider());
+        // if the property java.time.zone.DefaultZoneRulesProvider is
+        // set then its value is the class name of the default provider
+        final List<ZoneRulesProvider> loaded = new ArrayList<>();
+        AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                String prop = System.getProperty("java.time.zone.DefaultZoneRulesProvider");
+                if (prop != null) {
+                    try {
+                        Class<?> c = Class.forName(prop, true, ClassLoader.getSystemClassLoader());
+                        ZoneRulesProvider provider = ZoneRulesProvider.class.cast(c.newInstance());
+                        registerProvider(provider);
+                        loaded.add(provider);
+                    } catch (Exception x) {
+                        throw new Error(x);
+                    }
+                } else {
+                    registerProvider(new TzdbZoneRulesProvider());
+                }
+                return null;
+            }
+        });
+
         ServiceLoader<ZoneRulesProvider> sl = ServiceLoader.load(ZoneRulesProvider.class, ClassLoader.getSystemClassLoader());
-        List<ZoneRulesProvider> loaded = new ArrayList<>();
         Iterator<ZoneRulesProvider> it = sl.iterator();
         while (it.hasNext()) {
             ZoneRulesProvider provider;
@@ -130,7 +172,16 @@
                 }
                 throw ex;
             }
-            registerProvider0(provider);
+            boolean found = false;
+            for (ZoneRulesProvider p : loaded) {
+                if (p.getClass() == provider.getClass()) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                registerProvider0(provider);
+                loaded.add(provider);
+            }
         }
         // CopyOnWriteList could be slow if lots of providers and each added individually
         PROVIDERS.addAll(loaded);
@@ -140,7 +191,7 @@
     /**
      * Gets the set of available zone IDs.
      * <p>
-     * These zone IDs are loaded and available for use by {@code ZoneId}.
+     * These IDs are the string form of a {@link ZoneId}.
      *
      * @return a modifiable copy of the set of zone IDs, not null
      */
@@ -155,14 +206,25 @@
      * <p>
      * This method relies on time-zone data provider files that are configured.
      * These are loaded using a {@code ServiceLoader}.
+     * <p>
+     * The caching flag is designed to allow provider implementations to
+     * prevent the rules being cached in {@code ZoneId}.
+     * Under normal circumstances, the caching of zone rules is highly desirable
+     * as it will provide greater performance. However, there is a use case where
+     * the caching would not be desirable, see {@link #provideRules}.
      *
-     * @param zoneId  the zone region ID as used by {@code ZoneId}, not null
-     * @return the rules for the ID, not null
-     * @throws ZoneRulesException if the zone ID is unknown
+     * @param zoneId the zone ID as defined by {@code ZoneId}, not null
+     * @param forCaching whether the rules are being queried for caching,
+     * true if the returned rules will be cached by {@code ZoneId},
+     * false if they will be returned to the user without being cached in {@code ZoneId}
+     * @return the rules, null if {@code forCaching} is true and this
+     * is a dynamic provider that wants to prevent caching in {@code ZoneId},
+     * otherwise not null
+     * @throws ZoneRulesException if rules cannot be obtained for the zone ID
      */
-    public static ZoneRules getRules(String zoneId) {
+    public static ZoneRules getRules(String zoneId, boolean forCaching) {
         Objects.requireNonNull(zoneId, "zoneId");
-        return getProvider(zoneId).provideRules(zoneId);
+        return getProvider(zoneId).provideRules(zoneId, forCaching);
     }
 
     /**
@@ -184,10 +246,10 @@
      * Thus the map will always contain one element, and will only contain more
      * than one element if historical rule information is available.
      *
-     * @param zoneId  the zone region ID as used by {@code ZoneId}, not null
+     * @param zoneId  the zone ID as defined by {@code ZoneId}, not null
      * @return a modifiable copy of the history of the rules for the ID, sorted
      *  from oldest to newest, not null
-     * @throws ZoneRulesException if the zone ID is unknown
+     * @throws ZoneRulesException if history cannot be obtained for the zone ID
      */
     public static NavigableMap<String, ZoneRules> getVersions(String zoneId) {
         Objects.requireNonNull(zoneId, "zoneId");
@@ -197,7 +259,7 @@
     /**
      * Gets the provider for the zone ID.
      *
-     * @param zoneId  the zone region ID as used by {@code ZoneId}, not null
+     * @param zoneId  the zone ID as defined by {@code ZoneId}, not null
      * @return the provider, not null
      * @throws ZoneRulesException if the zone ID is unknown
      */
@@ -226,7 +288,7 @@
      * to deregister providers.
      *
      * @param provider  the provider to register, not null
-     * @throws ZoneRulesException if a region is already registered
+     * @throws ZoneRulesException if a zone ID is already registered
      */
     public static void registerProvider(ZoneRulesProvider provider) {
         Objects.requireNonNull(provider, "provider");
@@ -243,7 +305,7 @@
     private static void registerProvider0(ZoneRulesProvider provider) {
         for (String zoneId : provider.provideZoneIds()) {
             Objects.requireNonNull(zoneId, "zoneId");
-            ZoneRulesProvider old = ZONES.putIfAbsent(zoneId, provider.provideBind(zoneId));
+            ZoneRulesProvider old = ZONES.putIfAbsent(zoneId, provider);
             if (old != null) {
                 throw new ZoneRulesException(
                     "Unable to register zone as one already registered with that ID: " + zoneId +
@@ -252,17 +314,25 @@
         }
     }
 
-    //-------------------------------------------------------------------------
     /**
      * Refreshes the rules from the underlying data provider.
      * <p>
-     * This method is an extension point that allows providers to refresh their
-     * rules dynamically at a time of the applications choosing.
+     * This method allows an application to request that the providers check
+     * for any updates to the provided rules.
      * After calling this method, the offset stored in any {@link ZonedDateTime}
      * may be invalid for the zone ID.
      * <p>
-     * Dynamic behavior is entirely optional and most providers, including the
-     * default provider, do not support it.
+     * Dynamic update of rules is a complex problem and most applications
+     * should not use this method or dynamic rules.
+     * To achieve dynamic rules, a provider implementation will have to be written
+     * as per the specification of this class.
+     * In addition, instances of {@code ZoneRules} must not be cached in the
+     * application as they will become stale. However, the boolean flag on
+     * {@link #provideRules(String, boolean)} allows provider implementations
+     * to control the caching of {@code ZoneId}, potentially ensuring that
+     * all objects in the system see the new rules.
+     * Note that there is likely to be a cost in performance of a dynamic rules
+     * provider. Note also that no dynamic rules provider is in this specification.
      *
      * @return true if the rules were updated
      * @throws ZoneRulesException if an error occurs during the refresh
@@ -275,7 +345,6 @@
         return changed;
     }
 
-    //-----------------------------------------------------------------------
     /**
      * Constructor.
      */
@@ -287,49 +356,43 @@
      * SPI method to get the available zone IDs.
      * <p>
      * This obtains the IDs that this {@code ZoneRulesProvider} provides.
-     * A provider should provide data for at least one region.
+     * A provider should provide data for at least one zone ID.
      * <p>
-     * The returned regions remain available and valid for the lifetime of the application.
-     * A dynamic provider may increase the set of regions as more data becomes available.
+     * The returned zone IDs remain available and valid for the lifetime of the application.
+     * A dynamic provider may increase the set of IDs as more data becomes available.
      *
-     * @return the unmodifiable set of region IDs being provided, not null
+     * @return the set of zone IDs being provided, not null
+     * @throws ZoneRulesException if a problem occurs while providing the IDs
      */
     protected abstract Set<String> provideZoneIds();
 
     /**
-     * SPI method to bind to the specified zone ID.
-     * <p>
-     * {@code ZoneRulesProvider} has a lookup from zone ID to provider.
-     * This method is used when building that lookup, allowing providers
-     * to insert a derived provider that is precisely tuned to the zone ID.
-     * This replaces two hash map lookups by one, enhancing performance.
-     * <p>
-     * This optimization is optional. Returning {@code this} is acceptable.
-     * <p>
-     * This implementation creates a bound provider that caches the
-     * rules from the underlying provider. The request to version history
-     * is forward on to the underlying. This is suitable for providers that
-     * cannot change their contents during the lifetime of the JVM.
-     *
-     * @param zoneId  the zone region ID as used by {@code ZoneId}, not null
-     * @return the resolved provider for the ID, not null
-     * @throws DateTimeException if there is no provider for the specified group
-     */
-    protected ZoneRulesProvider provideBind(String zoneId) {
-        return new BoundProvider(this, zoneId);
-    }
-
-    /**
      * SPI method to get the rules for the zone ID.
      * <p>
-     * This loads the rules for the region and version specified.
-     * The version may be null to indicate the "latest" version.
+     * This loads the rules for the specified zone ID.
+     * The provider implementation must validate that the zone ID is valid and
+     * available, throwing a {@code ZoneRulesException} if it is not.
+     * The result of the method in the valid case depends on the caching flag.
+     * <p>
+     * If the provider implementation is not dynamic, then the result of the
+     * method must be the non-null set of rules selected by the ID.
+     * <p>
+     * If the provider implementation is dynamic, then the flag gives the option
+     * of preventing the returned rules from being cached in {@link ZoneId}.
+     * When the flag is true, the provider is permitted to return null, where
+     * null will prevent the rules from being cached in {@code ZoneId}.
+     * When the flag is false, the provider must return non-null rules.
      *
-     * @param regionId  the time-zone region ID, not null
-     * @return the rules, not null
-     * @throws DateTimeException if rules cannot be obtained
+     * @param zoneId the zone ID as defined by {@code ZoneId}, not null
+     * @param forCaching whether the rules are being queried for caching,
+     * true if the returned rules will be cached by {@code ZoneId},
+     * false if they will be returned to the user without being cached in {@code ZoneId}
+     * @return the rules, null if {@code forCaching} is true and this
+     * is a dynamic provider that wants to prevent caching in {@code ZoneId},
+     * otherwise not null
+     * @throws ZoneRulesException if rules cannot be obtained for the zone ID
      */
-    protected abstract ZoneRules provideRules(String regionId);
+    protected abstract ZoneRules provideRules(String zoneId, boolean forCaching);
 
     /**
      * SPI method to get the history of rules for the zone ID.
@@ -343,16 +406,16 @@
      * <p>
      * Implementations must provide a result for each valid zone ID, however
      * they do not have to provide a history of rules.
-     * Thus the map will always contain one element, and will only contain more
-     * than one element if historical rule information is available.
+     * Thus the map will contain at least one element, and will only contain
+     * more than one element if historical rule information is available.
      * <p>
      * The returned versions remain available and valid for the lifetime of the application.
      * A dynamic provider may increase the set of versions as more data becomes available.
      *
-     * @param zoneId  the zone region ID as used by {@code ZoneId}, not null
+     * @param zoneId  the zone ID as defined by {@code ZoneId}, not null
      * @return a modifiable copy of the history of the rules for the ID, sorted
      *  from oldest to newest, not null
-     * @throws ZoneRulesException if the zone ID is unknown
+     * @throws ZoneRulesException if history cannot be obtained for the zone ID
      */
     protected abstract NavigableMap<String, ZoneRules> provideVersions(String zoneId);
 
@@ -367,46 +430,10 @@
      * This implementation returns false.
      *
      * @return true if the rules were updated
-     * @throws DateTimeException if an error occurs during the refresh
+     * @throws ZoneRulesException if an error occurs during the refresh
      */
     protected boolean provideRefresh() {
         return false;
     }
 
-    //-------------------------------------------------------------------------
-    /**
-     * A provider bound to a single zone ID.
-     */
-    private static class BoundProvider extends ZoneRulesProvider {
-        private final ZoneRulesProvider provider;
-        private final String zoneId;
-        private final ZoneRules rules;
-
-        private BoundProvider(ZoneRulesProvider provider, String zoneId) {
-            this.provider = provider;
-            this.zoneId = zoneId;
-            this.rules = provider.provideRules(zoneId);
-        }
-
-        @Override
-        protected Set<String> provideZoneIds() {
-            return new HashSet<>(Collections.singleton(zoneId));
-        }
-
-        @Override
-        protected ZoneRules provideRules(String regionId) {
-            return rules;
-        }
-
-        @Override
-        protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
-            return provider.provideVersions(zoneId);
-        }
-
-        @Override
-        public String toString() {
-            return zoneId;
-        }
-    }
-
 }
diff --git a/jdk/src/share/classes/java/util/Calendar.java b/jdk/src/share/classes/java/util/Calendar.java
index 600da93..f14ee6d 100644
--- a/jdk/src/share/classes/java/util/Calendar.java
+++ b/jdk/src/share/classes/java/util/Calendar.java
@@ -51,6 +51,7 @@
 import java.security.ProtectionDomain;
 import java.text.DateFormat;
 import java.text.DateFormatSymbols;
+import java.time.Instant;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import sun.util.BuddhistCalendar;
@@ -3562,4 +3563,17 @@
             }
         }
     }
+
+    /**
+     * Converts this object to an {@link Instant}.
+     * <p>
+     * The conversion creates an {@code Instant} that represents the
+     * same point on the time-line as this {@code Calendar}.
+     *
+     * @return the instant representing the same point on the time-line
+     * @since 1.8
+     */
+    public final Instant toInstant() {
+        return Instant.ofEpochMilli(getTimeInMillis());
+    }
 }
diff --git a/jdk/src/share/classes/java/util/Comparator.java b/jdk/src/share/classes/java/util/Comparator.java
index 453e9b7..35ead37 100644
--- a/jdk/src/share/classes/java/util/Comparator.java
+++ b/jdk/src/share/classes/java/util/Comparator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -98,7 +98,7 @@
  * @see java.io.Serializable
  * @since 1.2
  */
-
+@FunctionalInterface
 public interface Comparator<T> {
     /**
      * Compares its two arguments for order.  Returns a negative integer,
diff --git a/jdk/src/share/classes/java/util/Date.java b/jdk/src/share/classes/java/util/Date.java
index 7735209..61dac35 100644
--- a/jdk/src/share/classes/java/util/Date.java
+++ b/jdk/src/share/classes/java/util/Date.java
@@ -26,10 +26,12 @@
 package java.util;
 
 import java.text.DateFormat;
+import java.time.LocalDate;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.ObjectInputStream;
 import java.lang.ref.SoftReference;
+import java.time.Instant;
 import sun.util.calendar.BaseCalendar;
 import sun.util.calendar.CalendarDate;
 import sun.util.calendar.CalendarSystem;
@@ -1328,4 +1330,46 @@
     {
         fastTime = s.readLong();
     }
+
+    /**
+     * Obtains an instance of {@code Date} from an {@code Instant} object.
+     * <p>
+     * {@code Instant} uses a precision of nanoseconds, whereas {@code Date}
+     * uses a precision of milliseconds.  The conversion will trancate any
+     * excess precision information as though the amount in nanoseconds was
+     * subject to integer division by one million.
+     * <p>
+     * {@code Instant} can store points on the time-line further in the future
+     * and further in the past than {@code Date}. In this scenario, this method
+     * will throw an exception.
+     *
+     * @param instant  the instant to convert
+     * @return a {@code Date} representing the same point on the time-line as
+     *  the provided instant
+     * @exception NullPointerException if {@code instant} is null.
+     * @exception IllegalArgumentException if the instant is too large to
+     *  represent as a {@code Date}
+     * @since 1.8
+     */
+    public static Date from(Instant instant) {
+        try {
+            return new Date(instant.toEpochMilli());
+        } catch (ArithmeticException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+
+    /**
+     * Converts this {@code Date} object to an {@code Instant}.
+     * <p>
+     * The conversion creates an {@code Instant} that represents the same
+     * point on the time-line as this {@code Date}.
+     *
+     * @return an instant representing the same point on the time-line as
+     *  this {@code Date} object
+     * @since 1.8
+     */
+    public Instant toInstant() {
+        return Instant.ofEpochMilli(getTime());
+    }
 }
diff --git a/jdk/src/share/classes/java/util/Formatter.java b/jdk/src/share/classes/java/util/Formatter.java
index 03a5800..c645861 100644
--- a/jdk/src/share/classes/java/util/Formatter.java
+++ b/jdk/src/share/classes/java/util/Formatter.java
@@ -50,7 +50,6 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.ZoneId;
@@ -58,12 +57,6 @@
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.Queries;
-import java.time.temporal.OffsetDate;
-import java.time.temporal.OffsetDateTime;
-import java.time.temporal.OffsetTime;
-import java.time.temporal.ChronoZonedDateTime;
-import java.time.format.TextStyle;
-import java.time.zone.ZoneRules;
 
 import sun.misc.DoubleConsts;
 import sun.misc.FormattedFloatingDecimal;
diff --git a/jdk/src/share/classes/java/util/GregorianCalendar.java b/jdk/src/share/classes/java/util/GregorianCalendar.java
index 0142c51..4e063ee 100644
--- a/jdk/src/share/classes/java/util/GregorianCalendar.java
+++ b/jdk/src/share/classes/java/util/GregorianCalendar.java
@@ -40,6 +40,12 @@
 
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.chrono.IsoChronology;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
 import sun.util.calendar.BaseCalendar;
 import sun.util.calendar.CalendarDate;
 import sun.util.calendar.CalendarSystem;
@@ -3200,4 +3206,61 @@
         }
         setGregorianChange(gregorianCutover);
     }
+
+    /**
+     * Converts this object to a {@code ZonedDateTime} that represents
+     * the same point on the time-line as this {@code GregorianCalendar}.
+     * <p>
+     * Since this object supports a Julian-Gregorian cutover date and
+     * {@code ZonedDateTime} does not, it is possible that the resulting year,
+     * month and day will have different values.  The result will represent the
+     * correct date in the ISO calendar system, which will also be the same value
+     * for Modified Julian Days.
+     *
+     * @return a zoned date-time representing the same point on the time-line
+     *  as this gregorian calendar
+     * @since 1.8
+     */
+    public ZonedDateTime toZonedDateTime() {
+        return ZonedDateTime.ofInstant(Instant.ofEpochMilli(getTimeInMillis()),
+                                       getTimeZone().toZoneId());
+    }
+
+    /**
+     * Obtains an instance of {@code GregorianCalendar} with the default locale
+     * from a {@code ZonedDateTime} object.
+     * <p>
+     * Since {@code ZonedDateTime} does not support a Julian-Gregorian cutover
+     * date and uses ISO calendar system, the return GregorianCalendar is a pure
+     * Gregorian calendar and uses ISO 8601 standard for week definitions,
+     * which has {@code MONDAY} as the {@link Calendar#getFirstDayOfWeek()
+     * FirstDayOfWeek} and {@code 4} as the value of the
+     * {@link Calendar#getMinimalDaysInFirstWeek() MinimalDaysInFirstWeek}.
+     * <p>
+     * {@code ZoneDateTime} can store points on the time-line further in the
+     * future and further in the past than {@code GregorianCalendar}. In this
+     * scenario, this method will throw an {@code IllegalArgumentException}
+     * exception.
+     *
+     * @param zdt  the zoned date-time object to convert
+     * @return  the gregorian calendar representing the same point on the
+     *  time-line as the zoned date-time provided
+     * @exception NullPointerException if {@code zdt} is null
+     * @exception IllegalArgumentException if the zoned date-time is too
+     * large to represent as a {@code GregorianCalendar}
+     * @since 1.8
+     */
+    public static GregorianCalendar from(ZonedDateTime zdt) {
+        GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(zdt.getZone()));
+        cal.setGregorianChange(new Date(Long.MIN_VALUE));
+        cal.setFirstDayOfWeek(MONDAY);
+        cal.setMinimalDaysInFirstWeek(4);
+        try {
+            cal.setTimeInMillis(Math.addExact(Math.multiplyExact(zdt.toEpochSecond(), 1000),
+                                              zdt.get(ChronoField.MILLI_OF_SECOND)));
+        } catch (ArithmeticException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+        return cal;
+    }
 }
diff --git a/jdk/src/share/classes/java/util/TimeZone.java b/jdk/src/share/classes/java/util/TimeZone.java
index d79e201..66297c0 100644
--- a/jdk/src/share/classes/java/util/TimeZone.java
+++ b/jdk/src/share/classes/java/util/TimeZone.java
@@ -42,6 +42,7 @@
 import java.lang.ref.SoftReference;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.time.ZoneId;
 import java.util.concurrent.ConcurrentHashMap;
 import sun.misc.JavaAWTAccess;
 import sun.misc.SharedSecrets;
@@ -530,6 +531,37 @@
         return getTimeZone(ID, true);
     }
 
+    /**
+     * Gets the {@code TimeZone} for the given {@code zoneId}.
+     *
+     * @param zoneid a {@link ZoneId} from which the time zone ID is obtained
+     * @return the specified {@code TimeZone}, or the GMT zone if the given ID
+     *         cannot be understood.
+     * @throws NullPointerException if {@code zoneId} is {@code null}
+     * @since 1.8
+     */
+    public static TimeZone getTimeZone(ZoneId zoneId) {
+        String tzid = zoneId.getId(); // throws an NPE if null
+        char c = tzid.charAt(0);
+        if (c == '+' || c == '-') {
+            tzid = "GMT" + tzid;
+        } else if (c == 'Z' && tzid.length() == 1) {
+            tzid = "UTC";
+        }
+        return getTimeZone(tzid, true);
+    }
+
+    /**
+     * Converts this {@code TimeZone} object to a {@code ZoneId}.
+     *
+     * @return a {@code ZoneId} representing the same time zone as this
+     *         {@code TimeZone}
+     * @since 1.8
+     */
+    public ZoneId toZoneId() {
+        return ZoneId.of(getID(), ZoneId.OLD_IDS_POST_2005);
+    }
+
     private static TimeZone getTimeZone(String ID, boolean fallback) {
         TimeZone tz = ZoneInfo.getTimeZone(ID);
         if (tz == null) {
diff --git a/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java b/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java
index 08bd887..20abfac 100644
--- a/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java
+++ b/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java
@@ -101,14 +101,14 @@
  *     // Block while not first in queue or cannot acquire lock
  *     while (waiters.peek() != current ||
  *            !locked.compareAndSet(false, true)) {
- *        LockSupport.park(this);
- *        if (Thread.interrupted()) // ignore interrupts while waiting
- *          wasInterrupted = true;
+ *       LockSupport.park(this);
+ *       if (Thread.interrupted()) // ignore interrupts while waiting
+ *         wasInterrupted = true;
  *     }
  *
  *     waiters.remove();
  *     if (wasInterrupted)          // reassert interrupt status on exit
- *        current.interrupt();
+ *       current.interrupt();
  *   }
  *
  *   public void unlock() {
@@ -120,20 +120,9 @@
 public class LockSupport {
     private LockSupport() {} // Cannot be instantiated.
 
-    // Hotspot implementation via intrinsics API
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long parkBlockerOffset;
-
-    static {
-        try {
-            parkBlockerOffset = unsafe.objectFieldOffset
-                (java.lang.Thread.class.getDeclaredField("parkBlocker"));
-        } catch (Exception ex) { throw new Error(ex); }
-    }
-
     private static void setBlocker(Thread t, Object arg) {
         // Even though volatile, hotspot doesn't need a write barrier here.
-        unsafe.putObject(t, parkBlockerOffset, arg);
+        UNSAFE.putObject(t, parkBlockerOffset, arg);
     }
 
     /**
@@ -149,7 +138,7 @@
      */
     public static void unpark(Thread thread) {
         if (thread != null)
-            unsafe.unpark(thread);
+            UNSAFE.unpark(thread);
     }
 
     /**
@@ -183,7 +172,7 @@
     public static void park(Object blocker) {
         Thread t = Thread.currentThread();
         setBlocker(t, blocker);
-        unsafe.park(false, 0L);
+        UNSAFE.park(false, 0L);
         setBlocker(t, null);
     }
 
@@ -223,7 +212,7 @@
         if (nanos > 0) {
             Thread t = Thread.currentThread();
             setBlocker(t, blocker);
-            unsafe.park(false, nanos);
+            UNSAFE.park(false, nanos);
             setBlocker(t, null);
         }
     }
@@ -264,7 +253,7 @@
     public static void parkUntil(Object blocker, long deadline) {
         Thread t = Thread.currentThread();
         setBlocker(t, blocker);
-        unsafe.park(true, deadline);
+        UNSAFE.park(true, deadline);
         setBlocker(t, null);
     }
 
@@ -283,7 +272,7 @@
     public static Object getBlocker(Thread t) {
         if (t == null)
             throw new NullPointerException();
-        return unsafe.getObjectVolatile(t, parkBlockerOffset);
+        return UNSAFE.getObjectVolatile(t, parkBlockerOffset);
     }
 
     /**
@@ -312,7 +301,7 @@
      * for example, the interrupt status of the thread upon return.
      */
     public static void park() {
-        unsafe.park(false, 0L);
+        UNSAFE.park(false, 0L);
     }
 
     /**
@@ -346,7 +335,7 @@
      */
     public static void parkNanos(long nanos) {
         if (nanos > 0)
-            unsafe.park(false, nanos);
+            UNSAFE.park(false, nanos);
     }
 
     /**
@@ -380,6 +369,46 @@
      *        to wait until
      */
     public static void parkUntil(long deadline) {
-        unsafe.park(true, deadline);
+        UNSAFE.park(true, deadline);
     }
+
+    /**
+     * Returns the pseudo-randomly initialized or updated secondary seed.
+     * Copied from ThreadLocalRandom due to package access restrictions.
+     */
+    static final int nextSecondarySeed() {
+        int r;
+        Thread t = Thread.currentThread();
+        if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
+            r ^= r << 13;   // xorshift
+            r ^= r >>> 17;
+            r ^= r << 5;
+        }
+        else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
+            r = 1; // avoid zero
+        UNSAFE.putInt(t, SECONDARY, r);
+        return r;
+    }
+
+    // Hotspot implementation via intrinsics API
+    private static final sun.misc.Unsafe UNSAFE;
+    private static final long parkBlockerOffset;
+    private static final long SEED;
+    private static final long PROBE;
+    private static final long SECONDARY;
+    static {
+        try {
+            UNSAFE = sun.misc.Unsafe.getUnsafe();
+            Class<?> tk = Thread.class;
+            parkBlockerOffset = UNSAFE.objectFieldOffset
+                (tk.getDeclaredField("parkBlocker"));
+            SEED = UNSAFE.objectFieldOffset
+                (tk.getDeclaredField("threadLocalRandomSeed"));
+            PROBE = UNSAFE.objectFieldOffset
+                (tk.getDeclaredField("threadLocalRandomProbe"));
+            SECONDARY = UNSAFE.objectFieldOffset
+                (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
+        } catch (Exception ex) { throw new Error(ex); }
+    }
+
 }
diff --git a/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java b/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java
new file mode 100644
index 0000000..0ca43f6
--- /dev/null
+++ b/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java
@@ -0,0 +1,1377 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent.locks;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.LockSupport;
+
+/**
+ * A capability-based lock with three modes for controlling read/write
+ * access.  The state of a StampedLock consists of a version and mode.
+ * Lock acquisition methods return a stamp that represents and
+ * controls access with respect to a lock state; "try" versions of
+ * these methods may instead return the special value zero to
+ * represent failure to acquire access. Lock release and conversion
+ * methods require stamps as arguments, and fail if they do not match
+ * the state of the lock. The three modes are:
+ *
+ * <ul>
+ *
+ *  <li><b>Writing.</b> Method {@link #writeLock} possibly blocks
+ *   waiting for exclusive access, returning a stamp that can be used
+ *   in method {@link #unlockWrite} to release the lock. Untimed and
+ *   timed versions of {@code tryWriteLock} are also provided. When
+ *   the lock is held in write mode, no read locks may be obtained,
+ *   and all optimistic read validations will fail.  </li>
+ *
+ *  <li><b>Reading.</b> Method {@link #readLock} possibly blocks
+ *   waiting for non-exclusive access, returning a stamp that can be
+ *   used in method {@link #unlockRead} to release the lock. Untimed
+ *   and timed versions of {@code tryReadLock} are also provided. </li>
+ *
+ *  <li><b>Optimistic Reading.</b> Method {@link #tryOptimisticRead}
+ *   returns a non-zero stamp only if the lock is not currently held
+ *   in write mode. Method {@link #validate} returns true if the lock
+ *   has not been acquired in write mode since obtaining a given
+ *   stamp.  This mode can be thought of as an extremely weak version
+ *   of a read-lock, that can be broken by a writer at any time.  The
+ *   use of optimistic mode for short read-only code segments often
+ *   reduces contention and improves throughput.  However, its use is
+ *   inherently fragile.  Optimistic read sections should only read
+ *   fields and hold them in local variables for later use after
+ *   validation. Fields read while in optimistic mode may be wildly
+ *   inconsistent, so usage applies only when you are familiar enough
+ *   with data representations to check consistency and/or repeatedly
+ *   invoke method {@code validate()}.  For example, such steps are
+ *   typically required when first reading an object or array
+ *   reference, and then accessing one of its fields, elements or
+ *   methods. </li>
+ *
+ * </ul>
+ *
+ * <p>This class also supports methods that conditionally provide
+ * conversions across the three modes. For example, method {@link
+ * #tryConvertToWriteLock} attempts to "upgrade" a mode, returning
+ * a valid write stamp if (1) already in writing mode (2) in reading
+ * mode and there are no other readers or (3) in optimistic mode and
+ * the lock is available. The forms of these methods are designed to
+ * help reduce some of the code bloat that otherwise occurs in
+ * retry-based designs.
+ *
+ * <p>StampedLocks are designed for use as internal utilities in the
+ * development of thread-safe components. Their use relies on
+ * knowledge of the internal properties of the data, objects, and
+ * methods they are protecting.  They are not reentrant, so locked
+ * bodies should not call other unknown methods that may try to
+ * re-acquire locks (although you may pass a stamp to other methods
+ * that can use or convert it).  The use of read lock modes relies on
+ * the associated code sections being side-effect-free.  Unvalidated
+ * optimistic read sections cannot call methods that are not known to
+ * tolerate potential inconsistencies.  Stamps use finite
+ * representations, and are not cryptographically secure (i.e., a
+ * valid stamp may be guessable). Stamp values may recycle after (no
+ * sooner than) one year of continuous operation. A stamp held without
+ * use or validation for longer than this period may fail to validate
+ * correctly.  StampedLocks are serializable, but always deserialize
+ * into initial unlocked state, so they are not useful for remote
+ * locking.
+ *
+ * <p>The scheduling policy of StampedLock does not consistently
+ * prefer readers over writers or vice versa.  All "try" methods are
+ * best-effort and do not necessarily conform to any scheduling or
+ * fairness policy. A zero return from any "try" method for acquiring
+ * or converting locks does not carry any information about the state
+ * of the lock; a subsequent invocation may succeed.
+ *
+ * <p>Because it supports coordinated usage across multiple lock
+ * modes, this class does not directly implement the {@link Lock} or
+ * {@link ReadWriteLock} interfaces. However, a StampedLock may be
+ * viewed {@link #asReadLock()}, {@link #asWriteLock()}, or {@link
+ * #asReadWriteLock()} in applications requiring only the associated
+ * set of functionality.
+ *
+ * <p><b>Sample Usage.</b> The following illustrates some usage idioms
+ * in a class that maintains simple two-dimensional points. The sample
+ * code illustrates some try/catch conventions even though they are
+ * not strictly needed here because no exceptions can occur in their
+ * bodies.<br>
+ *
+ *  <pre>{@code
+ * class Point {
+ *   private double x, y;
+ *   private final StampedLock sl = new StampedLock();
+ *
+ *   void move(double deltaX, double deltaY) { // an exclusively locked method
+ *     long stamp = sl.writeLock();
+ *     try {
+ *       x += deltaX;
+ *       y += deltaY;
+ *     } finally {
+ *       sl.unlockWrite(stamp);
+ *     }
+ *   }
+ *
+ *   double distanceFromOrigin() { // A read-only method
+ *     long stamp = sl.tryOptimisticRead();
+ *     double currentX = x, currentY = y;
+ *     if (!sl.validate(stamp)) {
+ *        stamp = sl.readLock();
+ *        try {
+ *          currentX = x;
+ *          currentY = y;
+ *        } finally {
+ *           sl.unlockRead(stamp);
+ *        }
+ *     }
+ *     return Math.sqrt(currentX * currentX + currentY * currentY);
+ *   }
+ *
+ *   void moveIfAtOrigin(double newX, double newY) { // upgrade
+ *     // Could instead start with optimistic, not read mode
+ *     long stamp = sl.readLock();
+ *     try {
+ *       while (x == 0.0 && y == 0.0) {
+ *         long ws = sl.tryConvertToWriteLock(stamp);
+ *         if (ws != 0L) {
+ *           stamp = ws;
+ *           x = newX;
+ *           y = newY;
+ *           break;
+ *         }
+ *         else {
+ *           sl.unlockRead(stamp);
+ *           stamp = sl.writeLock();
+ *         }
+ *       }
+ *     } finally {
+ *       sl.unlock(stamp);
+ *     }
+ *   }
+ * }}</pre>
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class StampedLock implements java.io.Serializable {
+    /*
+     * Algorithmic notes:
+     *
+     * The design employs elements of Sequence locks
+     * (as used in linux kernels; see Lameter's
+     * http://www.lameter.com/gelato2005.pdf
+     * and elsewhere; see
+     * Boehm's http://www.hpl.hp.com/techreports/2012/HPL-2012-68.html)
+     * and Ordered RW locks (see Shirako et al
+     * http://dl.acm.org/citation.cfm?id=2312015)
+     *
+     * Conceptually, the primary state of the lock includes a sequence
+     * number that is odd when write-locked and even otherwise.
+     * However, this is offset by a reader count that is non-zero when
+     * read-locked.  The read count is ignored when validating
+     * "optimistic" seqlock-reader-style stamps.  Because we must use
+     * a small finite number of bits (currently 7) for readers, a
+     * supplementary reader overflow word is used when the number of
+     * readers exceeds the count field. We do this by treating the max
+     * reader count value (RBITS) as a spinlock protecting overflow
+     * updates.
+     *
+     * Waiters use a modified form of CLH lock used in
+     * AbstractQueuedSynchronizer (see its internal documentation for
+     * a fuller account), where each node is tagged (field mode) as
+     * either a reader or writer. Sets of waiting readers are grouped
+     * (linked) under a common node (field cowait) so act as a single
+     * node with respect to most CLH mechanics.  By virtue of the
+     * queue structure, wait nodes need not actually carry sequence
+     * numbers; we know each is greater than its predecessor.  This
+     * simplifies the scheduling policy to a mainly-FIFO scheme that
+     * incorporates elements of Phase-Fair locks (see Brandenburg &
+     * Anderson, especially http://www.cs.unc.edu/~bbb/diss/).  In
+     * particular, we use the phase-fair anti-barging rule: If an
+     * incoming reader arrives while read lock is held but there is a
+     * queued writer, this incoming reader is queued.  (This rule is
+     * responsible for some of the complexity of method acquireRead,
+     * but without it, the lock becomes highly unfair.)
+     *
+     * These rules apply to threads actually queued. All tryLock forms
+     * opportunistically try to acquire locks regardless of preference
+     * rules, and so may "barge" their way in.  Randomized spinning is
+     * used in the acquire methods to reduce (increasingly expensive)
+     * context switching while also avoiding sustained memory
+     * thrashing among many threads.  We limit spins to the head of
+     * queue. A thread spin-waits up to SPINS times (where each
+     * iteration decreases spin count with 50% probability) before
+     * blocking. If, upon wakening it fails to obtain lock, and is
+     * still (or becomes) the first waiting thread (which indicates
+     * that some other thread barged and obtained lock), it escalates
+     * spins (up to MAX_HEAD_SPINS) to reduce the likelihood of
+     * continually losing to barging threads.
+     *
+     * Nearly all of these mechanics are carried out in methods
+     * acquireWrite and acquireRead, that, as typical of such code,
+     * sprawl out because actions and retries rely on consistent sets
+     * of locally cached reads.
+     *
+     * As noted in Boehm's paper (above), sequence validation (mainly
+     * method validate()) requires stricter ordering rules than apply
+     * to normal volatile reads (of "state").  To force orderings of
+     * reads before a validation and the validation itself in those
+     * cases where this is not already forced, we use
+     * Unsafe.loadFence.
+     *
+     * The memory layout keeps lock state and queue pointers together
+     * (normally on the same cache line). This usually works well for
+     * read-mostly loads. In most other cases, the natural tendency of
+     * adaptive-spin CLH locks to reduce memory contention lessens
+     * motivation to further spread out contended locations, but might
+     * be subject to future improvements.
+     */
+
+    private static final long serialVersionUID = -6001602636862214147L;
+
+    /** Number of processors, for spin control */
+    private static final int NCPU = Runtime.getRuntime().availableProcessors();
+
+    /** Maximum number of retries before blocking on acquisition */
+    private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0;
+
+    /** Maximum number of retries before re-blocking */
+    private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 12 : 0;
+
+    /** The period for yielding when waiting for overflow spinlock */
+    private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1
+
+    /** The number of bits to use for reader count before overflowing */
+    private static final int LG_READERS = 7;
+
+    // Values for lock state and stamp operations
+    private static final long RUNIT = 1L;
+    private static final long WBIT  = 1L << LG_READERS;
+    private static final long RBITS = WBIT - 1L;
+    private static final long RFULL = RBITS - 1L;
+    private static final long ABITS = RBITS | WBIT;
+    private static final long SBITS = ~RBITS; // note overlap with ABITS
+
+    // Initial value for lock state; avoid failure value zero
+    private static final long ORIGIN = WBIT << 1;
+
+    // Special value from cancelled acquire methods so caller can throw IE
+    private static final long INTERRUPTED = 1L;
+
+    // Values for node status; order matters
+    private static final int WAITING   = -1;
+    private static final int CANCELLED =  1;
+
+    // Modes for nodes (int not boolean to allow arithmetic)
+    private static final int RMODE = 0;
+    private static final int WMODE = 1;
+
+    /** Wait nodes */
+    static final class WNode {
+        volatile WNode prev;
+        volatile WNode next;
+        volatile WNode cowait;    // list of linked readers
+        volatile Thread thread;   // non-null while possibly parked
+        volatile int status;      // 0, WAITING, or CANCELLED
+        final int mode;           // RMODE or WMODE
+        WNode(int m, WNode p) { mode = m; prev = p; }
+    }
+
+    /** Head of CLH queue */
+    private transient volatile WNode whead;
+    /** Tail (last) of CLH queue */
+    private transient volatile WNode wtail;
+
+    // views
+    transient ReadLockView readLockView;
+    transient WriteLockView writeLockView;
+    transient ReadWriteLockView readWriteLockView;
+
+    /** Lock sequence/state */
+    private transient volatile long state;
+    /** extra reader count when state read count saturated */
+    private transient int readerOverflow;
+
+    /**
+     * Creates a new lock, initially in unlocked state.
+     */
+    public StampedLock() {
+        state = ORIGIN;
+    }
+
+    /**
+     * Exclusively acquires the lock, blocking if necessary
+     * until available.
+     *
+     * @return a stamp that can be used to unlock or convert mode
+     */
+    public long writeLock() {
+        long s, next;  // bypass acquireWrite in fully unlocked case only
+        return ((((s = state) & ABITS) == 0L &&
+                 U.compareAndSwapLong(this, STATE, s, next = s + WBIT)) ?
+                next : acquireWrite(false, 0L));
+    }
+
+    /**
+     * Exclusively acquires the lock if it is immediately available.
+     *
+     * @return a stamp that can be used to unlock or convert mode,
+     * or zero if the lock is not available
+     */
+    public long tryWriteLock() {
+        long s, next;
+        return ((((s = state) & ABITS) == 0L &&
+                 U.compareAndSwapLong(this, STATE, s, next = s + WBIT)) ?
+                next : 0L);
+    }
+
+    /**
+     * Exclusively acquires the lock if it is available within the
+     * given time and the current thread has not been interrupted.
+     * Behavior under timeout and interruption matches that specified
+     * for method {@link Lock#tryLock(long,TimeUnit)}.
+     *
+     * @return a stamp that can be used to unlock or convert mode,
+     * or zero if the lock is not available
+     * @throws InterruptedException if the current thread is interrupted
+     * before acquiring the lock
+     */
+    public long tryWriteLock(long time, TimeUnit unit)
+        throws InterruptedException {
+        long nanos = unit.toNanos(time);
+        if (!Thread.interrupted()) {
+            long next, deadline;
+            if ((next = tryWriteLock()) != 0L)
+                return next;
+            if (nanos <= 0L)
+                return 0L;
+            if ((deadline = System.nanoTime() + nanos) == 0L)
+                deadline = 1L;
+            if ((next = acquireWrite(true, deadline)) != INTERRUPTED)
+                return next;
+        }
+        throw new InterruptedException();
+    }
+
+    /**
+     * Exclusively acquires the lock, blocking if necessary
+     * until available or the current thread is interrupted.
+     * Behavior under interruption matches that specified
+     * for method {@link Lock#lockInterruptibly()}.
+     *
+     * @return a stamp that can be used to unlock or convert mode
+     * @throws InterruptedException if the current thread is interrupted
+     * before acquiring the lock
+     */
+    public long writeLockInterruptibly() throws InterruptedException {
+        long next;
+        if (!Thread.interrupted() &&
+            (next = acquireWrite(true, 0L)) != INTERRUPTED)
+            return next;
+        throw new InterruptedException();
+    }
+
+    /**
+     * Non-exclusively acquires the lock, blocking if necessary
+     * until available.
+     *
+     * @return a stamp that can be used to unlock or convert mode
+     */
+    public long readLock() {
+        long s, next;  // bypass acquireRead on fully unlocked case only
+        return ((((s = state) & ABITS) == 0L &&
+                 U.compareAndSwapLong(this, STATE, s, next = s + RUNIT)) ?
+                next : acquireRead(false, 0L));
+    }
+
+    /**
+     * Non-exclusively acquires the lock if it is immediately available.
+     *
+     * @return a stamp that can be used to unlock or convert mode,
+     * or zero if the lock is not available
+     */
+    public long tryReadLock() {
+        for (;;) {
+            long s, m, next;
+            if ((m = (s = state) & ABITS) == WBIT)
+                return 0L;
+            else if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
+                    return next;
+            }
+            else if ((next = tryIncReaderOverflow(s)) != 0L)
+                return next;
+        }
+    }
+
+    /**
+     * Non-exclusively acquires the lock if it is available within the
+     * given time and the current thread has not been interrupted.
+     * Behavior under timeout and interruption matches that specified
+     * for method {@link Lock#tryLock(long,TimeUnit)}.
+     *
+     * @return a stamp that can be used to unlock or convert mode,
+     * or zero if the lock is not available
+     * @throws InterruptedException if the current thread is interrupted
+     * before acquiring the lock
+     */
+    public long tryReadLock(long time, TimeUnit unit)
+        throws InterruptedException {
+        long s, m, next, deadline;
+        long nanos = unit.toNanos(time);
+        if (!Thread.interrupted()) {
+            if ((m = (s = state) & ABITS) != WBIT) {
+                if (m < RFULL) {
+                    if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
+                        return next;
+                }
+                else if ((next = tryIncReaderOverflow(s)) != 0L)
+                    return next;
+            }
+            if (nanos <= 0L)
+                return 0L;
+            if ((deadline = System.nanoTime() + nanos) == 0L)
+                deadline = 1L;
+            if ((next = acquireRead(true, deadline)) != INTERRUPTED)
+                return next;
+        }
+        throw new InterruptedException();
+    }
+
+    /**
+     * Non-exclusively acquires the lock, blocking if necessary
+     * until available or the current thread is interrupted.
+     * Behavior under interruption matches that specified
+     * for method {@link Lock#lockInterruptibly()}.
+     *
+     * @return a stamp that can be used to unlock or convert mode
+     * @throws InterruptedException if the current thread is interrupted
+     * before acquiring the lock
+     */
+    public long readLockInterruptibly() throws InterruptedException {
+        long next;
+        if (!Thread.interrupted() &&
+            (next = acquireRead(true, 0L)) != INTERRUPTED)
+            return next;
+        throw new InterruptedException();
+    }
+
+    /**
+     * Returns a stamp that can later be validated, or zero
+     * if exclusively locked.
+     *
+     * @return a stamp, or zero if exclusively locked
+     */
+    public long tryOptimisticRead() {
+        long s;
+        return (((s = state) & WBIT) == 0L) ? (s & SBITS) : 0L;
+    }
+
+    /**
+     * Returns true if the lock has not been exclusively acquired
+     * since issuance of the given stamp. Always returns false if the
+     * stamp is zero. Always returns true if the stamp represents a
+     * currently held lock. Invoking this method with a value not
+     * obtained from {@link #tryOptimisticRead} or a locking method
+     * for this lock has no defined effect or result.
+     *
+     * @return true if the lock has not been exclusively acquired
+     * since issuance of the given stamp; else false
+     */
+    public boolean validate(long stamp) {
+        U.loadFence();
+        return (stamp & SBITS) == (state & SBITS);
+    }
+
+    /**
+     * If the lock state matches the given stamp, releases the
+     * exclusive lock.
+     *
+     * @param stamp a stamp returned by a write-lock operation
+     * @throws IllegalMonitorStateException if the stamp does
+     * not match the current state of this lock
+     */
+    public void unlockWrite(long stamp) {
+        WNode h;
+        if (state != stamp || (stamp & WBIT) == 0L)
+            throw new IllegalMonitorStateException();
+        state = (stamp += WBIT) == 0L ? ORIGIN : stamp;
+        if ((h = whead) != null && h.status != 0)
+            release(h);
+    }
+
+    /**
+     * If the lock state matches the given stamp, releases the
+     * non-exclusive lock.
+     *
+     * @param stamp a stamp returned by a read-lock operation
+     * @throws IllegalMonitorStateException if the stamp does
+     * not match the current state of this lock
+     */
+    public void unlockRead(long stamp) {
+        long s, m; WNode h;
+        for (;;) {
+            if (((s = state) & SBITS) != (stamp & SBITS) ||
+                (stamp & ABITS) == 0L || (m = s & ABITS) == 0L || m == WBIT)
+                throw new IllegalMonitorStateException();
+            if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    break;
+                }
+            }
+            else if (tryDecReaderOverflow(s) != 0L)
+                break;
+        }
+    }
+
+    /**
+     * If the lock state matches the given stamp, releases the
+     * corresponding mode of the lock.
+     *
+     * @param stamp a stamp returned by a lock operation
+     * @throws IllegalMonitorStateException if the stamp does
+     * not match the current state of this lock
+     */
+    public void unlock(long stamp) {
+        long a = stamp & ABITS, m, s; WNode h;
+        while (((s = state) & SBITS) == (stamp & SBITS)) {
+            if ((m = s & ABITS) == 0L)
+                break;
+            else if (m == WBIT) {
+                if (a != m)
+                    break;
+                state = (s += WBIT) == 0L ? ORIGIN : s;
+                if ((h = whead) != null && h.status != 0)
+                    release(h);
+                return;
+            }
+            else if (a == 0L || a >= WBIT)
+                break;
+            else if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    return;
+                }
+            }
+            else if (tryDecReaderOverflow(s) != 0L)
+                return;
+        }
+        throw new IllegalMonitorStateException();
+    }
+
+    /**
+     * If the lock state matches the given stamp, performs one of
+     * the following actions. If the stamp represents holding a write
+     * lock, returns it.  Or, if a read lock, if the write lock is
+     * available, releases the read lock and returns a write stamp.
+     * Or, if an optimistic read, returns a write stamp only if
+     * immediately available. This method returns zero in all other
+     * cases.
+     *
+     * @param stamp a stamp
+     * @return a valid write stamp, or zero on failure
+     */
+    public long tryConvertToWriteLock(long stamp) {
+        long a = stamp & ABITS, m, s, next;
+        while (((s = state) & SBITS) == (stamp & SBITS)) {
+            if ((m = s & ABITS) == 0L) {
+                if (a != 0L)
+                    break;
+                if (U.compareAndSwapLong(this, STATE, s, next = s + WBIT))
+                    return next;
+            }
+            else if (m == WBIT) {
+                if (a != m)
+                    break;
+                return stamp;
+            }
+            else if (m == RUNIT && a != 0L) {
+                if (U.compareAndSwapLong(this, STATE, s,
+                                         next = s - RUNIT + WBIT))
+                    return next;
+            }
+            else
+                break;
+        }
+        return 0L;
+    }
+
+    /**
+     * If the lock state matches the given stamp, performs one of
+     * the following actions. If the stamp represents holding a write
+     * lock, releases it and obtains a read lock.  Or, if a read lock,
+     * returns it. Or, if an optimistic read, acquires a read lock and
+     * returns a read stamp only if immediately available. This method
+     * returns zero in all other cases.
+     *
+     * @param stamp a stamp
+     * @return a valid read stamp, or zero on failure
+     */
+    public long tryConvertToReadLock(long stamp) {
+        long a = stamp & ABITS, m, s, next; WNode h;
+        while (((s = state) & SBITS) == (stamp & SBITS)) {
+            if ((m = s & ABITS) == 0L) {
+                if (a != 0L)
+                    break;
+                else if (m < RFULL) {
+                    if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
+                        return next;
+                }
+                else if ((next = tryIncReaderOverflow(s)) != 0L)
+                    return next;
+            }
+            else if (m == WBIT) {
+                if (a != m)
+                    break;
+                state = next = s + (WBIT + RUNIT);
+                if ((h = whead) != null && h.status != 0)
+                    release(h);
+                return next;
+            }
+            else if (a != 0L && a < WBIT)
+                return stamp;
+            else
+                break;
+        }
+        return 0L;
+    }
+
+    /**
+     * If the lock state matches the given stamp then, if the stamp
+     * represents holding a lock, releases it and returns an
+     * observation stamp.  Or, if an optimistic read, returns it if
+     * validated. This method returns zero in all other cases, and so
+     * may be useful as a form of "tryUnlock".
+     *
+     * @param stamp a stamp
+     * @return a valid optimistic read stamp, or zero on failure
+     */
+    public long tryConvertToOptimisticRead(long stamp) {
+        long a = stamp & ABITS, m, s, next; WNode h;
+        U.loadFence();
+        for (;;) {
+            if (((s = state) & SBITS) != (stamp & SBITS))
+                break;
+            if ((m = s & ABITS) == 0L) {
+                if (a != 0L)
+                    break;
+                return s;
+            }
+            else if (m == WBIT) {
+                if (a != m)
+                    break;
+                state = next = (s += WBIT) == 0L ? ORIGIN : s;
+                if ((h = whead) != null && h.status != 0)
+                    release(h);
+                return next;
+            }
+            else if (a == 0L || a >= WBIT)
+                break;
+            else if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, next = s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    return next & SBITS;
+                }
+            }
+            else if ((next = tryDecReaderOverflow(s)) != 0L)
+                return next & SBITS;
+        }
+        return 0L;
+    }
+
+    /**
+     * Releases the write lock if it is held, without requiring a
+     * stamp value. This method may be useful for recovery after
+     * errors.
+     *
+     * @return true if the lock was held, else false
+     */
+    public boolean tryUnlockWrite() {
+        long s; WNode h;
+        if (((s = state) & WBIT) != 0L) {
+            state = (s += WBIT) == 0L ? ORIGIN : s;
+            if ((h = whead) != null && h.status != 0)
+                release(h);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Releases one hold of the read lock if it is held, without
+     * requiring a stamp value. This method may be useful for recovery
+     * after errors.
+     *
+     * @return true if the read lock was held, else false
+     */
+    public boolean tryUnlockRead() {
+        long s, m; WNode h;
+        while ((m = (s = state) & ABITS) != 0L && m < WBIT) {
+            if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    return true;
+                }
+            }
+            else if (tryDecReaderOverflow(s) != 0L)
+                return true;
+        }
+        return false;
+    }
+
+    // status monitoring methods
+
+    /**
+     * Returns combined state-held and overflow read count for given
+     * state s.
+     */
+    private int getReadLockCount(long s) {
+        long readers;
+        if ((readers = s & RBITS) >= RFULL)
+            readers = RFULL + readerOverflow;
+        return (int) readers;
+    }
+
+    /**
+     * Returns true if the lock is currently held exclusively.
+     *
+     * @return true if the lock is currently held exclusively
+     */
+    public boolean isWriteLocked() {
+        return (state & WBIT) != 0L;
+    }
+
+    /**
+     * Returns true if the lock is currently held non-exclusively.
+     *
+     * @return true if the lock is currently held non-exclusively
+     */
+    public boolean isReadLocked() {
+        return (state & RBITS) != 0L;
+    }
+
+    /**
+     * Queries the number of read locks held for this lock. This
+     * method is designed for use in monitoring system state, not for
+     * synchronization control.
+     * @return the number of read locks held
+     */
+    public int getReadLockCount() {
+        return getReadLockCount(state);
+    }
+
+    /**
+     * Returns a string identifying this lock, as well as its lock
+     * state.  The state, in brackets, includes the String {@code
+     * "Unlocked"} or the String {@code "Write-locked"} or the String
+     * {@code "Read-locks:"} followed by the current number of
+     * read-locks held.
+     *
+     * @return a string identifying this lock, as well as its lock state
+     */
+    public String toString() {
+        long s = state;
+        return super.toString() +
+            ((s & ABITS) == 0L ? "[Unlocked]" :
+             (s & WBIT) != 0L ? "[Write-locked]" :
+             "[Read-locks:" + getReadLockCount(s) + "]");
+    }
+
+    // views
+
+    /**
+     * Returns a plain {@link Lock} view of this StampedLock in which
+     * the {@link Lock#lock} method is mapped to {@link #readLock},
+     * and similarly for other methods. The returned Lock does not
+     * support a {@link Condition}; method {@link
+     * Lock#newCondition()} throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @return the lock
+     */
+    public Lock asReadLock() {
+        ReadLockView v;
+        return ((v = readLockView) != null ? v :
+                (readLockView = new ReadLockView()));
+    }
+
+    /**
+     * Returns a plain {@link Lock} view of this StampedLock in which
+     * the {@link Lock#lock} method is mapped to {@link #writeLock},
+     * and similarly for other methods. The returned Lock does not
+     * support a {@link Condition}; method {@link
+     * Lock#newCondition()} throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @return the lock
+     */
+    public Lock asWriteLock() {
+        WriteLockView v;
+        return ((v = writeLockView) != null ? v :
+                (writeLockView = new WriteLockView()));
+    }
+
+    /**
+     * Returns a {@link ReadWriteLock} view of this StampedLock in
+     * which the {@link ReadWriteLock#readLock()} method is mapped to
+     * {@link #asReadLock()}, and {@link ReadWriteLock#writeLock()} to
+     * {@link #asWriteLock()}.
+     *
+     * @return the lock
+     */
+    public ReadWriteLock asReadWriteLock() {
+        ReadWriteLockView v;
+        return ((v = readWriteLockView) != null ? v :
+                (readWriteLockView = new ReadWriteLockView()));
+    }
+
+    // view classes
+
+    final class ReadLockView implements Lock {
+        public void lock() { readLock(); }
+        public void lockInterruptibly() throws InterruptedException {
+            readLockInterruptibly();
+        }
+        public boolean tryLock() { return tryReadLock() != 0L; }
+        public boolean tryLock(long time, TimeUnit unit)
+            throws InterruptedException {
+            return tryReadLock(time, unit) != 0L;
+        }
+        public void unlock() { unstampedUnlockRead(); }
+        public Condition newCondition() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    final class WriteLockView implements Lock {
+        public void lock() { writeLock(); }
+        public void lockInterruptibly() throws InterruptedException {
+            writeLockInterruptibly();
+        }
+        public boolean tryLock() { return tryWriteLock() != 0L; }
+        public boolean tryLock(long time, TimeUnit unit)
+            throws InterruptedException {
+            return tryWriteLock(time, unit) != 0L;
+        }
+        public void unlock() { unstampedUnlockWrite(); }
+        public Condition newCondition() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    final class ReadWriteLockView implements ReadWriteLock {
+        public Lock readLock() { return asReadLock(); }
+        public Lock writeLock() { return asWriteLock(); }
+    }
+
+    // Unlock methods without stamp argument checks for view classes.
+    // Needed because view-class lock methods throw away stamps.
+
+    final void unstampedUnlockWrite() {
+        WNode h; long s;
+        if (((s = state) & WBIT) == 0L)
+            throw new IllegalMonitorStateException();
+        state = (s += WBIT) == 0L ? ORIGIN : s;
+        if ((h = whead) != null && h.status != 0)
+            release(h);
+    }
+
+    final void unstampedUnlockRead() {
+        for (;;) {
+            long s, m; WNode h;
+            if ((m = (s = state) & ABITS) == 0L || m >= WBIT)
+                throw new IllegalMonitorStateException();
+            else if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    break;
+                }
+            }
+            else if (tryDecReaderOverflow(s) != 0L)
+                break;
+        }
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        state = ORIGIN; // reset to unlocked state
+    }
+
+    // internals
+
+    /**
+     * Tries to increment readerOverflow by first setting state
+     * access bits value to RBITS, indicating hold of spinlock,
+     * then updating, then releasing.
+     *
+     * @param s a reader overflow stamp: (s & ABITS) >= RFULL
+     * @return new stamp on success, else zero
+     */
+    private long tryIncReaderOverflow(long s) {
+        // assert (s & ABITS) >= RFULL;
+        if ((s & ABITS) == RFULL) {
+            if (U.compareAndSwapLong(this, STATE, s, s | RBITS)) {
+                ++readerOverflow;
+                state = s;
+                return s;
+            }
+        }
+        else if ((LockSupport.nextSecondarySeed() &
+                  OVERFLOW_YIELD_RATE) == 0)
+            Thread.yield();
+        return 0L;
+    }
+
+    /**
+     * Tries to decrement readerOverflow.
+     *
+     * @param s a reader overflow stamp: (s & ABITS) >= RFULL
+     * @return new stamp on success, else zero
+     */
+    private long tryDecReaderOverflow(long s) {
+        // assert (s & ABITS) >= RFULL;
+        if ((s & ABITS) == RFULL) {
+            if (U.compareAndSwapLong(this, STATE, s, s | RBITS)) {
+                int r; long next;
+                if ((r = readerOverflow) > 0) {
+                    readerOverflow = r - 1;
+                    next = s;
+                }
+                else
+                    next = s - RUNIT;
+                 state = next;
+                 return next;
+            }
+        }
+        else if ((LockSupport.nextSecondarySeed() &
+                  OVERFLOW_YIELD_RATE) == 0)
+            Thread.yield();
+        return 0L;
+    }
+
+    /**
+     * Wakes up the successor of h (normally whead). This is normally
+     * just h.next, but may require traversal from wtail if next
+     * pointers are lagging. This may fail to wake up an acquiring
+     * thread when one or more have been cancelled, but the cancel
+     * methods themselves provide extra safeguards to ensure liveness.
+     */
+    private void release(WNode h) {
+        if (h != null) {
+            WNode q; Thread w;
+            U.compareAndSwapInt(h, WSTATUS, WAITING, 0);
+            if ((q = h.next) == null || q.status == CANCELLED) {
+                for (WNode t = wtail; t != null && t != h; t = t.prev)
+                    if (t.status <= 0)
+                        q = t;
+            }
+            if (q != null) {
+                for (WNode r = q;;) {  // release co-waiters too
+                    if ((w = r.thread) != null) {
+                        r.thread = null;
+                        U.unpark(w);
+                    }
+                    if ((r = q.cowait) == null)
+                        break;
+                    U.compareAndSwapObject(q, WCOWAIT, r, r.cowait);
+                }
+            }
+        }
+    }
+
+    /**
+     * See above for explanation.
+     *
+     * @param interruptible true if should check interrupts and if so
+     * return INTERRUPTED
+     * @param deadline if nonzero, the System.nanoTime value to timeout
+     * at (and return zero)
+     * @return next state, or INTERRUPTED
+     */
+    private long acquireWrite(boolean interruptible, long deadline) {
+        WNode node = null, p;
+        for (int spins = -1;;) { // spin while enqueuing
+            long s, ns;
+            if (((s = state) & ABITS) == 0L) {
+                if (U.compareAndSwapLong(this, STATE, s, ns = s + WBIT))
+                    return ns;
+            }
+            else if (spins > 0) {
+                if (LockSupport.nextSecondarySeed() >= 0)
+                    --spins;
+            }
+            else if ((p = wtail) == null) { // initialize queue
+                WNode h = new WNode(WMODE, null);
+                if (U.compareAndSwapObject(this, WHEAD, null, h))
+                    wtail = h;
+            }
+            else if (spins < 0)
+                spins = (p == whead) ? SPINS : 0;
+            else if (node == null)
+                node = new WNode(WMODE, p);
+            else if (node.prev != p)
+                node.prev = p;
+            else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
+                p.next = node;
+                break;
+            }
+        }
+
+        for (int spins = SPINS;;) {
+            WNode np, pp; int ps; long s, ns; Thread w;
+            while ((np = node.prev) != p && np != null)
+                (p = np).next = node;   // stale
+            if (whead == p) {
+                for (int k = spins;;) { // spin at head
+                    if (((s = state) & ABITS) == 0L) {
+                        if (U.compareAndSwapLong(this, STATE, s, ns = s+WBIT)) {
+                            whead = node;
+                            node.prev = null;
+                            return ns;
+                        }
+                    }
+                    else if (LockSupport.nextSecondarySeed() >= 0 &&
+                             --k <= 0)
+                        break;
+                }
+                if (spins < MAX_HEAD_SPINS)
+                    spins <<= 1;
+            }
+            if ((ps = p.status) == 0)
+                U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
+            else if (ps == CANCELLED) {
+                if ((pp = p.prev) != null) {
+                    node.prev = pp;
+                    pp.next = node;
+                }
+            }
+            else {
+                long time; // 0 argument to park means no timeout
+                if (deadline == 0L)
+                    time = 0L;
+                else if ((time = deadline - System.nanoTime()) <= 0L)
+                    return cancelWaiter(node, node, false);
+                Thread wt = Thread.currentThread();
+                U.putObject(wt, PARKBLOCKER, this); // emulate LockSupport.park
+                node.thread = wt;
+                if (node.prev == p && p.status == WAITING && // recheck
+                    (p != whead || (state & ABITS) != 0L))
+                    U.park(false, time);
+                node.thread = null;
+                U.putObject(wt, PARKBLOCKER, null);
+                if (interruptible && Thread.interrupted())
+                    return cancelWaiter(node, node, true);
+            }
+        }
+    }
+
+    /**
+     * See above for explanation.
+     *
+     * @param interruptible true if should check interrupts and if so
+     * return INTERRUPTED
+     * @param deadline if nonzero, the System.nanoTime value to timeout
+     * at (and return zero)
+     * @return next state, or INTERRUPTED
+     */
+    private long acquireRead(boolean interruptible, long deadline) {
+        WNode node = null, group = null, p;
+        for (int spins = -1;;) {
+            for (;;) {
+                long s, m, ns; WNode h, q; Thread w; // anti-barging guard
+                if (group == null && (h = whead) != null &&
+                    (q = h.next) != null && q.mode != RMODE)
+                    break;
+                if ((m = (s = state) & ABITS) < RFULL ?
+                    U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
+                    (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
+                    if (group != null) {  // help release others
+                        for (WNode r = group;;) {
+                            if ((w = r.thread) != null) {
+                                r.thread = null;
+                                U.unpark(w);
+                            }
+                            if ((r = group.cowait) == null)
+                                break;
+                            U.compareAndSwapObject(group, WCOWAIT, r, r.cowait);
+                        }
+                    }
+                    return ns;
+                }
+                if (m >= WBIT)
+                    break;
+            }
+            if (spins > 0) {
+                if (LockSupport.nextSecondarySeed() >= 0)
+                    --spins;
+            }
+            else if ((p = wtail) == null) {
+                WNode h = new WNode(WMODE, null);
+                if (U.compareAndSwapObject(this, WHEAD, null, h))
+                    wtail = h;
+            }
+            else if (spins < 0)
+                spins = (p == whead) ? SPINS : 0;
+            else if (node == null)
+                node = new WNode(WMODE, p);
+            else if (node.prev != p)
+                node.prev = p;
+            else if (p.mode == RMODE && p != whead) {
+                WNode pp = p.prev;  // become co-waiter with group p
+                if (pp != null && p == wtail &&
+                    U.compareAndSwapObject(p, WCOWAIT,
+                                           node.cowait = p.cowait, node)) {
+                    node.thread = Thread.currentThread();
+                    for (long time;;) {
+                        if (deadline == 0L)
+                            time = 0L;
+                        else if ((time = deadline - System.nanoTime()) <= 0L)
+                            return cancelWaiter(node, p, false);
+                        if (node.thread == null)
+                            break;
+                        if (p.prev != pp || p.status == CANCELLED ||
+                            p == whead || p.prev != pp) {
+                            node.thread = null;
+                            break;
+                        }
+                        Thread wt = Thread.currentThread();
+                        U.putObject(wt, PARKBLOCKER, this);
+                        if (node.thread == null) // must recheck
+                            break;
+                        U.park(false, time);
+                        U.putObject(wt, PARKBLOCKER, null);
+                        if (interruptible && Thread.interrupted())
+                            return cancelWaiter(node, p, true);
+                    }
+                    group = p;
+                }
+                node = null; // throw away
+            }
+            else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
+                p.next = node;
+                break;
+            }
+        }
+
+        for (int spins = SPINS;;) {
+            WNode np, pp, r; int ps; long m, s, ns; Thread w;
+            while ((np = node.prev) != p && np != null)
+                (p = np).next = node;
+            if (whead == p) {
+                for (int k = spins;;) {
+                    if ((m = (s = state) & ABITS) != WBIT) {
+                        if (m < RFULL ?
+                            U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT):
+                            (ns = tryIncReaderOverflow(s)) != 0L) {
+                            whead = node;
+                            node.prev = null;
+                            while ((r = node.cowait) != null) {
+                                if (U.compareAndSwapObject(node, WCOWAIT,
+                                                           r, r.cowait) &&
+                                    (w = r.thread) != null) {
+                                    r.thread = null;
+                                    U.unpark(w); // release co-waiter
+                                }
+                            }
+                            return ns;
+                        }
+                    }
+                    else if (LockSupport.nextSecondarySeed() >= 0 &&
+                             --k <= 0)
+                        break;
+                }
+                if (spins < MAX_HEAD_SPINS)
+                    spins <<= 1;
+            }
+            if ((ps = p.status) == 0)
+                U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
+            else if (ps == CANCELLED) {
+                if ((pp = p.prev) != null) {
+                    node.prev = pp;
+                    pp.next = node;
+                }
+            }
+            else {
+                long time;
+                if (deadline == 0L)
+                    time = 0L;
+                else if ((time = deadline - System.nanoTime()) <= 0L)
+                    return cancelWaiter(node, node, false);
+                Thread wt = Thread.currentThread();
+                U.putObject(wt, PARKBLOCKER, this);
+                node.thread = wt;
+                if (node.prev == p && p.status == WAITING &&
+                    (p != whead || (state & ABITS) != WBIT))
+                    U.park(false, time);
+                node.thread = null;
+                U.putObject(wt, PARKBLOCKER, null);
+                if (interruptible && Thread.interrupted())
+                    return cancelWaiter(node, node, true);
+            }
+        }
+    }
+
+    /**
+     * If node non-null, forces cancel status and unsplices it from
+     * queue if possible and wakes up any cowaiters (of the node, or
+     * group, as applicable), and in any case helps release current
+     * first waiter if lock is free. (Calling with null arguments
+     * serves as a conditional form of release, which is not currently
+     * needed but may be needed under possible future cancellation
+     * policies). This is a variant of cancellation methods in
+     * AbstractQueuedSynchronizer (see its detailed explanation in AQS
+     * internal documentation).
+     *
+     * @param node if nonnull, the waiter
+     * @param group either node or the group node is cowaiting with
+     * @param interrupted if already interrupted
+     * @return INTERRUPTED if interrupted or Thread.interrupted, else zero
+     */
+    private long cancelWaiter(WNode node, WNode group, boolean interrupted) {
+        if (node != null && group != null) {
+            Thread w;
+            node.status = CANCELLED;
+            node.thread = null;
+            // unsplice cancelled nodes from group
+            for (WNode p = group, q; (q = p.cowait) != null;) {
+                if (q.status == CANCELLED)
+                    U.compareAndSwapObject(p, WNEXT, q, q.next);
+                else
+                    p = q;
+            }
+            if (group == node) {
+                WNode r; // detach and wake up uncancelled co-waiters
+                while ((r = node.cowait) != null) {
+                    if (U.compareAndSwapObject(node, WCOWAIT, r, r.cowait) &&
+                        (w = r.thread) != null) {
+                        r.thread = null;
+                        U.unpark(w);
+                    }
+                }
+                for (WNode pred = node.prev; pred != null; ) { // unsplice
+                    WNode succ, pp;        // find valid successor
+                    while ((succ = node.next) == null ||
+                           succ.status == CANCELLED) {
+                        WNode q = null;    // find successor the slow way
+                        for (WNode t = wtail; t != null && t != node; t = t.prev)
+                            if (t.status != CANCELLED)
+                                q = t;     // don't link if succ cancelled
+                        if (succ == q ||   // ensure accurate successor
+                            U.compareAndSwapObject(node, WNEXT,
+                                                   succ, succ = q)) {
+                            if (succ == null && node == wtail)
+                                U.compareAndSwapObject(this, WTAIL, node, pred);
+                            break;
+                        }
+                    }
+                    if (pred.next == node) // unsplice pred link
+                        U.compareAndSwapObject(pred, WNEXT, node, succ);
+                    if (succ != null && (w = succ.thread) != null) {
+                        succ.thread = null;
+                        U.unpark(w);       // wake up succ to observe new pred
+                    }
+                    if (pred.status != CANCELLED || (pp = pred.prev) == null)
+                        break;
+                    node.prev = pp;        // repeat if new pred wrong/cancelled
+                    U.compareAndSwapObject(pp, WNEXT, pred, succ);
+                    pred = pp;
+                }
+            }
+        }
+        WNode h; // Possibly release first waiter
+        while ((h = whead) != null) {
+            long s; WNode q; // similar to release() but check eligibility
+            if ((q = h.next) == null || q.status == CANCELLED) {
+                for (WNode t = wtail; t != null && t != h; t = t.prev)
+                    if (t.status <= 0)
+                        q = t;
+            }
+            if (h == whead) {
+                if (q != null && h.status == 0 &&
+                    ((s = state) & ABITS) != WBIT && // waiter is eligible
+                    (s == 0L || q.mode == RMODE))
+                    release(h);
+                break;
+            }
+        }
+        return (interrupted || Thread.interrupted()) ? INTERRUPTED : 0L;
+    }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe U;
+    private static final long STATE;
+    private static final long WHEAD;
+    private static final long WTAIL;
+    private static final long WNEXT;
+    private static final long WSTATUS;
+    private static final long WCOWAIT;
+    private static final long PARKBLOCKER;
+
+    static {
+        try {
+            U = sun.misc.Unsafe.getUnsafe();
+            Class<?> k = StampedLock.class;
+            Class<?> wk = WNode.class;
+            STATE = U.objectFieldOffset
+                (k.getDeclaredField("state"));
+            WHEAD = U.objectFieldOffset
+                (k.getDeclaredField("whead"));
+            WTAIL = U.objectFieldOffset
+                (k.getDeclaredField("wtail"));
+            WSTATUS = U.objectFieldOffset
+                (wk.getDeclaredField("status"));
+            WNEXT = U.objectFieldOffset
+                (wk.getDeclaredField("next"));
+            WCOWAIT = U.objectFieldOffset
+                (wk.getDeclaredField("cowait"));
+            Class<?> tk = Thread.class;
+            PARKBLOCKER = U.objectFieldOffset
+                (tk.getDeclaredField("parkBlocker"));
+
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+    }
+}
diff --git a/jdk/src/share/classes/java/util/function/BinaryOperator.java b/jdk/src/share/classes/java/util/function/BinaryOperator.java
index 37653b6..2e9050e 100644
--- a/jdk/src/share/classes/java/util/function/BinaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/BinaryOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface BinaryOperator<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/Block.java b/jdk/src/share/classes/java/util/function/Block.java
index e468396..c41e9a4 100644
--- a/jdk/src/share/classes/java/util/function/Block.java
+++ b/jdk/src/share/classes/java/util/function/Block.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface Block<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java b/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java
index 07ff741..f63403b 100644
--- a/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -29,6 +29,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface DoubleBinaryOperator /* extends BinaryOperator<Double> */ {
 //
 //    @Override
diff --git a/jdk/src/share/classes/java/util/function/DoubleBlock.java b/jdk/src/share/classes/java/util/function/DoubleBlock.java
index d5abd87..ae00084 100644
--- a/jdk/src/share/classes/java/util/function/DoubleBlock.java
+++ b/jdk/src/share/classes/java/util/function/DoubleBlock.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -33,6 +33,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface DoubleBlock {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/DoubleFunction.java b/jdk/src/share/classes/java/util/function/DoubleFunction.java
index 06c405e..d9c522c 100644
--- a/jdk/src/share/classes/java/util/function/DoubleFunction.java
+++ b/jdk/src/share/classes/java/util/function/DoubleFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface DoubleFunction<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/DoubleSupplier.java b/jdk/src/share/classes/java/util/function/DoubleSupplier.java
index 7e718a3..19d7535 100644
--- a/jdk/src/share/classes/java/util/function/DoubleSupplier.java
+++ b/jdk/src/share/classes/java/util/function/DoubleSupplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface DoubleSupplier {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java b/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java
index b9ac7f6..3843f8b 100644
--- a/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -30,6 +30,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface DoubleUnaryOperator {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/Function.java b/jdk/src/share/classes/java/util/function/Function.java
index ce8ab1e..82bae01 100644
--- a/jdk/src/share/classes/java/util/function/Function.java
+++ b/jdk/src/share/classes/java/util/function/Function.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -35,6 +35,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface Function<T, R> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/IntBinaryOperator.java b/jdk/src/share/classes/java/util/function/IntBinaryOperator.java
index 312fb2d..e25c2ba 100644
--- a/jdk/src/share/classes/java/util/function/IntBinaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/IntBinaryOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -29,6 +29,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface IntBinaryOperator {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/IntBlock.java b/jdk/src/share/classes/java/util/function/IntBlock.java
index e016316..33cdbe7 100644
--- a/jdk/src/share/classes/java/util/function/IntBlock.java
+++ b/jdk/src/share/classes/java/util/function/IntBlock.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -33,6 +33,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface IntBlock {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/IntFunction.java b/jdk/src/share/classes/java/util/function/IntFunction.java
index af8d448..6e14185 100644
--- a/jdk/src/share/classes/java/util/function/IntFunction.java
+++ b/jdk/src/share/classes/java/util/function/IntFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface IntFunction<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/IntSupplier.java b/jdk/src/share/classes/java/util/function/IntSupplier.java
index e930e0b..c73fc84 100644
--- a/jdk/src/share/classes/java/util/function/IntSupplier.java
+++ b/jdk/src/share/classes/java/util/function/IntSupplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface IntSupplier {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/IntUnaryOperator.java b/jdk/src/share/classes/java/util/function/IntUnaryOperator.java
index 315619d..2c42995 100644
--- a/jdk/src/share/classes/java/util/function/IntUnaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/IntUnaryOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -29,6 +29,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface IntUnaryOperator {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/LongBinaryOperator.java b/jdk/src/share/classes/java/util/function/LongBinaryOperator.java
index 0705678..f767c92 100644
--- a/jdk/src/share/classes/java/util/function/LongBinaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/LongBinaryOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -29,6 +29,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface LongBinaryOperator {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/LongBlock.java b/jdk/src/share/classes/java/util/function/LongBlock.java
index d9af366..71606ec 100644
--- a/jdk/src/share/classes/java/util/function/LongBlock.java
+++ b/jdk/src/share/classes/java/util/function/LongBlock.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -33,6 +33,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface LongBlock {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/LongFunction.java b/jdk/src/share/classes/java/util/function/LongFunction.java
index 449543d..61c4fbf 100644
--- a/jdk/src/share/classes/java/util/function/LongFunction.java
+++ b/jdk/src/share/classes/java/util/function/LongFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface LongFunction<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/LongSupplier.java b/jdk/src/share/classes/java/util/function/LongSupplier.java
index fb76068..f56ad7d 100644
--- a/jdk/src/share/classes/java/util/function/LongSupplier.java
+++ b/jdk/src/share/classes/java/util/function/LongSupplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface LongSupplier {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/LongUnaryOperator.java b/jdk/src/share/classes/java/util/function/LongUnaryOperator.java
index ea2c1fc..f27ddf5 100644
--- a/jdk/src/share/classes/java/util/function/LongUnaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/LongUnaryOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -29,6 +29,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface LongUnaryOperator {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/Predicate.java b/jdk/src/share/classes/java/util/function/Predicate.java
index f4e6196..9b44078 100644
--- a/jdk/src/share/classes/java/util/function/Predicate.java
+++ b/jdk/src/share/classes/java/util/function/Predicate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -31,6 +31,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface Predicate<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/Supplier.java b/jdk/src/share/classes/java/util/function/Supplier.java
index 404af55..60bc801 100644
--- a/jdk/src/share/classes/java/util/function/Supplier.java
+++ b/jdk/src/share/classes/java/util/function/Supplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface Supplier<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/function/UnaryOperator.java b/jdk/src/share/classes/java/util/function/UnaryOperator.java
index 9fa99c8..a8aaa0d 100644
--- a/jdk/src/share/classes/java/util/function/UnaryOperator.java
+++ b/jdk/src/share/classes/java/util/function/UnaryOperator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,6 +32,7 @@
  *
  * @since 1.8
  */
+@FunctionalInterface
 public interface UnaryOperator<T> {
 
     /**
diff --git a/jdk/src/share/classes/java/util/jar/Attributes.java b/jdk/src/share/classes/java/util/jar/Attributes.java
index 0358407..18ea642 100644
--- a/jdk/src/share/classes/java/util/jar/Attributes.java
+++ b/jdk/src/share/classes/java/util/jar/Attributes.java
@@ -565,6 +565,15 @@
         public static final Name MAIN_CLASS = new Name("Main-Class");
 
         /**
+         * {@code Name} object for {@code Profile} manifest attribute used by
+         * applications or libraries packaged as JAR files to indicate the
+         * minimum profile required to execute the application.
+         * @since 1.8
+         * @see UnsupportedProfileException
+         */
+        public static final Name PROFILE = new Name("Profile");
+
+        /**
          * <code>Name</code> object for <code>Sealed</code> manifest attribute
          * used for sealing.
          * @see <a href="../../../../technotes/guides/extensions/spec.html#sealing">
diff --git a/jdk/src/share/classes/java/util/jar/Pack200.java b/jdk/src/share/classes/java/util/jar/Pack200.java
index 6f244f3..c3ea395 100644
--- a/jdk/src/share/classes/java/util/jar/Pack200.java
+++ b/jdk/src/share/classes/java/util/jar/Pack200.java
@@ -574,6 +574,13 @@
          * Registers a listener for PropertyChange events on the properties map.
          * This is typically used by applications to update a progress bar.
          *
+         * <p> The default implementation of this method does nothing and has
+         * no side-effects.</p>
+         *
+         * <p><b>WARNING:</b> This method is omitted from the interface
+         * declaration in all subset Profiles of Java SE that do not include
+         * the {@code java.beans} package. </p>
+
          * @see #properties
          * @see #PROGRESS
          * @param listener  An object to be invoked when a property is changed.
@@ -586,12 +593,20 @@
          *             property instead.
          */
         @Deprecated
-        void addPropertyChangeListener(PropertyChangeListener listener) ;
+        default void addPropertyChangeListener(PropertyChangeListener listener) {
+        }
 
         /**
          * Remove a listener for PropertyChange events, added by
          * the {@link #addPropertyChangeListener}.
          *
+         * <p> The default implementation of this method does nothing and has
+         * no side-effects.</p>
+         *
+         * <p><b>WARNING:</b> This method is omitted from the interface
+         * declaration in all subset Profiles of Java SE that do not include
+         * the {@code java.beans} package. </p>
+         *
          * @see #addPropertyChangeListener
          * @param listener  The PropertyChange listener to be removed.
          * @deprecated The dependency on {@code PropertyChangeListener} creates
@@ -600,8 +615,8 @@
          *             release.
          */
         @Deprecated
-        void removePropertyChangeListener(PropertyChangeListener listener);
-
+        default void removePropertyChangeListener(PropertyChangeListener listener) {
+        }
     }
 
     /**
@@ -718,6 +733,13 @@
          * Registers a listener for PropertyChange events on the properties map.
          * This is typically used by applications to update a progress bar.
          *
+         * <p> The default implementation of this method does nothing and has
+         * no side-effects.</p>
+         *
+         * <p><b>WARNING:</b> This method is omitted from the interface
+         * declaration in all subset Profiles of Java SE that do not include
+         * the {@code java.beans} package. </p>
+         *
          * @see #properties
          * @see #PROGRESS
          * @param listener  An object to be invoked when a property is changed.
@@ -730,12 +752,20 @@
          *             PROGRESS} property instead.
          */
         @Deprecated
-        void addPropertyChangeListener(PropertyChangeListener listener) ;
+        default void addPropertyChangeListener(PropertyChangeListener listener) {
+        }
 
         /**
          * Remove a listener for PropertyChange events, added by
          * the {@link #addPropertyChangeListener}.
          *
+         * <p> The default implementation of this method does nothing and has
+         * no side-effects.</p>
+         *
+         * <p><b>WARNING:</b> This method is omitted from the interface
+         * declaration in all subset Profiles of Java SE that do not include
+         * the {@code java.beans} package. </p>
+         *
          * @see #addPropertyChangeListener
          * @param listener  The PropertyChange listener to be removed.
          * @deprecated The dependency on {@code PropertyChangeListener} creates
@@ -744,7 +774,8 @@
          *             release.
          */
         @Deprecated
-        void removePropertyChangeListener(PropertyChangeListener listener);
+        default void removePropertyChangeListener(PropertyChangeListener listener) {
+        }
     }
 
     // Private stuff....
diff --git a/jdk/src/share/classes/java/util/jar/UnsupportedProfileException.java b/jdk/src/share/classes/java/util/jar/UnsupportedProfileException.java
new file mode 100644
index 0000000..17029d4
--- /dev/null
+++ b/jdk/src/share/classes/java/util/jar/UnsupportedProfileException.java
@@ -0,0 +1,54 @@
+/*
+ * 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.  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 java.util.jar;
+
+/**
+ * Thrown to indicate an attempt to access a JAR file with a {@link
+ * Attributes.Name#PROFILE Profile} attribute that names a profile that
+ * is not supported by this runtime.
+ *
+ * @since   1.8
+ */
+public class UnsupportedProfileException extends RuntimeException {
+    private static final long serialVersionUID = -1834773870678792406L;
+
+    /**
+     * Constructs an {@code UnsupportedProfileException} with no detail
+     * message.
+     */
+    public UnsupportedProfileException() {
+    }
+
+    /**
+     * Constructs an {@code UnsupportedProfileException} with the
+     * specified detail message.
+     *
+     * @param message the detail message
+     */
+    public UnsupportedProfileException(String message) {
+        super(message);
+    }
+}
diff --git a/jdk/src/share/classes/java/util/logging/Filter.java b/jdk/src/share/classes/java/util/logging/Filter.java
index 73bbad1..4383707 100644
--- a/jdk/src/share/classes/java/util/logging/Filter.java
+++ b/jdk/src/share/classes/java/util/logging/Filter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -37,7 +37,7 @@
  *
  * @since 1.4
  */
-
+@FunctionalInterface
 public interface Filter {
 
     /**
@@ -46,5 +46,4 @@
      * @return true if the log record should be published.
      */
     public boolean isLoggable(LogRecord record);
-
 }
diff --git a/jdk/src/share/classes/java/util/logging/LogManager.java b/jdk/src/share/classes/java/util/logging/LogManager.java
index e3a8bf2..2041acb 100644
--- a/jdk/src/share/classes/java/util/logging/LogManager.java
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java
@@ -302,6 +302,10 @@
      * the same event Listener results in multiple entries
      * in the property event listener table.
      *
+     * <p><b>WARNING:</b> This method is omitted from this class in all subset
+     * Profiles of Java SE that do not include the {@code java.beans} package.
+     * </p>
+     *
      * @param l  event listener
      * @exception  SecurityException  if a security manager exists and if
      *             the caller does not have LoggingPermission("control").
@@ -335,6 +339,10 @@
      * <P>
      * Returns silently if the given listener is not found.
      *
+     * <p><b>WARNING:</b> This method is omitted from this class in all subset
+     * Profiles of Java SE that do not include the {@code java.beans} package.
+     * </p>
+     *
      * @param l  event listener (can be null)
      * @exception  SecurityException  if a security manager exists and if
      *             the caller does not have LoggingPermission("control").
diff --git a/jdk/src/share/classes/java/util/prefs/PreferenceChangeListener.java b/jdk/src/share/classes/java/util/prefs/PreferenceChangeListener.java
index 2c0c51e..0fb96c5 100644
--- a/jdk/src/share/classes/java/util/prefs/PreferenceChangeListener.java
+++ b/jdk/src/share/classes/java/util/prefs/PreferenceChangeListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -34,6 +34,7 @@
  * @see NodeChangeListener
  * @since   1.4
  */
+@FunctionalInterface
 public interface PreferenceChangeListener extends java.util.EventListener {
     /**
      * This method gets called when a preference is added, removed or when
diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java b/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
index 4b20626..fbf7471 100644
--- a/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
@@ -31,8 +31,8 @@
 
 class JavaxSecurityAuthKerberosAccessImpl
         implements JavaxSecurityAuthKerberosAccess {
-    public EncryptionKey[] keyTabGetEncryptionKeys(
-            KeyTab ktab, PrincipalName principal) {
-        return ktab.getEncryptionKeys(principal);
+    public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot(
+            KeyTab ktab) {
+        return ktab.takeSnapshot();
     }
 }
diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java b/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java
index 3ebce99..32f644b 100644
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java
@@ -41,6 +41,20 @@
  * {@link javax.security.auth.Subject Subject} during the commit phase of the
  * authentication process.
  * <p>
+ * If a {@code KeyTab} object is obtained from {@link #getUnboundInstance()}
+ * or {@link #getUnboundInstance(java.io.File)}, it is unbound and thus can be
+ * used by any service principal. Otherwise, if it's obtained from
+ * {@link #getInstance(KerberosPrincipal)} or
+ * {@link #getInstance(KerberosPrincipal, java.io.File)}, it is bound to the
+ * specific service principal and can only be used by it.
+ * <p>
+ * Please note the constructors {@link #getInstance()} and
+ * {@link #getInstance(java.io.File)} were created when there was no support
+ * for unbound keytabs. These methods should not be used anymore. An object
+ * created with either of these methods are considered to be bound to an
+ * unknown principal, which means, its {@link #isBound()} returns true and
+ * {@link #getPrincipal()} returns null.
+ * <p>
  * It might be necessary for the application to be granted a
  * {@link javax.security.auth.PrivateCredentialPermission
  * PrivateCredentialPermission} if it needs to access the KeyTab
@@ -52,7 +66,7 @@
  * The keytab file format is described at
  * <a href="http://www.ioplex.com/utilities/keytab.txt">
  * http://www.ioplex.com/utilities/keytab.txt</a>.
- *
+ * <p>
  * @since 1.7
  */
 public final class KeyTab {
@@ -74,21 +88,33 @@
     // is maintained in snapshot, this field is never "resolved".
     private final File file;
 
+    // Bound user: normally from the "principal" value in a JAAS krb5
+    // login conf. Will be null if it's "*".
+    private final KerberosPrincipal princ;
+
+    private final boolean bound;
+
     // Set up JavaxSecurityAuthKerberosAccess in KerberosSecrets
     static {
         KerberosSecrets.setJavaxSecurityAuthKerberosAccess(
                 new JavaxSecurityAuthKerberosAccessImpl());
     }
 
-    private KeyTab(File file) {
+    private KeyTab(KerberosPrincipal princ, File file, boolean bound) {
+        this.princ = princ;
         this.file = file;
+        this.bound = bound;
     }
 
     /**
-     * Returns a {@code KeyTab} instance from a {@code File} object.
+     * Returns a {@code KeyTab} instance from a {@code File} object
+     * that is bound to an unknown service principal.
      * <p>
      * The result of this method is never null. This method only associates
      * the returned {@code KeyTab} object with the file and does not read it.
+     * <p>
+     * Developers should call {@link #getInstance(KerberosPrincipal,File)}
+     * when the bound service principal is known.
      * @param file the keytab {@code File} object, must not be null
      * @return the keytab instance
      * @throws NullPointerException if the {@code file} argument is null
@@ -97,23 +123,99 @@
         if (file == null) {
             throw new NullPointerException("file must be non null");
         }
-        return new KeyTab(file);
+        return new KeyTab(null, file, true);
     }
 
     /**
-     * Returns the default {@code KeyTab} instance.
+     * Returns an unbound {@code KeyTab} instance from a {@code File}
+     * object.
+     * <p>
+     * The result of this method is never null. This method only associates
+     * the returned {@code KeyTab} object with the file and does not read it.
+     * @param file the keytab {@code File} object, must not be null
+     * @return the keytab instance
+     * @throws NullPointerException if the file argument is null
+     * @since 1.8
+     */
+    public static KeyTab getUnboundInstance(File file) {
+        if (file == null) {
+            throw new NullPointerException("file must be non null");
+        }
+        return new KeyTab(null, file, false);
+    }
+
+    /**
+     * Returns a {@code KeyTab} instance from a {@code File} object
+     * that is bound to the specified service principal.
+     * <p>
+     * The result of this method is never null. This method only associates
+     * the returned {@code KeyTab} object with the file and does not read it.
+     * @param princ the bound service principal, must not be null
+     * @param file the keytab {@code File} object, must not be null
+     * @return the keytab instance
+     * @throws NullPointerException if either of the arguments is null
+     * @since 1.8
+     */
+    public static KeyTab getInstance(KerberosPrincipal princ, File file) {
+        if (princ == null) {
+            throw new NullPointerException("princ must be non null");
+        }
+        if (file == null) {
+            throw new NullPointerException("file must be non null");
+        }
+        return new KeyTab(princ, file, true);
+    }
+
+    /**
+     * Returns the default {@code KeyTab} instance that is bound
+     * to an unknown service principal.
      * <p>
      * The result of this method is never null. This method only associates
      * the returned {@code KeyTab} object with the default keytab file and
      * does not read it.
+     * <p>
+     * Developers should call {@link #getInstance(KerberosPrincipal)}
+     * when the bound service principal is known.
      * @return the default keytab instance.
      */
     public static KeyTab getInstance() {
-        return new KeyTab(null);
+        return new KeyTab(null, null, true);
+    }
+
+    /**
+     * Returns the default unbound {@code KeyTab} instance.
+     * <p>
+     * The result of this method is never null. This method only associates
+     * the returned {@code KeyTab} object with the default keytab file and
+     * does not read it.
+     * @return the default keytab instance
+     * @since 1.8
+     */
+    public static KeyTab getUnboundInstance() {
+        return new KeyTab(null, null, false);
+    }
+
+    /**
+     * Returns the default {@code KeyTab} instance that is bound
+     * to the specified service principal.
+     * <p>
+     * The result of this method is never null. This method only associates
+     * the returned {@code KeyTab} object with the default keytab file and
+     * does not read it.
+     * @param princ the bound service principal, must not be null
+     * @return the default keytab instance
+     * @throws NullPointerException if {@code princ} is null
+     * @since 1.8
+     */
+    public static KeyTab getInstance(KerberosPrincipal princ) {
+        if (princ == null) {
+            throw new NullPointerException("princ must be non null");
+        }
+        return new KeyTab(princ, null, true);
     }
 
     //Takes a snapshot of the keytab content
-    private sun.security.krb5.internal.ktab.KeyTab takeSnapshot() {
+    sun.security.krb5.internal.ktab.KeyTab takeSnapshot() {
         return sun.security.krb5.internal.ktab.KeyTab.getInstance(file);
     }
 
@@ -147,6 +249,9 @@
      * <p>
      * Any unsupported key read from the keytab is ignored and not included
      * in the result.
+     * <p>
+     * If this keytab is bound to a specific principal, calling this method on
+     * another principal will return an empty array.
      *
      * @param principal the Kerberos principal, must not be null.
      * @return the keys (never null, may be empty)
@@ -157,8 +262,11 @@
      */
     public KerberosKey[] getKeys(KerberosPrincipal principal) {
         try {
-            EncryptionKey[] keys = takeSnapshot().readServiceKeys(
-                    new PrincipalName(principal.getName()));
+            if (princ != null && !principal.equals(princ)) {
+                return new KerberosKey[0];
+            }
+            PrincipalName pn = new PrincipalName(principal.getName());
+            EncryptionKey[] keys = takeSnapshot().readServiceKeys(pn);
             KerberosKey[] kks = new KerberosKey[keys.length];
             for (int i=0; i<kks.length; i++) {
                 Integer tmp = keys[i].getKeyVersionNumber();
@@ -195,7 +303,10 @@
     }
 
     public String toString() {
-        return file == null ? "Default keytab" : file.toString();
+        String s = (file == null) ? "Default keytab" : file.toString();
+        if (!bound) return s;
+        else if (princ == null) return s + " for someone";
+        else return s + " for " + princ;
     }
 
     /**
@@ -204,7 +315,7 @@
      * @return a hashCode() for the <code>KeyTab</code>
      */
     public int hashCode() {
-        return Objects.hash(file);
+        return Objects.hash(file, princ, bound);
     }
 
     /**
@@ -225,6 +336,31 @@
         }
 
         KeyTab otherKtab = (KeyTab) other;
-        return Objects.equals(otherKtab.file, file);
+        return Objects.equals(otherKtab.princ, princ) &&
+                Objects.equals(otherKtab.file, file) &&
+                bound == otherKtab.bound;
+    }
+
+    /**
+     * Returns the service principal this {@code KeyTab} object
+     * is bound to. Returns {@code null} if it's not bound.
+     * <p>
+     * Please note the deprecated constructors create a KeyTab object bound for
+     * some unknown principal. In this case, this method also returns null.
+     * User can call {@link #isBound()} to verify this case.
+     * @return the service principal
+     * @since 1.8
+     */
+    public KerberosPrincipal getPrincipal() {
+        return princ;
+    }
+
+    /**
+     * Returns if the keytab is bound to a principal
+     * @return if the keytab is bound to a principal
+     * @since 1.8
+     */
+    public boolean isBound() {
+        return bound;
     }
 }
diff --git a/jdk/src/share/classes/javax/swing/JMenuBar.java b/jdk/src/share/classes/javax/swing/JMenuBar.java
index 0a16c86..22dbe62 100644
--- a/jdk/src/share/classes/javax/swing/JMenuBar.java
+++ b/jdk/src/share/classes/javax/swing/JMenuBar.java
@@ -70,7 +70,14 @@
  * of all JavaBeans<sup><font size="-2">TM</font></sup>
  * has been added to the <code>java.beans</code> package.
  * Please see {@link java.beans.XMLEncoder}.
- *
+ * <p>
+ * <strong>Warning:</strong>
+ * By default, pressing the Tab key does not transfer focus from a <code>
+ * JMenuBar</code> which is added to a container together with other Swing
+ * components, because the <code>focusTraversalKeysEnabled</code> property
+ * of <code>JMenuBar</code> is set to <code>false</code>. To resolve this,
+ * you should call the <code>JMenuBar.setFocusTraversalKeysEnabled(true)</code>
+ * method.
  * @beaninfo
  *   attribute: isContainer true
  * description: A container for holding and displaying menus.
diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java
index 269bd34..b31f760 100644
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1120,7 +1120,9 @@
             listBox.setSelectedIndex( si + 1 );
             listBox.ensureIndexIsVisible( si + 1 );
             if ( !isTableCellEditor ) {
-                comboBox.setSelectedIndex(si+1);
+                if (!(UIManager.getBoolean("ComboBox.noActionOnKeyNavigation") && comboBox.isPopupVisible())) {
+                    comboBox.setSelectedIndex(si+1);
+                }
             }
             comboBox.repaint();
         }
@@ -1144,7 +1146,9 @@
             listBox.setSelectedIndex( si - 1 );
             listBox.ensureIndexIsVisible( si - 1 );
             if ( !isTableCellEditor ) {
-                comboBox.setSelectedIndex(si-1);
+                if (!(UIManager.getBoolean("ComboBox.noActionOnKeyNavigation") && comboBox.isPopupVisible())) {
+                    comboBox.setSelectedIndex(si-1);
+                }
             }
             comboBox.repaint();
         }
@@ -1490,7 +1494,13 @@
                      key == HOME || key == END) {
                 int index = getNextIndex(comboBox, key);
                 if (index >= 0 && index < comboBox.getItemCount()) {
-                    comboBox.setSelectedIndex(index);
+                    if (UIManager.getBoolean("ComboBox.noActionOnKeyNavigation") && comboBox.isPopupVisible()) {
+                        ui.listBox.setSelectedIndex(index);
+                        ui.listBox.ensureIndexIsVisible(index);
+                        comboBox.repaint();
+                    } else {
+                        comboBox.setSelectedIndex(index);
+                    }
                 }
             }
             else if (key == DOWN) {
@@ -1558,22 +1568,33 @@
 
             else if (key == ENTER) {
                 if (comboBox.isPopupVisible()) {
-                    // Forces the selection of the list item
-                    boolean isEnterSelectablePopup =
-                            UIManager.getBoolean("ComboBox.isEnterSelectablePopup");
-                    if (!comboBox.isEditable() || isEnterSelectablePopup
-                            || ui.isTableCellEditor) {
+                    // If ComboBox.noActionOnKeyNavigation is set,
+                    // forse selection of list item
+                    if (UIManager.getBoolean("ComboBox.noActionOnKeyNavigation")) {
                         Object listItem = ui.popup.getList().getSelectedValue();
                         if (listItem != null) {
-                            // Use the selected value from popup
-                            // to set the selected item in combo box,
-                            // but ensure before that JComboBox.actionPerformed()
-                            // won't use editor's value to set the selected item
                             comboBox.getEditor().setItem(listItem);
                             comboBox.setSelectedItem(listItem);
                         }
+                        comboBox.setPopupVisible(false);
+                    } else {
+                        // Forces the selection of the list item
+                        boolean isEnterSelectablePopup =
+                                UIManager.getBoolean("ComboBox.isEnterSelectablePopup");
+                        if (!comboBox.isEditable() || isEnterSelectablePopup
+                                || ui.isTableCellEditor) {
+                            Object listItem = ui.popup.getList().getSelectedValue();
+                            if (listItem != null) {
+                                // Use the selected value from popup
+                                // to set the selected item in combo box,
+                                // but ensure before that JComboBox.actionPerformed()
+                                // won't use editor's value to set the selected item
+                                comboBox.getEditor().setItem(listItem);
+                                comboBox.setSelectedItem(listItem);
+                            }
+                        }
+                        comboBox.setPopupVisible(false);
                     }
-                    comboBox.setPopupVisible(false);
                 }
                 else {
                     // Hide combo box if it is a table cell editor
@@ -1604,14 +1625,20 @@
         }
 
         private int getNextIndex(JComboBox comboBox, String key) {
+            int listHeight = comboBox.getMaximumRowCount();
+
+            int selectedIndex = comboBox.getSelectedIndex();
+            if (UIManager.getBoolean("ComboBox.noActionOnKeyNavigation")
+                    && (comboBox.getUI() instanceof BasicComboBoxUI)) {
+                selectedIndex = ((BasicComboBoxUI) comboBox.getUI()).listBox.getSelectedIndex();
+            }
+
             if (key == PAGE_UP) {
-                int listHeight = comboBox.getMaximumRowCount();
-                int index = comboBox.getSelectedIndex() - listHeight;
+                int index = selectedIndex - listHeight;
                 return (index < 0 ? 0: index);
             }
             else if (key == PAGE_DOWN) {
-                int listHeight = comboBox.getMaximumRowCount();
-                int index = comboBox.getSelectedIndex() + listHeight;
+                int index = selectedIndex + listHeight;
                 int max = comboBox.getItemCount();
                 return (index < max ? index: max-1);
             }
diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java
index 5a91358..2e808c4 100644
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -861,6 +861,7 @@
                          "END", "endPassThrough",
                        "ENTER", "enterPressed"
                  }),
+            "ComboBox.noActionOnKeyNavigation", Boolean.FALSE,
 
             // *** FileChooser
 
diff --git a/jdk/src/share/classes/sun/awt/im/CompositionAreaHandler.java b/jdk/src/share/classes/sun/awt/im/CompositionAreaHandler.java
index 6ae4a95..1d661c4 100644
--- a/jdk/src/share/classes/sun/awt/im/CompositionAreaHandler.java
+++ b/jdk/src/share/classes/sun/awt/im/CompositionAreaHandler.java
@@ -33,6 +33,7 @@
 import java.awt.font.TextAttribute;
 import java.awt.font.TextHitInfo;
 import java.awt.im.InputMethodRequests;
+import java.lang.ref.WeakReference;
 import java.text.AttributedCharacterIterator;
 import java.text.AttributedCharacterIterator.Attribute;
 import java.text.AttributedString;
@@ -55,7 +56,7 @@
 
     private AttributedCharacterIterator composedText;
     private TextHitInfo caret = null;
-    private Component clientComponent = null;
+    private WeakReference<Component> clientComponent = new WeakReference<>(null);
     private InputMethodContext inputMethodContext;
 
     /**
@@ -76,8 +77,9 @@
             }
             // If the client component is an active client using below-the-spot style, then
             // make the composition window undecorated without a title bar.
-            if(clientComponent!=null){
-                InputMethodRequests req = clientComponent.getInputMethodRequests();
+            Component client = clientComponent.get();
+            if(client != null){
+                InputMethodRequests req = client.getInputMethodRequests();
                 if (req != null && inputMethodContext.useBelowTheSpotInput()) {
                     setCompositionAreaUndecorated(true);
                 }
@@ -86,7 +88,7 @@
     }
 
     void setClientComponent(Component clientComponent) {
-        this.clientComponent = clientComponent;
+        this.clientComponent = new WeakReference<>(clientComponent);
     }
 
     /**
@@ -256,8 +258,9 @@
      * the composed text are forwarded to the client component.
      */
     InputMethodRequests getClientInputMethodRequests() {
-        if (clientComponent != null) {
-            return clientComponent.getInputMethodRequests();
+        Component client = clientComponent.get();
+        if (client != null) {
+            return client.getInputMethodRequests();
         }
 
         return null;
diff --git a/jdk/src/share/classes/sun/launcher/LauncherHelper.java b/jdk/src/share/classes/sun/launcher/LauncherHelper.java
index 2fc42a6..fa6bf84 100644
--- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java
+++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java
@@ -65,10 +65,14 @@
 import java.util.jar.Attributes;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
+import sun.misc.Version;
+import sun.misc.URLClassPath;
 
 public enum LauncherHelper {
     INSTANCE;
     private static final String MAIN_CLASS = "Main-Class";
+    private static final String PROFILE    = "Profile";
+
     private static StringBuilder outBuf = new StringBuilder();
 
     private static final String INDENT = "    ";
@@ -409,6 +413,28 @@
             if (mainValue == null) {
                 abort(null, "java.launcher.jar.error3", jarname);
             }
+
+            /*
+             * If this is not a full JRE then the Profile attribute must be
+             * present with the Main-Class attribute so as to indicate the minimum
+             * profile required. Note that we need to suppress checking of the Profile
+             * attribute after we detect an error. This is because the abort may
+             * need to lookup resources and this may involve opening additional JAR
+             * files that would result in errors that suppress the main error.
+             */
+            String profile = mainAttrs.getValue(PROFILE);
+            if (profile == null) {
+                if (!Version.isFullJre()) {
+                    URLClassPath.suppressProfileCheckForLauncher();
+                    abort(null, "java.launcher.jar.error4", jarname);
+                }
+            } else {
+                if (!Version.supportsProfile(profile)) {
+                    URLClassPath.suppressProfileCheckForLauncher();
+                    abort(null, "java.launcher.jar.error5", profile, jarname);
+                }
+            }
+
             /*
              * Hand off to FXHelper if it detects a JavaFX application
              * This must be done after ensuring a Main-Class entry
@@ -418,6 +444,7 @@
                     new Attributes.Name(FXHelper.JAVAFX_APPLICATION_MARKER))) {
                 return FXHelper.class.getName();
             }
+
             return mainValue.trim();
         } catch (IOException ioe) {
             abort(ioe, "java.launcher.jar.error1", jarname);
diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher.properties b/jdk/src/share/classes/sun/launcher/resources/launcher.properties
index 8fbefac..cbfc3f0 100644
--- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties
+++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties
@@ -139,6 +139,8 @@
     Error: An unexpected error occurred while trying to open file {0}
 java.launcher.jar.error2=manifest not found in {0}
 java.launcher.jar.error3=no main manifest attribute, in {0}
+java.launcher.jar.error4=no Profile manifest attribute in {0}
+java.launcher.jar.error5=Profile {0} required by {1} not supported by this runtime
 java.launcher.init.error=initialization error
 java.launcher.javafx.error1=\
     Error: The JavaFX launchApplication method has the wrong signature, it\n\
diff --git a/jdk/src/share/classes/sun/management/jdp/JdpBroadcaster.java b/jdk/src/share/classes/sun/management/jdp/JdpBroadcaster.java
index df5f234..b1766e6 100644
--- a/jdk/src/share/classes/sun/management/jdp/JdpBroadcaster.java
+++ b/jdk/src/share/classes/sun/management/jdp/JdpBroadcaster.java
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * 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/jdk/src/share/classes/sun/management/jdp/JdpController.java b/jdk/src/share/classes/sun/management/jdp/JdpController.java
index d8d0ed4..3083c97 100644
--- a/jdk/src/share/classes/sun/management/jdp/JdpController.java
+++ b/jdk/src/share/classes/sun/management/jdp/JdpController.java
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * 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/jdk/src/share/classes/sun/management/jdp/JdpException.java b/jdk/src/share/classes/sun/management/jdp/JdpException.java
index 0340422..7c312d4 100644
--- a/jdk/src/share/classes/sun/management/jdp/JdpException.java
+++ b/jdk/src/share/classes/sun/management/jdp/JdpException.java
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * 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/jdk/src/share/classes/sun/management/jdp/JdpGenericPacket.java b/jdk/src/share/classes/sun/management/jdp/JdpGenericPacket.java
index 8e88b14..74b8a58 100644
--- a/jdk/src/share/classes/sun/management/jdp/JdpGenericPacket.java
+++ b/jdk/src/share/classes/sun/management/jdp/JdpGenericPacket.java
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * 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/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java b/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java
index 7d5ccc2..60aea2b 100644
--- a/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java
+++ b/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * 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/jdk/src/share/classes/sun/management/jdp/JdpPacket.java b/jdk/src/share/classes/sun/management/jdp/JdpPacket.java
index ba0ec4f..9260112 100644
--- a/jdk/src/share/classes/sun/management/jdp/JdpPacket.java
+++ b/jdk/src/share/classes/sun/management/jdp/JdpPacket.java
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * 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
@@ -20,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package sun.management.jdp;
 
 import java.io.IOException;
diff --git a/jdk/src/share/classes/sun/management/jdp/JdpPacketReader.java b/jdk/src/share/classes/sun/management/jdp/JdpPacketReader.java
index 9f3957a..f69c07d 100644
--- a/jdk/src/share/classes/sun/management/jdp/JdpPacketReader.java
+++ b/jdk/src/share/classes/sun/management/jdp/JdpPacketReader.java
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * 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/jdk/src/share/classes/sun/management/jdp/JdpPacketWriter.java b/jdk/src/share/classes/sun/management/jdp/JdpPacketWriter.java
index 7ebd002..2af2fdc 100644
--- a/jdk/src/share/classes/sun/management/jdp/JdpPacketWriter.java
+++ b/jdk/src/share/classes/sun/management/jdp/JdpPacketWriter.java
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * 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/jdk/src/share/classes/sun/management/jdp/package-info.java b/jdk/src/share/classes/sun/management/jdp/package-info.java
index e21e461..4a0d169 100644
--- a/jdk/src/share/classes/sun/management/jdp/package-info.java
+++ b/jdk/src/share/classes/sun/management/jdp/package-info.java
@@ -1,3 +1,27 @@
+/*
+ * 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.  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.
+ */
 /**
  *  Summary
  *  -------
diff --git a/jdk/src/share/classes/sun/misc/URLClassPath.java b/jdk/src/share/classes/sun/misc/URLClassPath.java
index 4056723..b8036ab 100644
--- a/jdk/src/share/classes/sun/misc/URLClassPath.java
+++ b/jdk/src/share/classes/sun/misc/URLClassPath.java
@@ -35,6 +35,7 @@
 import java.util.jar.Manifest;
 import java.util.jar.Attributes;
 import java.util.jar.Attributes.Name;
+import java.util.jar.UnsupportedProfileException;
 import java.net.JarURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -64,6 +65,12 @@
     final static String JAVA_VERSION;
     private static final boolean DEBUG;
 
+    /**
+     * Used by launcher to indicate that checking of the JAR file "Profile"
+     * attribute has been suppressed.
+     */
+    private static boolean profileCheckSuppressedByLauncher;
+
     static {
         JAVA_VERSION = java.security.AccessController.doPrivileged(
             new sun.security.action.GetPropertyAction("java.version"));
@@ -582,6 +589,15 @@
         }
     }
 
+    /**
+     * Used by the launcher to suppress further checking of the JAR file Profile
+     * attribute (necessary when the launcher is aborting as the abort involves
+     * a resource lookup that may involve opening additional JAR files)
+     */
+    public static void suppressProfileCheckForLauncher() {
+        profileCheckSuppressedByLauncher = true;
+    }
+
     /*
      * Inner class used to represent a Loader of resources from a JAR URL.
      */
@@ -789,6 +805,28 @@
             return false;
         }
 
+        /**
+         * If the Profile attribute is present then this method checks that the runtime
+         * supports that profile.
+         *
+         * ## Add a fast path like Class-Path to avoid reading the manifest when the attribute
+         *    is not present.
+         */
+        void checkProfileAttribute() throws IOException {
+            Manifest man = jar.getManifest();
+            if (man != null) {
+                Attributes attr = man.getMainAttributes();
+                if (attr != null) {
+                    String value = attr.getValue(Name.PROFILE);
+                    if (value != null && !Version.supportsProfile(value)) {
+                        String prefix = Version.profileName().length() > 0 ?
+                            "This runtime implements " + Version.profileName() + ", " : "";
+                        throw new UnsupportedProfileException(prefix + csu + " requires " + value);
+                    }
+                }
+            }
+        }
+
         /*
          * Returns the URL for a resource with the specified name
          */
@@ -958,6 +996,12 @@
 
             ensureOpen();
             parseExtensionsDependencies();
+
+            // check Profile attribute if present
+            if (!profileCheckSuppressedByLauncher) {
+                checkProfileAttribute();
+            }
+
             if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary
                 Manifest man = jar.getManifest();
                 if (man != null) {
diff --git a/jdk/src/share/classes/sun/misc/Version.java.template b/jdk/src/share/classes/sun/misc/Version.java.template
index 62babae..710bf71 100644
--- a/jdk/src/share/classes/sun/misc/Version.java.template
+++ b/jdk/src/share/classes/sun/misc/Version.java.template
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -36,8 +36,11 @@
         "@@java_version@@";
 
     private static final String java_runtime_name =
-	"@@java_runtime_name@@";
- 
+        "@@java_runtime_name@@";
+
+    private static final String java_profile_name =
+        "@@java_profile_name@@";
+
     private static final String java_runtime_version =
         "@@java_runtime_version@@";
 
@@ -49,6 +52,8 @@
         System.setProperty("java.version", java_version);
         System.setProperty("java.runtime.version", java_runtime_version);
         System.setProperty("java.runtime.name", java_runtime_name);
+        if (java_profile_name.length() > 0)
+            System.setProperty("java.runtime.profile", java_profile_name);
     }
 
     private static boolean versionsInitialized = false;
@@ -90,23 +95,28 @@
         boolean isHeadless = false;
 
         /* Report that we're running headless if the property is true */
-	String headless = System.getProperty("java.awt.headless");
-	if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
+        String headless = System.getProperty("java.awt.headless");
+        if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
             isHeadless = true;
-	} 
+        }
 
         /* First line: platform version. */
         ps.println(launcher_name + " version \"" + java_version + "\"");
 
         /* Second line: runtime version (ie, libraries). */
 
-	ps.print(java_runtime_name + " (build " + java_runtime_version);
+        ps.print(java_runtime_name + " (build " + java_runtime_version);
 
-	if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
-	    // embedded builds report headless state
-	    ps.print(", headless");
-	}
-	ps.println(')');
+        if (java_profile_name.length() > 0) {
+            // profile name
+            ps.print(", profile " + java_profile_name);
+        }
+
+        if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
+            // embedded builds report headless state
+            ps.print(", headless");
+        }
+        ps.println(')');
 
         /* Third line: JVM information. */
         String java_vm_name    = System.getProperty("java.vm.name");
@@ -332,6 +342,67 @@
     private static native boolean getJvmVersionInfo();
     private static native void getJdkVersionInfo();
 
+    // Possible runtime profiles, ordered from small to large
+    private final static String[] PROFILES = { "compact1", "compact2", "compact3" };
+
+    /**
+     * Returns the name of the profile that this runtime implements. The empty
+     * string is returned for the full Java Runtime.
+     */
+    public static String profileName() {
+        return java_profile_name;
+    }
+
+    /**
+     * Indicates if this runtime implements the full Java Runtime.
+     */
+    public static boolean isFullJre() {
+        return java_profile_name.length() == 0;
+    }
+
+    // cached index of this profile's name in PROFILES (1-based)
+    private static int thisRuntimeIndex;
+
+    /**
+     * Indicates if this runtime supports the given profile. Profile names are
+     * case sensitive. 
+     *
+     * @return {@code true} if the given profile is supported
+     */
+    public static boolean supportsProfile(String requiredProfile) {
+        int x = thisRuntimeIndex - 1;
+        if (x < 0) {
+            String profile = profileName();
+            if (profile.length() > 0) {
+                x = 0;
+                while (x < PROFILES.length) {
+                    if (PROFILES[x].equals(profile))
+                        break;
+                    x++;
+                }
+                if (x >= PROFILES.length)
+                    throw new InternalError(profile + " not known to sun.misc.Version");
+
+                // okay if another thread has already set it
+                thisRuntimeIndex = x + 1;
+            }
+            // else we are a full JRE
+        }
+
+        int y = 0;
+        while (y < PROFILES.length) {
+            if (PROFILES[y].equals(requiredProfile))
+                break;
+            y++;
+        }
+        if (y >= PROFILES.length) {
+            // profile not found so caller has requested something that is not defined
+            return false;
+        }
+
+        return x < 0 || x >= y;
+    }
+
 }
 
 // Help Emacs a little because this file doesn't end in .java.
diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java
index e0524e8..e9f3f95 100644
--- a/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java
+++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java
@@ -148,8 +148,8 @@
         }
 
         @Override
-        public final <T extends Annotation> T[] getAnnotations(Class<T> annotation) {
-            return getDeclaredAnnotations(annotation);
+        public final <T extends Annotation> T[] getAnnotationsByType(Class<T> annotation) {
+            return getDeclaredAnnotationsByType(annotation);
         }
 
         @Override
@@ -164,7 +164,7 @@
         }
 
         @Override
-        public <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotation) {
+        public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotation) {
             return AnnotationSupport.getMultipleAnnotations(annotations, annotation);
         }
 
diff --git a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
index 528658d..0b1a13e 100644
--- a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
+++ b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java
@@ -200,14 +200,16 @@
         return getAnnotation(annotationClass);
     }
 
-    public <T extends Annotation> T[] getAnnotations(Class<T> annotationClass) {
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
         return AnnotationSupport.getMultipleAnnotations(mapAnnotations(getAnnotations()), annotationClass);
     }
 
-    public <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotationClass) {
+    @Override
+    public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
-        return getAnnotations(annotationClass);
+        return getAnnotationsByType(annotationClass);
     }
 
     public Annotation[] getAnnotations() {
diff --git a/jdk/src/share/classes/sun/security/jgss/LoginConfigImpl.java b/jdk/src/share/classes/sun/security/jgss/LoginConfigImpl.java
index 41a783a..52e2fa4 100644
--- a/jdk/src/share/classes/sun/security/jgss/LoginConfigImpl.java
+++ b/jdk/src/share/classes/sun/security/jgss/LoginConfigImpl.java
@@ -175,6 +175,7 @@
                 options.put("useKeyTab", "true");
                 options.put("storeKey", "true");
                 options.put("doNotPrompt", "true");
+                options.put("principal", "*");
                 options.put("isInitiator", "false");
             } else {
                 options.put("useTicketCache", "true");
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
index f0495ee..0d5a314 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
@@ -243,14 +243,24 @@
     }
 
     /**
+     * A helper method to get a sun..KeyTab from a javax..KeyTab
+     * @param ktab the javax..KeyTab object
+     * @return the sun..KeyTab object
+     */
+    public static sun.security.krb5.internal.ktab.KeyTab
+            snapshotFromJavaxKeyTab(KeyTab ktab) {
+        return KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+                .keyTabTakeSnapshot(ktab);
+    }
+
+    /**
      * A helper method to get EncryptionKeys from a javax..KeyTab
-     * @param ktab the javax..KeyTab class
+     * @param ktab the javax..KeyTab object
      * @param cname the PrincipalName
      * @return the EKeys, never null, might be empty
      */
     public static EncryptionKey[] keysFromJavaxKeyTab(
             KeyTab ktab, PrincipalName cname) {
-        return KerberosSecrets.getJavaxSecurityAuthKerberosAccess().
-                keyTabGetEncryptionKeys(ktab, cname);
+        return snapshotFromJavaxKeyTab(ktab).readServiceKeys(cname);
     }
 }
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/ServiceCreds.java b/jdk/src/share/classes/sun/security/jgss/krb5/ServiceCreds.java
index 21b8f57..824724b 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/ServiceCreds.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/ServiceCreds.java
@@ -101,9 +101,22 @@
         if (serverPrincipal != null) {      // A named principal
             sc.kp = new KerberosPrincipal(serverPrincipal);
         } else {
-            if (sc.allPrincs.size() == 1) { // choose the only one
-                sc.kp = sc.allPrincs.iterator().next();
-                serverPrincipal = sc.kp.getName();
+            // For compatibility reason, we set the name of default principal
+            // to the "only possible" name it can take, which means there is
+            // only one KerberosPrincipal and there is no unbound keytabs
+            if (sc.allPrincs.size() == 1) {
+                boolean hasUnbound = false;
+                for (KeyTab ktab: SubjectComber.findMany(
+                        subj, null, null, KeyTab.class)) {
+                    if (!ktab.isBound()) {
+                        hasUnbound = true;
+                        break;
+                    }
+                }
+                if (!hasUnbound) {
+                    sc.kp = sc.allPrincs.iterator().next();
+                    serverPrincipal = sc.kp.getName();
+                }
             }
         }
 
@@ -131,20 +144,35 @@
     }
 
     /**
-     * Gets keys for someone unknown.
-     * Used by TLS or as a fallback in getEKeys(). Can still return an
-     * empty array.
+     * Gets keys for "someone". Used in 2 cases:
+     * 1. By TLS because it needs to get keys before client comes in.
+     * 2. As a fallback in getEKeys() below.
+     * This method can still return an empty array.
      */
     public KerberosKey[] getKKeys() {
         if (destroyed) {
             throw new IllegalStateException("This object is destroyed");
         }
-        if (kp != null) {
-            return getKKeys(kp);
-        } else if (!allPrincs.isEmpty()) {
-            return getKKeys(allPrincs.iterator().next());
+        KerberosPrincipal one = kp;                 // named principal
+        if (one == null && !allPrincs.isEmpty()) {  // or, a known principal
+            one = allPrincs.iterator().next();
         }
-        return new KerberosKey[0];
+        if (one == null) {                          // Or, some random one
+            for (KeyTab ktab: ktabs) {
+                // Must be unbound keytab, otherwise, allPrincs is not empty
+                PrincipalName pn =
+                        Krb5Util.snapshotFromJavaxKeyTab(ktab).getOneName();
+                if (pn != null) {
+                    one = new KerberosPrincipal(pn.getName());
+                    break;
+                }
+            }
+        }
+        if (one != null) {
+            return getKKeys(one);
+        } else {
+            return new KerberosKey[0];
+        }
     }
 
     /**
@@ -152,15 +180,13 @@
      * @param princ the target name initiator requests. Not null.
      * @return keys for the princ, never null, might be empty
      */
-    private KerberosKey[] getKKeys(KerberosPrincipal princ) {
-        ArrayList<KerberosKey> keys = new ArrayList<>();
-        if (kp != null && !princ.equals(kp)) {
-            return new KerberosKey[0];      // Not me
+    public KerberosKey[] getKKeys(KerberosPrincipal princ) {
+        if (destroyed) {
+            throw new IllegalStateException("This object is destroyed");
         }
-        if (!allPrincs.contains(princ)) {
-            return new KerberosKey[0];      // Not someone I know, This check
-                                            // is necessary but a KeyTab has
-                                            // no principal name recorded.
+        ArrayList<KerberosKey> keys = new ArrayList<>();
+        if (kp != null && !princ.equals(kp)) {      // named principal
+            return new KerberosKey[0];
         }
         for (KerberosKey k: kk) {
             if (k.getPrincipal().equals(princ)) {
@@ -168,6 +194,13 @@
             }
         }
         for (KeyTab ktab: ktabs) {
+            if (ktab.getPrincipal() == null && ktab.isBound()) {
+                // legacy bound keytab. although we don't know who
+                // the bound principal is, it must be in allPrincs
+                if (!allPrincs.contains(princ)) {
+                    continue;   // skip this legacy bound keytab
+                }
+            }
             for (KerberosKey k: ktab.getKeys(princ)) {
                 keys.add(k);
             }
@@ -186,12 +219,12 @@
         }
         KerberosKey[] kkeys = getKKeys(new KerberosPrincipal(princ.getName()));
         if (kkeys.length == 0) {
-            // Note: old JDK does not perform real name checking. If the
-            // acceptor starts by name A but initiator requests for B,
-            // as long as their keys match (i.e. A's keys can decrypt B's
-            // service ticket), the authentication is OK. There are real
-            // customers depending on this to use different names for a
-            // single service.
+            // Fallback: old JDK does not perform real name checking. If the
+            // acceptor has host.sun.com but initiator requests for host,
+            // as long as their keys match (i.e. keys for one can decrypt
+            // the other's service ticket), the authentication is OK.
+            // There are real customers depending on this to use different
+            // names for a single service.
             kkeys = getKKeys();
         }
         EncryptionKey[] ekeys = new EncryptionKey[kkeys.length];
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java b/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
index d267dbd..ad1723f 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
@@ -86,36 +86,39 @@
             List<T> answer = (oneOnly ? null : new ArrayList<T>());
 
             if (credClass == KeyTab.class) {
-                // TODO: There is currently no good way to filter out keytabs
-                // not for serverPrincipal. We can only check the principal
-                // set. If the server is not there, we can be sure none of the
-                // keytabs should be used, otherwise, use all for safety.
-                boolean useAll = false;
-                if (serverPrincipal != null) {
-                    for (KerberosPrincipal princ:
-                            subject.getPrincipals(KerberosPrincipal.class)) {
-                        if (princ.getName().equals(serverPrincipal)) {
-                            useAll = true;
-                            break;
+                Iterator<KeyTab> iterator =
+                    subject.getPrivateCredentials(KeyTab.class).iterator();
+                while (iterator.hasNext()) {
+                    KeyTab t = iterator.next();
+                    if (serverPrincipal != null && t.isBound()) {
+                        KerberosPrincipal name = t.getPrincipal();
+                        if (name != null) {
+                            if (!serverPrincipal.equals(name.getName())) {
+                                continue;
+                            }
+                        } else {
+                            // legacy bound keytab. although we don't know who
+                            // the bound principal is, it must be in allPrincs
+                            boolean found = false;
+                            for (KerberosPrincipal princ:
+                                    subject.getPrincipals(KerberosPrincipal.class)) {
+                                if (princ.getName().equals(serverPrincipal)) {
+                                    found = true;
+                                    break;
+                                }
+                            }
+                            if (!found) continue;
                         }
                     }
-                } else {
-                    useAll = true;
-                }
-                if (useAll) {
-                    Iterator<KeyTab> iterator =
-                        subject.getPrivateCredentials(KeyTab.class).iterator();
-                    while (iterator.hasNext()) {
-                        KeyTab t = iterator.next();
-                        if (DEBUG) {
-                            System.out.println("Found " + credClass.getSimpleName()
-                                    + " " + t);
-                        }
-                        if (oneOnly) {
-                            return t;
-                        } else {
-                            answer.add(credClass.cast(t));
-                        }
+                    // Check passed, we can add now
+                    if (DEBUG) {
+                        System.out.println("Found " + credClass.getSimpleName()
+                                + " " + t);
+                    }
+                    if (oneOnly) {
+                        return t;
+                    } else {
+                        answer.add(credClass.cast(t));
                     }
                 }
             } else if (credClass == KerberosKey.class) {
diff --git a/jdk/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java b/jdk/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
index 3992e48..ae3dc3d 100644
--- a/jdk/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
+++ b/jdk/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
@@ -35,9 +35,8 @@
  */
 public interface JavaxSecurityAuthKerberosAccess {
     /**
-     * Returns keys for a principal in a keytab.
-     * @return the keys, never null, can be empty.
+     * Returns a snapshot to the backing keytab
      */
-    public EncryptionKey[] keyTabGetEncryptionKeys(
-            KeyTab ktab, PrincipalName principal);
+    public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot(
+            KeyTab ktab);
 }
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
index d1023de..b556c90 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
@@ -46,6 +46,7 @@
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import sun.security.jgss.krb5.ServiceCreds;
 
 /**
  * This class represents key table. The key table functions deal with storing
@@ -268,6 +269,15 @@
     }
 
     /**
+     * Returns a principal name in this keytab. Used by
+     * {@link ServiceCreds#getKKeys()}.
+     */
+    public PrincipalName getOneName() {
+        int size = entries.size();
+        return size > 0 ? entries.elementAt(size-1).service : null;
+    }
+
+    /**
      * Reads all keys for a service from the keytab file that have
      * etypes that have been configured for use. If there are multiple
      * keys with same etype, the one with the highest kvno is returned.
diff --git a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
index d40e033..32f1da5 100644
--- a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
+++ b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
@@ -326,7 +326,7 @@
             DerValue val = new DerValue(encrInfo.getAlgorithm().encode());
             DerInputStream in = val.toDerInputStream();
             algOid = in.getOID();
-            algParams = parseAlgParameters(in);
+            algParams = parseAlgParameters(algOid, in);
 
         } catch (IOException ioe) {
             UnrecoverableKeyException uke =
@@ -342,7 +342,8 @@
                 try {
                     // Use JCE
                     SecretKey skey = getPBEKey(password);
-                    Cipher cipher = Cipher.getInstance(algOid.toString());
+                    Cipher cipher = Cipher.getInstance(
+                        mapPBEParamsToAlgorithm(algOid, algParams));
                     cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
                     keyInfo = cipher.doFinal(encryptedKey);
                     break;
@@ -759,8 +760,8 @@
     /*
      * parse Algorithm Parameters
      */
-    private AlgorithmParameters parseAlgParameters(DerInputStream in)
-        throws IOException
+    private AlgorithmParameters parseAlgParameters(ObjectIdentifier algorithm,
+        DerInputStream in) throws IOException
     {
         AlgorithmParameters algParams = null;
         try {
@@ -774,7 +775,11 @@
                 }
             }
             if (params != null) {
-                algParams = AlgorithmParameters.getInstance("PBE");
+                if (algorithm.equals(pbes2_OID)) {
+                    algParams = AlgorithmParameters.getInstance("PBES2");
+                } else {
+                    algParams = AlgorithmParameters.getInstance("PBE");
+                }
                 algParams.init(params.toByteArray());
             }
         } catch (Exception e) {
@@ -834,13 +839,6 @@
                 } else {
                     algParams = getAlgorithmParameters(algorithm);
                 }
-                ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
-                if (pbeOID != null) {
-                    algid = new AlgorithmId(pbeOID, algParams);
-                } else {
-                    throw new IOException("PBE algorithm '" + algorithm +
-                        " 'is not supported for key entry protection");
-                }
             } else {
                 // Check default key protection algorithm for PKCS12 keystores
                 algorithm = AccessController.doPrivileged(
@@ -856,12 +854,16 @@
                             return prop;
                         }
                     });
-                if (algorithm == null) {
+                if (algorithm == null || algorithm.isEmpty()) {
                     algorithm = "PBEWithSHA1AndDESede";
                 }
                 algParams = getAlgorithmParameters(algorithm);
-                algid = new AlgorithmId(pbeWithSHAAnd3KeyTripleDESCBC_OID,
-                    algParams);
+            }
+
+            ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
+            if (pbeOID == null) {
+                    throw new IOException("PBE algorithm '" + algorithm +
+                        " 'is not supported for key entry protection");
             }
 
             // Use JCE
@@ -869,6 +871,7 @@
             Cipher cipher = Cipher.getInstance(algorithm);
             cipher.init(Cipher.ENCRYPT_MODE, skey, algParams);
             byte[] encryptedKey = cipher.doFinal(data);
+            algid = new AlgorithmId(pbeOID, cipher.getParameters());
 
             if (debug != null) {
                 debug.println("  (Cipher algorithm: " + cipher.getAlgorithm() +
@@ -894,7 +897,7 @@
     /*
      * Map a PBE algorithm name onto its object identifier
      */
-    private ObjectIdentifier mapPBEAlgorithmToOID(String algorithm)
+    private static ObjectIdentifier mapPBEAlgorithmToOID(String algorithm)
         throws NoSuchAlgorithmException {
         // Check for PBES2 algorithms
         if (algorithm.toLowerCase().startsWith("pbewithhmacsha")) {
@@ -903,6 +906,18 @@
         return AlgorithmId.get(algorithm).getOID();
     }
 
+    /*
+     * Map a PBE algorithm parameters onto its algorithm name
+     */
+    private static String mapPBEParamsToAlgorithm(ObjectIdentifier algorithm,
+        AlgorithmParameters algParams) throws NoSuchAlgorithmException {
+        // Check for PBES2 algorithms
+        if (algorithm.equals(pbes2_OID) && algParams != null) {
+            return algParams.toString();
+        }
+        return algorithm.toString();
+    }
+
     /**
      * Assigns the given certificate to the given alias.
      *
@@ -1933,7 +1948,7 @@
                 // parse Algorithm parameters
                 DerInputStream in = seq[1].toDerInputStream();
                 ObjectIdentifier algOid = in.getOID();
-                AlgorithmParameters algParams = parseAlgParameters(in);
+                AlgorithmParameters algParams = parseAlgParameters(algOid, in);
 
                 while (true) {
                     try {
diff --git a/jdk/src/share/classes/sun/security/provider/ConfigSpiFile.java b/jdk/src/share/classes/sun/security/provider/ConfigSpiFile.java
index 3a9ca47..03cdc57 100644
--- a/jdk/src/share/classes/sun/security/provider/ConfigSpiFile.java
+++ b/jdk/src/share/classes/sun/security/provider/ConfigSpiFile.java
@@ -404,6 +404,7 @@
         st.wordChars('$', '$');
         st.wordChars('_', '_');
         st.wordChars('-', '-');
+        st.wordChars('*', '*');
         st.lowerCaseMode(false);
         st.slashSlashComments(true);
         st.slashStarComments(true);
diff --git a/jdk/src/share/classes/sun/security/provider/DomainKeyStore.java b/jdk/src/share/classes/sun/security/provider/DomainKeyStore.java
new file mode 100644
index 0000000..ae0dbfb
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/provider/DomainKeyStore.java
@@ -0,0 +1,900 @@
+/*
+ * 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.  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.provider;
+
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateException;
+import java.util.*;
+
+import sun.misc.IOUtils;
+import sun.security.pkcs.EncryptedPrivateKeyInfo;
+import sun.security.util.PolicyUtil;
+
+/**
+ * This class provides the domain keystore type identified as "DKS".
+ * DKS presents a collection of separate keystores as a single logical keystore.
+ * The collection of keystores is specified in a domain configuration file which
+ * is passed to DKS in a {@link KeyStore.DomainLoadStoreParameter}.
+ * <p>
+ * The following properties are supported:
+ * <dl>
+ * <dt> {@code keystoreType="<type>"} </dt>
+ *     <dd> The keystore type. </dd>
+ * <dt> {@code keystoreURI="<url>"} </dt>
+ *     <dd> The keystore location. </dd>
+ * <dt> {@code keystoreProviderName="<name>"} </dt>
+ *     <dd> The name of the keystore's JCE provider. </dd>
+ * <dt> {@code keystorePasswordEnv="<environment-variable>"} </dt>
+ *     <dd> The environment variable that stores a keystore password.
+ * <dt> {@code entryNameSeparator="<separator>"} </dt>
+ *     <dd> The separator between a keystore name prefix and an entry name.
+ *          When specified, it applies to all the entries in a domain.
+ *          Its default value is a space. </dd>
+ * </dl>
+ *
+ * @since 1.8
+ */
+
+abstract class DomainKeyStore extends KeyStoreSpi {
+
+    // regular DKS
+    public static final class DKS extends DomainKeyStore {
+        String convertAlias(String alias) {
+            return alias.toLowerCase(Locale.ENGLISH);
+        }
+    }
+
+    // DKS property names
+    private static final String ENTRY_NAME_SEPARATOR = "entrynameseparator";
+    private static final String KEYSTORE_PROVIDER_NAME = "keystoreprovidername";
+    private static final String KEYSTORE_TYPE = "keystoretype";
+    private static final String KEYSTORE_URI = "keystoreuri";
+    private static final String KEYSTORE_PASSWORD_ENV = "keystorepasswordenv";
+
+    // RegEx meta characters
+    private static final String REGEX_META = ".$|()[{^?*+\\";
+
+    // Default prefix for keystores loaded-by-stream
+    private static final String DEFAULT_STREAM_PREFIX = "iostream";
+    private int streamCounter = 1;
+    private String entryNameSeparator = " ";
+    private String entryNameSeparatorRegEx = " ";
+
+    // Default keystore type
+    private static final String DEFAULT_KEYSTORE_TYPE =
+        KeyStore.getDefaultType();
+
+    // Domain keystores
+    private final Map<String, KeyStore> keystores = new HashMap<>();
+
+    DomainKeyStore() {
+    }
+
+    // convert an alias to internal form, overridden in subclasses:
+    // lower case for regular DKS
+    abstract String convertAlias(String alias);
+
+    /**
+     * Returns the key associated with the given alias, using the given
+     * password to recover it.
+     *
+     * @param alias the alias name
+     * @param password the password for recovering the key
+     *
+     * @return the requested key, or null if the given alias does not exist
+     * or does not identify a <i>key entry</i>.
+     *
+     * @exception NoSuchAlgorithmException if the algorithm for recovering the
+     * key cannot be found
+     * @exception UnrecoverableKeyException if the key cannot be recovered
+     * (e.g., the given password is wrong).
+     */
+    public Key engineGetKey(String alias, char[] password)
+        throws NoSuchAlgorithmException, UnrecoverableKeyException
+    {
+        AbstractMap.SimpleEntry<String, Collection<KeyStore>> pair =
+            getKeystoresForReading(alias);
+        Key key = null;
+
+        try {
+            String entryAlias = pair.getKey();
+            for (KeyStore keystore : pair.getValue()) {
+                key = keystore.getKey(entryAlias, password);
+                if (key != null) {
+                    break;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return key;
+    }
+
+    /**
+     * Returns the certificate chain associated with the given alias.
+     *
+     * @param alias the alias name
+     *
+     * @return the certificate chain (ordered with the user's certificate first
+     * and the root certificate authority last), or null if the given alias
+     * does not exist or does not contain a certificate chain (i.e., the given
+     * alias identifies either a <i>trusted certificate entry</i> or a
+     * <i>key entry</i> without a certificate chain).
+     */
+    public Certificate[] engineGetCertificateChain(String alias) {
+
+        AbstractMap.SimpleEntry<String, Collection<KeyStore>> pair =
+            getKeystoresForReading(alias);
+        Certificate[] chain = null;
+
+        try {
+            String entryAlias = pair.getKey();
+            for (KeyStore keystore : pair.getValue()) {
+                chain = keystore.getCertificateChain(entryAlias);
+                if (chain != null) {
+                    break;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return chain;
+    }
+
+    /**
+     * Returns the certificate associated with the given alias.
+     *
+     * <p>If the given alias name identifies a
+     * <i>trusted certificate entry</i>, the certificate associated with that
+     * entry is returned. If the given alias name identifies a
+     * <i>key entry</i>, the first element of the certificate chain of that
+     * entry is returned, or null if that entry does not have a certificate
+     * chain.
+     *
+     * @param alias the alias name
+     *
+     * @return the certificate, or null if the given alias does not exist or
+     * does not contain a certificate.
+     */
+    public Certificate engineGetCertificate(String alias) {
+
+        AbstractMap.SimpleEntry<String, Collection<KeyStore>> pair =
+            getKeystoresForReading(alias);
+        Certificate cert = null;
+
+        try {
+            String entryAlias = pair.getKey();
+            for (KeyStore keystore : pair.getValue()) {
+                cert = keystore.getCertificate(entryAlias);
+                if (cert != null) {
+                    break;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return cert;
+    }
+
+    /**
+     * Returns the creation date of the entry identified by the given alias.
+     *
+     * @param alias the alias name
+     *
+     * @return the creation date of this entry, or null if the given alias does
+     * not exist
+     */
+    public Date engineGetCreationDate(String alias) {
+
+        AbstractMap.SimpleEntry<String, Collection<KeyStore>> pair =
+            getKeystoresForReading(alias);
+        Date date = null;
+
+        try {
+            String entryAlias = pair.getKey();
+            for (KeyStore keystore : pair.getValue()) {
+                date = keystore.getCreationDate(entryAlias);
+                if (date != null) {
+                    break;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return date;
+    }
+
+    /**
+     * Assigns the given private key to the given alias, protecting
+     * it with the given password as defined in PKCS8.
+     *
+     * <p>The given java.security.PrivateKey <code>key</code> must
+     * be accompanied by a certificate chain certifying the
+     * corresponding public key.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key and certificate
+     * chain.
+     *
+     * @param alias the alias name
+     * @param key the private key to be associated with the alias
+     * @param password the password to protect the key
+     * @param chain the certificate chain for the corresponding public
+     * key (only required if the given key is of type
+     * <code>java.security.PrivateKey</code>).
+     *
+     * @exception KeyStoreException if the given key is not a private key,
+     * cannot be protected, or this operation fails for some other reason
+     */
+    public void engineSetKeyEntry(String alias, Key key, char[] password,
+                                  Certificate[] chain)
+        throws KeyStoreException
+    {
+        AbstractMap.SimpleEntry<String,
+            AbstractMap.SimpleEntry<String, KeyStore>> pair =
+                getKeystoreForWriting(alias);
+
+        if (pair == null) {
+            throw new KeyStoreException("Error setting key entry for '" +
+                alias + "'");
+        }
+        String entryAlias = pair.getKey();
+        Map.Entry<String, KeyStore> keystore = pair.getValue();
+        keystore.getValue().setKeyEntry(entryAlias, key, password, chain);
+    }
+
+    /**
+     * Assigns the given key (that has already been protected) to the given
+     * alias.
+     *
+     * <p>If the protected key is of type
+     * <code>java.security.PrivateKey</code>, it must be accompanied by a
+     * certificate chain certifying the corresponding public key. If the
+     * underlying keystore implementation is of type <code>jks</code>,
+     * <code>key</code> must be encoded as an
+     * <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key (and possibly
+     * certificate chain).
+     *
+     * @param alias the alias name
+     * @param key the key (in protected format) to be associated with the alias
+     * @param chain the certificate chain for the corresponding public
+     * key (only useful if the protected key is of type
+     * <code>java.security.PrivateKey</code>).
+     *
+     * @exception KeyStoreException if this operation fails.
+     */
+    public void engineSetKeyEntry(String alias, byte[] key,
+                                  Certificate[] chain)
+        throws KeyStoreException
+    {
+        AbstractMap.SimpleEntry<String,
+            AbstractMap.SimpleEntry<String, KeyStore>> pair =
+                getKeystoreForWriting(alias);
+
+        if (pair == null) {
+            throw new KeyStoreException(
+                "Error setting protected key entry for '" + alias + "'");
+        }
+        String entryAlias = pair.getKey();
+        Map.Entry<String, KeyStore> keystore = pair.getValue();
+        keystore.getValue().setKeyEntry(entryAlias, key, chain);
+    }
+
+    /**
+     * Assigns the given certificate to the given alias.
+     *
+     * <p>If the given alias already exists in this keystore and identifies a
+     * <i>trusted certificate entry</i>, the certificate associated with it is
+     * overridden by the given certificate.
+     *
+     * @param alias the alias name
+     * @param cert the certificate
+     *
+     * @exception KeyStoreException if the given alias already exists and does
+     * not identify a <i>trusted certificate entry</i>, or this operation
+     * fails for some other reason.
+     */
+    public void engineSetCertificateEntry(String alias, Certificate cert)
+        throws KeyStoreException
+    {
+        AbstractMap.SimpleEntry<String,
+            AbstractMap.SimpleEntry<String, KeyStore>> pair =
+                getKeystoreForWriting(alias);
+
+        if (pair == null) {
+            throw new KeyStoreException("Error setting certificate entry for '"
+                + alias + "'");
+        }
+        String entryAlias = pair.getKey();
+        Map.Entry<String, KeyStore> keystore = pair.getValue();
+        keystore.getValue().setCertificateEntry(entryAlias, cert);
+    }
+
+    /**
+     * Deletes the entry identified by the given alias from this keystore.
+     *
+     * @param alias the alias name
+     *
+     * @exception KeyStoreException if the entry cannot be removed.
+     */
+    public void engineDeleteEntry(String alias) throws KeyStoreException
+    {
+        AbstractMap.SimpleEntry<String,
+            AbstractMap.SimpleEntry<String, KeyStore>> pair =
+                getKeystoreForWriting(alias);
+
+        if (pair == null) {
+            throw new KeyStoreException("Error deleting entry for '" + alias +
+                "'");
+        }
+        String entryAlias = pair.getKey();
+        Map.Entry<String, KeyStore> keystore = pair.getValue();
+        keystore.getValue().deleteEntry(entryAlias);
+    }
+
+    /**
+     * Lists all the alias names of this keystore.
+     *
+     * @return enumeration of the alias names
+     */
+    public Enumeration<String> engineAliases() {
+        final Iterator<Map.Entry<String, KeyStore>> iterator =
+            keystores.entrySet().iterator();
+
+        return new Enumeration<String>() {
+            private int index = 0;
+            private Map.Entry<String, KeyStore> keystoresEntry = null;
+            private String prefix = null;
+            private Enumeration<String> aliases = null;
+
+            public boolean hasMoreElements() {
+                try {
+                    if (aliases == null) {
+                        if (iterator.hasNext()) {
+                            keystoresEntry = iterator.next();
+                            prefix = keystoresEntry.getKey() +
+                                entryNameSeparator;
+                            aliases = keystoresEntry.getValue().aliases();
+                        } else {
+                            return false;
+                        }
+                    }
+                    if (aliases.hasMoreElements()) {
+                        return true;
+                    } else {
+                        if (iterator.hasNext()) {
+                            keystoresEntry = iterator.next();
+                            prefix = keystoresEntry.getKey() +
+                                entryNameSeparator;
+                            aliases = keystoresEntry.getValue().aliases();
+                        } else {
+                            return false;
+                        }
+                    }
+                } catch (KeyStoreException e) {
+                    return false;
+                }
+
+                return aliases.hasMoreElements();
+            }
+
+            public String nextElement() {
+                if (hasMoreElements()) {
+                    return prefix + aliases.nextElement();
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+
+    /**
+     * Checks if the given alias exists in this keystore.
+     *
+     * @param alias the alias name
+     *
+     * @return true if the alias exists, false otherwise
+     */
+    public boolean engineContainsAlias(String alias) {
+
+        AbstractMap.SimpleEntry<String, Collection<KeyStore>> pair =
+            getKeystoresForReading(alias);
+
+        try {
+            String entryAlias = pair.getKey();
+            for (KeyStore keystore : pair.getValue()) {
+                if (keystore.containsAlias(entryAlias)) {
+                    return true;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return false;
+    }
+
+    /**
+     * Retrieves the number of entries in this keystore.
+     *
+     * @return the number of entries in this keystore
+     */
+    public int engineSize() {
+
+        int size = 0;
+        try {
+            for (KeyStore keystore : keystores.values()) {
+                size += keystore.size();
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return size;
+    }
+
+    /**
+     * Returns true if the entry identified by the given alias is a
+     * <i>key entry</i>, and false otherwise.
+     *
+     * @return true if the entry identified by the given alias is a
+     * <i>key entry</i>, false otherwise.
+     */
+    public boolean engineIsKeyEntry(String alias) {
+
+        AbstractMap.SimpleEntry<String, Collection<KeyStore>> pair =
+            getKeystoresForReading(alias);
+
+        try {
+            String entryAlias = pair.getKey();
+            for (KeyStore keystore : pair.getValue()) {
+                if (keystore.isKeyEntry(entryAlias)) {
+                    return true;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true if the entry identified by the given alias is a
+     * <i>trusted certificate entry</i>, and false otherwise.
+     *
+     * @return true if the entry identified by the given alias is a
+     * <i>trusted certificate entry</i>, false otherwise.
+     */
+    public boolean engineIsCertificateEntry(String alias) {
+
+        AbstractMap.SimpleEntry<String, Collection<KeyStore>> pair =
+            getKeystoresForReading(alias);
+
+        try {
+            String entryAlias = pair.getKey();
+            for (KeyStore keystore : pair.getValue()) {
+                if (keystore.isCertificateEntry(entryAlias)) {
+                    return true;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return false;
+    }
+
+    /*
+     * Returns a keystore entry alias and a list of target keystores.
+     * When the supplied alias prefix identifies a keystore then that single
+     * keystore is returned. When no alias prefix is supplied then all the
+     * keystores are returned.
+     */
+    private AbstractMap.SimpleEntry<String, Collection<KeyStore>>
+        getKeystoresForReading(String alias) {
+
+        String[] splits = alias.split(this.entryNameSeparatorRegEx, 2);
+        if (splits.length == 2) { // prefixed alias
+            KeyStore keystore = keystores.get(splits[0]);
+            if (keystore != null) {
+                return new AbstractMap.SimpleEntry<>(splits[1],
+                    (Collection<KeyStore>) Collections.singleton(keystore));
+            }
+        } else if (splits.length == 1) { // unprefixed alias
+            // Check all keystores for the first occurrence of the alias
+            return new AbstractMap.SimpleEntry<>(alias, keystores.values());
+        }
+        return new AbstractMap.SimpleEntry<>("",
+            (Collection<KeyStore>) Collections.<KeyStore>emptyList());
+    }
+
+    /*
+     * Returns a keystore entry alias and a single target keystore.
+     * An alias prefix must be supplied.
+     */
+    private
+    AbstractMap.SimpleEntry<String, AbstractMap.SimpleEntry<String, KeyStore>>
+        getKeystoreForWriting(String alias) {
+
+        String[] splits = alias.split(this.entryNameSeparator, 2);
+        if (splits.length == 2) { // prefixed alias
+            KeyStore keystore = keystores.get(splits[0]);
+            if (keystore != null) {
+                return new AbstractMap.SimpleEntry<>(splits[1],
+                    new AbstractMap.SimpleEntry<>(splits[0], keystore));
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the (alias) name of the first keystore entry whose certificate
+     * matches the given certificate.
+     *
+     * <p>This method attempts to match the given certificate with each
+     * keystore entry. If the entry being considered
+     * is a <i>trusted certificate entry</i>, the given certificate is
+     * compared to that entry's certificate. If the entry being considered is
+     * a <i>key entry</i>, the given certificate is compared to the first
+     * element of that entry's certificate chain (if a chain exists).
+     *
+     * @param cert the certificate to match with.
+     *
+     * @return the (alias) name of the first entry with matching certificate,
+     * or null if no such entry exists in this keystore.
+     */
+    public String engineGetCertificateAlias(Certificate cert) {
+
+        try {
+
+            String alias = null;
+            for (KeyStore keystore : keystores.values()) {
+                if ((alias = keystore.getCertificateAlias(cert)) != null) {
+                    break;
+                }
+            }
+            return alias;
+
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /**
+     * Stores this keystore to the given output stream, and protects its
+     * integrity with the given password.
+     *
+     * @param stream the output stream to which this keystore is written.
+     * @param password the password to generate the keystore integrity check
+     *
+     * @exception IOException if there was an I/O problem with data
+     * @exception NoSuchAlgorithmException if the appropriate data integrity
+     * algorithm could not be found
+     * @exception CertificateException if any of the certificates included in
+     * the keystore data could not be stored
+     */
+    public void engineStore(OutputStream stream, char[] password)
+        throws IOException, NoSuchAlgorithmException, CertificateException
+    {
+        // Support storing to a stream only when a single keystore has been
+        // configured
+        try {
+            if (keystores.size() == 1) {
+                keystores.values().iterator().next().store(stream, password);
+                return;
+            }
+        } catch (KeyStoreException e) {
+            throw new IllegalStateException(e);
+        }
+
+        throw new UnsupportedOperationException(
+            "This keystore must be stored using a " +
+            "KeyStore.DomainLoadStoreParameter");
+    }
+
+    @Override
+    public void engineStore(KeyStore.LoadStoreParameter param)
+        throws IOException, NoSuchAlgorithmException, CertificateException
+    {
+        if (param instanceof KeyStore.DomainLoadStoreParameter) {
+            KeyStore.DomainLoadStoreParameter domainParameter =
+                (KeyStore.DomainLoadStoreParameter) param;
+            List<KeyStoreBuilderComponents> builders = getBuilders(
+                domainParameter.getConfiguration(),
+                    domainParameter.getProtectionParams());
+
+            for (KeyStoreBuilderComponents builder : builders) {
+
+                try {
+
+                    KeyStore.ProtectionParameter pp = builder.protection;
+                    if (!(pp instanceof KeyStore.PasswordProtection)) {
+                        throw new KeyStoreException(
+                            new IllegalArgumentException("ProtectionParameter" +
+                                " must be a KeyStore.PasswordPartection"));
+                    }
+                    char[] password =
+                        ((KeyStore.PasswordProtection) builder.protection)
+                            .getPassword();
+
+                    // Store the keystores
+                    KeyStore keystore = keystores.get(builder.name);
+                    keystore.store(new FileOutputStream(builder.file),
+                        password);
+
+                } catch (KeyStoreException e) {
+                    throw new IOException(e);
+                }
+            }
+        } else {
+            throw new UnsupportedOperationException(
+                "This keystore must be stored using a " +
+                "KeyStore.DomainLoadStoreParameter");
+        }
+    }
+
+    /**
+     * Loads the keystore from the given input stream.
+     *
+     * <p>If a password is given, it is used to check the integrity of the
+     * keystore data. Otherwise, the integrity of the keystore is not checked.
+     *
+     * @param stream the input stream from which the keystore is loaded
+     * @param password the (optional) password used to check the integrity of
+     * the keystore.
+     *
+     * @exception IOException if there is an I/O or format problem with the
+     * keystore data
+     * @exception NoSuchAlgorithmException if the algorithm used to check
+     * the integrity of the keystore cannot be found
+     * @exception CertificateException if any of the certificates in the
+     * keystore could not be loaded
+     */
+    public void engineLoad(InputStream stream, char[] password)
+        throws IOException, NoSuchAlgorithmException, CertificateException
+    {
+        // Support loading from a stream only for a JKS or default type keystore
+        try {
+            KeyStore keystore = null;
+
+            try {
+                keystore = KeyStore.getInstance("JKS");
+                keystore.load(stream, password);
+
+            } catch (Exception e) {
+                // Retry
+                if (!"JKS".equalsIgnoreCase(DEFAULT_KEYSTORE_TYPE)) {
+                    keystore = KeyStore.getInstance(DEFAULT_KEYSTORE_TYPE);
+                    keystore.load(stream, password);
+                } else {
+                    throw e;
+                }
+            }
+            String keystoreName = DEFAULT_STREAM_PREFIX + streamCounter++;
+            keystores.put(keystoreName, keystore);
+
+        } catch (Exception e) {
+            throw new UnsupportedOperationException(
+                "This keystore must be loaded using a " +
+                "KeyStore.DomainLoadStoreParameter");
+        }
+    }
+
+    @Override
+    public void engineLoad(KeyStore.LoadStoreParameter param)
+        throws IOException, NoSuchAlgorithmException, CertificateException
+    {
+        if (param instanceof KeyStore.DomainLoadStoreParameter) {
+            KeyStore.DomainLoadStoreParameter domainParameter =
+                (KeyStore.DomainLoadStoreParameter) param;
+            List<KeyStoreBuilderComponents> builders = getBuilders(
+                domainParameter.getConfiguration(),
+                    domainParameter.getProtectionParams());
+
+            for (KeyStoreBuilderComponents builder : builders) {
+
+                try {
+                    // Load the keystores (file-based and non-file-based)
+                    if (builder.file != null) {
+                        keystores.put(builder.name,
+                            KeyStore.Builder.newInstance(builder.type,
+                                builder.provider, builder.file,
+                                builder.protection)
+                                    .getKeyStore());
+                    } else {
+                        keystores.put(builder.name,
+                            KeyStore.Builder.newInstance(builder.type,
+                                builder.provider, builder.protection)
+                                    .getKeyStore());
+                    }
+                } catch (KeyStoreException e) {
+                    throw new IOException(e);
+                }
+            }
+        } else {
+            throw new UnsupportedOperationException(
+                "This keystore must be loaded using a " +
+                "KeyStore.DomainLoadStoreParameter");
+        }
+    }
+
+    /*
+     * Parse a keystore domain configuration file and associated collection
+     * of keystore passwords to create a collection of KeyStore.Builder.
+     */
+    private List<KeyStoreBuilderComponents> getBuilders(URI configuration,
+        Map<String, KeyStore.ProtectionParameter> passwords)
+            throws IOException {
+
+        PolicyParser parser = new PolicyParser(true); // expand properties
+        Collection<PolicyParser.DomainEntry> domains = null;
+        List<KeyStoreBuilderComponents> builders = new ArrayList<>();
+        String uriDomain = configuration.getFragment();
+
+        try (InputStreamReader configurationReader =
+            new InputStreamReader(
+                PolicyUtil.getInputStream(configuration.toURL()), "UTF-8")) {
+            parser.read(configurationReader);
+            domains = parser.getDomainEntries();
+
+        } catch (MalformedURLException mue) {
+            throw new IOException(mue);
+
+        } catch (PolicyParser.ParsingException pe) {
+            throw new IOException(pe);
+        }
+
+        for (PolicyParser.DomainEntry domain : domains) {
+            Map<String, String> domainProperties = domain.getProperties();
+
+            if (uriDomain != null &&
+                (!uriDomain.equalsIgnoreCase(domain.getName()))) {
+                continue; // skip this domain
+            }
+
+            if (domainProperties.containsKey(ENTRY_NAME_SEPARATOR)) {
+                this.entryNameSeparator =
+                    domainProperties.get(ENTRY_NAME_SEPARATOR);
+                // escape any regex meta characters
+                char ch = 0;
+                StringBuilder s = new StringBuilder();
+                for (int i = 0; i < this.entryNameSeparator.length(); i++) {
+                    ch = this.entryNameSeparator.charAt(i);
+                    if (REGEX_META.indexOf(ch) != -1) {
+                        s.append('\\');
+                    }
+                    s.append(ch);
+                }
+                this.entryNameSeparatorRegEx = s.toString();
+            }
+
+            Collection<PolicyParser.KeyStoreEntry> keystores =
+                domain.getEntries();
+            for (PolicyParser.KeyStoreEntry keystore : keystores) {
+                String keystoreName = keystore.getName();
+                Map<String, String> properties =
+                    new HashMap<>(domainProperties);
+                properties.putAll(keystore.getProperties());
+
+                String keystoreType = DEFAULT_KEYSTORE_TYPE;
+                if (properties.containsKey(KEYSTORE_TYPE)) {
+                    keystoreType = properties.get(KEYSTORE_TYPE);
+                }
+
+                Provider keystoreProvider = null;
+                if (properties.containsKey(KEYSTORE_PROVIDER_NAME)) {
+                    String keystoreProviderName =
+                        properties.get(KEYSTORE_PROVIDER_NAME);
+                    keystoreProvider =
+                        Security.getProvider(keystoreProviderName);
+                    if (keystoreProvider == null) {
+                        throw new IOException("Error locating JCE provider: " +
+                            keystoreProviderName);
+                    }
+                }
+
+                File keystoreFile = null;
+                if (properties.containsKey(KEYSTORE_URI)) {
+                    String uri = properties.get(KEYSTORE_URI);
+
+                    try {
+                        if (uri.startsWith("file://")) {
+                            keystoreFile = new File(new URI(uri));
+                        } else {
+                            keystoreFile = new File(uri);
+                        }
+
+                    } catch (URISyntaxException | IllegalArgumentException e) {
+                        throw new IOException(
+                            "Error processing keystore property: " +
+                                "keystoreURI=\"" + uri + "\"", e);
+                    }
+                }
+
+                KeyStore.ProtectionParameter keystoreProtection = null;
+                if (passwords.containsKey(keystoreName)) {
+                    keystoreProtection = passwords.get(keystoreName);
+
+                } else if (properties.containsKey(KEYSTORE_PASSWORD_ENV)) {
+                    String env = properties.get(KEYSTORE_PASSWORD_ENV);
+                    String pwd = System.getenv(env);
+                    if (pwd != null) {
+                        keystoreProtection =
+                            new KeyStore.PasswordProtection(pwd.toCharArray());
+                    } else {
+                        throw new IOException(
+                            "Error processing keystore property: " +
+                                "keystorePasswordEnv=\"" + env + "\"");
+                    }
+                } else {
+                    keystoreProtection = new KeyStore.PasswordProtection(null);
+                }
+
+                builders.add(new KeyStoreBuilderComponents(keystoreName,
+                    keystoreType, keystoreProvider, keystoreFile,
+                    keystoreProtection));
+            }
+            break; // skip other domains
+        }
+        if (builders.isEmpty()) {
+            throw new IOException("Error locating domain configuration data " +
+                "for: " + configuration);
+        }
+
+        return builders;
+    }
+
+/*
+ * Utility class that holds the components used to construct a KeyStore.Builder
+ */
+class KeyStoreBuilderComponents {
+    String name;
+    String type;
+    Provider provider;
+    File file;
+    KeyStore.ProtectionParameter protection;
+
+    KeyStoreBuilderComponents(String name, String type, Provider provider,
+        File file, KeyStore.ProtectionParameter protection) {
+        this.name = name;
+        this.type = type;
+        this.provider = provider;
+        this.file = file;
+        this.protection = protection;
+    }
+}
+}
diff --git a/jdk/src/share/classes/sun/security/provider/PolicyParser.java b/jdk/src/share/classes/sun/security/provider/PolicyParser.java
index b5247c7..b13345f 100644
--- a/jdk/src/share/classes/sun/security/provider/PolicyParser.java
+++ b/jdk/src/share/classes/sun/security/provider/PolicyParser.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -32,12 +32,7 @@
 import java.security.GeneralSecurityException;
 import java.security.Principal;
 import java.text.MessageFormat;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Vector;
-import java.util.StringTokenizer;
+import java.util.*;
 import javax.security.auth.x500.X500Principal;
 
 import sun.security.util.Debug;
@@ -97,6 +92,7 @@
 
 
     private Vector<GrantEntry> grantEntries;
+    private Map<String, DomainEntry> domainEntries;
 
     // Convenience variables for parsing
     private static final Debug debug = Debug.getInstance("parser",
@@ -195,9 +191,10 @@
          */
 
         lookahead = st.nextToken();
+        GrantEntry ge = null;
         while (lookahead != StreamTokenizer.TT_EOF) {
             if (peek("grant")) {
-                GrantEntry ge = parseGrantEntry();
+                ge = parseGrantEntry();
                 // could be null if we couldn't expand a property
                 if (ge != null)
                     add(ge);
@@ -209,6 +206,24 @@
                 // only one keystore passwordURL per policy file, others will be
                 // ignored
                 parseStorePassURL();
+            } else if (ge == null && keyStoreUrlString == null &&
+                storePassURL == null && peek("domain")) {
+                if (domainEntries == null) {
+                    domainEntries = new TreeMap<>();
+                }
+                DomainEntry de = parseDomainEntry();
+                if (de != null) {
+                    String domainName = de.getName();
+                    if (!domainEntries.containsKey(domainName)) {
+                        domainEntries.put(domainName, de);
+                    } else {
+                        MessageFormat form =
+                            new MessageFormat(ResourcesMgr.getString(
+                                "duplicate.keystore.domain.name"));
+                        Object[] source = {domainName};
+                        throw new ParsingException(form.format(source));
+                    }
+                }
             } else {
                 // error?
             }
@@ -304,6 +319,10 @@
         return grantEntries.elements();
     }
 
+    public Collection<DomainEntry> getDomainEntries() {
+        return domainEntries.values();
+    }
+
     /**
      * write out the policy
      */
@@ -633,6 +652,67 @@
         return e;
     }
 
+    /**
+     * parse a domain entry
+     */
+    private DomainEntry parseDomainEntry()
+        throws ParsingException, IOException
+    {
+        boolean ignoreEntry = false;
+        DomainEntry domainEntry;
+        String name = null;
+        Map<String, String> properties = new HashMap<>();
+
+        match("domain");
+        name = match("domain name");
+
+        while(!peek("{")) {
+            // get the domain properties
+            properties = parseProperties("{");
+        }
+        match("{");
+        domainEntry = new DomainEntry(name, properties);
+
+        while(!peek("}")) {
+
+            match("keystore");
+            name = match("keystore name");
+            // get the keystore properties
+            if (!peek("}")) {
+                properties = parseProperties(";");
+            }
+            match(";");
+            domainEntry.add(new KeyStoreEntry(name, properties));
+        }
+        match("}");
+
+        return (ignoreEntry == true) ? null : domainEntry;
+    }
+
+    /*
+     * Return a collection of domain properties or keystore properties.
+     */
+    private Map<String, String> parseProperties(String terminator)
+        throws ParsingException, IOException {
+
+        Map<String, String> properties = new HashMap<>();
+        String key;
+        String value;
+        while (!peek(terminator)) {
+            key = match("property name");
+            match("=");
+
+            try {
+                value = expand(match("quoted string"));
+            } catch (PropertyExpander.ExpandException peee) {
+                throw new IOException(peee.getLocalizedMessage());
+            }
+            properties.put(key.toLowerCase(), value);
+        }
+
+        return properties;
+    }
+
     // package-private: used by PolicyFile for static policy
     static String[] parseExtDirs(String codebase, int start) {
 
@@ -708,6 +788,10 @@
             if (expect.equalsIgnoreCase("*"))
                 found = true;
             break;
+        case ';':
+            if (expect.equalsIgnoreCase(";"))
+                found = true;
+            break;
         default:
 
         }
@@ -739,6 +823,11 @@
             } else if (expect.equalsIgnoreCase("principal type")) {
                 value = st.sval;
                 lookahead = st.nextToken();
+            } else if (expect.equalsIgnoreCase("domain name") ||
+                       expect.equalsIgnoreCase("keystore name") ||
+                       expect.equalsIgnoreCase("property name")) {
+                value = st.sval;
+                lookahead = st.nextToken();
             } else {
                  throw new ParsingException(st.lineno(), expect,
                                             st.sval);
@@ -788,6 +877,12 @@
             else
                 throw new ParsingException(st.lineno(), expect, "*");
             break;
+        case '=':
+            if (expect.equalsIgnoreCase("="))
+                lookahead = st.nextToken();
+            else
+                throw new ParsingException(st.lineno(), expect, "=");
+            break;
         default:
             throw new ParsingException(st.lineno(), expect,
                                new String(new char[] {(char)lookahead}));
@@ -1185,6 +1280,108 @@
         }
     }
 
+    /**
+     * Each domain entry in the keystore domain configuration file is
+     * represented by a DomainEntry object.
+     */
+    static class DomainEntry {
+        private final String name;
+        private final Map<String, String> properties;
+        private final Map<String, KeyStoreEntry> entries;
+
+        DomainEntry(String name, Map<String, String> properties) {
+            this.name = name;
+            this.properties = properties;
+            entries = new HashMap<>();
+        }
+
+        String getName() {
+            return name;
+        }
+
+        Map<String, String> getProperties() {
+            return properties;
+        }
+
+        Collection<KeyStoreEntry> getEntries() {
+            return entries.values();
+        }
+
+        void add(KeyStoreEntry entry) throws ParsingException {
+            String keystoreName = entry.getName();
+            if (!entries.containsKey(keystoreName)) {
+                entries.put(keystoreName, entry);
+            } else {
+                MessageFormat form = new MessageFormat(ResourcesMgr.getString(
+                    "duplicate.keystore.name"));
+                Object[] source = {keystoreName};
+                throw new ParsingException(form.format(source));
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder s =
+                new StringBuilder("\ndomain ").append(name);
+
+            if (properties != null) {
+                for (Map.Entry<String, String> property :
+                    properties.entrySet()) {
+                    s.append("\n        ").append(property.getKey()).append('=')
+                        .append(property.getValue());
+                }
+            }
+            s.append(" {\n");
+
+            if (entries != null) {
+                for (KeyStoreEntry entry : entries.values()) {
+                    s.append(entry).append("\n");
+                }
+            }
+            s.append("}");
+
+            return s.toString();
+        }
+    }
+
+    /**
+     * Each keystore entry in the keystore domain configuration file is
+     * represented by a KeyStoreEntry object.
+     */
+
+    static class KeyStoreEntry {
+        private final String name;
+        private final Map<String, String> properties;
+
+        KeyStoreEntry(String name, Map<String, String> properties) {
+            this.name = name;
+            this.properties = properties;
+        }
+
+        String getName() {
+            return name;
+        }
+
+        Map<String, String>  getProperties() {
+            return properties;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder s = new StringBuilder("\n    keystore ").append(name);
+            if (properties != null) {
+                for (Map.Entry<String, String> property :
+                    properties.entrySet()) {
+                    s.append("\n        ").append(property.getKey()).append('=')
+                        .append(property.getValue());
+                }
+            }
+            s.append(";");
+
+            return s.toString();
+        }
+    }
+
     public static class ParsingException extends GeneralSecurityException {
 
         private static final long serialVersionUID = -4330692689482574072L;
diff --git a/jdk/src/share/classes/sun/security/provider/Sun.java b/jdk/src/share/classes/sun/security/provider/Sun.java
index 20edc86..4af2be5 100644
--- a/jdk/src/share/classes/sun/security/provider/Sun.java
+++ b/jdk/src/share/classes/sun/security/provider/Sun.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -40,13 +40,14 @@
 
     private static final String INFO = "SUN " +
     "(DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; " +
-    "SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator; " +
+    "SecureRandom; X.509 certificates; JKS & DKS keystores; " +
+    "PKIX CertPathValidator; " +
     "PKIX CertPathBuilder; LDAP, Collection CertStores, JavaPolicy Policy; " +
     "JavaLoginConfig Configuration)";
 
     public Sun() {
         /* We are the SUN provider */
-        super("SUN", 1.7, INFO);
+        super("SUN", 1.8, INFO);
 
         // if there is no security manager installed, put directly into
         // the provider. Otherwise, create a temporary map and use a
diff --git a/jdk/src/share/classes/sun/security/provider/SunEntries.java b/jdk/src/share/classes/sun/security/provider/SunEntries.java
index 3876acb..daa4e96 100644
--- a/jdk/src/share/classes/sun/security/provider/SunEntries.java
+++ b/jdk/src/share/classes/sun/security/provider/SunEntries.java
@@ -208,6 +208,7 @@
         map.put("KeyStore.JKS", "sun.security.provider.JavaKeyStore$JKS");
         map.put("KeyStore.CaseExactJKS",
                         "sun.security.provider.JavaKeyStore$CaseExactJKS");
+        map.put("KeyStore.DKS", "sun.security.provider.DomainKeyStore$DKS");
 
         /*
          * Policy
diff --git a/jdk/src/share/classes/sun/security/util/Resources.java b/jdk/src/share/classes/sun/security/util/Resources.java
index ef073b0..5002826 100644
--- a/jdk/src/share/classes/sun/security/util/Resources.java
+++ b/jdk/src/share/classes/sun/security/util/Resources.java
@@ -127,6 +127,8 @@
         {"multiple.Codebase.expressions",
                 "multiple Codebase expressions"},
         {"multiple.SignedBy.expressions","multiple SignedBy expressions"},
+        {"duplicate.keystore.domain.name","duplicate keystore domain name: {0}"},
+        {"duplicate.keystore.name","duplicate keystore name: {0}"},
         {"SignedBy.has.empty.alias","SignedBy has empty alias"},
         {"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
                 "can not specify Principal with a wildcard class without a wildcard name"},
diff --git a/jdk/src/share/classes/sun/text/resources/FormatData.java b/jdk/src/share/classes/sun/text/resources/FormatData.java
index f31a1d3..7657633 100644
--- a/jdk/src/share/classes/sun/text/resources/FormatData.java
+++ b/jdk/src/share/classes/sun/text/resources/FormatData.java
@@ -85,14 +85,22 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
-        final String[] buddhistEras = new String[] { // Thai Buddhist calendar era strings
+        // Julian calendar era strings
+        final String[] julianEras = {
+            "BC",
+            "AD"
+        };
+
+        // Thai Buddhist calendar era strings
+        final String[] buddhistEras = {
             "BC",     // BC
             "B.E."    // Buddhist Era
         };
 
         // Japanese imperial calendar era abbreviations
-        final String[] japaneseEraAbbrs = new String[] {
+        final String[] japaneseEraAbbrs = {
             "",
             "M",
             "T",
@@ -100,6 +108,21 @@
             "H",
         };
 
+        // Japanese imperial calendar era strings
+        final String[] japaneseEras = {
+            "",
+            "Meiji",
+            "Taisho",
+            "Showa",
+            "Heisei",
+        };
+
+        // Minguo era strings
+        final String[] rocEras ={
+            "Before R.O.C.",
+            "R.O.C.",
+        };
+
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -181,11 +204,15 @@
                 }
             },
             { "Eras",
-                new String[] { // era strings for GregorianCalendar
-                    "BC",
-                    "AD"
+                julianEras },
+            { "cldr.long.Eras",
+                new String[] {
+                    "Before Christ",
+                    "Anno Domini"
                 }
             },
+            { "cldr.short.Eras",
+                julianEras },
             { "narrow.Eras",
                 new String[] {
                     "B",
@@ -202,19 +229,16 @@
               buddhistEras
             },
             { "japanese.Eras",
-                new String[] { // Japanese imperial calendar era strings
-                    "",
-                    "Meiji",
-                    "Taisho",
-                    "Showa",
-                    "Heisei",
-                }
-            },
+                japaneseEras },
+            { "cldr.japanese.long.Eras",
+                japaneseEras },
+            { "cldr.japanese.short.Eras",
+                japaneseEras },
             { "japanese.short.Eras",
-              japaneseEraAbbrs
+                japaneseEraAbbrs
             },
             { "japanese.narrow.Eras",
-              japaneseEraAbbrs
+                japaneseEraAbbrs
             },
             { "japanese.FirstYear",
                 new String[] { // Japanese imperial calendar year name
@@ -848,12 +872,8 @@
                     "{1} {0}"                  // date-time pattern
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "Before R.O.C.",
-                    "R.O.C.",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "EEEE, G y MMMM dd",
diff --git a/jdk/src/share/classes/sun/text/resources/ar/FormatData_ar.java b/jdk/src/share/classes/sun/text/resources/ar/FormatData_ar.java
index 127c03a..b50abe1 100644
--- a/jdk/src/share/classes/sun/text/resources/ar/FormatData_ar.java
+++ b/jdk/src/share/classes/sun/text/resources/ar/FormatData_ar.java
@@ -85,7 +85,12 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
+        final String[] rocEras = {
+            "Before R.O.C.",
+            "\u062c\u0645\u0647\u0648\u0631\u064a\u0629 \u0627\u0644\u0635\u064a",
+        };
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -211,12 +216,8 @@
                     "d\u200f/M\u200f/y G",
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "Before R.O.C.",
-                    "\u062c\u0645\u0647\u0648\u0631\u064a\u0629 \u0627\u0644\u0635\u064a",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "EEEE\u060c d MMMM\u060c y G",
diff --git a/jdk/src/share/classes/sun/text/resources/el/FormatData_el.java b/jdk/src/share/classes/sun/text/resources/el/FormatData_el.java
index 608ae6d..398bbdd 100644
--- a/jdk/src/share/classes/sun/text/resources/el/FormatData_el.java
+++ b/jdk/src/share/classes/sun/text/resources/el/FormatData_el.java
@@ -85,7 +85,12 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
+        final String[] rocEras = {
+            "\u03a0\u03c1\u03b9\u03bd R.O.C.",
+            "R.O.C.",
+        };
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -230,12 +235,8 @@
                     "d/M/yy",
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "\u03a0\u03c1\u03b9\u03bd R.O.C.",
-                    "R.O.C.",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "EEEE, d MMMM, y G",
diff --git a/jdk/src/share/classes/sun/text/resources/hr/FormatData_hr.java b/jdk/src/share/classes/sun/text/resources/hr/FormatData_hr.java
index ff37b50..8d3a64d 100644
--- a/jdk/src/share/classes/sun/text/resources/hr/FormatData_hr.java
+++ b/jdk/src/share/classes/sun/text/resources/hr/FormatData_hr.java
@@ -82,7 +82,12 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
+        final String[] rocEras ={
+            "prije R.O.C.",
+            "R.O.C.",
+        };
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -266,12 +271,8 @@
                     "d.M.y. G",
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "prije R.O.C.",
-                    "R.O.C.",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "EEEE, d. MMMM y. G",
diff --git a/jdk/src/share/classes/sun/text/resources/ja/FormatData_ja.java b/jdk/src/share/classes/sun/text/resources/ja/FormatData_ja.java
index cbff241..53eba9d 100644
--- a/jdk/src/share/classes/sun/text/resources/ja/FormatData_ja.java
+++ b/jdk/src/share/classes/sun/text/resources/ja/FormatData_ja.java
@@ -82,7 +82,20 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
+        // era strings for Japanese imperial calendar
+        final String[] japaneseEras = {
+            "\u897f\u66a6", // Seireki (Gregorian)
+            "\u660e\u6cbb", // Meiji
+            "\u5927\u6b63", // Taisho
+            "\u662d\u548c", // Showa
+            "\u5e73\u6210", // Heisei
+        };
+        final String[] rocEras = {
+            "\u6c11\u56fd\u524d",
+            "\u6c11\u56fd",
+        };
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -177,15 +190,8 @@
                     "Gy/MM/dd",
                 }
             },
-            { "japanese.Eras",
-                new String[] { // era strings for Japanese imperial calendar
-                    "\u897f\u66a6",     // Seireki (Gregorian)
-                    "\u660e\u6cbb",     // Meiji
-                    "\u5927\u6b63",     // Taisho
-                    "\u662d\u548c",     // Showa
-                    "\u5e73\u6210",     // Heisei
-                }
-            },
+            { "japanese.Eras", japaneseEras },
+            { "cldr.japanese.short.Eras", japaneseEras },
             { "japanese.FirstYear",
                 new String[] {  // first year name
                     "\u5143",   // "Gan"-nen
@@ -257,12 +263,8 @@
                 }
             },
             { "DateTimePatternChars", "GyMdkHmsSEDFwWahKzZ" },
-            { "roc.Eras",
-                new String[] {
-                    "\u6c11\u56fd\u524d",
-                    "\u6c11\u56fd",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "Gy\u5e74M\u6708d\u65e5EEEE",
diff --git a/jdk/src/share/classes/sun/text/resources/ko/FormatData_ko.java b/jdk/src/share/classes/sun/text/resources/ko/FormatData_ko.java
index 6e1b3fb..15872b2 100644
--- a/jdk/src/share/classes/sun/text/resources/ko/FormatData_ko.java
+++ b/jdk/src/share/classes/sun/text/resources/ko/FormatData_ko.java
@@ -82,7 +82,12 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
+        final String[] rocEras = {
+            "\uc911\ud654\ubbfc\uad6d\uc804",
+            "\uc911\ud654\ubbfc\uad6d",
+        };
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -195,12 +200,8 @@
                     "G y. M. d",
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "\uc911\ud654\ubbfc\uad6d\uc804",
-                    "\uc911\ud654\ubbfc\uad6d",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "G y\ub144 M\uc6d4 d\uc77c EEEE",
diff --git a/jdk/src/share/classes/sun/text/resources/sr/FormatData_sr.java b/jdk/src/share/classes/sun/text/resources/sr/FormatData_sr.java
index a190e09..793b00b 100644
--- a/jdk/src/share/classes/sun/text/resources/sr/FormatData_sr.java
+++ b/jdk/src/share/classes/sun/text/resources/sr/FormatData_sr.java
@@ -43,7 +43,12 @@
 import java.util.ListResourceBundle;
 
 public class FormatData_sr extends ListResourceBundle {
+    @Override
     protected final Object[][] getContents() {
+        final String[] rocEras = {
+            "\u041f\u0440\u0435 \u0420\u041a",
+            "\u0420\u041a",
+        };
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -182,12 +187,8 @@
                     "M/d/yy G",
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "\u041f\u0440\u0435 \u0420\u041a",
-                    "\u0420\u041a",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "islamic.MonthNames",
                 new String[] {
                     "\u041c\u0443\u0440\u0430\u0445\u0430\u043c",
diff --git a/jdk/src/share/classes/sun/text/resources/sv/FormatData_sv.java b/jdk/src/share/classes/sun/text/resources/sv/FormatData_sv.java
index 1d555e4..b7ee4e7 100644
--- a/jdk/src/share/classes/sun/text/resources/sv/FormatData_sv.java
+++ b/jdk/src/share/classes/sun/text/resources/sv/FormatData_sv.java
@@ -82,7 +82,12 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
+        final String[] rocEras = {
+            "f\u00f6re R.K.",
+            "R.K.",
+        };
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -250,12 +255,8 @@
                     "G y-MM-dd",
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "f\u00f6re R.K.",
-                    "R.K.",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "EEEE d MMMM y G",
diff --git a/jdk/src/share/classes/sun/text/resources/zh/FormatData_zh.java b/jdk/src/share/classes/sun/text/resources/zh/FormatData_zh.java
index 8e7da48..83e0d78 100644
--- a/jdk/src/share/classes/sun/text/resources/zh/FormatData_zh.java
+++ b/jdk/src/share/classes/sun/text/resources/zh/FormatData_zh.java
@@ -82,7 +82,12 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
+        final String[] rocEras = {
+            "\u6c11\u56fd\u524d",
+            "\u6c11\u56fd",
+        };
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -217,12 +222,8 @@
                     "Gyy-MM-dd",
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "\u6c11\u56fd\u524d",
-                    "\u6c11\u56fd",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "Gy\u5e74M\u6708d\u65e5EEEE",
diff --git a/jdk/src/share/classes/sun/text/resources/zh/FormatData_zh_TW.java b/jdk/src/share/classes/sun/text/resources/zh/FormatData_zh_TW.java
index c7fef5e..7171bd9 100644
--- a/jdk/src/share/classes/sun/text/resources/zh/FormatData_zh_TW.java
+++ b/jdk/src/share/classes/sun/text/resources/zh/FormatData_zh_TW.java
@@ -82,7 +82,12 @@
     /**
      * Overrides ListResourceBundle
      */
+    @Override
     protected final Object[][] getContents() {
+        final String[] rocEras = {
+            "\u6c11\u570b\u524d",
+            "\u6c11\u570b",
+        };
         return new Object[][] {
             { "Eras",
                 new String[] { // era strings
@@ -135,12 +140,8 @@
                     "Gy/M/d",
                 }
             },
-            { "roc.Eras",
-                new String[] {
-                    "\u6c11\u570b\u524d",
-                    "\u6c11\u570b",
-                }
-            },
+            { "roc.Eras", rocEras },
+            { "roc.short.Eras", rocEras },
             { "cldr.roc.DatePatterns",
                 new String[] {
                     "Gy\u5e74M\u6708d\u65e5EEEE",
diff --git a/jdk/src/share/classes/sun/tools/jar/Main.java b/jdk/src/share/classes/sun/tools/jar/Main.java
index 73a3d0e..9667783 100644
--- a/jdk/src/share/classes/sun/tools/jar/Main.java
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java
@@ -47,7 +47,7 @@
 class Main {
     String program;
     PrintStream out, err;
-    String fname, mname, ename;
+    String fname, mname, ename, pname;
     String zname = "";
     String[] files;
     String rootjar = null;
@@ -78,6 +78,9 @@
     static final String MANIFEST_DIR = "META-INF/";
     static final String VERSION = "1.0";
 
+    // valid values for Profile attribute
+    private static final String[] PROFILES = { "compact1", "compact2", "compact3" };
+
     private static ResourceBundle rsrc;
 
     /**
@@ -184,6 +187,14 @@
                     if (ename != null) {
                         addMainClass(manifest, ename);
                     }
+                    if (pname != null) {
+                        if (!addProfileName(manifest, pname)) {
+                            if (in != null) {
+                                in.close();
+                            }
+                            return false;
+                        }
+                    }
                 }
                 OutputStream out;
                 if (fname != null) {
@@ -230,7 +241,7 @@
                 if (manifest != null) {
                     manifest.close();
                 }
-                if (fname != null) {
+                if (ok && fname != null) {
                     // on Win32, we need this delete
                     inputFile.delete();
                     if (!tmpFile.renameTo(inputFile)) {
@@ -361,6 +372,9 @@
                 case 'e':
                      ename = args[count++];
                      break;
+                case 'p':
+                     pname = args[count++];
+                     break;
                 default:
                     error(formatMsg("error.illegal.option",
                                 String.valueOf(flags.charAt(i))));
@@ -410,7 +424,7 @@
             usageError();
             return false;
         } else if (uflag) {
-            if ((mname != null) || (ename != null)) {
+            if ((mname != null) || (ename != null) || (pname != null)) {
                 /* just want to update the manifest */
                 return true;
             } else {
@@ -544,7 +558,7 @@
                 || (Mflag && isManifestEntry)) {
                 continue;
             } else if (isManifestEntry && ((newManifest != null) ||
-                        (ename != null))) {
+                        (ename != null) || (pname != null))) {
                 foundManifest = true;
                 if (newManifest != null) {
                     // Don't read from the newManifest InputStream, as we
@@ -563,7 +577,9 @@
                 if (newManifest != null) {
                     old.read(newManifest);
                 }
-                updateManifest(old, zos);
+                if (!updateManifest(old, zos)) {
+                    return false;
+                }
             } else {
                 if (!entryMap.containsKey(name)) { // copy the old stuff
                     // do our own compression
@@ -596,10 +612,14 @@
                 Manifest m = new Manifest(newManifest);
                 updateOk = !isAmbiguousMainClass(m);
                 if (updateOk) {
-                    updateManifest(m, zos);
+                    if (!updateManifest(m, zos)) {
+                        updateOk = false;
+                    }
                 }
-            } else if (ename != null) {
-                updateManifest(new Manifest(), zos);
+            } else if (ename != null || pname != null) {
+                if (!updateManifest(new Manifest(), zos)) {
+                    updateOk = false;
+                }
             }
         }
         zis.close();
@@ -623,7 +643,7 @@
         zos.closeEntry();
     }
 
-    private void updateManifest(Manifest m, ZipOutputStream zos)
+    private boolean updateManifest(Manifest m, ZipOutputStream zos)
         throws IOException
     {
         addVersion(m);
@@ -631,6 +651,11 @@
         if (ename != null) {
             addMainClass(m, ename);
         }
+        if (pname != null) {
+            if (!addProfileName(m, pname)) {
+                return false;
+            }
+        }
         ZipEntry e = new ZipEntry(MANIFEST_NAME);
         e.setTime(System.currentTimeMillis());
         if (flag0) {
@@ -641,6 +666,7 @@
         if (vflag) {
             output(getMsg("out.update.manifest"));
         }
+        return true;
     }
 
 
@@ -687,6 +713,28 @@
         global.put(Attributes.Name.MAIN_CLASS, mainApp);
     }
 
+    private boolean addProfileName(Manifest m, String profile) {
+        // check profile name
+        boolean found = false;
+        int i = 0;
+        while (i < PROFILES.length) {
+            if (profile.equals(PROFILES[i])) {
+                found = true;
+                break;
+            }
+            i++;
+        }
+        if (!found) {
+            error(formatMsg("error.bad.pvalue", profile));
+            return false;
+        }
+
+        // overrides any existing Profile attribute
+        Attributes global = m.getMainAttributes();
+        global.put(Attributes.Name.PROFILE, profile);
+        return true;
+    }
+
     private boolean isAmbiguousMainClass(Manifest m) {
         if (ename != null) {
             Attributes global = m.getMainAttributes();
diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar.properties
index 852cac2..655542a 100644
--- a/jdk/src/share/classes/sun/tools/jar/resources/jar.properties
+++ b/jdk/src/share/classes/sun/tools/jar/resources/jar.properties
@@ -36,6 +36,8 @@
 error.bad.eflag=\
 	'e' flag and manifest with the 'Main-Class' attribute cannot be specified \n\
 	 together!
+error.bad.pvalue=\
+        bad value for 'Profile' attribute: {0}
 error.nosuch.fileordir=\
         {0} : no such file or directory
 error.write.file=\
@@ -77,6 +79,7 @@
 \ \   -m  include manifest information from specified manifest file\n\
 \ \   -e  specify application entry point for stand-alone application \n\
 \ \       bundled into an executable jar file\n\
+\ \   -p  specify profile name\n\
 \ \   -0  store only; use no ZIP compression\n\
 \ \   -M  do not create a manifest file for the entries\n\
 \ \   -i  generate index information for the specified jar files\n\
diff --git a/jdk/src/share/classes/sun/util/calendar/CalendarSystem.java b/jdk/src/share/classes/sun/util/calendar/CalendarSystem.java
index fdbdcb0..589f552 100644
--- a/jdk/src/share/classes/sun/util/calendar/CalendarSystem.java
+++ b/jdk/src/share/classes/sun/util/calendar/CalendarSystem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -25,6 +25,13 @@
 
 package sun.util.calendar;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Properties;
 import java.util.TimeZone;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -170,6 +177,44 @@
         return (cs == null) ? cal : cs;
     }
 
+    /**
+     * Returns a {@link Properties} loaded from lib/calendars.properties.
+     *
+     * @return a {@link Properties} loaded from lib/calendars.properties
+     * @throws IOException if an error occurred when reading from the input stream
+     * @throws IllegalArgumentException if the input stream contains any malformed
+     *                                  Unicode escape sequences
+     */
+    public static Properties getCalendarProperties() throws IOException {
+        Properties calendarProps = null;
+        try {
+            String homeDir = AccessController.doPrivileged(
+                new sun.security.action.GetPropertyAction("java.home"));
+            final String fname = homeDir + File.separator + "lib" + File.separator
+                                 + "calendars.properties";
+            calendarProps = AccessController.doPrivileged(new PrivilegedExceptionAction<Properties>() {
+                @Override
+                public Properties run() throws IOException {
+                    Properties props = new Properties();
+                    try (FileInputStream fis = new FileInputStream(fname)) {
+                        props.load(fis);
+                    }
+                    return props;
+                }
+            });
+        } catch (PrivilegedActionException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof IOException) {
+                throw (IOException) cause;
+            } else if (cause instanceof IllegalArgumentException) {
+                throw (IllegalArgumentException) cause;
+            }
+            // Should not happen
+            throw new InternalError(cause);
+        }
+        return calendarProps;
+    }
+
     //////////////////////////////// Calendar API //////////////////////////////////
 
     /**
diff --git a/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java b/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java
index d107a00..aa0a73b 100644
--- a/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java
+++ b/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -25,12 +25,7 @@
 
 package sun.util.calendar;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
@@ -59,6 +54,7 @@
 
         private int gregorianYear = FIELD_UNDEFINED;
 
+        @Override
         public Date setEra(Era era) {
             if (getEra() != era) {
                 super.setEra(era);
@@ -67,12 +63,14 @@
             return this;
         }
 
+        @Override
         public Date addYear(int localYear) {
             super.addYear(localYear);
             gregorianYear += localYear;
             return this;
         }
 
+        @Override
         public Date setYear(int localYear) {
             if (getYear() != localYear) {
                 super.setYear(localYear);
@@ -81,10 +79,12 @@
             return this;
         }
 
+        @Override
         public int getNormalizedYear() {
             return gregorianYear;
         }
 
+        @Override
         public void setNormalizedYear(int normalizedYear) {
             this.gregorianYear = normalizedYear;
         }
@@ -97,6 +97,7 @@
             super.setYear(year);
         }
 
+        @Override
         public String toString() {
             String time = super.toString();
             time = time.substring(time.indexOf('T'));
@@ -117,25 +118,12 @@
     }
 
     static LocalGregorianCalendar getLocalGregorianCalendar(String name) {
-        Properties calendarProps = null;
+        Properties calendarProps;
         try {
-            String homeDir = AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("java.home"));
-            final String fname = homeDir + File.separator + "lib" + File.separator
-                                 + "calendars.properties";
-            calendarProps = AccessController.doPrivileged(new PrivilegedExceptionAction<Properties>() {
-                public Properties run() throws IOException {
-                    Properties props = new Properties();
-                    try (FileInputStream fis = new FileInputStream(fname)) {
-                        props.load(fis);
-                    }
-                    return props;
-                }
-            });
-        } catch (PrivilegedActionException e) {
-            throw new RuntimeException(e.getException());
+            calendarProps = CalendarSystem.getCalendarProperties();
+        } catch (IOException | IllegalArgumentException e) {
+            throw new InternalError(e);
         }
-
         // Parse calendar.*.eras
         String props = calendarProps.getProperty("calendar." + name + ".eras");
         if (props == null) {
@@ -190,22 +178,27 @@
         setEras(eras);
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public Date getCalendarDate() {
         return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
     }
 
+    @Override
     public Date getCalendarDate(long millis) {
         return getCalendarDate(millis, newCalendarDate());
     }
 
+    @Override
     public Date getCalendarDate(long millis, TimeZone zone) {
         return getCalendarDate(millis, newCalendarDate(zone));
     }
 
+    @Override
     public Date getCalendarDate(long millis, CalendarDate date) {
         Date ldate = (Date) super.getCalendarDate(millis, date);
         return adjustYear(ldate, millis, ldate.getZoneOffset());
@@ -234,14 +227,17 @@
         return ldate;
     }
 
+    @Override
     public Date newCalendarDate() {
         return new Date();
     }
 
+    @Override
     public Date newCalendarDate(TimeZone zone) {
         return new Date(zone);
     }
 
+    @Override
     public boolean validate(CalendarDate date) {
         Date ldate = (Date) date;
         Era era = ldate.getEra();
@@ -249,7 +245,16 @@
             if (!validateEra(era)) {
                 return false;
             }
-            ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear());
+            ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear() - 1);
+            // If it's not the last Era, validate the date.
+            if (era != eras[eras.length - 1]) {
+                Date tmp = newCalendarDate(date.getZone());
+                tmp.setEra(era).setDate(date.getYear(), date.getMonth(), date.getDayOfMonth());
+                normalize(tmp);
+                if (tmp.getEra() != era) {
+                    return false;
+                }
+            }
         } else {
             ldate.setNormalizedYear(ldate.getYear());
         }
@@ -266,6 +271,7 @@
         return false;
     }
 
+    @Override
     public boolean normalize(CalendarDate date) {
         if (date.isNormalized()) {
             return true;
@@ -339,6 +345,7 @@
         return true;
     }
 
+    @Override
     void normalizeMonth(CalendarDate date) {
         normalizeYear(date);
         super.normalizeMonth(date);
@@ -360,6 +367,7 @@
      * Returns whether the specified Gregorian year is a leap year.
      * @see #isLeapYear(Era, int)
      */
+    @Override
     public boolean isLeapYear(int gregorianYear) {
         return CalendarUtils.isGregorianLeapYear(gregorianYear);
     }
@@ -372,6 +380,7 @@
         return isLeapYear(gyear);
     }
 
+    @Override
     public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {
         Date ldate = (Date) date;
         super.getCalendarDateFromFixedDate(ldate, fixedDate);
diff --git a/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java b/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java
index 2838be44..995ec45 100644
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java
@@ -30,10 +30,12 @@
 import java.lang.ref.SoftReference;
 import java.security.AccessController;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.SimpleTimeZone;
 import java.util.TimeZone;
 
@@ -78,19 +80,6 @@
     private static final long ABBR_MASK = 0xf00L;
     private static final int TRANSITION_NSHIFT = 12;
 
-    // Flag for supporting JDK backward compatible IDs, such as "EST".
-    static final boolean USE_OLDMAPPING;
-    static {
-      String oldmapping = AccessController.doPrivileged(
-          new sun.security.action.GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT);
-      USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
-    }
-
-    // IDs having conflicting data between Olson and JDK 1.1
-    static final String[] conflictingIDs = {
-        "EST", "MST", "HST"
-    };
-
     private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
 
     /**
@@ -521,7 +510,7 @@
         SimpleTimeZone tz = getLastRule();
         if (tz != null) {
             return tz.inDaylightTime(date);
-        }
+       }
         return false;
     }
 
@@ -572,17 +561,8 @@
      * @return an array of time zone IDs.
      */
     public static String[] getAvailableIDs() {
-        List<String> idList = ZoneInfoFile.getZoneIDs();
-        List<String> excluded = ZoneInfoFile.getExcludedZones();
-        if (excluded != null) {
-            // List all zones from the idList and excluded lists
-            List<String> list = new ArrayList<>(idList.size() + excluded.size());
-            list.addAll(idList);
-            list.addAll(excluded);
-            idList = list;
-        }
-        String[] ids = new String[idList.size()];
-        return idList.toArray(ids);
+        Set<String> idSet = ZoneInfoFile.getZoneIds();
+        return idSet.toArray(new String[idSet.size()]);
     }
 
     /**
@@ -595,45 +575,7 @@
      * @return an array of time zone IDs.
      */
     public static String[] getAvailableIDs(int rawOffset) {
-        String[] result;
-        List<String> matched = new ArrayList<>();
-        List<String> IDs = ZoneInfoFile.getZoneIDs();
-        int[] rawOffsets = ZoneInfoFile.getRawOffsets();
-
-    loop:
-        for (int index = 0; index < rawOffsets.length; index++) {
-            if (rawOffsets[index] == rawOffset) {
-                byte[] indices = ZoneInfoFile.getRawOffsetIndices();
-                for (int i = 0; i < indices.length; i++) {
-                    if (indices[i] == index) {
-                        matched.add(IDs.get(i++));
-                        while (i < indices.length && indices[i] == index) {
-                            matched.add(IDs.get(i++));
-                        }
-                        break loop;
-                    }
-                }
-            }
-        }
-
-        // We need to add any zones from the excluded zone list that
-        // currently have the same GMT offset as the specified
-        // rawOffset. The zones returned by this method may not be
-        // correct as of return to the caller if any GMT offset
-        // transition is happening during this GMT offset checking...
-        List<String> excluded = ZoneInfoFile.getExcludedZones();
-        if (excluded != null) {
-            for (String id : excluded) {
-                TimeZone zi = getTimeZone(id);
-                if (zi != null && zi.getRawOffset() == rawOffset) {
-                    matched.add(id);
-                }
-            }
-        }
-
-        result = new String[matched.size()];
-        matched.toArray(result);
-        return result;
+        return ZoneInfoFile.getZoneIds(rawOffset);
     }
 
     /**
@@ -645,44 +587,7 @@
      * time zone of the ID.
      */
     public static TimeZone getTimeZone(String ID) {
-        String givenID = null;
-
-        /*
-         * If old JDK compatibility is specified, get the old alias
-         * name.
-         */
-        if (USE_OLDMAPPING) {
-            String compatibleID = TzIDOldMapping.MAP.get(ID);
-            if (compatibleID != null) {
-                givenID = ID;
-                ID = compatibleID;
-            }
-        }
-
-        ZoneInfo zi = ZoneInfoFile.getZoneInfo(ID);
-        if (zi == null) {
-            // if we can't create an object for the ID, try aliases.
-            try {
-                Map<String, String> map = getAliasTable();
-                String alias = ID;
-                while ((alias = map.get(alias)) != null) {
-                    zi = ZoneInfoFile.getZoneInfo(alias);
-                    if (zi != null) {
-                        zi.setID(ID);
-                        zi = ZoneInfoFile.addToCache(ID, zi);
-                        zi = (ZoneInfo) zi.clone();
-                        break;
-                    }
-                }
-            } catch (Exception e) {
-                // ignore exceptions
-            }
-        }
-
-        if (givenID != null && zi != null) {
-            zi.setID(givenID);
-        }
-        return zi;
+        return ZoneInfoFile.getZoneInfo(ID);
     }
 
     private transient SimpleTimeZone lastRule;
@@ -811,18 +716,6 @@
         return (checksum == ((ZoneInfo)other).checksum);
     }
 
-    private static SoftReference<Map<String, String>> aliasTable;
-
-    static Map<String, String> getCachedAliasTable() {
-        Map<String, String> aliases = null;
-
-        SoftReference<Map<String, String>> cache = aliasTable;
-        if (cache != null) {
-            aliases = cache.get();
-        }
-        return aliases;
-    }
-
     /**
      * Returns a Map from alias time zone IDs to their standard
      * time zone IDs.
@@ -831,22 +724,9 @@
      *    to their standard time zone IDs, or null if
      *    <code>ZoneInfoMappings</code> file is not available.
      */
-     public synchronized static Map<String, String> getAliasTable() {
-         Map<String, String> aliases = getCachedAliasTable();
-         if (aliases == null) {
-             aliases = ZoneInfoFile.getZoneAliases();
-             if (aliases != null) {
-                 if (!USE_OLDMAPPING) {
-                     // Remove the conflicting IDs from the alias table.
-                     for (String key : conflictingIDs) {
-                         aliases.remove(key);
-                     }
-                 }
-                 aliasTable = new SoftReference<Map<String, String>>(aliases);
-             }
-         }
-         return aliases;
-     }
+    public static Map<String, String> getAliasTable() {
+         return ZoneInfoFile.getAliasMap();
+    }
 
     private void readObject(ObjectInputStream stream)
             throws IOException, ClassNotFoundException {
diff --git a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
index 094c956..2bddab2 100644
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -25,494 +25,125 @@
 
 package sun.util.calendar;
 
-import  java.io.File;
-import  java.io.FileInputStream;
-import  java.io.FileNotFoundException;
-import  java.io.IOException;
-import  java.lang.ref.SoftReference;
-import  java.nio.file.FileSystems;
-import  java.security.AccessController;
-import  java.security.PrivilegedAction;
-import  java.security.PrivilegedActionException;
-import  java.security.PrivilegedExceptionAction;
-import  java.util.ArrayList;
-import  java.util.HashMap;
-import  java.util.List;
-import  java.util.Map;
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.time.DayOfWeek;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.Month;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.time.zone.ZoneRules;
+import java.time.zone.ZoneOffsetTransition;
+import java.time.zone.ZoneOffsetTransitionRule;
+import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.SimpleTimeZone;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.zip.CRC32;
+import java.util.zip.ZipFile;
 
 /**
- * <code>ZoneInfoFile</code> reads Zone information files in the
- * &lt;java.home&gt;/lib/zi directory and provides time zone
- * information in the form of a {@link ZoneInfo} object. Also, it
- * reads the ZoneInfoMappings file to obtain time zone IDs information
- * that is used by the {@link ZoneInfo} class. The directory layout
- * and data file formats are as follows.
- *
- * <p><strong>Directory layout</strong><p>
- *
- * All zone data files and ZoneInfoMappings are put under the
- * &lt;java.home&gt;/lib/zi directory. A path name for a given time
- * zone ID is a concatenation of &lt;java.home&gt;/lib/zi/ and the
- * time zone ID. (The file separator is replaced with the platform
- * dependent value. e.g., '\' for Win32.) An example layout will look
- * like as follows.
- * <blockquote>
- * <pre>
- * &lt;java.home&gt;/lib/zi/Africa/Addis_Ababa
- *                   /Africa/Dakar
- *                   /America/Los_Angeles
- *                   /Asia/Singapore
- *                   /EET
- *                   /Europe/Oslo
- *                   /GMT
- *                   /Pacific/Galapagos
- *                       ...
- *                   /ZoneInfoMappings
- * </pre>
- * </blockquote>
- *
- * A zone data file has specific information of each zone.
- * <code>ZoneInfoMappings</code> has global information of zone IDs so
- * that the information can be obtained without instantiating all time
- * zones.
- *
- * <p><strong>File format</strong><p>
- *
- * Two binary-file formats based on a simple Tag-Length-Value format are used
- * to describe TimeZone information. The generic format of a data file is:
- * <blockquote>
- * <pre>
- *    DataFile {
- *      u1              magic[7];
- *      u1              version;
- *      data_item       data[];
- *    }
- * </pre>
- * </blockquote>
- * where <code>magic</code> is a magic number identifying a file
- * format, <code>version</code> is the format version number, and
- * <code>data</code> is one or more <code>data_item</code>s. The
- * <code>data_item</code> structure is:
- * <blockquote>
- * <pre>
- *    data_item {
- *      u1              tag;
- *      u2              length;
- *      u1              value[length];
- *    }
- * </pre>
- * </blockquote>
- * where <code>tag</code> indicates the data type of the item,
- * <code>length</code> is a byte count of the following
- * <code>value</code> that is the content of item data.
+ * Loads TZDB time-zone rules for j.u.TimeZone
  * <p>
- * All data is stored in the big-endian order. There is no boundary
- * alignment between date items.
- *
- * <p><strong>1. ZoneInfo data file</strong><p>
- *
- * Each ZoneInfo data file consists of the following members.
- * <br>
- * <blockquote>
- * <pre>
- *    ZoneInfoDataFile {
- *      u1              magic[7];
- *      u1              version;
- *      SET OF<sup>1</sup> {
- *        transition            transitions<sup>2</sup>;
- *        offset_table          offsets<sup>2</sup>;
- *        simpletimezone        stzparams<sup>2</sup>;
- *        raw_offset            rawoffset;
- *        dstsaving             dst;
- *        checksum              crc32;
- *        gmtoffsetwillchange   gmtflag<sup>2</sup>;
- *      }
- *   }
- *   1: an unordered collection of zero or one occurrences of each item
- *   2: optional item
- * </pre>
- * </blockquote>
- * <code>magic</code> is a byte-string constant identifying the
- * ZoneInfo data file.  This field must be <code>"javazi&#92;0"</code>
- * defined as {@link #JAVAZI_LABEL}.
- * <p>
- * <code>version</code> is the version number of the file format. This
- * will be used for compatibility check. This field must be
- * <code>0x01</code> in this version.
- * <p>
- * <code>transition</code>, <code>offset_table</code> and
- * <code>simpletimezone</code> have information of time transition
- * from the past to the future.  Therefore, these structures don't
- * exist if the zone didn't change zone names and haven't applied DST in
- * the past, and haven't planned to apply it.  (e.g. Asia/Tokyo zone)
- * <p>
- * <code>raw_offset</code>, <code>dstsaving</code> and <code>checksum</code>
- * exist in every zoneinfo file. They are used by TimeZone.class indirectly.
- *
- * <p><strong>1.1 <code>transition</code> structure</strong><p><a name="transition"></a>
- * <blockquote>
- * <pre>
- *    transition {
- *      u1      tag;              // 0x04 : constant
- *      u2      length;           // byte length of whole values
- *      s8      value[length/8];  // transitions in `long'
- *    }
- * </pre>
- * </blockquote>
- * See {@link ZoneInfo#transitions ZoneInfo.transitions} about the value.
- *
- * <p><strong>1.2 <code>offset_table</code> structure</strong><p>
- * <blockquote>
- * <pre>
- *    offset_table {
- *      u1      tag;              // 0x05 : constant
- *      u2      length;           // byte length of whole values
- *      s4      value[length/4];  // offset values in `int'
- *    }
- * </pre>
- * </blockquote>
- *
- * <p><strong>1.3 <code>simpletimezone</code> structure</strong><p>
- * See {@link ZoneInfo#simpleTimeZoneParams ZoneInfo.simpleTimeZoneParams}
- * about the value.
- * <blockquote>
- * <pre>
- *    simpletimezone {
- *      u1      tag;              // 0x06 : constant
- *      u2      length;           // byte length of whole values
- *      s4      value[length/4];  // SimpleTimeZone parameters
- *    }
- * </pre>
- * </blockquote>
- * See {@link ZoneInfo#offsets ZoneInfo.offsets} about the value.
- *
- * <p><strong>1.4 <code>raw_offset</code> structure</strong><p>
- * <blockquote>
- * <pre>
- *    raw_offset {
- *      u1      tag;              // 0x01 : constant
- *      u2      length;           // must be 4.
- *      s4      value;            // raw GMT offset [millisecond]
- *    }
- * </pre>
- * </blockquote>
- * See {@link ZoneInfo#rawOffset ZoneInfo.rawOffset} about the value.
- *
- * <p><strong>1.5 <code>dstsaving</code> structure</strong><p>
- * Value has dstSaving in seconds.
- * <blockquote>
- * <pre>
- *    dstsaving {
- *      u1      tag;              // 0x02 : constant
- *      u2      length;           // must be 2.
- *      s2      value;            // DST save value [second]
- *    }
- * </pre>
- * </blockquote>
- * See {@link ZoneInfo#dstSavings ZoneInfo.dstSavings} about value.
- *
- * <p><strong>1.6 <code>checksum</code> structure</strong><p>
- * <blockquote>
- * <pre>
- *    checksum {
- *      u1      tag;              // 0x03 : constant
- *      u2      length;           // must be 4.
- *      s4      value;            // CRC32 value of transitions
- *    }
- * </pre>
- * </blockquote>
- * See {@link ZoneInfo#checksum ZoneInfo.checksum}.
- *
- * <p><strong>1.7 <code>gmtoffsetwillchange</code> structure</strong><p>
- * This record has a flag value for {@link ZoneInfo#rawOffsetWillChange}.
- * If this record is not present in a zoneinfo file, 0 is assumed for
- * the value.
- * <blockquote>
- * <pre>
- *    gmtoffsetwillchange {
- *      u1      tag;             // 0x07 : constant
- *      u2      length;          // must be 1.
- *      u1      value;           // 1: if the GMT raw offset will change
- *                               // in the future, 0, otherwise.
- *     }
- * </pre>
- * </blockquote>
- *
- *
- * <p><strong>2. ZoneInfoMappings file</strong><p>
- *
- * The ZoneInfoMappings file consists of the following members.
- * <br>
- * <blockquote>
- * <pre>
- *    ZoneInfoMappings {
- *      u1      magic[7];
- *      u1      version;
- *      SET OF {
- *        versionName                   version;
- *        zone_id_table                 zoneIDs;
- *        raw_offset_table              rawoffsets;
- *        raw_offset_index_table        rawoffsetindices;
- *        alias_table                   aliases;
- *        excluded_list                 excludedList;
- *      }
- *   }
- * </pre>
- * </blockquote>
- *
- * <code>magic</code> is a byte-string constant which has the file type.
- * This field must be <code>"javazm&#92;0"</code> defined as {@link #JAVAZM_LABEL}.
- * <p>
- * <code>version</code> is the version number of this file
- * format. This will be used for compatibility check. This field must
- * be <code>0x01</code> in this version.
- * <p>
- * <code>versionName</code> shows which version of Olson's data has been used
- * to generate this ZoneInfoMappings. (e.g. <code>tzdata2000g</code>) <br>
- * This field is for trouble-shooting and isn't usually used in runtime.
- * <p>
- * <code>zone_id_table</code>, <code>raw_offset_index_table</code> and
- * <code>alias_table</code> are general information of supported
- * zones.
- *
- * <p><strong>2.1 <code>zone_id_table</code> structure</strong><p>
- * The list of zone IDs included in the zi database. The list does
- * <em>not</em> include zone IDs, if any, listed in excludedList.
- * <br>
- * <blockquote>
- * <pre>
- *    zone_id_table {
- *      u1      tag;              // 0x40 : constant
- *      u2      length;           // byte length of whole values
- *      u2      zone_id_count;
- *      zone_id value[zone_id_count];
- *    }
- *
- *    zone_id {
- *      u1      byte_length;      // byte length of id
- *      u1      id[byte_length];  // zone name string
- *    }
- * </pre>
- * </blockquote>
- *
- * <p><strong>2.2 <code>raw_offset_table</code> structure</strong><p>
- * <br>
- * <blockquote>
- * <pre>
- *    raw_offset_table {
- *      u1      tag;              // 0x41 : constant
- *      u2      length;           // byte length of whole values
- *      s4      value[length/4];  // raw GMT offset in milliseconds
- *   }
- * </pre>
- * </blockquote>
- *
- * <p><strong>2.3 <code>raw_offset_index_table</code> structure</strong><p>
- * <br>
- * <blockquote>
- * <pre>
- *    raw_offset_index_table {
- *      u1      tag;              // 0x42 : constant
- *      u2      length;           // byte length of whole values
- *      u1      value[length];
- *    }
- * </pre>
- * </blockquote>
- *
- * <p><strong>2.4 <code>alias_table</code> structure</strong><p>
- * <br>
- * <blockquote>
- * <pre>
- *   alias_table {
- *      u1      tag;              // 0x43 : constant
- *      u2      length;           // byte length of whole values
- *      u2      nentries;         // number of id-pairs
- *      id_pair value[nentries];
- *   }
- *
- *   id_pair {
- *      zone_id aliasname;
- *      zone_id ID;
- *   }
- * </pre>
- * </blockquote>
- *
- * <p><strong>2.5 <code>versionName</code> structure</strong><p>
- * <br>
- * <blockquote>
- * <pre>
- *   versionName {
- *      u1      tag;              // 0x44 : constant
- *      u2      length;           // byte length of whole values
- *      u1      value[length];
- *   }
- * </pre>
- * </blockquote>
- *
- * <p><strong>2.6 <code>excludeList</code> structure</strong><p>
- * The list of zone IDs whose zones will change their GMT offsets
- * (a.k.a. raw offsets) some time in the future. Those IDs must be
- * added to the list of zone IDs for getAvailableIDs(). Also they must
- * be examined for getAvailableIDs(int) to determine the
- * <em>current</em> GMT offsets.
- * <br>
- * <blockquote>
- * <pre>
- *   excluded_list {
- *      u1      tag;              // 0x45 : constant
- *      u2      length;           // byte length of whole values
- *      u2      nentries;         // number of zone_ids
- *      zone_id value[nentries];  // excluded zone IDs
- *   }
- * </pre>
- * </blockquote>
- *
- * @since 1.4
+ * @since 1.8
  */
-
-public class ZoneInfoFile {
+public final class ZoneInfoFile {
 
     /**
-     * The magic number for the ZoneInfo data file format.
+     * Gets all available IDs supported in the Java run-time.
+     *
+     * @return a set of time zone IDs.
      */
-    public static final byte[]  JAVAZI_LABEL = {
-        (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'i', (byte)'\0'
-    };
-    private static final int    JAVAZI_LABEL_LENGTH = JAVAZI_LABEL.length;
+    public static Set<String> getZoneIds() {
+        return zones.keySet();
+    }
 
     /**
-     * The ZoneInfo data file format version number. Must increase
-     * one when any incompatible change has been made.
+     * Gets all available IDs that have the same value as the
+     * specified raw GMT offset.
+     *
+     * @param rawOffset  the GMT offset in milliseconds. This
+     *                   value should not include any daylight saving time.
+     * @return an array of time zone IDs.
      */
-    public static final byte    JAVAZI_VERSION = 0x01;
-
-    /**
-     * Raw offset data item tag.
-     */
-    public static final byte    TAG_RawOffset = 1;
-
-    /**
-     * Known last Daylight Saving Time save value data item tag.
-     */
-    public static final byte    TAG_LastDSTSaving = 2;
-
-    /**
-     * Checksum data item tag.
-     */
-    public static final byte    TAG_CRC32 = 3;
-
-    /**
-     * Transition data item tag.
-     */
-    public static final byte    TAG_Transition = 4;
-
-    /**
-     * Offset table data item tag.
-     */
-    public static final byte    TAG_Offset = 5;
-
-    /**
-     * SimpleTimeZone parameters data item tag.
-     */
-    public static final byte    TAG_SimpleTimeZone = 6;
-
-    /**
-     * Raw GMT offset will change in the future.
-     */
-    public static final byte    TAG_GMTOffsetWillChange = 7;
-
-
-    /**
-     * The ZoneInfoMappings file name.
-     */
-    public static final String  JAVAZM_FILE_NAME = "ZoneInfoMappings";
-
-    /**
-     * The magic number for the ZoneInfoMappings file format.
-     */
-    public static final byte[]  JAVAZM_LABEL = {
-        (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'m', (byte)'\0'
-    };
-    private static final int    JAVAZM_LABEL_LENGTH = JAVAZM_LABEL.length;
-
-    /**
-     * The ZoneInfoMappings file format version number. Must increase
-     * one when any incompatible change has been made.
-     */
-    public static final byte    JAVAZM_VERSION = 0x01;
-
-    /**
-     * Time zone IDs data item tag.
-     */
-    public static final byte    TAG_ZoneIDs = 64;
-
-    /**
-     * Raw GMT offsets table data item tag.
-     */
-    public static final byte    TAG_RawOffsets = 65;
-
-    /**
-     * Indices to the raw GMT offset table data item tag.
-     */
-    public static final byte    TAG_RawOffsetIndices = 66;
-
-    /**
-     * Time zone aliases table data item tag.
-     */
-    public static final byte    TAG_ZoneAliases = 67;
-
-    /**
-     * Olson's public zone information version tag.
-     */
-    public static final byte    TAG_TZDataVersion = 68;
-
-    /**
-     * Excluded zones item tag. (Added in Mustang)
-     */
-    public static final byte    TAG_ExcludedZones = 69;
-
-    private static Map<String, ZoneInfo> zoneInfoObjects = null;
-
-    private static final ZoneInfo GMT = new ZoneInfo("GMT", 0);
-
-    private static final String ziDir = AccessController.doPrivileged(
-        new PrivilegedAction<String>() {
-            public String run() {
-                String zi = System.getProperty("java.home") +
-                    File.separator + "lib" + File.separator + "zi";
-                try {
-                    zi = FileSystems.getDefault().getPath(zi).toRealPath().toString();
-                } catch(Exception e) {
-                }
-                return zi;
+    public static String[] getZoneIds(int rawOffset) {
+        List<String> ids = new ArrayList<>();
+        for (String id : zones.keySet()) {
+            ZoneInfo zi = getZoneInfo0(id);
+            if (zi.getRawOffset() == rawOffset) {
+                ids.add(id);
             }
-        });
+        }
+        // It appears the "zi" implementation returns the
+        // sorted list, though the specification does not
+        // specify it. Keep the same behavior for better
+        // compatibility.
+        String[] list = ids.toArray(new String[ids.size()]);
+        Arrays.sort(list);
+        return list;
+    }
+
+    public static ZoneInfo getZoneInfo(String zoneId) {
+        if (!zones.containsKey(zoneId)) {
+            return null;
+        }
+        // ZoneInfo is mutable, return the copy
+
+        ZoneInfo zi = getZoneInfo0(zoneId);
+        zi = (ZoneInfo)zi.clone();
+        zi.setID(zoneId);
+        return zi;
+    }
 
     /**
-     * Converts the given time zone ID to a platform dependent path
-     * name. For example, "America/Los_Angeles" is converted to
-     * "America\Los_Angeles" on Win32.
-     * @return a modified ID replacing '/' with {@link
-     * java.io.File#separatorChar File.separatorChar} if needed.
+     * Returns a Map from alias time zone IDs to their standard
+     * time zone IDs.
+     *
+     * @return an unmodified alias mapping
      */
-    public static String getFileName(String ID) {
-        if (File.separatorChar == '/') {
-            return ID;
-        }
-        return ID.replace('/', File.separatorChar);
+    public static Map<String, String> getAliasMap() {
+        return aliases;
+    }
+
+    /**
+     * Gets the version of this tz data.
+     *
+     * @return the tzdb version
+     */
+    public static String getVersion() {
+        return versionId;
     }
 
     /**
      * Gets a ZoneInfo with the given GMT offset. The object
      * has its ID in the format of GMT{+|-}hh:mm.
      *
-     * @param originalId the given custom id (before normalized such as "GMT+9")
-     * @param gmtOffset GMT offset <em>in milliseconds</em>
+     * @param originalId  the given custom id (before normalized such as "GMT+9")
+     * @param gmtOffset   GMT offset <em>in milliseconds</em>
      * @return a ZoneInfo constructed with the given GMT offset
      */
     public static ZoneInfo getCustomTimeZone(String originalId, int gmtOffset) {
         String id = toCustomID(gmtOffset);
-
+        return new ZoneInfo(id, gmtOffset);
+/*
         ZoneInfo zi = getFromCache(id);
         if (zi == null) {
             zi = new ZoneInfo(id, gmtOffset);
@@ -522,6 +153,7 @@
             }
         }
         return (ZoneInfo) zi.clone();
+*/
     }
 
     public static String toCustomID(int gmtOffset) {
@@ -549,531 +181,670 @@
         return new String(buf);
     }
 
-    /**
-     * @return a ZoneInfo instance created for the specified id, or
-     * null if there is no time zone data file found for the specified
-     * id.
-     */
-    public static ZoneInfo getZoneInfo(String id) {
-        //treat GMT zone as special
-        if ("GMT".equals(id))
-            return (ZoneInfo) GMT.clone();
-        ZoneInfo zi = getFromCache(id);
-        if (zi == null) {
-            Map<String, String> aliases = ZoneInfo.getCachedAliasTable();
-            if (aliases != null && aliases.get(id) != null) {
-                return null;
-            }
-            zi = createZoneInfo(id);
-            if (zi == null) {
-                return null;
-            }
-            zi = addToCache(id, zi);
-        }
-        return (ZoneInfo) zi.clone();
-    }
 
-    synchronized static ZoneInfo getFromCache(String id) {
-        if (zoneInfoObjects == null) {
-            return null;
-        }
-        return zoneInfoObjects.get(id);
-    }
+    ///////////////////////////////////////////////////////////
 
-    synchronized static ZoneInfo addToCache(String id, ZoneInfo zi) {
-        if (zoneInfoObjects == null) {
-            zoneInfoObjects = new HashMap<>();
-        } else {
-            ZoneInfo zone = zoneInfoObjects.get(id);
-            if (zone != null) {
-                return zone;
-            }
-        }
-        zoneInfoObjects.put(id, zi);
-        return zi;
-    }
-
-    private static ZoneInfo createZoneInfo(String id) {
-        byte[] buf = readZoneInfoFile(getFileName(id));
-        if (buf == null) {
-            return null;
-        }
-
-        int index = 0;
-        int filesize = buf.length;
-        int rawOffset = 0;
-        int dstSavings = 0;
-        int checksum = 0;
-        boolean willGMTOffsetChange = false;
-        long[] transitions = null;
-        int[] offsets = null;
-        int[] simpleTimeZoneParams = null;
-
+    private static ZoneInfo getZoneInfo0(String zoneId) {
         try {
-            for (index = 0; index < JAVAZI_LABEL.length; index++) {
-                if (buf[index] != JAVAZI_LABEL[index]) {
-                    System.err.println("ZoneInfo: wrong magic number: " + id);
-                    return null;
-                }
+
+            Object obj = zones.get(zoneId);
+            if (obj instanceof byte[]) {
+                byte[] bytes = (byte[]) obj;
+                DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
+                obj = getZoneInfo(dis, zoneId);
+                zones.put(zoneId, obj);
             }
-            if (buf[index++] > JAVAZI_VERSION) {
-                System.err.println("ZoneInfo: incompatible version ("
-                                   + buf[index - 1] + "): " + id);
-                return null;
-            }
-
-            while (index < filesize) {
-                byte tag = buf[index++];
-                int  len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
-
-                if (filesize < index+len) {
-                    break;
-                }
-
-                switch (tag) {
-                case TAG_CRC32:
-                    {
-                        int val = buf[index++] & 0xff;
-                        val = (val << 8) + (buf[index++] & 0xff);
-                        val = (val << 8) + (buf[index++] & 0xff);
-                        val = (val << 8) + (buf[index++] & 0xff);
-                        checksum = val;
-                    }
-                    break;
-
-                case TAG_LastDSTSaving:
-                    {
-                        short val = (short)(buf[index++] & 0xff);
-                        val = (short)((val << 8) + (buf[index++] & 0xff));
-                        dstSavings = val * 1000;
-                    }
-                    break;
-
-                case TAG_RawOffset:
-                    {
-                        int val = buf[index++] & 0xff;
-                        val = (val << 8) + (buf[index++] & 0xff);
-                        val = (val << 8) + (buf[index++] & 0xff);
-                        val = (val << 8) + (buf[index++] & 0xff);
-                        rawOffset = val;
-                    }
-                    break;
-
-                case TAG_Transition:
-                    {
-                        int n = len / 8;
-                        transitions = new long[n];
-                        for (int i = 0; i < n; i ++) {
-                            long val = buf[index++] & 0xff;
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            transitions[i] = val;
-                        }
-                    }
-                    break;
-
-                case TAG_Offset:
-                    {
-                        int n = len / 4;
-                        offsets = new int[n];
-                        for (int i = 0; i < n; i ++) {
-                            int val = buf[index++] & 0xff;
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            offsets[i] = val;
-                        }
-                    }
-                    break;
-
-                case TAG_SimpleTimeZone:
-                    {
-                        if (len != 32 && len != 40) {
-                            System.err.println("ZoneInfo: wrong SimpleTimeZone parameter size");
-                            return null;
-                        }
-                        int n = len / 4;
-                        simpleTimeZoneParams = new int[n];
-                        for (int i = 0; i < n; i++) {
-                            int val = buf[index++] & 0xff;
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            simpleTimeZoneParams[i] = val;
-                        }
-                    }
-                    break;
-
-                case TAG_GMTOffsetWillChange:
-                    {
-                        if (len != 1) {
-                            System.err.println("ZoneInfo: wrong byte length for TAG_GMTOffsetWillChange");
-                        }
-                        willGMTOffsetChange = buf[index++] == 1;
-                    }
-                    break;
-
-                default:
-                    System.err.println("ZoneInfo: unknown tag < " + tag + ">. ignored.");
-                    index += len;
-                    break;
-                }
-            }
-        } catch (Exception e) {
-            System.err.println("ZoneInfo: corrupted zoneinfo file: " + id);
-            return null;
+            return (ZoneInfo)obj;
+        } catch (Exception ex) {
+            throw new RuntimeException("Invalid binary time-zone data: TZDB:" +
+                zoneId + ", version: " + versionId, ex);
         }
-
-        if (index != filesize) {
-            System.err.println("ZoneInfo: wrong file size: " + id);
-            return null;
-        }
-
-        return new ZoneInfo(id, rawOffset, dstSavings, checksum,
-                            transitions, offsets, simpleTimeZoneParams,
-                            willGMTOffsetChange);
-    }
-
-    private volatile static SoftReference<List<String>> zoneIDs = null;
-
-    static List<String> getZoneIDs() {
-        List<String> ids = null;
-
-        SoftReference<List<String>> cache = zoneIDs;
-        if (cache != null) {
-            ids = cache.get();
-            if (ids != null) {
-                return ids;
-            }
-        }
-
-        byte[] buf = null;
-        buf = getZoneInfoMappings();
-        int index = JAVAZM_LABEL_LENGTH + 1;
-        int filesize = buf.length;
-
-        try {
-        loop:
-            while (index < filesize) {
-                byte tag = buf[index++];
-                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
-
-                switch (tag) {
-                case TAG_ZoneIDs:
-                    {
-                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);
-                        ids = new ArrayList<>(n);
-
-                        for (int i = 0; i < n; i++) {
-                            byte m = buf[index++];
-                            ids.add(new String(buf, index, m, "UTF-8"));
-                            index += m;
-                        }
-                    }
-                    break loop;
-
-                default:
-                    index += len;
-                    break;
-                }
-            }
-        } catch (Exception e) {
-            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);
-        }
-
-        zoneIDs = new SoftReference<>(ids);
-        return ids;
-    }
-
-    /**
-     * @return an alias table in HashMap where a key is an alias ID
-     * (e.g., "PST") and its value is a real time zone ID (e.g.,
-     * "America/Los_Angeles").
-     */
-    static Map<String, String> getZoneAliases() {
-        byte[] buf = getZoneInfoMappings();
-        int index = JAVAZM_LABEL_LENGTH + 1;
-        int filesize = buf.length;
-        Map<String, String> aliases = null;
-
-        try {
-        loop:
-            while (index < filesize) {
-                byte tag = buf[index++];
-                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
-
-                switch (tag) {
-                case TAG_ZoneAliases:
-                    {
-                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);
-                        aliases = new HashMap<>(n);
-                        for (int i = 0; i < n; i++) {
-                            byte m = buf[index++];
-                            String name = new String(buf, index, m, "UTF-8");
-                            index += m;
-                            m = buf[index++];
-                            String realName = new String(buf, index, m, "UTF-8");
-                            index += m;
-                            aliases.put(name, realName);
-                        }
-                    }
-                    break loop;
-
-                default:
-                    index += len;
-                    break;
-                }
-            }
-        } catch (Exception e) {
-            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);
-            return null;
-        }
-        return aliases;
-    }
-
-    private volatile static SoftReference<List<String>> excludedIDs = null;
-    private volatile static boolean hasNoExcludeList = false;
-
-    /**
-     * @return a List of zone IDs for zones that will change their GMT
-     * offsets in some future time.
-     *
-     * @since 1.6
-     */
-    static List<String> getExcludedZones() {
-        if (hasNoExcludeList) {
-            return null;
-        }
-
-        List<String> excludeList = null;
-
-        SoftReference<List<String>> cache = excludedIDs;
-        if (cache != null) {
-            excludeList = cache.get();
-            if (excludeList != null) {
-                return excludeList;
-            }
-        }
-
-        byte[] buf = getZoneInfoMappings();
-        int index = JAVAZM_LABEL_LENGTH + 1;
-        int filesize = buf.length;
-
-        try {
-          loop:
-            while (index < filesize) {
-                byte tag = buf[index++];
-                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
-
-                switch (tag) {
-                case TAG_ExcludedZones:
-                    {
-                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);
-                        excludeList = new ArrayList<>();
-                        for (int i = 0; i < n; i++) {
-                            byte m = buf[index++];
-                            String name = new String(buf, index, m, "UTF-8");
-                            index += m;
-                            excludeList.add(name);
-                        }
-                    }
-                    break loop;
-
-                default:
-                    index += len;
-                    break;
-                }
-            }
-        } catch (Exception e) {
-            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);
-            return null;
-        }
-
-        if (excludeList != null) {
-            excludedIDs = new SoftReference<>(excludeList);
-        } else {
-            hasNoExcludeList = true;
-        }
-        return excludeList;
-    }
-
-    private volatile static SoftReference<byte[]> rawOffsetIndices = null;
-
-    static byte[] getRawOffsetIndices() {
-        byte[] indices = null;
-
-        SoftReference<byte[]> cache = rawOffsetIndices;
-        if (cache != null) {
-            indices = cache.get();
-            if (indices != null) {
-                return indices;
-            }
-        }
-
-        byte[] buf = getZoneInfoMappings();
-        int index = JAVAZM_LABEL_LENGTH + 1;
-        int filesize = buf.length;
-
-        try {
-        loop:
-            while (index < filesize) {
-                byte tag = buf[index++];
-                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
-
-                switch (tag) {
-                case TAG_RawOffsetIndices:
-                    {
-                        indices = new byte[len];
-                        for (int i = 0; i < len; i++) {
-                            indices[i] = buf[index++];
-                        }
-                    }
-                    break loop;
-
-                default:
-                    index += len;
-                    break;
-                }
-            }
-        } catch (ArrayIndexOutOfBoundsException e) {
-            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);
-        }
-
-        rawOffsetIndices = new SoftReference<>(indices);
-        return indices;
-    }
-
-    private volatile static SoftReference<int[]> rawOffsets = null;
-
-    static int[] getRawOffsets() {
-        int[] offsets = null;
-
-        SoftReference<int[]> cache = rawOffsets;
-        if (cache != null) {
-            offsets = cache.get();
-            if (offsets != null) {
-                return offsets;
-            }
-        }
-
-        byte[] buf = getZoneInfoMappings();
-        int index = JAVAZM_LABEL_LENGTH + 1;
-        int filesize = buf.length;
-
-        try {
-        loop:
-            while (index < filesize) {
-                byte tag = buf[index++];
-                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
-
-                switch (tag) {
-                case TAG_RawOffsets:
-                    {
-                        int n = len/4;
-                        offsets = new int[n];
-                        for (int i = 0; i < n; i++) {
-                            int val = buf[index++] & 0xff;
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            val = (val << 8) + (buf[index++] & 0xff);
-                            offsets[i] = val;
-                        }
-                    }
-                    break loop;
-
-                default:
-                    index += len;
-                    break;
-                }
-            }
-        } catch (ArrayIndexOutOfBoundsException e) {
-            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);
-        }
-
-        rawOffsets = new SoftReference<>(offsets);
-        return offsets;
-    }
-
-    private volatile static SoftReference<byte[]> zoneInfoMappings = null;
-
-    private static byte[] getZoneInfoMappings() {
-        byte[] data;
-
-        SoftReference<byte[]> cache = zoneInfoMappings;
-        if (cache != null) {
-            data = cache.get();
-            if (data != null) {
-                return data;
-            }
-        }
-
-        data = readZoneInfoFile(JAVAZM_FILE_NAME);
-
-        if (data == null) {
-            return null;
-        }
-
-        int index;
-        for (index = 0; index < JAVAZM_LABEL.length; index++) {
-            if (data[index] != JAVAZM_LABEL[index]) {
-                System.err.println("ZoneInfo: wrong magic number: " + JAVAZM_FILE_NAME);
-                return null;
-            }
-        }
-        if (data[index++] > JAVAZM_VERSION) {
-            System.err.println("ZoneInfo: incompatible version ("
-                               + data[index - 1] + "): " + JAVAZM_FILE_NAME);
-            return null;
-        }
-
-        zoneInfoMappings = new SoftReference<>(data);
-        return data;
-    }
-
-    /**
-     * Reads the specified file under &lt;java.home&gt;/lib/zi into a buffer.
-     * @return the buffer, or null if any I/O error occurred.
-     */
-    private static byte[] readZoneInfoFile(final String fileName) {
-        if (fileName.indexOf("..") >= 0) {
-            return null;
-        }
-        byte[] buffer = null;
-
-        try {
-            buffer = AccessController.doPrivileged(new PrivilegedExceptionAction<byte[]>() {
-                public byte[] run() throws IOException {
-                    File file = new File(ziDir, fileName);
-                    byte[] buf = null;
-                    int filesize = (int)file.length();
-                    if (filesize > 0) {
-                        FileInputStream fis = new FileInputStream(file);
-                        buf = new byte[filesize];
-                        try {
-                            if (fis.read(buf) != filesize) {
-                                throw new IOException("read error on " + fileName);
-                            }
-                        } finally {
-                            fis.close();
-                        }
-                    }
-                    return buf;
-                }
-            });
-        } catch (PrivilegedActionException e) {
-            Exception ex = e.getException();
-            if (!(ex instanceof FileNotFoundException) || JAVAZM_FILE_NAME.equals(fileName)) {
-                System.err.println("ZoneInfo: " + ex.getMessage());
-            }
-        }
-        return buffer;
     }
 
     private ZoneInfoFile() {
     }
+
+    private static String versionId;
+    private final static Map<String, Object> zones = new ConcurrentHashMap<>();
+    private static Map<String, String> aliases = new HashMap<>();
+
+    // Flag for supporting JDK backward compatible IDs, such as "EST".
+    private static final boolean USE_OLDMAPPING;
+
+    static {
+        String oldmapping = AccessController.doPrivileged(
+            new sun.security.action.GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT);
+        USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+                try {
+
+                    String libDir = System.getProperty("java.home") + File.separator + "lib";
+                    File tzdbJar = new File(libDir, "tzdb.jar");
+                    try (ZipFile zf = new ZipFile(tzdbJar);
+                        DataInputStream dis = new DataInputStream(
+                            zf.getInputStream(zf.getEntry("TZDB.dat")))) {
+                        load(dis);
+                    }
+                } catch (Exception x) {
+                    throw new Error(x);
+                }
+                return null;
+            }
+        });
+    }
+
+    // Must be invoked after loading in all data
+    private static void addOldMapping() {
+        String[][] oldMappings = new String[][] {
+            { "ACT", "Australia/Darwin" },
+            { "AET", "Australia/Sydney" },
+            { "AGT", "America/Argentina/Buenos_Aires" },
+            { "ART", "Africa/Cairo" },
+            { "AST", "America/Anchorage" },
+            { "BET", "America/Sao_Paulo" },
+            { "BST", "Asia/Dhaka" },
+            { "CAT", "Africa/Harare" },
+            { "CNT", "America/St_Johns" },
+            { "CST", "America/Chicago" },
+            { "CTT", "Asia/Shanghai" },
+            { "EAT", "Africa/Addis_Ababa" },
+            { "ECT", "Europe/Paris" },
+            { "IET", "America/Indiana/Indianapolis" },
+            { "IST", "Asia/Kolkata" },
+            { "JST", "Asia/Tokyo" },
+            { "MIT", "Pacific/Apia" },
+            { "NET", "Asia/Yerevan" },
+            { "NST", "Pacific/Auckland" },
+            { "PLT", "Asia/Karachi" },
+            { "PNT", "America/Phoenix" },
+            { "PRT", "America/Puerto_Rico" },
+            { "PST", "America/Los_Angeles" },
+            { "SST", "Pacific/Guadalcanal" },
+            { "VST", "Asia/Ho_Chi_Minh" },
+        };
+        for (String[] alias : oldMappings) {
+            String k = alias[0];
+            String v = alias[1];
+            if (zones.containsKey(v)) {  // make sure we do have the data
+                aliases.put(k, v);
+                zones.put(k, zones.get(v));
+            }
+        }
+        if (USE_OLDMAPPING) {
+            if (zones.containsKey("America/New_York")) {
+                aliases.put("EST", "America/New_York");
+                zones.put("EST", zones.get("America/New_York"));
+            }
+            if (zones.containsKey("America/Denver")) {
+                aliases.put("MST", "America/Denver");
+                zones.put("MST", zones.get("America/Denver"));
+            }
+            if (zones.containsKey("Pacific/Honolulu")) {
+                aliases.put("HST", "Pacific/Honolulu");
+                zones.put("HST", zones.get("Pacific/Honolulu"));
+            }
+        }
+    }
+
+    /**
+     * Loads the rules from a DateInputStream
+     *
+     * @param dis  the DateInputStream to load, not null
+     * @throws Exception if an error occurs
+     */
+    private static void load(DataInputStream dis) throws ClassNotFoundException, IOException {
+        if (dis.readByte() != 1) {
+            throw new StreamCorruptedException("File format not recognised");
+        }
+        // group
+        String groupId = dis.readUTF();
+        if ("TZDB".equals(groupId) == false) {
+            throw new StreamCorruptedException("File format not recognised");
+        }
+        // versions, only keep the last one
+        int versionCount = dis.readShort();
+        for (int i = 0; i < versionCount; i++) {
+            versionId = dis.readUTF();
+
+        }
+        // regions
+        int regionCount = dis.readShort();
+        String[] regionArray = new String[regionCount];
+        for (int i = 0; i < regionCount; i++) {
+            regionArray[i] = dis.readUTF();
+        }
+        // rules
+        int ruleCount = dis.readShort();
+        Object[] ruleArray = new Object[ruleCount];
+        for (int i = 0; i < ruleCount; i++) {
+            byte[] bytes = new byte[dis.readShort()];
+            dis.readFully(bytes);
+            ruleArray[i] = bytes;
+        }
+        // link version-region-rules, only keep the last version, if more than one
+        for (int i = 0; i < versionCount; i++) {
+            regionCount = dis.readShort();
+            zones.clear();
+            for (int j = 0; j < regionCount; j++) {
+                String region = regionArray[dis.readShort()];
+                Object rule = ruleArray[dis.readShort() & 0xffff];
+                zones.put(region, rule);
+            }
+        }
+        // remove the following ids from the map, they
+        // are exclued from the "old" ZoneInfo
+        zones.remove("ROC");
+        for (int i = 0; i < versionCount; i++) {
+            int aliasCount = dis.readShort();
+            aliases.clear();
+            for (int j = 0; j < aliasCount; j++) {
+                String alias = regionArray[dis.readShort()];
+                String region = regionArray[dis.readShort()];
+                aliases.put(alias, region);
+            }
+        }
+        // old us time-zone names
+        addOldMapping();
+        aliases = Collections.unmodifiableMap(aliases);
+    }
+
+    /////////////////////////Ser/////////////////////////////////
+    public static ZoneInfo getZoneInfo(DataInput in, String zoneId) throws Exception {
+        byte type = in.readByte();
+        // TBD: assert ZRULES:
+        int stdSize = in.readInt();
+        long[] stdTrans = new long[stdSize];
+        for (int i = 0; i < stdSize; i++) {
+            stdTrans[i] = readEpochSec(in);
+        }
+        int [] stdOffsets = new int[stdSize + 1];
+        for (int i = 0; i < stdOffsets.length; i++) {
+            stdOffsets[i] = readOffset(in);
+        }
+        int savSize = in.readInt();
+        long[] savTrans = new long[savSize];
+        for (int i = 0; i < savSize; i++) {
+            savTrans[i] = readEpochSec(in);
+        }
+        int[] savOffsets = new int[savSize + 1];
+        for (int i = 0; i < savOffsets.length; i++) {
+            savOffsets[i] = readOffset(in);
+        }
+        int ruleSize = in.readByte();
+        ZoneOffsetTransitionRule[] rules = new ZoneOffsetTransitionRule[ruleSize];
+        for (int i = 0; i < ruleSize; i++) {
+            rules[i] = readZOTRule(in);
+        }
+        return getZoneInfo(zoneId, stdTrans, stdOffsets, savTrans, savOffsets, rules);
+    }
+
+    public static int readOffset(DataInput in) throws IOException {
+        int offsetByte = in.readByte();
+        return offsetByte == 127 ? in.readInt() : offsetByte * 900;
+    }
+
+    static long readEpochSec(DataInput in) throws IOException {
+        int hiByte = in.readByte() & 255;
+        if (hiByte == 255) {
+            return in.readLong();
+        } else {
+            int midByte = in.readByte() & 255;
+            int loByte = in.readByte() & 255;
+            long tot = ((hiByte << 16) + (midByte << 8) + loByte);
+            return (tot * 900) - 4575744000L;
+        }
+    }
+
+    static ZoneOffsetTransitionRule readZOTRule(DataInput in) throws IOException {
+        int data = in.readInt();
+        Month month = Month.of(data >>> 28);
+        int dom = ((data & (63 << 22)) >>> 22) - 32;
+        int dowByte = (data & (7 << 19)) >>> 19;
+        DayOfWeek dow = dowByte == 0 ? null : DayOfWeek.of(dowByte);
+        int timeByte = (data & (31 << 14)) >>> 14;
+        TimeDefinition defn = TimeDefinition.values()[(data & (3 << 12)) >>> 12];
+        int stdByte = (data & (255 << 4)) >>> 4;
+        int beforeByte = (data & (3 << 2)) >>> 2;
+        int afterByte = (data & 3);
+        LocalTime time = (timeByte == 31 ? LocalTime.ofSecondOfDay(in.readInt()) : LocalTime.of(timeByte % 24, 0));
+        ZoneOffset std = (stdByte == 255 ? ZoneOffset.ofTotalSeconds(in.readInt()) : ZoneOffset.ofTotalSeconds((stdByte - 128) * 900));
+        ZoneOffset before = (beforeByte == 3 ? ZoneOffset.ofTotalSeconds(in.readInt()) : ZoneOffset.ofTotalSeconds(std.getTotalSeconds() + beforeByte * 1800));
+        ZoneOffset after = (afterByte == 3 ? ZoneOffset.ofTotalSeconds(in.readInt()) : ZoneOffset.ofTotalSeconds(std.getTotalSeconds() + afterByte * 1800));
+        return ZoneOffsetTransitionRule.of(month, dom, dow, time, timeByte == 24, defn, std, before, after);
+    }
+
+    /////////////////////////ZoneRules --> ZoneInfo/////////////////////////////////
+
+    // ZoneInfo starts with UTC1900
+    private static final long UTC1900 = -2208988800L;
+    // ZoneInfo ends with   UTC2037
+    private static final long UTC2037 =
+        LocalDateTime.of(2038, 1, 1, 0, 0, 0).toEpochSecond(ZoneOffset.UTC) - 1;
+
+    /* Get a ZoneInfo instance.
+     *
+     * @param standardTransitions  the standard transitions, not null
+     * @param standardOffsets  the standard offsets, not null
+     * @param savingsInstantTransitions  the standard transitions, not null
+     * @param wallOffsets  the wall offsets, not null
+     * @param lastRules  the recurring last rules, size 15 or less, not null
+     */
+    private static ZoneInfo getZoneInfo(String zoneId,
+                                        long[] standardTransitions,
+                                        int[] standardOffsets,
+                                        long[] savingsInstantTransitions,
+                                        int[] wallOffsets,
+                                        ZoneOffsetTransitionRule[] lastRules) {
+        int rawOffset = 0;
+        int dstSavings = 0;
+        int checksum = 0;
+        int[] params = null;
+        boolean willGMTOffsetChange = false;
+
+        // rawOffset, pick the last one
+        if (standardTransitions.length > 0)
+            rawOffset = standardOffsets[standardOffsets.length - 1] * 1000;
+        else
+            rawOffset = standardOffsets[0] * 1000;
+
+        // transitions, offsets;
+        long[] transitions = null;
+        int[]  offsets = null;
+        int    nOffsets = 0;
+        int    nTrans = 0;
+
+        if (savingsInstantTransitions.length != 0) {
+            transitions = new long[250];
+            offsets = new int[100];    // TBD: ZoneInfo actually can't handle
+                                       // offsets.length > 16 (4-bit index limit)
+            // last year in trans table
+            // It should not matter to use before or after offset for year
+            int lastyear = LocalDateTime.ofEpochSecond(
+                savingsInstantTransitions[savingsInstantTransitions.length - 1], 0,
+                ZoneOffset.ofTotalSeconds(wallOffsets[savingsInstantTransitions.length - 1])).getYear();
+            // int lastyear = savingsLocalTransitions[savingsLocalTransitions.length - 1].getYear();
+
+            int i = 0, k = 1;
+            while (i < savingsInstantTransitions.length &&
+                   savingsInstantTransitions[i] < UTC1900) {
+                 i++;     // skip any date before UTC1900
+            }
+            if (i < savingsInstantTransitions.length) {
+                // javazic writes the last GMT offset into index 0!
+                if (i < savingsInstantTransitions.length) {
+                    offsets[0] = standardOffsets[standardOffsets.length - 1] * 1000;
+                    nOffsets = 1;
+                }
+                // ZoneInfo has a beginning entry for 1900.
+                // Only add it if this is not the only one in table
+                nOffsets = addTrans(transitions, nTrans++, offsets, nOffsets,
+                                    UTC1900,
+                                    wallOffsets[i],
+                                    getStandardOffset(standardTransitions, standardOffsets, UTC1900));
+            }
+            for (; i < savingsInstantTransitions.length; i++) {
+                //if (savingsLocalTransitions[i * 2].getYear() > LASTYEAR) {
+                if (savingsInstantTransitions[i] > UTC2037) {
+                    // no trans beyond LASTYEAR
+                    lastyear = LASTYEAR;
+                    break;
+                }
+                long trans = savingsInstantTransitions[i];
+                while (k < standardTransitions.length) {
+                    // some standard offset transitions don't exist in
+                    // savingInstantTrans, if the offset "change" doesn't
+                    // really change the "effectiveWallOffset". For example
+                    // the 1999/2000 pair in Zone Arg/Buenos_Aires, in which
+                    // the daylightsaving "happened" but it actually does
+                    //  not result in the timezone switch. ZoneInfo however
+                    // needs them in its transitions table
+                    long trans_s = standardTransitions[k];
+                    if (trans_s >= UTC1900) {
+                        if (trans_s > trans)
+                            break;
+                        if (trans_s < trans) {
+                            if (nOffsets + 2 >= offsets.length) {
+                                offsets = Arrays.copyOf(offsets, offsets.length + 100);
+                            }
+                            if (nTrans + 1 >= transitions.length) {
+                                transitions = Arrays.copyOf(transitions, transitions.length + 100);
+                            }
+                            nOffsets = addTrans(transitions, nTrans++, offsets, nOffsets,
+                                                trans_s,
+                                                wallOffsets[i],
+                                                standardOffsets[k+1]);
+                        }
+                    }
+                    k++;
+                }
+                if (nOffsets + 2 >= offsets.length) {
+                    offsets = Arrays.copyOf(offsets, offsets.length + 100);
+                }
+                if (nTrans + 1 >= transitions.length) {
+                    transitions = Arrays.copyOf(transitions, transitions.length + 100);
+                }
+                nOffsets = addTrans(transitions, nTrans++, offsets, nOffsets,
+                                    trans,
+                                    wallOffsets[i + 1],
+                                    getStandardOffset(standardTransitions, standardOffsets, trans));
+            }
+            // append any leftover standard trans
+            while (k < standardTransitions.length) {
+                long trans = standardTransitions[k];
+                if (trans >= UTC1900) {
+                    int offset = wallOffsets[i];
+                    int offsetIndex = indexOf(offsets, 0, nOffsets, offset);
+                    if (offsetIndex == nOffsets)
+                        nOffsets++;
+                    transitions[nTrans++] = ((trans * 1000) << TRANSITION_NSHIFT) |
+                                            (offsetIndex & OFFSET_MASK);
+                }
+                k++;
+            }
+            if (lastRules.length > 1) {
+                // fill the gap between the last trans until LASTYEAR
+                while (lastyear++ < LASTYEAR) {
+                    for (ZoneOffsetTransitionRule zotr : lastRules) {
+                        ZoneOffsetTransition zot = zotr.createTransition(lastyear);
+                        //long trans = zot.getDateTimeBefore().toEpochSecond();
+                        long trans = zot.toEpochSecond();
+                        if (nOffsets + 2 >= offsets.length) {
+                            offsets = Arrays.copyOf(offsets, offsets.length + 100);
+                        }
+                        if (nTrans + 1 >= transitions.length) {
+                            transitions = Arrays.copyOf(transitions, transitions.length + 100);
+                        }
+                        nOffsets = addTrans(transitions, nTrans++, offsets, nOffsets,
+                                            trans,
+                                            zot.getOffsetAfter().getTotalSeconds(),
+                                            getStandardOffset(standardTransitions, standardOffsets, trans));
+                    }
+                }
+                ZoneOffsetTransitionRule startRule =  lastRules[lastRules.length - 2];
+                ZoneOffsetTransitionRule endRule =  lastRules[lastRules.length - 1];
+                params = new int[10];
+                if (startRule.getOffsetBefore().compareTo(startRule.getOffsetAfter()) < 0 &&
+                    endRule.getOffsetBefore().compareTo(endRule.getOffsetAfter()) > 0) {
+                    ZoneOffsetTransitionRule tmp;
+                    tmp = startRule;
+                    startRule = endRule;
+                    endRule = tmp;
+                }
+                params[0] = startRule.getMonth().getValue() - 1;
+                // params[1] = startRule.getDayOfMonthIndicator();
+                // params[2] = toCalendarDOW[startRule.getDayOfWeek().getValue()];
+                int       dom = startRule.getDayOfMonthIndicator();
+                DayOfWeek dow = startRule.getDayOfWeek();
+                if (dow == null) {
+                    params[1] = startRule.getDayOfMonthIndicator();
+                    params[2] = 0;
+                } else {
+                    // ZoneRulesBuilder adjusts < 0 case (-1, for last, don't have
+                    // "<=" case yet) to positive value if not February (it appears
+                    // we don't have February cutoff in tzdata table yet)
+                    // Ideally, if JSR310 can just pass in the nagative and
+                    // we can then pass in the dom = -1, dow > 0 into ZoneInfo
+                    //
+                    // hacking, assume the >=24 is the result of ZRB optimization for
+                    // "last", it works for now.
+                    if (dom < 0 || dom >= 24) {
+                        params[1] = -1;
+                        params[2] = toCalendarDOW[dow.getValue()];
+                    } else {
+                        params[1] = dom;
+                        // To specify a day of week on or after an exact day of month,
+                        // set the month to an exact month value, day-of-month to the
+                        // day on or after which the rule is applied, and day-of-week
+                        // to a negative Calendar.DAY_OF_WEEK DAY_OF_WEEK field value.
+                        params[2] = -toCalendarDOW[dow.getValue()];
+                    }
+                }
+                params[3] = startRule.getLocalTime().toSecondOfDay() * 1000;
+                params[4] = toSTZTime[startRule.getTimeDefinition().ordinal()];
+
+                params[5] = endRule.getMonth().getValue() - 1;
+                // params[6] = endRule.getDayOfMonthIndicator();
+                // params[7] = toCalendarDOW[endRule.getDayOfWeek().getValue()];
+                dom = endRule.getDayOfMonthIndicator();
+                dow = endRule.getDayOfWeek();
+                if (dow == null) {
+                    params[6] = dom;
+                    params[7] = 0;
+                } else {
+                    // hacking: see comment above
+                    if (dom < 0 || dom >= 24) {
+                        params[6] = -1;
+                        params[7] = toCalendarDOW[dow.getValue()];
+                    } else {
+                        params[6] = dom;
+                        params[7] = -toCalendarDOW[dow.getValue()];
+                    }
+                }
+                params[8] = endRule.getLocalTime().toSecondOfDay() * 1000;
+                params[9] = toSTZTime[endRule.getTimeDefinition().ordinal()];
+                dstSavings = (startRule.getOffsetAfter().getTotalSeconds()
+                             - startRule.getOffsetBefore().getTotalSeconds()) * 1000;
+                // Note: known mismatching -> Asia/Amman
+                // ZoneInfo :      startDayOfWeek=5     <= Thursday
+                //                 startTime=86400000   <= 24 hours
+                // This:           startDayOfWeek=6
+                //                 startTime=0
+                // Below is the workaround, it probably slows down everyone a little
+                if (params[2] == 6 && params[3] == 0 && zoneId.equals("Asia/Amman")) {
+                    params[2] = 5;
+                    params[3] = 86400000;
+                }
+            } else if (nTrans > 0) {  // only do this if there is something in table already
+                if (lastyear < LASTYEAR) {
+                    // ZoneInfo has an ending entry for 2037
+                    long trans = OffsetDateTime.of(LASTYEAR, Month.JANUARY.getValue(), 1, 0, 0, 0, 0,
+                                                   ZoneOffset.ofTotalSeconds(rawOffset/1000))
+                                               .toEpochSecond();
+                    int offsetIndex = indexOf(offsets, 0, nOffsets, rawOffset/1000);
+                    if (offsetIndex == nOffsets)
+                        nOffsets++;
+                    transitions[nTrans++] = (trans * 1000) << TRANSITION_NSHIFT |
+                                       (offsetIndex & OFFSET_MASK);
+                } else if (savingsInstantTransitions.length > 2) {
+                    // Workaround: create the params based on the last pair for
+                    // zones like Israel and Iran which have trans defined
+                    // up until 2037, but no "transition rule" defined
+                    //
+                    // Note: Known mismatching for Israel, Asia/Jerusalem/Tel Aviv
+                    // ZoneInfo:        startMode=3
+                    //                  startMonth=2
+                    //                  startDay=26
+                    //                  startDayOfWeek=6
+                    //
+                    // This:            startMode=1
+                    //                  startMonth=2
+                    //                  startDay=27
+                    //                  startDayOfWeek=0
+                    // these two are actually the same for 2037, the SimpleTimeZone
+                    // for the last "known" year
+                    int m = savingsInstantTransitions.length;
+                    long startTrans = savingsInstantTransitions[m - 2];
+                    int startOffset = wallOffsets[m - 2 + 1];
+                    int startStd = getStandardOffset(standardTransitions, standardOffsets, startTrans);
+                    long endTrans =  savingsInstantTransitions[m - 1];
+                    int endOffset = wallOffsets[m - 1 + 1];
+                    int endStd = getStandardOffset(standardTransitions, standardOffsets, endTrans);
+
+                    if (startOffset > startStd && endOffset == endStd) {
+                        /*
+                        m = savingsLocalTransitions.length;
+                        LocalDateTime startLDT = savingsLocalTransitions[m -4];  //gap
+                        LocalDateTime endLDT = savingsLocalTransitions[m - 1];   //over
+                         */
+                        // last - 1 trans
+                        m = savingsInstantTransitions.length - 2;
+                        ZoneOffset before = ZoneOffset.ofTotalSeconds(wallOffsets[m]);
+                        ZoneOffset after = ZoneOffset.ofTotalSeconds(wallOffsets[m + 1]);
+                        ZoneOffsetTransition trans = ZoneOffsetTransition.of(
+                            LocalDateTime.ofEpochSecond(savingsInstantTransitions[m], 0, before),
+                            before,
+                            after);
+                        LocalDateTime startLDT;
+                        if (trans.isGap()) {
+                            startLDT = trans.getDateTimeBefore();
+                        } else {
+                            startLDT = trans.getDateTimeAfter();
+                        }
+                        // last trans
+                        m = savingsInstantTransitions.length - 1;
+                        before = ZoneOffset.ofTotalSeconds(wallOffsets[m]);
+                        after = ZoneOffset.ofTotalSeconds(wallOffsets[m + 1]);
+                        trans = ZoneOffsetTransition.of(
+                            LocalDateTime.ofEpochSecond(savingsInstantTransitions[m], 0, before),
+                            before,
+                            after);
+                        LocalDateTime endLDT;
+                        if (trans.isGap()) {
+                            endLDT = trans.getDateTimeAfter();
+                        } else {
+                            endLDT = trans.getDateTimeBefore();
+                        }
+                        params = new int[10];
+                        params[0] = startLDT.getMonthValue() - 1;
+                        params[1] = startLDT.getDayOfMonth();
+                        params[2] = 0;
+                        params[3] = startLDT.toLocalTime().toSecondOfDay() * 1000;
+                        params[4] = SimpleTimeZone.WALL_TIME;
+                        params[5] = endLDT.getMonthValue() - 1;
+                        params[6] = endLDT.getDayOfMonth();
+                        params[7] = 0;
+                        params[8] = endLDT.toLocalTime().toSecondOfDay() * 1000;
+                        params[9] = SimpleTimeZone.WALL_TIME;
+                        dstSavings = (startOffset - startStd) * 1000;
+                    }
+                }
+            }
+            if (transitions != null && transitions.length != nTrans) {
+                if (nTrans == 0) {
+                   transitions = null;
+                } else {
+                    transitions = Arrays.copyOf(transitions, nTrans);
+                }
+            }
+            if (offsets != null && offsets.length != nOffsets) {
+                if (nOffsets == 0) {
+                   offsets = null;
+                } else {
+                    offsets = Arrays.copyOf(offsets, nOffsets);
+                }
+            }
+            if (transitions != null) {
+                Checksum sum = new Checksum();
+                for (i = 0; i < transitions.length; i++) {
+                    long val = transitions[i];
+                    int dst = (int)((val >>> DST_NSHIFT) & 0xfL);
+                    int saving = (dst == 0) ? 0 : offsets[dst];
+                    int index = (int)(val & OFFSET_MASK);
+                    int offset = offsets[index];
+                    long second = (val >> TRANSITION_NSHIFT);
+                    // javazic uses "index of the offset in offsets",
+                    // instead of the real offset value itself to
+                    // calculate the checksum. Have to keep doing
+                    // the same thing, checksum is part of the
+                    // ZoneInfo serialization form.
+                    sum.update(second + index);
+                    sum.update(index);
+                    sum.update(dst == 0 ? -1 : dst);
+                }
+                checksum = (int)sum.getValue();
+            }
+        }
+        return new ZoneInfo(zoneId, rawOffset, dstSavings, checksum, transitions,
+                            offsets, params, willGMTOffsetChange);
+    }
+
+    private static int getStandardOffset(long[] standardTransitions,
+                                         int[] standardOffsets,
+                                         long epochSec) {
+        int index  = Arrays.binarySearch(standardTransitions, epochSec);
+        if (index < 0) {
+            // switch negative insert position to start of matched range
+            index = -index - 2;
+        }
+        return standardOffsets[index + 1];
+    }
+
+    private static int toCalendarDOW[] = new int[] {
+        -1,
+        Calendar.MONDAY,
+        Calendar.TUESDAY,
+        Calendar.WEDNESDAY,
+        Calendar.THURSDAY,
+        Calendar.FRIDAY,
+        Calendar.SATURDAY,
+        Calendar.SUNDAY
+    };
+
+    private static int toSTZTime[] = new int[] {
+        SimpleTimeZone.UTC_TIME,
+        SimpleTimeZone.WALL_TIME,
+        SimpleTimeZone.STANDARD_TIME,
+    };
+
+    private static final long OFFSET_MASK = 0x0fL;
+    private static final long DST_MASK = 0xf0L;
+    private static final int  DST_NSHIFT = 4;
+    private static final int  TRANSITION_NSHIFT = 12;
+    private static final int  LASTYEAR = 2037;
+
+    // from: 0 for offset lookup, 1 for dstsvings lookup
+    private static int indexOf(int[] offsets, int from, int nOffsets, int offset) {
+        offset *= 1000;
+        for (; from < nOffsets; from++) {
+            if (offsets[from] == offset)
+                return from;
+        }
+        offsets[from] = offset;
+        return from;
+    }
+
+    // return updated nOffsets
+    private static int addTrans(long transitions[], int nTrans,
+                                int offsets[], int nOffsets,
+                                long trans, int offset, int stdOffset) {
+        int offsetIndex = indexOf(offsets, 0, nOffsets, offset);
+        if (offsetIndex == nOffsets)
+            nOffsets++;
+        int dstIndex = 0;
+        if (offset != stdOffset) {
+            dstIndex = indexOf(offsets, 1, nOffsets, offset - stdOffset);
+            if (dstIndex == nOffsets)
+                nOffsets++;
+        }
+        transitions[nTrans] = ((trans * 1000) << TRANSITION_NSHIFT) |
+                              ((dstIndex << DST_NSHIFT) & DST_MASK) |
+                              (offsetIndex & OFFSET_MASK);
+        return nOffsets;
+    }
+
+    /////////////////////////////////////////////////////////////
+    // ZoneInfo checksum, copy/pasted from javazic
+    private static class Checksum extends CRC32 {
+        public void update(int val) {
+            byte[] b = new byte[4];
+            b[0] = (byte)((val >>> 24) & 0xff);
+            b[1] = (byte)((val >>> 16) & 0xff);
+            b[2] = (byte)((val >>> 8) & 0xff);
+            b[3] = (byte)(val & 0xff);
+            update(b);
+        }
+        void update(long val) {
+            byte[] b = new byte[8];
+            b[0] = (byte)((val >>> 56) & 0xff);
+            b[1] = (byte)((val >>> 48) & 0xff);
+            b[2] = (byte)((val >>> 40) & 0xff);
+            b[3] = (byte)((val >>> 32) & 0xff);
+            b[4] = (byte)((val >>> 24) & 0xff);
+            b[5] = (byte)((val >>> 16) & 0xff);
+            b[6] = (byte)((val >>> 8) & 0xff);
+            b[7] = (byte)(val & 0xff);
+            update(b);
+        }
+    }
 }
diff --git a/jdk/src/share/classes/sun/util/locale/provider/CalendarDataUtility.java b/jdk/src/share/classes/sun/util/locale/provider/CalendarDataUtility.java
index 5b11c6c..656b695 100644
--- a/jdk/src/share/classes/sun/util/locale/provider/CalendarDataUtility.java
+++ b/jdk/src/share/classes/sun/util/locale/provider/CalendarDataUtility.java
@@ -66,17 +66,43 @@
         LocaleServiceProviderPool pool =
                 LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
         return pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),
-                                       field, value, style);
+                                       field, value, style, false);
+    }
+
+    public static String retrieveCldrFieldValueName(String id, int field, int value, int style, Locale locale) {
+        LocaleServiceProviderPool pool =
+                LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
+        String name;
+        name = pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),
+                                       field, value, style, true);
+        if (name == null) {
+            name = pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),
+                                           field, value, style, false);
+        }
+        return name;
     }
 
     public static Map<String, Integer> retrieveFieldValueNames(String id, int field, int style, Locale locale) {
         LocaleServiceProviderPool pool =
             LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
         return pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,
-                                       normalizeCalendarType(id), field, style);
+                                       normalizeCalendarType(id), field, style, false);
     }
 
-    private static String normalizeCalendarType(String requestID) {
+    public static Map<String, Integer> retrieveCldrFieldValueNames(String id, int field, int style, Locale locale) {
+        LocaleServiceProviderPool pool =
+            LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
+        Map<String, Integer> map;
+        map = pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,
+                                       normalizeCalendarType(id), field, style, true);
+        if (map == null) {
+            map = pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,
+                                           normalizeCalendarType(id), field, style, false);
+        }
+        return map;
+    }
+
+    static String normalizeCalendarType(String requestID) {
         String type;
         if (requestID.equals("gregorian") || requestID.equals("iso8601")) {
             type = "gregory";
@@ -103,10 +129,20 @@
                                 Locale locale,
                                 String requestID, // calendarType
                                 Object... params) {
-            assert params.length == 3;
+            assert params.length == 4;
             int field = (int) params[0];
             int value = (int) params[1];
             int style = (int) params[2];
+            boolean cldr = (boolean) params[3];
+
+            // If cldr is true, resources from CLDR have precedence over JRE
+            // native resources.
+            if (cldr && calendarNameProvider instanceof CalendarNameProviderImpl) {
+                String name;
+                name = ((CalendarNameProviderImpl)calendarNameProvider)
+                        .getCldrDisplayName(requestID, field, value, style, locale);
+                return name;
+            }
             return calendarNameProvider.getDisplayName(requestID, field, value, style, locale);
         }
     }
@@ -126,9 +162,19 @@
                                               Locale locale,
                                               String requestID, // calendarType
                                               Object... params) {
-            assert params.length == 2;
+            assert params.length == 3;
             int field = (int) params[0];
             int style = (int) params[1];
+            boolean cldr = (boolean) params[2];
+
+            // If cldr is true, resources from CLDR have precedence over JRE
+            // native resources.
+            if (cldr && calendarNameProvider instanceof CalendarNameProviderImpl) {
+                Map<String, Integer> map;
+                map = ((CalendarNameProviderImpl)calendarNameProvider)
+                        .getCldrDisplayNames(requestID, field, style, locale);
+                return map;
+            }
             return calendarNameProvider.getDisplayNames(requestID, field, style, locale);
         }
     }
diff --git a/jdk/src/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java b/jdk/src/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java
index 6aa2893..afdfd07 100644
--- a/jdk/src/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java
+++ b/jdk/src/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java
@@ -50,14 +50,25 @@
 
     @Override
     public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
+        return getDisplayNameImpl(calendarType, field, value, style, locale, false);
+    }
+
+    public String getCldrDisplayName(String calendarType, int field, int value, int style, Locale locale) {
+        return getDisplayNameImpl(calendarType, field, value, style, locale, true);
+    }
+
+    public String getDisplayNameImpl(String calendarType, int field, int value, int style, Locale locale, boolean cldr) {
         String name = null;
-        String key = getResourceKey(calendarType, field, style);
+        String key = getResourceKey(calendarType, field, style, cldr);
         if (key != null) {
             String[] strings = LocaleProviderAdapter.forType(type).getLocaleResources(locale).getCalendarNames(key);
             if (strings != null && strings.length > 0) {
                 if (field == DAY_OF_WEEK || field == YEAR) {
                     --value;
                 }
+                if (value < 0 || value >= strings.length) {
+                    return null;
+                }
                 name = strings[value];
                 // If name is empty in standalone, try its `format' style.
                 if (name.length() == 0
@@ -76,24 +87,32 @@
         SHORT_STANDALONE, LONG_FORMAT, LONG_STANDALONE,
         NARROW_FORMAT, NARROW_STANDALONE
     };
+
     @Override
     public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
         Map<String, Integer> names;
         if (style == ALL_STYLES) {
-            names = getDisplayNamesImpl(calendarType, field, SHORT_FORMAT, locale);
+            names = getDisplayNamesImpl(calendarType, field, SHORT_FORMAT, locale, false);
             for (int st : REST_OF_STYLES) {
-                names.putAll(getDisplayNamesImpl(calendarType, field, st, locale));
+                names.putAll(getDisplayNamesImpl(calendarType, field, st, locale, false));
             }
         } else {
             // specific style
-            names = getDisplayNamesImpl(calendarType, field, style, locale);
+            names = getDisplayNamesImpl(calendarType, field, style, locale, false);
         }
         return names.isEmpty() ? null : names;
     }
 
+    // NOTE: This method should be used ONLY BY JSR 310 classes.
+    public Map<String, Integer> getCldrDisplayNames(String calendarType, int field, int style, Locale locale) {
+        Map<String, Integer> names;
+        names = getDisplayNamesImpl(calendarType, field, style, locale, true);
+        return names.isEmpty() ? null : names;
+    }
+
     private Map<String, Integer> getDisplayNamesImpl(String calendarType, int field,
-                                                     int style, Locale locale) {
-        String key = getResourceKey(calendarType, field, style);
+                                                     int style, Locale locale, boolean cldr) {
+        String key = getResourceKey(calendarType, field, style, cldr);
         Map<String, Integer> map = new TreeMap<>(LengthBasedComparator.INSTANCE);
         if (key != null) {
             String[] strings = LocaleProviderAdapter.forType(type).getLocaleResources(locale).getCalendarNames(key);
@@ -201,7 +220,7 @@
         return false;
     }
 
-    private String getResourceKey(String type, int field, int style) {
+    private String getResourceKey(String type, int field, int style, boolean cldr) {
         int baseStyle = getBaseStyle(style);
         boolean isStandalone = (style != baseStyle);
 
@@ -210,6 +229,10 @@
         }
         boolean isNarrow = (baseStyle == NARROW_FORMAT);
         StringBuilder key = new StringBuilder();
+        // If cldr is true, use prefix "cldr.".
+        if (cldr) {
+            key.append("cldr.");
+        }
         switch (field) {
         case ERA:
             if (type != null) {
@@ -222,6 +245,11 @@
                 // due to historical reasons. (JRE DateFormatSymbols.getEras returns
                 // abbreviations while other getShort*() return abbreviations.)
                 if (this.type == LocaleProviderAdapter.Type.JRE) {
+                    if (cldr) {
+                        if (baseStyle == LONG) {
+                            key.append("long.");
+                        }
+                    }
                     if (baseStyle == SHORT) {
                         key.append("short.");
                     }
diff --git a/jdk/src/share/classes/sun/util/locale/provider/LocaleResources.java b/jdk/src/share/classes/sun/util/locale/provider/LocaleResources.java
index 009cc5b..dafa74e 100644
--- a/jdk/src/share/classes/sun/util/locale/provider/LocaleResources.java
+++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleResources.java
@@ -332,23 +332,61 @@
     }
 
     public String getDateTimePattern(int timeStyle, int dateStyle, Calendar cal) {
-        String pattern;
-
         if (cal == null) {
             cal = Calendar.getInstance(locale);
         }
-        String calType = cal.getCalendarType();
+        return getDateTimePattern(null, timeStyle, dateStyle, cal.getCalendarType());
+    }
+
+    /**
+     * Returns a date-time format pattern
+     * @param timeStyle style of time; one of FULL, LONG, MEDIUM, SHORT in DateFormat,
+     *                  or -1 if not required
+     * @param dateStyle style of time; one of FULL, LONG, MEDIUM, SHORT in DateFormat,
+     *                  or -1 if not required
+     * @param calType   the calendar type for the pattern
+     * @return the pattern string
+     */
+    public String getCldrDateTimePattern(int timeStyle, int dateStyle, String calType) {
+        calType = CalendarDataUtility.normalizeCalendarType(calType);
+        String pattern;
+        pattern = getDateTimePattern("cldr.", timeStyle, dateStyle, calType);
+        if (pattern == null) {
+            pattern = getDateTimePattern(null, timeStyle, dateStyle, calType);
+        }
+        return pattern;
+    }
+
+    private String getDateTimePattern(String prefix, int timeStyle, int dateStyle, String calType) {
+        String pattern;
         String timePattern = null;
         String datePattern = null;
+
         if (timeStyle >= 0) {
-            timePattern = getDateTimePattern("TimePatterns", timeStyle, calType);
+            if (prefix != null) {
+                timePattern = getDateTimePattern(prefix, "TimePatterns", timeStyle, calType);
+            }
+            if (timePattern == null) {
+                timePattern = getDateTimePattern(null, "TimePatterns", timeStyle, calType);
+            }
         }
         if (dateStyle >= 0) {
-            datePattern = getDateTimePattern("DatePatterns", dateStyle, calType);
+            if (prefix != null) {
+                datePattern = getDateTimePattern(prefix, "DatePatterns", dateStyle, calType);
+            }
+            if (datePattern == null) {
+                datePattern = getDateTimePattern(null, "DatePatterns", dateStyle, calType);
+            }
         }
         if (timeStyle >= 0) {
             if (dateStyle >= 0) {
-                String dateTimePattern = getDateTimePattern("DateTimePatterns", 0, calType);
+                String dateTimePattern = null;
+                if (prefix != null) {
+                    dateTimePattern = getDateTimePattern(prefix, "DateTimePatterns", 0, calType);
+                }
+                if (dateTimePattern == null) {
+                    dateTimePattern = getDateTimePattern(null, "DateTimePatterns", 0, calType);
+                }
                 switch (dateTimePattern) {
                 case "{1} {0}":
                     pattern = datePattern + " " + timePattern;
@@ -396,27 +434,40 @@
         return localeData.getDateFormatData(locale);
     }
 
-    private String getDateTimePattern(String key, int styleIndex, String calendarType) {
-        String resourceKey = "gregory".equals(calendarType) ? key : calendarType + "." + key;
-        String cacheKey = DATE_TIME_PATTERN + resourceKey;
-        String[] patterns = null;
+    private String getDateTimePattern(String prefix, String key, int styleIndex, String calendarType) {
+        StringBuilder sb = new StringBuilder();
+        if (prefix != null) {
+            sb.append(prefix);
+        }
+        if (!"gregory".equals(calendarType)) {
+            sb.append(calendarType).append('.');
+        }
+        sb.append(key);
+        String resourceKey = sb.toString();
+        String cacheKey = sb.insert(0, DATE_TIME_PATTERN).toString();
 
         removeEmptyReferences();
         ResourceReference data = cache.get(cacheKey);
+        Object value = NULLOBJECT;
 
-        if (data == null || ((patterns = (String[]) data.get()) == null)) {
+        if (data == null || ((value = data.get()) == null)) {
             ResourceBundle r = localeData.getDateFormatData(locale);
             if (r.containsKey(resourceKey)) {
-                patterns = r.getStringArray(resourceKey);
+                value = r.getStringArray(resourceKey);
             } else {
                 assert !resourceKey.equals(key);
-                patterns = r.getStringArray(key);
+                if (r.containsKey(key)) {
+                    value = r.getStringArray(key);
+                }
             }
             cache.put(cacheKey,
-                      new ResourceReference(cacheKey, (Object) patterns, referenceQueue));
+                      new ResourceReference(cacheKey, value, referenceQueue));
         }
-
-        return patterns[styleIndex];
+        if (value == NULLOBJECT) {
+            assert prefix != null;
+            return null;
+        }
+        return ((String[])value)[styleIndex];
     }
 
     private static class ResourceReference extends SoftReference<Object> {
diff --git a/jdk/src/share/javavm/export/jvm.h b/jdk/src/share/javavm/export/jvm.h
index 56a8abb..44b0be5 100644
--- a/jdk/src/share/javavm/export/jvm.h
+++ b/jdk/src/share/javavm/export/jvm.h
@@ -822,6 +822,13 @@
 JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index);
 
 /*
+ * Is the given method generated by the VM.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jboolean JNICALL
+JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cb, int index);
+
+/*
  * Returns the name of a given method in UTF format.
  * The result remains valid until JVM_ReleaseUTF is called.
  *
@@ -1401,8 +1408,7 @@
      * the new bit is also added in the main/baseline.
      */
     unsigned int is_attach_supported : 1;
-    unsigned int is_kernel_jvm : 1;
-    unsigned int : 30;
+    unsigned int : 31;
     unsigned int : 32;
     unsigned int : 32;
 } jvm_version_info;
diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
index bc91827..4b5e38a 100644
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
@@ -4758,8 +4758,8 @@
     PTRLIST_QSORT(cp.requested_bsms, outputEntry_cmp);
     // append the BootstrapMethods attribute (after the InnerClasses attr):
     putref(cp.sym[cpool::s_BootstrapMethods]);
+    // make a note of the offset, for lazy patching
     int sizeOffset = (int)wpoffset();
-    byte* sizewp = wp;
     putu4(-99);  // attr size will be patched
     putu2(cur_class_local_bsm_count);
     int written_bsms = 0;
@@ -4776,6 +4776,7 @@
       written_bsms += 1;
     }
     assert(written_bsms == cur_class_local_bsm_count);  // else insane
+    byte* sizewp = wp_at(sizeOffset);
     putu4_at(sizewp, (int)(wp - (sizewp+4)));  // size of code attr
     putu2_at(wp_at(naOffset), ++na);  // increment class attr count
   }
diff --git a/jdk/src/share/native/common/check_code.c b/jdk/src/share/native/common/check_code.c
index c5e8855..c761a3d 100644
--- a/jdk/src/share/native/common/check_code.c
+++ b/jdk/src/share/native/common/check_code.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -983,6 +983,12 @@
         CCerror(context, "Inconsistent access bits.");
     }
 
+    // If this method is an overpass method, which is generated by the VM,
+    // we trust the code and no check needs to be done.
+    if (JVM_IsVMGeneratedMethodIx(env, cb, method_index)) {
+      return;
+    }
+
     /* Run through the code.  Mark the start of each instruction, and give
      * the instruction a number */
     for (i = 0, offset = 0; offset < code_length; i++) {
diff --git a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
index 0f39761..b405618 100644
--- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
+++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
@@ -2694,6 +2694,11 @@
             scale[i] = (UINT8*) malloc((maxBandValue + 1) * sizeof(UINT8));
 
             if (scale[i] == NULL) {
+                // Cleanup before throwing an out of memory exception
+                for (j = 0; j < i; j++) {
+                    free(scale[j]);
+                }
+                free(scale);
                 JNU_ThrowByName( env, "java/lang/OutOfMemoryError",
                                  "Writing JPEG Stream");
                 return JNI_FALSE;
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv.h b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv.h
index 82243b9..24d99ce 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv.h
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv.h
@@ -31,6 +31,16 @@
 extern "C" {
 #endif /* __cplusplus */
 
+// Shared macro defined for cleanup of allocated memory.
+#ifndef FREE_AND_RETURN_STATUS
+#define FREE_AND_RETURN_STATUS \
+{ \
+if (pbuff != buff) mlib_free(pbuff); \
+if (k != akernel) mlib_free(k); \
+return status; \
+}
+#endif /* FREE_AND_RETURN_STATUS */
+
 void mlib_ImageXor80_aa(mlib_u8  *dl,
                         mlib_s32 wid,
                         mlib_s32 hgt,
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConvMxN_ext.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConvMxN_ext.c
index e489f57..88ade07 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConvMxN_ext.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConvMxN_ext.c
@@ -253,8 +253,10 @@
   if (mn > 256) {
     dkernel = mlib_malloc(mn * sizeof(mlib_d64));
 
-    if (dkernel == NULL)
+    if (dkernel == NULL) {
+      if (dsa != dspace) mlib_free(dsa);
       return MLIB_FAILURE;
+    }
   }
 
   while (scale > 30) {
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c
index 5ddcbb3..70f3831 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c
@@ -1884,6 +1884,8 @@
   mlib_s32 nchannel, chan1, chan2;
   mlib_s32 i, j, c, swid;
   d64_2x32 dd;
+  mlib_status status = MLIB_SUCCESS;
+
   GET_SRC_DST_PARAMETERS(DTYPE);
 
   if (scale > 30) {
@@ -1905,7 +1907,10 @@
     k[i] = kernel[i]*fscale;
   }
 
-  if (m == 1) return mlib_ImageConv1xN_ext(dst, src, k, n, dy_t, dy_b, cmask);
+  if (m == 1) {
+    status = mlib_ImageConv1xN_ext(dst, src, k, n, dy_t, dy_b, cmask);
+    FREE_AND_RETURN_STATUS;
+  }
 
   swid = wid + (m - 1);
 
@@ -1914,7 +1919,10 @@
   if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
     pbuff = mlib_malloc(sizeof(FTYPE)*bsize + sizeof(FTYPE *)*2*(n + 1));
 
-    if (pbuff == NULL) return MLIB_FAILURE;
+    if (pbuff == NULL) {
+      status = MLIB_FAILURE;
+      FREE_AND_RETURN_STATUS;
+    }
     buffs = (FTYPE   **)(pbuff + bsize);
   }
 
@@ -2318,9 +2326,7 @@
     }
   }
 
-  if (pbuff != buff) mlib_free(pbuff);
-
-  return MLIB_SUCCESS;
+  FREE_AND_RETURN_STATUS;
 }
 
 /***************************************************************/
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c
index 8c5ada3..7fc3d5e 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c
@@ -1651,6 +1651,8 @@
   DEF_VARS(DTYPE);
   mlib_s32 chan2;
   mlib_s32 *buffo, *buffi;
+  mlib_status status = MLIB_SUCCESS;
+
   GET_SRC_DST_PARAMETERS(DTYPE);
 
   if (scale > 30) {
@@ -1672,14 +1674,20 @@
     k[i] = kernel[i]*fscale;
   }
 
-  if (m == 1) return mlib_ImageConv1xN(dst, src, k, n, dn, cmask);
+  if (m == 1) {
+    status = mlib_ImageConv1xN(dst, src, k, n, dn, cmask);
+    FREE_AND_RETURN_STATUS;
+  }
 
   bsize = (n + 3)*wid;
 
   if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
     pbuff = mlib_malloc(sizeof(FTYPE)*bsize + sizeof(FTYPE *)*2*(n + 1));
 
-    if (pbuff == NULL) return MLIB_FAILURE;
+    if (pbuff == NULL) {
+      status = MLIB_FAILURE;
+      FREE_AND_RETURN_STATUS;
+    }
     buffs = (FTYPE   **)(pbuff + bsize);
   }
 
@@ -2033,9 +2041,7 @@
     }
   }
 
-  if (pbuff != buff) mlib_free(pbuff);
-
-  return MLIB_SUCCESS;
+  FREE_AND_RETURN_STATUS;
 }
 
 /***************************************************************/
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_32nw.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_32nw.c
index eb70373..9d80ddd 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_32nw.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_32nw.c
@@ -1160,6 +1160,8 @@
   DEF_VARS_MxN(mlib_s32);
   mlib_s32 chan2 = chan1 + chan1;
 
+  mlib_status status = MLIB_SUCCESS;
+
   if (scale > 30) {
     fscale *= 1.0/(1 << 30);
     scale -= 30;
@@ -1179,14 +1181,20 @@
     k[i] = kernel[i]*fscale;
   }
 
-  if (m == 1) return mlib_ImageConv1xN(dst, src, k, n, dn, cmask);
+  if (m == 1) {
+    status = mlib_ImageConv1xN(dst, src, k, n, dn, cmask);
+    FREE_AND_RETURN_STATUS;
+  }
 
   bsize = (n + 2)*wid;
 
   if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
     pbuff = mlib_malloc(sizeof(mlib_d64)*bsize + sizeof(mlib_d64*)*2*(n + 1));
 
-    if (pbuff == NULL) return MLIB_FAILURE;
+    if (pbuff == NULL) {
+      status = MLIB_FAILURE;
+      FREE_AND_RETURN_STATUS;
+    }
     buffs = (mlib_d64**)(pbuff + bsize);
   }
 
@@ -1531,9 +1539,7 @@
     }
   }
 
-  if (pbuff != buff) mlib_free(pbuff);
-
-  return MLIB_SUCCESS;
+  FREE_AND_RETURN_STATUS;
 }
 
 /***************************************************************/
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c
index 3a006ed..1ca321e 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c
@@ -1884,6 +1884,8 @@
   mlib_s32 nchannel, chan1, chan2;
   mlib_s32 i, j, c, swid;
   d64_2x32 dd;
+  mlib_status status = MLIB_SUCCESS;
+
   GET_SRC_DST_PARAMETERS(DTYPE);
 
   if (scale > 30) {
@@ -1905,7 +1907,10 @@
     k[i] = kernel[i]*fscale;
   }
 
-  if (m == 1) return mlib_ImageConv1xN_ext(dst, src, k, n, dy_t, dy_b, cmask);
+  if (m == 1) {
+    status = mlib_ImageConv1xN_ext(dst, src, k, n, dy_t, dy_b, cmask);
+    FREE_AND_RETURN_STATUS;
+  }
 
   swid = wid + (m - 1);
 
@@ -1914,7 +1919,10 @@
   if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
     pbuff = mlib_malloc(sizeof(FTYPE)*bsize + sizeof(FTYPE *)*2*(n + 1));
 
-    if (pbuff == NULL) return MLIB_FAILURE;
+    if (pbuff == NULL) {
+      status = MLIB_FAILURE;
+      FREE_AND_RETURN_STATUS;
+    }
     buffs = (FTYPE   **)(pbuff + bsize);
   }
 
@@ -2318,9 +2326,7 @@
     }
   }
 
-  if (pbuff != buff) mlib_free(pbuff);
-
-  return MLIB_SUCCESS;
+  FREE_AND_RETURN_STATUS;
 }
 
 /***************************************************************/
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c
index ce33753..5c4de68 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c
@@ -1652,6 +1652,8 @@
   DEF_VARS(DTYPE);
   mlib_s32 chan2;
   mlib_s32 *buffo, *buffi;
+  mlib_status status = MLIB_SUCCESS;
+
   GET_SRC_DST_PARAMETERS(DTYPE);
 
   if (scale > 30) {
@@ -1673,14 +1675,20 @@
     k[i] = kernel[i]*fscale;
   }
 
-  if (m == 1) return mlib_ImageConv1xN(dst, src, k, n, dn, cmask);
+  if (m == 1) {
+    status = mlib_ImageConv1xN(dst, src, k, n, dn, cmask);
+    FREE_AND_RETURN_STATUS;
+  }
 
   bsize = (n + 3)*wid;
 
   if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
     pbuff = mlib_malloc(sizeof(FTYPE)*bsize + sizeof(FTYPE *)*2*(n + 1));
 
-    if (pbuff == NULL) return MLIB_FAILURE;
+    if (pbuff == NULL) {
+      status = MLIB_FAILURE;
+      FREE_AND_RETURN_STATUS;
+    }
     buffs = (FTYPE   **)(pbuff + bsize);
   }
 
@@ -2034,9 +2042,7 @@
     }
   }
 
-  if (pbuff != buff) mlib_free(pbuff);
-
-  return MLIB_SUCCESS;
+  FREE_AND_RETURN_STATUS;
 }
 
 /***************************************************************/
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c
index f412112..0369f57 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c
@@ -1884,6 +1884,8 @@
   mlib_s32 nchannel, chan1, chan2;
   mlib_s32 i, j, c, swid;
   d64_2x32 dd;
+  mlib_status status = MLIB_SUCCESS;
+
   GET_SRC_DST_PARAMETERS(DTYPE);
 
   if (scale > 30) {
@@ -1905,7 +1907,10 @@
     k[i] = kernel[i]*fscale;
   }
 
-  if (m == 1) return mlib_ImageConv1xN_ext(dst, src, k, n, dy_t, dy_b, cmask);
+  if (m == 1) {
+    status = mlib_ImageConv1xN_ext(dst, src, k, n, dy_t, dy_b, cmask);
+    FREE_AND_RETURN_STATUS;
+  }
 
   swid = wid + (m - 1);
 
@@ -1914,7 +1919,10 @@
   if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
     pbuff = mlib_malloc(sizeof(FTYPE)*bsize + sizeof(FTYPE *)*2*(n + 1));
 
-    if (pbuff == NULL) return MLIB_FAILURE;
+    if (pbuff == NULL) {
+      status = MLIB_FAILURE;
+      FREE_AND_RETURN_STATUS;
+    }
     buffs = (FTYPE   **)(pbuff + bsize);
   }
 
@@ -2318,9 +2326,7 @@
     }
   }
 
-  if (pbuff != buff) mlib_free(pbuff);
-
-  return MLIB_SUCCESS;
+  FREE_AND_RETURN_STATUS;
 }
 
 /***************************************************************/
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c
index eb68aef..fe15909 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c
@@ -1651,6 +1651,8 @@
   DEF_VARS(DTYPE);
   mlib_s32 chan2;
   mlib_s32 *buffo, *buffi;
+  mlib_status status = MLIB_SUCCESS;
+
   GET_SRC_DST_PARAMETERS(DTYPE);
 
   if (scale > 30) {
@@ -1672,14 +1674,20 @@
     k[i] = kernel[i]*fscale;
   }
 
-  if (m == 1) return mlib_ImageConv1xN(dst, src, k, n, dn, cmask);
+  if (m == 1) {
+    status = mlib_ImageConv1xN(dst, src, k, n, dn, cmask);
+    FREE_AND_RETURN_STATUS;
+  }
 
   bsize = (n + 3)*wid;
 
   if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
     pbuff = mlib_malloc(sizeof(FTYPE)*bsize + sizeof(FTYPE *)*2*(n + 1));
 
-    if (pbuff == NULL) return MLIB_FAILURE;
+    if (pbuff == NULL) {
+      status = MLIB_FAILURE;
+      FREE_AND_RETURN_STATUS;
+    }
     buffs = (FTYPE   **)(pbuff + bsize);
   }
 
@@ -2033,9 +2041,7 @@
     }
   }
 
-  if (pbuff != buff) mlib_free(pbuff);
-
-  return MLIB_SUCCESS;
+  FREE_AND_RETURN_STATUS;
 }
 
 /***************************************************************/
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c b/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
index fe065b3..40662d6 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
@@ -477,9 +477,9 @@
   im_height = mlib_ImageGetHeight(img);
   im_stride = mlib_ImageGetStride(img);
   tline     = mlib_ImageGetData(img);
+  if (tline == NULL) return NULL;
   rtable    = mlib_malloc((3 + im_height)*sizeof(mlib_u8 *));
-
-  if (rtable == NULL || tline == NULL) return NULL;
+  if (rtable == NULL) return NULL;
 
   rtable[0] = 0;
   rtable[1] = (mlib_u8*)((void **)rtable + 1);
diff --git a/jdk/src/share/native/sun/awt/medialib/mlib_c_ImageConv.h b/jdk/src/share/native/sun/awt/medialib/mlib_c_ImageConv.h
index 8b94af0..ba1cfa3 100644
--- a/jdk/src/share/native/sun/awt/medialib/mlib_c_ImageConv.h
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_c_ImageConv.h
@@ -31,6 +31,16 @@
 extern "C" {
 #endif /* __cplusplus */
 
+// Shared macro defined for cleanup of allocated memory.
+#ifndef FREE_AND_RETURN_STATUS
+#define FREE_AND_RETURN_STATUS \
+{ \
+if (pbuff != buff) mlib_free(pbuff); \
+if (k != akernel) mlib_free(k); \
+return status; \
+}
+#endif /* FREE_AND_RETURN_STATUS */
+
 mlib_status mlib_c_conv2x2ext_s16(mlib_image       *dst,
                                   const mlib_image *src,
                                   mlib_s32         dx_l,
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XIconWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XIconWindow.java
index 1d0e55d..bf521db 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XIconWindow.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XIconWindow.java
@@ -92,7 +92,7 @@
         }
 
         XIconSize[] sizeList = getIconSizes();
-        log.finest("Icon sizes: {0}", sizeList);
+        log.finest("Icon sizes: {0}", (Object[]) sizeList);
         if (sizeList == null) {
             // No icon sizes so we simply fall back to 16x16
             return new Dimension(16, 16);
diff --git a/jdk/src/solaris/classes/sun/awt/X11InputMethod.java b/jdk/src/solaris/classes/sun/awt/X11InputMethod.java
index b2a62c6..b1939a6 100644
--- a/jdk/src/solaris/classes/sun/awt/X11InputMethod.java
+++ b/jdk/src/solaris/classes/sun/awt/X11InputMethod.java
@@ -57,6 +57,7 @@
 import java.io.FileReader;
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.lang.ref.WeakReference;
 import sun.util.logging.PlatformLogger;
 import java.util.StringTokenizer;
 import java.util.regex.Pattern;
@@ -104,7 +105,7 @@
 
     //reset the XIC if necessary
     private boolean   needResetXIC = false;
-    private Component needResetXICClient = null;
+    private WeakReference<Component> needResetXICClient = new WeakReference<>(null);
 
     // The use of compositionEnableSupported is to reduce unnecessary
     // native calls if set/isCompositionEnabled
@@ -272,14 +273,14 @@
            called on the passive client when endComposition is called.
         */
         if (needResetXIC && haveActiveClient() &&
-            getClientComponent() != needResetXICClient){
+            getClientComponent() != needResetXICClient.get()){
             resetXIC();
 
             // needs to reset the last xic focussed component.
             lastXICFocussedComponent = null;
             isLastXICActive = false;
 
-            needResetXICClient = null;
+            needResetXICClient.clear();
             needResetXIC = false;
         }
     }
@@ -417,7 +418,7 @@
             isLastXICActive = false;
 
             resetXIC();
-            needResetXICClient = null;
+            needResetXICClient.clear();
             needResetXIC = false;
         }
     }
@@ -478,7 +479,7 @@
         disableInputMethod();
         if (needResetXIC) {
             resetXIC();
-            needResetXICClient = null;
+            needResetXICClient.clear();
             needResetXIC = false;
         }
     }
@@ -877,7 +878,7 @@
         boolean active = haveActiveClient();
         if (active && composedText == null && committedText == null){
             needResetXIC = true;
-            needResetXICClient = getClientComponent();
+            needResetXICClient = new WeakReference<>(getClientComponent());
             return;
         }
 
diff --git a/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c b/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
index 16209e7..a9549e0 100644
--- a/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
+++ b/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
@@ -57,22 +57,23 @@
                                               jobject peer, jlong aData)
 {
 #ifndef HEADLESS
-    OGLSDOps *oglsdo = (OGLSDOps *)SurfaceData_InitOps(env, glxsd,
-                                                       sizeof(OGLSDOps));
     GLXSDOps *glxsdo = (GLXSDOps *)malloc(sizeof(GLXSDOps));
 
-    J2dTraceLn(J2D_TRACE_INFO, "GLXSurfaceData_initOps");
-
-    if (oglsdo == NULL) {
-        JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
-        return;
-    }
-
     if (glxsdo == NULL) {
         JNU_ThrowOutOfMemoryError(env, "creating native GLX ops");
         return;
     }
 
+    OGLSDOps *oglsdo = (OGLSDOps *)SurfaceData_InitOps(env, glxsd,
+                                                       sizeof(OGLSDOps));
+    if (oglsdo == NULL) {
+        free(glxsdo);
+        JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
+        return;
+    }
+
+    J2dTraceLn(J2D_TRACE_INFO, "GLXSurfaceData_initOps");
+
     oglsdo->privOps = glxsdo;
 
     oglsdo->sdOps.Lock       = OGLSD_Lock;
diff --git a/jdk/test/Makefile b/jdk/test/Makefile
index 408aaae..093d464 100644
--- a/jdk/test/Makefile
+++ b/jdk/test/Makefile
@@ -342,8 +342,8 @@
 
 # Cleanup
 clean:
-	$(RM) -r $(ABS_TEST_OUTPUT_DIR)
-	$(RM) $(ARCHIVE_BUNDLE)
+	@$(RM) -r $(ABS_TEST_OUTPUT_DIR)
+	@$(RM) $(ARCHIVE_BUNDLE)
 
 ################################################################
 
@@ -401,7 +401,7 @@
           ($(ECHO) "#") ;\
         ) | $(SED) -e 's@^[\ ]*@@' \
           | $(EGREP) -v '^#' > $@.temp1
-	for tdir in $(TESTDIRS) SOLARIS_10_SH_BUG_NO_EMPTY_FORS ; do \
+	@for tdir in $(TESTDIRS) SOLARIS_10_SH_BUG_NO_EMPTY_FORS ; do \
           ( ( $(CAT) $@.temp1 | $(EGREP) "^$${tdir}" ) ; $(ECHO) "#" ) >> $@.temp2 ; \
         done
 	@$(ECHO) "# at least one line" >> $@.temp2
@@ -431,6 +431,7 @@
 # ------------------------------------------------------------------
 
 # Batches of tests (somewhat arbitrary assigments to jdk_* targets)
+# NOTE: These *do not* run the same tests as make/jprt.properties
 JDK_DEFAULT_TARGETS =
 JDK_ALL_TARGETS =
 
@@ -614,15 +615,24 @@
 # ------------------------------------------------------------------
 
 # Run default tests
+# note that this *does not* have the same meaning as jprt.properties :: jprt.make.rule.default.test.targets
 jdk_default: $(JDK_DEFAULT_TARGETS)
 	@$(SummaryInfo)
 
+# Run core tests
+# please keep this in sync with jdk/make/jprt.properties :: jprt.make.rule.core.test.targets
+jdk_core: jdk_lang jdk_math jdk_util jdk_io jdk_net jdk_nio \
+        jdk_security1 jdk_security2 jdk_security3 jdk_rmi \
+        jdk_management jdk_jmx jdk_text jdk_tools jdk_jfr jdk_other
+	@$(SummaryInfo)
+
 # Run all tests
+# note that this *does not* have the same meaning as jprt.properties :: jprt.make.rule.all.test.targets
 jdk_all: $(JDK_ALL_TARGETS)
 	@$(SummaryInfo)
 
 # These are all phony targets
-PHONY_LIST += $(JDK_ALL_TARGETS)
+PHONY_LIST += $(JDK_ALL_TARGETS) jdk_default jdk_core jdk_all
 
 # ------------------------------------------------------------------
 
@@ -892,4 +902,3 @@
 .PHONY: all clean prep $(PHONY_LIST)
 
 ################################################################
-
diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt
index 1870b0b..840a927 100644
--- a/jdk/test/ProblemList.txt
+++ b/jdk/test/ProblemList.txt
@@ -45,8 +45,8 @@
 #   as to why they are here and use a label:
 #     generic-all       Problems on all platforms
 #     generic-ARCH      Where ARCH is one of: sparc, sparcv9, x64, i586, etc.
-#     OSNAME-all        Where OSNAME is one of: solaris, linux, windows
-#     OSNAME-ARCH       Specific on to one OSNAME and ARCH, e.g. solaris-x64
+#     OSNAME-all        Where OSNAME is one of: solaris, linux, windows, macosx
+#     OSNAME-ARCH       Specific on to one OSNAME and ARCH, e.g. solaris-amd64
 #     OSNAME-REV        Specific on to one OSNAME and REV, e.g. solaris-5.8
 #
 # More than one label is allowed but must be on the same line.
@@ -317,13 +317,16 @@
 # 7132203
 sun/jvmstat/monitor/MonitoredVm/CR6672135.java                  generic-all
 
-# Tests take too long, see 7143279
-tools/pack200/CommandLineTests.java                             generic-all
-tools/pack200/Pack200Test.java                                  generic-all
+# Tests take too long, on sparcs see 7143279
+tools/pack200/CommandLineTests.java                             solaris-all, macosx-all 
+tools/pack200/Pack200Test.java                                  solaris-all, macosx-all
 
 # 7150569
 tools/launcher/UnicodeTest.java                                 macosx-all
 
+# 8006039
+tools/launcher/I18NJarTest.java                                 macosx-all
+
 # 8007410
 tools/launcher/FXLauncherTest.java                              linux-all
 
diff --git a/jdk/test/com/sun/jdi/RedefineAbstractClass.sh b/jdk/test/com/sun/jdi/RedefineAbstractClass.sh
new file mode 100644
index 0000000..9e6e484
--- /dev/null
+++ b/jdk/test/com/sun/jdi/RedefineAbstractClass.sh
@@ -0,0 +1,153 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2009, 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 6805864
+# @summary Redefine an abstract class that is called via a concrete
+#   class and via two interface objects and verify that the right
+#   methods are called.
+# @author Daniel D. Daugherty
+#
+# @run shell RedefineAbstractClass.sh
+
+compileOptions=-g
+
+# Uncomment this to see the JDI trace
+#jdbOptions=-dbgtrace
+
+createJavaFile()
+{
+    cat <<EOF > $1.java.1
+
+public class $1 {
+  public static void main(String[] args) {
+    System.out.println("This is RedefineAbstractClass");
+
+    MyConcreteClass foo = new MyConcreteClass();
+    // do the work once before redefine
+    foo.doWork();
+
+    System.out.println("stop here for redefine");  // @1 breakpoint
+
+    // do the work again after redefine
+    foo.doWork();
+
+    System.out.println("stop here to check results");  // @2 breakpoint
+  }
+}
+
+interface MyInterface1 {
+  public boolean checkFunc();
+  public boolean isMyInterface1();
+}
+
+interface MyInterface2 {
+  public boolean checkFunc();
+  public boolean isMyInterface2();
+}
+
+abstract class MyAbstractClass implements MyInterface1, MyInterface2 {
+  static int counter = 0;
+  public boolean checkFunc() {
+    counter++;
+    System.out.println("MyAbstractClass.checkFunc() called.");
+    // @1 uncomment System.out.println("This is call " + counter + " to checkFunc");
+    return true;
+  }
+  public boolean isMyInterface1() {
+    System.out.println("MyAbstractClass.isMyInterface1() called.");
+    return true;
+  }
+  public boolean isMyInterface2() {
+    System.out.println("MyAbstractClass.isMyInterface2() called.");
+    return true;
+  }
+}
+
+class MyConcreteClass extends MyAbstractClass {
+  public void doWork() {
+    // checkFunc() is called via invokevirtual here; MyConcreteClass
+    // inherits via MyAbstractClass
+    System.out.println("In doWork() calling checkFunc(): " + checkFunc());
+
+    MyInterface1 if1 = (MyInterface1) this;
+    // checkFunc() is called via invokeinterface here; this call will
+    // use the first itable entry
+    System.out.println("In doWork() calling if1.checkFunc(): " + if1.checkFunc());
+
+    MyInterface2 if2 = (MyInterface2) this;
+    // checkFunc() is called via invokeinterface here; this call will
+    // use the second itable entry
+    System.out.println("In doWork() calling if2.checkFunc(): " + if2.checkFunc());
+  }
+}
+
+EOF
+}
+
+# This is called to feed cmds to jdb.
+dojdbCmds()
+{
+    setBkpts @1
+    setBkpts @2
+    runToBkpt @1
+    # modified version of redefineClass function
+    vers=2
+    abs_class=MyAbstractClass
+    cmd redefine $pkgDot$abs_class $tmpFileDir/vers$vers/$abs_class.class
+    cp $tmpFileDir/$classname.java.$vers \
+        $tmpFileDir/$classname.java
+    # end modified version of redefineClass function
+
+    # this will continue to the second breakpoint
+    cmd cont
+}
+
+
+mysetup()
+{
+    if [ -z "$TESTSRC" ] ; then
+        TESTSRC=.
+    fi
+
+    for ii in . $TESTSRC $TESTSRC/.. ; do
+        if [ -r "$ii/ShellScaffold.sh" ] ; then
+            . $ii/ShellScaffold.sh 
+            break
+        fi
+    done
+}
+
+# You could replace this next line with the contents
+# of ShellScaffold.sh and this script will run just the same.
+mysetup
+
+runit
+
+debuggeeFailIfNotPresent 'This is call 4 to checkFunc'
+debuggeeFailIfNotPresent 'This is call 5 to checkFunc'
+debuggeeFailIfNotPresent 'This is call 6 to checkFunc'
+pass
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/AbsoluteComponentCenterCalculator.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/AbsoluteComponentCenterCalculator.java
new file mode 100644
index 0000000..6a9f630
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/AbsoluteComponentCenterCalculator.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+
+class AbsoluteComponentCenterCalculator {
+    private AbsoluteComponentCenterCalculator() {
+    }
+
+    public static int calculateXCenterCoordinate(Component component) {
+        return (int) component.getLocationOnScreen().getX() + (component.getWidth() / 2);
+    }
+
+    public static int calculateYCenterCoordinate(Component component) {
+        return (int) component.getLocationOnScreen().getY() + (component.getHeight() / 2);
+    }
+}
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/DataFlavorSearcher.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/DataFlavorSearcher.java
new file mode 100644
index 0000000..2b46cf6
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/DataFlavorSearcher.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.FlavorTable;
+import java.awt.datatransfer.SystemFlavorMap;
+import java.util.Arrays;
+
+public class DataFlavorSearcher {
+    static public String[] HTML_NAMES = new String[]{"HTML", "HTML Format"};
+    static public String[] RICH_TEXT_NAMES = new String[]{"RICH_TEXT", "Rich Text Format"};
+
+    static public DataFlavor getByteDataFlavorForNative(String[] nats) {
+        FlavorTable flavorTable = (FlavorTable) SystemFlavorMap.getDefaultFlavorMap();
+
+        for (String nat : nats) {
+            java.util.List<DataFlavor> flavors = flavorTable.getFlavorsForNative(nat);
+            for (DataFlavor flavor : flavors) {
+                if (flavor != null
+                        && flavor.getRepresentationClass().equals(byte[].class)) {
+                    return flavor;
+                }
+            }
+        }
+        throw new RuntimeException("No data flavor was found for natives: " + Arrays.toString(nats));
+    }
+}
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java
new file mode 100644
index 0000000..d66982d
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+interface InterprocessMessages {
+    final static int EXECUTION_IS_SUCCESSFULL = 0;
+    final static int DATA_IS_CORRUPTED = 212;
+}
+
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
new file mode 100644
index 0000000..03f470d
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
@@ -0,0 +1,27 @@
+<html>
+<!--  
+
+  @test
+  @bug 8005932
+  @summary Java 7 on mac os x only provides text clipboard formats
+  @author mikhail.cherkasov@oracle.com
+  @library ../../regtesthelpers
+  @library ../../regtesthelpers/process
+  @build Util
+  @build ProcessResults ProcessCommunicator
+
+
+  @run applet/othervm MissedHtmlAndRtfBug.html
+*/>
+<head>
+    <title>Java 7 on mac os x only provides text clipboard formats</title>
+</head>
+<body>
+
+<h1> MissedHtmlAndRtfBug <br>Bug ID: 8005932 </h1>
+
+<p> This is an AUTOMATIC test, simply wait for completion </p>
+
+<APPLET CODE="MissedHtmlAndRtfBug.class" WIDTH=200 HEIGHT=200></APPLET>
+</body>
+</html>
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java
new file mode 100644
index 0000000..765457e
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java
@@ -0,0 +1,205 @@
+/*
+ * 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 8005932
+  @summary Java 7 on mac os x only provides text clipboard formats
+  @author mikhail.cherkasov@oracle.com
+  @library ../../regtesthelpers
+  @library ../../regtesthelpers/process
+  @build Util
+  @build ProcessResults ProcessCommunicator
+
+
+  @run applet/othervm MissedHtmlAndRtfBug.html
+*/
+import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.event.*;
+import java.applet.Applet;
+import java.io.File;
+import java.util.ArrayList;
+
+import test.java.awt.regtesthelpers.process.ProcessCommunicator;
+import test.java.awt.regtesthelpers.process.ProcessResults;
+import test.java.awt.regtesthelpers.Util;
+import sun.awt.OSInfo;
+
+import static java.lang.Thread.sleep;
+
+public class MissedHtmlAndRtfBug extends Applet {
+    public void init() {
+        setLayout(new BorderLayout());
+    }//End  init()
+
+    public void start() {
+        if (OSInfo.getOSType() != OSInfo.OSType.MACOSX
+                && OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+            System.out.println("This test is for Windows and Mac only. Passed.");
+            return;
+        }
+
+        final Frame sourceFrame = new Frame("Source frame");
+        final SourcePanel sourcePanel = new SourcePanel();
+        sourceFrame.add(sourcePanel);
+        sourceFrame.pack();
+        sourceFrame.addWindowListener(new WindowAdapter() {
+            @Override
+            public void windowClosing(WindowEvent e) {
+                sourceFrame.dispose();
+            }
+        });
+        sourceFrame.setVisible(true);
+
+        Util.waitForIdle(null);
+
+        NextFramePositionCalculator positionCalculator = new NextFramePositionCalculator(sourceFrame);
+
+        ArrayList<String> args = new ArrayList<String>(5);
+        args.add(String.valueOf(positionCalculator.getNextLocationX()));
+        args.add(String.valueOf(positionCalculator.getNextLocationY()));
+        args.add(String.valueOf(AbsoluteComponentCenterCalculator.calculateXCenterCoordinate(sourcePanel)));
+        args.add(String.valueOf(AbsoluteComponentCenterCalculator.calculateYCenterCoordinate(sourcePanel)));
+        args.add(concatStrings(DataFlavorSearcher.RICH_TEXT_NAMES));
+
+        ProcessResults processResults =
+//                ProcessCommunicator.executeChildProcess(this.getClass(), "/Users/mcherkasov/ws/clipboard/DataFlover/out/production/DataFlover" +
+//                        " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 ",
+//                        args.toArray(new String[0]));
+                ProcessCommunicator.executeChildProcess(this.getClass(),
+                        "." + File.separator + System.getProperty("java.class.path"), args.toArray(new String[]{}));
+
+        verifyTestResults(processResults);
+
+        args.set(args.size() - 1, concatStrings(DataFlavorSearcher.HTML_NAMES));
+
+        ProcessCommunicator.executeChildProcess(this.getClass(),
+                "." + File.separator + System.getProperty("java.class.path"), args.toArray(new String[]{}));
+        verifyTestResults(processResults);
+
+
+    }// start()
+
+    private String concatStrings(String[] strings) {
+        StringBuffer result = new StringBuffer("\"");
+        for (int i = 0; i < strings.length; i++) {
+            result.append(strings[i]);
+            result.append(",");
+        }
+        result.append("\"");
+        return result.toString();
+    }
+
+
+    private static void verifyTestResults(ProcessResults processResults) {
+        if (InterprocessMessages.DATA_IS_CORRUPTED ==
+                processResults.getExitValue()) {
+            processResults.printProcessErrorOutput(System.err);
+            throw new RuntimeException("TEST IS FAILED: Target has received" +
+                    " corrupted data.");
+        }
+        processResults.verifyStdErr(System.err);
+        processResults.verifyProcessExitValue(System.err);
+        processResults.printProcessStandartOutput(System.out);
+    }
+
+    //We cannot make an instance of the applet without the default constructor
+    public MissedHtmlAndRtfBug() {
+        super();
+    }
+
+    //We need in this constructor to pass frame position between JVMs
+    public MissedHtmlAndRtfBug(Point targetFrameLocation, Point dragSourcePoint, DataFlavor df)
+            throws InterruptedException {
+        final Frame targetFrame = new Frame("Target frame");
+        final TargetPanel targetPanel = new TargetPanel(targetFrame, df);
+        targetFrame.add(targetPanel);
+        targetFrame.addWindowListener(new WindowAdapter() {
+            @Override
+            public void windowClosing(WindowEvent e) {
+                targetFrame.dispose();
+            }
+        });
+        targetFrame.setLocation(targetFrameLocation);
+        targetFrame.pack();
+        targetFrame.setVisible(true);
+
+        doTest(dragSourcePoint, targetPanel);
+    }
+
+    private void doTest(Point dragSourcePoint, TargetPanel targetPanel) {
+        Util.waitForIdle(null);
+
+        final Robot robot = Util.createRobot();
+
+        robot.mouseMove((int) dragSourcePoint.getX(), (int) dragSourcePoint.getY());
+        try {
+            sleep(100);
+            robot.mousePress(InputEvent.BUTTON1_MASK);
+            sleep(100);
+            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            sleep(100);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        Util.drag(robot, dragSourcePoint, new Point(AbsoluteComponentCenterCalculator.calculateXCenterCoordinate(targetPanel),
+                AbsoluteComponentCenterCalculator.calculateYCenterCoordinate(targetPanel)),
+                InputEvent.BUTTON1_MASK);
+    }
+
+
+    enum InterprocessArguments {
+        TARGET_FRAME_X_POSITION_ARGUMENT,
+        TARGET_FRAME_Y_POSITION_ARGUMENT,
+        DRAG_SOURCE_POINT_X_ARGUMENT,
+        DRAG_SOURCE_POINT_Y_ARGUMENT,
+        DATA_FLAVOR_NAMES;
+
+        int extractInt(String[] args) {
+            return Integer.parseInt(args[this.ordinal()]);
+        }
+
+        String[] extractStringArray(String[] args) {
+            return args[this.ordinal()].replaceAll("\"", "").split(",");
+        }
+    }
+
+    public static void main(String[] args) {
+        Point dragSourcePoint = new Point(InterprocessArguments.DRAG_SOURCE_POINT_X_ARGUMENT.extractInt(args),
+                InterprocessArguments.DRAG_SOURCE_POINT_Y_ARGUMENT.extractInt(args));
+        Point targetFrameLocation = new Point(InterprocessArguments.TARGET_FRAME_X_POSITION_ARGUMENT.extractInt(args),
+                InterprocessArguments.TARGET_FRAME_Y_POSITION_ARGUMENT.extractInt(args));
+        String[] names = InterprocessArguments.DATA_FLAVOR_NAMES.extractStringArray(args);
+
+        DataFlavor df = DataFlavorSearcher.getByteDataFlavorForNative(names);
+        try {
+            new MissedHtmlAndRtfBug(targetFrameLocation, dragSourcePoint, df);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MyTransferable.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MyTransferable.java
new file mode 100644
index 0000000..1e369be
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MyTransferable.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.datatransfer.*;
+import java.io.IOException;
+
+class MyTransferable implements Transferable {
+
+    public static final String TEST_DATA = "<b>Test</b>";
+    private DataFlavor[] dataFlavors;
+
+    public MyTransferable() {
+        dataFlavors = new DataFlavor[]{DataFlavorSearcher.getByteDataFlavorForNative(DataFlavorSearcher.HTML_NAMES),
+                DataFlavorSearcher.getByteDataFlavorForNative(DataFlavorSearcher.RICH_TEXT_NAMES)};
+    }
+
+
+    @Override
+    public DataFlavor[] getTransferDataFlavors() {
+        return dataFlavors;
+    }
+
+    @Override
+    public boolean isDataFlavorSupported(DataFlavor flavor) {
+        for (DataFlavor f : dataFlavors) {
+            if (f.equals(flavor)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Object getTransferData(DataFlavor flavor)
+            throws UnsupportedFlavorException, IOException {
+        if (isDataFlavorSupported(flavor)) {
+            return TEST_DATA.getBytes("UTF-16");
+        } else {
+            throw new UnsupportedFlavorException(flavor);
+        }
+    }
+}
\ No newline at end of file
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/NextFramePositionCalculator.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/NextFramePositionCalculator.java
new file mode 100644
index 0000000..c97ea67
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/NextFramePositionCalculator.java
@@ -0,0 +1,20 @@
+import java.awt.*;
+
+
+class NextFramePositionCalculator {
+
+    private final Frame currentFrame;
+
+    public NextFramePositionCalculator(Frame currentFrame) {
+        this.currentFrame = currentFrame;
+    }
+
+    public int getNextLocationX() {
+        return currentFrame.getX() + currentFrame.getWidth();
+    }
+
+    public int getNextLocationY() {
+        return currentFrame.getY();
+    }
+
+}
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/SourcePanel.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/SourcePanel.java
new file mode 100644
index 0000000..5985df5
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/SourcePanel.java
@@ -0,0 +1,26 @@
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.*;
+
+public class SourcePanel extends Panel {
+
+    private final MyDragGestureListener dragGestureListener =
+            new MyDragGestureListener();
+
+    public SourcePanel() {
+        setPreferredSize(new Dimension(200, 200));
+        DragSource defaultDragSource =
+                DragSource.getDefaultDragSource();
+        defaultDragSource.createDefaultDragGestureRecognizer(this,
+                DnDConstants.ACTION_COPY_OR_MOVE, dragGestureListener);
+        setBackground(Color.RED);
+    }
+
+    private class MyDragGestureListener implements DragGestureListener {
+        public void dragGestureRecognized(DragGestureEvent dge) {
+            dge.startDrag(null, new MyTransferable());
+        }
+    }
+}
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/TargetPanel.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/TargetPanel.java
new file mode 100644
index 0000000..2e56961
--- /dev/null
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/TargetPanel.java
@@ -0,0 +1,83 @@
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.*;
+import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class TargetPanel extends Panel implements DropTargetListener {
+
+
+    //private final CustomDropTargetListener dropTargetListener = new CustomDropTargetListener();
+
+    private Frame frame;
+    DataFlavor dataFlavor;
+
+    public TargetPanel(Frame frame, DataFlavor dataFlavor) {
+        this.dataFlavor = dataFlavor;
+        this.frame = frame;
+        setBackground(Color.DARK_GRAY);
+        setPreferredSize(new Dimension(200, 200));
+        setDropTarget(new DropTarget(this, this));
+    }
+
+    public void dragEnter(DropTargetDragEvent dtde) {
+        if (dtde.isDataFlavorSupported(dataFlavor)) {
+            dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
+        }
+    }
+
+    public void dragOver(DropTargetDragEvent dtde) {
+        if (dtde.isDataFlavorSupported(dataFlavor)) {
+            dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
+        }
+    }
+
+    public void dropActionChanged(DropTargetDragEvent dtde) {
+        if (dtde.isDataFlavorSupported(dataFlavor)) {
+            dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
+        }
+    }
+
+    public void dragExit(DropTargetEvent dte) {
+
+    }
+
+    public void drop(DropTargetDropEvent dtde) {
+        dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+        if (dtde.isDataFlavorSupported(dataFlavor)) {
+            String result = null;
+            try {
+                Transferable t = dtde.getTransferable();
+                byte[] data = (byte[]) dtde.getTransferable().getTransferData(dataFlavor);
+                result = new String(data, "UTF-16");
+                repaint();
+            } catch (UnsupportedFlavorException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            dtde.dropComplete(true);
+
+
+            if (result != null && result.contains(MyTransferable.TEST_DATA)) {
+                System.err.println(InterprocessMessages.EXECUTION_IS_SUCCESSFULL);
+                Timer t = new Timer();
+                t.schedule(new TimerTask() {
+                    @Override
+                    public void run() {
+                        System.exit(0);
+                    }
+                }, 2000);
+                return;
+
+            }
+        }
+        dtde.rejectDrop();
+        System.err.println(InterprocessMessages.DATA_IS_CORRUPTED);
+        System.exit(InterprocessMessages.DATA_IS_CORRUPTED);
+    }
+
+}
diff --git a/jdk/test/java/awt/Frame/WindowDragTest/WindowDragTest.java b/jdk/test/java/awt/Frame/WindowDragTest/WindowDragTest.java
index 127a49e..e7b0970 100644
--- a/jdk/test/java/awt/Frame/WindowDragTest/WindowDragTest.java
+++ b/jdk/test/java/awt/Frame/WindowDragTest/WindowDragTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -23,10 +23,11 @@
 
 /*
   @test
-  @bug 7128738
+  @bug 7128738 7161759
   @summary dragged dialog freezes system on dispose
   @author Oleg Pekhovskiy: area=awt.toplevel
   @library ../../regtesthelpers
+  @build Util
   @run main WindowDragTest
 */
 
diff --git a/jdk/test/java/awt/im/memoryleak/InputContextMemoryLeakTest.java b/jdk/test/java/awt/im/memoryleak/InputContextMemoryLeakTest.java
new file mode 100644
index 0000000..04e4a33
--- /dev/null
+++ b/jdk/test/java/awt/im/memoryleak/InputContextMemoryLeakTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.FlowLayout;
+import java.awt.Robot;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import test.java.awt.regtesthelpers.Util;
+
+/*
+ @test
+ @bug 7079260
+ @summary XInputContext leaks memory by needRecetXXIClient field
+ @author Petr Pchelko
+ @library ../../regtesthelpers
+ @build Util
+ @compile InputContextMemoryLeakTest.java
+ @run main/othervm -Xmx20M InputContextMemoryLeakTest
+ */
+public class InputContextMemoryLeakTest {
+
+    private static JFrame frame;
+    private static WeakReference<JTextField> text;
+    private static WeakReference<JPanel> p;
+    private static JButton button;
+
+    public static void init() throws Throwable {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame();
+                frame.setLayout(new FlowLayout());
+                JPanel p1 = new JPanel();
+                button = new JButton("Test");
+                p1.add(button);
+                frame.add(p1);
+                text = new WeakReference<JTextField>(new JTextField("Text"));
+                p = new WeakReference<JPanel>(new JPanel(new FlowLayout()));
+                p.get().add(text.get());
+                frame.add(p.get());
+                frame.setBounds(500, 400, 200, 200);
+                frame.setVisible(true);
+            }
+        });
+
+        Util.focusComponent(text.get(), 500);
+        Util.clickOnComp(button, new Robot());
+        //References to objects testes for memory leak are stored in Util.
+        //Need to clean them
+        Util.cleanUp();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.remove(p.get());
+            }
+        });
+
+        Util.waitForIdle(null);
+        //After the next caret blink it automatically TextField references
+        Thread.sleep(text.get().getCaret().getBlinkRate() * 2);
+        Util.waitForIdle(null);
+        assertGC();
+    }
+
+      public static void assertGC() throws Throwable {
+        List<byte[]> alloc = new ArrayList<byte[]>();
+        int size = 1024 * 10;
+        while (true) {
+            try {
+                alloc.add(new byte[size]);
+            } catch (OutOfMemoryError err) {
+                break;
+            }
+        }
+        alloc = null;
+        if (text.get() != null) {
+            throw new Exception("Test failed: JTextField was not collected");
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        init();
+    }
+}
diff --git a/jdk/test/java/awt/regtesthelpers/Util.java b/jdk/test/java/awt/regtesthelpers/Util.java
index ebbfdf9..90b2822 100644
--- a/jdk/test/java/awt/regtesthelpers/Util.java
+++ b/jdk/test/java/awt/regtesthelpers/Util.java
@@ -463,6 +463,13 @@
         return -1;
     }
 
+    //Cleans all the references
+    public static void cleanUp() {
+        apListener = null;
+        fgListener = null;
+        wgfListener = null;
+    }
+
 
     ////////////////////////////
     // Some stuff to test focus.
diff --git a/jdk/test/java/lang/SecurityManager/NoAWT.java b/jdk/test/java/lang/SecurityManager/NoAWT.java
new file mode 100644
index 0000000..3224af4
--- /dev/null
+++ b/jdk/test/java/lang/SecurityManager/NoAWT.java
@@ -0,0 +1,53 @@
+/*
+ * 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 8004502
+ * @summary Sanity check that SecurityManager methods that check AWTPermission
+ *   behave as expected when AWT is not present
+ */
+
+public class NoAWT {
+    public static void main(String[] args) {
+        SecurityManager sm = new SecurityManager();
+
+        try {
+            sm.checkAwtEventQueueAccess();
+            throw new RuntimeException("SecurityException expected");
+        } catch (SecurityException expected) { }
+
+        try {
+            sm.checkSystemClipboardAccess();
+            throw new RuntimeException("SecurityException expected");
+        } catch (SecurityException expected) { }
+
+        try {
+            sm.checkTopLevelWindow(null);
+            throw new RuntimeException("NullPointException expected");
+        } catch (NullPointerException expected) { }
+
+        if (sm.checkTopLevelWindow(new Object())) {
+            throw new RuntimeException("checkTopLevelWindow expected to return false");
+        }
+    }
+}
diff --git a/jdk/test/java/lang/annotation/TypeParamAnnotation.java b/jdk/test/java/lang/annotation/TypeParamAnnotation.java
index 50457ec..694d83d 100644
--- a/jdk/test/java/lang/annotation/TypeParamAnnotation.java
+++ b/jdk/test/java/lang/annotation/TypeParamAnnotation.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8004698
+ * @bug 8004698 8007278
  * @summary Unit test for annotations on TypeVariables
  */
 
@@ -93,7 +93,7 @@
     private static void testGetAnnos() throws Exception {
         TypeVariable<?>[] ts = TypeParam.class.getDeclaredMethod("foo").getTypeParameters();
         ParamAnno2[] as;
-        as = ts[0].getAnnotations(ParamAnno2.class);
+        as = ts[0].getAnnotationsByType(ParamAnno2.class);
         check(as.length == 1);
         check(as[0].value() == 3);
     }
diff --git a/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java b/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java
index 10e3d74..674f37f 100644
--- a/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java
+++ b/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug     7154390 8005712
+ * @bug     7154390 8005712 8007278
  * @summary Unit test for repeated annotation reflection
  *
  * @compile RepeatedUnitTest.java subpackage/package-info.java subpackage/Container.java subpackage/Containee.java subpackage/NonRepeated.java subpackage/InheritedContainee.java subpackage/InheritedContainer.java subpackage/InheritedNonRepeated.java
@@ -76,7 +76,7 @@
 
         check(1 == countAnnotation(e, NonRepeated.class));
 
-        nr = e.getAnnotations(NonRepeated.class)[0];
+        nr = e.getAnnotationsByType(NonRepeated.class)[0];
         check(nr.value() == 10);
 
         check(1 == containsAnnotationOfType(e.getAnnotations(), NonRepeated.class));
@@ -87,9 +87,9 @@
         check(c == null);
         check(2 == countAnnotation(e, Containee.class));
 
-        c = e.getAnnotations(Containee.class)[0];
+        c = e.getAnnotationsByType(Containee.class)[0];
         check(c.value() == 1);
-        c = e.getAnnotations(Containee.class)[1];
+        c = e.getAnnotationsByType(Containee.class)[1];
         check(c.value() == 2);
 
         check(0 == containsAnnotationOfType(e.getAnnotations(), Containee.class));
@@ -98,7 +98,7 @@
     static void packageContainer(AnnotatedElement e) {
         Container cr = e.getAnnotation(Container.class);
         check(null != cr);
-        check(1 == containsAnnotationOfType(e.getAnnotations(Container.class), Container.class));
+        check(1 == containsAnnotationOfType(e.getAnnotationsByType(Container.class), Container.class));
         check(1 == countAnnotation(e, Container.class));
     }
 
@@ -123,10 +123,10 @@
         check(1 == countAnnotation(e, NonRepeated.class));
         check(1 == countAnnotation(e, InheritedNonRepeated.class));
 
-        check(e.getAnnotations(Containee.class)[2].value() == 300);
-        check(e.getAnnotations(InheritedContainee.class)[2].value() == 300);
-        check(e.getAnnotations(InheritedNonRepeated.class)[0].value() == 200);
-        check(e.getAnnotations(NonRepeated.class)[0].value() == 100);
+        check(e.getAnnotationsByType(Containee.class)[2].value() == 300);
+        check(e.getAnnotationsByType(InheritedContainee.class)[2].value() == 300);
+        check(e.getAnnotationsByType(InheritedNonRepeated.class)[0].value() == 200);
+        check(e.getAnnotationsByType(NonRepeated.class)[0].value() == 100);
     }
 
     static void inheritedMe3() {
@@ -138,8 +138,8 @@
         check(0 == countAnnotation(e, Container.class));
         check(1 == countAnnotation(e, InheritedContainer.class));
 
-        check(e.getAnnotations(InheritedContainee.class)[2].value() == 350);
-        check(e.getAnnotations(InheritedNonRepeated.class)[0].value() == 15);
+        check(e.getAnnotationsByType(InheritedContainee.class)[2].value() == 350);
+        check(e.getAnnotationsByType(InheritedNonRepeated.class)[0].value() == 15);
     }
 
     static void inheritedMe4() {
@@ -153,24 +153,24 @@
         check(1 == countAnnotation(e, NonRepeated.class));
         check(1 == countAnnotation(e, InheritedNonRepeated.class));
 
-        check(e.getAnnotations(Containee.class)[2].value() == 3000);
-        check(e.getAnnotations(InheritedContainee.class)[2].value() == 3000);
-        check(e.getAnnotations(InheritedNonRepeated.class)[0].value() == 2000);
-        check(e.getAnnotations(NonRepeated.class)[0].value() == 1000);
+        check(e.getAnnotationsByType(Containee.class)[2].value() == 3000);
+        check(e.getAnnotationsByType(InheritedContainee.class)[2].value() == 3000);
+        check(e.getAnnotationsByType(InheritedNonRepeated.class)[0].value() == 2000);
+        check(e.getAnnotationsByType(NonRepeated.class)[0].value() == 1000);
     }
 
     static void checkMultiplier(AnnotatedElement e, int m) {
         // Basic sanity of non-repeating getAnnotation(Class)
         check(e.getAnnotation(NonRepeated.class).value() == 5 * m);
 
-        // Check count of annotations returned from getAnnotations(Class)
+        // Check count of annotations returned from getAnnotationsByType(Class)
         check(4 == countAnnotation(e, Containee.class));
         check(1 == countAnnotation(e, Container.class));
         check(1 == countAnnotation(e, NonRepeated.class));
 
-        // Check contents of array returned from getAnnotations(Class)
-        check(e.getAnnotations(Containee.class)[2].value() == 3 * m);
-        check(e.getAnnotations(NonRepeated.class)[0].value() == 5 * m);
+        // Check contents of array returned from getAnnotationsByType(Class)
+        check(e.getAnnotationsByType(Containee.class)[2].value() == 3 * m);
+        check(e.getAnnotationsByType(NonRepeated.class)[0].value() == 5 * m);
 
         // Check getAnnotation(Class)
         check(e.getAnnotation(Containee.class) == null);
@@ -187,7 +187,7 @@
     }
 
     static int countAnnotation(AnnotatedElement e, Class<? extends Annotation> c) {
-        return containsAnnotationOfType(e.getAnnotations(c), c);
+        return containsAnnotationOfType(e.getAnnotationsByType(c), c);
     }
 
     static <A extends Annotation> int containsAnnotationOfType(A[] l, Class<? extends Annotation> a) {
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh
new file mode 100644
index 0000000..6deb7ce
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh
@@ -0,0 +1,175 @@
+#
+# 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 7182152
+# @bug 8007935
+# @summary Redefine a subclass that implements two interfaces and
+#   verify that the right methods are called.
+# @author Daniel D. Daugherty
+#
+# @run shell MakeJAR3.sh RedefineSubclassWithTwoInterfacesAgent 'Can-Redefine-Classes: true'
+# @run build RedefineSubclassWithTwoInterfacesApp
+# @run shell RedefineSubclassWithTwoInterfaces.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+if [ "${COMPILEJAVA}" = "" ]
+then
+  COMPILEJAVA="${TESTJAVA}"
+fi
+echo "COMPILEJAVA=${COMPILEJAVA}"
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+JAVAC="${COMPILEJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+echo "INFO: building the replacement classes."
+
+cp "${TESTSRC}"/RedefineSubclassWithTwoInterfacesTarget_1.java \
+    RedefineSubclassWithTwoInterfacesTarget.java
+cp "${TESTSRC}"/RedefineSubclassWithTwoInterfacesImpl_1.java \
+    RedefineSubclassWithTwoInterfacesImpl.java
+"${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
+    -cp "${TESTCLASSES}" -d . \
+    RedefineSubclassWithTwoInterfacesTarget.java \
+    RedefineSubclassWithTwoInterfacesImpl.java 
+status="$?"
+if [ "$status" != 0 ]; then
+    echo "FAIL: compile of *_1.java files failed."
+    exit "$status"
+fi
+
+mv RedefineSubclassWithTwoInterfacesTarget.java \
+    RedefineSubclassWithTwoInterfacesTarget_1.java
+mv RedefineSubclassWithTwoInterfacesTarget.class \
+    RedefineSubclassWithTwoInterfacesTarget_1.class
+mv RedefineSubclassWithTwoInterfacesImpl.java \
+    RedefineSubclassWithTwoInterfacesImpl_1.java
+mv RedefineSubclassWithTwoInterfacesImpl.class \
+    RedefineSubclassWithTwoInterfacesImpl_1.class
+
+echo "INFO: launching RedefineSubclassWithTwoInterfacesApp"
+
+# TraceRedefineClasses options:
+#
+#    0x00000001 |          1 - name each target class before loading, after
+#                              loading and after redefinition is completed
+#    0x00000002 |          2 - print info if parsing, linking or
+#                              verification throws an exception
+#    0x00000004 |          4 - print timer info for the VM operation
+#    0x00001000 |       4096 - detect calls to obsolete methods
+#    0x00002000 |       8192 - fail a guarantee() in addition to detection
+#    0x00004000 |      16384 - detect old/obsolete methods in metadata
+#    0x00100000 |    1048576 - impl details: vtable updates
+#    0x00200000 |    2097152 - impl details: itable updates
+#
+#    1+2+4+4096+8192+16384+1048576+2097152 == 3174407
+
+"${JAVA}" ${TESTVMOPTS} \
+    -XX:TraceRedefineClasses=3174407 \
+    -javaagent:RedefineSubclassWithTwoInterfacesAgent.jar \
+    -classpath "${TESTCLASSES}" \
+    RedefineSubclassWithTwoInterfacesApp > output.log 2>&1
+status="$?"
+
+echo "INFO: <begin output.log>"
+cat output.log
+echo "INFO: <end output.log>"
+
+if [ "$status" != 0 ]; then
+    echo "FAIL: RedefineSubclassWithTwoInterfacesApp failed."
+    exit "$status"
+fi
+
+# When this bug manifests, RedefineClasses() will fail to update
+# one of the itable entries to refer to the new method. The log
+# will include the following line when the bug occurs:
+#
+#     guarantee(false) failed: OLD and/or OBSOLETE method(s) found
+#
+# If this guarantee happens, the test should fail in the status
+# check above, but just in case it doesn't, we check for "guarantee".
+#
+
+FAIL_MESG="guarantee"
+grep "$FAIL_MESG" output.log
+status=$?
+if [ "$status" = 0 ]; then
+    echo "FAIL: found '$FAIL_MESG' in the test output."
+    result=1
+else
+    echo "INFO: did NOT find '$FAIL_MESG' in the test output."
+    # be optimistic here
+    result=0
+fi
+
+PASS1_MESG="before any redefines"
+cnt=`grep "$PASS1_MESG" output.log | grep 'version-0' | wc -l | sed 's/^ *//'`
+case "$cnt" in
+2)
+    echo "INFO: found 2 version-0 '$PASS1_MESG' mesgs."
+    ;;
+*)
+    echo "FAIL: did NOT find 2 version-0 '$PASS1_MESG' mesgs."
+    echo "INFO: grep '$PASS1_MESG' output:"
+    grep "$PASS1_MESG" output.log
+    result=1
+    ;;
+esac
+
+PASS2_MESG="after redefine"
+cnt=`grep "$PASS2_MESG" output.log | grep 'version-1' | wc -l | sed 's/^ *//'`
+case "$cnt" in
+2)
+    echo "INFO: found 2 version-1 '$PASS2_MESG' mesgs."
+    ;;
+*)
+    echo "FAIL: did NOT find 2 version-1 '$PASS2_MESG' mesgs."
+    echo "INFO: grep '$PASS2_MESG' output:"
+    grep "$PASS2_MESG" output.log
+    result=1
+    ;;
+esac
+
+if [ "$result" = 0 ]; then
+    echo "PASS: test passed both positive and negative output checks."
+fi
+
+exit $result
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesAgent.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesAgent.java
new file mode 100644
index 0000000..abd9931
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesAgent.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.instrument.Instrumentation;
+
+public class RedefineSubclassWithTwoInterfacesAgent {
+    private static Instrumentation instrumentation;
+
+    private RedefineSubclassWithTwoInterfacesAgent() {
+    }
+
+    public static void premain(String agentArgs, Instrumentation inst) {
+        System.out.println("Hello from " +
+            "RedefineSubclassWithTwoInterfacesAgent!");
+        System.out.println("isRedefineClassesSupported()=" +
+            inst.isRedefineClassesSupported());
+
+        instrumentation = inst;
+    }
+
+    public static Instrumentation getInstrumentation() {
+        return instrumentation;
+    }
+}
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesApp.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesApp.java
new file mode 100644
index 0000000..bb62058
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesApp.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.lang.instrument.*;
+
+public class RedefineSubclassWithTwoInterfacesApp {
+    public static void main(String args[]) throws Exception {
+        System.out.println("Hello from RedefineSubclassWithTwoInterfacesApp!");
+
+        new RedefineSubclassWithTwoInterfacesApp().doTest();
+
+        System.exit(0);
+    }
+
+    private void doTest() throws Exception {
+        RedefineSubclassWithTwoInterfacesImpl impl
+            = new RedefineSubclassWithTwoInterfacesImpl();
+        RedefineSubclassWithTwoInterfacesRemote remote
+            = new RedefineSubclassWithTwoInterfacesRemote(impl, impl);
+        String mesg;
+
+        // make echo() calls before any redefinitions:
+        mesg = remote.echo1("test message #1.1");
+        System.out.println("RedefineSubclassWithTwoInterfacesApp: echo1 mesg='"
+            + mesg + "' before any redefines");
+        mesg = remote.echo2("test message #2.1");
+        System.out.println("RedefineSubclassWithTwoInterfacesApp: echo2 mesg='"
+            + mesg + "' before any redefines");
+
+
+        // redefining RedefineSubclassWithTwoInterfacesImpl before
+        // RedefineSubclassWithTwoInterfacesTarget fails:
+        do_redefine("RedefineSubclassWithTwoInterfacesImpl", 1);
+        do_redefine("RedefineSubclassWithTwoInterfacesTarget", 1);
+
+        mesg = remote.echo1("test message #1.2");
+        System.out.println("RedefineSubclassWithTwoInterfacesApp: echo1 mesg='"
+            + mesg + "' after redefine");
+        mesg = remote.echo2("test message #2.2");
+        System.out.println("RedefineSubclassWithTwoInterfacesApp: echo2 mesg='"
+            + mesg + "' after redefine");
+    }
+
+    private static void do_redefine(String className, int counter)
+            throws Exception {
+        File f = new File(className + "_" + counter + ".class");
+        System.out.println("Reading test class from " + f);
+        InputStream redefineStream = new FileInputStream(f);
+
+        byte[] redefineBuffer
+            = NamedBuffer.loadBufferFromStream(redefineStream);
+
+        ClassDefinition redefineParamBlock = new ClassDefinition(
+            Class.forName(className), redefineBuffer);
+
+        RedefineSubclassWithTwoInterfacesAgent.getInstrumentation().
+            redefineClasses(new ClassDefinition[] {redefineParamBlock});
+    }
+}
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesImpl.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesImpl.java
new file mode 100644
index 0000000..f42e79f
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesImpl.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+// Reproducing this bug only requires an EMCP version of the
+// RedefineSubclassWithTwoInterfacesImpl class so
+// RedefineSubclassWithTwoInterfacesImpl.java and
+// RedefineSubclassWithTwoInterfacesImpl_1.java are identical.
+public class RedefineSubclassWithTwoInterfacesImpl
+                 extends RedefineSubclassWithTwoInterfacesTarget
+                 implements RedefineSubclassWithTwoInterfacesIntf1,
+                            RedefineSubclassWithTwoInterfacesIntf2 {
+    // This class is acting in the role of:
+    // wlstest.unit.diagnostics.common.apps.echoejb.EchoBean4_nh7k_Impl
+}
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesImpl_1.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesImpl_1.java
new file mode 100644
index 0000000..f42e79f
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesImpl_1.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+// Reproducing this bug only requires an EMCP version of the
+// RedefineSubclassWithTwoInterfacesImpl class so
+// RedefineSubclassWithTwoInterfacesImpl.java and
+// RedefineSubclassWithTwoInterfacesImpl_1.java are identical.
+public class RedefineSubclassWithTwoInterfacesImpl
+                 extends RedefineSubclassWithTwoInterfacesTarget
+                 implements RedefineSubclassWithTwoInterfacesIntf1,
+                            RedefineSubclassWithTwoInterfacesIntf2 {
+    // This class is acting in the role of:
+    // wlstest.unit.diagnostics.common.apps.echoejb.EchoBean4_nh7k_Impl
+}
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesIntf1.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesIntf1.java
new file mode 100644
index 0000000..b6e2542
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesIntf1.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+public interface RedefineSubclassWithTwoInterfacesIntf1 {
+    // This interface is acting in the role of:
+    // wlstest.unit.diagnostics.common.apps.echoejb.EchoBean4_nh7k_Intf
+    String echo(String s);
+}
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesIntf2.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesIntf2.java
new file mode 100644
index 0000000..66fe162
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesIntf2.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+public interface RedefineSubclassWithTwoInterfacesIntf2 {
+    // This interface is acting in the role of:
+    // weblogic.ejb.container.interfaces.WLEnterpriseBean
+    String echo(String s);
+}
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesRemote.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesRemote.java
new file mode 100644
index 0000000..e50e049
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesRemote.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+public class RedefineSubclassWithTwoInterfacesRemote {
+    // This class is acting in the role of:
+    // wlstest.unit.diagnostics.common.apps.echoejb.EchoBean4_nh7k_EchoRemoteImpl
+    // since it is calling the echo() method via an interface.
+    private RedefineSubclassWithTwoInterfacesIntf1 intf1;
+    private RedefineSubclassWithTwoInterfacesIntf2 intf2;
+
+    RedefineSubclassWithTwoInterfacesRemote(
+            RedefineSubclassWithTwoInterfacesIntf1 intf1,
+            RedefineSubclassWithTwoInterfacesIntf2 intf2) {
+        this.intf1 = intf1;
+        this.intf2 = intf2;
+    }
+
+    // There is actually a bit more logic in the call stack from
+    // EchoBean4_nh7k_EchoRemoteImpl.echo() to EchoBean4_nh7k_Intf.echo()
+    public String echo1(String s) {
+        return "intf1<" + intf1.echo(s) + ">";
+    }
+
+    public String echo2(String s) {
+        return "intf2<" + intf2.echo(s) + ">";
+    }
+}
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesTarget.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesTarget.java
new file mode 100644
index 0000000..55c1d58
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesTarget.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+public class RedefineSubclassWithTwoInterfacesTarget {
+    // This class is acting in the role of:
+    // wlstest.unit.diagnostics.common.apps.echoejb.EchoBean4
+    public String echo(String s) {
+        return "echo: (version-0) <" + s + ">";
+    }
+}
diff --git a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesTarget_1.java b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesTarget_1.java
new file mode 100644
index 0000000..429d0fe
--- /dev/null
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfacesTarget_1.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+public class RedefineSubclassWithTwoInterfacesTarget {
+    // This class is acting in the role of:
+    // wlstest.unit.diagnostics.common.apps.echoejb.EchoBean4
+    public String echo(String s) {
+        return "echo: (version-1) <" + s + ">";
+    }
+}
diff --git a/jdk/test/java/net/URLClassLoader/profiles/Basic.java b/jdk/test/java/net/URLClassLoader/profiles/Basic.java
new file mode 100644
index 0000000..d16e52f
--- /dev/null
+++ b/jdk/test/java/net/URLClassLoader/profiles/Basic.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+import java.net.*;
+import java.io.File;
+import java.util.jar.*;
+
+/**
+ * Attempts to load classes or resources from a JAR file. The load should succeed
+ * if the runtime supports the profile indicated by the Profile attribute, fail
+ * with UnsupportedProfileException otherwise.
+ */
+
+public class Basic {
+
+    static int indexOf(String profile) {
+        if (profile == null || "compact1".equals(profile)) return 1;
+        if ("compact2".equals(profile)) return 2;
+        if ("compact3".equals(profile)) return 3;
+        if ("".equals(profile)) return 4;
+        return Integer.MAX_VALUE;  // unknown profile name
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (args.length < 2)
+            throw new RuntimeException("Usage: java <jarfile> <classname>");
+        String jar = args[0];
+        String cn = args[1];
+
+        File lib = new File(jar);
+        URL url = lib.toURI().toURL();
+        URL urls[] = { url };
+
+        // ## replace this if there is a standard way to determine the profile
+        String thisProfile = sun.misc.Version.profileName();
+
+        String jarProfile = null;
+        try (JarFile jf = new JarFile(lib)) {
+            Manifest manifest = jf.getManifest();
+            if (manifest != null) {
+                Attributes mainAttrs = manifest.getMainAttributes();
+                if (mainAttrs != null) {
+                    jarProfile = mainAttrs.getValue(Attributes.Name.PROFILE);
+                }
+            }
+        }
+
+        boolean shouldFail = indexOf(thisProfile) < indexOf(jarProfile);
+
+        try (URLClassLoader cl = new URLClassLoader(urls)) {
+            System.out.format("Loading %s from %s ...%n", cn, jar);
+            Class<?> c = Class.forName(cn, true, cl);
+            System.out.println(c);
+            if (shouldFail)
+                throw new RuntimeException("UnsupportedProfileException expected");
+        } catch (UnsupportedProfileException x) {
+            if (!shouldFail)
+                throw x;
+            System.out.println("UnsupportedProfileException thrown as expected");
+        }
+
+        try (URLClassLoader cl = new URLClassLoader(urls)) {
+            System.out.format("Loading resource from %s ...%n", jar);
+            URL r = cl.findResource("META-INF/MANIFEST.MF");
+            System.out.println(r);
+            if (shouldFail)
+                throw new RuntimeException("UnsupportedProfileException expected");
+        } catch (UnsupportedProfileException x) {
+            if (!shouldFail)
+                throw x;
+            System.out.println("UnsupportedProfileException thrown as expected");
+        }
+    }
+}
+
diff --git a/jdk/test/java/net/URLClassLoader/profiles/Lib.java b/jdk/test/java/net/URLClassLoader/profiles/Lib.java
new file mode 100644
index 0000000..6a5f793
--- /dev/null
+++ b/jdk/test/java/net/URLClassLoader/profiles/Lib.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package lib;
+
+public class Lib {
+    private Lib() { }
+
+    public static void doSomething() { }
+}
diff --git a/jdk/test/java/net/URLClassLoader/profiles/basic.sh b/jdk/test/java/net/URLClassLoader/profiles/basic.sh
new file mode 100644
index 0000000..9f0867f
--- /dev/null
+++ b/jdk/test/java/net/URLClassLoader/profiles/basic.sh
@@ -0,0 +1,55 @@
+#
+# 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 8003255
+# @compile -XDignore.symbol.file Basic.java Lib.java
+# @summary Test that UnsupportedProfileException thrown when attempting to
+#     load classes or resources from a JAR file with the Profile attribute
+# @run shell basic.sh
+
+if [ -z "$TESTJAVA" ]; then
+  if [ $# -lt 1 ]; then exit 1; fi
+  TESTJAVA=$1; shift
+  COMPILEJAVA=$TESTJAVA
+  TESTSRC=`pwd`
+  TESTCLASSES=`pwd`
+fi
+
+echo "Creating GoodLib.jar ..."
+echo "Profile: compact3" > good.mf
+$COMPILEJAVA/bin/jar cvfm GoodLib.jar good.mf -C $TESTCLASSES lib
+
+echo "Create BadLib.jar ..."
+echo "Profile: badname" > bad.mf
+$COMPILEJAVA/bin/jar cvfm BadLib.jar bad.mf -C $TESTCLASSES lib
+
+# remove classes so that they aren't on the classpath
+rm -rf $TESTCLASSES/lib
+
+echo "Test with GoodLib.jar ..."
+$TESTJAVA/bin/java -cp $TESTCLASSES Basic GoodLib.jar lib.Lib
+
+echo "Test with BadLib.jar ..."
+$TESTJAVA/bin/java -cp $TESTCLASSES Basic BadLib.jar lib.Lib
+
diff --git a/jdk/test/java/security/KeyStore/PBETest.java b/jdk/test/java/security/KeyStore/PBETest.java
index 2186165..671e001 100644
--- a/jdk/test/java/security/KeyStore/PBETest.java
+++ b/jdk/test/java/security/KeyStore/PBETest.java
@@ -29,6 +29,7 @@
 
 import java.io.*;
 import java.security.*;
+import javax.crypto.*;
 import javax.crypto.spec.*;
 
 // Retrieve a keystore entry, protected by the default encryption algorithm.
@@ -36,13 +37,20 @@
 
 public class PBETest {
     private final static String DIR = System.getProperty("test.src", ".");
-    //private static final String PBE_ALGO = "PBEWithHmacSHA1AndAES_128";
-    private static final String PBE_ALGO = "PBEWithSHA1AndDESede";
+    private final static String KEY_PROTECTION_PROPERTY =
+        "keystore.PKCS12.keyProtectionAlgorithm";
+    private static final String[] PBE_ALGOS = {
+        "PBEWithSHA1AndDESede",
+        "PBEWithHmacSHA1AndAES_128",
+        "PBEWithHmacSHA224AndAES_128",
+        "PBEWithHmacSHA256AndAES_128",
+        "PBEWithHmacSHA384AndAES_128",
+        "PBEWithHmacSHA512AndAES_128"
+    };
     private static final char[] PASSWORD = "passphrase".toCharArray();
     private static final String KEYSTORE_TYPE = "JKS";
     private static final String KEYSTORE = DIR + "/keystore.jks";
     private static final String NEW_KEYSTORE_TYPE = "PKCS12";
-    private static final String NEW_KEYSTORE = PBE_ALGO + ".p12";
     private static final String ALIAS = "vajra";
 
     private static final byte[] IV = {
@@ -55,32 +63,87 @@
     private static final int ITERATION_COUNT = 1024;
 
     public static void main(String[] args) throws Exception {
+        for (String algo : PBE_ALGOS) {
+            String filename = algo + ".p12";
+            main0(algo, filename, true);
+            main0(algo, filename, false);
+            Security.setProperty(KEY_PROTECTION_PROPERTY, algo);
+            main0(null, "PBE.p12", false);
+            Security.setProperty(KEY_PROTECTION_PROPERTY, "");
+        }
+        main0(null, "default.p12", false); // default algorithm
+    }
 
-        new File(NEW_KEYSTORE).delete();
+    private static void main0(String algo, String filename, boolean useParams)
+        throws Exception {
 
         KeyStore keystore = load(KEYSTORE_TYPE, KEYSTORE, PASSWORD);
         KeyStore.Entry entry =
             keystore.getEntry(ALIAS,
                 new KeyStore.PasswordProtection(PASSWORD));
-        System.out.println("Retrieved entry named '" + ALIAS + "'");
+        System.out.println("Retrieved key entry named '" + ALIAS + "'");
+        Key originalKey = null;
+        if (entry instanceof KeyStore.PrivateKeyEntry) {
+            originalKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
+        } else if (entry instanceof KeyStore.SecretKeyEntry) {
+            originalKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
+        }
 
         // Set entry
         KeyStore keystore2 = load(NEW_KEYSTORE_TYPE, null, null);
-        keystore2.setEntry(ALIAS, entry,
-            new KeyStore.PasswordProtection(PASSWORD, PBE_ALGO,
-                new PBEParameterSpec(SALT, ITERATION_COUNT,
-                    new IvParameterSpec(IV))));
-        System.out.println("Encrypted entry using: " + PBE_ALGO);
+        if (useParams) {
+            keystore2.setEntry(ALIAS, entry,
+                new KeyStore.PasswordProtection(PASSWORD, algo,
+                    new PBEParameterSpec(SALT, ITERATION_COUNT,
+                        new IvParameterSpec(IV))));
+            System.out.println("Encrypted key entry using: " + algo +
+                " (with PBE parameters)");
+        } else if (algo != null) {
+            keystore2.setEntry(ALIAS, entry,
+                new KeyStore.PasswordProtection(PASSWORD, algo, null));
+            System.out.println("Encrypted key entry using: " + algo +
+                " (without PBE parameters)");
+        } else {
+            keystore2.setEntry(ALIAS, entry,
+                new KeyStore.PasswordProtection(PASSWORD));
+            String prop = Security.getProperty(KEY_PROTECTION_PROPERTY);
+            if (prop == null || prop.isEmpty()) {
+                System.out.println("Encrypted key entry using: " +
+                    "default PKCS12 key protection algorithm");
+            } else {
+                System.out.println("Encrypted key entry using: " +
+                    "keyProtectionAlgorithm=" + prop);
+            }
+        }
 
-        try (FileOutputStream outStream = new FileOutputStream(NEW_KEYSTORE)) {
-            System.out.println("Storing keystore to: " + NEW_KEYSTORE);
+        try (FileOutputStream outStream = new FileOutputStream(filename)) {
+            System.out.println("Storing keystore to: " + filename);
             keystore2.store(outStream, PASSWORD);
         }
 
-        keystore2 = load(NEW_KEYSTORE_TYPE, NEW_KEYSTORE, PASSWORD);
-        entry = keystore2.getEntry(ALIAS,
-            new KeyStore.PasswordProtection(PASSWORD));
-        System.out.println("Retrieved entry named '" + ALIAS + "'");
+        try {
+            keystore2 = load(NEW_KEYSTORE_TYPE, filename, PASSWORD);
+            entry = keystore2.getEntry(ALIAS,
+                new KeyStore.PasswordProtection(PASSWORD));
+            Key key;
+            if (entry instanceof KeyStore.PrivateKeyEntry) {
+                key = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
+            } else if (entry instanceof KeyStore.SecretKeyEntry) {
+                key = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
+            } else {
+                throw new Exception("Failed to retrieve key entry");
+            }
+            if (originalKey.equals(key)) {
+                System.out.println("Retrieved key entry named '" + ALIAS + "'");
+                System.out.println();
+            } else {
+                throw new Exception(
+                    "Failed: recovered key does not match the original key");
+            }
+
+        } finally {
+            new File(filename).delete();
+        }
     }
 
     private static KeyStore load(String type, String path, char[] password)
diff --git a/jdk/test/java/security/cert/CertStore/NoLDAP.java b/jdk/test/java/security/cert/CertStore/NoLDAP.java
new file mode 100644
index 0000000..cede90c
--- /dev/null
+++ b/jdk/test/java/security/cert/CertStore/NoLDAP.java
@@ -0,0 +1,50 @@
+/*
+ * 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 8004502
+ * @summary Sanity check that NoSuchAlgorithmException is thrown when requesting
+ *   a CertStore of type "LDAP" and LDAP is not available.
+ */
+
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertStore;
+import java.security.cert.LDAPCertStoreParameters;
+
+
+public class NoLDAP {
+    public static void main(String[] args) throws Exception {
+        try {
+            Class.forName("javax.naming.ldap.LdapName");
+            System.out.println("LDAP is present, test skipped");
+            return;
+        } catch (ClassNotFoundException ignore) { }
+
+        try {
+            CertStore.getInstance("LDAP", new LDAPCertStoreParameters());
+            throw new RuntimeException("NoSuchAlgorithmException expected");
+        } catch (NoSuchAlgorithmException x) {
+            System.out.println("NoSuchAlgorithmException thrown as expected");
+        }
+    }
+}
diff --git a/jdk/test/java/sql/JavatimeTest.java b/jdk/test/java/sql/JavatimeTest.java
new file mode 100644
index 0000000..3ff70d0
--- /dev/null
+++ b/jdk/test/java/sql/JavatimeTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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 8007520
+ *@summary Test those bridge methods to/from java.time date/time classes
+ */
+
+import java.util.Random;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+public class JavatimeTest {
+
+    static final int NANOS_PER_SECOND = 1000000000;
+
+    public static void main(String[] args) throws Throwable {
+        int N = 10000;
+        long t1970 = new java.util.Date(70, 0, 01).getTime();
+        Random r = new Random();
+        for (int i = 0; i < N; i++) {
+            int days  = r.nextInt(50) * 365 + r.nextInt(365);
+            long secs = t1970 + days * 86400 + r.nextInt(86400);
+            int nanos = r.nextInt(NANOS_PER_SECOND);
+            int nanos_ms = nanos / 1000000 * 1000000; // millis precision
+            long millis = secs * 1000 + r.nextInt(1000);
+
+            LocalDateTime ldt = LocalDateTime.ofEpochSecond(secs, nanos, ZoneOffset.UTC);
+            LocalDateTime ldt_ms = LocalDateTime.ofEpochSecond(secs, nanos_ms, ZoneOffset.UTC);
+            Instant inst = Instant.ofEpochSecond(secs, nanos);
+            Instant inst_ms = Instant.ofEpochSecond(secs, nanos_ms);
+            //System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+
+            /////////// Timestamp ////////////////////////////////
+            Timestamp ta = new Timestamp(millis);
+            ta.setNanos(nanos);
+            if (!isEqual(ta.toLocalDateTime(), ta)) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                print(ta.toLocalDateTime(), ta);
+                throw new RuntimeException("FAILED: j.s.ts -> ldt");
+            }
+            if (!isEqual(ldt, Timestamp.valueOf(ldt))) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                print(ldt, Timestamp.valueOf(ldt));
+                throw new RuntimeException("FAILED: ldt -> j.s.ts");
+            }
+            Instant inst0 = ta.toInstant();
+            if (ta.getTime() != inst0.toEpochMilli() ||
+                ta.getNanos() != inst0.getNano() ||
+                !ta.equals(Timestamp.from(inst0))) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                throw new RuntimeException("FAILED: j.s.ts -> instant -> j.s.ts");
+            }
+            inst = Instant.ofEpochSecond(secs, nanos);
+            Timestamp ta0 = Timestamp.from(inst);
+            if (ta0.getTime() != inst.toEpochMilli() ||
+                ta0.getNanos() != inst.getNano() ||
+                !inst.equals(ta0.toInstant())) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                throw new RuntimeException("FAILED: instant -> timestamp -> instant");
+            }
+
+            ////////// java.sql.Date /////////////////////////////
+            // j.s.d/t uses j.u.d.equals() !!!!!!!!
+            java.sql.Date jsd = new java.sql.Date(millis);
+            if (!isEqual(jsd.toLocalDate(), jsd)) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                print(jsd.toLocalDate(), jsd);
+                throw new RuntimeException("FAILED: j.s.d -> ld");
+            }
+            LocalDate ld = ldt.toLocalDate();
+            if (!isEqual(ld, java.sql.Date.valueOf(ld))) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                print(ld, java.sql.Date.valueOf(ld));
+                throw new RuntimeException("FAILED: ld -> j.s.d");
+            }
+            ////////// java.sql.Time /////////////////////////////
+            java.sql.Time jst = new java.sql.Time(millis);
+            if (!isEqual(jst.toLocalTime(), jst)) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                print(jst.toLocalTime(), jst);
+                throw new RuntimeException("FAILED: j.s.t -> lt");
+            }
+            // millis precision
+            LocalTime lt = ldt_ms.toLocalTime();
+            if (!isEqual(lt, java.sql.Time.valueOf(lt))) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                print(lt, java.sql.Time.valueOf(lt));
+                throw new RuntimeException("FAILED: lt -> j.s.t");
+            }
+        }
+        System.out.println("Passed!");
+    }
+
+    private static boolean isEqual(LocalDateTime ldt, Timestamp ts) {
+        ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
+        return zdt.getYear() == ts.getYear() + 1900 &&
+               zdt.getMonthValue() == ts.getMonth() + 1 &&
+               zdt.getDayOfMonth() == ts.getDate() &&
+               zdt.getHour() == ts.getHours() &&
+               zdt.getMinute() == ts.getMinutes() &&
+               zdt.getSecond() == ts.getSeconds() &&
+               zdt.getNano() == ts.getNanos();
+    }
+
+    private static void print(LocalDateTime ldt, Timestamp ts) {
+        ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
+        System.out.printf("ldt:ts  %d/%d, %d/%d, %d/%d, %d/%d, %d/%d, %d/%d, nano:[%d/%d]%n",
+               zdt.getYear(), ts.getYear() + 1900,
+               zdt.getMonthValue(), ts.getMonth() + 1,
+               zdt.getDayOfMonth(), ts.getDate(),
+               zdt.getHour(), ts.getHours(),
+               zdt.getMinute(), ts.getMinutes(),
+               zdt.getSecond(), ts.getSeconds(),
+               zdt.getNano(), ts.getNanos());
+    }
+
+    private static boolean isEqual(LocalDate ld, java.sql.Date d) {
+        return ld.getYear() == d.getYear() + 1900 &&
+               ld.getMonthValue() == d.getMonth() + 1 &&
+               ld.getDayOfMonth() == d.getDate();
+    }
+
+    private static void print(LocalDate ld, java.sql.Date d) {
+        System.out.printf("%d/%d, %d/%d, %d/%d%n",
+               ld.getYear(), d.getYear() + 1900,
+               ld.getMonthValue(), d.getMonth() + 1,
+               ld.getDayOfMonth(), d.getDate());
+    }
+
+    private static boolean isEqual(LocalTime lt, java.sql.Time t) {
+        return lt.getHour() == t.getHours() &&
+               lt.getMinute() == t.getMinutes() &&
+               lt.getSecond() == t.getSeconds();
+    }
+
+    private static void print(LocalTime lt, java.sql.Time t) {
+        System.out.printf("%d/%d, %d/%d, %d/%d%n",
+                          lt.getHour(), t.getHours(),
+                          lt.getMinute(), t.getMinutes(),
+                          lt.getSecond(), t.getSeconds());
+    }
+}
diff --git a/jdk/test/java/time/META-INF/services/java.time.chrono.Chronology b/jdk/test/java/time/META-INF/services/java.time.chrono.Chronology
new file mode 100644
index 0000000..d30ab01
--- /dev/null
+++ b/jdk/test/java/time/META-INF/services/java.time.chrono.Chronology
@@ -0,0 +1 @@
+tck.java.time.chrono.CopticChronology
diff --git a/jdk/test/java/time/META-INF/services/java.time.temporal.Chrono b/jdk/test/java/time/META-INF/services/java.time.temporal.Chrono
deleted file mode 100644
index 918ad84..0000000
--- a/jdk/test/java/time/META-INF/services/java.time.temporal.Chrono
+++ /dev/null
@@ -1 +0,0 @@
-tck.java.time.calendar.CopticChrono
diff --git a/jdk/test/java/time/tck/java/time/AbstractTCKTest.java b/jdk/test/java/time/tck/java/time/AbstractTCKTest.java
index ce20d6b..ff7fc02 100644
--- a/jdk/test/java/time/tck/java/time/AbstractTCKTest.java
+++ b/jdk/test/java/time/tck/java/time/AbstractTCKTest.java
@@ -57,6 +57,7 @@
 package tck.java.time;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -89,6 +90,12 @@
         assertEquals(deserializedObject, object);
     }
 
+    protected static void assertSerializableSame(Object object) throws IOException, ClassNotFoundException {
+        assertEquals(object instanceof Serializable, true);
+        Object deserializedObject = writeThenRead(object);
+        assertSame(deserializedObject, object);
+    }
+
     private static Object writeThenRead(Object object) throws IOException, ClassNotFoundException {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) {
diff --git a/jdk/test/java/time/tck/java/time/MockSimplePeriod.java b/jdk/test/java/time/tck/java/time/MockSimplePeriod.java
new file mode 100644
index 0000000..7b00834
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/MockSimplePeriod.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time;
+
+import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.FOREVER;
+import static java.time.temporal.ChronoUnit.SECONDS;
+
+import java.time.DateTimeException;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalUnit;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Mock period of time measured using a single unit, such as {@code 3 Days}.
+ */
+public final class MockSimplePeriod
+        implements TemporalAmount, Comparable<MockSimplePeriod> {
+
+    /**
+     * A constant for a period of zero, measured in days.
+     */
+    public static final MockSimplePeriod ZERO_DAYS = new MockSimplePeriod(0, DAYS);
+    /**
+     * A constant for a period of zero, measured in seconds.
+     */
+    public static final MockSimplePeriod ZERO_SECONDS = new MockSimplePeriod(0, SECONDS);
+
+    /**
+     * The amount of the period.
+     */
+    private final long amount;
+    /**
+     * The unit the period is measured in.
+     */
+    private final TemporalUnit unit;
+
+    /**
+     * Obtains a {@code MockSimplePeriod} from an amount and unit.
+     * <p>
+     * The parameters represent the two parts of a phrase like '6 Days'.
+     *
+     * @param amount  the amount of the period, measured in terms of the unit, positive or negative
+     * @param unit  the unit that the period is measured in, must not be the 'Forever' unit, not null
+     * @return the {@code MockSimplePeriod} instance, not null
+     * @throws java.time.DateTimeException if the period unit is {@link java.time.temporal.ChronoUnit#FOREVER}.
+     */
+    public static MockSimplePeriod of(long amount, TemporalUnit unit) {
+        return new MockSimplePeriod(amount, unit);
+    }
+
+    private MockSimplePeriod(long amount, TemporalUnit unit) {
+        Objects.requireNonNull(unit, "unit");
+        if (unit == FOREVER) {
+            throw new DateTimeException("Cannot create a period of the Forever unit");
+        }
+        this.amount = amount;
+        this.unit = unit;
+    }
+
+    @Override
+    public long get(TemporalUnit unit) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public List<TemporalUnit> getUnits() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    //-----------------------------------------------------------------------
+    public long getAmount() {
+        return amount;
+    }
+
+    public TemporalUnit getUnit() {
+        return unit;
+    }
+
+    //-------------------------------------------------------------------------
+    @Override
+    public Temporal addTo(Temporal temporal) {
+        return temporal.plus(amount, unit);
+    }
+
+    @Override
+    public Temporal subtractFrom(Temporal temporal) {
+        return temporal.minus(amount, unit);
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public int compareTo(MockSimplePeriod otherPeriod) {
+        if (unit.equals(otherPeriod.getUnit()) == false) {
+            throw new IllegalArgumentException("Units cannot be compared: " + unit + " and " + otherPeriod.getUnit());
+        }
+        return Long.compare(amount, otherPeriod.amount);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+           return true;
+        }
+        if (obj instanceof MockSimplePeriod) {
+            MockSimplePeriod other = (MockSimplePeriod) obj;
+            return this.amount == other.amount &&
+                    this.unit.equals(other.unit);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return unit.hashCode() ^ (int) (amount ^ (amount >>> 32));
+    }
+
+    @Override
+    public String toString() {
+        return amount + " " + unit.getName();
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/TCKClock.java b/jdk/test/java/time/tck/java/time/TCKClock.java
index e4a870e..82e47f7 100644
--- a/jdk/test/java/time/tck/java/time/TCKClock.java
+++ b/jdk/test/java/time/tck/java/time/TCKClock.java
@@ -83,6 +83,10 @@
             return millis;
         }
         @Override
+        public Instant instant() {
+            return Instant.ofEpochMilli(millis());
+        }
+        @Override
         public ZoneId getZone() {
             return zone;
         }
diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java b/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java
index 20e66a2..13cc7b4 100644
--- a/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java
+++ b/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java
@@ -154,13 +154,4 @@
         Clock d = Clock.fixed(INSTANT.minusNanos(1), ZoneOffset.UTC);
         assertEquals(a.hashCode() == d.hashCode(), false);
     }
-
-    //-----------------------------------------------------------------------
-    public void test_toString() {
-        // spec requires "full state" in toString()
-        Clock test = Clock.fixed(INSTANT, PARIS);
-        assertEquals(test.toString().contains("Europe/Paris"), true);
-        assertEquals(test.toString().contains("2008-06-30T09:30:10.000000500Z"), true);
-    }
-
 }
diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Offset.java b/jdk/test/java/time/tck/java/time/TCKClock_Offset.java
index b628c0c..3bab2ac 100644
--- a/jdk/test/java/time/tck/java/time/TCKClock_Offset.java
+++ b/jdk/test/java/time/tck/java/time/TCKClock_Offset.java
@@ -91,8 +91,8 @@
     //-----------------------------------------------------------------------
     public void test_offset_ClockDuration() {
         Clock test = Clock.offset(Clock.fixed(INSTANT, PARIS), OFFSET);
-        System.out.println(test.instant());
-        System.out.println(INSTANT.plus(OFFSET));
+        //System.out.println(test.instant());
+        //System.out.println(INSTANT.plus(OFFSET));
         assertEquals(test.instant(), INSTANT.plus(OFFSET));
         assertEquals(test.getZone(), PARIS);
     }
@@ -165,12 +165,4 @@
         assertEquals(a.hashCode() == d.hashCode(), false);
     }
 
-    //-----------------------------------------------------------------------
-    public void test_toString() {
-        // spec requires "full state" in toString()
-        Clock test = Clock.offset(Clock.system(PARIS), OFFSET);
-        assertEquals(test.toString().contains("Europe/Paris"), true);
-        assertEquals(test.toString().contains("PT2S"), true);
-    }
-
 }
diff --git a/jdk/test/java/time/tck/java/time/TCKClock_System.java b/jdk/test/java/time/tck/java/time/TCKClock_System.java
index 8152a50..b5440b2 100644
--- a/jdk/test/java/time/tck/java/time/TCKClock_System.java
+++ b/jdk/test/java/time/tck/java/time/TCKClock_System.java
@@ -197,11 +197,4 @@
         assertEquals(a.hashCode() == c.hashCode(), false);
     }
 
-    //-----------------------------------------------------------------------
-    public void test_toString() {
-        // spec requires "full state" in toString()
-        Clock test = Clock.system(PARIS);
-        assertEquals(test.toString().contains("Europe/Paris"), true);
-    }
-
 }
diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Tick.java b/jdk/test/java/time/tck/java/time/TCKClock_Tick.java
index 3022d77..b245d14 100644
--- a/jdk/test/java/time/tck/java/time/TCKClock_Tick.java
+++ b/jdk/test/java/time/tck/java/time/TCKClock_Tick.java
@@ -248,13 +248,4 @@
         Clock d = Clock.tick(Clock.system(PARIS), Duration.ofMillis(499));
         assertEquals(a.hashCode() == d.hashCode(), false);
     }
-
-    //-----------------------------------------------------------------------
-    public void test_toString() {
-        // spec requires "full state" in toString()
-        Clock test = Clock.tick(Clock.system(PARIS), AMOUNT);
-        assertEquals(test.toString().contains("Europe/Paris"), true);
-        assertEquals(test.toString().contains("PT2S"), true);
-    }
-
 }
diff --git a/jdk/test/java/time/tck/java/time/TCKDayOfWeek.java b/jdk/test/java/time/tck/java/time/TCKDayOfWeek.java
index a246089..196c040 100644
--- a/jdk/test/java/time/tck/java/time/TCKDayOfWeek.java
+++ b/jdk/test/java/time/tck/java/time/TCKDayOfWeek.java
@@ -66,25 +66,24 @@
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertSame;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
 import java.time.DateTimeException;
 import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.time.Month;
+import java.time.chrono.IsoChronology;
 import java.time.format.TextStyle;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.JulianFields;
 import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
@@ -177,34 +176,27 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(DayOfWeek.FRIDAY.query(Queries.chrono()), null);
-        assertEquals(Queries.chrono().queryFrom(DayOfWeek.FRIDAY), null);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {DayOfWeek.FRIDAY, Queries.chronology(), null},
+                {DayOfWeek.FRIDAY, Queries.zoneId(), null},
+                {DayOfWeek.FRIDAY, Queries.precision(), ChronoUnit.DAYS},
+                {DayOfWeek.FRIDAY, Queries.zone(), null},
+                {DayOfWeek.FRIDAY, Queries.offset(), null},
+                {DayOfWeek.FRIDAY, Queries.localDate(), null},
+                {DayOfWeek.FRIDAY, Queries.localTime(), null},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(DayOfWeek.FRIDAY.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(DayOfWeek.FRIDAY), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        assertEquals(DayOfWeek.FRIDAY.query(Queries.precision()), ChronoUnit.DAYS);
-        assertEquals(Queries.precision().queryFrom(DayOfWeek.FRIDAY), ChronoUnit.DAYS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(DayOfWeek.FRIDAY.query(Queries.offset()), null);
-        assertEquals(Queries.offset().queryFrom(DayOfWeek.FRIDAY), null);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(DayOfWeek.FRIDAY.query(Queries.zone()), null);
-        assertEquals(Queries.zone().queryFrom(DayOfWeek.FRIDAY), null);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -217,17 +209,17 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_getText() {
-        assertEquals(DayOfWeek.MONDAY.getText(TextStyle.SHORT, Locale.US), "Mon");
+        assertEquals(DayOfWeek.MONDAY.getDisplayName(TextStyle.SHORT, Locale.US), "Mon");
     }
 
     @Test(expectedExceptions = NullPointerException.class, groups={"tck"})
     public void test_getText_nullStyle() {
-        DayOfWeek.MONDAY.getText(null, Locale.US);
+        DayOfWeek.MONDAY.getDisplayName(null, Locale.US);
     }
 
     @Test(expectedExceptions = NullPointerException.class, groups={"tck"})
     public void test_getText_nullLocale() {
-        DayOfWeek.MONDAY.getText(TextStyle.FULL, null);
+        DayOfWeek.MONDAY.getDisplayName(TextStyle.FULL, null);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/tck/java/time/TCKDuration.java b/jdk/test/java/time/tck/java/time/TCKDuration.java
index aeba804..797b54b 100644
--- a/jdk/test/java/time/tck/java/time/TCKDuration.java
+++ b/jdk/test/java/time/tck/java/time/TCKDuration.java
@@ -69,6 +69,7 @@
 import static java.time.temporal.ChronoUnit.SECONDS;
 import static java.time.temporal.ChronoUnit.WEEKS;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
 import java.io.ByteArrayInputStream;
@@ -76,12 +77,17 @@
 import java.io.DataOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-
 import java.time.DateTimeException;
 import java.time.Duration;
 import java.time.Instant;
+import java.time.LocalTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
 import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalUnit;
+import java.util.List;
+import java.util.Locale;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -436,8 +442,8 @@
     //-----------------------------------------------------------------------
     // between()
     //-----------------------------------------------------------------------
-    @DataProvider(name="DurationBetween")
-    Object[][] provider_factory_between_Instant_Instant() {
+    @DataProvider(name="durationBetweenInstant")
+    Object[][] data_durationBetweenInstant() {
         return new Object[][] {
             {0, 0, 0, 0, 0, 0},
             {3, 0, 7, 0, 4, 0},
@@ -447,8 +453,8 @@
         };
     }
 
-    @Test(dataProvider="DurationBetween", groups={"tck"})
-    public void factory_between_Instant_Instant(long secs1, int nanos1, long secs2, int nanos2, long expectedSeconds, int expectedNanoOfSecond) {
+    @Test(dataProvider="durationBetweenInstant")
+    public void factory_between_TemporalTemporal_Instant(long secs1, int nanos1, long secs2, int nanos2, long expectedSeconds, int expectedNanoOfSecond) {
         Instant start = Instant.ofEpochSecond(secs1, nanos1);
         Instant end = Instant.ofEpochSecond(secs2, nanos2);
         Duration t = Duration.between(start, end);
@@ -456,14 +462,36 @@
         assertEquals(t.getNano(), expectedNanoOfSecond);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_between_Instant_Instant_startNull() {
+    @DataProvider(name="durationBetweenLocalTime")
+    Object[][] data_durationBetweenLocalTime() {
+        return new Object[][] {
+                {LocalTime.of(11, 0, 30), LocalTime.of(11, 0, 45), 15L, 0},
+                {LocalTime.of(11, 0, 30), LocalTime.of(11, 0, 25), -5L, 0},
+        };
+    }
+
+    @Test(dataProvider="durationBetweenLocalTime")
+    public void factory_between_TemporalTemporal_LT(LocalTime start, LocalTime end, long expectedSeconds, int expectedNanoOfSecond) {
+        Duration t = Duration.between(start, end);
+        assertEquals(t.getSeconds(), expectedSeconds);
+        assertEquals(t.getNano(), expectedNanoOfSecond);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void factory_between_TemporalTemporal_mixedTypes() {
+        Instant start = Instant.ofEpochSecond(1);
+        ZonedDateTime end = Instant.ofEpochSecond(4).atZone(ZoneOffset.UTC);
+        Duration.between(start, end);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void factory_between__TemporalTemporal_startNull() {
         Instant end = Instant.ofEpochSecond(1);
         Duration.between(null, end);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_between_Instant_Instant_endNull() {
+    @Test(expectedExceptions=NullPointerException.class)
+    public void factory_between__TemporalTemporal_endNull() {
         Instant start = Instant.ofEpochSecond(1);
         Duration.between(start, null);
     }
@@ -471,140 +499,257 @@
     //-----------------------------------------------------------------------
     // parse(String)
     //-----------------------------------------------------------------------
-    @DataProvider(name="Parse")
-    Object[][] provider_factory_parse() {
+    @DataProvider(name="parseSuccess")
+    Object[][] data_parseSuccess() {
         return new Object[][] {
-            {"PT0S", 0, 0},
-            {"pT0S", 0, 0},
-            {"Pt0S", 0, 0},
-            {"PT0s", 0, 0},
+                {"PT0S", 0, 0},
+                {"PT1S", 1, 0},
+                {"PT12S", 12, 0},
+                {"PT123456789S", 123456789, 0},
+                {"PT" + Long.MAX_VALUE + "S", Long.MAX_VALUE, 0},
 
-            {"PT1S", 1, 0},
-            {"PT12S", 12, 0},
-            {"PT123456789S", 123456789, 0},
-            {"PT" + Long.MAX_VALUE + "S", Long.MAX_VALUE, 0},
+                {"PT+1S", 1, 0},
+                {"PT+12S", 12, 0},
+                {"PT+123456789S", 123456789, 0},
+                {"PT+" + Long.MAX_VALUE + "S", Long.MAX_VALUE, 0},
 
-            {"PT-1S", -1, 0},
-            {"PT-12S", -12, 0},
-            {"PT-123456789S", -123456789, 0},
-            {"PT" + Long.MIN_VALUE + "S", Long.MIN_VALUE, 0},
+                {"PT-1S", -1, 0},
+                {"PT-12S", -12, 0},
+                {"PT-123456789S", -123456789, 0},
+                {"PT" + Long.MIN_VALUE + "S", Long.MIN_VALUE, 0},
 
-            {"PT1.1S", 1, 100000000},
-            {"PT1.12S", 1, 120000000},
-            {"PT1.123S", 1, 123000000},
-            {"PT1.1234S", 1, 123400000},
-            {"PT1.12345S", 1, 123450000},
-            {"PT1.123456S", 1, 123456000},
-            {"PT1.1234567S", 1, 123456700},
-            {"PT1.12345678S", 1, 123456780},
-            {"PT1.123456789S", 1, 123456789},
+                {"PT1.1S", 1, 100000000},
+                {"PT1.12S", 1, 120000000},
+                {"PT1.123S", 1, 123000000},
+                {"PT1.1234S", 1, 123400000},
+                {"PT1.12345S", 1, 123450000},
+                {"PT1.123456S", 1, 123456000},
+                {"PT1.1234567S", 1, 123456700},
+                {"PT1.12345678S", 1, 123456780},
+                {"PT1.123456789S", 1, 123456789},
 
-            {"PT-1.1S", -2, 1000000000 - 100000000},
-            {"PT-1.12S", -2, 1000000000 - 120000000},
-            {"PT-1.123S", -2, 1000000000 - 123000000},
-            {"PT-1.1234S", -2, 1000000000 - 123400000},
-            {"PT-1.12345S", -2, 1000000000 - 123450000},
-            {"PT-1.123456S", -2, 1000000000 - 123456000},
-            {"PT-1.1234567S", -2, 1000000000 - 123456700},
-            {"PT-1.12345678S", -2, 1000000000 - 123456780},
-            {"PT-1.123456789S", -2, 1000000000 - 123456789},
+                {"PT-1.1S", -2, 1000000000 - 100000000},
+                {"PT-1.12S", -2, 1000000000 - 120000000},
+                {"PT-1.123S", -2, 1000000000 - 123000000},
+                {"PT-1.1234S", -2, 1000000000 - 123400000},
+                {"PT-1.12345S", -2, 1000000000 - 123450000},
+                {"PT-1.123456S", -2, 1000000000 - 123456000},
+                {"PT-1.1234567S", -2, 1000000000 - 123456700},
+                {"PT-1.12345678S", -2, 1000000000 - 123456780},
+                {"PT-1.123456789S", -2, 1000000000 - 123456789},
 
-            {"PT" + Long.MAX_VALUE + ".123456789S", Long.MAX_VALUE, 123456789},
-            {"PT" + Long.MIN_VALUE + ".000000000S", Long.MIN_VALUE, 0},
+                {"PT" + Long.MAX_VALUE + ".123456789S", Long.MAX_VALUE, 123456789},
+                {"PT" + Long.MIN_VALUE + ".000000000S", Long.MIN_VALUE, 0},
+
+                {"PT01S", 1, 0},
+                {"PT001S", 1, 0},
+                {"PT000S", 0, 0},
+                {"PT+01S", 1, 0},
+                {"PT-01S", -1, 0},
+
+                {"PT1.S", 1, 0},
+                {"PT+1.S", 1, 0},
+                {"PT-1.S", -1, 0},
+
+                {"P0D", 0, 0},
+                {"P0DT0H", 0, 0},
+                {"P0DT0M", 0, 0},
+                {"P0DT0S", 0, 0},
+                {"P0DT0H0S", 0, 0},
+                {"P0DT0M0S", 0, 0},
+                {"P0DT0H0M0S", 0, 0},
+
+                {"P1D", 86400, 0},
+                {"P1DT0H", 86400, 0},
+                {"P1DT0M", 86400, 0},
+                {"P1DT0S", 86400, 0},
+                {"P1DT0H0S", 86400, 0},
+                {"P1DT0M0S", 86400, 0},
+                {"P1DT0H0M0S", 86400, 0},
+
+                {"P3D", 86400 * 3, 0},
+                {"P3DT2H", 86400 * 3 + 3600 * 2, 0},
+                {"P3DT2M", 86400 * 3 + 60 * 2, 0},
+                {"P3DT2S", 86400 * 3 + 2, 0},
+                {"P3DT2H1S", 86400 * 3 + 3600 * 2 + 1, 0},
+                {"P3DT2M1S", 86400 * 3 + 60 * 2 + 1, 0},
+                {"P3DT2H1M1S", 86400 * 3 + 3600 * 2 + 60 + 1, 0},
+
+                {"P-3D", -86400 * 3, 0},
+                {"P-3DT2H", -86400 * 3 + 3600 * 2, 0},
+                {"P-3DT2M", -86400 * 3 + 60 * 2, 0},
+                {"P-3DT2S", -86400 * 3 + 2, 0},
+                {"P-3DT2H1S", -86400 * 3 + 3600 * 2 + 1, 0},
+                {"P-3DT2M1S", -86400 * 3 + 60 * 2 + 1, 0},
+                {"P-3DT2H1M1S", -86400 * 3 + 3600 * 2 + 60 + 1, 0},
+
+                {"P-3DT-2H", -86400 * 3 - 3600 * 2, 0},
+                {"P-3DT-2M", -86400 * 3 - 60 * 2, 0},
+                {"P-3DT-2S", -86400 * 3 - 2, 0},
+                {"P-3DT-2H1S", -86400 * 3 - 3600 * 2 + 1, 0},
+                {"P-3DT-2M1S", -86400 * 3 - 60 * 2 + 1, 0},
+                {"P-3DT-2H1M1S", -86400 * 3 - 3600 * 2 + 60 + 1, 0},
+
+                {"PT0H", 0, 0},
+                {"PT0H0M", 0, 0},
+                {"PT0H0S", 0, 0},
+                {"PT0H0M0S", 0, 0},
+
+                {"PT1H", 3600, 0},
+                {"PT3H", 3600 * 3, 0},
+                {"PT-1H", -3600, 0},
+                {"PT-3H", -3600 * 3, 0},
+
+                {"PT2H5M", 3600 * 2 + 60 * 5, 0},
+                {"PT2H5S", 3600 * 2 + 5, 0},
+                {"PT2H5M8S", 3600 * 2 + 60 * 5 + 8, 0},
+                {"PT-2H5M", -3600 * 2 + 60 * 5, 0},
+                {"PT-2H5S", -3600 * 2 + 5, 0},
+                {"PT-2H5M8S", -3600 * 2 + 60 * 5 + 8, 0},
+                {"PT-2H-5M", -3600 * 2 - 60 * 5, 0},
+                {"PT-2H-5S", -3600 * 2 - 5, 0},
+                {"PT-2H-5M8S", -3600 * 2 - 60 * 5 + 8, 0},
+                {"PT-2H-5M-8S", -3600 * 2 - 60 * 5 - 8, 0},
+
+                {"PT0M", 0, 0},
+                {"PT1M", 60, 0},
+                {"PT3M", 60 * 3, 0},
+                {"PT-1M", -60, 0},
+                {"PT-3M", -60 * 3, 0},
+                {"P0DT3M", 60 * 3, 0},
+                {"P0DT-3M", -60 * 3, 0},
         };
     }
 
-    @Test(dataProvider="Parse", groups={"tck"})
+    @Test(dataProvider="parseSuccess")
     public void factory_parse(String text, long expectedSeconds, int expectedNanoOfSecond) {
-        Duration t = Duration.parse(text);
-        assertEquals(t.getSeconds(), expectedSeconds);
-        assertEquals(t.getNano(), expectedNanoOfSecond);
+        Duration test = Duration.parse(text);
+        assertEquals(test.getSeconds(), expectedSeconds);
+        assertEquals(test.getNano(), expectedNanoOfSecond);
     }
 
-    @Test(dataProvider="Parse", groups={"tck"})
+    @Test(dataProvider="parseSuccess")
+    public void factory_parse_plus(String text, long expectedSeconds, int expectedNanoOfSecond) {
+        Duration test = Duration.parse("+" + text);
+        assertEquals(test.getSeconds(), expectedSeconds);
+        assertEquals(test.getNano(), expectedNanoOfSecond);
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void factory_parse_minus(String text, long expectedSeconds, int expectedNanoOfSecond) {
+        Duration test;
+        try {
+            test = Duration.parse("-" + text);
+        } catch (DateTimeParseException ex) {
+            assertEquals(expectedSeconds == Long.MIN_VALUE, true);
+            return;
+        }
+        // not inside try/catch or it breaks test
+        assertEquals(test, Duration.ofSeconds(expectedSeconds, expectedNanoOfSecond).negated());
+    }
+
+    @Test(dataProvider="parseSuccess")
     public void factory_parse_comma(String text, long expectedSeconds, int expectedNanoOfSecond) {
         text = text.replace('.', ',');
-        Duration t = Duration.parse(text);
-        assertEquals(t.getSeconds(), expectedSeconds);
-        assertEquals(t.getNano(), expectedNanoOfSecond);
+        Duration test = Duration.parse(text);
+        assertEquals(test.getSeconds(), expectedSeconds);
+        assertEquals(test.getNano(), expectedNanoOfSecond);
     }
 
-    @DataProvider(name="ParseFailures")
-    Object[][] provider_factory_parseFailures() {
+    @Test(dataProvider="parseSuccess")
+    public void factory_parse_lowerCase(String text, long expectedSeconds, int expectedNanoOfSecond) {
+        Duration test = Duration.parse(text.toLowerCase(Locale.ENGLISH));
+        assertEquals(test.getSeconds(), expectedSeconds);
+        assertEquals(test.getNano(), expectedNanoOfSecond);
+    }
+
+    @DataProvider(name="parseFailure")
+    Object[][] data_parseFailure() {
         return new Object[][] {
-            {""},
-            {"PTS"},
-            {"AT0S"},
-            {"PA0S"},
-            {"PT0A"},
+                {""},
+                {"ABCDEF"},
+                {" PT0S"},
+                {"PT0S "},
 
-            {"PT+S"},
-            {"PT-S"},
-            {"PT.S"},
-            {"PTAS"},
+                {"PTS"},
+                {"AT0S"},
+                {"PA0S"},
+                {"PT0A"},
 
-            {"PT+0S"},
-            {"PT+00S"},
-            {"PT+000S"},
-            {"PT-0S"},
-            {"PT-00S"},
-            {"PT-000S"},
-            {"PT+1S"},
-            {"PT-.S"},
-            {"PT+.S"},
+                {"P0Y"},
+                {"P1Y"},
+                {"P-2Y"},
+                {"P0M"},
+                {"P1M"},
+                {"P-2M"},
+                {"P3Y2D"},
+                {"P3M2D"},
+                {"P3W"},
+                {"P-3W"},
+                {"P2YT30S"},
+                {"P2MT30S"},
 
-            {"PT1ABC2S"},
-            {"PT1.1ABC2S"},
+                {"P1DT"},
 
-            {"PT123456789123456789123456789S"},
-            {"PT0.1234567891S"},
-            {"PT1.S"},
-            {"PT.1S"},
+                {"PT+S"},
+                {"PT-S"},
+                {"PT.S"},
+                {"PTAS"},
 
-            {"PT2.-3"},
-            {"PT-2.-3"},
-            {"PT2.+3"},
-            {"PT-2.+3"},
+                {"PT-.S"},
+                {"PT+.S"},
+
+                {"PT1ABC2S"},
+                {"PT1.1ABC2S"},
+
+                {"PT123456789123456789123456789S"},
+                {"PT0.1234567891S"},
+
+                {"PT2.-3"},
+                {"PT-2.-3"},
+                {"PT2.+3"},
+                {"PT-2.+3"},
         };
     }
 
-    @Test(dataProvider="ParseFailures", expectedExceptions=DateTimeParseException.class, groups={"tck"})
+    @Test(dataProvider="parseFailure", expectedExceptions=DateTimeParseException.class)
     public void factory_parseFailures(String text) {
         Duration.parse(text);
     }
 
-    @Test(dataProvider="ParseFailures", expectedExceptions=DateTimeParseException.class, groups={"tck"})
+    @Test(dataProvider="parseFailure", expectedExceptions=DateTimeParseException.class)
     public void factory_parseFailures_comma(String text) {
         text = text.replace('.', ',');
         Duration.parse(text);
     }
 
-    @Test(expectedExceptions=DateTimeParseException.class, groups={"tck"})
+    @Test(expectedExceptions=DateTimeParseException.class)
     public void factory_parse_tooBig() {
         Duration.parse("PT" + Long.MAX_VALUE + "1S");
     }
 
-    @Test(expectedExceptions=DateTimeParseException.class, groups={"tck"})
+    @Test(expectedExceptions=DateTimeParseException.class)
     public void factory_parse_tooBig_decimal() {
         Duration.parse("PT" + Long.MAX_VALUE + "1.1S");
     }
 
-    @Test(expectedExceptions=DateTimeParseException.class, groups={"tck"})
+    @Test(expectedExceptions=DateTimeParseException.class)
     public void factory_parse_tooSmall() {
         Duration.parse("PT" + Long.MIN_VALUE + "1S");
     }
 
-    @Test(expectedExceptions=DateTimeParseException.class, groups={"tck"})
+    @Test(expectedExceptions=DateTimeParseException.class)
     public void factory_parse_tooSmall_decimal() {
         Duration.parse("PT" + Long.MIN_VALUE + ".1S");
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void factory_parse_nullText() {
-        Duration.parse((String) null);
+        Duration.parse(null);
     }
 
-    @Test(groups={"tck"})
+    //-----------------------------------------------------------------------
+    @Test
     public void test_deserialization() throws Exception {
         Duration orginal = Duration.ofSeconds(2);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -620,7 +765,7 @@
     //-----------------------------------------------------------------------
     // isZero(), isPositive(), isPositiveOrZero(), isNegative(), isNegativeOrZero()
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_isZero() {
         assertEquals(Duration.ofNanos(0).isZero(), true);
         assertEquals(Duration.ofSeconds(0).isZero(), true);
@@ -632,19 +777,7 @@
         assertEquals(Duration.ofSeconds(-1, -1).isZero(), false);
     }
 
-    @Test(groups={"tck"})
-    public void test_isPositive() {
-        assertEquals(Duration.ofNanos(0).isPositive(), false);
-        assertEquals(Duration.ofSeconds(0).isPositive(), false);
-        assertEquals(Duration.ofNanos(1).isPositive(), true);
-        assertEquals(Duration.ofSeconds(1).isPositive(), true);
-        assertEquals(Duration.ofSeconds(1, 1).isPositive(), true);
-        assertEquals(Duration.ofNanos(-1).isPositive(), false);
-        assertEquals(Duration.ofSeconds(-1).isPositive(), false);
-        assertEquals(Duration.ofSeconds(-1, -1).isPositive(), false);
-    }
-
-    @Test(groups={"tck"})
+    @Test
     public void test_isNegative() {
         assertEquals(Duration.ofNanos(0).isNegative(), false);
         assertEquals(Duration.ofSeconds(0).isNegative(), false);
@@ -1989,18 +2122,12 @@
                 Duration b = durations[j];
                 if (i < j) {
                     assertEquals(a.compareTo(b)< 0, true, a + " <=> " + b);
-                    assertEquals(a.isLessThan(b), true, a + " <=> " + b);
-                    assertEquals(a.isGreaterThan(b), false, a + " <=> " + b);
                     assertEquals(a.equals(b), false, a + " <=> " + b);
                 } else if (i > j) {
                     assertEquals(a.compareTo(b) > 0, true, a + " <=> " + b);
-                    assertEquals(a.isLessThan(b), false, a + " <=> " + b);
-                    assertEquals(a.isGreaterThan(b), true, a + " <=> " + b);
                     assertEquals(a.equals(b), false, a + " <=> " + b);
                 } else {
                     assertEquals(a.compareTo(b), 0, a + " <=> " + b);
-                    assertEquals(a.isLessThan(b), false, a + " <=> " + b);
-                    assertEquals(a.isGreaterThan(b), false, a + " <=> " + b);
                     assertEquals(a.equals(b), true, a + " <=> " + b);
                 }
             }
@@ -2013,18 +2140,6 @@
         a.compareTo(null);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_isLessThan_ObjectNull() {
-        Duration a = Duration.ofSeconds(0L, 0);
-        a.isLessThan(null);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_isGreaterThan_ObjectNull() {
-        Duration a = Duration.ofSeconds(0L, 0);
-        a.isGreaterThan(null);
-    }
-
     @Test(expectedExceptions=ClassCastException.class, groups={"tck"})
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public void compareToNonDuration() {
@@ -2096,7 +2211,7 @@
     //-----------------------------------------------------------------------
     // toString()
     //-----------------------------------------------------------------------
-    @DataProvider(name="ToString")
+    @DataProvider(name="toString")
     Object[][] provider_toString() {
         return new Object[][] {
             {0, 0, "PT0S"},
@@ -2118,18 +2233,72 @@
             {0, 123456780, "PT0.12345678S"},
             {0, 123456789, "PT0.123456789S"},
             {1, 0, "PT1S"},
+            {59, 0, "PT59S"},
+            {60, 0, "PT1M"},
+            {61, 0, "PT1M1S"},
+            {3599, 0, "PT59M59S"},
+            {3600, 0, "PT1H"},
+            {3601, 0, "PT1H1S"},
+            {3661, 0, "PT1H1M1S"},
+            {86399, 0, "PT23H59M59S"},
+            {86400, 0, "PT24H"},
+            {59, 0, "PT59S"},
+            {59, 0, "PT59S"},
             {-1, 0, "PT-1S"},
             {-1, 1000, "PT-0.999999S"},
             {-1, 900000000, "PT-0.1S"},
-            {Long.MAX_VALUE, 0, "PT9223372036854775807S"},
-            {Long.MIN_VALUE, 0, "PT-9223372036854775808S"},
+            {Long.MAX_VALUE, 0, "PT" + (Long.MAX_VALUE / 3600) + "H" +
+                    ((Long.MAX_VALUE % 3600) / 60) + "M" + (Long.MAX_VALUE % 60) + "S"},
+            {Long.MIN_VALUE, 0, "PT" + (Long.MIN_VALUE / 3600) + "H" +
+                    ((Long.MIN_VALUE % 3600) / 60) + "M" + (Long.MIN_VALUE % 60) + "S"},
         };
     }
 
-    @Test(dataProvider="ToString", groups={"tck"})
+    @Test(dataProvider="toString")
     public void test_toString(long seconds, int nanos, String expected) {
         Duration t = Duration.ofSeconds(seconds, nanos);
         assertEquals(t.toString(), expected);
     }
 
+    //-----------------------------------------------------------------------
+    @Test(groups="{tck}")
+    public void test_duration_getUnits() {
+        Duration duration = Duration.ofSeconds(5000, 1000);
+        List<TemporalUnit> units = duration.getUnits();
+        assertEquals(units.size(), 2, "Period.getUnits length");
+        assertTrue(units.contains(ChronoUnit.SECONDS), "Period.getUnits contains ChronoUnit.SECONDS");
+        assertTrue(units.contains(ChronoUnit.NANOS), "contains ChronoUnit.NANOS");
+    }
+
+    @Test()
+    public void test_getUnit() {
+        Duration test = Duration.ofSeconds(2000, 1000);
+        long seconds = test.get(ChronoUnit.SECONDS);
+        assertEquals(seconds, 2000, "duration.get(SECONDS)");
+        long nanos = test.get(ChronoUnit.NANOS);
+        assertEquals(nanos, 1000, "duration.get(NANOS)");
+    }
+
+    @DataProvider(name="BadTemporalUnit")
+    Object[][] provider_factory_of_badTemporalUnit() {
+        return new Object[][] {
+            {0, MICROS},
+            {0, MILLIS},
+            {0, MINUTES},
+            {0, HOURS},
+            {0, HALF_DAYS},
+            {0, DAYS},
+            {0, ChronoUnit.MONTHS},
+            {0, ChronoUnit.YEARS},
+            {0, ChronoUnit.DECADES},
+            {0, ChronoUnit.CENTURIES},
+            {0, ChronoUnit.MILLENNIA},
+        };
+    }
+
+    @Test(dataProvider="BadTemporalUnit", expectedExceptions=DateTimeException.class)
+    public void test_bad_getUnit(long amount, TemporalUnit unit) {
+        Duration t = Duration.of(amount, unit);
+        long actual = t.get(unit);
+    }
 }
diff --git a/jdk/test/java/time/tck/java/time/TCKInstant.java b/jdk/test/java/time/tck/java/time/TCKInstant.java
index e1f99d9..0dd745d 100644
--- a/jdk/test/java/time/tck/java/time/TCKInstant.java
+++ b/jdk/test/java/time/tck/java/time/TCKInstant.java
@@ -64,30 +64,42 @@
 import static java.time.temporal.ChronoField.MILLI_OF_SECOND;
 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
 import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.HOURS;
+import static java.time.temporal.ChronoUnit.MICROS;
+import static java.time.temporal.ChronoUnit.MILLIS;
+import static java.time.temporal.ChronoUnit.MINUTES;
+import static java.time.temporal.ChronoUnit.MONTHS;
 import static java.time.temporal.ChronoUnit.NANOS;
 import static java.time.temporal.ChronoUnit.SECONDS;
+import static java.time.temporal.ChronoUnit.WEEKS;
+import static java.time.temporal.ChronoUnit.YEARS;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Duration;
 import java.time.Instant;
 import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
 import java.time.temporal.JulianFields;
 import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
@@ -396,34 +408,27 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(TEST_12345_123456789.query(Queries.chrono()), null);
-        assertEquals(Queries.chrono().queryFrom(TEST_12345_123456789), null);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_12345_123456789, Queries.chronology(), null},
+                {TEST_12345_123456789, Queries.zoneId(), null},
+                {TEST_12345_123456789, Queries.precision(), NANOS},
+                {TEST_12345_123456789, Queries.zone(), null},
+                {TEST_12345_123456789, Queries.offset(), null},
+                {TEST_12345_123456789, Queries.localDate(), null},
+                {TEST_12345_123456789, Queries.localTime(), null},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(TEST_12345_123456789.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(TEST_12345_123456789), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        assertEquals(TEST_12345_123456789.query(Queries.precision()), NANOS);
-        assertEquals(Queries.precision().queryFrom(TEST_12345_123456789), NANOS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(TEST_12345_123456789.query(Queries.offset()), null);
-        assertEquals(Queries.offset().queryFrom(TEST_12345_123456789), null);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(TEST_12345_123456789.query(Queries.zone()), null);
-        assertEquals(Queries.zone().queryFrom(TEST_12345_123456789), null);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -432,6 +437,147 @@
     }
 
     //-----------------------------------------------------------------------
+    // truncated(TemporalUnit)
+    //-----------------------------------------------------------------------
+    TemporalUnit NINETY_MINS = new TemporalUnit() {
+        @Override
+        public String getName() {
+            return "NinetyMins";
+        }
+        @Override
+        public Duration getDuration() {
+            return Duration.ofMinutes(90);
+        }
+        @Override
+        public boolean isDurationEstimated() {
+            return false;
+        }
+        @Override
+        public boolean isSupportedBy(Temporal temporal) {
+            return false;
+        }
+        @Override
+        public <R extends Temporal> R addTo(R temporal, long amount) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public long between(Temporal temporal1, Temporal temporal2) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
+    TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() {
+        @Override
+        public String getName() {
+            return "NinetyFiveMins";
+        }
+        @Override
+        public Duration getDuration() {
+            return Duration.ofMinutes(95);
+        }
+        @Override
+        public boolean isDurationEstimated() {
+            return false;
+        }
+        @Override
+        public boolean isSupportedBy(Temporal temporal) {
+            return false;
+        }
+        @Override
+        public <R extends Temporal> R addTo(R temporal, long amount) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public long between(Temporal temporal1, Temporal temporal2) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
+    @DataProvider(name="truncatedToValid")
+    Object[][] data_truncatedToValid() {
+        return new Object[][] {
+                {Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789), NANOS, Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789)},
+                {Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789), MICROS, Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_000)},
+                {Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789), MILLIS, Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 1230_00_000)},
+                {Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789), SECONDS, Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 0)},
+                {Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789), MINUTES, Instant.ofEpochSecond(86400 + 3600 + 60, 0)},
+                {Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789), HOURS, Instant.ofEpochSecond(86400 + 3600, 0)},
+                {Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789), DAYS, Instant.ofEpochSecond(86400, 0)},
+
+                {Instant.ofEpochSecond(86400 + 3600 + 60 + 1, 123_456_789), NINETY_MINS, Instant.ofEpochSecond(86400 + 0, 0)},
+                {Instant.ofEpochSecond(86400 + 7200 + 60 + 1, 123_456_789), NINETY_MINS, Instant.ofEpochSecond(86400 + 5400, 0)},
+                {Instant.ofEpochSecond(86400 + 10800 + 60 + 1, 123_456_789), NINETY_MINS, Instant.ofEpochSecond(86400 + 10800, 0)},
+        };
+    }
+    @Test(groups={"tck"}, dataProvider="truncatedToValid")
+    public void test_truncatedTo_valid(Instant input, TemporalUnit unit, Instant expected) {
+        assertEquals(input.truncatedTo(unit), expected);
+    }
+
+    @DataProvider(name="truncatedToInvalid")
+    Object[][] data_truncatedToInvalid() {
+        return new Object[][] {
+                {Instant.ofEpochSecond(1, 123_456_789), NINETY_FIVE_MINS},
+                {Instant.ofEpochSecond(1, 123_456_789), WEEKS},
+                {Instant.ofEpochSecond(1, 123_456_789), MONTHS},
+                {Instant.ofEpochSecond(1, 123_456_789), YEARS},
+        };
+    }
+
+    @Test(groups={"tck"}, dataProvider="truncatedToInvalid", expectedExceptions=DateTimeException.class)
+    public void test_truncatedTo_invalid(Instant input, TemporalUnit unit) {
+        input.truncatedTo(unit);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    public void test_truncatedTo_null() {
+        TEST_12345_123456789.truncatedTo(null);
+    }
+
+    //-----------------------------------------------------------------------
+    // plus(TemporalAmount)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="plusTemporalAmount")
+    Object[][] data_plusTemporalAmount() {
+        return new Object[][] {
+                {DAYS, MockSimplePeriod.of(1, DAYS), 86401, 0},
+                {HOURS, MockSimplePeriod.of(2, HOURS), 7201, 0},
+                {MINUTES, MockSimplePeriod.of(4, MINUTES), 241, 0},
+                {SECONDS, MockSimplePeriod.of(5, SECONDS), 6, 0},
+                {NANOS, MockSimplePeriod.of(6, NANOS), 1, 6},
+                {DAYS, MockSimplePeriod.of(10, DAYS), 864001, 0},
+                {HOURS, MockSimplePeriod.of(11, HOURS), 39601, 0},
+                {MINUTES, MockSimplePeriod.of(12, MINUTES), 721, 0},
+                {SECONDS, MockSimplePeriod.of(13, SECONDS), 14, 0},
+                {NANOS, MockSimplePeriod.of(14, NANOS), 1, 14},
+                {SECONDS, Duration.ofSeconds(20, 40), 21, 40},
+                {NANOS, Duration.ofSeconds(30, 300), 31, 300},
+        };
+    }
+
+    @Test(dataProvider="plusTemporalAmount")
+    public void test_plusTemporalAmount(TemporalUnit unit, TemporalAmount amount, int seconds, int nanos) {
+        Instant inst = Instant.ofEpochMilli(1000);
+        Instant actual = inst.plus(amount);
+        Instant expected = Instant.ofEpochSecond(seconds, nanos);
+        assertEquals(actual, expected, "plus(TemporalAmount) failed");
+    }
+
+    @DataProvider(name="badTemporalAmount")
+    Object[][] data_badPlusTemporalAmount() {
+        return new Object[][] {
+                {MockSimplePeriod.of(2, YEARS)},
+                {MockSimplePeriod.of(2, MONTHS)},
+        };
+    }
+
+    @Test(dataProvider="badTemporalAmount",expectedExceptions=DateTimeException.class)
+    public void test_badPlusTemporalAmount(TemporalAmount amount) {
+        Instant inst = Instant.ofEpochMilli(1000);
+        inst.plus(amount);
+    }
+
+    //-----------------------------------------------------------------------
     @DataProvider(name="Plus")
     Object[][] provider_plus() {
         return new Object[][] {
@@ -1434,6 +1580,50 @@
     }
 
     //-----------------------------------------------------------------------
+    // atOffset()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_atOffset() {
+        for (int i = 0; i < (24 * 60 * 60); i++) {
+            Instant instant = Instant.ofEpochSecond(i);
+            OffsetDateTime test = instant.atOffset(ZoneOffset.ofHours(1));
+            assertEquals(test.getYear(), 1970);
+            assertEquals(test.getMonthValue(), 1);
+            assertEquals(test.getDayOfMonth(), 1 + (i >= 23 * 60 * 60 ? 1 : 0));
+            assertEquals(test.getHour(), ((i / (60 * 60)) + 1) % 24);
+            assertEquals(test.getMinute(), (i / 60) % 60);
+            assertEquals(test.getSecond(), i % 60);
+        }
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_atOffset_null() {
+        TEST_12345_123456789.atOffset(null);
+    }
+
+    //-----------------------------------------------------------------------
+    // atZone()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_atZone() {
+        for (int i = 0; i < (24 * 60 * 60); i++) {
+            Instant instant = Instant.ofEpochSecond(i);
+            ZonedDateTime test = instant.atZone(ZoneOffset.ofHours(1));
+            assertEquals(test.getYear(), 1970);
+            assertEquals(test.getMonthValue(), 1);
+            assertEquals(test.getDayOfMonth(), 1 + (i >= 23 * 60 * 60 ? 1 : 0));
+            assertEquals(test.getHour(), ((i / (60 * 60)) + 1) % 24);
+            assertEquals(test.getMinute(), (i / 60) % 60);
+            assertEquals(test.getSecond(), i % 60);
+        }
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_atZone_null() {
+        TEST_12345_123456789.atZone(null);
+    }
+
+    //-----------------------------------------------------------------------
     // toEpochMilli()
     //-----------------------------------------------------------------------
     @Test
diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/TCKLocalDate.java
index 721da56..48b6938 100644
--- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java
+++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java
@@ -80,11 +80,6 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.DayOfWeek;
@@ -93,24 +88,29 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Month;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Period;
+import java.time.Year;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.JulianFields;
-import java.time.temporal.OffsetDate;
 import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalAdjuster;
 import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
 import java.time.temporal.TemporalUnit;
-import java.time.temporal.Year;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
@@ -595,14 +595,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d");
         LocalDate test = LocalDate.parse("2010 12 3", f);
         assertEquals(test, LocalDate.of(2010, 12, 3));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d");
         LocalDate.parse((String) null, f);
     }
 
@@ -637,34 +637,27 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(TEST_2007_07_15.query(Queries.chrono()), ISOChrono.INSTANCE);
-        assertEquals(Queries.chrono().queryFrom(TEST_2007_07_15), ISOChrono.INSTANCE);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_2007_07_15, Queries.chronology(), IsoChronology.INSTANCE},
+                {TEST_2007_07_15, Queries.zoneId(), null},
+                {TEST_2007_07_15, Queries.precision(), ChronoUnit.DAYS},
+                {TEST_2007_07_15, Queries.zone(), null},
+                {TEST_2007_07_15, Queries.offset(), null},
+                {TEST_2007_07_15, Queries.localDate(), TEST_2007_07_15},
+                {TEST_2007_07_15, Queries.localTime(), null},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(TEST_2007_07_15.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(TEST_2007_07_15), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        assertEquals(TEST_2007_07_15.query(Queries.precision()), ChronoUnit.DAYS);
-        assertEquals(Queries.precision().queryFrom(TEST_2007_07_15), ChronoUnit.DAYS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(TEST_2007_07_15.query(Queries.offset()), null);
-        assertEquals(Queries.offset().queryFrom(TEST_2007_07_15), null);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(TEST_2007_07_15.query(Queries.zone()), null);
-        assertEquals(Queries.zone().queryFrom(TEST_2007_07_15), null);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -1629,6 +1622,117 @@
     }
 
     //-----------------------------------------------------------------------
+    // periodUntil(ChronoLocalDate)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="periodUntil")
+    Object[][] data_periodUntil() {
+        return new Object[][] {
+                {2010, 1, 1, 2010, 1, 1, 0, 0, 0},
+                {2010, 1, 1, 2010, 1, 2, 0, 0, 1},
+                {2010, 1, 1, 2010, 1, 31, 0, 0, 30},
+                {2010, 1, 1, 2010, 2, 1, 0, 1, 0},
+                {2010, 1, 1, 2010, 2, 28, 0, 1, 27},
+                {2010, 1, 1, 2010, 3, 1, 0, 2, 0},
+                {2010, 1, 1, 2010, 12, 31, 0, 11, 30},
+                {2010, 1, 1, 2011, 1, 1, 1, 0, 0},
+                {2010, 1, 1, 2011, 12, 31, 1, 11, 30},
+                {2010, 1, 1, 2012, 1, 1, 2, 0, 0},
+
+                {2010, 1, 10, 2010, 1, 1, 0, 0, -9},
+                {2010, 1, 10, 2010, 1, 2, 0, 0, -8},
+                {2010, 1, 10, 2010, 1, 9, 0, 0, -1},
+                {2010, 1, 10, 2010, 1, 10, 0, 0, 0},
+                {2010, 1, 10, 2010, 1, 11, 0, 0, 1},
+                {2010, 1, 10, 2010, 1, 31, 0, 0, 21},
+                {2010, 1, 10, 2010, 2, 1, 0, 0, 22},
+                {2010, 1, 10, 2010, 2, 9, 0, 0, 30},
+                {2010, 1, 10, 2010, 2, 10, 0, 1, 0},
+                {2010, 1, 10, 2010, 2, 28, 0, 1, 18},
+                {2010, 1, 10, 2010, 3, 1, 0, 1, 19},
+                {2010, 1, 10, 2010, 3, 9, 0, 1, 27},
+                {2010, 1, 10, 2010, 3, 10, 0, 2, 0},
+                {2010, 1, 10, 2010, 12, 31, 0, 11, 21},
+                {2010, 1, 10, 2011, 1, 1, 0, 11, 22},
+                {2010, 1, 10, 2011, 1, 9, 0, 11, 30},
+                {2010, 1, 10, 2011, 1, 10, 1, 0, 0},
+
+                {2010, 3, 30, 2011, 5, 1, 1, 1, 1},
+                {2010, 4, 30, 2011, 5, 1, 1, 0, 1},
+
+                {2010, 2, 28, 2012, 2, 27, 1, 11, 30},
+                {2010, 2, 28, 2012, 2, 28, 2, 0, 0},
+                {2010, 2, 28, 2012, 2, 29, 2, 0, 1},
+
+                {2012, 2, 28, 2014, 2, 27, 1, 11, 30},
+                {2012, 2, 28, 2014, 2, 28, 2, 0, 0},
+                {2012, 2, 28, 2014, 3, 1, 2, 0, 1},
+
+                {2012, 2, 29, 2014, 2, 28, 1, 11, 30},
+                {2012, 2, 29, 2014, 3, 1, 2, 0, 1},
+                {2012, 2, 29, 2014, 3, 2, 2, 0, 2},
+
+                {2012, 2, 29, 2016, 2, 28, 3, 11, 30},
+                {2012, 2, 29, 2016, 2, 29, 4, 0, 0},
+                {2012, 2, 29, 2016, 3, 1, 4, 0, 1},
+
+                {2010, 1, 1, 2009, 12, 31, 0, 0, -1},
+                {2010, 1, 1, 2009, 12, 30, 0, 0, -2},
+                {2010, 1, 1, 2009, 12, 2, 0, 0, -30},
+                {2010, 1, 1, 2009, 12, 1, 0, -1, 0},
+                {2010, 1, 1, 2009, 11, 30, 0, -1, -1},
+                {2010, 1, 1, 2009, 11, 2, 0, -1, -29},
+                {2010, 1, 1, 2009, 11, 1, 0, -2, 0},
+                {2010, 1, 1, 2009, 1, 2, 0, -11, -30},
+                {2010, 1, 1, 2009, 1, 1, -1, 0, 0},
+
+                {2010, 1, 15, 2010, 1, 15, 0, 0, 0},
+                {2010, 1, 15, 2010, 1, 14, 0, 0, -1},
+                {2010, 1, 15, 2010, 1, 1, 0, 0, -14},
+                {2010, 1, 15, 2009, 12, 31, 0, 0, -15},
+                {2010, 1, 15, 2009, 12, 16, 0, 0, -30},
+                {2010, 1, 15, 2009, 12, 15, 0, -1, 0},
+                {2010, 1, 15, 2009, 12, 14, 0, -1, -1},
+
+                {2010, 2, 28, 2009, 3, 1, 0, -11, -27},
+                {2010, 2, 28, 2009, 2, 28, -1, 0, 0},
+                {2010, 2, 28, 2009, 2, 27, -1, 0, -1},
+
+                {2010, 2, 28, 2008, 2, 29, -1, -11, -28},
+                {2010, 2, 28, 2008, 2, 28, -2, 0, 0},
+                {2010, 2, 28, 2008, 2, 27, -2, 0, -1},
+
+                {2012, 2, 29, 2009, 3, 1, -2, -11, -28},
+                {2012, 2, 29, 2009, 2, 28, -3, 0, -1},
+                {2012, 2, 29, 2009, 2, 27, -3, 0, -2},
+
+                {2012, 2, 29, 2008, 3, 1, -3, -11, -28},
+                {2012, 2, 29, 2008, 2, 29, -4, 0, 0},
+                {2012, 2, 29, 2008, 2, 28, -4, 0, -1},
+        };
+    }
+
+    @Test(dataProvider="periodUntil")
+    public void test_periodUntil_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
+        LocalDate start = LocalDate.of(y1, m1, d1);
+        LocalDate end = LocalDate.of(y2, m2, d2);
+        Period test = start.periodUntil(end);
+        assertEquals(test.getYears(), ye);
+        assertEquals(test.getMonths(), me);
+        assertEquals(test.getDays(), de);
+    }
+
+    @Test
+    public void test_periodUntil_LocalDate_max() {
+        int years = Math.toIntExact((long) Year.MAX_VALUE - (long) Year.MIN_VALUE);
+        assertEquals(LocalDate.MIN.periodUntil(LocalDate.MAX), Period.of(years, 11, 30));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_periodUntil_LocalDate_null() {
+        TEST_2007_07_15.periodUntil(null);
+    }
+
+    //-----------------------------------------------------------------------
     // atTime()
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
@@ -1771,39 +1875,53 @@
     }
 
     //-----------------------------------------------------------------------
-    // atOffset()
-    //-----------------------------------------------------------------------
     @Test(groups={"tck"})
-    public void test_atOffset() {
+    public void test_atTime_OffsetTime() {
         LocalDate t = LocalDate.of(2008, 6, 30);
-        assertEquals(t.atOffset(OFFSET_PTWO), OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PTWO));
+        assertEquals(t.atTime(OffsetTime.of(11, 30, 0, 0, OFFSET_PONE)), OffsetDateTime.of(2008, 6, 30, 11, 30, 0, 0, OFFSET_PONE));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_atOffset_nullZoneOffset() {
+    public void test_atTime_OffsetTime_null() {
         LocalDate t = LocalDate.of(2008, 6, 30);
-        t.atOffset((ZoneOffset) null);
+        t.atTime((OffsetTime) null);
     }
 
     //-----------------------------------------------------------------------
     // atStartOfDay()
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_atStartOfDay() {
-        LocalDate t = LocalDate.of(2008, 6, 30);
-        assertEquals(t.atStartOfDay(ZONE_PARIS),
-                ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 0, 0), ZONE_PARIS));
+    @DataProvider(name="atStartOfDay")
+    Object[][] data_atStartOfDay() {
+        return new Object[][] {
+                {LocalDate.of(2008, 6, 30), LocalDateTime.of(2008, 6, 30, 0, 0)},
+                {LocalDate.of(-12, 6, 30), LocalDateTime.of(-12, 6, 30, 0, 0)},
+        };
     }
 
-    @Test(groups={"tck"})
-    public void test_atStartOfDay_dstGap() {
-        LocalDate t = LocalDate.of(2007, 4, 1);
-        assertEquals(t.atStartOfDay(ZONE_GAZA),
-                ZonedDateTime.of(LocalDateTime.of(2007, 4, 1, 1, 0), ZONE_GAZA));
+    @Test(dataProvider="atStartOfDay")
+    public void test_atStartOfDay(LocalDate test, LocalDateTime expected) {
+        assertEquals(test.atStartOfDay(), expected);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_atStartOfDay_nullTimeZone() {
+    //-----------------------------------------------------------------------
+    // atStartOfDay(ZoneId)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="atStartOfDayZoneId")
+    Object[][] data_atStartOfDayZoneId() {
+        return new Object[][] {
+                {LocalDate.of(2008, 6, 30), ZONE_PARIS, ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 0, 0), ZONE_PARIS)},
+                {LocalDate.of(2008, 6, 30), OFFSET_PONE, ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 0, 0), OFFSET_PONE)},
+                {LocalDate.of(2007, 4, 1), ZONE_GAZA, ZonedDateTime.of(LocalDateTime.of(2007, 4, 1, 1, 0), ZONE_GAZA)},
+        };
+    }
+
+    @Test(dataProvider="atStartOfDayZoneId")
+    public void test_atStartOfDay_ZoneId(LocalDate test, ZoneId zone, ZonedDateTime expected) {
+        assertEquals(test.atStartOfDay(zone), expected);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_atStartOfDay_ZoneId_null() {
         LocalDate t = LocalDate.of(2008, 6, 30);
         t.atStartOfDay((ZoneId) null);
     }
@@ -2005,7 +2123,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d");
         String t = LocalDate.of(2010, 12, 3).toString(f);
         assertEquals(t, "2010 12 3");
     }
diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java
index 1fa08f3..9b95fcd 100644
--- a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java
@@ -88,8 +88,10 @@
 import static java.time.temporal.ChronoField.YEAR;
 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
 import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.MONTHS;
 import static java.time.temporal.ChronoUnit.NANOS;
 import static java.time.temporal.ChronoUnit.SECONDS;
+import static java.time.temporal.ChronoUnit.YEARS;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertSame;
@@ -97,12 +99,6 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.DayOfWeek;
@@ -111,33 +107,33 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Month;
-import java.time.Period;
+import java.time.OffsetDateTime;
+import java.time.Year;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.JulianFields;
-import java.time.temporal.OffsetDateTime;
 import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
 import java.time.temporal.TemporalUnit;
-import java.time.temporal.Year;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import test.java.time.MockSimplePeriod;
 
 /**
  * Test LocalDateTime.
@@ -280,12 +276,12 @@
     public void now() {
         LocalDateTime expected = LocalDateTime.now(Clock.systemDefaultZone());
         LocalDateTime test = LocalDateTime.now();
-        long diff = Math.abs(test.getTime().toNanoOfDay() - expected.getTime().toNanoOfDay());
+        long diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
         if (diff >= 100000000) {
             // may be date change
             expected = LocalDateTime.now(Clock.systemDefaultZone());
             test = LocalDateTime.now();
-            diff = Math.abs(test.getTime().toNanoOfDay() - expected.getTime().toNanoOfDay());
+            diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
         }
         assertTrue(diff < 100000000);  // less than 0.1 secs
     }
@@ -364,7 +360,7 @@
             assertEquals(test.getMonth(), Month.DECEMBER);
             assertEquals(test.getDayOfMonth(), 31);
             expected = expected.minusSeconds(1);
-            assertEquals(test.getTime(), expected);
+            assertEquals(test.toLocalTime(), expected);
         }
     }
 
@@ -915,14 +911,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
         LocalDateTime test = LocalDateTime.parse("2010 12 3 11 30 45", f);
         assertEquals(test, LocalDateTime.of(2010, 12, 3, 11, 30, 45));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
         LocalDateTime.parse((String) null, f);
     }
 
@@ -971,34 +967,27 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(TEST_2007_07_15_12_30_40_987654321.query(Queries.chrono()), ISOChrono.INSTANCE);
-        assertEquals(Queries.chrono().queryFrom(TEST_2007_07_15_12_30_40_987654321), ISOChrono.INSTANCE);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_2007_07_15_12_30_40_987654321, Queries.chronology(), IsoChronology.INSTANCE},
+                {TEST_2007_07_15_12_30_40_987654321, Queries.zoneId(), null},
+                {TEST_2007_07_15_12_30_40_987654321, Queries.precision(), ChronoUnit.NANOS},
+                {TEST_2007_07_15_12_30_40_987654321, Queries.zone(), null},
+                {TEST_2007_07_15_12_30_40_987654321, Queries.offset(), null},
+                {TEST_2007_07_15_12_30_40_987654321, Queries.localDate(), LocalDate.of(2007, 7, 15)},
+                {TEST_2007_07_15_12_30_40_987654321, Queries.localTime(), LocalTime.of(12, 30, 40, 987654321)},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(TEST_2007_07_15_12_30_40_987654321.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(TEST_2007_07_15_12_30_40_987654321), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        assertEquals(TEST_2007_07_15_12_30_40_987654321.query(Queries.precision()), NANOS);
-        assertEquals(Queries.precision().queryFrom(TEST_2007_07_15_12_30_40_987654321), NANOS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(TEST_2007_07_15_12_30_40_987654321.query(Queries.offset()), null);
-        assertEquals(Queries.offset().queryFrom(TEST_2007_07_15_12_30_40_987654321), null);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(TEST_2007_07_15_12_30_40_987654321.query(Queries.zone()), null);
-        assertEquals(Queries.zone().queryFrom(TEST_2007_07_15_12_30_40_987654321), null);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -1065,7 +1054,7 @@
 
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_get_times(int h, int m, int s, int ns) {
-        LocalDateTime a = LocalDateTime.of(TEST_2007_07_15_12_30_40_987654321.getDate(), LocalTime.of(h, m, s, ns));
+        LocalDateTime a = LocalDateTime.of(TEST_2007_07_15_12_30_40_987654321.toLocalDate(), LocalTime.of(h, m, s, ns));
         assertEquals(a.getHour(), h);
         assertEquals(a.getMinute(), m);
         assertEquals(a.getSecond(), s);
@@ -1082,7 +1071,7 @@
             int length = month.length(false);
             for (int i = 1; i <= length; i++) {
                 LocalDateTime d = LocalDateTime.of(LocalDate.of(2007, month, i),
-                        TEST_2007_07_15_12_30_40_987654321.getTime());
+                        TEST_2007_07_15_12_30_40_987654321.toLocalTime());
                 assertSame(d.getDayOfWeek(), dow);
                 dow = dow.plus(1);
             }
@@ -1297,54 +1286,39 @@
     }
 
     //-----------------------------------------------------------------------
-    // plus(adjuster)
+    // plus(TemporalAmount)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_plus_adjuster() {
-        Period p = Period.ofTime(0, 0, 62, 3);
-        LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(p);
-        assertEquals(t, LocalDateTime.of(2007, 7, 15, 12, 31, 42, 987654324));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_plus_adjuster_null() {
-        TEST_2007_07_15_12_30_40_987654321.plus((TemporalAdder) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // plus(Period)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_plus_Period_positiveMonths() {
-        MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
+    @Test
+    public void test_plus_TemporalAmount_positiveMonths() {
+        MockSimplePeriod period = MockSimplePeriod.of(7, MONTHS);
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(period);
         assertEquals(t, LocalDateTime.of(2008, 2, 15, 12, 30, 40, 987654321));
     }
 
-    @Test(groups={"tck"})
-    public void test_plus_Period_negativeDays() {
-        MockSimplePeriod period = MockSimplePeriod.of(-25, ChronoUnit.DAYS);
+    @Test
+    public void test_plus_TemporalAmount_negativeDays() {
+        MockSimplePeriod period = MockSimplePeriod.of(-25, DAYS);
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(period);
         assertEquals(t, LocalDateTime.of(2007, 6, 20, 12, 30, 40, 987654321));
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_plus_Period_null() {
-        TEST_2007_07_15_12_30_40_987654321.plus((MockSimplePeriod) null);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_plus_Period_invalidTooLarge() {
-        MockSimplePeriod period = MockSimplePeriod.of(1, ChronoUnit.YEARS);
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_plus_TemporalAmount_invalidTooLarge() {
+        MockSimplePeriod period = MockSimplePeriod.of(1, YEARS);
         LocalDateTime.of(Year.MAX_VALUE, 1, 1, 0, 0).plus(period);
     }
 
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_plus_Period_invalidTooSmall() {
-        MockSimplePeriod period = MockSimplePeriod.of(-1, ChronoUnit.YEARS);
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_plus_TemporalAmount_invalidTooSmall() {
+        MockSimplePeriod period = MockSimplePeriod.of(-1, YEARS);
         LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0).plus(period);
     }
 
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_plus_TemporalAmount_null() {
+        TEST_2007_07_15_12_30_40_987654321.plus((TemporalAmount) null);
+    }
+
     //-----------------------------------------------------------------------
     // plus(long,TemporalUnit)
     //-----------------------------------------------------------------------
@@ -1697,7 +1671,7 @@
     @Test(groups={"tck"})
     public void test_plusHours_one() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = t.getDate();
+        LocalDate d = t.toLocalDate();
 
         for (int i = 0; i < 50; i++) {
             t = t.plusHours(1);
@@ -1706,7 +1680,7 @@
                 d = d.plusDays(1);
             }
 
-            assertEquals(t.getDate(), d);
+            assertEquals(t.toLocalDate(), d);
             assertEquals(t.getHour(), (i + 1) % 24);
         }
     }
@@ -1714,7 +1688,7 @@
     @Test(groups={"tck"})
     public void test_plusHours_fromZero() {
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = base.getDate().minusDays(3);
+        LocalDate d = base.toLocalDate().minusDays(3);
         LocalTime t = LocalTime.of(21, 0);
 
         for (int i = -50; i < 50; i++) {
@@ -1725,15 +1699,15 @@
                 d = d.plusDays(1);
             }
 
-            assertEquals(dt.getDate(), d);
-            assertEquals(dt.getTime(), t);
+            assertEquals(dt.toLocalDate(), d);
+            assertEquals(dt.toLocalTime(), t);
         }
     }
 
     @Test(groups={"tck"})
     public void test_plusHours_fromOne() {
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(1, 0));
-        LocalDate d = base.getDate().minusDays(3);
+        LocalDate d = base.toLocalDate().minusDays(3);
         LocalTime t = LocalTime.of(22, 0);
 
         for (int i = -50; i < 50; i++) {
@@ -1745,8 +1719,8 @@
                 d = d.plusDays(1);
             }
 
-            assertEquals(dt.getDate(), d);
-            assertEquals(dt.getTime(), t);
+            assertEquals(dt.toLocalDate(), d);
+            assertEquals(dt.toLocalTime(), t);
         }
     }
 
@@ -1756,7 +1730,7 @@
     @Test(groups={"tck"})
     public void test_plusMinutes_one() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = t.getDate();
+        LocalDate d = t.toLocalDate();
 
         int hour = 0;
         int min = 0;
@@ -1769,7 +1743,7 @@
                 min = 0;
             }
 
-            assertEquals(t.getDate(), d);
+            assertEquals(t.toLocalDate(), d);
             assertEquals(t.getHour(), hour);
             assertEquals(t.getMinute(), min);
         }
@@ -1778,7 +1752,7 @@
     @Test(groups={"tck"})
     public void test_plusMinutes_fromZero() {
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = base.getDate().minusDays(1);
+        LocalDate d = base.toLocalDate().minusDays(1);
         LocalTime t = LocalTime.of(22, 49);
 
         for (int i = -70; i < 70; i++) {
@@ -1789,15 +1763,15 @@
                 d = d.plusDays(1);
             }
 
-            assertEquals(dt.getDate(), d, String.valueOf(i));
-            assertEquals(dt.getTime(), t, String.valueOf(i));
+            assertEquals(dt.toLocalDate(), d, String.valueOf(i));
+            assertEquals(dt.toLocalTime(), t, String.valueOf(i));
         }
     }
 
     @Test(groups={"tck"})
     public void test_plusMinutes_noChange_oneDay() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusMinutes(24 * 60);
-        assertEquals(t.getDate(), TEST_2007_07_15_12_30_40_987654321.getDate().plusDays(1));
+        assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().plusDays(1));
     }
 
     //-----------------------------------------------------------------------
@@ -1806,7 +1780,7 @@
     @Test(groups={"tck"})
     public void test_plusSeconds_one() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = t.getDate();
+        LocalDate d = t.toLocalDate();
 
         int hour = 0;
         int min = 0;
@@ -1824,7 +1798,7 @@
                 min = 0;
             }
 
-            assertEquals(t.getDate(), d);
+            assertEquals(t.toLocalDate(), d);
             assertEquals(t.getHour(), hour);
             assertEquals(t.getMinute(), min);
             assertEquals(t.getSecond(), sec);
@@ -1837,7 +1811,7 @@
             int delta = 30;
 
             int i = -3660;
-            LocalDate date = TEST_2007_07_15_12_30_40_987654321.getDate().minusDays(1);
+            LocalDate date = TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1);
             int hour = 22;
             int min = 59;
             int sec = 0;
@@ -1883,7 +1857,7 @@
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
         LocalDateTime t = base.plusSeconds(seconds);
 
-        assertEquals(date, t.getDate());
+        assertEquals(date, t.toLocalDate());
         assertEquals(hour, t.getHour());
         assertEquals(min, t.getMinute());
         assertEquals(sec, t.getSecond());
@@ -1892,7 +1866,7 @@
     @Test(groups={"tck"})
     public void test_plusSeconds_noChange_oneDay() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusSeconds(24 * 60 * 60);
-        assertEquals(t.getDate(), TEST_2007_07_15_12_30_40_987654321.getDate().plusDays(1));
+        assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().plusDays(1));
     }
 
     //-----------------------------------------------------------------------
@@ -1901,7 +1875,7 @@
     @Test(groups={"tck"})
     public void test_plusNanos_halfABillion() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = t.getDate();
+        LocalDate d = t.toLocalDate();
 
         int hour = 0;
         int min = 0;
@@ -1924,7 +1898,7 @@
                 min = 0;
             }
 
-            assertEquals(t.getDate(), d, String.valueOf(i));
+            assertEquals(t.toLocalDate(), d, String.valueOf(i));
             assertEquals(t.getHour(), hour);
             assertEquals(t.getMinute(), min);
             assertEquals(t.getSecond(), sec);
@@ -1938,7 +1912,7 @@
             long delta = 7500000000L;
 
             long i = -3660 * 1000000000L;
-            LocalDate date = TEST_2007_07_15_12_30_40_987654321.getDate().minusDays(1);
+            LocalDate date = TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1);
             int hour = 22;
             int min = 59;
             int sec = 0;
@@ -1987,7 +1961,7 @@
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
         LocalDateTime t = base.plusNanos(nanoseconds);
 
-        assertEquals(date, t.getDate());
+        assertEquals(date, t.toLocalDate());
         assertEquals(hour, t.getHour());
         assertEquals(min, t.getMinute());
         assertEquals(sec, t.getSecond());
@@ -1997,58 +1971,43 @@
     @Test(groups={"tck"})
     public void test_plusNanos_noChange_oneDay() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusNanos(24 * 60 * 60 * 1000000000L);
-        assertEquals(t.getDate(), TEST_2007_07_15_12_30_40_987654321.getDate().plusDays(1));
+        assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().plusDays(1));
     }
 
     //-----------------------------------------------------------------------
-    // minus(adjuster)
+    // minus(TemporalAmount)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_minus_adjuster() {
-        Period p = Period.ofTime(0, 0, 62, 3);
-        LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(p);
-        assertEquals(t, LocalDateTime.of(2007, 7, 15, 12, 29, 38, 987654318));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_minus_adjuster_null() {
-        TEST_2007_07_15_12_30_40_987654321.minus((TemporalSubtractor) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // minus(Period)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_minus_Period_positiveMonths() {
-        MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
+    @Test
+    public void test_minus_TemporalAmount_positiveMonths() {
+        MockSimplePeriod period = MockSimplePeriod.of(7, MONTHS);
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(period);
         assertEquals(t, LocalDateTime.of(2006, 12, 15, 12, 30, 40, 987654321));
     }
 
-    @Test(groups={"tck"})
-    public void test_minus_Period_negativeDays() {
-        MockSimplePeriod period = MockSimplePeriod.of(-25, ChronoUnit.DAYS);
+    @Test
+    public void test_minus_TemporalAmount_negativeDays() {
+        MockSimplePeriod period = MockSimplePeriod.of(-25, DAYS);
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(period);
         assertEquals(t, LocalDateTime.of(2007, 8, 9, 12, 30, 40, 987654321));
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_minus_Period_null() {
-        TEST_2007_07_15_12_30_40_987654321.minus((MockSimplePeriod) null);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_minus_Period_invalidTooLarge() {
-        MockSimplePeriod period = MockSimplePeriod.of(-1, ChronoUnit.YEARS);
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_minus_TemporalAmount_invalidTooLarge() {
+        MockSimplePeriod period = MockSimplePeriod.of(-1, YEARS);
         LocalDateTime.of(Year.MAX_VALUE, 1, 1, 0, 0).minus(period);
     }
 
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_minus_Period_invalidTooSmall() {
-        MockSimplePeriod period = MockSimplePeriod.of(1, ChronoUnit.YEARS);
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_minus_TemporalAmount_invalidTooSmall() {
+        MockSimplePeriod period = MockSimplePeriod.of(1, YEARS);
         LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0).minus(period);
     }
 
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_minus_TemporalAmount_null() {
+        TEST_2007_07_15_12_30_40_987654321.minus((TemporalAmount) null);
+    }
+
     //-----------------------------------------------------------------------
     // minus(long,TemporalUnit)
     //-----------------------------------------------------------------------
@@ -2401,7 +2360,7 @@
     @Test(groups={"tck"})
     public void test_minusHours_one() {
         LocalDateTime t =TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = t.getDate();
+        LocalDate d = t.toLocalDate();
 
         for (int i = 0; i < 50; i++) {
             t = t.minusHours(1);
@@ -2410,7 +2369,7 @@
                 d = d.minusDays(1);
             }
 
-            assertEquals(t.getDate(), d);
+            assertEquals(t.toLocalDate(), d);
             assertEquals(t.getHour(), (((-i + 23) % 24) + 24) % 24);
         }
     }
@@ -2418,7 +2377,7 @@
     @Test(groups={"tck"})
     public void test_minusHours_fromZero() {
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = base.getDate().plusDays(2);
+        LocalDate d = base.toLocalDate().plusDays(2);
         LocalTime t = LocalTime.of(3, 0);
 
         for (int i = -50; i < 50; i++) {
@@ -2429,15 +2388,15 @@
                 d = d.minusDays(1);
             }
 
-            assertEquals(dt.getDate(), d, String.valueOf(i));
-            assertEquals(dt.getTime(), t);
+            assertEquals(dt.toLocalDate(), d, String.valueOf(i));
+            assertEquals(dt.toLocalTime(), t);
         }
     }
 
     @Test(groups={"tck"})
     public void test_minusHours_fromOne() {
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(1, 0));
-        LocalDate d = base.getDate().plusDays(2);
+        LocalDate d = base.toLocalDate().plusDays(2);
         LocalTime t = LocalTime.of(4, 0);
 
         for (int i = -50; i < 50; i++) {
@@ -2449,8 +2408,8 @@
                 d = d.minusDays(1);
             }
 
-            assertEquals(dt.getDate(), d, String.valueOf(i));
-            assertEquals(dt.getTime(), t);
+            assertEquals(dt.toLocalDate(), d, String.valueOf(i));
+            assertEquals(dt.toLocalTime(), t);
         }
     }
 
@@ -2460,7 +2419,7 @@
     @Test(groups={"tck"})
     public void test_minusMinutes_one() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = t.getDate().minusDays(1);
+        LocalDate d = t.toLocalDate().minusDays(1);
 
         int hour = 0;
         int min = 0;
@@ -2476,7 +2435,7 @@
                     hour = 23;
                 }
             }
-            assertEquals(t.getDate(), d);
+            assertEquals(t.toLocalDate(), d);
             assertEquals(t.getHour(), hour);
             assertEquals(t.getMinute(), min);
         }
@@ -2485,7 +2444,7 @@
     @Test(groups={"tck"})
     public void test_minusMinutes_fromZero() {
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = base.getDate().minusDays(1);
+        LocalDate d = base.toLocalDate().minusDays(1);
         LocalTime t = LocalTime.of(22, 49);
 
         for (int i = 70; i > -70; i--) {
@@ -2496,15 +2455,15 @@
                 d = d.plusDays(1);
             }
 
-            assertEquals(dt.getDate(), d);
-            assertEquals(dt.getTime(), t);
+            assertEquals(dt.toLocalDate(), d);
+            assertEquals(dt.toLocalTime(), t);
         }
     }
 
     @Test(groups={"tck"})
     public void test_minusMinutes_noChange_oneDay() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusMinutes(24 * 60);
-        assertEquals(t.getDate(), TEST_2007_07_15_12_30_40_987654321.getDate().minusDays(1));
+        assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1));
     }
 
     //-----------------------------------------------------------------------
@@ -2513,7 +2472,7 @@
     @Test(groups={"tck"})
     public void test_minusSeconds_one() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = t.getDate().minusDays(1);
+        LocalDate d = t.toLocalDate().minusDays(1);
 
         int hour = 0;
         int min = 0;
@@ -2536,7 +2495,7 @@
                 }
             }
 
-            assertEquals(t.getDate(), d);
+            assertEquals(t.toLocalDate(), d);
             assertEquals(t.getHour(), hour);
             assertEquals(t.getMinute(), min);
             assertEquals(t.getSecond(), sec);
@@ -2549,7 +2508,7 @@
             int delta = 30;
 
             int i = 3660;
-            LocalDate date = TEST_2007_07_15_12_30_40_987654321.getDate().minusDays(1);
+            LocalDate date = TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1);
             int hour = 22;
             int min = 59;
             int sec = 0;
@@ -2595,7 +2554,7 @@
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
         LocalDateTime t = base.minusSeconds(seconds);
 
-        assertEquals(date, t.getDate());
+        assertEquals(date, t.toLocalDate());
         assertEquals(hour, t.getHour());
         assertEquals(min, t.getMinute());
         assertEquals(sec, t.getSecond());
@@ -2607,7 +2566,7 @@
     @Test(groups={"tck"})
     public void test_minusNanos_halfABillion() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
-        LocalDate d = t.getDate().minusDays(1);
+        LocalDate d = t.toLocalDate().minusDays(1);
 
         int hour = 0;
         int min = 0;
@@ -2637,7 +2596,7 @@
                 }
             }
 
-            assertEquals(t.getDate(), d);
+            assertEquals(t.toLocalDate(), d);
             assertEquals(t.getHour(), hour);
             assertEquals(t.getMinute(), min);
             assertEquals(t.getSecond(), sec);
@@ -2651,7 +2610,7 @@
             long delta = 7500000000L;
 
             long i = 3660 * 1000000000L;
-            LocalDate date = TEST_2007_07_15_12_30_40_987654321.getDate().minusDays(1);
+            LocalDate date = TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1);
             int hour = 22;
             int min = 59;
             int sec = 0;
@@ -2700,7 +2659,7 @@
         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
         LocalDateTime t = base.minusNanos(nanoseconds);
 
-        assertEquals(date, t.getDate());
+        assertEquals(date, t.toLocalDate());
         assertEquals(hour, t.getHour());
         assertEquals(min, t.getMinute());
         assertEquals(sec, t.getSecond());
@@ -3032,7 +2991,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
         String t = LocalDateTime.of(2010, 12, 3, 11, 30, 45).toString(f);
         assertEquals(t, "2010 12 3 11 30 45");
     }
diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java
index 1cc5486..9b4d65f 100644
--- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java
@@ -92,42 +92,39 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
-import java.io.IOException;
+import java.time.Clock;
+import java.time.DateTimeException;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetTime;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.JulianFields;
+import java.time.temporal.Queries;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.List;
 
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.Period;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
-import java.time.format.DateTimeParseException;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.JulianFields;
-import java.time.temporal.OffsetTime;
-import java.time.temporal.Queries;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
-import java.time.temporal.TemporalAdjuster;
-import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.TemporalUnit;
-
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import test.java.time.MockSimplePeriod;
 
 /**
  * Test LocalTime.
@@ -505,35 +502,6 @@
     }
 
     //-----------------------------------------------------------------------
-    // ofSecondOfDay(long, int)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_ofSecondOfDay_long_int() {
-        LocalTime localTime = LocalTime.ofSecondOfDay(2 * 60 * 60 + 17 * 60 + 23, 987);
-        check(localTime, 2, 17, 23, 987);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_ofSecondOfDay_long_int_tooLowSecs() {
-        LocalTime.ofSecondOfDay(-1, 0);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_ofSecondOfDay_long_int_tooHighSecs() {
-        LocalTime.ofSecondOfDay(24 * 60 * 60, 0);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_ofSecondOfDay_long_int_tooLowNanos() {
-        LocalTime.ofSecondOfDay(0, -1);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_ofSecondOfDay_long_int_tooHighNanos() {
-        LocalTime.ofSecondOfDay(0, 1000000000);
-    }
-
-    //-----------------------------------------------------------------------
     // ofNanoOfDay(long)
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
@@ -631,14 +599,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
         LocalTime test = LocalTime.parse("14 30 40", f);
         assertEquals(test, LocalTime.of(14, 30, 40));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
         LocalTime.parse((String) null, f);
     }
 
@@ -685,34 +653,27 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(TEST_12_30_40_987654321.query(Queries.chrono()), null);
-        assertEquals(Queries.chrono().queryFrom(TEST_12_30_40_987654321), null);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_12_30_40_987654321, Queries.chronology(), null},
+                {TEST_12_30_40_987654321, Queries.zoneId(), null},
+                {TEST_12_30_40_987654321, Queries.precision(), ChronoUnit.NANOS},
+                {TEST_12_30_40_987654321, Queries.zone(), null},
+                {TEST_12_30_40_987654321, Queries.offset(), null},
+                {TEST_12_30_40_987654321, Queries.localDate(), null},
+                {TEST_12_30_40_987654321, Queries.localTime(), TEST_12_30_40_987654321},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(TEST_12_30_40_987654321.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(TEST_12_30_40_987654321), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        assertEquals(TEST_12_30_40_987654321.query(Queries.precision()), NANOS);
-        assertEquals(Queries.precision().queryFrom(TEST_12_30_40_987654321), NANOS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(TEST_12_30_40_987654321.query(Queries.offset()), null);
-        assertEquals(Queries.offset().queryFrom(TEST_12_30_40_987654321), null);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(TEST_12_30_40_987654321.query(Queries.zone()), null);
-        assertEquals(Queries.zone().queryFrom(TEST_12_30_40_987654321), null);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -942,6 +903,60 @@
     //-----------------------------------------------------------------------
     // truncated(TemporalUnit)
     //-----------------------------------------------------------------------
+    TemporalUnit NINETY_MINS = new TemporalUnit() {
+        @Override
+        public String getName() {
+            return "NinetyMins";
+        }
+        @Override
+        public Duration getDuration() {
+            return Duration.ofMinutes(90);
+        }
+        @Override
+        public boolean isDurationEstimated() {
+            return false;
+        }
+        @Override
+        public boolean isSupportedBy(Temporal temporal) {
+            return false;
+        }
+        @Override
+        public <R extends Temporal> R addTo(R temporal, long amount) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public long between(Temporal temporal1, Temporal temporal2) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
+    TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() {
+        @Override
+        public String getName() {
+            return "NinetyFiveMins";
+        }
+        @Override
+        public Duration getDuration() {
+            return Duration.ofMinutes(95);
+        }
+        @Override
+        public boolean isDurationEstimated() {
+            return false;
+        }
+        @Override
+        public boolean isSupportedBy(Temporal temporal) {
+            return false;
+        }
+        @Override
+        public <R extends Temporal> R addTo(R temporal, long amount) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public long between(Temporal temporal1, Temporal temporal2) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
     @DataProvider(name="truncatedToValid")
     Object[][] data_truncatedToValid() {
         return new Object[][] {
@@ -952,6 +967,10 @@
             {LocalTime.of(1, 2, 3, 123_456_789), MINUTES, LocalTime.of(1, 2)},
             {LocalTime.of(1, 2, 3, 123_456_789), HOURS, LocalTime.of(1, 0)},
             {LocalTime.of(1, 2, 3, 123_456_789), DAYS, LocalTime.MIDNIGHT},
+
+            {LocalTime.of(1, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(0, 0)},
+            {LocalTime.of(2, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(1, 30)},
+            {LocalTime.of(3, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(3, 0)},
         };
     }
 
@@ -963,6 +982,7 @@
     @DataProvider(name="truncatedToInvalid")
     Object[][] data_truncatedToInvalid() {
         return new Object[][] {
+            {LocalTime.of(1, 2, 3, 123_456_789), NINETY_FIVE_MINS},
             {LocalTime.of(1, 2, 3, 123_456_789), WEEKS},
             {LocalTime.of(1, 2, 3, 123_456_789), MONTHS},
             {LocalTime.of(1, 2, 3, 123_456_789), YEARS},
@@ -980,45 +1000,45 @@
     }
 
     //-----------------------------------------------------------------------
-    // plus(PlusAdjuster)
+    // plus(TemporalAmount)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_plus_Adjuster_positiveHours() {
-        TemporalAdder period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
+    @Test
+    public void test_plus_TemporalAmount_positiveHours() {
+        TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
         LocalTime t = TEST_12_30_40_987654321.plus(period);
         assertEquals(t, LocalTime.of(19, 30, 40, 987654321));
     }
 
-    @Test(groups={"tck"})
-    public void test_plus_Adjuster_negativeMinutes() {
-        TemporalAdder period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
+    @Test
+    public void test_plus_TemporalAmount_negativeMinutes() {
+        TemporalAmount period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
         LocalTime t = TEST_12_30_40_987654321.plus(period);
         assertEquals(t, LocalTime.of(12, 5, 40, 987654321));
     }
 
-    @Test(groups={"tck"})
-    public void test_plus_Adjuster_zero() {
-        TemporalAdder period = Period.ZERO;
+    @Test
+    public void test_plus_TemporalAmount_zero() {
+        TemporalAmount period = Period.ZERO;
         LocalTime t = TEST_12_30_40_987654321.plus(period);
         assertEquals(t, TEST_12_30_40_987654321);
     }
 
-    @Test(groups={"tck"})
-    public void test_plus_Adjuster_wrap() {
-        TemporalAdder p = Period.ofTime(1, 0, 0);
+    @Test
+    public void test_plus_TemporalAmount_wrap() {
+        TemporalAmount p = MockSimplePeriod.of(1, HOURS);
         LocalTime t = LocalTime.of(23, 30).plus(p);
         assertEquals(t, LocalTime.of(0, 30));
     }
 
-    @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
-    public void test_plus_Adjuster_dateNotAllowed() {
-        TemporalAdder period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_plus_TemporalAmount_dateNotAllowed() {
+        TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
         TEST_12_30_40_987654321.plus(period);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_plus_Adjuster_null() {
-        TEST_12_30_40_987654321.plus((TemporalAdder) null);
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_plus_TemporalAmount_null() {
+        TEST_12_30_40_987654321.plus((TemporalAmount) null);
     }
 
     //-----------------------------------------------------------------------
@@ -1068,41 +1088,6 @@
     }
 
     //-----------------------------------------------------------------------
-    // plus(adjuster)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_plus_adjuster() {
-        Period p = Period.ofTime(0, 0, 62, 3);
-        LocalTime t = TEST_12_30_40_987654321.plus(p);
-        assertEquals(t, LocalTime.of(12, 31, 42, 987654324));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plus_adjuster_big() {
-        Period p = Period.ofTime(0, 0, 0, Long.MAX_VALUE);
-        LocalTime t = TEST_12_30_40_987654321.plus(p);
-        assertEquals(t, TEST_12_30_40_987654321.plusNanos(Long.MAX_VALUE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plus_adjuster_zero_equal() {
-        LocalTime t = TEST_12_30_40_987654321.plus(Period.ZERO);
-        assertEquals(t, TEST_12_30_40_987654321);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plus_adjuster_wrap() {
-        Period p = Period.ofTime(1, 0, 0);
-        LocalTime t = LocalTime.of(23, 30).plus(p);
-        assertEquals(t, LocalTime.of(0, 30));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_plus_adjuster_null() {
-        TEST_12_30_40_987654321.plus((TemporalAdder) null);
-    }
-
-    //-----------------------------------------------------------------------
     // plusHours()
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
@@ -1449,59 +1434,45 @@
     }
 
     //-----------------------------------------------------------------------
-    // minus(MinusAdjuster)
+    // minus(TemporalAmount)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_minus_Adjuster() {
-        TemporalSubtractor p = Period.ofTime(0, 0, 62, 3);
-        LocalTime t = TEST_12_30_40_987654321.minus(p);
-        assertEquals(t, LocalTime.of(12, 29, 38, 987654318));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minus_Adjuster_positiveHours() {
-        TemporalSubtractor period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
+    @Test
+    public void test_minus_TemporalAmount_positiveHours() {
+        TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
         LocalTime t = TEST_12_30_40_987654321.minus(period);
         assertEquals(t, LocalTime.of(5, 30, 40, 987654321));
     }
 
-    @Test(groups={"tck"})
-    public void test_minus_Adjuster_negativeMinutes() {
-        TemporalSubtractor period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
+    @Test
+    public void test_minus_TemporalAmount_negativeMinutes() {
+        TemporalAmount period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
         LocalTime t = TEST_12_30_40_987654321.minus(period);
         assertEquals(t, LocalTime.of(12, 55, 40, 987654321));
     }
 
-    @Test(groups={"tck"})
-    public void test_minus_Adjuster_big1() {
-        TemporalSubtractor p = Period.ofTime(0, 0, 0, Long.MAX_VALUE);
-        LocalTime t = TEST_12_30_40_987654321.minus(p);
-        assertEquals(t, TEST_12_30_40_987654321.minusNanos(Long.MAX_VALUE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minus_Adjuster_zero() {
-        TemporalSubtractor p = Period.ZERO;
-        LocalTime t = TEST_12_30_40_987654321.minus(p);
+    @Test
+    public void test_minus_TemporalAmount_zero() {
+        TemporalAmount period = Period.ZERO;
+        LocalTime t = TEST_12_30_40_987654321.minus(period);
         assertEquals(t, TEST_12_30_40_987654321);
     }
 
-    @Test(groups={"tck"})
-    public void test_minus_Adjuster_wrap() {
-        TemporalSubtractor p = Period.ofTime(1, 0, 0);
+    @Test
+    public void test_minus_TemporalAmount_wrap() {
+        TemporalAmount p = MockSimplePeriod.of(1, HOURS);
         LocalTime t = LocalTime.of(0, 30).minus(p);
         assertEquals(t, LocalTime.of(23, 30));
     }
 
-    @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
-    public void test_minus_Adjuster_dateNotAllowed() {
-        TemporalSubtractor period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_minus_TemporalAmount_dateNotAllowed() {
+        TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
         TEST_12_30_40_987654321.minus(period);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_minus_Adjuster_null() {
-        TEST_12_30_40_987654321.minus((TemporalSubtractor) null);
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_minus_TemporalAmount_null() {
+        TEST_12_30_40_987654321.minus((TemporalAmount) null);
     }
 
     //-----------------------------------------------------------------------
@@ -2213,7 +2184,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
         String t = LocalTime.of(11, 30, 45).toString(f);
         assertEquals(t, "11 30 45");
     }
diff --git a/jdk/test/java/time/tck/java/time/TCKMonth.java b/jdk/test/java/time/tck/java/time/TCKMonth.java
index 6f6170d..c5160c1 100644
--- a/jdk/test/java/time/tck/java/time/TCKMonth.java
+++ b/jdk/test/java/time/tck/java/time/TCKMonth.java
@@ -62,23 +62,23 @@
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static org.testng.Assert.assertEquals;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.Month;
+import java.time.chrono.IsoChronology;
 import java.time.format.TextStyle;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.JulianFields;
 import java.time.temporal.Queries;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -167,34 +167,27 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(Month.JUNE.query(Queries.chrono()), ISOChrono.INSTANCE);
-        assertEquals(Queries.chrono().queryFrom(Month.JUNE), ISOChrono.INSTANCE);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {Month.JUNE, Queries.chronology(), IsoChronology.INSTANCE},
+                {Month.JUNE, Queries.zoneId(), null},
+                {Month.JUNE, Queries.precision(), ChronoUnit.MONTHS},
+                {Month.JUNE, Queries.zone(), null},
+                {Month.JUNE, Queries.offset(), null},
+                {Month.JUNE, Queries.localDate(), null},
+                {Month.JUNE, Queries.localTime(), null},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(Month.JUNE.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(Month.JUNE), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        assertEquals(Month.JUNE.query(Queries.precision()), ChronoUnit.MONTHS);
-        assertEquals(Queries.precision().queryFrom(Month.JUNE), ChronoUnit.MONTHS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(Month.JUNE.query(Queries.offset()), null);
-        assertEquals(Queries.offset().queryFrom(Month.JUNE), null);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(Month.JUNE.query(Queries.zone()), null);
-        assertEquals(Queries.zone().queryFrom(Month.JUNE), null);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -207,17 +200,17 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_getText() {
-        assertEquals(Month.JANUARY.getText(TextStyle.SHORT, Locale.US), "Jan");
+        assertEquals(Month.JANUARY.getDisplayName(TextStyle.SHORT, Locale.US), "Jan");
     }
 
     @Test(expectedExceptions = NullPointerException.class, groups={"tck"})
     public void test_getText_nullStyle() {
-        Month.JANUARY.getText(null, Locale.US);
+        Month.JANUARY.getDisplayName(null, Locale.US);
     }
 
     @Test(expectedExceptions = NullPointerException.class, groups={"tck"})
     public void test_getText_nullLocale() {
-        Month.JANUARY.getText(TextStyle.FULL, null);
+        Month.JANUARY.getDisplayName(TextStyle.FULL, null);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKMonthDay.java b/jdk/test/java/time/tck/java/time/TCKMonthDay.java
similarity index 93%
rename from jdk/test/java/time/tck/java/time/temporal/TCKMonthDay.java
rename to jdk/test/java/time/tck/java/time/TCKMonthDay.java
index 774777c..1a80e8c 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKMonthDay.java
+++ b/jdk/test/java/time/tck/java/time/TCKMonthDay.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.temporal;
+package tck.java.time;
 
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
@@ -68,12 +68,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Instant;
@@ -81,22 +75,28 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Month;
+import java.time.MonthDay;
+import java.time.YearMonth;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
 import java.time.temporal.JulianFields;
-import java.time.temporal.MonthDay;
+import java.time.temporal.Queries;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
-import java.time.temporal.YearMonth;
+import java.time.temporal.TemporalQuery;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import tck.java.time.AbstractDateTimeTest;
 
 /**
  * Test MonthDay.
@@ -147,7 +147,7 @@
     public void test_serialization_format() throws Exception {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(6);
+            dos.writeByte(13);       // java.time.temporal.Ser.MONTH_DAY_TYPE
             dos.writeByte(9);
             dos.writeByte(16);
         }
@@ -372,14 +372,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("M d");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("M d");
         MonthDay test = MonthDay.parse("12 3", f);
         assertEquals(test, MonthDay.of(12, 3));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("M d");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("M d");
         MonthDay.parse((String) null, f);
     }
 
@@ -404,6 +404,37 @@
     }
 
     //-----------------------------------------------------------------------
+    // query(TemporalQuery)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_07_15, Queries.chronology(), IsoChronology.INSTANCE},
+                {TEST_07_15, Queries.zoneId(), null},
+                {TEST_07_15, Queries.precision(), null},
+                {TEST_07_15, Queries.zone(), null},
+                {TEST_07_15, Queries.offset(), null},
+                {TEST_07_15, Queries.localDate(), null},
+                {TEST_07_15, Queries.localTime(), null},
+        };
+    }
+
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
+    }
+
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_query_null() {
+        TEST_07_15.query(null);
+    }
+
+    //-----------------------------------------------------------------------
     // get*()
     //-----------------------------------------------------------------------
     @DataProvider(name="sampleDates")
@@ -419,10 +450,11 @@
         };
     }
 
-    @Test(dataProvider="sampleDates", groups={"tck"})
+    @Test(dataProvider="sampleDates")
     public void test_get(int m, int d) {
         MonthDay a = MonthDay.of(m, d);
         assertEquals(a.getMonth(), Month.of(m));
+        assertEquals(a.getMonthValue(), m);
         assertEquals(a.getDayOfMonth(), d);
     }
 
@@ -743,7 +775,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("M d");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("M d");
         String t = MonthDay.of(12, 3).toString(f);
         assertEquals(t, "12 3");
     }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java
similarity index 77%
rename from jdk/test/java/time/tck/java/time/temporal/TCKOffsetDateTime.java
rename to jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java
index 01d72a4..ee0832e 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKOffsetDateTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.temporal;
+package tck.java.time;
 
 import static java.time.Month.DECEMBER;
 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
@@ -98,13 +98,8 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
-import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Duration;
@@ -113,31 +108,31 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Month;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Year;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.JulianFields;
-import java.time.temporal.OffsetDate;
-import java.time.temporal.OffsetDateTime;
-import java.time.temporal.OffsetTime;
 import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalAdjuster;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.Year;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import tck.java.time.AbstractDateTimeTest;
 import test.java.time.MockSimplePeriod;
 
 /**
@@ -225,7 +220,7 @@
     public void test_serialization_format() throws Exception {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(3);
+            dos.writeByte(10);       // java.time.Ser.OFFSET_DATE_TIME_TYPE
         }
         byte[] bytes = baos.toByteArray();
         ByteArrayOutputStream baosDateTime = new ByteArrayOutputStream();
@@ -270,12 +265,12 @@
     public void now() {
         OffsetDateTime expected = OffsetDateTime.now(Clock.systemDefaultZone());
         OffsetDateTime test = OffsetDateTime.now();
-        long diff = Math.abs(test.getTime().toNanoOfDay() - expected.getTime().toNanoOfDay());
+        long diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
         if (diff >= 100000000) {
             // may be date change
             expected = OffsetDateTime.now(Clock.systemDefaultZone());
             test = OffsetDateTime.now();
-            diff = Math.abs(test.getTime().toNanoOfDay() - expected.getTime().toNanoOfDay());
+            diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
         }
         assertTrue(diff < 100000000);  // less than 0.1 secs
     }
@@ -328,14 +323,14 @@
             assertEquals(test.getMonth(), Month.DECEMBER);
             assertEquals(test.getDayOfMonth(), 31);
             expected = expected.minusSeconds(1);
-            assertEquals(test.getTime(), expected);
+            assertEquals(test.toLocalTime(), expected);
             assertEquals(test.getOffset(), ZoneOffset.UTC);
         }
     }
 
     @Test(groups={"tck"})
     public void now_Clock_offsets() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(1970, 1, 1), LocalTime.of(12, 0), ZoneOffset.UTC);
+        OffsetDateTime base = OffsetDateTime.of(1970, 1, 1, 12, 0, 0, 0, ZoneOffset.UTC);
         for (int i = -9; i < 15; i++) {
             ZoneOffset offset = ZoneOffset.ofHours(i);
             Clock clock = Clock.fixed(base.toInstant(), offset);
@@ -374,49 +369,11 @@
     }
 
     //-----------------------------------------------------------------------
-    // dateTime factories
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_intMonthIntHM() {
-        OffsetDateTime test = OffsetDateTime.of(LocalDate.of(2008, Month.JUNE, 30),
-                LocalTime.of(11, 30), OFFSET_PONE);
-        check(test, 2008, 6, 30, 11, 30, 0, 0, OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_intMonthIntHMS() {
-        OffsetDateTime test = OffsetDateTime.of(LocalDate.of(2008, Month.JUNE, 30),
-                LocalTime.of(11, 30, 10), OFFSET_PONE);
-        check(test, 2008, 6, 30, 11, 30, 10, 0, OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_intMonthIntHMSN() {
-        OffsetDateTime test = OffsetDateTime.of(LocalDate.of(2008, Month.JUNE, 30),
-                LocalTime.of(11, 30, 10, 500), OFFSET_PONE);
-        check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_intsHM() {
-        OffsetDateTime test = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30), OFFSET_PONE);
-        check(test, 2008, 6, 30, 11, 30, 0, 0, OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_intsHMS() {
-        OffsetDateTime test = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 10), OFFSET_PONE);
-        check(test, 2008, 6, 30, 11, 30, 10, 0, OFFSET_PONE);
-    }
-
+    // factories
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_of_intsHMSN() {
-        OffsetDateTime test = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 10, 500), OFFSET_PONE);
+        OffsetDateTime test = OffsetDateTime.of(2008, 6, 30, 11, 30, 10, 500, OFFSET_PONE);
         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_PONE);
     }
 
@@ -523,14 +480,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s XXX");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s XXX");
         OffsetDateTime test = OffsetDateTime.parse("2010 12 3 11 30 0 +01:00", f);
         assertEquals(test, OffsetDateTime.of(LocalDate.of(2010, 12, 3), LocalTime.of(11, 30), ZoneOffset.ofHours(1)));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
         OffsetDateTime.parse((String) null, f);
     }
 
@@ -593,7 +550,6 @@
         assertEquals(a.getSecond(), localDateTime.getSecond());
         assertEquals(a.getNano(), localDateTime.getNano());
 
-        assertEquals(a.toOffsetDate(), OffsetDate.of(localDate, offset));
         assertEquals(a.toOffsetTime(), OffsetTime.of(localTime, offset));
         assertEquals(a.toString(), localDateTime.toString() + offset.toString());
     }
@@ -643,34 +599,27 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(TEST_2008_6_30_11_30_59_000000500.query(Queries.chrono()), ISOChrono.INSTANCE);
-        assertEquals(Queries.chrono().queryFrom(TEST_2008_6_30_11_30_59_000000500), ISOChrono.INSTANCE);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_2008_6_30_11_30_59_000000500, Queries.chronology(), IsoChronology.INSTANCE},
+                {TEST_2008_6_30_11_30_59_000000500, Queries.zoneId(), null},
+                {TEST_2008_6_30_11_30_59_000000500, Queries.precision(), ChronoUnit.NANOS},
+                {TEST_2008_6_30_11_30_59_000000500, Queries.zone(), OFFSET_PONE},
+                {TEST_2008_6_30_11_30_59_000000500, Queries.offset(), OFFSET_PONE},
+                {TEST_2008_6_30_11_30_59_000000500, Queries.localDate(), LocalDate.of(2008, 6, 30)},
+                {TEST_2008_6_30_11_30_59_000000500, Queries.localTime(), LocalTime.of(11, 30, 59, 500)},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(TEST_2008_6_30_11_30_59_000000500.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(TEST_2008_6_30_11_30_59_000000500), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        assertEquals(TEST_2008_6_30_11_30_59_000000500.query(Queries.precision()), NANOS);
-        assertEquals(Queries.precision().queryFrom(TEST_2008_6_30_11_30_59_000000500), NANOS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(TEST_2008_6_30_11_30_59_000000500.query(Queries.offset()), OFFSET_PONE);
-        assertEquals(Queries.offset().queryFrom(TEST_2008_6_30_11_30_59_000000500), OFFSET_PONE);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(TEST_2008_6_30_11_30_59_000000500.query(Queries.zone()), OFFSET_PONE);
-        assertEquals(Queries.zone().queryFrom(TEST_2008_6_30_11_30_59_000000500), OFFSET_PONE);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -712,12 +661,6 @@
     }
 
     @Test(groups={"tck"})
-    public void test_with_adjustment_OffsetDate() {
-        OffsetDateTime test = TEST_2008_6_30_11_30_59_000000500.with(OffsetDate.of(LocalDate.of(2012, 9, 3), OFFSET_PTWO));
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2012, 9, 3), LocalTime.of(11, 30, 59, 500), OFFSET_PTWO));
-    }
-
-    @Test(groups={"tck"})
     public void test_with_adjustment_OffsetTime() {
         OffsetDateTime test = TEST_2008_6_30_11_30_59_000000500.with(OffsetTime.of(LocalTime.of(19, 15), OFFSET_PTWO));
         assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(19, 15), OFFSET_PTWO));
@@ -880,7 +823,7 @@
     public void test_plus_Period() {
         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
         OffsetDateTime t = TEST_2008_6_30_11_30_59_000000500.plus(period);
-        assertEquals(t, OffsetDateTime.of(LocalDate.of(2009, 1, 30), LocalTime.of(11, 30, 59, 500), OFFSET_PONE));
+        assertEquals(t, OffsetDateTime.of(2009, 1, 30, 11, 30, 59, 500, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -890,7 +833,7 @@
     public void test_plus_Duration() {
         Duration dur = Duration.ofSeconds(62, 3);
         OffsetDateTime t = TEST_2008_6_30_11_30_59_000000500.plus(dur);
-        assertEquals(t, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 32, 1, 503), OFFSET_PONE));
+        assertEquals(t, OffsetDateTime.of(2008, 6, 30, 11, 32, 1, 503, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
@@ -909,9 +852,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusYears() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.plusYears(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2009, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2009, 6, 30, 11, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -919,9 +862,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusMonths() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.plusMonths(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 7, 30), LocalTime.of(11, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 7, 30, 11, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -929,9 +872,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusWeeks() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.plusWeeks(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 7, 7), LocalTime.of(11, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 7, 7, 11, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -939,9 +882,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusDays() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.plusDays(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 7, 1), LocalTime.of(11, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 7, 1, 11, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -949,9 +892,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusHours() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.plusHours(13);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 7, 1), LocalTime.of(0, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 7, 1, 0, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -959,9 +902,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusMinutes() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.plusMinutes(30);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(12, 0, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 30, 12, 0, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -969,9 +912,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusSeconds() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.plusSeconds(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 31, 0), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 30, 11, 31, 0, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -979,9 +922,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusNanos() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59, 0), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.plusNanos(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59, 1), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 1, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -991,7 +934,7 @@
     public void test_minus_Period() {
         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
         OffsetDateTime t = TEST_2008_6_30_11_30_59_000000500.minus(period);
-        assertEquals(t, OffsetDateTime.of(LocalDate.of(2007, 11, 30), LocalTime.of(11, 30, 59, 500), OFFSET_PONE));
+        assertEquals(t, OffsetDateTime.of(2007, 11, 30, 11, 30, 59, 500, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1001,7 +944,7 @@
     public void test_minus_Duration() {
         Duration dur = Duration.ofSeconds(62, 3);
         OffsetDateTime t = TEST_2008_6_30_11_30_59_000000500.minus(dur);
-        assertEquals(t, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 29, 57, 497), OFFSET_PONE));
+        assertEquals(t, OffsetDateTime.of(2008, 6, 30, 11, 29, 57, 497, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
@@ -1020,9 +963,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusYears() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.minusYears(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2007, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2007, 6, 30, 11, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1030,9 +973,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusMonths() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.minusMonths(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 5, 30), LocalTime.of(11, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 5, 30, 11, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1040,9 +983,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusWeeks() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.minusWeeks(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 23), LocalTime.of(11, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 23, 11, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1050,9 +993,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusDays() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.minusDays(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 29), LocalTime.of(11, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 29, 11, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1060,9 +1003,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusHours() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.minusHours(13);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 29), LocalTime.of(22, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 29, 22, 30, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1070,9 +1013,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusMinutes() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.minusMinutes(30);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 0, 59), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 30, 11, 0, 59, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1080,9 +1023,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusSeconds() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.minusSeconds(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 58), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 30, 11, 30, 58, 0, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1090,9 +1033,9 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusNanos() {
-        OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59, 0), OFFSET_PONE);
+        OffsetDateTime base = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         OffsetDateTime test = base.minusNanos(1);
-        assertEquals(test, OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 58, 999999999), OFFSET_PONE));
+        assertEquals(test, OffsetDateTime.of(2008, 6, 30, 11, 30, 58, 999999999, OFFSET_PONE));
     }
 
     //-----------------------------------------------------------------------
@@ -1100,14 +1043,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_atZone() {
-        OffsetDateTime t = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30), OFFSET_MTWO);
+        OffsetDateTime t = OffsetDateTime.of(2008, 6, 30, 11, 30, 0, 0, OFFSET_MTWO);
         assertEquals(t.atZoneSameInstant(ZONE_PARIS),
-                ZonedDateTime.of(LocalDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(15, 30)), ZONE_PARIS));
+                ZonedDateTime.of(2008, 6, 30, 15, 30, 0, 0, ZONE_PARIS));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_atZone_nullTimeZone() {
-        OffsetDateTime t = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30), OFFSET_PTWO);
+        OffsetDateTime t = OffsetDateTime.of(2008, 6, 30, 11, 30, 0, 0, OFFSET_PTWO);
         t.atZoneSameInstant((ZoneId) null);
     }
 
@@ -1116,37 +1059,37 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_atZoneSimilarLocal() {
-        OffsetDateTime t = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30), OFFSET_MTWO);
+        OffsetDateTime t = OffsetDateTime.of(2008, 6, 30, 11, 30, 0, 0, OFFSET_MTWO);
         assertEquals(t.atZoneSimilarLocal(ZONE_PARIS),
-                ZonedDateTime.of(LocalDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30)), ZONE_PARIS));
+                ZonedDateTime.of(2008, 6, 30, 11, 30, 0, 0, ZONE_PARIS));
     }
 
     @Test(groups={"tck"})
     public void test_atZoneSimilarLocal_dstGap() {
-        OffsetDateTime t = OffsetDateTime.of(LocalDate.of(2007, 4, 1), LocalTime.of(0, 0), OFFSET_MTWO);
+        OffsetDateTime t = OffsetDateTime.of(2007, 4, 1, 0, 0, 0, 0, OFFSET_MTWO);
         assertEquals(t.atZoneSimilarLocal(ZONE_GAZA),
-                ZonedDateTime.of(LocalDateTime.of(LocalDate.of(2007, 4, 1), LocalTime.of(1, 0)), ZONE_GAZA));
+                ZonedDateTime.of(2007, 4, 1, 1, 0, 0, 0, ZONE_GAZA));
     }
 
     @Test(groups={"tck"})
     public void test_atZone_dstOverlapSummer() {
-        OffsetDateTime t = OffsetDateTime.of(LocalDate.of(2007, 10, 28), LocalTime.of(2, 30), OFFSET_PTWO);
-        assertEquals(t.atZoneSimilarLocal(ZONE_PARIS).getDateTime(), t.getDateTime());
+        OffsetDateTime t = OffsetDateTime.of(2007, 10, 28, 2, 30, 0, 0, OFFSET_PTWO);
+        assertEquals(t.atZoneSimilarLocal(ZONE_PARIS).toLocalDateTime(), t.toLocalDateTime());
         assertEquals(t.atZoneSimilarLocal(ZONE_PARIS).getOffset(), OFFSET_PTWO);
         assertEquals(t.atZoneSimilarLocal(ZONE_PARIS).getZone(), ZONE_PARIS);
     }
 
     @Test(groups={"tck"})
     public void test_atZone_dstOverlapWinter() {
-        OffsetDateTime t = OffsetDateTime.of(LocalDate.of(2007, 10, 28), LocalTime.of(2, 30), OFFSET_PONE);
-        assertEquals(t.atZoneSimilarLocal(ZONE_PARIS).getDateTime(), t.getDateTime());
+        OffsetDateTime t = OffsetDateTime.of(2007, 10, 28, 2, 30, 0, 0, OFFSET_PONE);
+        assertEquals(t.atZoneSimilarLocal(ZONE_PARIS).toLocalDateTime(), t.toLocalDateTime());
         assertEquals(t.atZoneSimilarLocal(ZONE_PARIS).getOffset(), OFFSET_PONE);
         assertEquals(t.atZoneSimilarLocal(ZONE_PARIS).getZone(), ZONE_PARIS);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_atZoneSimilarLocal_nullTimeZone() {
-        OffsetDateTime t = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30), OFFSET_PTWO);
+        OffsetDateTime t = OffsetDateTime.of(2008, 6, 30, 11, 30, 0, 0, OFFSET_PTWO);
         t.atZoneSimilarLocal((ZoneId) null);
     }
 
@@ -1156,7 +1099,7 @@
     @Test(groups={"tck"})
     public void test_toEpochSecond_afterEpoch() {
         for (int i = 0; i < 100000; i++) {
-            OffsetDateTime a = OffsetDateTime.of(LocalDate.of(1970, 1, 1), LocalTime.of(0, 0), ZoneOffset.UTC).plusSeconds(i);
+            OffsetDateTime a = OffsetDateTime.of(1970, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).plusSeconds(i);
             assertEquals(a.toEpochSecond(), i);
         }
     }
@@ -1164,7 +1107,7 @@
     @Test(groups={"tck"})
     public void test_toEpochSecond_beforeEpoch() {
         for (int i = 0; i < 100000; i++) {
-            OffsetDateTime a = OffsetDateTime.of(LocalDate.of(1970, 1, 1), LocalTime.of(0, 0), ZoneOffset.UTC).minusSeconds(i);
+            OffsetDateTime a = OffsetDateTime.of(1970, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).minusSeconds(i);
             assertEquals(a.toEpochSecond(), -i);
         }
     }
@@ -1174,8 +1117,8 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_compareTo_timeMins() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 29, 3), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 2), OFFSET_PONE);  // a is before b due to time
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 29, 3, 0, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 30, 2, 0, OFFSET_PONE);  // a is before b due to time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1185,8 +1128,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_timeSecs() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 29, 2), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 29, 3), OFFSET_PONE);  // a is before b due to time
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 29, 2, 0, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 29, 3, 0, OFFSET_PONE);  // a is before b due to time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1196,8 +1139,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_timeNanos() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 29, 40, 4), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 29, 40, 5), OFFSET_PONE);  // a is before b due to time
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 29, 40, 4, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 29, 40, 5, OFFSET_PONE);  // a is before b due to time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1207,8 +1150,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_offset() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30), OFFSET_PTWO);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30), OFFSET_PONE);  // a is before b due to offset
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 30, 0, 0, OFFSET_PTWO);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 30, 0, 0, OFFSET_PONE);  // a is before b due to offset
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1218,8 +1161,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_offsetNanos() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 40, 6), OFFSET_PTWO);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 40, 5), OFFSET_PONE);  // a is before b due to offset
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 30, 40, 6, OFFSET_PTWO);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 30, 40, 5, OFFSET_PONE);  // a is before b due to offset
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1229,8 +1172,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_both() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 50), OFFSET_PTWO);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 20), OFFSET_PONE);  // a is before b on instant scale
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 50, 0, 0, OFFSET_PTWO);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 20, 0, 0, OFFSET_PONE);  // a is before b on instant scale
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1240,8 +1183,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_bothNanos() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 20, 40, 4), OFFSET_PTWO);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(10, 20, 40, 5), OFFSET_PONE);  // a is before b on instant scale
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 20, 40, 4, OFFSET_PTWO);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 10, 20, 40, 5, OFFSET_PONE);  // a is before b on instant scale
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1251,8 +1194,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_hourDifference() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(10, 0), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 0), OFFSET_PTWO);  // a is before b despite being same time-line time
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 10, 0, 0, 0, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 0, 0, 0, OFFSET_PTWO);  // a is before b despite being same time-line time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1262,8 +1205,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_max() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(Year.MAX_VALUE, 12, 31), LocalTime.of(23, 59), OFFSET_MONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(Year.MAX_VALUE, 12, 31), LocalTime.of(23, 59), OFFSET_MTWO);  // a is before b due to offset
+        OffsetDateTime a = OffsetDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 0, 0, OFFSET_MONE);
+        OffsetDateTime b = OffsetDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 0, 0, OFFSET_MTWO);  // a is before b due to offset
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1272,8 +1215,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_min() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(Year.MIN_VALUE, 1, 1), LocalTime.of(0, 0), OFFSET_PTWO);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(Year.MIN_VALUE, 1, 1), LocalTime.of(0, 0), OFFSET_PONE);  // a is before b due to offset
+        OffsetDateTime a = OffsetDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0, 0, 0, OFFSET_PTWO);
+        OffsetDateTime b = OffsetDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0, 0, 0, OFFSET_PONE);  // a is before b due to offset
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1282,7 +1225,7 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_compareTo_null() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         a.compareTo(null);
     }
 
@@ -1298,8 +1241,8 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_isBeforeIsAfterIsEqual1() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 58, 3), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59, 2), OFFSET_PONE);  // a is before b due to time
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 30, 58, 3, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 2, OFFSET_PONE);  // a is before b due to time
         assertEquals(a.isBefore(b), true);
         assertEquals(a.isEqual(b), false);
         assertEquals(a.isAfter(b), false);
@@ -1320,8 +1263,8 @@
 
     @Test(groups={"tck"})
     public void test_isBeforeIsAfterIsEqual2() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59, 2), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59, 3), OFFSET_PONE);  // a is before b due to time
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 2, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 3, OFFSET_PONE);  // a is before b due to time
         assertEquals(a.isBefore(b), true);
         assertEquals(a.isEqual(b), false);
         assertEquals(a.isAfter(b), false);
@@ -1342,8 +1285,8 @@
 
     @Test(groups={"tck"})
     public void test_isBeforeIsAfterIsEqual_instantComparison() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(10, 0), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 0), OFFSET_PTWO);  // a is same instant as b
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 10, 0, 0, 0, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 11, 0, 0, 0, OFFSET_PTWO);  // a is same instant as b
         assertEquals(a.isBefore(b), false);
         assertEquals(a.isEqual(b), true);
         assertEquals(a.isAfter(b), false);
@@ -1364,19 +1307,19 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_isBefore_null() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         a.isBefore(null);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_isEqual_null() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         a.isEqual(null);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_isAfter_null() {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 0, OFFSET_PONE);
         a.isAfter(null);
     }
 
@@ -1385,49 +1328,49 @@
     //-----------------------------------------------------------------------
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_true(int y, int o, int d, int h, int m, int s, int n, ZoneOffset ignored) {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PONE);
         assertEquals(a.equals(b), true);
         assertEquals(a.hashCode() == b.hashCode(), true);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_year_differs(int y, int o, int d, int h, int m, int s, int n, ZoneOffset ignored) {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(y + 1, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(y + 1, o, d, h, m, s, n, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_hour_differs(int y, int o, int d, int h, int m, int s, int n, ZoneOffset ignored) {
         h = (h == 23 ? 22 : h);
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h + 1, m, s, n), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(y, o, d, h + 1, m, s, n, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_minute_differs(int y, int o, int d, int h, int m, int s, int n, ZoneOffset ignored) {
         m = (m == 59 ? 58 : m);
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m + 1, s, n), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(y, o, d, h, m + 1, s, n, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_second_differs(int y, int o, int d, int h, int m, int s, int n, ZoneOffset ignored) {
         s = (s == 59 ? 58 : s);
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s + 1, n), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(y, o, d, h, m, s + 1, n, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_nano_differs(int y, int o, int d, int h, int m, int s, int n, ZoneOffset ignored) {
         n = (n == 999999999 ? 999999998 : n);
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n + 1), OFFSET_PONE);
+        OffsetDateTime a = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(y, o, d, h, m, s, n + 1, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_offset_differs(int y, int o, int d, int h, int m, int s, int n, ZoneOffset ignored) {
-        OffsetDateTime a = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetDateTime b = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), OFFSET_PTWO);
+        OffsetDateTime a = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PONE);
+        OffsetDateTime b = OffsetDateTime.of(y, o, d, h, m, s, n, OFFSET_PTWO);
         assertEquals(a.equals(b), false);
     }
 
@@ -1465,7 +1408,7 @@
 
     @Test(dataProvider="sampleToString", groups={"tck"})
     public void test_toString(int y, int o, int d, int h, int m, int s, int n, String offsetId, String expected) {
-        OffsetDateTime t = OffsetDateTime.of(LocalDate.of(y, o, d), LocalTime.of(h, m, s, n), ZoneOffset.of(offsetId));
+        OffsetDateTime t = OffsetDateTime.of(y, o, d, h, m, s, n, ZoneOffset.of(offsetId));
         String str = t.toString();
         assertEquals(str, expected);
     }
@@ -1475,14 +1418,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s");
-        String t = OffsetDateTime.of(LocalDate.of(2010, 12, 3), LocalTime.of(11, 30), OFFSET_PONE).toString(f);
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
+        String t = OffsetDateTime.of(2010, 12, 3, 11, 30, 0, 0, OFFSET_PONE).toString(f);
         assertEquals(t, "2010 12 3 11 30 0");
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_toString_formatter_null() {
-        OffsetDateTime.of(LocalDate.of(2010, 12, 3), LocalTime.of(11, 30), OFFSET_PONE).toString(null);
+        OffsetDateTime.of(2010, 12, 3, 11, 30, 0, 0, OFFSET_PONE).toString(null);
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java
similarity index 79%
rename from jdk/test/java/time/tck/java/time/temporal/TCKOffsetTime.java
rename to jdk/test/java/time/tck/java/time/TCKOffsetTime.java
index 3742685..8311709 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKOffsetTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.temporal;
+package tck.java.time;
 
 import static java.time.temporal.ChronoField.AMPM_OF_DAY;
 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
@@ -84,45 +84,38 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
-import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.OffsetTime;
 import java.time.Period;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.JulianFields;
-import java.time.temporal.OffsetDate;
-import java.time.temporal.OffsetDateTime;
-import java.time.temporal.OffsetTime;
 import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import tck.java.time.AbstractDateTimeTest;
 import test.java.time.MockSimplePeriod;
 
 /**
@@ -138,7 +131,7 @@
 
     @BeforeMethod(groups={"tck","implementation"})
     public void setUp() {
-        TEST_11_30_59_500_PONE = OffsetTime.of(LocalTime.of(11, 30, 59, 500), OFFSET_PONE);
+        TEST_11_30_59_500_PONE = OffsetTime.of(11, 30, 59, 500, OFFSET_PONE);
     }
 
     //-----------------------------------------------------------------------
@@ -193,7 +186,7 @@
     public void test_serialization_format() throws Exception {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(2);
+            dos.writeByte(9);       // java.time.Ser.OFFSET_TIME_TYPE
         }
         byte[] bytes = baos.toByteArray();
         ByteArrayOutputStream baosTime = new ByteArrayOutputStream();
@@ -211,7 +204,7 @@
             dos.writeByte(4);  // quarter hours stored: 3600 / 900
         }
         byte[] bytesOffset = baosOffset.toByteArray();
-        assertSerializedBySer(OffsetTime.of(LocalTime.of(22, 17, 59, 464_000_000), ZoneOffset.ofHours(1)), bytes,
+        assertSerializedBySer(OffsetTime.of(22, 17, 59, 464_000_000, ZoneOffset.ofHours(1)), bytes,
                 bytesTime, bytesOffset);
     }
 
@@ -237,7 +230,7 @@
 
         OffsetTime expected = OffsetTime.now(Clock.systemDefaultZone());
         OffsetTime test = OffsetTime.now();
-        long diff = Math.abs(test.getTime().toNanoOfDay() - expected.getTime().toNanoOfDay());
+        long diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
         assertTrue(diff < 100000000);  // less than 0.1 secs
         assertEquals(test.getOffset(), nowDT.getOffset());
     }
@@ -302,7 +295,7 @@
     // factories
     //-----------------------------------------------------------------------
     private void check(OffsetTime test, int h, int m, int s, int n, ZoneOffset offset) {
-        assertEquals(test.getTime(), LocalTime.of(h, m, s, n));
+        assertEquals(test.toLocalTime(), LocalTime.of(h, m, s, n));
         assertEquals(test.getOffset(), offset);
 
         assertEquals(test.getHour(), h);
@@ -317,22 +310,8 @@
 
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
-    public void factory_intsHM() {
-        OffsetTime test = OffsetTime.of(LocalTime.of(11, 30), OFFSET_PONE);
-        check(test, 11, 30, 0, 0, OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_intsHMS() {
-        OffsetTime test = OffsetTime.of(LocalTime.of(11, 30, 10), OFFSET_PONE);
-        check(test, 11, 30, 10, 0, OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
     public void factory_intsHMSN() {
-        OffsetTime test = OffsetTime.of(LocalTime.of(11, 30, 10, 500), OFFSET_PONE);
+        OffsetTime test = OffsetTime.of(11, 30, 10, 500, OFFSET_PONE);
         check(test, 11, 30, 10, 500, OFFSET_PONE);
     }
 
@@ -417,7 +396,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_from_TemporalAccessor_OT() {
-        assertEquals(OffsetTime.from(OffsetTime.of(LocalTime.of(17, 30), OFFSET_PONE)), OffsetTime.of(LocalTime.of(17, 30), OFFSET_PONE));
+        assertEquals(OffsetTime.from(OffsetTime.of(17, 30, 0, 0, OFFSET_PONE)), OffsetTime.of(17, 30, 0, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
@@ -487,14 +466,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("H m s XXX");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s XXX");
         OffsetTime test = OffsetTime.parse("11 30 0 +01:00", f);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 30), ZoneOffset.ofHours(1)));
+        assertEquals(test, OffsetTime.of(11, 30, 0, 0, ZoneOffset.ofHours(1)));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
         OffsetTime.parse((String) null, f);
     }
 
@@ -522,7 +501,7 @@
         Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
         con.setAccessible(true);
         try {
-            con.newInstance(LocalTime.of(11, 30), null);
+            con.newInstance(LocalTime.of(11, 30, 0, 0), null);
         } catch (InvocationTargetException ex) {
             throw ex.getCause();
         }
@@ -545,7 +524,7 @@
         LocalTime localTime = LocalTime.of(h, m, s, n);
         OffsetTime a = OffsetTime.of(localTime, offset);
 
-        assertEquals(a.getTime(), localTime);
+        assertEquals(a.toLocalTime(), localTime);
         assertEquals(a.getOffset(), offset);
         assertEquals(a.toString(), localTime.toString() + offset.toString());
         assertEquals(a.getHour(), localTime.getHour());
@@ -559,7 +538,7 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_get_TemporalField() {
-        OffsetTime test = OffsetTime.of(LocalTime.of(12, 30, 40, 987654321), OFFSET_PONE);
+        OffsetTime test = OffsetTime.of(12, 30, 40, 987654321, OFFSET_PONE);
         assertEquals(test.get(ChronoField.HOUR_OF_DAY), 12);
         assertEquals(test.get(ChronoField.MINUTE_OF_HOUR), 30);
         assertEquals(test.get(ChronoField.SECOND_OF_MINUTE), 40);
@@ -572,7 +551,7 @@
 
     @Test
     public void test_getLong_TemporalField() {
-        OffsetTime test = OffsetTime.of(LocalTime.of(12, 30, 40, 987654321), OFFSET_PONE);
+        OffsetTime test = OffsetTime.of(12, 30, 40, 987654321, OFFSET_PONE);
         assertEquals(test.getLong(ChronoField.HOUR_OF_DAY), 12);
         assertEquals(test.getLong(ChronoField.MINUTE_OF_HOUR), 30);
         assertEquals(test.getLong(ChronoField.SECOND_OF_MINUTE), 40);
@@ -586,34 +565,27 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(TEST_11_30_59_500_PONE.query(Queries.chrono()), null);
-        assertEquals(Queries.chrono().queryFrom(TEST_11_30_59_500_PONE), null);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_11_30_59_500_PONE, Queries.chronology(), null},
+                {TEST_11_30_59_500_PONE, Queries.zoneId(), null},
+                {TEST_11_30_59_500_PONE, Queries.precision(), ChronoUnit.NANOS},
+                {TEST_11_30_59_500_PONE, Queries.zone(), OFFSET_PONE},
+                {TEST_11_30_59_500_PONE, Queries.offset(), OFFSET_PONE},
+                {TEST_11_30_59_500_PONE, Queries.localDate(), null},
+                {TEST_11_30_59_500_PONE, Queries.localTime(), LocalTime.of(11, 30, 59, 500)},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(TEST_11_30_59_500_PONE.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(TEST_11_30_59_500_PONE), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        assertEquals(TEST_11_30_59_500_PONE.query(Queries.precision()), NANOS);
-        assertEquals(Queries.precision().queryFrom(TEST_11_30_59_500_PONE), NANOS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(TEST_11_30_59_500_PONE.query(Queries.offset()), OFFSET_PONE);
-        assertEquals(Queries.offset().queryFrom(TEST_11_30_59_500_PONE), OFFSET_PONE);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(TEST_11_30_59_500_PONE.query(Queries.zone()), OFFSET_PONE);
-        assertEquals(Queries.zone().queryFrom(TEST_11_30_59_500_PONE), OFFSET_PONE);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -626,22 +598,22 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_withOffsetSameLocal() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withOffsetSameLocal(OFFSET_PTWO);
-        assertEquals(test.getTime(), base.getTime());
+        assertEquals(test.toLocalTime(), base.toLocalTime());
         assertEquals(test.getOffset(), OFFSET_PTWO);
     }
 
     @Test(groups={"tck"})
     public void test_withOffsetSameLocal_noChange() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withOffsetSameLocal(OFFSET_PONE);
         assertEquals(test, base);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_withOffsetSameLocal_null() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         base.withOffsetSameLocal(null);
     }
 
@@ -650,22 +622,22 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_withOffsetSameInstant() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withOffsetSameInstant(OFFSET_PTWO);
-        OffsetTime expected = OffsetTime.of(LocalTime.of(12, 30, 59), OFFSET_PTWO);
+        OffsetTime expected = OffsetTime.of(12, 30, 59, 0, OFFSET_PTWO);
         assertEquals(test, expected);
     }
 
     @Test(groups={"tck"})
     public void test_withOffsetSameInstant_noChange() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withOffsetSameInstant(OFFSET_PONE);
         assertEquals(test, base);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_withOffsetSameInstant_null() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         base.withOffsetSameInstant(null);
     }
 
@@ -674,7 +646,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_with_adjustment() {
-        final OffsetTime sample = OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE);
+        final OffsetTime sample = OffsetTime.of(23, 5, 0, 0, OFFSET_PONE);
         TemporalAdjuster adjuster = new TemporalAdjuster() {
             @Override
             public Temporal adjustInto(Temporal dateTime) {
@@ -687,19 +659,19 @@
     @Test(groups={"tck"})
     public void test_with_adjustment_LocalTime() {
         OffsetTime test = TEST_11_30_59_500_PONE.with(LocalTime.of(13, 30));
-        assertEquals(test, OffsetTime.of(LocalTime.of(13, 30), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(13, 30, 0, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_with_adjustment_OffsetTime() {
-        OffsetTime test = TEST_11_30_59_500_PONE.with(OffsetTime.of(LocalTime.of(13, 35), OFFSET_PTWO));
-        assertEquals(test, OffsetTime.of(LocalTime.of(13, 35), OFFSET_PTWO));
+        OffsetTime test = TEST_11_30_59_500_PONE.with(OffsetTime.of(13, 35, 0, 0, OFFSET_PTWO));
+        assertEquals(test, OffsetTime.of(13, 35, 0, 0, OFFSET_PTWO));
     }
 
     @Test(groups={"tck"})
     public void test_with_adjustment_ZoneOffset() {
         OffsetTime test = TEST_11_30_59_500_PONE.with(OFFSET_PTWO);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 30, 59, 500), OFFSET_PTWO));
+        assertEquals(test, OffsetTime.of(11, 30, 59, 500, OFFSET_PTWO));
     }
 
     @Test(groups={"tck"})
@@ -710,7 +682,7 @@
                 return dateTime.with(HOUR_OF_DAY, 23);
             }
         });
-        assertEquals(test, OffsetTime.of(LocalTime.of(23, 30, 59, 500), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(23, 30, 59, 500, OFFSET_PONE));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
@@ -723,15 +695,15 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_with_TemporalField() {
-        OffsetTime test = OffsetTime.of(LocalTime.of(12, 30, 40, 987654321), OFFSET_PONE);
-        assertEquals(test.with(ChronoField.HOUR_OF_DAY, 15), OffsetTime.of(LocalTime.of(15, 30, 40, 987654321), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.MINUTE_OF_HOUR, 50), OffsetTime.of(LocalTime.of(12, 50, 40, 987654321), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.SECOND_OF_MINUTE, 50), OffsetTime.of(LocalTime.of(12, 30, 50, 987654321), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.NANO_OF_SECOND, 12345), OffsetTime.of(LocalTime.of(12, 30, 40, 12345), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.HOUR_OF_AMPM, 6), OffsetTime.of(LocalTime.of(18, 30, 40, 987654321), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.AMPM_OF_DAY, 0), OffsetTime.of(LocalTime.of(0, 30, 40, 987654321), OFFSET_PONE));
+        OffsetTime test = OffsetTime.of(12, 30, 40, 987654321, OFFSET_PONE);
+        assertEquals(test.with(ChronoField.HOUR_OF_DAY, 15), OffsetTime.of(15, 30, 40, 987654321, OFFSET_PONE));
+        assertEquals(test.with(ChronoField.MINUTE_OF_HOUR, 50), OffsetTime.of(12, 50, 40, 987654321, OFFSET_PONE));
+        assertEquals(test.with(ChronoField.SECOND_OF_MINUTE, 50), OffsetTime.of(12, 30, 50, 987654321, OFFSET_PONE));
+        assertEquals(test.with(ChronoField.NANO_OF_SECOND, 12345), OffsetTime.of(12, 30, 40, 12345, OFFSET_PONE));
+        assertEquals(test.with(ChronoField.HOUR_OF_AMPM, 6), OffsetTime.of(18, 30, 40, 987654321, OFFSET_PONE));
+        assertEquals(test.with(ChronoField.AMPM_OF_DAY, 0), OffsetTime.of(0, 30, 40, 987654321, OFFSET_PONE));
 
-        assertEquals(test.with(ChronoField.OFFSET_SECONDS, 7205), OffsetTime.of(LocalTime.of(12, 30, 40, 987654321), ZoneOffset.ofHoursMinutesSeconds(2, 0, 5)));
+        assertEquals(test.with(ChronoField.OFFSET_SECONDS, 7205), OffsetTime.of(12, 30, 40, 987654321, ZoneOffset.ofHoursMinutesSeconds(2, 0, 5)));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"} )
@@ -749,14 +721,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_withHour_normal() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withHour(15);
-        assertEquals(test, OffsetTime.of(LocalTime.of(15, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(15, 30, 59, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_withHour_noChange() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withHour(11);
         assertEquals(test, base);
     }
@@ -766,14 +738,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_withMinute_normal() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withMinute(15);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 15, 59), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(11, 15, 59, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_withMinute_noChange() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withMinute(30);
         assertEquals(test, base);
     }
@@ -783,14 +755,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_withSecond_normal() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withSecond(15);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 30, 15), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(11, 30, 15, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_withSecond_noChange() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.withSecond(59);
         assertEquals(test, base);
     }
@@ -800,14 +772,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_withNanoOfSecond_normal() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59, 1), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 1, OFFSET_PONE);
         OffsetTime test = base.withNano(15);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 30, 59, 15), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(11, 30, 59, 15, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_withNanoOfSecond_noChange() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59, 1), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 1, OFFSET_PONE);
         OffsetTime test = base.withNano(1);
         assertEquals(test, base);
     }
@@ -834,7 +806,7 @@
     public void test_plus_PlusAdjuster() {
         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MINUTES);
         OffsetTime t = TEST_11_30_59_500_PONE.plus(period);
-        assertEquals(t, OffsetTime.of(LocalTime.of(11, 37, 59, 500), OFFSET_PONE));
+        assertEquals(t, OffsetTime.of(11, 37, 59, 500, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
@@ -851,7 +823,7 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_plus_PlusAdjuster_null() {
-        TEST_11_30_59_500_PONE.plus((TemporalAdder) null);
+        TEST_11_30_59_500_PONE.plus((TemporalAmount) null);
     }
 
     //-----------------------------------------------------------------------
@@ -859,14 +831,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusHours() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.plusHours(13);
-        assertEquals(test, OffsetTime.of(LocalTime.of(0, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(0, 30, 59, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_plusHours_zero() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.plusHours(0);
         assertEquals(test, base);
     }
@@ -876,14 +848,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusMinutes() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.plusMinutes(30);
-        assertEquals(test, OffsetTime.of(LocalTime.of(12, 0, 59), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(12, 0, 59, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_plusMinutes_zero() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.plusMinutes(0);
         assertEquals(test, base);
     }
@@ -893,14 +865,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusSeconds() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.plusSeconds(1);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 31, 0), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(11, 31, 0, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_plusSeconds_zero() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.plusSeconds(0);
         assertEquals(test, base);
     }
@@ -910,14 +882,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_plusNanos() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59, 0), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.plusNanos(1);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 30, 59, 1), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(11, 30, 59, 1, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_plusNanos_zero() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.plusNanos(0);
         assertEquals(test, base);
     }
@@ -929,7 +901,7 @@
     public void test_minus_MinusAdjuster() {
         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MINUTES);
         OffsetTime t = TEST_11_30_59_500_PONE.minus(period);
-        assertEquals(t, OffsetTime.of(LocalTime.of(11, 23, 59, 500), OFFSET_PONE));
+        assertEquals(t, OffsetTime.of(11, 23, 59, 500, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
@@ -946,7 +918,7 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_minus_MinusAdjuster_null() {
-        TEST_11_30_59_500_PONE.minus((TemporalSubtractor) null);
+        TEST_11_30_59_500_PONE.minus((TemporalAmount) null);
     }
 
     //-----------------------------------------------------------------------
@@ -954,14 +926,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusHours() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.minusHours(-13);
-        assertEquals(test, OffsetTime.of(LocalTime.of(0, 30, 59), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(0, 30, 59, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_minusHours_zero() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.minusHours(0);
         assertEquals(test, base);
     }
@@ -971,14 +943,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusMinutes() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.minusMinutes(50);
-        assertEquals(test, OffsetTime.of(LocalTime.of(10, 40, 59), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(10, 40, 59, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_minusMinutes_zero() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.minusMinutes(0);
         assertEquals(test, base);
     }
@@ -988,14 +960,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusSeconds() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.minusSeconds(60);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 29, 59), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(11, 29, 59, 0, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_minusSeconds_zero() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.minusSeconds(0);
         assertEquals(test, base);
     }
@@ -1005,14 +977,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_minusNanos() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59, 0), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.minusNanos(1);
-        assertEquals(test, OffsetTime.of(LocalTime.of(11, 30, 58, 999999999), OFFSET_PONE));
+        assertEquals(test, OffsetTime.of(11, 30, 58, 999999999, OFFSET_PONE));
     }
 
     @Test(groups={"tck"})
     public void test_minusNanos_zero() {
-        OffsetTime base = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         OffsetTime test = base.minusNanos(0);
         assertEquals(test, base);
     }
@@ -1022,8 +994,8 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_compareTo_time() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 29), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(11, 30), OFFSET_PONE);  // a is before b due to time
+        OffsetTime a = OffsetTime.of(11, 29, 0, 0, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(11, 30, 0, 0, OFFSET_PONE);  // a is before b due to time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1033,8 +1005,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_offset() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30), OFFSET_PTWO);
-        OffsetTime b = OffsetTime.of(LocalTime.of(11, 30), OFFSET_PONE);  // a is before b due to offset
+        OffsetTime a = OffsetTime.of(11, 30, 0, 0, OFFSET_PTWO);
+        OffsetTime b = OffsetTime.of(11, 30, 0, 0, OFFSET_PONE);  // a is before b due to offset
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1044,8 +1016,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_both() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 50), OFFSET_PTWO);
-        OffsetTime b = OffsetTime.of(LocalTime.of(11, 20), OFFSET_PONE);  // a is before b on instant scale
+        OffsetTime a = OffsetTime.of(11, 50, 0, 0, OFFSET_PTWO);
+        OffsetTime b = OffsetTime.of(11, 20, 0, 0, OFFSET_PONE);  // a is before b on instant scale
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1055,8 +1027,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_bothNearStartOfDay() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(0, 10), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(2, 30), OFFSET_PTWO);  // a is before b on instant scale
+        OffsetTime a = OffsetTime.of(0, 10, 0, 0, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(2, 30, 0, 0, OFFSET_PTWO);  // a is before b on instant scale
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1066,8 +1038,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_hourDifference() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(10, 0), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(11, 0), OFFSET_PTWO);  // a is before b despite being same time-line time
+        OffsetTime a = OffsetTime.of(10, 0, 0, 0, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(11, 0, 0, 0, OFFSET_PTWO);  // a is before b despite being same time-line time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1077,7 +1049,7 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_compareTo_null() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         a.compareTo(null);
     }
 
@@ -1089,7 +1061,7 @@
     }
 
     private Instant convertInstant(OffsetTime ot) {
-        return DATE.atTime(ot.getTime()).toInstant(ot.getOffset());
+        return DATE.atTime(ot.toLocalTime()).toInstant(ot.getOffset());
     }
 
     //-----------------------------------------------------------------------
@@ -1097,8 +1069,8 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_isBeforeIsAfterIsEqual1() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 58), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);  // a is before b due to time
+        OffsetTime a = OffsetTime.of(11, 30, 58, 0, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);  // a is before b due to time
         assertEquals(a.isBefore(b), true);
         assertEquals(a.isEqual(b), false);
         assertEquals(a.isAfter(b), false);
@@ -1119,8 +1091,8 @@
 
     @Test(groups={"tck"})
     public void test_isBeforeIsAfterIsEqual1nanos() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 59, 3), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(11, 30, 59, 4), OFFSET_PONE);  // a is before b due to time
+        OffsetTime a = OffsetTime.of(11, 30, 59, 3, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(11, 30, 59, 4, OFFSET_PONE);  // a is before b due to time
         assertEquals(a.isBefore(b), true);
         assertEquals(a.isEqual(b), false);
         assertEquals(a.isAfter(b), false);
@@ -1141,8 +1113,8 @@
 
     @Test(groups={"tck"})
     public void test_isBeforeIsAfterIsEqual2() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PTWO);
-        OffsetTime b = OffsetTime.of(LocalTime.of(11, 30, 58), OFFSET_PONE);  // a is before b due to offset
+        OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PTWO);
+        OffsetTime b = OffsetTime.of(11, 30, 58, 0, OFFSET_PONE);  // a is before b due to offset
         assertEquals(a.isBefore(b), true);
         assertEquals(a.isEqual(b), false);
         assertEquals(a.isAfter(b), false);
@@ -1163,8 +1135,8 @@
 
     @Test(groups={"tck"})
     public void test_isBeforeIsAfterIsEqual2nanos() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 59, 4), ZoneOffset.ofTotalSeconds(OFFSET_PONE.getTotalSeconds() + 1));
-        OffsetTime b = OffsetTime.of(LocalTime.of(11, 30, 59, 3), OFFSET_PONE);  // a is before b due to offset
+        OffsetTime a = OffsetTime.of(11, 30, 59, 4, ZoneOffset.ofTotalSeconds(OFFSET_PONE.getTotalSeconds() + 1));
+        OffsetTime b = OffsetTime.of(11, 30, 59, 3, OFFSET_PONE);  // a is before b due to offset
         assertEquals(a.isBefore(b), true);
         assertEquals(a.isEqual(b), false);
         assertEquals(a.isAfter(b), false);
@@ -1185,8 +1157,8 @@
 
     @Test(groups={"tck"})
     public void test_isBeforeIsAfterIsEqual_instantComparison() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PTWO);
-        OffsetTime b = OffsetTime.of(LocalTime.of(10, 30, 59), OFFSET_PONE);  // a is same instant as b
+        OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PTWO);
+        OffsetTime b = OffsetTime.of(10, 30, 59, 0, OFFSET_PONE);  // a is same instant as b
         assertEquals(a.isBefore(b), false);
         assertEquals(a.isEqual(b), true);
         assertEquals(a.isAfter(b), false);
@@ -1207,19 +1179,19 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_isBefore_null() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         a.isBefore(null);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_isAfter_null() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         a.isAfter(null);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_isEqual_null() {
-        OffsetTime a = OffsetTime.of(LocalTime.of(11, 30, 59), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
         a.isEqual(null);
     }
 
@@ -1228,43 +1200,43 @@
     //-----------------------------------------------------------------------
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_true(int h, int m, int s, int n, ZoneOffset ignored) {
-        OffsetTime a = OffsetTime.of(LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(h, m, s, n), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(h, m, s, n, OFFSET_PONE);
         assertEquals(a.equals(b), true);
         assertEquals(a.hashCode() == b.hashCode(), true);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_hour_differs(int h, int m, int s, int n, ZoneOffset ignored) {
         h = (h == 23 ? 22 : h);
-        OffsetTime a = OffsetTime.of(LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(h + 1, m, s, n), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(h + 1, m, s, n, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_minute_differs(int h, int m, int s, int n, ZoneOffset ignored) {
         m = (m == 59 ? 58 : m);
-        OffsetTime a = OffsetTime.of(LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(h, m + 1, s, n), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(h, m + 1, s, n, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_second_differs(int h, int m, int s, int n, ZoneOffset ignored) {
         s = (s == 59 ? 58 : s);
-        OffsetTime a = OffsetTime.of(LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(h, m, s + 1, n), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(h, m, s + 1, n, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_nano_differs(int h, int m, int s, int n, ZoneOffset ignored) {
         n = (n == 999999999 ? 999999998 : n);
-        OffsetTime a = OffsetTime.of(LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(h, m, s, n + 1), OFFSET_PONE);
+        OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(h, m, s, n + 1, OFFSET_PONE);
         assertEquals(a.equals(b), false);
     }
     @Test(dataProvider="sampleTimes", groups={"tck"})
     public void test_equals_false_offset_differs(int h, int m, int s, int n, ZoneOffset ignored) {
-        OffsetTime a = OffsetTime.of(LocalTime.of(h, m, s, n), OFFSET_PONE);
-        OffsetTime b = OffsetTime.of(LocalTime.of(h, m, s, n), OFFSET_PTWO);
+        OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
+        OffsetTime b = OffsetTime.of(h, m, s, n, OFFSET_PTWO);
         assertEquals(a.equals(b), false);
     }
 
@@ -1302,7 +1274,7 @@
 
     @Test(dataProvider="sampleToString", groups={"tck"})
     public void test_toString(int h, int m, int s, int n, String offsetId, String expected) {
-        OffsetTime t = OffsetTime.of(LocalTime.of(h, m, s, n), ZoneOffset.of(offsetId));
+        OffsetTime t = OffsetTime.of(h, m, s, n, ZoneOffset.of(offsetId));
         String str = t.toString();
         assertEquals(str, expected);
     }
@@ -1312,14 +1284,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("H m s");
-        String t = OffsetTime.of(LocalTime.of(11, 30), OFFSET_PONE).toString(f);
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
+        String t = OffsetTime.of(11, 30, 0, 0, OFFSET_PONE).toString(f);
         assertEquals(t, "11 30 0");
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_toString_formatter_null() {
-        OffsetTime.of(LocalTime.of(11, 30), OFFSET_PONE).toString(null);
+        OffsetTime.of(11, 30, 0, 0, OFFSET_PONE).toString(null);
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/TCKPeriod.java b/jdk/test/java/time/tck/java/time/TCKPeriod.java
new file mode 100644
index 0000000..7399b50
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/TCKPeriod.java
@@ -0,0 +1,906 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time;
+
+import static org.testng.Assert.assertEquals;
+
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.Period;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalUnit;
+import java.util.List;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test Period.
+ */
+@Test
+public class TCKPeriod extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(Period.ZERO);
+        assertSerializable(Period.ofDays(1));
+        assertSerializable(Period.of(1, 2, 3));
+    }
+
+    //-----------------------------------------------------------------------
+    // ofYears(int)
+    //-----------------------------------------------------------------------
+    @Test
+    public void factory_ofYears_int() {
+        assertPeriod(Period.ofYears(0), 0, 0, 0);
+        assertPeriod(Period.ofYears(1), 1, 0, 0);
+        assertPeriod(Period.ofYears(234), 234, 0, 0);
+        assertPeriod(Period.ofYears(-100), -100, 0, 0);
+        assertPeriod(Period.ofYears(Integer.MAX_VALUE), Integer.MAX_VALUE, 0, 0);
+        assertPeriod(Period.ofYears(Integer.MIN_VALUE), Integer.MIN_VALUE, 0, 0);
+    }
+
+    //-----------------------------------------------------------------------
+    // ofMonths(int)
+    //-----------------------------------------------------------------------
+    @Test
+    public void factory_ofMonths_int() {
+        assertPeriod(Period.ofMonths(0), 0, 0, 0);
+        assertPeriod(Period.ofMonths(1), 0, 1, 0);
+        assertPeriod(Period.ofMonths(234), 0, 234, 0);
+        assertPeriod(Period.ofMonths(-100), 0, -100, 0);
+        assertPeriod(Period.ofMonths(Integer.MAX_VALUE), 0, Integer.MAX_VALUE, 0);
+        assertPeriod(Period.ofMonths(Integer.MIN_VALUE), 0, Integer.MIN_VALUE, 0);
+    }
+
+    //-----------------------------------------------------------------------
+    // ofDays(int)
+    //-----------------------------------------------------------------------
+    @Test
+    public void factory_ofDay_int() {
+        assertPeriod(Period.ofDays(0), 0, 0, 0);
+        assertPeriod(Period.ofDays(1), 0, 0, 1);
+        assertPeriod(Period.ofDays(234), 0, 0, 234);
+        assertPeriod(Period.ofDays(-100), 0, 0, -100);
+        assertPeriod(Period.ofDays(Integer.MAX_VALUE), 0, 0, Integer.MAX_VALUE);
+        assertPeriod(Period.ofDays(Integer.MIN_VALUE), 0, 0, Integer.MIN_VALUE);
+    }
+
+    //-----------------------------------------------------------------------
+    // of(int3)
+    //-----------------------------------------------------------------------
+    @Test
+    public void factory_of_ints() {
+        assertPeriod(Period.of(1, 2, 3), 1, 2, 3);
+        assertPeriod(Period.of(0, 2, 3), 0, 2, 3);
+        assertPeriod(Period.of(1, 0, 0), 1, 0, 0);
+        assertPeriod(Period.of(0, 0, 0), 0, 0, 0);
+        assertPeriod(Period.of(-1, -2, -3), -1, -2, -3);
+    }
+
+    //-----------------------------------------------------------------------
+    // parse(String)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="parseSuccess")
+    Object[][] data_factory_parseSuccess() {
+        return new Object[][] {
+                {"P1Y", Period.ofYears(1)},
+                {"P12Y", Period.ofYears(12)},
+                {"P987654321Y", Period.ofYears(987654321)},
+                {"P+1Y", Period.ofYears(1)},
+                {"P+12Y", Period.ofYears(12)},
+                {"P+987654321Y", Period.ofYears(987654321)},
+                {"P+0Y", Period.ofYears(0)},
+                {"P0Y", Period.ofYears(0)},
+                {"P-0Y", Period.ofYears(0)},
+                {"P-25Y", Period.ofYears(-25)},
+                {"P-987654321Y", Period.ofYears(-987654321)},
+                {"P" + Integer.MAX_VALUE + "Y", Period.ofYears(Integer.MAX_VALUE)},
+                {"P" + Integer.MIN_VALUE + "Y", Period.ofYears(Integer.MIN_VALUE)},
+
+                {"P1M", Period.ofMonths(1)},
+                {"P12M", Period.ofMonths(12)},
+                {"P987654321M", Period.ofMonths(987654321)},
+                {"P+1M", Period.ofMonths(1)},
+                {"P+12M", Period.ofMonths(12)},
+                {"P+987654321M", Period.ofMonths(987654321)},
+                {"P+0M", Period.ofMonths(0)},
+                {"P0M", Period.ofMonths(0)},
+                {"P-0M", Period.ofMonths(0)},
+                {"P-25M", Period.ofMonths(-25)},
+                {"P-987654321M", Period.ofMonths(-987654321)},
+                {"P" + Integer.MAX_VALUE + "M", Period.ofMonths(Integer.MAX_VALUE)},
+                {"P" + Integer.MIN_VALUE + "M", Period.ofMonths(Integer.MIN_VALUE)},
+
+                {"P1D", Period.ofDays(1)},
+                {"P12D", Period.ofDays(12)},
+                {"P987654321D", Period.ofDays(987654321)},
+                {"P+1D", Period.ofDays(1)},
+                {"P+12D", Period.ofDays(12)},
+                {"P+987654321D", Period.ofDays(987654321)},
+                {"P+0D", Period.ofDays(0)},
+                {"P0D", Period.ofDays(0)},
+                {"P-0D", Period.ofDays(0)},
+                {"P-25D", Period.ofDays(-25)},
+                {"P-987654321D", Period.ofDays(-987654321)},
+                {"P" + Integer.MAX_VALUE + "D", Period.ofDays(Integer.MAX_VALUE)},
+                {"P" + Integer.MIN_VALUE + "D", Period.ofDays(Integer.MIN_VALUE)},
+
+                {"P0Y0M0D", Period.of(0, 0, 0)},
+                {"P2Y0M0D", Period.of(2, 0, 0)},
+                {"P0Y3M0D", Period.of(0, 3, 0)},
+                {"P0Y0M4D", Period.of(0, 0, 4)},
+                {"P2Y3M25D", Period.of(2, 3, 25)},
+                {"P-2Y3M25D", Period.of(-2, 3, 25)},
+                {"P2Y-3M25D", Period.of(2, -3, 25)},
+                {"P2Y3M-25D", Period.of(2, 3, -25)},
+                {"P-2Y-3M-25D", Period.of(-2, -3, -25)},
+        };
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void factory_parse(String text, Period expected) {
+        Period p = Period.parse(text);
+        assertEquals(p, expected);
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void factory_parse_plus(String text, Period expected) {
+        Period p = Period.parse("+" + text);
+        assertEquals(p, expected);
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void factory_parse_minus(String text, Period expected) {
+        Period p = null;
+        try {
+            p = Period.parse("-" + text);
+        } catch (DateTimeParseException ex) {
+            assertEquals(expected.getYears() == Integer.MIN_VALUE ||
+                    expected.getMonths() == Integer.MIN_VALUE ||
+                    expected.getDays() == Integer.MIN_VALUE, true);
+            return;
+        }
+        // not inside try/catch or it breaks test
+        assertEquals(p, expected.negated());
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void factory_parse_lowerCase(String text, Period expected) {
+        Period p = Period.parse(text.toLowerCase(Locale.ENGLISH));
+        assertEquals(p, expected);
+    }
+
+    @DataProvider(name="parseFailure")
+    Object[][] data_parseFailure() {
+        return new Object[][] {
+                {""},
+                {"PTD"},
+                {"AT0D"},
+                {"PA0D"},
+                {"PT0A"},
+
+                {"PT+D"},
+                {"PT-D"},
+                {"PT.D"},
+                {"PTAD"},
+
+                {"PT+0D"},
+                {"PT-0D"},
+                {"PT+1D"},
+                {"PT-.D"},
+
+                {"P1Y1MT1D"},
+                {"P1YMD"},
+                {"P1Y2Y"},
+                {"PT1M+3S"},
+
+                {"PT1S1"},
+                {"PT1S."},
+                {"PT1SA"},
+                {"PT1M1"},
+                {"PT1M."},
+                {"PT1MA"},
+
+                {"P"+ (((long) Integer.MAX_VALUE) + 1) + "Y"},
+                {"P"+ (((long) Integer.MAX_VALUE) + 1) + "M"},
+                {"P"+ (((long) Integer.MAX_VALUE) + 1) + "D"},
+                {"P"+ (((long) Integer.MIN_VALUE) - 1) + "Y"},
+                {"P"+ (((long) Integer.MIN_VALUE) - 1) + "M"},
+                {"P"+ (((long) Integer.MIN_VALUE) - 1) + "D"},
+
+                {"Rubbish"},
+        };
+    }
+
+    @Test(dataProvider="parseFailure", expectedExceptions=DateTimeParseException.class)
+    public void factory_parseFailures(String text) {
+        try {
+            Period.parse(text);
+        } catch (DateTimeParseException ex) {
+            assertEquals(ex.getParsedString(), text);
+            throw ex;
+        }
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void factory_parse_null() {
+        Period.parse(null);
+    }
+
+    //-----------------------------------------------------------------------
+    // between(LocalDate,LocalDate)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="between")
+    Object[][] data_between() {
+        return new Object[][] {
+                {2010, 1, 1, 2010, 1, 1, 0, 0, 0},
+                {2010, 1, 1, 2010, 1, 2, 0, 0, 1},
+                {2010, 1, 1, 2010, 1, 31, 0, 0, 30},
+                {2010, 1, 1, 2010, 2, 1, 0, 1, 0},
+                {2010, 1, 1, 2010, 2, 28, 0, 1, 27},
+                {2010, 1, 1, 2010, 3, 1, 0, 2, 0},
+                {2010, 1, 1, 2010, 12, 31, 0, 11, 30},
+                {2010, 1, 1, 2011, 1, 1, 1, 0, 0},
+                {2010, 1, 1, 2011, 12, 31, 1, 11, 30},
+                {2010, 1, 1, 2012, 1, 1, 2, 0, 0},
+
+                {2010, 1, 10, 2010, 1, 1, 0, 0, -9},
+                {2010, 1, 10, 2010, 1, 2, 0, 0, -8},
+                {2010, 1, 10, 2010, 1, 9, 0, 0, -1},
+                {2010, 1, 10, 2010, 1, 10, 0, 0, 0},
+                {2010, 1, 10, 2010, 1, 11, 0, 0, 1},
+                {2010, 1, 10, 2010, 1, 31, 0, 0, 21},
+                {2010, 1, 10, 2010, 2, 1, 0, 0, 22},
+                {2010, 1, 10, 2010, 2, 9, 0, 0, 30},
+                {2010, 1, 10, 2010, 2, 10, 0, 1, 0},
+                {2010, 1, 10, 2010, 2, 28, 0, 1, 18},
+                {2010, 1, 10, 2010, 3, 1, 0, 1, 19},
+                {2010, 1, 10, 2010, 3, 9, 0, 1, 27},
+                {2010, 1, 10, 2010, 3, 10, 0, 2, 0},
+                {2010, 1, 10, 2010, 12, 31, 0, 11, 21},
+                {2010, 1, 10, 2011, 1, 1, 0, 11, 22},
+                {2010, 1, 10, 2011, 1, 9, 0, 11, 30},
+                {2010, 1, 10, 2011, 1, 10, 1, 0, 0},
+
+                {2010, 3, 30, 2011, 5, 1, 1, 1, 1},
+                {2010, 4, 30, 2011, 5, 1, 1, 0, 1},
+
+                {2010, 2, 28, 2012, 2, 27, 1, 11, 30},
+                {2010, 2, 28, 2012, 2, 28, 2, 0, 0},
+                {2010, 2, 28, 2012, 2, 29, 2, 0, 1},
+
+                {2012, 2, 28, 2014, 2, 27, 1, 11, 30},
+                {2012, 2, 28, 2014, 2, 28, 2, 0, 0},
+                {2012, 2, 28, 2014, 3, 1, 2, 0, 1},
+
+                {2012, 2, 29, 2014, 2, 28, 1, 11, 30},
+                {2012, 2, 29, 2014, 3, 1, 2, 0, 1},
+                {2012, 2, 29, 2014, 3, 2, 2, 0, 2},
+
+                {2012, 2, 29, 2016, 2, 28, 3, 11, 30},
+                {2012, 2, 29, 2016, 2, 29, 4, 0, 0},
+                {2012, 2, 29, 2016, 3, 1, 4, 0, 1},
+
+                {2010, 1, 1, 2009, 12, 31, 0, 0, -1},
+                {2010, 1, 1, 2009, 12, 30, 0, 0, -2},
+                {2010, 1, 1, 2009, 12, 2, 0, 0, -30},
+                {2010, 1, 1, 2009, 12, 1, 0, -1, 0},
+                {2010, 1, 1, 2009, 11, 30, 0, -1, -1},
+                {2010, 1, 1, 2009, 11, 2, 0, -1, -29},
+                {2010, 1, 1, 2009, 11, 1, 0, -2, 0},
+                {2010, 1, 1, 2009, 1, 2, 0, -11, -30},
+                {2010, 1, 1, 2009, 1, 1, -1, 0, 0},
+
+                {2010, 1, 15, 2010, 1, 15, 0, 0, 0},
+                {2010, 1, 15, 2010, 1, 14, 0, 0, -1},
+                {2010, 1, 15, 2010, 1, 1, 0, 0, -14},
+                {2010, 1, 15, 2009, 12, 31, 0, 0, -15},
+                {2010, 1, 15, 2009, 12, 16, 0, 0, -30},
+                {2010, 1, 15, 2009, 12, 15, 0, -1, 0},
+                {2010, 1, 15, 2009, 12, 14, 0, -1, -1},
+
+                {2010, 2, 28, 2009, 3, 1, 0, -11, -27},
+                {2010, 2, 28, 2009, 2, 28, -1, 0, 0},
+                {2010, 2, 28, 2009, 2, 27, -1, 0, -1},
+
+                {2010, 2, 28, 2008, 2, 29, -1, -11, -28},
+                {2010, 2, 28, 2008, 2, 28, -2, 0, 0},
+                {2010, 2, 28, 2008, 2, 27, -2, 0, -1},
+
+                {2012, 2, 29, 2009, 3, 1, -2, -11, -28},
+                {2012, 2, 29, 2009, 2, 28, -3, 0, -1},
+                {2012, 2, 29, 2009, 2, 27, -3, 0, -2},
+
+                {2012, 2, 29, 2008, 3, 1, -3, -11, -28},
+                {2012, 2, 29, 2008, 2, 29, -4, 0, 0},
+                {2012, 2, 29, 2008, 2, 28, -4, 0, -1},
+        };
+    }
+
+    @Test(dataProvider="between")
+    public void factory_between_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
+        LocalDate start = LocalDate.of(y1, m1, d1);
+        LocalDate end = LocalDate.of(y2, m2, d2);
+        Period test = Period.between(start, end);
+        assertPeriod(test, ye, me, de);
+        //assertEquals(start.plus(test), end);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void factory_between_LocalDate_nullFirst() {
+        Period.between((LocalDate) null, LocalDate.of(2010, 1, 1));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void factory_between_LocalDate_nullSecond() {
+        Period.between(LocalDate.of(2010, 1, 1), (LocalDate) null);
+    }
+
+    //-----------------------------------------------------------------------
+    // isZero()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_isZero() {
+        assertEquals(Period.of(0, 0, 0).isZero(), true);
+        assertEquals(Period.of(1, 2, 3).isZero(), false);
+        assertEquals(Period.of(1, 0, 0).isZero(), false);
+        assertEquals(Period.of(0, 2, 0).isZero(), false);
+        assertEquals(Period.of(0, 0, 3).isZero(), false);
+    }
+
+    //-----------------------------------------------------------------------
+    // isNegative()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_isPositive() {
+        assertEquals(Period.of(0, 0, 0).isNegative(), false);
+        assertEquals(Period.of(1, 2, 3).isNegative(), false);
+        assertEquals(Period.of(1, 0, 0).isNegative(), false);
+        assertEquals(Period.of(0, 2, 0).isNegative(), false);
+        assertEquals(Period.of(0, 0, 3).isNegative(), false);
+
+        assertEquals(Period.of(-1, -2, -3).isNegative(), true);
+        assertEquals(Period.of(-1, -2, 3).isNegative(), true);
+        assertEquals(Period.of(1, -2, -3).isNegative(), true);
+        assertEquals(Period.of(-1, 2, -3).isNegative(), true);
+        assertEquals(Period.of(-1, 2, 3).isNegative(), true);
+        assertEquals(Period.of(1, -2, 3).isNegative(), true);
+        assertEquals(Period.of(1, 2, -3).isNegative(), true);
+    }
+
+    //-----------------------------------------------------------------------
+    // withYears()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_withYears() {
+        assertPeriod(Period.of(1, 2, 3).withYears(1), 1, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).withYears(10), 10, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).withYears(-10), -10, 2, 3);
+        assertPeriod(Period.of(-1, -2, -3).withYears(10), 10, -2, -3);
+        assertPeriod(Period.of(1, 2, 3).withYears(0), 0, 2, 3);
+    }
+
+    //-----------------------------------------------------------------------
+    // withMonths()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_withMonths() {
+        assertPeriod(Period.of(1, 2, 3).withMonths(2), 1, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).withMonths(10), 1, 10, 3);
+        assertPeriod(Period.of(1, 2, 3).withMonths(-10), 1, -10, 3);
+        assertPeriod(Period.of(-1, -2, -3).withMonths(10), -1, 10, -3);
+        assertPeriod(Period.of(1, 2, 3).withMonths(0), 1, 0, 3);
+    }
+
+    //-----------------------------------------------------------------------
+    // withDays()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_withDays() {
+        assertPeriod(Period.of(1, 2, 3).withDays(3), 1, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).withDays(10), 1, 2, 10);
+        assertPeriod(Period.of(1, 2, 3).withDays(-10), 1, 2, -10);
+        assertPeriod(Period.of(-1, -2, -3).withDays(10), -1, -2, 10);
+        assertPeriod(Period.of(1, 2, 3).withDays(0), 1, 2, 0);
+    }
+
+    //-----------------------------------------------------------------------
+    // plusYears()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_plusYears() {
+        assertPeriod(Period.of(1, 2, 3).plusYears(0), 1, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).plusYears(10), 11, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).plusYears(-10), -9, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).plusYears(-1), 0, 2, 3);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_plusYears_overflowTooBig() {
+        Period test = Period.ofYears(Integer.MAX_VALUE);
+        test.plusYears(1);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_plusYears_overflowTooSmall() {
+        Period test = Period.ofYears(Integer.MIN_VALUE);
+        test.plusYears(-1);
+    }
+
+    //-----------------------------------------------------------------------
+    // plusMonths()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_plusMonths() {
+        assertPeriod(Period.of(1, 2, 3).plusMonths(0), 1, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).plusMonths(10), 1, 12, 3);
+        assertPeriod(Period.of(1, 2, 3).plusMonths(-10), 1, -8, 3);
+        assertPeriod(Period.of(1, 2, 3).plusMonths(-2), 1, 0, 3);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_plusMonths_overflowTooBig() {
+        Period test = Period.ofMonths(Integer.MAX_VALUE);
+        test.plusMonths(1);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_plusMonths_overflowTooSmall() {
+        Period test = Period.ofMonths(Integer.MIN_VALUE);
+        test.plusMonths(-1);
+    }
+
+    //-----------------------------------------------------------------------
+    // plusDays()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_plusDays() {
+        assertPeriod(Period.of(1, 2, 3).plusDays(0), 1, 2, 3);
+        assertPeriod(Period.of(1, 2, 3).plusDays(10), 1, 2, 13);
+        assertPeriod(Period.of(1, 2, 3).plusDays(-10), 1, 2, -7);
+        assertPeriod(Period.of(1, 2, 3).plusDays(-3), 1, 2, 0);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_plusDays_overflowTooBig() {
+        Period test = Period.ofDays(Integer.MAX_VALUE);
+        test.plusDays(1);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_plusDays_overflowTooSmall() {
+        Period test = Period.ofDays(Integer.MIN_VALUE);
+        test.plusDays(-1);
+    }
+
+    //-----------------------------------------------------------------------
+    // multipliedBy()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_multipliedBy() {
+        Period test = Period.of(1, 2, 3);
+        assertPeriod(test.multipliedBy(0), 0, 0, 0);
+        assertPeriod(test.multipliedBy(1), 1, 2, 3);
+        assertPeriod(test.multipliedBy(2), 2, 4, 6);
+        assertPeriod(test.multipliedBy(-3), -3, -6, -9);
+    }
+
+    @Test
+    public void test_multipliedBy_zeroBase() {
+        assertPeriod(Period.ZERO.multipliedBy(2), 0, 0, 0);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_multipliedBy_overflowTooBig() {
+        Period test = Period.ofYears(Integer.MAX_VALUE / 2 + 1);
+        test.multipliedBy(2);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_multipliedBy_overflowTooSmall() {
+        Period test = Period.ofYears(Integer.MIN_VALUE / 2 - 1);
+        test.multipliedBy(2);
+    }
+
+    //-----------------------------------------------------------------------
+    // negated()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_negated() {
+        assertPeriod(Period.of(0, 0, 0).negated(), 0 ,0, 0);
+        assertPeriod(Period.of(1, 2, 3).negated(), -1, -2, -3);
+        assertPeriod(Period.of(-1, -2, -3).negated(), 1, 2, 3);
+        assertPeriod(Period.of(-1, 2, -3).negated(), 1, -2, 3);
+        assertPeriod(Period.of(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).negated(),
+                -Integer.MAX_VALUE, -Integer.MAX_VALUE, -Integer.MAX_VALUE);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_negated_overflow_years() {
+        Period.ofYears(Integer.MIN_VALUE).negated();
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_negated_overflow_months() {
+        Period.ofMonths(Integer.MIN_VALUE).negated();
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_negated_overflow_days() {
+        Period.ofDays(Integer.MIN_VALUE).negated();
+    }
+
+    //-----------------------------------------------------------------------
+    // normalized()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="normalized")
+    Object[][] data_normalized() {
+        return new Object[][] {
+                {0, 0,  0, 0},
+                {1, 0,  1, 0},
+                {-1, 0,  -1, 0},
+
+                {1, 1,  1, 1},
+                {1, 2,  1, 2},
+                {1, 11,  1, 11},
+                {1, 12,  2, 0},
+                {1, 13,  2, 1},
+                {1, 23,  2, 11},
+                {1, 24,  3, 0},
+                {1, 25,  3, 1},
+
+                {1, -1,  0, 11},
+                {1, -2,  0, 10},
+                {1, -11,  0, 1},
+                {1, -12,  0, 0},
+                {1, -13,  0, -1},
+                {1, -23,  0, -11},
+                {1, -24,  -1, 0},
+                {1, -25,  -1, -1},
+                {1, -35,  -1, -11},
+                {1, -36,  -2, 0},
+                {1, -37,  -2, -1},
+
+                {-1, 1,  0, -11},
+                {-1, 11,  0, -1},
+                {-1, 12,  0, 0},
+                {-1, 13,  0, 1},
+                {-1, 23,  0, 11},
+                {-1, 24,  1, 0},
+                {-1, 25,  1, 1},
+
+                {-1, -1,  -1, -1},
+                {-1, -11,  -1, -11},
+                {-1, -12,  -2, 0},
+                {-1, -13,  -2, -1},
+        };
+    }
+
+    @Test(dataProvider="normalized")
+    public void test_normalized(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
+        assertPeriod(Period.of(inputYears, inputMonths, 0).normalized(), expectedYears, expectedMonths, 0);
+    }
+
+    @Test(dataProvider="normalized")
+    public void test_normalized_daysUnaffected(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
+        assertPeriod(Period.of(inputYears, inputMonths, 5).normalized(), expectedYears, expectedMonths, 5);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_normalized_min() {
+        Period base = Period.of(Integer.MIN_VALUE, -12, 0);
+        base.normalized();
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_normalized_max() {
+        Period base = Period.of(Integer.MAX_VALUE, 12, 0);
+        base.normalized();
+    }
+
+    //-----------------------------------------------------------------------
+    // addTo()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="addTo")
+    Object[][] data_addTo() {
+        return new Object[][] {
+                {pymd(0, 0, 0),  date(2012, 6, 30), date(2012, 6, 30)},
+
+                {pymd(1, 0, 0),  date(2012, 6, 10), date(2013, 6, 10)},
+                {pymd(0, 1, 0),  date(2012, 6, 10), date(2012, 7, 10)},
+                {pymd(0, 0, 1),  date(2012, 6, 10), date(2012, 6, 11)},
+
+                {pymd(-1, 0, 0),  date(2012, 6, 10), date(2011, 6, 10)},
+                {pymd(0, -1, 0),  date(2012, 6, 10), date(2012, 5, 10)},
+                {pymd(0, 0, -1),  date(2012, 6, 10), date(2012, 6, 9)},
+
+                {pymd(1, 2, 3),  date(2012, 6, 27), date(2013, 8, 30)},
+                {pymd(1, 2, 3),  date(2012, 6, 28), date(2013, 8, 31)},
+                {pymd(1, 2, 3),  date(2012, 6, 29), date(2013, 9, 1)},
+                {pymd(1, 2, 3),  date(2012, 6, 30), date(2013, 9, 2)},
+                {pymd(1, 2, 3),  date(2012, 7, 1), date(2013, 9, 4)},
+
+                {pymd(1, 0, 0),  date(2011, 2, 28), date(2012, 2, 28)},
+                {pymd(4, 0, 0),  date(2011, 2, 28), date(2015, 2, 28)},
+                {pymd(1, 0, 0),  date(2012, 2, 29), date(2013, 2, 28)},
+                {pymd(4, 0, 0),  date(2012, 2, 29), date(2016, 2, 29)},
+
+                {pymd(1, 1, 0),  date(2011, 1, 29), date(2012, 2, 29)},
+                {pymd(1, 2, 0),  date(2012, 2, 29), date(2013, 4, 29)},
+        };
+    }
+
+    @Test(dataProvider="addTo")
+    public void test_addTo(Period period, LocalDate baseDate, LocalDate expected) {
+        assertEquals(period.addTo(baseDate), expected);
+    }
+
+    @Test(dataProvider="addTo")
+    public void test_addTo_usingLocalDatePlus(Period period, LocalDate baseDate, LocalDate expected) {
+        assertEquals(baseDate.plus(period), expected);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_addTo_nullZero() {
+        Period.ZERO.addTo(null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_addTo_nullNonZero() {
+        Period.ofDays(2).addTo(null);
+    }
+
+    //-----------------------------------------------------------------------
+    // subtractFrom()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="subtractFrom")
+    Object[][] data_subtractFrom() {
+        return new Object[][] {
+                {pymd(0, 0, 0), date(2012, 6, 30), date(2012, 6, 30)},
+
+                {pymd(1, 0, 0), date(2012, 6, 10), date(2011, 6, 10)},
+                {pymd(0, 1, 0), date(2012, 6, 10), date(2012, 5, 10)},
+                {pymd(0, 0, 1), date(2012, 6, 10), date(2012, 6, 9)},
+
+                {pymd(-1, 0, 0), date(2012, 6, 10), date(2013, 6, 10)},
+                {pymd(0, -1, 0), date(2012, 6, 10), date(2012, 7, 10)},
+                {pymd(0, 0, -1), date(2012, 6, 10), date(2012, 6, 11)},
+
+                {pymd(1, 2, 3), date(2012, 8, 30), date(2011, 6, 27)},
+                {pymd(1, 2, 3), date(2012, 8, 31), date(2011, 6, 27)},
+                {pymd(1, 2, 3), date(2012, 9, 1), date(2011, 6, 28)},
+                {pymd(1, 2, 3), date(2012, 9, 2), date(2011, 6, 29)},
+                {pymd(1, 2, 3), date(2012, 9, 3), date(2011, 6, 30)},
+                {pymd(1, 2, 3), date(2012, 9, 4), date(2011, 7, 1)},
+
+                {pymd(1, 0, 0), date(2011, 2, 28), date(2010, 2, 28)},
+                {pymd(4, 0, 0), date(2011, 2, 28), date(2007, 2, 28)},
+                {pymd(1, 0, 0), date(2012, 2, 29), date(2011, 2, 28)},
+                {pymd(4, 0, 0), date(2012, 2, 29), date(2008, 2, 29)},
+
+                {pymd(1, 1, 0), date(2013, 3, 29), date(2012, 2, 29)},
+                {pymd(1, 2, 0), date(2012, 2, 29), date(2010, 12, 29)},
+        };
+    }
+
+    @Test(dataProvider="subtractFrom")
+    public void test_subtractFrom(Period period, LocalDate baseDate, LocalDate expected) {
+        assertEquals(period.subtractFrom(baseDate), expected);
+    }
+
+    @Test(dataProvider="subtractFrom")
+    public void test_subtractFrom_usingLocalDateMinus(Period period, LocalDate baseDate, LocalDate expected) {
+        assertEquals(baseDate.minus(period), expected);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_subtractFrom_nullZero() {
+        Period.ZERO.subtractFrom(null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_subtractFrom_nullNonZero() {
+        Period.ofDays(2).subtractFrom(null);
+    }
+
+    //-----------------------------------------------------------------------
+    // get units
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_Period_getUnits() {
+        Period period = Period.of(2012, 1, 1);
+        List<TemporalUnit> units = period.getUnits();
+        assertEquals(units.size(), 3, "Period.getUnits should return 3 units");
+        assertEquals(units.get(0), ChronoUnit.YEARS, "Period.getUnits contains ChronoUnit.YEARS");
+        assertEquals(units.get(1), ChronoUnit.MONTHS, "Period.getUnits contains ChronoUnit.MONTHS");
+        assertEquals(units.get(2), ChronoUnit.DAYS, "Period.getUnits contains ChronoUnit.DAYS");
+    }
+
+
+    @DataProvider(name="GoodTemporalUnit")
+    Object[][] data_goodTemporalUnit() {
+        return new Object[][] {
+            {2, ChronoUnit.DAYS},
+            {2, ChronoUnit.MONTHS},
+            {2, ChronoUnit.YEARS},
+        };
+    }
+
+    @Test(dataProvider="GoodTemporalUnit")
+    public void test_good_getUnit(long amount, TemporalUnit unit) {
+        Period period = Period.of(2, 2, 2);
+        long actual = period.get(unit);
+        assertEquals(actual, amount, "Value of unit: " + unit);
+    }
+
+    @DataProvider(name="BadTemporalUnit")
+    Object[][] data_badTemporalUnit() {
+        return new Object[][] {
+            {ChronoUnit.MICROS},
+            {ChronoUnit.MILLIS},
+            {ChronoUnit.HALF_DAYS},
+            {ChronoUnit.DECADES},
+            {ChronoUnit.CENTURIES},
+            {ChronoUnit.MILLENNIA},
+        };
+    }
+
+    @Test(dataProvider="BadTemporalUnit", expectedExceptions=DateTimeException.class)
+    public void test_bad_getUnit(TemporalUnit unit) {
+        Period period = Period.of(2, 2, 2);
+        period.get(unit);
+    }
+
+    //-----------------------------------------------------------------------
+    // equals() / hashCode()
+    //-----------------------------------------------------------------------
+    public void test_equals() {
+        assertEquals(Period.of(1, 0, 0).equals(Period.ofYears(1)), true);
+        assertEquals(Period.of(0, 1, 0).equals(Period.ofMonths(1)), true);
+        assertEquals(Period.of(0, 0, 1).equals(Period.ofDays(1)), true);
+        assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 2, 3)), true);
+
+        assertEquals(Period.ofYears(1).equals(Period.ofYears(1)), true);
+        assertEquals(Period.ofYears(1).equals(Period.ofYears(2)), false);
+
+        assertEquals(Period.ofMonths(1).equals(Period.ofMonths(1)), true);
+        assertEquals(Period.ofMonths(1).equals(Period.ofMonths(2)), false);
+
+        assertEquals(Period.ofDays(1).equals(Period.ofDays(1)), true);
+        assertEquals(Period.ofDays(1).equals(Period.ofDays(2)), false);
+
+        assertEquals(Period.of(1, 2, 3).equals(Period.of(0, 2, 3)), false);
+        assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 0, 3)), false);
+        assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 2, 0)), false);
+    }
+
+    public void test_equals_self() {
+        Period test = Period.of(1, 2, 3);
+        assertEquals(test.equals(test), true);
+    }
+
+    public void test_equals_null() {
+        Period test = Period.of(1, 2, 3);
+        assertEquals(test.equals(null), false);
+    }
+
+    public void test_equals_otherClass() {
+        Period test = Period.of(1, 2, 3);
+        assertEquals(test.equals(""), false);
+    }
+
+    //-----------------------------------------------------------------------
+    public void test_hashCode() {
+        Period test5 = Period.ofDays(5);
+        Period test6 = Period.ofDays(6);
+        Period test5M = Period.ofMonths(5);
+        Period test5Y = Period.ofYears(5);
+        assertEquals(test5.hashCode() == test5.hashCode(), true);
+        assertEquals(test5.hashCode() == test6.hashCode(), false);
+    }
+
+    //-----------------------------------------------------------------------
+    // toString()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toStringAndParse")
+    Object[][] data_toString() {
+        return new Object[][] {
+                {Period.ZERO, "P0D"},
+                {Period.ofDays(0), "P0D"},
+                {Period.ofYears(1), "P1Y"},
+                {Period.ofMonths(1), "P1M"},
+                {Period.ofDays(1), "P1D"},
+                {Period.of(1, 2, 0), "P1Y2M"},
+                {Period.of(0, 2, 3), "P2M3D"},
+                {Period.of(1, 2, 3), "P1Y2M3D"},
+        };
+    }
+
+    @Test(dataProvider="toStringAndParse")
+    public void test_toString(Period input, String expected) {
+        assertEquals(input.toString(), expected);
+    }
+
+    @Test(dataProvider="toStringAndParse")
+    public void test_parse(Period test, String expected) {
+        assertEquals(Period.parse(expected), test);
+    }
+
+    //-----------------------------------------------------------------------
+    private void assertPeriod(Period test, int y, int m, int d) {
+        assertEquals(test.getYears(), y, "years");
+        assertEquals(test.getMonths(), m, "months");
+        assertEquals(test.getDays(), d, "days");
+        assertEquals(test.toTotalMonths(), y * 12L + m, "totalMonths");
+    }
+
+    private static Period pymd(int y, int m, int d) {
+        return Period.of(y, m, d);
+    }
+
+    private static LocalDate date(int y, int m, int d) {
+        return LocalDate.of(y, m, d);
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKYear.java b/jdk/test/java/time/tck/java/time/TCKYear.java
similarity index 89%
rename from jdk/test/java/time/tck/java/time/temporal/TCKYear.java
rename to jdk/test/java/time/tck/java/time/TCKYear.java
index 5464c6b..3f0e653 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKYear.java
+++ b/jdk/test/java/time/tck/java/time/TCKYear.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.temporal;
+package tck.java.time;
 
 import static java.time.temporal.ChronoField.ERA;
 import static java.time.temporal.ChronoField.YEAR;
@@ -67,36 +67,36 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.Month;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.Year;
+import java.time.YearMonth;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
 import java.time.temporal.JulianFields;
-import java.time.temporal.MonthDay;
-import java.time.temporal.OffsetDateTime;
+import java.time.temporal.Queries;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
-import java.time.temporal.Year;
-import java.time.temporal.YearMonth;
+import java.time.temporal.TemporalQuery;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import tck.java.time.AbstractDateTimeTest;
 
 /**
  * Test Year.
@@ -149,7 +149,7 @@
     public void test_serialization_format() throws Exception {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(4);
+            dos.writeByte(11);       // java.time.temporal.Ser.YEAR_TYPE
             dos.writeInt(2012);
         }
         byte[] bytes = baos.toByteArray();
@@ -317,14 +317,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y");
         Year test = Year.parse("2010", f);
         assertEquals(test, Year.of(2010));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y");
         Year.parse((String) null, f);
     }
 
@@ -351,6 +351,37 @@
     }
 
     //-----------------------------------------------------------------------
+    // query(TemporalQuery)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_2008, Queries.chronology(), IsoChronology.INSTANCE},
+                {TEST_2008, Queries.zoneId(), null},
+                {TEST_2008, Queries.precision(), ChronoUnit.YEARS},
+                {TEST_2008, Queries.zone(), null},
+                {TEST_2008, Queries.offset(), null},
+                {TEST_2008, Queries.localDate(), null},
+                {TEST_2008, Queries.localTime(), null},
+        };
+    }
+
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
+    }
+
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_query_null() {
+        TEST_2008.query(null);
+    }
+
+    //-----------------------------------------------------------------------
     // isLeap()
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
@@ -555,45 +586,35 @@
     }
 
     //-----------------------------------------------------------------------
-    // isValidMonthDay(Month)
+    // isValidMonthDay(MonthDay)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_isValidMonthDay_june() {
-        Year test = Year.of(2007);
-        MonthDay monthDay = MonthDay.of(6, 30);
-        assertEquals(test.isValidMonthDay(monthDay), true);
+    @DataProvider(name="isValidMonthDay")
+    Object[][] data_isValidMonthDay() {
+        return new Object[][] {
+                {Year.of(2007), MonthDay.of(6, 30), true},
+                {Year.of(2008), MonthDay.of(2, 28), true},
+                {Year.of(2008), MonthDay.of(2, 29), true},
+                {Year.of(2009), MonthDay.of(2, 28), true},
+                {Year.of(2009), MonthDay.of(2, 29), false},
+                {Year.of(2009), null, false},
+        };
     }
 
-    @Test(groups={"tck"})
-    public void test_isValidMonthDay_febNonLeap() {
-        Year test = Year.of(2007);
-        MonthDay monthDay = MonthDay.of(2, 29);
-        assertEquals(test.isValidMonthDay(monthDay), false);
-    }
-
-    @Test(groups={"tck"})
-    public void test_isValidMonthDay_febLeap() {
-        Year test = Year.of(2008);
-        MonthDay monthDay = MonthDay.of(2, 29);
-        assertEquals(test.isValidMonthDay(monthDay), true);
-    }
-
-    @Test(groups={"tck"})
-    public void test_isValidMonthDay_null() {
-        Year test = Year.of(2008);
-        assertEquals(test.isValidMonthDay(null), false);
+    @Test(dataProvider="isValidMonthDay")
+    public void test_isValidMonthDay(Year year, MonthDay monthDay, boolean expected) {
+        assertEquals(year.isValidMonthDay(monthDay), expected);
     }
 
     //-----------------------------------------------------------------------
     // atMonth(Month)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_atMonth() {
         Year test = Year.of(2008);
         assertEquals(test.atMonth(Month.JUNE), YearMonth.of(2008, 6));
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_atMonth_nullMonth() {
         Year test = Year.of(2008);
         test.atMonth((Month) null);
@@ -602,13 +623,13 @@
     //-----------------------------------------------------------------------
     // atMonth(int)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_atMonth_int() {
         Year test = Year.of(2008);
         assertEquals(test.atMonth(6), YearMonth.of(2008, 6));
     }
 
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
+    @Test(expectedExceptions=DateTimeException.class)
     public void test_atMonth_int_invalidMonth() {
         Year test = Year.of(2008);
         test.atMonth(13);
@@ -617,24 +638,26 @@
     //-----------------------------------------------------------------------
     // atMonthDay(Month)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_atMonthDay() {
-        Year test = Year.of(2008);
-        assertEquals(test.atMonthDay(MonthDay.of(6, 30)), LocalDate.of(2008, 6, 30));
+    @DataProvider(name="atMonthDay")
+    Object[][] data_atMonthDay() {
+        return new Object[][] {
+                {Year.of(2008), MonthDay.of(6, 30), LocalDate.of(2008, 6, 30)},
+                {Year.of(2008), MonthDay.of(2, 29), LocalDate.of(2008, 2, 29)},
+                {Year.of(2009), MonthDay.of(2, 29), LocalDate.of(2009, 2, 28)},
+        };
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(dataProvider="atMonthDay")
+    public void test_atMonthDay(Year year, MonthDay monthDay, LocalDate expected) {
+        assertEquals(year.atMonthDay(monthDay), expected);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_atMonthDay_nullMonthDay() {
         Year test = Year.of(2008);
         test.atMonthDay((MonthDay) null);
     }
 
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_atMonthDay_invalidMonthDay() {
-        Year test = Year.of(2008);
-        test.atMonthDay(MonthDay.of(6, 31));
-    }
-
     //-----------------------------------------------------------------------
     // atDay(int)
     //-----------------------------------------------------------------------
@@ -768,7 +791,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y");
         String t = Year.of(2010).toString(f);
         assertEquals(t, "2010");
     }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/TCKYearMonth.java
similarity index 89%
rename from jdk/test/java/time/tck/java/time/temporal/TCKYearMonth.java
rename to jdk/test/java/time/tck/java/time/TCKYearMonth.java
index 25d57f1..3369dac 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKYearMonth.java
+++ b/jdk/test/java/time/tck/java/time/TCKYearMonth.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.temporal;
+package tck.java.time;
 
 import static java.time.temporal.ChronoField.EPOCH_MONTH;
 import static java.time.temporal.ChronoField.ERA;
@@ -71,12 +71,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Instant;
@@ -84,22 +78,29 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Month;
+import java.time.Year;
+import java.time.YearMonth;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
 import java.time.temporal.JulianFields;
+import java.time.temporal.Queries;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
-import java.time.temporal.Year;
-import java.time.temporal.YearMonth;
+import java.time.temporal.TemporalQuery;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import tck.java.time.AbstractDateTimeTest;
 
 /**
  * Test YearMonth.
@@ -153,7 +154,7 @@
     public void test_serialization_format() throws Exception {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(5);
+            dos.writeByte(12);       // java.time.temporal.Ser.YEAR_MONTH_TYPE
             dos.writeInt(2012);
             dos.writeByte(9);
         }
@@ -378,14 +379,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M");
         YearMonth test = YearMonth.parse("2010 12", f);
         assertEquals(test, YearMonth.of(2010, 12));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M");
         YearMonth.parse((String) null, f);
     }
 
@@ -415,6 +416,37 @@
     }
 
     //-----------------------------------------------------------------------
+    // query(TemporalQuery)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {TEST_2008_06, Queries.chronology(), IsoChronology.INSTANCE},
+                {TEST_2008_06, Queries.zoneId(), null},
+                {TEST_2008_06, Queries.precision(), ChronoUnit.MONTHS},
+                {TEST_2008_06, Queries.zone(), null},
+                {TEST_2008_06, Queries.offset(), null},
+                {TEST_2008_06, Queries.localDate(), null},
+                {TEST_2008_06, Queries.localTime(), null},
+        };
+    }
+
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
+    }
+
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_query_null() {
+        TEST_2008_06.query(null);
+    }
+
+    //-----------------------------------------------------------------------
     // get*()
     //-----------------------------------------------------------------------
     @DataProvider(name="sampleDates")
@@ -427,6 +459,14 @@
         };
     }
 
+    @Test(dataProvider="sampleDates")
+    public void test_get(int y, int m) {
+        YearMonth a = YearMonth.of(y, m);
+        assertEquals(a.getYear(), y);
+        assertEquals(a.getMonth(), Month.of(m));
+        assertEquals(a.getMonthValue(), m);
+    }
+
     //-----------------------------------------------------------------------
     // with(Year)
     //-----------------------------------------------------------------------
@@ -870,16 +910,66 @@
     //-----------------------------------------------------------------------
     // atDay(int)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_atDay_int() {
-        YearMonth test = YearMonth.of(2008, 6);
-        assertEquals(test.atDay(30), LocalDate.of(2008, 6, 30));
+    @DataProvider(name="atDay")
+    Object[][] data_atDay() {
+        return new Object[][] {
+                {YearMonth.of(2008, 6), 8, LocalDate.of(2008, 6, 8)},
+
+                {YearMonth.of(2008, 1), 31, LocalDate.of(2008, 1, 31)},
+                {YearMonth.of(2008, 2), 29, LocalDate.of(2008, 2, 29)},
+                {YearMonth.of(2008, 3), 31, LocalDate.of(2008, 3, 31)},
+                {YearMonth.of(2008, 4), 30, LocalDate.of(2008, 4, 30)},
+
+                {YearMonth.of(2009, 1), 32, null},
+                {YearMonth.of(2009, 1), 0, null},
+                {YearMonth.of(2009, 2), 29, null},
+                {YearMonth.of(2009, 2), 30, null},
+                {YearMonth.of(2009, 2), 31, null},
+                {YearMonth.of(2009, 4), 31, null},
+        };
     }
 
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_atDay_int_invalidDay() {
-        YearMonth test = YearMonth.of(2008, 6);
-        test.atDay(31);
+    @Test(dataProvider="atDay")
+    public void test_atDay(YearMonth test, int day, LocalDate expected) {
+        if (expected != null) {
+            assertEquals(test.atDay(day), expected);
+        } else {
+            try {
+                test.atDay(day);
+                fail();
+            } catch (DateTimeException ex) {
+                // expected
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    // atEndOfMonth()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="atEndOfMonth")
+    Object[][] data_atEndOfMonth() {
+        return new Object[][] {
+                {YearMonth.of(2008, 1), LocalDate.of(2008, 1, 31)},
+                {YearMonth.of(2008, 2), LocalDate.of(2008, 2, 29)},
+                {YearMonth.of(2008, 3), LocalDate.of(2008, 3, 31)},
+                {YearMonth.of(2008, 4), LocalDate.of(2008, 4, 30)},
+                {YearMonth.of(2008, 5), LocalDate.of(2008, 5, 31)},
+                {YearMonth.of(2008, 6), LocalDate.of(2008, 6, 30)},
+                {YearMonth.of(2008, 12), LocalDate.of(2008, 12, 31)},
+
+                {YearMonth.of(2009, 1), LocalDate.of(2009, 1, 31)},
+                {YearMonth.of(2009, 2), LocalDate.of(2009, 2, 28)},
+                {YearMonth.of(2009, 3), LocalDate.of(2009, 3, 31)},
+                {YearMonth.of(2009, 4), LocalDate.of(2009, 4, 30)},
+                {YearMonth.of(2009, 5), LocalDate.of(2009, 5, 31)},
+                {YearMonth.of(2009, 6), LocalDate.of(2009, 6, 30)},
+                {YearMonth.of(2009, 12), LocalDate.of(2009, 12, 31)},
+        };
+    }
+
+    @Test(dataProvider="atEndOfMonth")
+    public void test_atEndOfMonth(YearMonth test, LocalDate expected) {
+        assertEquals(test.atEndOfMonth(), expected);
     }
 
     //-----------------------------------------------------------------------
@@ -1033,7 +1123,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M");
         String t = YearMonth.of(2010, 12).toString(f);
         assertEquals(t, "2010 12");
     }
diff --git a/jdk/test/java/time/tck/java/time/TCKZoneId.java b/jdk/test/java/time/tck/java/time/TCKZoneId.java
index adc2bb6..bc6944a 100644
--- a/jdk/test/java/time/tck/java/time/TCKZoneId.java
+++ b/jdk/test/java/time/tck/java/time/TCKZoneId.java
@@ -59,11 +59,30 @@
  */
 package tck.java.time;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
 import java.io.DataOutputStream;
-
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamConstants;
+import java.lang.reflect.Field;
+import java.time.DateTimeException;
+import java.time.LocalTime;
 import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.temporal.Queries;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.zone.ZoneRulesException;
+import java.util.HashMap;
+import java.util.Map;
 
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 /**
@@ -76,6 +95,7 @@
     @Test
     public void test_serialization() throws Exception {
         assertSerializable(ZoneId.of("Europe/London"));
+        assertSerializable(ZoneId.of("America/Chicago"));
     }
 
     @Test
@@ -89,4 +109,484 @@
         assertSerializedBySer(ZoneId.of("Europe/London"), bytes);
     }
 
+    @Test
+    public void test_deserialization_lenient_characters() throws Exception {
+        // an ID can be loaded without validation during deserialization
+        String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-";
+        ZoneId deser = deserialize(id);
+        // getting the ID and string are OK
+        assertEquals(deser.getId(), id);
+        assertEquals(deser.toString(), id);
+        // getting the rules is not
+        try {
+            deser.getRules();
+            fail();
+        } catch (ZoneRulesException ex) {
+            // expected
+        }
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_deserialization_lenient_badCharacters() throws Exception {
+        // an ID can be loaded without validation during deserialization
+        // but there is a check to ensure the ID format is valid
+        deserialize("|!?");
+    }
+
+    @Test(dataProvider="offsetBasedValid", expectedExceptions=DateTimeException.class)
+    public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception {
+        // an ID can be loaded without validation during deserialization
+        // but there is a check to ensure the ID format is valid
+        deserialize(input);
+    }
+
+    @Test(dataProvider="offsetBasedValid", expectedExceptions=DateTimeException.class)
+    public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId) throws Exception {
+        // an ID can be loaded without validation during deserialization
+        // but there is a check to ensure the ID format is valid
+        deserialize("UTC" + input);
+    }
+
+    @Test(dataProvider="offsetBasedValid", expectedExceptions=DateTimeException.class)
+    public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId) throws Exception {
+        // an ID can be loaded without validation during deserialization
+        // but there is a check to ensure the ID format is valid
+        deserialize("GMT" + input);
+    }
+
+    @Test(dataProvider="offsetBasedValid", expectedExceptions=DateTimeException.class)
+    public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId) throws Exception {
+        // an ID can be loaded without validation during deserialization
+        // but there is a check to ensure the ID format is valid
+        deserialize("UT" + input);
+    }
+
+    private ZoneId deserialize(String id) throws Exception {
+        String serClass = ZoneId.class.getPackage().getName() + ".Ser";
+        Class<?> serCls = Class.forName(serClass);
+        Field field = serCls.getDeclaredField("serialVersionUID");
+        field.setAccessible(true);
+        long serVer = (Long) field.get(null);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos)) {
+            dos.writeShort(ObjectStreamConstants.STREAM_MAGIC);
+            dos.writeShort(ObjectStreamConstants.STREAM_VERSION);
+            dos.writeByte(ObjectStreamConstants.TC_OBJECT);
+            dos.writeByte(ObjectStreamConstants.TC_CLASSDESC);
+            dos.writeUTF(serClass);
+            dos.writeLong(serVer);
+            dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA);
+            dos.writeShort(0);  // number of fields
+            dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);  // end of classdesc
+            dos.writeByte(ObjectStreamConstants.TC_NULL);  // no superclasses
+            dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA);
+            dos.writeByte(1 + 2 + id.length());  // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF)
+            dos.writeByte(7);  // ZoneId
+            dos.writeUTF(id);
+            dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);  // end of blockdata
+        }
+        ZoneId deser = null;
+        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
+            deser = (ZoneId) ois.readObject();
+        }
+        return deser;
+    }
+
+    //-----------------------------------------------------------------------
+    // OLD_IDS_PRE_2005
+    //-----------------------------------------------------------------------
+    public void test_constant_OLD_IDS_PRE_2005() {
+        Map<String, String> ids = ZoneId.OLD_IDS_PRE_2005;
+        assertEquals(ids.get("EST"), "America/New_York");
+        assertEquals(ids.get("MST"), "America/Denver");
+        assertEquals(ids.get("HST"), "Pacific/Honolulu");
+        assertEquals(ids.get("ACT"), "Australia/Darwin");
+        assertEquals(ids.get("AET"), "Australia/Sydney");
+        assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires");
+        assertEquals(ids.get("ART"), "Africa/Cairo");
+        assertEquals(ids.get("AST"), "America/Anchorage");
+        assertEquals(ids.get("BET"), "America/Sao_Paulo");
+        assertEquals(ids.get("BST"), "Asia/Dhaka");
+        assertEquals(ids.get("CAT"), "Africa/Harare");
+        assertEquals(ids.get("CNT"), "America/St_Johns");
+        assertEquals(ids.get("CST"), "America/Chicago");
+        assertEquals(ids.get("CTT"), "Asia/Shanghai");
+        assertEquals(ids.get("EAT"), "Africa/Addis_Ababa");
+        assertEquals(ids.get("ECT"), "Europe/Paris");
+        assertEquals(ids.get("IET"), "America/Indiana/Indianapolis");
+        assertEquals(ids.get("IST"), "Asia/Kolkata");
+        assertEquals(ids.get("JST"), "Asia/Tokyo");
+        assertEquals(ids.get("MIT"), "Pacific/Apia");
+        assertEquals(ids.get("NET"), "Asia/Yerevan");
+        assertEquals(ids.get("NST"), "Pacific/Auckland");
+        assertEquals(ids.get("PLT"), "Asia/Karachi");
+        assertEquals(ids.get("PNT"), "America/Phoenix");
+        assertEquals(ids.get("PRT"), "America/Puerto_Rico");
+        assertEquals(ids.get("PST"), "America/Los_Angeles");
+        assertEquals(ids.get("SST"), "Pacific/Guadalcanal");
+        assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh");
+    }
+
+    @Test(expectedExceptions=UnsupportedOperationException.class)
+    public void test_constant_OLD_IDS_PRE_2005_immutable() {
+        Map<String, String> ids = ZoneId.OLD_IDS_PRE_2005;
+        ids.clear();
+    }
+
+    //-----------------------------------------------------------------------
+    // OLD_IDS_POST_2005
+    //-----------------------------------------------------------------------
+    public void test_constant_OLD_IDS_POST_2005() {
+        Map<String, String> ids = ZoneId.OLD_IDS_POST_2005;
+        assertEquals(ids.get("EST"), "-05:00");
+        assertEquals(ids.get("MST"), "-07:00");
+        assertEquals(ids.get("HST"), "-10:00");
+        assertEquals(ids.get("ACT"), "Australia/Darwin");
+        assertEquals(ids.get("AET"), "Australia/Sydney");
+        assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires");
+        assertEquals(ids.get("ART"), "Africa/Cairo");
+        assertEquals(ids.get("AST"), "America/Anchorage");
+        assertEquals(ids.get("BET"), "America/Sao_Paulo");
+        assertEquals(ids.get("BST"), "Asia/Dhaka");
+        assertEquals(ids.get("CAT"), "Africa/Harare");
+        assertEquals(ids.get("CNT"), "America/St_Johns");
+        assertEquals(ids.get("CST"), "America/Chicago");
+        assertEquals(ids.get("CTT"), "Asia/Shanghai");
+        assertEquals(ids.get("EAT"), "Africa/Addis_Ababa");
+        assertEquals(ids.get("ECT"), "Europe/Paris");
+        assertEquals(ids.get("IET"), "America/Indiana/Indianapolis");
+        assertEquals(ids.get("IST"), "Asia/Kolkata");
+        assertEquals(ids.get("JST"), "Asia/Tokyo");
+        assertEquals(ids.get("MIT"), "Pacific/Apia");
+        assertEquals(ids.get("NET"), "Asia/Yerevan");
+        assertEquals(ids.get("NST"), "Pacific/Auckland");
+        assertEquals(ids.get("PLT"), "Asia/Karachi");
+        assertEquals(ids.get("PNT"), "America/Phoenix");
+        assertEquals(ids.get("PRT"), "America/Puerto_Rico");
+        assertEquals(ids.get("PST"), "America/Los_Angeles");
+        assertEquals(ids.get("SST"), "Pacific/Guadalcanal");
+        assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh");
+    }
+
+    @Test(expectedExceptions=UnsupportedOperationException.class)
+    public void test_constant_OLD_IDS_POST_2005_immutable() {
+        Map<String, String> ids = ZoneId.OLD_IDS_POST_2005;
+        ids.clear();
+    }
+
+    //-----------------------------------------------------------------------
+    // mapped factory
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_of_string_Map() {
+        Map<String, String> map = new HashMap<>();
+        map.put("LONDON", "Europe/London");
+        map.put("PARIS", "Europe/Paris");
+        ZoneId test = ZoneId.of("LONDON", map);
+        assertEquals(test.getId(), "Europe/London");
+    }
+
+    @Test
+    public void test_of_string_Map_lookThrough() {
+        Map<String, String> map = new HashMap<>();
+        map.put("LONDON", "Europe/London");
+        map.put("PARIS", "Europe/Paris");
+        ZoneId test = ZoneId.of("Europe/Madrid", map);
+        assertEquals(test.getId(), "Europe/Madrid");
+    }
+
+    @Test
+    public void test_of_string_Map_emptyMap() {
+        Map<String, String> map = new HashMap<>();
+        ZoneId test = ZoneId.of("Europe/Madrid", map);
+        assertEquals(test.getId(), "Europe/Madrid");
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_of_string_Map_badFormat() {
+        Map<String, String> map = new HashMap<>();
+        ZoneId.of("Not known", map);
+    }
+
+    @Test(expectedExceptions=ZoneRulesException.class)
+    public void test_of_string_Map_unknown() {
+        Map<String, String> map = new HashMap<>();
+        ZoneId.of("Unknown", map);
+    }
+
+    //-----------------------------------------------------------------------
+    // regular factory
+    //-----------------------------------------------------------------------
+    @DataProvider(name="offsetBasedZero")
+    Object[][] data_offsetBasedZero() {
+        return new Object[][] {
+                {""}, {"0"},
+                {"+00"},{"+0000"},{"+00:00"},{"+000000"},{"+00:00:00"},
+                {"-00"},{"-0000"},{"-00:00"},{"-000000"},{"-00:00:00"},
+        };
+    }
+
+    @Test(dataProvider="offsetBasedZero")
+    public void factory_of_String_offsetBasedZero_noPrefix(String id) {
+        if (id.length() > 0 && id.equals("0") == false) {
+            ZoneId test = ZoneId.of(id);
+            assertEquals(test, ZoneOffset.UTC);
+        }
+    }
+
+    @Test(dataProvider="offsetBasedZero")
+    public void factory_of_String_offsetBasedZero_prefixUTC(String id) {
+        ZoneId test = ZoneId.of("UTC" + id);
+        assertEquals(test, ZoneOffset.UTC);
+    }
+
+    @Test(dataProvider="offsetBasedZero")
+    public void factory_of_String_offsetBasedZero_prefixGMT(String id) {
+        ZoneId test = ZoneId.of("GMT" + id);
+        assertEquals(test, ZoneOffset.UTC);
+    }
+
+    @Test(dataProvider="offsetBasedZero")
+    public void factory_of_String_offsetBasedZero_prefixUT(String id) {
+        ZoneId test = ZoneId.of("UT" + id);
+        assertEquals(test, ZoneOffset.UTC);
+    }
+
+    @Test
+    public void factory_of_String_offsetBasedZero_z() {
+        ZoneId test = ZoneId.of("Z");
+        assertEquals(test, ZoneOffset.UTC);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="offsetBasedValid")
+    Object[][] data_offsetBasedValid() {
+        return new Object[][] {
+                {"+0", "Z"},
+                {"+5", "+05:00"},
+                {"+01", "+01:00"},
+                {"+0100", "+01:00"},{"+01:00", "+01:00"},
+                {"+010000", "+01:00"},{"+01:00:00", "+01:00"},
+                {"+12", "+12:00"},
+                {"+1234", "+12:34"},{"+12:34", "+12:34"},
+                {"+123456", "+12:34:56"},{"+12:34:56", "+12:34:56"},
+                {"-02", "-02:00"},
+                {"-5", "-05:00"},
+                {"-0200", "-02:00"},{"-02:00", "-02:00"},
+                {"-020000", "-02:00"},{"-02:00:00", "-02:00"},
+        };
+    }
+
+    @Test(dataProvider="offsetBasedValid")
+    public void factory_of_String_offsetBasedValid_noPrefix(String input, String id) {
+        ZoneId test = ZoneId.of(input);
+        assertEquals(test.getId(), id);
+        assertEquals(test, ZoneOffset.of(id));
+    }
+
+    @Test(dataProvider="offsetBasedValid")
+    public void factory_of_String_offsetBasedValid_prefixUTC(String input, String id) {
+        ZoneId test = ZoneId.of("UTC" + input);
+        assertEquals(test.getId(), id);
+        assertEquals(test, ZoneOffset.of(id));
+    }
+
+    @Test(dataProvider="offsetBasedValid")
+    public void factory_of_String_offsetBasedValid_prefixGMT(String input, String id) {
+        ZoneId test = ZoneId.of("GMT" + input);
+        assertEquals(test.getId(), id);
+        assertEquals(test, ZoneOffset.of(id));
+    }
+
+    @Test(dataProvider="offsetBasedValid")
+    public void factory_of_String_offsetBasedValid_prefixUT(String input, String id) {
+        ZoneId test = ZoneId.of("UT" + input);
+        assertEquals(test.getId(), id);
+        assertEquals(test, ZoneOffset.of(id));
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="offsetBasedInvalid")
+    Object[][] data_offsetBasedInvalid() {
+        return new Object[][] {
+                {"A"}, {"B"}, {"C"}, {"D"}, {"E"}, {"F"}, {"G"}, {"H"}, {"I"}, {"J"}, {"K"}, {"L"}, {"M"},
+                {"N"}, {"O"}, {"P"}, {"Q"}, {"R"}, {"S"}, {"T"}, {"U"}, {"V"}, {"W"}, {"X"}, {"Y"}, {"Z"},
+                {"+0:00"}, {"+00:0"}, {"+0:0"},
+                {"+000"}, {"+00000"},
+                {"+0:00:00"}, {"+00:0:00"}, {"+00:00:0"}, {"+0:0:0"}, {"+0:0:00"}, {"+00:0:0"}, {"+0:00:0"},
+                {"+01_00"}, {"+01;00"}, {"+01@00"}, {"+01:AA"},
+                {"+19"}, {"+19:00"}, {"+18:01"}, {"+18:00:01"}, {"+1801"}, {"+180001"},
+                {"-0:00"}, {"-00:0"}, {"-0:0"},
+                {"-000"}, {"-00000"},
+                {"-0:00:00"}, {"-00:0:00"}, {"-00:00:0"}, {"-0:0:0"}, {"-0:0:00"}, {"-00:0:0"}, {"-0:00:0"},
+                {"-19"}, {"-19:00"}, {"-18:01"}, {"-18:00:01"}, {"-1801"}, {"-180001"},
+                {"-01_00"}, {"-01;00"}, {"-01@00"}, {"-01:AA"},
+                {"@01:00"},
+        };
+    }
+
+    @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class)
+    public void factory_of_String_offsetBasedInvalid_noPrefix(String id) {
+        if (id.equals("Z")) {
+            throw new DateTimeException("Fake exception: Z alone is valid, not invalid");
+        }
+        ZoneId.of(id);
+    }
+
+    @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class)
+    public void factory_of_String_offsetBasedInvalid_prefixUTC(String id) {
+        ZoneId.of("UTC" + id);
+    }
+
+    @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class)
+    public void factory_of_String_offsetBasedInvalid_prefixGMT(String id) {
+        ZoneId.of("GMT" + id);
+    }
+
+    @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class)
+    public void factory_of_String_offsetBasedInvalid_prefixUT(String id) {
+        if (id.equals("C")) {
+            throw new DateTimeException("Fake exception: UT + C = UTC, thus it is valid, not invalid");
+        }
+        ZoneId.of("UT" + id);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="regionBasedInvalid")
+    Object[][] data_regionBasedInvalid() {
+        // \u00ef is a random unicode character
+        return new Object[][] {
+                {""}, {":"}, {"#"},
+                {"\u00ef"}, {"`"}, {"!"}, {"\""}, {"\u00ef"}, {"$"}, {"^"}, {"&"}, {"*"}, {"("}, {")"}, {"="},
+                {"\\"}, {"|"}, {","}, {"<"}, {">"}, {"?"}, {";"}, {"'"}, {"["}, {"]"}, {"{"}, {"}"},
+                {"\u00ef:A"}, {"`:A"}, {"!:A"}, {"\":A"}, {"\u00ef:A"}, {"$:A"}, {"^:A"}, {"&:A"}, {"*:A"}, {"(:A"}, {"):A"}, {"=:A"}, {"+:A"},
+                {"\\:A"}, {"|:A"}, {",:A"}, {"<:A"}, {">:A"}, {"?:A"}, {";:A"}, {"::A"}, {"':A"}, {"@:A"}, {"~:A"}, {"[:A"}, {"]:A"}, {"{:A"}, {"}:A"},
+                {"A:B#\u00ef"}, {"A:B#`"}, {"A:B#!"}, {"A:B#\""}, {"A:B#\u00ef"}, {"A:B#$"}, {"A:B#^"}, {"A:B#&"}, {"A:B#*"},
+                {"A:B#("}, {"A:B#)"}, {"A:B#="}, {"A:B#+"},
+                {"A:B#\\"}, {"A:B#|"}, {"A:B#,"}, {"A:B#<"}, {"A:B#>"}, {"A:B#?"}, {"A:B#;"}, {"A:B#:"},
+                {"A:B#'"}, {"A:B#@"}, {"A:B#~"}, {"A:B#["}, {"A:B#]"}, {"A:B#{"}, {"A:B#}"},
+        };
+    }
+
+    @Test(dataProvider="regionBasedInvalid", expectedExceptions=DateTimeException.class)
+    public void factory_of_String_regionBasedInvalid(String id) {
+        ZoneId.of(id);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void factory_of_String_region_EuropeLondon() {
+        ZoneId test = ZoneId.of("Europe/London");
+        assertEquals(test.getId(), "Europe/London");
+        assertEquals(test.getRules().isFixedOffset(), false);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(expectedExceptions=NullPointerException.class)
+    public void factory_of_String_null() {
+        ZoneId.of(null);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void factory_of_String_badFormat() {
+        ZoneId.of("Unknown rule");
+    }
+
+    @Test(expectedExceptions=ZoneRulesException.class)
+    public void factory_of_String_unknown() {
+        ZoneId.of("Unknown");
+    }
+
+    //-----------------------------------------------------------------------
+    // from(TemporalAccessor)
+    //-----------------------------------------------------------------------
+    @Test
+    public void factory_from_TemporalAccessor_zoneId() {
+        TemporalAccessor mock = new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                return false;
+            }
+            @Override
+            public long getLong(TemporalField field) {
+                throw new DateTimeException("Mock");
+            }
+            @SuppressWarnings("unchecked")
+            @Override
+            public <R> R query(TemporalQuery<R> query) {
+                if (query == Queries.zoneId()) {
+                    return (R) ZoneId.of("Europe/Paris");
+                }
+                return TemporalAccessor.super.query(query);
+            }
+        };
+        assertEquals(ZoneId.from(mock),  ZoneId.of("Europe/Paris"));
+    }
+
+    @Test
+    public void factory_from_TemporalAccessor_offset() {
+        ZoneOffset offset = ZoneOffset.ofHours(1);
+        assertEquals(ZoneId.from(offset), offset);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void factory_from_TemporalAccessor_invalid_noDerive() {
+        ZoneId.from(LocalTime.of(12, 30));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void factory_from_TemporalAccessor_null() {
+        ZoneId.from(null);
+    }
+
+    //-----------------------------------------------------------------------
+    // equals() / hashCode()
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_equals() {
+        ZoneId test1 = ZoneId.of("Europe/London");
+        ZoneId test2 = ZoneId.of("Europe/Paris");
+        ZoneId test2b = ZoneId.of("Europe/Paris");
+        assertEquals(test1.equals(test2), false);
+        assertEquals(test2.equals(test1), false);
+
+        assertEquals(test1.equals(test1), true);
+        assertEquals(test2.equals(test2), true);
+        assertEquals(test2.equals(test2b), true);
+
+        assertEquals(test1.hashCode() == test1.hashCode(), true);
+        assertEquals(test2.hashCode() == test2.hashCode(), true);
+        assertEquals(test2.hashCode() == test2b.hashCode(), true);
+    }
+
+    @Test
+    public void test_equals_null() {
+        assertEquals(ZoneId.of("Europe/London").equals(null), false);
+    }
+
+    @Test
+    public void test_equals_notEqualWrongType() {
+        assertEquals(ZoneId.of("Europe/London").equals("Europe/London"), false);
+    }
+
+    //-----------------------------------------------------------------------
+    // toString()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toString")
+    Object[][] data_toString() {
+        return new Object[][] {
+                {"Europe/London", "Europe/London"},
+                {"Europe/Paris", "Europe/Paris"},
+                {"Europe/Berlin", "Europe/Berlin"},
+                {"UTC", "Z"},
+                {"UTC+01:00", "+01:00"},
+        };
+    }
+
+    @Test(dataProvider="toString")
+    public void test_toString(String id, String expected) {
+        ZoneId test = ZoneId.of(id);
+        assertEquals(test.toString(), expected);
+    }
+
 }
diff --git a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java
index 4cfd40d..c8fb56b 100644
--- a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java
+++ b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java
@@ -67,10 +67,6 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import java.time.DateTimeException;
 import java.time.Duration;
 import java.time.Instant;
@@ -81,11 +77,15 @@
 import java.time.ZonedDateTime;
 import java.time.temporal.ChronoField;
 import java.time.temporal.JulianFields;
-import java.time.temporal.OffsetDate;
 import java.time.temporal.Queries;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 /**
@@ -480,7 +480,6 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_factory_CalendricalObject() {
-        assertEquals(ZoneOffset.from(OffsetDate.of(LocalDate.of(2012, 5, 2), ZoneOffset.ofHours(6))), ZoneOffset.ofHours(6));
         assertEquals(ZoneOffset.from(ZonedDateTime.of(LocalDateTime.of(LocalDate.of(2007, 7, 15),
                 LocalTime.of(17, 30)), ZoneOffset.ofHours(2))), ZoneOffset.ofHours(2));
     }
@@ -560,44 +559,32 @@
     //-----------------------------------------------------------------------
     // query(TemporalQuery)
     //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        ZoneOffset test = ZoneOffset.ofHoursMinutes(1, 30);
-        assertEquals(test.query(Queries.chrono()), null);
-        assertEquals(Queries.chrono().queryFrom(test), null);
+    @DataProvider(name="query")
+    Object[][] data_query() {
+        return new Object[][] {
+                {ZoneOffset.UTC, Queries.chronology(), null},
+                {ZoneOffset.UTC, Queries.zoneId(), null},
+                {ZoneOffset.UTC, Queries.precision(), null},
+                {ZoneOffset.UTC, Queries.zone(), ZoneOffset.UTC},
+                {ZoneOffset.UTC, Queries.offset(), ZoneOffset.UTC},
+                {ZoneOffset.UTC, Queries.localDate(), null},
+                {ZoneOffset.UTC, Queries.localTime(), null},
+        };
     }
 
-    @Test
-    public void test_query_zoneId() {
-        ZoneOffset test = ZoneOffset.ofHoursMinutes(1, 30);
-        assertEquals(test.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(test), null);
+    @Test(dataProvider="query")
+    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(temporal.query(query), expected);
     }
 
-    @Test
-    public void test_query_precision() {
-        ZoneOffset test = ZoneOffset.ofHoursMinutes(1, 30);
-        assertEquals(test.query(Queries.precision()), null);
-        assertEquals(Queries.precision().queryFrom(test), null);
-    }
-
-    @Test
-    public void test_query_offset() {
-        ZoneOffset test = ZoneOffset.ofHoursMinutes(1, 30);
-        assertEquals(test.query(Queries.offset()), test);
-        assertEquals(Queries.offset().queryFrom(test), test);
-    }
-
-    @Test
-    public void test_query_zone() {
-        ZoneOffset test = ZoneOffset.ofHoursMinutes(1, 30);
-        assertEquals(test.query(Queries.zone()), test);
-        assertEquals(Queries.zone().queryFrom(test), test);
+    @Test(dataProvider="query")
+    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
+        assertEquals(query.queryFrom(temporal), expected);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_query_null() {
-        ZoneOffset.ofHoursMinutes(1, 30).query(null);
+        ZoneOffset.UTC.query(null);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java
index df18b4f..9841fc8 100644
--- a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java
@@ -60,7 +60,6 @@
 package tck.java.time;
 
 import java.time.*;
-import test.java.time.MockSimplePeriod;
 
 import static java.time.Month.JANUARY;
 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
@@ -111,21 +110,21 @@
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.Queries;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.TemporalAdder;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalAdjuster;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalQuery;
 import java.time.temporal.TemporalField;
-import java.time.temporal.ISOChrono;
+import java.time.chrono.IsoChronology;
 import java.time.temporal.JulianFields;
 import test.java.time.temporal.MockFieldNoValue;
 
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
+import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
-import java.time.temporal.OffsetDateTime;
-import java.time.temporal.Year;
+import java.time.OffsetDateTime;
+import java.time.Year;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
@@ -272,12 +271,12 @@
     public void now() {
         ZonedDateTime expected = ZonedDateTime.now(Clock.systemDefaultZone());
         ZonedDateTime test = ZonedDateTime.now();
-        long diff = Math.abs(test.getTime().toNanoOfDay() - expected.getTime().toNanoOfDay());
+        long diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
         if (diff >= 100000000) {
             // may be date change
             expected = ZonedDateTime.now(Clock.systemDefaultZone());
             test = ZonedDateTime.now();
-            diff = Math.abs(test.getTime().toNanoOfDay() - expected.getTime().toNanoOfDay());
+            diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
         }
         assertTrue(diff < 100000000);  // less than 0.1 secs
     }
@@ -354,7 +353,7 @@
             assertEquals(test.getMonth(), Month.DECEMBER);
             assertEquals(test.getDayOfMonth(), 31);
             expected = expected.minusSeconds(1);
-            assertEquals(test.getTime(), expected);
+            assertEquals(test.toLocalTime(), expected);
             assertEquals(test.getOffset(), ZoneOffset.UTC);
             assertEquals(test.getZone(), ZoneOffset.UTC);
         }
@@ -392,10 +391,44 @@
     }
 
     //-----------------------------------------------------------------------
+    // of(LocalDate, LocalTime, ZoneId)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void factory_of_LocalDateLocalTime() {
+        ZonedDateTime test = ZonedDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 10, 500), ZONE_PARIS);
+        check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
+    }
+
+    @Test(groups={"tck"})
+    public void factory_of_LocalDateLocalTime_inGap() {
+        ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_GAP_2008_03_30_02_30.toLocalDate(), TEST_PARIS_GAP_2008_03_30_02_30.toLocalTime(), ZONE_PARIS);
+        check(test, 2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // one hour later in summer offset
+    }
+
+    @Test(groups={"tck"})
+    public void factory_of_LocalDateLocalTime_inOverlap() {
+        ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_OVERLAP_2008_10_26_02_30.toLocalDate(), TEST_PARIS_OVERLAP_2008_10_26_02_30.toLocalTime(), ZONE_PARIS);
+        check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // same time in summer offset
+    }
+
+    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    public void factory_of_LocalDateLocalTime_nullDate() {
+        ZonedDateTime.of((LocalDate) null, LocalTime.of(11, 30, 10, 500), ZONE_PARIS);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    public void factory_of_LocalDateLocalTime_nullTime() {
+        ZonedDateTime.of(LocalDate.of(2008, 6, 30), (LocalTime) null, ZONE_PARIS);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    public void factory_of_LocalDateLocalTime_nullZone() {
+        ZonedDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 10, 500), null);
+    }
+
+    //-----------------------------------------------------------------------
     // of(LocalDateTime, ZoneId)
     //-----------------------------------------------------------------------
-    // TODO: tests of overlap/gap
-
     @Test(groups={"tck"})
     public void factory_of_LocalDateTime() {
         LocalDateTime base = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500);
@@ -403,6 +436,18 @@
         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
     }
 
+    @Test(groups={"tck"})
+    public void factory_of_LocalDateTime_inGap() {
+        ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_GAP_2008_03_30_02_30, ZONE_PARIS);
+        check(test, 2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // one hour later in summer offset
+    }
+
+    @Test(groups={"tck"})
+    public void factory_of_LocalDateTime_inOverlap() {
+        ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_OVERLAP_2008_10_26_02_30, ZONE_PARIS);
+        check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // same time in summer offset
+    }
+
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_of_LocalDateTime_nullDateTime() {
         ZonedDateTime.of((LocalDateTime) null, ZONE_PARIS);
@@ -415,6 +460,15 @@
     }
 
     //-----------------------------------------------------------------------
+    // of(int..., ZoneId)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void factory_of_ints() {
+        ZonedDateTime test = ZonedDateTime.of(2008, 6, 30, 11, 30, 10, 500, ZONE_PARIS);
+        check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
+    }
+
+    //-----------------------------------------------------------------------
     // ofInstant(Instant, ZoneId)
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
@@ -662,11 +716,11 @@
         assertEquals(ZonedDateTime.from(new TemporalAccessor() {
             @Override
             public boolean isSupported(TemporalField field) {
-                return TEST_DATE_TIME_PARIS.getDateTime().isSupported(field);
+                return TEST_DATE_TIME_PARIS.toLocalDateTime().isSupported(field);
             }
             @Override
             public long getLong(TemporalField field) {
-                return TEST_DATE_TIME_PARIS.getDateTime().getLong(field);
+                return TEST_DATE_TIME_PARIS.toLocalDateTime().getLong(field);
             }
             @SuppressWarnings("unchecked")
             @Override
@@ -716,7 +770,7 @@
     //-----------------------------------------------------------------------
     // parse()
     //-----------------------------------------------------------------------
-    @Test(dataProvider="sampleToString", groups={"tck"})
+    @Test(dataProvider="sampleToString")
     public void test_parse(int y, int month, int d, int h, int m, int s, int n, String zoneId, String text) {
         ZonedDateTime t = ZonedDateTime.parse(text);
         assertEquals(t.getYear(), y);
@@ -729,6 +783,37 @@
         assertEquals(t.getZone().getId(), zoneId);
     }
 
+    @DataProvider(name="parseAdditional")
+    Object[][] data_parseAdditional() {
+        return new Object[][] {
+                {"2012-06-30T12:30:40Z[GMT]", 2012, 6, 30, 12, 30, 40, 0, "Z"},
+                {"2012-06-30T12:30:40Z[UT]", 2012, 6, 30, 12, 30, 40, 0, "Z"},
+                {"2012-06-30T12:30:40Z[UTC]", 2012, 6, 30, 12, 30, 40, 0, "Z"},
+                {"2012-06-30T12:30:40+01:00[+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
+                {"2012-06-30T12:30:40+01:00[GMT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
+                {"2012-06-30T12:30:40+01:00[UT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
+                {"2012-06-30T12:30:40+01:00[UTC+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
+                {"2012-06-30T12:30:40-01:00[-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
+                {"2012-06-30T12:30:40-01:00[GMT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
+                {"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
+                {"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
+                {"2012-06-30T12:30:40+01:00[Europe/London]", 2012, 6, 30, 12, 30, 40, 0, "Europe/London"},
+        };
+    }
+
+    @Test(dataProvider="parseAdditional")
+    public void test_parseAdditional(String text, int y, int month, int d, int h, int m, int s, int n, String zoneId) {
+        ZonedDateTime t = ZonedDateTime.parse(text);
+        assertEquals(t.getYear(), y);
+        assertEquals(t.getMonth().getValue(), month);
+        assertEquals(t.getDayOfMonth(), d);
+        assertEquals(t.getHour(), h);
+        assertEquals(t.getMinute(), m);
+        assertEquals(t.getSecond(), s);
+        assertEquals(t.getNano(), n);
+        assertEquals(t.getZone().getId(), zoneId);
+    }
+
     @Test(expectedExceptions=DateTimeParseException.class, groups={"tck"})
     public void factory_parse_illegalValue() {
         ZonedDateTime.parse("2008-06-32T11:15+01:00[Europe/Paris]");
@@ -749,14 +834,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s I");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s VV");
         ZonedDateTime test = ZonedDateTime.parse("2010 12 3 11 30 0 Europe/London", f);
         assertEquals(test, ZonedDateTime.of(LocalDateTime.of(2010, 12, 3, 11, 30), ZoneId.of("Europe/London")));
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
         ZonedDateTime.parse((String) null, f);
     }
 
@@ -799,9 +884,9 @@
         assertEquals(a.getSecond(), localTime.getSecond());
         assertEquals(a.getNano(), localTime.getNano());
 
-        assertEquals(a.getDate(), localDate);
-        assertEquals(a.getTime(), localTime);
-        assertEquals(a.getDateTime(), localDateTime);
+        assertEquals(a.toLocalDate(), localDate);
+        assertEquals(a.toLocalTime(), localTime);
+        assertEquals(a.toLocalDateTime(), localDateTime);
         if (zone instanceof ZoneOffset) {
             assertEquals(a.toString(), localDateTime.toString() + offset.toString());
         } else {
@@ -856,8 +941,8 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_query_chrono() {
-        assertEquals(TEST_DATE_TIME.query(Queries.chrono()), ISOChrono.INSTANCE);
-        assertEquals(Queries.chrono().queryFrom(TEST_DATE_TIME), ISOChrono.INSTANCE);
+        assertEquals(TEST_DATE_TIME.query(Queries.chronology()), IsoChronology.INSTANCE);
+        assertEquals(Queries.chronology().queryFrom(TEST_DATE_TIME), IsoChronology.INSTANCE);
     }
 
     @Test
@@ -904,7 +989,7 @@
         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0100, ZONE_PARIS);
         ZonedDateTime test = base.withEarlierOffsetAtOverlap();
         assertEquals(test.getOffset(), OFFSET_0200);  // offset changed to earlier
-        assertEquals(test.getDateTime(), base.getDateTime());  // date-time not changed
+        assertEquals(test.toLocalDateTime(), base.toLocalDateTime());  // date-time not changed
     }
 
     @Test(groups={"tck"})
@@ -929,7 +1014,7 @@
         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0200, ZONE_PARIS);
         ZonedDateTime test = base.withLaterOffsetAtOverlap();
         assertEquals(test.getOffset(), OFFSET_0100);  // offset changed to later
-        assertEquals(test.getDateTime(), base.getDateTime());  // date-time not changed
+        assertEquals(test.toLocalDateTime(), base.toLocalDateTime());  // date-time not changed
     }
 
     @Test(groups={"tck"})
@@ -947,10 +1032,10 @@
         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
         ZonedDateTime test = base.withZoneSameLocal(ZONE_0200);
-        assertEquals(test.getDateTime(), base.getDateTime());
+        assertEquals(test.toLocalDateTime(), base.toLocalDateTime());
     }
 
-    @Test(groups={"implementation"})
+    @Test(groups={"tck","implementation"})
     public void test_withZoneSameLocal_noChange() {
         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
@@ -1357,25 +1442,25 @@
     }
 
     //-----------------------------------------------------------------------
-    // plus(adjuster)
+    // plus(TemporalAmount)
     //-----------------------------------------------------------------------
     @Test(groups={"tck"}, dataProvider="plusDays")
-    public void test_plus_adjuster_Period_days(ZonedDateTime base, long amount, ZonedDateTime expected) {
-        assertEquals(base.plus(Period.of(amount, DAYS)), expected);
+    public void test_plus_TemporalAmount_Period_days(ZonedDateTime base, int amount, ZonedDateTime expected) {
+        assertEquals(base.plus(Period.ofDays(amount)), expected);
     }
 
     @Test(groups={"tck"}, dataProvider="plusTime")
-    public void test_plus_adjuster_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
-        assertEquals(base.plus(Period.of(amount, HOURS)), expected);
+    public void test_plus_TemporalAmount_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
+        assertEquals(base.plus(MockSimplePeriod.of(amount, HOURS)), expected);
     }
 
     @Test(groups={"tck"}, dataProvider="plusTime")
-    public void test_plus_adjuster_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
+    public void test_plus_TemporalAmount_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
         assertEquals(base.plus(Duration.ofHours(amount)), expected);
     }
 
     @Test(groups={"tck"})
-    public void test_plus_adjuster() {
+    public void test_plus_TemporalAmount() {
         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2009, 1, 1, 12, 30, 59, 500), ZONE_0100);
@@ -1383,7 +1468,7 @@
     }
 
     @Test(groups={"tck"})
-    public void test_plus_adjuster_Duration() {
+    public void test_plus_TemporalAmount_Duration() {
         Duration duration = Duration.ofSeconds(4L * 60 * 60 + 5L * 60 + 6L);
         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 16, 36, 5, 500), ZONE_0100);
@@ -1391,20 +1476,20 @@
     }
 
     @Test(groups={"tck"})
-    public void test_plus_adjuster_Period_zero() {
+    public void test_plus_TemporalAmount_Period_zero() {
         ZonedDateTime t = TEST_DATE_TIME.plus(MockSimplePeriod.ZERO_DAYS);
         assertEquals(t, TEST_DATE_TIME);
     }
 
     @Test(groups={"tck"})
-    public void test_plus_adjuster_Duration_zero() {
+    public void test_plus_TemporalAmount_Duration_zero() {
         ZonedDateTime t = TEST_DATE_TIME.plus(Duration.ZERO);
         assertEquals(t, TEST_DATE_TIME);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_plus_adjuster_null() {
-        TEST_DATE_TIME.plus((TemporalAdder) null);
+    public void test_plus_TemporalAmount_null() {
+        TEST_DATE_TIME.plus((TemporalAmount) null);
     }
 
     //-----------------------------------------------------------------------
@@ -1562,25 +1647,25 @@
     }
 
     //-----------------------------------------------------------------------
-    // minus(adjuster)
+    // minus(TemporalAmount)
     //-----------------------------------------------------------------------
     @Test(groups={"tck"}, dataProvider="plusDays")
-    public void test_minus_adjuster_Period_days(ZonedDateTime base, long amount, ZonedDateTime expected) {
-        assertEquals(base.minus(Period.of(-amount, DAYS)), expected);
+    public void test_minus_TemporalAmount_Period_days(ZonedDateTime base, int amount, ZonedDateTime expected) {
+        assertEquals(base.minus(Period.ofDays(-amount)), expected);
     }
 
     @Test(groups={"tck"}, dataProvider="plusTime")
-    public void test_minus_adjuster_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
-        assertEquals(base.minus(Period.of(-amount, HOURS)), expected);
+    public void test_minus_TemporalAmount_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
+        assertEquals(base.minus(MockSimplePeriod.of(-amount, HOURS)), expected);
     }
 
     @Test(groups={"tck"}, dataProvider="plusTime")
-    public void test_minus_adjuster_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
+    public void test_minus_TemporalAmount_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
         assertEquals(base.minus(Duration.ofHours(-amount)), expected);
     }
 
     @Test(groups={"tck"})
-    public void test_minus_adjuster() {
+    public void test_minus_TemporalAmount() {
         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2007, 11, 1, 12, 30, 59, 500), ZONE_0100);
@@ -1588,7 +1673,7 @@
     }
 
     @Test(groups={"tck"})
-    public void test_minus_adjuster_Duration() {
+    public void test_minus_TemporalAmount_Duration() {
         Duration duration = Duration.ofSeconds(4L * 60 * 60 + 5L * 60 + 6L);
         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 8, 25, 53, 500), ZONE_0100);
@@ -1596,20 +1681,20 @@
     }
 
     @Test(groups={"tck"})
-    public void test_minus_adjuster_Period_zero() {
+    public void test_minus_TemporalAmount_Period_zero() {
         ZonedDateTime t = TEST_DATE_TIME.minus(MockSimplePeriod.ZERO_DAYS);
         assertEquals(t, TEST_DATE_TIME);
     }
 
     @Test(groups={"tck"})
-    public void test_minus_adjuster_Duration_zero() {
+    public void test_minus_TemporalAmount_Duration_zero() {
         ZonedDateTime t = TEST_DATE_TIME.minus(Duration.ZERO);
         assertEquals(t, TEST_DATE_TIME);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_minus_adjuster_null() {
-        TEST_DATE_TIME.minus((TemporalSubtractor) null);
+    public void test_minus_TemporalAmount_null() {
+        TEST_DATE_TIME.minus((TemporalAmount) null);
     }
 
     //-----------------------------------------------------------------------
@@ -1818,7 +1903,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toOffsetDateTime() {
-        assertEquals(TEST_DATE_TIME.toOffsetDateTime(), OffsetDateTime.of(TEST_DATE_TIME.getDateTime(), TEST_DATE_TIME.getOffset()));
+        assertEquals(TEST_DATE_TIME.toOffsetDateTime(), OffsetDateTime.of(TEST_DATE_TIME.toLocalDateTime(), TEST_DATE_TIME.getOffset()));
     }
 
     //-----------------------------------------------------------------------
@@ -1908,8 +1993,8 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_compareTo_time1() {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30, 39), ZONE_0100);
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30, 41), ZONE_0100);  // a is before b due to time
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 39, 0, ZONE_0100);
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 41, 0, ZONE_0100);  // a is before b due to time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1918,8 +2003,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_time2() {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30, 40, 4), ZONE_0100);
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30, 40, 5), ZONE_0100);  // a is before b due to time
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 4, ZONE_0100);
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 5, ZONE_0100);  // a is before b due to time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1928,8 +2013,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_offset1() {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30, 41), ZONE_0200);
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30, 39), ZONE_0100);  // a is before b due to offset
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 41, 0, ZONE_0200);
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 39, 0, ZONE_0100);  // a is before b due to offset
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1938,8 +2023,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_offset2() {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30, 40, 5), ZoneId.of("UTC+01:01"));
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30, 40, 4), ZONE_0100);  // a is before b due to offset
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 5, ZoneId.of("UTC+01:01"));
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 4, ZONE_0100);  // a is before b due to offset
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1948,8 +2033,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_both() {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 50), ZONE_0200);
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 20), ZONE_0100);  // a is before b on instant scale
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 50, 0, 0, ZONE_0200);
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 20, 0, 0, ZONE_0100);  // a is before b on instant scale
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1958,8 +2043,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_bothNanos() {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 20, 40, 5), ZONE_0200);
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 10, 20, 40, 6), ZONE_0100);  // a is before b on instant scale
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 20, 40, 5, ZONE_0200);
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 10, 20, 40, 6, ZONE_0100);  // a is before b on instant scale
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1968,8 +2053,8 @@
 
     @Test(groups={"tck"})
     public void test_compareTo_hourDifference() {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 10, 0), ZONE_0100);
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 0), ZONE_0200);  // a is before b despite being same time-line time
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 10, 0, 0, 0, ZONE_0100);
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 0, 0, 0, ZONE_0200);  // a is before b despite being same time-line time
         assertEquals(a.compareTo(b) < 0, true);
         assertEquals(b.compareTo(a) > 0, true);
         assertEquals(a.compareTo(a) == 0, true);
@@ -1978,8 +2063,7 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_compareTo_null() {
-        LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
-        ZonedDateTime a = ZonedDateTime.of(ldt, ZONE_0100);
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
         a.compareTo(null);
     }
 
@@ -1997,8 +2081,8 @@
 
     @Test(dataProvider="IsBefore", groups={"tck"})
     public void test_isBefore(int hour1, int minute1, ZoneId zone1, int hour2, int minute2, ZoneId zone2, boolean expected) {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, hour1, minute1), zone1);
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, hour2, minute2), zone2);
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, hour1, minute1, 0, 0, zone1);
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, hour2, minute2, 0, 0, zone2);
         assertEquals(a.isBefore(b), expected);
         assertEquals(b.isBefore(a), false);
         assertEquals(a.isBefore(a), false);
@@ -2007,8 +2091,7 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_isBefore_null() {
-        LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
-        ZonedDateTime a = ZonedDateTime.of(ldt, ZONE_0100);
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
         a.isBefore(null);
     }
 
@@ -2026,8 +2109,8 @@
 
     @Test(dataProvider="IsAfter", groups={"tck"})
     public void test_isAfter(int hour1, int minute1, ZoneId zone1, int hour2, int minute2, ZoneId zone2, boolean expected) {
-        ZonedDateTime a = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, hour1, minute1), zone1);
-        ZonedDateTime b = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, hour2, minute2), zone2);
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, hour1, minute1, 0, 0, zone1);
+        ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, hour2, minute2, 0, 0, zone2);
         assertEquals(a.isAfter(b), expected);
         assertEquals(b.isAfter(a), false);
         assertEquals(a.isAfter(a), false);
@@ -2036,8 +2119,7 @@
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_isAfter_null() {
-        LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
-        ZonedDateTime a = ZonedDateTime.of(ldt, ZONE_0100);
+        ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
         a.isAfter(null);
     }
 
@@ -2134,7 +2216,7 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d H m s");
+        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
         String t = ZonedDateTime.of(dateTime(2010, 12, 3, 11, 30), ZONE_PARIS).toString(f);
         assertEquals(t, "2010 12 3 11 30 0");
     }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TestChrono.java b/jdk/test/java/time/tck/java/time/TestChronology.java
similarity index 75%
rename from jdk/test/java/time/tck/java/time/temporal/TestChrono.java
rename to jdk/test/java/time/tck/java/time/TestChronology.java
index cd30519..b186cd3 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TestChrono.java
+++ b/jdk/test/java/time/tck/java/time/TestChronology.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.temporal;
+package tck.java.time;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -71,36 +71,23 @@
 import java.util.Locale;
 import java.util.Set;
 
-import java.time.temporal.Chrono;
+import java.time.chrono.Chronology;
 import java.time.temporal.ChronoField;
-import java.time.calendar.HijrahChrono;
-import java.time.calendar.JapaneseChrono;
-import java.time.calendar.MinguoChrono;
-import java.time.calendar.ThaiBuddhistChrono;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.ISOChrono;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.IsoChronology;
 
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 /**
- * Test Chrono class.
+ * Test Chronology class.
  */
 @Test
-public class TestChrono {
-
-    @BeforeMethod(groups="tck")
-    public void setUp() {
-        // Ensure each of the classes are initialized (until initialization is fixed)
-        Chrono<?> c;
-        c = HijrahChrono.INSTANCE;
-        c = ISOChrono.INSTANCE;
-        c = JapaneseChrono.INSTANCE;
-        c = MinguoChrono.INSTANCE;
-        c = ThaiBuddhistChrono.INSTANCE;
-        c.toString();  // avoids variable being marked as unused
-    }
+public class TestChronology {
 
     //-----------------------------------------------------------------------
     // regular data factory for names and descriptions of available calendars
@@ -118,7 +105,7 @@
 
     @Test(dataProvider = "calendars")
     public void test_getters(String chronoId, String calendarSystemType, String description) {
-        Chrono<?> chrono = Chrono.of(chronoId);
+        Chronology chrono = Chronology.of(chronoId);
         assertNotNull(chrono, "Required calendar not found by ID: " + chronoId);
         assertEquals(chrono.getId(), chronoId);
         assertEquals(chrono.getCalendarType(), calendarSystemType);
@@ -126,23 +113,23 @@
 
     @Test(dataProvider = "calendars")
     public void test_required_calendars(String chronoId, String calendarSystemType, String description) {
-        Chrono<?> chrono = Chrono.of(chronoId);
+        Chronology chrono = Chronology.of(chronoId);
         assertNotNull(chrono, "Required calendar not found by ID: " + chronoId);
-        chrono = Chrono.of(calendarSystemType);
+        chrono = Chronology.of(calendarSystemType);
         assertNotNull(chrono, "Required calendar not found by type: " + chronoId);
-        Set<Chrono<?>> cals = Chrono.getAvailableChronologies();
+        Set<Chronology> cals = Chronology.getAvailableChronologies();
         assertTrue(cals.contains(chrono), "Required calendar not found in set of available calendars");
     }
 
     @Test(groups="tck")
     public void test_calendar_list() {
-        Set<Chrono<?>> chronos = Chrono.getAvailableChronologies();
+        Set<Chronology> chronos = Chronology.getAvailableChronologies();
         assertNotNull(chronos, "Required list of calendars must be non-null");
-        for (Chrono<?> chrono : chronos) {
-            Chrono<?> lookup = Chrono.of(chrono.getId());
+        for (Chronology chrono : chronos) {
+            Chronology lookup = Chronology.of(chrono.getId());
             assertNotNull(lookup, "Required calendar not found: " + chrono);
         }
-        assertEquals(chronos.size() >= data_of_calendars().length, true, "Chrono.getAvailableChronologies().size = " + chronos.size()
+        assertEquals(chronos.size() >= data_of_calendars().length, true, "Chronology.getAvailableChronologies().size = " + chronos.size()
                 + ", expected >= " + data_of_calendars().length);
     }
 
@@ -151,7 +138,7 @@
      */
     @Test(dataProvider = "calendars", groups="tck")
     public void test_epoch(String name, String alias, String description) {
-        Chrono<?> chrono = Chrono.of(name); // a chronology. In practice this is rarely hardcoded
+        Chronology chrono = Chronology.of(name); // a chronology. In practice this is rarely hardcoded
         ChronoLocalDate<?> date1 = chrono.dateNow();
         long epoch1 = date1.getLong(ChronoField.EPOCH_DAY);
         ChronoLocalDate<?> date2 = date1.with(ChronoField.EPOCH_DAY, epoch1);
@@ -166,41 +153,40 @@
     @DataProvider(name = "calendarsystemtype")
     Object[][] data_CalendarType() {
         return new Object[][] {
-            {HijrahChrono.INSTANCE, "islamicc"},
-            {ISOChrono.INSTANCE, "iso8601"},
-            {JapaneseChrono.INSTANCE, "japanese"},
-            {MinguoChrono.INSTANCE, "roc"},
-            {ThaiBuddhistChrono.INSTANCE, "buddhist"},
+            {HijrahChronology.INSTANCE, "islamicc"},
+            {IsoChronology.INSTANCE, "iso8601"},
+            {JapaneseChronology.INSTANCE, "japanese"},
+            {MinguoChronology.INSTANCE, "roc"},
+            {ThaiBuddhistChronology.INSTANCE, "buddhist"},
         };
     }
 
     @Test(dataProvider = "calendarsystemtype", groups="tck")
-    public void test_getCalendarType(Chrono<?> chrono, String calendarType) {
+    public void test_getCalendarType(Chronology chrono, String calendarType) {
         assertEquals(chrono.getCalendarType(), calendarType);
     }
 
     @Test(dataProvider = "calendarsystemtype", groups="tck")
-    public void test_lookupLocale(Chrono<?> chrono, String calendarType) {
+    public void test_lookupLocale(Chronology chrono, String calendarType) {
         Locale locale = new Locale.Builder().setLanguage("en").setRegion("CA").setUnicodeLocaleKeyword("ca", calendarType).build();
-        assertEquals(Chrono.ofLocale(locale), chrono);
+        assertEquals(Chronology.ofLocale(locale), chrono);
     }
 
 
     //-----------------------------------------------------------------------
     // serialization; serialize and check each calendar system
     //-----------------------------------------------------------------------
-    @Test(groups={"implementation"}, dataProvider = "calendarsystemtype")
-    public <C extends Chrono<C>> void test_chronoSerializationSingleton(C chrono, String calendarType) throws Exception {
-        C orginal = chrono;
+    @Test(groups={"tck","implementation"}, dataProvider = "calendarsystemtype")
+    public void test_chronoSerializationSingleton(Chronology chrono, String calendarType) throws Exception {
+        Chronology orginal = chrono;
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream(baos);
         out.writeObject(orginal);
         out.close();
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         ObjectInputStream in = new ObjectInputStream(bais);
-        @SuppressWarnings("unchecked")
-        C ser = (C) in.readObject();
-        assertSame(ser, chrono, "Deserialized Chrono is not the singleton serialized");
+        Chronology ser = (Chronology) in.readObject();
+        assertSame(ser, chrono, "Deserialized Chronology is not the singleton serialized");
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TestISOChrono.java b/jdk/test/java/time/tck/java/time/TestIsoChronology.java
similarity index 70%
rename from jdk/test/java/time/tck/java/time/temporal/TestISOChrono.java
rename to jdk/test/java/time/tck/java/time/TestIsoChronology.java
index 634fab3..aa42e4a 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TestISOChrono.java
+++ b/jdk/test/java/time/tck/java/time/TestIsoChronology.java
@@ -57,13 +57,13 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.temporal;
+package tck.java.time;
 
+import static java.time.chrono.IsoChronology.ERA_BCE;
+import static java.time.chrono.IsoChronology.ERA_CE;
 import static java.time.temporal.ChronoField.ERA;
 import static java.time.temporal.ChronoField.YEAR;
 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
-import static java.time.temporal.ISOChrono.ERA_BCE;
-import static java.time.temporal.ISOChrono.ERA_CE;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
@@ -73,13 +73,13 @@
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.Month;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
 import java.time.temporal.Adjusters;
-import java.time.calendar.HijrahChrono;
-import java.time.temporal.Era;
-import java.time.temporal.ISOChrono;
+import java.time.temporal.ChronoField;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.Chronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Era;
+import java.time.chrono.IsoChronology;
 
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
@@ -89,15 +89,15 @@
  * Test.
  */
 @Test
-public class TestISOChrono {
+public class TestIsoChronology {
 
     //-----------------------------------------------------------------------
-    // Chrono.ofName("ISO")  Lookup by name
+    // Chronology.ofName("ISO")  Lookup by name
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_chrono_byName() {
-        Chrono<ISOChrono> c = ISOChrono.INSTANCE;
-        Chrono<?> test = Chrono.of("ISO");
+        Chronology c = IsoChronology.INSTANCE;
+        Chronology test = Chronology.of("ISO");
         Assert.assertNotNull(test, "The ISO calendar could not be found byName");
         Assert.assertEquals(test.getId(), "ISO", "ID mismatch");
         Assert.assertEquals(test.getCalendarType(), "iso8601", "Type mismatch");
@@ -109,7 +109,7 @@
     //-----------------------------------------------------------------------
     @Test(groups="tck")
     public void instanceNotNull() {
-        assertNotNull(ISOChrono.INSTANCE);
+        assertNotNull(IsoChronology.INSTANCE);
     }
 
     //-----------------------------------------------------------------------
@@ -117,8 +117,8 @@
     //-----------------------------------------------------------------------
     @Test(groups="tck")
     public void test_eraOf() {
-        assertEquals(ISOChrono.INSTANCE.eraOf(0), ERA_BCE);
-        assertEquals(ISOChrono.INSTANCE.eraOf(1), ERA_CE);
+        assertEquals(IsoChronology.INSTANCE.eraOf(0), ERA_BCE);
+        assertEquals(IsoChronology.INSTANCE.eraOf(1), ERA_CE);
     }
 
     //-----------------------------------------------------------------------
@@ -127,31 +127,31 @@
     @DataProvider(name="samples")
     Object[][] data_samples() {
         return new Object[][] {
-            {ISOChrono.INSTANCE.date(1, 7, 8), LocalDate.of(1, 7, 8)},
-            {ISOChrono.INSTANCE.date(1, 7, 20), LocalDate.of(1, 7, 20)},
-            {ISOChrono.INSTANCE.date(1, 7, 21), LocalDate.of(1, 7, 21)},
+            {IsoChronology.INSTANCE.date(1, 7, 8), LocalDate.of(1, 7, 8)},
+            {IsoChronology.INSTANCE.date(1, 7, 20), LocalDate.of(1, 7, 20)},
+            {IsoChronology.INSTANCE.date(1, 7, 21), LocalDate.of(1, 7, 21)},
 
-            {ISOChrono.INSTANCE.date(2, 7, 8), LocalDate.of(2, 7, 8)},
-            {ISOChrono.INSTANCE.date(3, 6, 27), LocalDate.of(3, 6, 27)},
-            {ISOChrono.INSTANCE.date(3, 5, 23), LocalDate.of(3, 5, 23)},
-            {ISOChrono.INSTANCE.date(4, 6, 16), LocalDate.of(4, 6, 16)},
-            {ISOChrono.INSTANCE.date(4, 7, 3), LocalDate.of(4, 7, 3)},
-            {ISOChrono.INSTANCE.date(4, 7, 4), LocalDate.of(4, 7, 4)},
-            {ISOChrono.INSTANCE.date(5, 1, 1), LocalDate.of(5, 1, 1)},
-            {ISOChrono.INSTANCE.date(1727, 3, 3), LocalDate.of(1727, 3, 3)},
-            {ISOChrono.INSTANCE.date(1728, 10, 28), LocalDate.of(1728, 10, 28)},
-            {ISOChrono.INSTANCE.date(2012, 10, 29), LocalDate.of(2012, 10, 29)},
+            {IsoChronology.INSTANCE.date(2, 7, 8), LocalDate.of(2, 7, 8)},
+            {IsoChronology.INSTANCE.date(3, 6, 27), LocalDate.of(3, 6, 27)},
+            {IsoChronology.INSTANCE.date(3, 5, 23), LocalDate.of(3, 5, 23)},
+            {IsoChronology.INSTANCE.date(4, 6, 16), LocalDate.of(4, 6, 16)},
+            {IsoChronology.INSTANCE.date(4, 7, 3), LocalDate.of(4, 7, 3)},
+            {IsoChronology.INSTANCE.date(4, 7, 4), LocalDate.of(4, 7, 4)},
+            {IsoChronology.INSTANCE.date(5, 1, 1), LocalDate.of(5, 1, 1)},
+            {IsoChronology.INSTANCE.date(1727, 3, 3), LocalDate.of(1727, 3, 3)},
+            {IsoChronology.INSTANCE.date(1728, 10, 28), LocalDate.of(1728, 10, 28)},
+            {IsoChronology.INSTANCE.date(2012, 10, 29), LocalDate.of(2012, 10, 29)},
         };
     }
 
     @Test(dataProvider="samples", groups={"tck"})
-    public void test_toLocalDate(ChronoLocalDate<ISOChrono> isoDate, LocalDate iso) {
+    public void test_toLocalDate(LocalDate isoDate, LocalDate iso) {
         assertEquals(LocalDate.from(isoDate), iso);
     }
 
     @Test(dataProvider="samples", groups={"tck"})
-    public void test_fromCalendrical(ChronoLocalDate<ISOChrono> isoDate, LocalDate iso) {
-        assertEquals(ISOChrono.INSTANCE.date(iso), isoDate);
+    public void test_fromCalendrical(LocalDate isoDate, LocalDate iso) {
+        assertEquals(IsoChronology.INSTANCE.date(iso), isoDate);
     }
 
     @DataProvider(name="badDates")
@@ -176,7 +176,7 @@
 
     @Test(dataProvider="badDates", groups={"tck"}, expectedExceptions=DateTimeException.class)
     public void test_badDates(int year, int month, int dom) {
-        ISOChrono.INSTANCE.date(year, month, dom);
+        IsoChronology.INSTANCE.date(year, month, dom);
     }
 
     @Test(groups="tck")
@@ -184,7 +184,7 @@
         int year = 5;
         int month = 5;
         int dayOfMonth = 5;
-        ChronoLocalDate<ISOChrono> test = ISOChrono.INSTANCE.date(ERA_BCE, year, month, dayOfMonth);
+        LocalDate test = IsoChronology.INSTANCE.date(ERA_BCE, year, month, dayOfMonth);
         assertEquals(test.getEra(), ERA_BCE);
         assertEquals(test.get(ChronoField.YEAR_OF_ERA), year);
         assertEquals(test.get(ChronoField.MONTH_OF_YEAR), month);
@@ -198,7 +198,7 @@
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Test(expectedExceptions=DateTimeException.class, groups="tck")
     public void test_date_withEra_withWrongEra() {
-        ISOChrono.INSTANCE.date((Era) HijrahChrono.ERA_AH, 1, 1, 1);
+        IsoChronology.INSTANCE.date((Era) HijrahChronology.ERA_AH, 1, 1, 1);
     }
 
     //-----------------------------------------------------------------------
@@ -206,16 +206,16 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_adjust1() {
-        ChronoLocalDate<ISOChrono> base = ISOChrono.INSTANCE.date(1728, 10, 28);
-        ChronoLocalDate<ISOChrono> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, ISOChrono.INSTANCE.date(1728, 10, 31));
+        LocalDate base = IsoChronology.INSTANCE.date(1728, 10, 28);
+        LocalDate test = base.with(Adjusters.lastDayOfMonth());
+        assertEquals(test, IsoChronology.INSTANCE.date(1728, 10, 31));
     }
 
     @Test(groups={"tck"})
     public void test_adjust2() {
-        ChronoLocalDate<ISOChrono> base = ISOChrono.INSTANCE.date(1728, 12, 2);
-        ChronoLocalDate<ISOChrono> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, ISOChrono.INSTANCE.date(1728, 12, 31));
+        LocalDate base = IsoChronology.INSTANCE.date(1728, 12, 2);
+        LocalDate test = base.with(Adjusters.lastDayOfMonth());
+        assertEquals(test, IsoChronology.INSTANCE.date(1728, 12, 31));
     }
 
     //-----------------------------------------------------------------------
@@ -223,15 +223,15 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_adjust_toLocalDate() {
-        ChronoLocalDate<ISOChrono> isoDate = ISOChrono.INSTANCE.date(1726, 1, 4);
-        ChronoLocalDate<ISOChrono> test = isoDate.with(LocalDate.of(2012, 7, 6));
-        assertEquals(test, ISOChrono.INSTANCE.date(2012, 7, 6));
+        LocalDate isoDate = IsoChronology.INSTANCE.date(1726, 1, 4);
+        LocalDate test = isoDate.with(LocalDate.of(2012, 7, 6));
+        assertEquals(test, IsoChronology.INSTANCE.date(2012, 7, 6));
     }
 
     @Test(groups={"tck"})
     public void test_adjust_toMonth() {
-        ChronoLocalDate<ISOChrono> isoDate = ISOChrono.INSTANCE.date(1726, 1, 4);
-        assertEquals(ISOChrono.INSTANCE.date(1726, 4, 4), isoDate.with(Month.APRIL));
+        LocalDate isoDate = IsoChronology.INSTANCE.date(1726, 1, 4);
+        assertEquals(IsoChronology.INSTANCE.date(1726, 4, 4), isoDate.with(Month.APRIL));
     }
 
     //-----------------------------------------------------------------------
@@ -239,14 +239,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_LocalDate_adjustToISODate() {
-        ChronoLocalDate<ISOChrono> isoDate = ISOChrono.INSTANCE.date(1728, 10, 29);
+        LocalDate isoDate = IsoChronology.INSTANCE.date(1728, 10, 29);
         LocalDate test = LocalDate.MIN.with(isoDate);
         assertEquals(test, LocalDate.of(1728, 10, 29));
     }
 
     @Test(groups={"tck"})
     public void test_LocalDateTime_adjustToISODate() {
-        ChronoLocalDate<ISOChrono> isoDate = ISOChrono.INSTANCE.date(1728, 10, 29);
+        LocalDate isoDate = IsoChronology.INSTANCE.date(1728, 10, 29);
         LocalDateTime test = LocalDateTime.MIN.with(isoDate);
         assertEquals(test, LocalDateTime.of(1728, 10, 29, 0, 0));
     }
@@ -268,7 +268,7 @@
 
     @Test(dataProvider="leapYears", groups="tck")
     public void test_isLeapYear(int year, boolean isLeapYear) {
-        assertEquals(ISOChrono.INSTANCE.isLeapYear(year), isLeapYear);
+        assertEquals(IsoChronology.INSTANCE.isLeapYear(year), isLeapYear);
     }
 
     //-----------------------------------------------------------------------
@@ -276,7 +276,7 @@
     //-----------------------------------------------------------------------
     @Test(groups="tck")
     public void test_now() {
-        assertEquals(LocalDate.from(ISOChrono.INSTANCE.dateNow()), LocalDate.now());
+        assertEquals(LocalDate.from(IsoChronology.INSTANCE.dateNow()), LocalDate.now());
     }
 
     //-----------------------------------------------------------------------
@@ -285,16 +285,16 @@
     @DataProvider(name="toString")
     Object[][] data_toString() {
         return new Object[][] {
-            {ISOChrono.INSTANCE.date(1, 1, 1), "0001-01-01"},
-            {ISOChrono.INSTANCE.date(1728, 10, 28), "1728-10-28"},
-            {ISOChrono.INSTANCE.date(1728, 10, 29), "1728-10-29"},
-            {ISOChrono.INSTANCE.date(1727, 12, 5), "1727-12-05"},
-            {ISOChrono.INSTANCE.date(1727, 12, 6), "1727-12-06"},
+            {IsoChronology.INSTANCE.date(1, 1, 1), "0001-01-01"},
+            {IsoChronology.INSTANCE.date(1728, 10, 28), "1728-10-28"},
+            {IsoChronology.INSTANCE.date(1728, 10, 29), "1728-10-29"},
+            {IsoChronology.INSTANCE.date(1727, 12, 5), "1727-12-05"},
+            {IsoChronology.INSTANCE.date(1727, 12, 6), "1727-12-06"},
         };
     }
 
     @Test(dataProvider="toString", groups={"tck"})
-    public void test_toString(ChronoLocalDate<ISOChrono> isoDate, String expected) {
+    public void test_toString(LocalDate isoDate, String expected) {
         assertEquals(isoDate.toString(), expected);
     }
 
@@ -303,12 +303,12 @@
     //-----------------------------------------------------------------------
     @Test(groups="tck")
     public void test_equals_true() {
-        assertTrue(ISOChrono.INSTANCE.equals(ISOChrono.INSTANCE));
+        assertTrue(IsoChronology.INSTANCE.equals(IsoChronology.INSTANCE));
     }
 
     @Test(groups="tck")
     public void test_equals_false() {
-        assertFalse(ISOChrono.INSTANCE.equals(HijrahChrono.INSTANCE));
+        assertFalse(IsoChronology.INSTANCE.equals(HijrahChronology.INSTANCE));
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/calendar/TestJapaneseChrono.java b/jdk/test/java/time/tck/java/time/calendar/TestJapaneseChrono.java
deleted file mode 100644
index 614a3ff..0000000
--- a/jdk/test/java/time/tck/java/time/calendar/TestJapaneseChrono.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package tck.java.time.calendar;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.util.List;
-
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.Month;
-import java.time.calendar.JapaneseChrono;
-import java.time.temporal.Adjusters;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
-import java.time.temporal.ISOChrono;
-
-import org.testng.Assert;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * Test.
- */
-@Test
-public class TestJapaneseChrono {
-
-    //-----------------------------------------------------------------------
-    // Chrono.ofName("Japanese")  Lookup by name
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_chrono_byName() {
-        Chrono<JapaneseChrono> c = JapaneseChrono.INSTANCE;
-        Chrono<?> test = Chrono.of("Japanese");
-        Assert.assertNotNull(test, "The Japanese calendar could not be found byName");
-        Assert.assertEquals(test.getId(), "Japanese", "ID mismatch");
-        Assert.assertEquals(test.getCalendarType(), "japanese", "Type mismatch");
-        Assert.assertEquals(test, c);
-    }
-
-    //-----------------------------------------------------------------------
-    // creation, toLocalDate()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="samples")
-    Object[][] data_samples() {
-        return new Object[][] {
-            {JapaneseChrono.INSTANCE.date(1, 1, 1), LocalDate.of(1, 1, 1)},
-            {JapaneseChrono.INSTANCE.date(1, 1, 2), LocalDate.of(1, 1, 2)},
-            {JapaneseChrono.INSTANCE.date(1, 1, 3), LocalDate.of(1, 1, 3)},
-
-            {JapaneseChrono.INSTANCE.date(2, 1, 1), LocalDate.of(2, 1, 1)},
-            {JapaneseChrono.INSTANCE.date(3, 1, 1), LocalDate.of(3, 1, 1)},
-            {JapaneseChrono.INSTANCE.date(3, 12, 6), LocalDate.of(3, 12, 6)},
-            {JapaneseChrono.INSTANCE.date(4, 1, 1), LocalDate.of(4, 1, 1)},
-            {JapaneseChrono.INSTANCE.date(4, 7, 3), LocalDate.of(4, 7, 3)},
-            {JapaneseChrono.INSTANCE.date(4, 7, 4), LocalDate.of(4, 7, 4)},
-            {JapaneseChrono.INSTANCE.date(5, 1, 1), LocalDate.of(5, 1, 1)},
-            {JapaneseChrono.INSTANCE.date(1662, 3, 3), LocalDate.of(1662, 3, 3)},
-            {JapaneseChrono.INSTANCE.date(1728, 10, 28), LocalDate.of(1728, 10, 28)},
-            {JapaneseChrono.INSTANCE.date(1728, 10, 29), LocalDate.of(1728, 10, 29)},
-        };
-    }
-
-    @Test(dataProvider="samples", groups={"tck"})
-    public void test_toLocalDate(ChronoLocalDate<JapaneseChrono> jdate, LocalDate iso) {
-        assertEquals(LocalDate.from(jdate), iso);
-    }
-
-    @Test(dataProvider="samples", groups={"tck"})
-    public void test_fromCalendrical(ChronoLocalDate<JapaneseChrono> jdate, LocalDate iso) {
-        assertEquals(JapaneseChrono.INSTANCE.date(iso), jdate);
-    }
-
-    @DataProvider(name="badDates")
-    Object[][] data_badDates() {
-        return new Object[][] {
-            {1728, 0, 0},
-
-            {1728, -1, 1},
-            {1728, 0, 1},
-            {1728, 14, 1},
-            {1728, 15, 1},
-
-            {1728, 1, -1},
-            {1728, 1, 0},
-            {1728, 1, 32},
-
-            {1728, 12, -1},
-            {1728, 12, 0},
-            {1728, 12, 32},
-        };
-    }
-
-    @Test(dataProvider="badDates", groups={"tck"}, expectedExceptions=DateTimeException.class)
-    public void test_badDates(int year, int month, int dom) {
-        JapaneseChrono.INSTANCE.date(year, month, dom);
-    }
-
-    //-----------------------------------------------------------------------
-    // with(WithAdjuster)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_adjust1() {
-        ChronoLocalDate<JapaneseChrono> base = JapaneseChrono.INSTANCE.date(1728, 10, 29);
-        ChronoLocalDate<JapaneseChrono> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, JapaneseChrono.INSTANCE.date(1728, 10, 31));
-    }
-
-    @Test(groups={"tck"})
-    public void test_adjust2() {
-        ChronoLocalDate<JapaneseChrono> base = JapaneseChrono.INSTANCE.date(1728, 12, 2);
-        ChronoLocalDate<JapaneseChrono> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, JapaneseChrono.INSTANCE.date(1728, 12, 31));
-    }
-
-    //-----------------------------------------------------------------------
-    // JapaneseDate.with(Local*)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_adjust_toLocalDate() {
-        ChronoLocalDate<JapaneseChrono> jdate = JapaneseChrono.INSTANCE.date(1726, 1, 4);
-        ChronoLocalDate<JapaneseChrono> test = jdate.with(LocalDate.of(2012, 7, 6));
-        assertEquals(test, JapaneseChrono.INSTANCE.date(2012, 7, 6));
-    }
-
-    @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
-    public void test_adjust_toMonth() {
-        ChronoLocalDate<?> jdate = JapaneseChrono.INSTANCE.date(1726, 1, 4);
-        jdate.with(Month.APRIL);
-    }
-
-    //-----------------------------------------------------------------------
-    // LocalDate.with(JapaneseDate)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_LocalDate_adjustToJapaneseDate() {
-        ChronoLocalDate<JapaneseChrono> jdate = JapaneseChrono.INSTANCE.date(1728, 10, 29);
-        LocalDate test = LocalDate.MIN.with(jdate);
-        assertEquals(test, LocalDate.of(1728, 10, 29));
-    }
-
-    @Test(groups={"tck"})
-    public void test_LocalDateTime_adjustToJapaneseDate() {
-        ChronoLocalDate<JapaneseChrono> jdate = JapaneseChrono.INSTANCE.date(1728, 10, 29);
-        LocalDateTime test = LocalDateTime.MIN.with(jdate);
-        assertEquals(test, LocalDateTime.of(1728, 10, 29, 0, 0));
-    }
-
-    //-----------------------------------------------------------------------
-    // Check Japanese Eras
-    //-----------------------------------------------------------------------
-    @DataProvider(name="japaneseEras")
-    Object[][] data_japanseseEras() {
-        return new Object[][] {
-            { JapaneseChrono.ERA_SEIREKI, -999, "Seireki"},
-            { JapaneseChrono.ERA_MEIJI, -1, "Meiji"},
-            { JapaneseChrono.ERA_TAISHO, 0, "Taisho"},
-            { JapaneseChrono.ERA_SHOWA, 1, "Showa"},
-            { JapaneseChrono.ERA_HEISEI, 2, "Heisei"},
-        };
-    }
-
-    @Test(groups={"tck"}, dataProvider="japaneseEras")
-    public void test_Japanese_Eras(Era era, int eraValue, String name) {
-        assertEquals(era.getValue(), eraValue, "EraValue");
-        assertEquals(era.toString(), name, "Era Name");
-        assertEquals(era, JapaneseChrono.INSTANCE.eraOf(eraValue), "JapaneseChrono.eraOf()");
-        List<Era<JapaneseChrono>> eras = JapaneseChrono.INSTANCE.eras();
-        assertTrue(eras.contains(era), "Era is not present in JapaneseChrono.INSTANCE.eras()");
-    }
-
-    @Test(groups="tck")
-    public void test_Japanese_badEras() {
-        int badEras[] = {-1000, -998, -997, -2, 3, 4, 1000};
-        for (int badEra : badEras) {
-            try {
-                Era<JapaneseChrono> era = JapaneseChrono.INSTANCE.eraOf(badEra);
-                fail("JapaneseChrono.eraOf returned " + era + " + for invalid eraValue " + badEra);
-            } catch (DateTimeException ex) {
-                // ignore expected exception
-            }
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    // toString()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="toString")
-    Object[][] data_toString() {
-        return new Object[][] {
-            {JapaneseChrono.INSTANCE.date(0001,  1,  1), "Japanese 0001-01-01"},
-            {JapaneseChrono.INSTANCE.date(1728, 10, 28), "Japanese 1728-10-28"},
-            {JapaneseChrono.INSTANCE.date(1728, 10, 29), "Japanese 1728-10-29"},
-            {JapaneseChrono.INSTANCE.date(1727, 12,  5), "Japanese 1727-12-05"},
-            {JapaneseChrono.INSTANCE.date(1727, 12,  6), "Japanese 1727-12-06"},
-            {JapaneseChrono.INSTANCE.date(1868,  9,  8), "Japanese Meiji 1-09-08"},
-            {JapaneseChrono.INSTANCE.date(1912,  7, 29), "Japanese Meiji 45-07-29"},
-            {JapaneseChrono.INSTANCE.date(1912,  7, 30), "Japanese Taisho 1-07-30"},
-            {JapaneseChrono.INSTANCE.date(1926, 12, 24), "Japanese Taisho 15-12-24"},
-            {JapaneseChrono.INSTANCE.date(1926, 12, 25), "Japanese Showa 1-12-25"},
-            {JapaneseChrono.INSTANCE.date(1989,  1,  7), "Japanese Showa 64-01-07"},
-            {JapaneseChrono.INSTANCE.date(1989,  1,  8), "Japanese Heisei 1-01-08"},
-            {JapaneseChrono.INSTANCE.date(2012, 12,  6), "Japanese Heisei 24-12-06"},
-        };
-    }
-
-    @Test(dataProvider="toString", groups={"tck"})
-    public void test_toString(ChronoLocalDate<JapaneseChrono> jdate, String expected) {
-        assertEquals(jdate.toString(), expected);
-    }
-
-    //-----------------------------------------------------------------------
-    // equals()
-    //-----------------------------------------------------------------------
-    @Test(groups="tck")
-    public void test_equals_true() {
-        assertTrue(JapaneseChrono.INSTANCE.equals(JapaneseChrono.INSTANCE));
-    }
-
-    @Test(groups="tck")
-    public void test_equals_false() {
-        assertFalse(JapaneseChrono.INSTANCE.equals(ISOChrono.INSTANCE));
-    }
-
-}
diff --git a/jdk/test/java/time/tck/java/time/calendar/TestMinguoChrono.java b/jdk/test/java/time/tck/java/time/calendar/TestMinguoChrono.java
deleted file mode 100644
index 118f7d8..0000000
--- a/jdk/test/java/time/tck/java/time/calendar/TestMinguoChrono.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package tck.java.time.calendar;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.Month;
-import java.time.ZoneOffset;
-import java.time.calendar.MinguoChrono;
-import java.time.temporal.Adjusters;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.ChronoZonedDateTime;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.ChronoLocalDateTime;
-import java.time.temporal.ISOChrono;
-
-import org.testng.Assert;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * Test.
- */
-@Test
-public class TestMinguoChrono {
-
-    //-----------------------------------------------------------------------
-    // Chrono.ofName("Minguo")  Lookup by name
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_chrono_byName() {
-        Chrono<MinguoChrono> c = MinguoChrono.INSTANCE;
-        Chrono<?> test = Chrono.of("Minguo");
-        Assert.assertNotNull(test, "The Minguo calendar could not be found byName");
-        Assert.assertEquals(test.getId(), "Minguo", "ID mismatch");
-        Assert.assertEquals(test.getCalendarType(), "roc", "Type mismatch");
-        Assert.assertEquals(test, c);
-    }
-
-    //-----------------------------------------------------------------------
-    // creation, toLocalDate()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="samples")
-    Object[][] data_samples() {
-        return new Object[][] {
-            {MinguoChrono.INSTANCE.date(1, 1, 1), LocalDate.of(1912, 1, 1)},
-            {MinguoChrono.INSTANCE.date(1, 1, 2), LocalDate.of(1912, 1, 2)},
-            {MinguoChrono.INSTANCE.date(1, 1, 3), LocalDate.of(1912, 1, 3)},
-
-            {MinguoChrono.INSTANCE.date(2, 1, 1), LocalDate.of(1913, 1, 1)},
-            {MinguoChrono.INSTANCE.date(3, 1, 1), LocalDate.of(1914, 1, 1)},
-            {MinguoChrono.INSTANCE.date(3, 12, 6), LocalDate.of(1914, 12, 6)},
-            {MinguoChrono.INSTANCE.date(4, 1, 1), LocalDate.of(1915, 1, 1)},
-            {MinguoChrono.INSTANCE.date(4, 7, 3), LocalDate.of(1915, 7, 3)},
-            {MinguoChrono.INSTANCE.date(4, 7, 4), LocalDate.of(1915, 7, 4)},
-            {MinguoChrono.INSTANCE.date(5, 1, 1), LocalDate.of(1916, 1, 1)},
-            {MinguoChrono.INSTANCE.date(100, 3, 3), LocalDate.of(2011, 3, 3)},
-            {MinguoChrono.INSTANCE.date(101, 10, 28), LocalDate.of(2012, 10, 28)},
-            {MinguoChrono.INSTANCE.date(101, 10, 29), LocalDate.of(2012, 10, 29)},
-        };
-    }
-
-    @Test(dataProvider="samples", groups={"tck"})
-    public void test_toLocalDate(ChronoLocalDate<MinguoChrono> minguo, LocalDate iso) {
-        assertEquals(LocalDate.from(minguo), iso);
-    }
-
-    @Test(dataProvider="samples", groups={"tck"})
-    public void test_fromCalendrical(ChronoLocalDate<MinguoChrono> minguo, LocalDate iso) {
-        assertEquals(MinguoChrono.INSTANCE.date(iso), minguo);
-    }
-
-    @SuppressWarnings("unused")
-    @Test(dataProvider="samples", groups={"implementation"})
-    public void test_MinguoDate(ChronoLocalDate<MinguoChrono> minguoDate, LocalDate iso) {
-        ChronoLocalDate<MinguoChrono> hd = minguoDate;
-        ChronoLocalDateTime<MinguoChrono> hdt = hd.atTime(LocalTime.NOON);
-        ZoneOffset zo = ZoneOffset.ofHours(1);
-        ChronoZonedDateTime<MinguoChrono> hzdt = hdt.atZone(zo);
-        hdt = hdt.plus(1, ChronoUnit.YEARS);
-        hdt = hdt.plus(1, ChronoUnit.MONTHS);
-        hdt = hdt.plus(1, ChronoUnit.DAYS);
-        hdt = hdt.plus(1, ChronoUnit.HOURS);
-        hdt = hdt.plus(1, ChronoUnit.MINUTES);
-        hdt = hdt.plus(1, ChronoUnit.SECONDS);
-        hdt = hdt.plus(1, ChronoUnit.NANOS);
-        ChronoLocalDateTime<MinguoChrono> a2 = hzdt.getDateTime();
-        ChronoLocalDate<MinguoChrono> a3 = a2.getDate();
-        ChronoLocalDate<MinguoChrono> a5 = hzdt.getDate();
-        //System.out.printf(" d: %s, dt: %s; odt: %s; zodt: %s; a4: %s%n", date, hdt, hodt, hzdt, a5);
-    }
-
-    @Test()
-    public void test_MinguoChrono() {
-        ChronoLocalDate<MinguoChrono> h1 = MinguoChrono.ERA_ROC.date(1, 2, 3);
-        ChronoLocalDate<MinguoChrono> h2 = h1;
-        ChronoLocalDateTime<MinguoChrono> h3 = h2.atTime(LocalTime.NOON);
-        @SuppressWarnings("unused")
-        ChronoZonedDateTime<MinguoChrono> h4 = h3.atZone(ZoneOffset.UTC);
-    }
-
-    @DataProvider(name="badDates")
-    Object[][] data_badDates() {
-        return new Object[][] {
-            {1912, 0, 0},
-
-            {1912, -1, 1},
-            {1912, 0, 1},
-            {1912, 14, 1},
-            {1912, 15, 1},
-
-            {1912, 1, -1},
-            {1912, 1, 0},
-            {1912, 1, 32},
-            {1912, 2, 29},
-            {1912, 2, 30},
-
-            {1912, 12, -1},
-            {1912, 12, 0},
-            {1912, 12, 32},
-            };
-    }
-
-    @Test(dataProvider="badDates", groups={"tck"}, expectedExceptions=DateTimeException.class)
-    public void test_badDates(int year, int month, int dom) {
-        MinguoChrono.INSTANCE.date(year, month, dom);
-    }
-
-    //-----------------------------------------------------------------------
-    // with(DateTimeAdjuster)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_adjust1() {
-        ChronoLocalDate<MinguoChrono> base = MinguoChrono.INSTANCE.date(2012, 10, 29);
-        ChronoLocalDate<MinguoChrono> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, MinguoChrono.INSTANCE.date(2012, 10, 31));
-    }
-
-    @Test(groups={"tck"})
-    public void test_adjust2() {
-        ChronoLocalDate<MinguoChrono> base = MinguoChrono.INSTANCE.date(1728, 12, 2);
-        ChronoLocalDate<MinguoChrono> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, MinguoChrono.INSTANCE.date(1728, 12, 31));
-    }
-
-    //-----------------------------------------------------------------------
-    // MinguoDate.with(Local*)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_adjust_toLocalDate() {
-        ChronoLocalDate<MinguoChrono> minguo = MinguoChrono.INSTANCE.date(99, 1, 4);
-        ChronoLocalDate<MinguoChrono> test = minguo.with(LocalDate.of(2012, 7, 6));
-        assertEquals(test, MinguoChrono.INSTANCE.date(101, 7, 6));
-    }
-
-    @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
-    public void test_adjust_toMonth() {
-        ChronoLocalDate<MinguoChrono> minguo = MinguoChrono.INSTANCE.date(1726, 1, 4);
-        minguo.with(Month.APRIL);
-    }
-
-    //-----------------------------------------------------------------------
-    // LocalDate.with(MinguoDate)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_LocalDate_adjustToMinguoDate() {
-        ChronoLocalDate<MinguoChrono> minguo = MinguoChrono.INSTANCE.date(101, 10, 29);
-        LocalDate test = LocalDate.MIN.with(minguo);
-        assertEquals(test, LocalDate.of(2012, 10, 29));
-    }
-
-    @Test(groups={"tck"})
-    public void test_LocalDateTime_adjustToMinguoDate() {
-        ChronoLocalDate<MinguoChrono> minguo = MinguoChrono.INSTANCE.date(101, 10, 29);
-        LocalDateTime test = LocalDateTime.MIN.with(minguo);
-        assertEquals(test, LocalDateTime.of(2012, 10, 29, 0, 0));
-    }
-
-    //-----------------------------------------------------------------------
-    // toString()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="toString")
-    Object[][] data_toString() {
-        return new Object[][] {
-            {MinguoChrono.INSTANCE.date(1, 1, 1), "Minguo ROC 1-01-01"},
-            {MinguoChrono.INSTANCE.date(1728, 10, 28), "Minguo ROC 1728-10-28"},
-            {MinguoChrono.INSTANCE.date(1728, 10, 29), "Minguo ROC 1728-10-29"},
-            {MinguoChrono.INSTANCE.date(1727, 12, 5), "Minguo ROC 1727-12-05"},
-            {MinguoChrono.INSTANCE.date(1727, 12, 6), "Minguo ROC 1727-12-06"},
-        };
-    }
-
-    @Test(dataProvider="toString", groups={"tck"})
-    public void test_toString(ChronoLocalDate<MinguoChrono> minguo, String expected) {
-        assertEquals(minguo.toString(), expected);
-    }
-
-    //-----------------------------------------------------------------------
-    // equals()
-    //-----------------------------------------------------------------------
-    @Test(groups="tck")
-    public void test_equals_true() {
-        assertTrue(MinguoChrono.INSTANCE.equals(MinguoChrono.INSTANCE));
-    }
-
-    @Test(groups="tck")
-    public void test_equals_false() {
-        assertFalse(MinguoChrono.INSTANCE.equals(ISOChrono.INSTANCE));
-    }
-
-}
diff --git a/jdk/test/java/time/tck/java/time/calendar/TestServiceLoader.java b/jdk/test/java/time/tck/java/time/calendar/TestServiceLoader.java
deleted file mode 100644
index b7381b7..0000000
--- a/jdk/test/java/time/tck/java/time/calendar/TestServiceLoader.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package tck.java.time.calendar;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.fail;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.time.LocalDate;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.ISOChrono;
-import java.time.DateTimeException;
-
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-/**
- * Tests that a custom Chronology is available via the ServiceLoader.
- * The CopticChrono is configured via META-INF/services/java.time.temporal.Chrono.
- */
-@Test
-public class TestServiceLoader {
-
-     @Test(groups={"tck"})
-     public void test_CopticServiceLoader() {
-        Chrono chrono = Chrono.of("Coptic");
-        ChronoLocalDate<?> copticDate = chrono.date(1729, 4, 27);
-        LocalDate ld = LocalDate.from(copticDate);
-        assertEquals(ld, LocalDate.of(2013, 1, 5), "CopticDate does not match LocalDate");
-    }
-
-    @Test(groups="implementation")
-    public void test_copticServiceLoader() {
-        Map<String, Chrono> chronos = new HashMap<>();
-        ServiceLoader<Chrono> loader = ServiceLoader.load(Chrono.class, null);
-        for (Chrono<?> chrono : loader) {
-            chronos.put(chrono.getId(), chrono);
-        }
-        assertNotNull(chronos.get("Coptic"), "CopticChrono not found");
-    }
-
-}
diff --git a/jdk/test/java/time/tck/java/time/calendar/TestThaiBuddhistChrono.java b/jdk/test/java/time/tck/java/time/calendar/TestThaiBuddhistChrono.java
deleted file mode 100644
index 4d20f57..0000000
--- a/jdk/test/java/time/tck/java/time/calendar/TestThaiBuddhistChrono.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  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.
- */
-
-/*
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package tck.java.time.calendar;
-
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.DAY_OF_YEAR;
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.YEAR;
-import static java.time.temporal.ChronoField.YEAR_OF_ERA;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.Month;
-import java.time.calendar.ThaiBuddhistChrono;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Adjusters;
-import java.time.temporal.ValueRange;
-import java.time.temporal.ISOChrono;
-
-import org.testng.Assert;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * Test.
- */
-@Test
-public class TestThaiBuddhistChrono {
-
-    private static final int YDIFF = 543;
-
-    //-----------------------------------------------------------------------
-    // Chrono.ofName("ThaiBuddhist")  Lookup by name
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_chrono_byName() {
-        Chrono<ThaiBuddhistChrono> c = ThaiBuddhistChrono.INSTANCE;
-        Chrono<?> test = Chrono.of("ThaiBuddhist");
-        Assert.assertNotNull(test, "The ThaiBuddhist calendar could not be found byName");
-        Assert.assertEquals(test.getId(), "ThaiBuddhist", "ID mismatch");
-        Assert.assertEquals(test.getCalendarType(), "buddhist", "Type mismatch");
-        Assert.assertEquals(test, c);
-    }
-
-    //-----------------------------------------------------------------------
-    // creation, toLocalDate()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="samples")
-    Object[][] data_samples() {
-        return new Object[][] {
-            {ThaiBuddhistChrono.INSTANCE.date(1 + YDIFF, 1, 1), LocalDate.of(1, 1, 1)},
-            {ThaiBuddhistChrono.INSTANCE.date(1 + YDIFF, 1, 2), LocalDate.of(1, 1, 2)},
-            {ThaiBuddhistChrono.INSTANCE.date(1 + YDIFF, 1, 3), LocalDate.of(1, 1, 3)},
-
-            {ThaiBuddhistChrono.INSTANCE.date(2 + YDIFF, 1, 1), LocalDate.of(2, 1, 1)},
-            {ThaiBuddhistChrono.INSTANCE.date(3 + YDIFF, 1, 1), LocalDate.of(3, 1, 1)},
-            {ThaiBuddhistChrono.INSTANCE.date(3 + YDIFF, 12, 6), LocalDate.of(3, 12, 6)},
-            {ThaiBuddhistChrono.INSTANCE.date(4 + YDIFF, 1, 1), LocalDate.of(4, 1, 1)},
-            {ThaiBuddhistChrono.INSTANCE.date(4 + YDIFF, 7, 3), LocalDate.of(4, 7, 3)},
-            {ThaiBuddhistChrono.INSTANCE.date(4 + YDIFF, 7, 4), LocalDate.of(4, 7, 4)},
-            {ThaiBuddhistChrono.INSTANCE.date(5 + YDIFF, 1, 1), LocalDate.of(5, 1, 1)},
-            {ThaiBuddhistChrono.INSTANCE.date(1662 + YDIFF, 3, 3), LocalDate.of(1662, 3, 3)},
-            {ThaiBuddhistChrono.INSTANCE.date(1728 + YDIFF, 10, 28), LocalDate.of(1728, 10, 28)},
-            {ThaiBuddhistChrono.INSTANCE.date(1728 + YDIFF, 10, 29), LocalDate.of(1728, 10, 29)},
-            {ThaiBuddhistChrono.INSTANCE.date(2555, 8, 29), LocalDate.of(2012, 8, 29)},
-        };
-    }
-
-    @Test(dataProvider="samples", groups={"tck"})
-    public void test_toLocalDate(ChronoLocalDate<ThaiBuddhistChrono> jdate, LocalDate iso) {
-        assertEquals(LocalDate.from(jdate), iso);
-    }
-
-    @Test(dataProvider="samples", groups={"tck"})
-    public void test_fromCalendrical(ChronoLocalDate<ThaiBuddhistChrono> jdate, LocalDate iso) {
-        assertEquals(ThaiBuddhistChrono.INSTANCE.date(iso), jdate);
-    }
-
-    @DataProvider(name="badDates")
-    Object[][] data_badDates() {
-        return new Object[][] {
-            {1728, 0, 0},
-
-            {1728, -1, 1},
-            {1728, 0, 1},
-            {1728, 14, 1},
-            {1728, 15, 1},
-
-            {1728, 1, -1},
-            {1728, 1, 0},
-            {1728, 1, 32},
-
-            {1728, 12, -1},
-            {1728, 12, 0},
-            {1728, 12, 32},
-        };
-    }
-
-    @Test(dataProvider="badDates", groups={"tck"}, expectedExceptions=DateTimeException.class)
-    public void test_badDates(int year, int month, int dom) {
-        ThaiBuddhistChrono.INSTANCE.date(year, month, dom);
-    }
-
-    //-----------------------------------------------------------------------
-    // with(WithAdjuster)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_adjust1() {
-        ChronoLocalDate<ThaiBuddhistChrono> base = ThaiBuddhistChrono.INSTANCE.date(1728, 10, 29);
-        ChronoLocalDate<ThaiBuddhistChrono> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, ThaiBuddhistChrono.INSTANCE.date(1728, 10, 31));
-    }
-
-    @Test(groups={"tck"})
-    public void test_adjust2() {
-        ChronoLocalDate<ThaiBuddhistChrono> base = ThaiBuddhistChrono.INSTANCE.date(1728, 12, 2);
-        ChronoLocalDate<ThaiBuddhistChrono> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, ThaiBuddhistChrono.INSTANCE.date(1728, 12, 31));
-    }
-
-    //-----------------------------------------------------------------------
-    // withYear()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_withYear_BE() {
-        ChronoLocalDate<ThaiBuddhistChrono> base = ThaiBuddhistChrono.INSTANCE.date(2555, 8, 29);
-        ChronoLocalDate<ThaiBuddhistChrono> test = base.with(YEAR, 2554);
-        assertEquals(test, ThaiBuddhistChrono.INSTANCE.date(2554, 8, 29));
-    }
-
-    @Test(groups={"tck"})
-    public void test_withYear_BBE() {
-        ChronoLocalDate<ThaiBuddhistChrono> base = ThaiBuddhistChrono.INSTANCE.date(-2554, 8, 29);
-        ChronoLocalDate<ThaiBuddhistChrono> test = base.with(YEAR_OF_ERA, 2554);
-        assertEquals(test, ThaiBuddhistChrono.INSTANCE.date(-2553, 8, 29));
-    }
-
-    //-----------------------------------------------------------------------
-    // withEra()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_withEra_BE() {
-        ChronoLocalDate<ThaiBuddhistChrono> base = ThaiBuddhistChrono.INSTANCE.date(2555, 8, 29);
-        ChronoLocalDate<ThaiBuddhistChrono> test = base.with(ChronoField.ERA, ThaiBuddhistChrono.ERA_BE.getValue());
-        assertEquals(test, ThaiBuddhistChrono.INSTANCE.date(2555, 8, 29));
-    }
-
-    @Test(groups={"tck"})
-    public void test_withEra_BBE() {
-        ChronoLocalDate<ThaiBuddhistChrono> base = ThaiBuddhistChrono.INSTANCE.date(-2554, 8, 29);
-        ChronoLocalDate<ThaiBuddhistChrono> test = base.with(ChronoField.ERA, ThaiBuddhistChrono.ERA_BEFORE_BE.getValue());
-        assertEquals(test, ThaiBuddhistChrono.INSTANCE.date(-2554, 8, 29));
-    }
-
-    @Test(groups={"tck"})
-    public void test_withEra_swap() {
-        ChronoLocalDate<ThaiBuddhistChrono> base = ThaiBuddhistChrono.INSTANCE.date(-2554, 8, 29);
-        ChronoLocalDate<ThaiBuddhistChrono> test = base.with(ChronoField.ERA, ThaiBuddhistChrono.ERA_BE.getValue());
-        assertEquals(test, ThaiBuddhistChrono.INSTANCE.date(2555, 8, 29));
-    }
-
-    //-----------------------------------------------------------------------
-    // BuddhistDate.with(Local*)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_adjust_toLocalDate() {
-        ChronoLocalDate<ThaiBuddhistChrono> jdate = ThaiBuddhistChrono.INSTANCE.date(1726, 1, 4);
-        ChronoLocalDate<ThaiBuddhistChrono> test = jdate.with(LocalDate.of(2012, 7, 6));
-        assertEquals(test, ThaiBuddhistChrono.INSTANCE.date(2555, 7, 6));
-    }
-
-    @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
-    public void test_adjust_toMonth() {
-        ChronoLocalDate<ThaiBuddhistChrono> jdate = ThaiBuddhistChrono.INSTANCE.date(1726, 1, 4);
-        jdate.with(Month.APRIL);
-    }
-
-    //-----------------------------------------------------------------------
-    // LocalDate.with(BuddhistDate)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_LocalDate_adjustToBuddhistDate() {
-        ChronoLocalDate<ThaiBuddhistChrono> jdate = ThaiBuddhistChrono.INSTANCE.date(2555, 10, 29);
-        LocalDate test = LocalDate.MIN.with(jdate);
-        assertEquals(test, LocalDate.of(2012, 10, 29));
-    }
-
-    @Test(groups={"tck"})
-    public void test_LocalDateTime_adjustToBuddhistDate() {
-        ChronoLocalDate<ThaiBuddhistChrono> jdate = ThaiBuddhistChrono.INSTANCE.date(2555, 10, 29);
-        LocalDateTime test = LocalDateTime.MIN.with(jdate);
-        assertEquals(test, LocalDateTime.of(2012, 10, 29, 0, 0));
-    }
-
-    //-----------------------------------------------------------------------
-    // toString()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="toString")
-    Object[][] data_toString() {
-        return new Object[][] {
-            {ThaiBuddhistChrono.INSTANCE.date(544, 1, 1), "ThaiBuddhist BE 544-01-01"},
-            {ThaiBuddhistChrono.INSTANCE.date(2271, 10, 28), "ThaiBuddhist BE 2271-10-28"},
-            {ThaiBuddhistChrono.INSTANCE.date(2271, 10, 29), "ThaiBuddhist BE 2271-10-29"},
-            {ThaiBuddhistChrono.INSTANCE.date(2270, 12, 5), "ThaiBuddhist BE 2270-12-05"},
-            {ThaiBuddhistChrono.INSTANCE.date(2270, 12, 6), "ThaiBuddhist BE 2270-12-06"},
-        };
-    }
-
-    @Test(dataProvider="toString", groups={"tck"})
-    public void test_toString(ChronoLocalDate<ThaiBuddhistChrono> jdate, String expected) {
-        assertEquals(jdate.toString(), expected);
-    }
-
-    //-----------------------------------------------------------------------
-    // chronology range(ChronoField)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_Chrono_range() {
-        long minYear = LocalDate.MIN.getYear() + YDIFF;
-        long maxYear = LocalDate.MAX.getYear() + YDIFF;
-        assertEquals(ThaiBuddhistChrono.INSTANCE.range(YEAR), ValueRange.of(minYear, maxYear));
-        assertEquals(ThaiBuddhistChrono.INSTANCE.range(YEAR_OF_ERA), ValueRange.of(1, -minYear + 1, maxYear));
-
-        assertEquals(ThaiBuddhistChrono.INSTANCE.range(DAY_OF_MONTH), DAY_OF_MONTH.range());
-        assertEquals(ThaiBuddhistChrono.INSTANCE.range(DAY_OF_YEAR), DAY_OF_YEAR.range());
-        assertEquals(ThaiBuddhistChrono.INSTANCE.range(MONTH_OF_YEAR), MONTH_OF_YEAR.range());
-    }
-
-    //-----------------------------------------------------------------------
-    // equals()
-    //-----------------------------------------------------------------------
-    @Test(groups="tck")
-    public void test_equals_true() {
-        assertTrue(ThaiBuddhistChrono.INSTANCE.equals(ThaiBuddhistChrono.INSTANCE));
-    }
-
-    @Test(groups="tck")
-    public void test_equals_false() {
-        assertFalse(ThaiBuddhistChrono.INSTANCE.equals(ISOChrono.INSTANCE));
-    }
-
-}
diff --git a/jdk/test/java/time/tck/java/time/calendar/CopticChrono.java b/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java
similarity index 87%
rename from jdk/test/java/time/tck/java/time/calendar/CopticChrono.java
rename to jdk/test/java/time/tck/java/time/chrono/CopticChronology.java
index c3dc941..5c55d75 100644
--- a/jdk/test/java/time/tck/java/time/calendar/CopticChrono.java
+++ b/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java
@@ -54,7 +54,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package tck.java.time.calendar;
+package tck.java.time.chrono;
 
 import static java.time.temporal.ChronoField.EPOCH_DAY;
 
@@ -67,9 +67,9 @@
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.ValueRange;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
+import java.time.chrono.Chronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Era;
 
 /**
  * The Coptic calendar system.
@@ -96,22 +96,22 @@
  * <h4>Implementation notes</h4>
  * This class is immutable and thread-safe.
  */
-public final class CopticChrono extends Chrono<CopticChrono> implements Serializable {
+public final class CopticChronology extends Chronology implements Serializable {
 
     /**
      * Singleton instance of the Coptic chronology.
      */
-    public static final CopticChrono INSTANCE = new CopticChrono();
+    public static final CopticChronology INSTANCE = new CopticChronology();
     /**
      * The singleton instance for the era BEFORE_AM.
      * This has the numeric value of {@code 0}.
      */
-    public static final Era<CopticChrono> ERA_BEFORE_AM = CopticEra.BEFORE_AM;
+    public static final Era ERA_BEFORE_AM = CopticEra.BEFORE_AM;
     /**
      * The singleton instance for the era AM - 'Era of the Martyrs'.
      * This has the numeric value of {@code 1}.
      */
-    public static final Era<CopticChrono> ERA_AM = CopticEra.AM;
+    public static final Era ERA_AM = CopticEra.AM;
 
     /**
      * Serialization version.
@@ -137,7 +137,7 @@
     /**
      * Public Constructor to be instantiated by the ServiceLoader
      */
-    public CopticChrono() {
+    public CopticChronology() {
     }
 
     /**
@@ -153,8 +153,8 @@
     /**
      * Gets the ID of the chronology - 'Coptic'.
      * <p>
-     * The ID uniquely identifies the {@code Chrono}.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * The ID uniquely identifies the {@code Chronology}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      *
      * @return the chronology ID - 'Coptic'
      * @see #getCalendarType()
@@ -169,7 +169,7 @@
      * <p>
      * The calendar type is an identifier defined by the
      * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
-     * It can be used to lookup the {@code Chrono} using {@link #of(String)}.
+     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
      * It can also be used as part of a locale, accessible via
      * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
      *
@@ -183,17 +183,17 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<CopticChrono> date(int prolepticYear, int month, int dayOfMonth) {
+    public CopticDate date(int prolepticYear, int month, int dayOfMonth) {
         return new CopticDate(prolepticYear, month, dayOfMonth);
     }
 
     @Override
-    public ChronoLocalDate<CopticChrono> dateYearDay(int prolepticYear, int dayOfYear) {
+    public CopticDate dateYearDay(int prolepticYear, int dayOfYear) {
         return new CopticDate(prolepticYear, (dayOfYear - 1) / 30 + 1, (dayOfYear - 1) % 30 + 1);
     }
 
     @Override
-    public ChronoLocalDate<CopticChrono> date(TemporalAccessor dateTime) {
+    public CopticDate date(TemporalAccessor dateTime) {
         if (dateTime instanceof CopticDate) {
             return (CopticDate) dateTime;
         }
@@ -217,7 +217,7 @@
     }
 
     @Override
-    public int prolepticYear(Era<CopticChrono> era, int yearOfEra) {
+    public int prolepticYear(Era era, int yearOfEra) {
         if (era instanceof CopticEra == false) {
             throw new DateTimeException("Era must be CopticEra");
         }
@@ -225,13 +225,13 @@
     }
 
     @Override
-    public Era<CopticChrono> eraOf(int eraValue) {
+    public Era eraOf(int eraValue) {
         return CopticEra.of(eraValue);
     }
 
     @Override
-    public List<Era<CopticChrono>> eras() {
-        return Arrays.<Era<CopticChrono>>asList(CopticEra.values());
+    public List<Era> eras() {
+        return Arrays.<Era>asList(CopticEra.values());
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/tck/java/time/calendar/CopticDate.java b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java
similarity index 87%
rename from jdk/test/java/time/tck/java/time/calendar/CopticDate.java
rename to jdk/test/java/time/tck/java/time/chrono/CopticDate.java
index 30f1664..d8447eb 100644
--- a/jdk/test/java/time/tck/java/time/calendar/CopticDate.java
+++ b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java
@@ -53,7 +53,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.calendar;
+package tck.java.time.chrono;
 
 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
@@ -67,29 +67,26 @@
 
 import java.time.DateTimeException;
 import java.time.LocalDate;
+import java.time.Period;
+import java.time.chrono.ChronoLocalDate;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.Era;
 import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAdjuster;
-import java.time.temporal.TemporalAdder;
-import java.time.temporal.TemporalSubtractor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalUnit;
 import java.time.temporal.ValueRange;
-import java.time.temporal.Year;
+import java.time.Year;
 
 /**
  * A date in the Coptic calendar system.
  * <p>
- * This implements {@code ChronoLocalDate} for the {@link CopticChrono Coptic calendar}.
+ * This implements {@code ChronoLocalDate} for the {@link CopticChronology Coptic calendar}.
  *
  * <h4>Implementation notes</h4>
  * This class is immutable and thread-safe.
  */
-final class CopticDate
-        implements ChronoLocalDate<CopticChrono>, Serializable {
+public final class CopticDate
+        implements ChronoLocalDate<CopticDate>, Serializable {
 
     /**
      * Serialization version.
@@ -133,7 +130,7 @@
 
     private static CopticDate resolvePreviousValid(int prolepticYear, int month, int day) {
         if (month == 13 && day > 5) {
-            day = CopticChrono.INSTANCE.isLeapYear(prolepticYear) ? 6 : 5;
+            day = CopticChronology.INSTANCE.isLeapYear(prolepticYear) ? 6 : 5;
         }
         return new CopticDate(prolepticYear, month, day);
     }
@@ -148,12 +145,12 @@
      * @throws DateTimeException if the date is invalid
      */
     CopticDate(int prolepticYear, int month, int dayOfMonth) {
-        CopticChrono.MOY_RANGE.checkValidValue(month, MONTH_OF_YEAR);
+        CopticChronology.MOY_RANGE.checkValidValue(month, MONTH_OF_YEAR);
         ValueRange range;
         if (month == 13) {
-            range = CopticChrono.INSTANCE.isLeapYear(prolepticYear) ? CopticChrono.DOM_RANGE_LEAP : CopticChrono.DOM_RANGE_NONLEAP;
+            range = CopticChronology.INSTANCE.isLeapYear(prolepticYear) ? CopticChronology.DOM_RANGE_LEAP : CopticChronology.DOM_RANGE_NONLEAP;
         } else {
-            range = CopticChrono.DOM_RANGE;
+            range = CopticChronology.DOM_RANGE;
         }
         range.checkValidValue(dayOfMonth, DAY_OF_MONTH);
 
@@ -174,8 +171,8 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public CopticChrono getChrono() {
-        return CopticChrono.INSTANCE;
+    public CopticChronology getChronology() {
+        return CopticChronology.INSTANCE;
     }
 
     //-----------------------------------------------------------------------
@@ -202,11 +199,11 @@
                     case YEAR_OF_ERA: return (prolepticYear <= 0 ?
                             ValueRange.of(1, Year.MAX_VALUE + 1) : ValueRange.of(1, Year.MAX_VALUE));  // TODO
                 }
-                return getChrono().range(f);
+                return getChronology().range(f);
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     @Override
@@ -228,7 +225,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     @Override
@@ -253,7 +250,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
@@ -272,7 +269,7 @@
             }
             throw new DateTimeException(unit.getName() + " not valid for CopticDate");
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
@@ -304,13 +301,32 @@
             throw new DateTimeException("Unable to calculate period between objects of two different types");
         }
         ChronoLocalDate<?> end = (ChronoLocalDate<?>) endDateTime;
-        if (getChrono().equals(end.getChrono()) == false) {
+        if (getChronology().equals(end.getChronology()) == false) {
             throw new DateTimeException("Unable to calculate period between two different chronologies");
         }
         if (unit instanceof ChronoUnit) {
             return LocalDate.from(this).periodUntil(end, unit);  // TODO: this is wrong
         }
-        return unit.between(this, endDateTime).getAmount();
+        return unit.between(this, endDateTime);
+    }
+
+    @Override
+    public Period periodUntil(ChronoLocalDate<?> endDate) {
+        // TODO: untested
+        CopticDate end = (CopticDate) getChronology().date(endDate);
+        long totalMonths = (end.prolepticYear - this.prolepticYear) * 13 + (end.month - this.month);  // safe
+        int days = end.day - this.day;
+        if (totalMonths > 0 && days < 0) {
+            totalMonths--;
+            CopticDate calcDate = this.plusMonths(totalMonths);
+            days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
+        } else if (totalMonths < 0 && days > 0) {
+            totalMonths++;
+            days -= end.lengthOfMonth();
+        }
+        long years = totalMonths / 13;  // safe
+        int months = (int) (totalMonths % 13);  // safe
+        return Period.of(Math.toIntExact(years), months, days);
     }
 
     //-----------------------------------------------------------------------
@@ -328,7 +344,7 @@
         long moy = getLong(MONTH_OF_YEAR);
         long dom = getLong(DAY_OF_MONTH);
         StringBuilder buf = new StringBuilder(30);
-        buf.append(getChrono().toString())
+        buf.append(getChronology().toString())
                 .append(" ")
                 .append(getEra())
                 .append(" ")
diff --git a/jdk/test/java/time/tck/java/time/calendar/CopticEra.java b/jdk/test/java/time/tck/java/time/chrono/CopticEra.java
similarity index 63%
rename from jdk/test/java/time/tck/java/time/calendar/CopticEra.java
rename to jdk/test/java/time/tck/java/time/chrono/CopticEra.java
index 2526530..cfe4bdc 100644
--- a/jdk/test/java/time/tck/java/time/calendar/CopticEra.java
+++ b/jdk/test/java/time/tck/java/time/chrono/CopticEra.java
@@ -53,23 +53,11 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.calendar;
+package tck.java.time.chrono;
 
-import static java.time.temporal.ChronoField.ERA;
-
-import java.util.Locale;
 
 import java.time.DateTimeException;
-import java.time.temporal.ChronoField;
-import java.time.temporal.Queries;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalQuery;
-import java.time.temporal.ValueRange;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.Era;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.TextStyle;
+import java.time.chrono.Era;
 
 /**
  * An era in the Coptic calendar system.
@@ -83,7 +71,7 @@
  * <h4>Implementation notes</h4>
  * This is an immutable and thread-safe enum.
  */
-enum CopticEra implements Era<CopticChrono> {
+enum CopticEra implements Era {
 
     /**
      * The singleton instance for the era BEFORE_AM, 'Before Era of the Martyrs'.
@@ -131,80 +119,20 @@
     }
 
     @Override
-    public CopticChrono getChrono() {
-        return CopticChrono.INSTANCE;
+    public CopticChronology getChronology() {
+        return CopticChronology.INSTANCE;
     }
 
     // JDK8 default methods:
     //-----------------------------------------------------------------------
     @Override
-    public ChronoLocalDate<CopticChrono> date(int year, int month, int day) {
-        return getChrono().date(this, year, month, day);
+    public CopticDate date(int year, int month, int day) {
+        return (CopticDate)(getChronology().date(this, year, month, day));
     }
 
     @Override
-    public ChronoLocalDate<CopticChrono> dateYearDay(int year, int dayOfYear) {
-        return getChrono().dateYearDay(this, year, dayOfYear);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public boolean isSupported(TemporalField field) {
-        if (field instanceof ChronoField) {
-            return field == ERA;
-        }
-        return field != null && field.doIsSupported(this);
-    }
-
-    @Override
-    public ValueRange range(TemporalField field) {
-        if (field == ERA) {
-            return field.range();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doRange(this);
-    }
-
-    @Override
-    public int get(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        }
-        return range(field).checkValidIntValue(getLong(field), field);
-    }
-
-    @Override
-    public long getLong(TemporalField field) {
-        if (field == ERA) {
-            return getValue();
-        } else if (field instanceof ChronoField) {
-            throw new DateTimeException("Unsupported field: " + field.getName());
-        }
-        return field.doGet(this);
-    }
-
-    //-------------------------------------------------------------------------
-    @Override
-    public Temporal adjustInto(Temporal dateTime) {
-        return dateTime.with(ERA, getValue());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.zoneId()) {
-            return null;
-        } else if (query == Queries.chrono()) {
-            return (R) getChrono();
-        }
-        return query.queryFrom(this);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    public String getText(TextStyle style, Locale locale) {
-        return new DateTimeFormatterBuilder().appendText(ERA, style).toFormatter(locale).print(this);
+    public CopticDate dateYearDay(int year, int dayOfYear) {
+        return (CopticDate)(getChronology().dateYearDay(this, year, dayOfYear));
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java
new file mode 100644
index 0000000..c1a4309
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.chrono;
+
+import static org.testng.Assert.assertEquals;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Chronology;
+import java.time.chrono.Era;
+import java.time.chrono.IsoChronology;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.ValueRange;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+/**
+ * Test.
+ */
+@Test
+public class TCKChronology {
+    // Can only work with IsoChronology here
+    // others may be in separate module
+
+    @Test
+    public void factory_from_TemporalAccessor_dateWithChronlogy() {
+        assertEquals(Chronology.from(LocalDate.of(2012, 6, 30)), IsoChronology.INSTANCE);
+    }
+
+    @Test
+    public void factory_from_TemporalAccessor_chronology() {
+        assertEquals(Chronology.from(new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public long getLong(TemporalField field) {
+                throw new UnsupportedOperationException();
+            }
+            @SuppressWarnings("unchecked")
+            @Override
+            public <R> R query(TemporalQuery<R> query) {
+                if (query == Queries.chronology()) {
+                    return (R) IsoChronology.INSTANCE;
+                }
+                throw new UnsupportedOperationException();
+            }
+        }), IsoChronology.INSTANCE);
+    }
+
+    @Test
+    public void factory_from_TemporalAccessor_noChronology() {
+        assertEquals(Chronology.from(new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public long getLong(TemporalField field) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public <R> R query(TemporalQuery<R> query) {
+                if (query == Queries.chronology()) {
+                    return null;
+                }
+                throw new UnsupportedOperationException();
+            }
+        }), IsoChronology.INSTANCE);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void factory_from_TemporalAccessor_null() {
+        Chronology.from(null);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_date_TemporalAccessor() {
+        assertEquals(IsoChronology.INSTANCE.date(new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                if (field == ChronoField.EPOCH_DAY) {
+                    return true;
+                }
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public long getLong(TemporalField field) {
+                if (field == ChronoField.EPOCH_DAY) {
+                    return LocalDate.of(2012, 6, 30).toEpochDay();
+                }
+                throw new UnsupportedOperationException();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public <R> R query(TemporalQuery<R> query) {
+                if (query == Queries.localDate()) {
+                    return (R) LocalDate.of(2012, 6, 30);
+                }
+                throw new UnsupportedOperationException();
+            }
+        }), LocalDate.of(2012, 6, 30));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_date_TemporalAccessor_null() {
+        IsoChronology.INSTANCE.date(null);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_localDateTime_TemporalAccessor() {
+        assertEquals(IsoChronology.INSTANCE.localDateTime(new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                if (field == ChronoField.EPOCH_DAY || field == ChronoField.NANO_OF_DAY) {
+                    return true;
+                }
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public long getLong(TemporalField field) {
+                if (field == ChronoField.EPOCH_DAY) {
+                    return LocalDate.of(2012, 6, 30).toEpochDay();
+                }
+                if (field == ChronoField.NANO_OF_DAY) {
+                    return LocalTime.of(12, 30, 40).toNanoOfDay();
+                }
+                throw new UnsupportedOperationException();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public <R> R query(TemporalQuery<R> query) {
+                if (query == Queries.localDate()) {
+                    return (R) LocalDate.of(2012, 6, 30);
+                }
+                if (query == Queries.localTime()) {
+                    return (R) LocalTime.of(12, 30, 40);
+                }
+                throw new UnsupportedOperationException();
+            }
+        }), LocalDateTime.of(2012, 6, 30, 12, 30, 40));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_localDateTime_TemporalAccessor_null() {
+        IsoChronology.INSTANCE.localDateTime(null);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_zonedDateTime_TemporalAccessor() {
+        assertEquals(IsoChronology.INSTANCE.zonedDateTime(new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                if (field == ChronoField.EPOCH_DAY || field == ChronoField.NANO_OF_DAY ||
+                        field == ChronoField.INSTANT_SECONDS || field == ChronoField.NANO_OF_SECOND) {
+                    return true;
+                }
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public long getLong(TemporalField field) {
+                if (field == ChronoField.INSTANT_SECONDS) {
+                    return ZonedDateTime.of(2012, 6, 30, 12, 30, 40, 0, ZoneId.of("Europe/London")).toEpochSecond();
+                }
+                if (field == ChronoField.NANO_OF_SECOND) {
+                    return 0;
+                }
+                if (field == ChronoField.EPOCH_DAY) {
+                    return LocalDate.of(2012, 6, 30).toEpochDay();
+                }
+                if (field == ChronoField.NANO_OF_DAY) {
+                    return LocalTime.of(12, 30, 40).toNanoOfDay();
+                }
+                throw new UnsupportedOperationException();
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public <R> R query(TemporalQuery<R> query) {
+                if (query == Queries.localDate()) {
+                    return (R) LocalDate.of(2012, 6, 30);
+                }
+                if (query == Queries.localTime()) {
+                    return (R) LocalTime.of(12, 30, 40);
+                }
+                if (query == Queries.zoneId() || query == Queries.zone()) {
+                    return (R) ZoneId.of("Europe/London");
+                }
+                throw new UnsupportedOperationException();
+            }
+        }), ZonedDateTime.of(2012, 6, 30, 12, 30, 40, 0, ZoneId.of("Europe/London")));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_zonedDateTime_TemporalAccessor_null() {
+        IsoChronology.INSTANCE.zonedDateTime(null);
+    }
+
+}
diff --git a/jdk/test/java/time/test/java/time/temporal/TestOffsetDate.java b/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java
similarity index 77%
rename from jdk/test/java/time/test/java/time/temporal/TestOffsetDate.java
rename to jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java
index 5ba0032..0236656 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestOffsetDate.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java
@@ -1,5 +1,4 @@
 /*
- * Copyright (c) 2012, 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
@@ -27,7 +26,7 @@
  * However, the following notice accompanied the original version of this
  * file:
  *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos
  *
  * All rights reserved.
  *
@@ -57,22 +56,29 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package tck.java.time.chrono;
 
-import java.time.temporal.OffsetDate;
+import static org.testng.Assert.assertEquals;
+
+import java.time.LocalDate;
+import java.time.chrono.Chronology;
+import java.time.chrono.ChronoLocalDate;
 
 import org.testng.annotations.Test;
-import test.java.time.AbstractTest;
 
 /**
- * Test OffsetDate.
+ * Tests that a custom Chronology is available via the ServiceLoader.
+ * The CopticChronology is configured via META-INF/services/java.time.chrono.Chronology.
  */
 @Test
-public class TestOffsetDate extends AbstractTest {
+public class TCKTestServiceLoader {
 
-    @Test
-    public void test_immutable() {
-        assertImmutable(OffsetDate.class);
+     @Test(groups={"tck"})
+     public void test_CopticServiceLoader() {
+        Chronology chrono = Chronology.of("Coptic");
+        ChronoLocalDate copticDate = chrono.date(1729, 4, 27);
+        LocalDate ld = LocalDate.from(copticDate);
+        assertEquals(ld, LocalDate.of(2013, 1, 5), "CopticDate does not match LocalDate");
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/calendar/TestChronoLocalDate.java b/jdk/test/java/time/tck/java/time/chrono/TestChronoLocalDate.java
similarity index 84%
rename from jdk/test/java/time/tck/java/time/calendar/TestChronoLocalDate.java
rename to jdk/test/java/time/tck/java/time/chrono/TestChronoLocalDate.java
index 67175c0..51674e2 100644
--- a/jdk/test/java/time/tck/java/time/calendar/TestChronoLocalDate.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TestChronoLocalDate.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.calendar;
+package tck.java.time.chrono;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
@@ -63,29 +63,25 @@
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
 import java.time.Duration;
 import java.time.LocalDate;
-import java.time.calendar.HijrahChrono;
-import java.time.calendar.JapaneseChrono;
-import java.time.calendar.MinguoChrono;
-import java.time.calendar.ThaiBuddhistChrono;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDate;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.Chronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.IsoChronology;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.SimplePeriod;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.ValueRange;
 import java.time.temporal.TemporalUnit;
-import java.time.temporal.ISOChrono;
+import java.time.temporal.ValueRange;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
@@ -101,21 +97,21 @@
     // regular data factory for names and descriptions of available calendars
     //-----------------------------------------------------------------------
     @DataProvider(name = "calendars")
-    Chrono<?>[][] data_of_calendars() {
-        return new Chrono<?>[][]{
-                    {HijrahChrono.INSTANCE},
-                    {ISOChrono.INSTANCE},
-                    {JapaneseChrono.INSTANCE},
-                    {MinguoChrono.INSTANCE},
-                    {ThaiBuddhistChrono.INSTANCE}};
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+                    {HijrahChronology.INSTANCE},
+                    {IsoChronology.INSTANCE},
+                    {JapaneseChronology.INSTANCE},
+                    {MinguoChronology.INSTANCE},
+                    {ThaiBuddhistChronology.INSTANCE}};
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badWithAdjusterChrono(Chrono<?> chrono) {
+    public void test_badWithAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDate<?> date2 = chrono2.date(refDate);
             TemporalAdjuster adjuster = new FixedAdjuster(date2);
             if (chrono != chrono2) {
@@ -134,13 +130,13 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusAdjusterChrono(Chrono<?> chrono) {
+    public void test_badPlusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDate<?> date2 = chrono2.date(refDate);
-            TemporalAdder adjuster = new FixedAdjuster(date2);
+            TemporalAmount adjuster = new FixedAdjuster(date2);
             if (chrono != chrono2) {
                 try {
                     date.plus(adjuster);
@@ -157,13 +153,13 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusAdjusterChrono(Chrono<?> chrono) {
+    public void test_badMinusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDate<?> date2 = chrono2.date(refDate);
-            TemporalSubtractor adjuster = new FixedAdjuster(date2);
+            TemporalAmount adjuster = new FixedAdjuster(date2);
             if (chrono != chrono2) {
                 try {
                     date.minus(adjuster);
@@ -180,11 +176,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusTemporalUnitChrono(Chrono<?> chrono) {
+    public void test_badPlusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDate<?> date2 = chrono2.date(refDate);
             TemporalUnit adjuster = new FixedTemporalUnit(date2);
             if (chrono != chrono2) {
@@ -204,11 +200,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusTemporalUnitChrono(Chrono<?> chrono) {
+    public void test_badMinusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDate<?> date2 = chrono2.date(refDate);
             TemporalUnit adjuster = new FixedTemporalUnit(date2);
             if (chrono != chrono2) {
@@ -228,11 +224,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badTemporalFieldChrono(Chrono<?> chrono) {
+    public void test_badTemporalFieldChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDate<?> date2 = chrono2.date(refDate);
             TemporalField adjuster = new FixedTemporalField(date2);
             if (chrono != chrono2) {
@@ -255,8 +251,8 @@
     // isBefore, isAfter, isEqual, DATE_COMPARATOR
     //-----------------------------------------------------------------------
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_date_comparisons(Chrono<?> chrono) {
-        List<ChronoLocalDate<?>> dates = new ArrayList<>();
+    public void test_date_comparisons(Chronology chrono) {
+        List<ChronoLocalDate> dates = new ArrayList<>();
 
         ChronoLocalDate<?> date = chrono.date(LocalDate.of(1900, 1, 1));
 
@@ -278,9 +274,9 @@
         dates.add(date.plus(1000, ChronoUnit.YEARS));
 
         // Check these dates against the corresponding dates for every calendar
-        for (Chrono<?>[] clist : data_of_calendars()) {
+        for (Chronology[] clist : data_of_calendars()) {
             List<ChronoLocalDate<?>> otherDates = new ArrayList<>();
-            Chrono<?> chrono2 = clist[0];
+            Chronology chrono2 = clist[0];
             for (ChronoLocalDate<?> d : dates) {
                 otherDates.add(chrono2.date(d));
             }
@@ -316,9 +312,9 @@
     // Test Serialization of Calendars
     //-----------------------------------------------------------------------
     @Test( groups={"tck"}, dataProvider="calendars")
-    public <C extends Chrono<C>> void test_ChronoSerialization(C chrono) throws Exception {
+    public void test_ChronoSerialization(Chronology chrono) throws Exception {
         LocalDate ref = LocalDate.of(1900, 1, 5);
-        ChronoLocalDate<C> orginal = chrono.date(ref);
+        ChronoLocalDate<?> orginal = chrono.date(ref);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream(baos);
         out.writeObject(orginal);
@@ -326,7 +322,7 @@
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         ObjectInputStream in = new ObjectInputStream(bais);
         @SuppressWarnings("unchecked")
-        ChronoLocalDate<C> ser = (ChronoLocalDate<C>) in.readObject();
+        ChronoLocalDate<?> ser = (ChronoLocalDate<?>) in.readObject();
         assertEquals(ser, orginal, "deserialized date is wrong");
     }
 
@@ -334,7 +330,7 @@
      * FixedAdjusted returns a fixed Temporal in all adjustments.
      * Construct an adjuster with the Temporal that should be returned from adjust.
      */
-    static class FixedAdjuster implements TemporalAdjuster, TemporalAdder, TemporalSubtractor {
+    static class FixedAdjuster implements TemporalAdjuster, TemporalAmount {
         private Temporal datetime;
 
         FixedAdjuster(Temporal datetime) {
@@ -356,6 +352,15 @@
             return datetime;
         }
 
+        @Override
+        public long get(TemporalUnit unit) {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public List<TemporalUnit> getUnits() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
     }
 
     /**
@@ -385,18 +390,18 @@
         }
 
         @Override
-        public boolean isSupported(Temporal temporal) {
+        public boolean isSupportedBy(Temporal temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) {
+        public <R extends Temporal> R addTo(R temporal, long amount) {
             return (R) this.temporal;
         }
 
         @Override
-        public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) {
+        public long between(Temporal temporal1, Temporal temporal2) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
     }
@@ -432,30 +437,24 @@
         }
 
         @Override
-        public boolean doIsSupported(TemporalAccessor temporal) {
+        public boolean isSupportedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public ValueRange doRange(TemporalAccessor temporal) {
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public long doGet(TemporalAccessor temporal) {
+        public long getFrom(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doWith(R temporal, long newValue) {
+        public <R extends Temporal> R adjustInto(R temporal, long newValue) {
             return (R) this.temporal;
         }
-
-        @Override
-        public boolean resolve(DateTimeBuilder builder, long value) {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
     }
 }
diff --git a/jdk/test/java/time/tck/java/time/calendar/TestChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TestChronoLocalDateTime.java
similarity index 84%
rename from jdk/test/java/time/tck/java/time/calendar/TestChronoLocalDateTime.java
rename to jdk/test/java/time/tck/java/time/chrono/TestChronoLocalDateTime.java
index e514fb8..fd72237 100644
--- a/jdk/test/java/time/tck/java/time/calendar/TestChronoLocalDateTime.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TestChronoLocalDateTime.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.calendar;
+package tck.java.time.chrono;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
@@ -63,31 +63,28 @@
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
-import java.time.calendar.HijrahChrono;
-import java.time.calendar.JapaneseChrono;
-import java.time.calendar.MinguoChrono;
-import java.time.calendar.ThaiBuddhistChrono;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDateTime;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.SimplePeriod;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.ValueRange;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
@@ -102,21 +99,21 @@
     // regular data factory for names and descriptions of available calendars
     //-----------------------------------------------------------------------
     @DataProvider(name = "calendars")
-    Chrono[][] data_of_calendars() {
-        return new Chrono[][]{
-                    {HijrahChrono.INSTANCE},
-                    {ISOChrono.INSTANCE},
-                    {JapaneseChrono.INSTANCE},
-                    {MinguoChrono.INSTANCE},
-                    {ThaiBuddhistChrono.INSTANCE}};
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+                    {HijrahChronology.INSTANCE},
+                    {IsoChronology.INSTANCE},
+                    {JapaneseChronology.INSTANCE},
+                    {MinguoChronology.INSTANCE},
+                    {ThaiBuddhistChronology.INSTANCE}};
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badWithAdjusterChrono(Chrono chrono) {
+    public void test_badWithAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono[] clist : data_of_calendars()) {
-            Chrono chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
             TemporalAdjuster adjuster = new FixedAdjuster(cdt2);
             if (chrono != chrono2) {
@@ -136,13 +133,13 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusAdjusterChrono(Chrono chrono) {
+    public void test_badPlusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono[] clist : data_of_calendars()) {
-            Chrono chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
-            TemporalAdder adjuster = new FixedAdjuster(cdt2);
+            TemporalAmount adjuster = new FixedAdjuster(cdt2);
             if (chrono != chrono2) {
                 try {
                     ChronoLocalDateTime<?> notreached = cdt.plus(adjuster);
@@ -160,13 +157,13 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusAdjusterChrono(Chrono chrono) {
+    public void test_badMinusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono[] clist : data_of_calendars()) {
-            Chrono chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
-            TemporalSubtractor adjuster = new FixedAdjuster(cdt2);
+            TemporalAmount adjuster = new FixedAdjuster(cdt2);
             if (chrono != chrono2) {
                 try {
                     ChronoLocalDateTime<?> notreached = cdt.minus(adjuster);
@@ -184,11 +181,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusTemporalUnitChrono(Chrono chrono) {
+    public void test_badPlusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono[] clist : data_of_calendars()) {
-            Chrono chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
             TemporalUnit adjuster = new FixedTemporalUnit(cdt2);
             if (chrono != chrono2) {
@@ -208,11 +205,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusTemporalUnitChrono(Chrono chrono) {
+    public void test_badMinusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono[] clist : data_of_calendars()) {
-            Chrono chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
             TemporalUnit adjuster = new FixedTemporalUnit(cdt2);
             if (chrono != chrono2) {
@@ -232,11 +229,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badTemporalFieldChrono(Chrono chrono) {
+    public void test_badTemporalFieldChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono[] clist : data_of_calendars()) {
-            Chrono chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
             TemporalField adjuster = new FixedTemporalField(cdt2);
             if (chrono != chrono2) {
@@ -259,7 +256,7 @@
     // isBefore, isAfter, isEqual
     //-----------------------------------------------------------------------
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_datetime_comparisons(Chrono chrono) {
+    public void test_datetime_comparisons(Chronology chrono) {
         List<ChronoLocalDateTime<?>> dates = new ArrayList<>();
 
         ChronoLocalDateTime<?> date = chrono.date(LocalDate.of(1900, 1, 1)).atTime(LocalTime.MIN);
@@ -286,11 +283,11 @@
         dates.add(date.plus(100, ChronoUnit.YEARS));
 
         // Check these dates against the corresponding dates for every calendar
-        for (Chrono[] clist : data_of_calendars()) {
+        for (Chronology[] clist : data_of_calendars()) {
             List<ChronoLocalDateTime<?>> otherDates = new ArrayList<>();
-            Chrono chrono2 = clist[0];
+            Chronology chrono2 = clist[0];
             for (ChronoLocalDateTime<?> d : dates) {
-                otherDates.add(chrono2.date(d).atTime(d.getTime()));
+                otherDates.add(chrono2.date(d).atTime(d.toLocalTime()));
             }
 
             // Now compare  the sequence of original dates with the sequence of converted dates
@@ -324,16 +321,16 @@
     // Test Serialization of ISO via chrono API
     //-----------------------------------------------------------------------
     @Test( groups={"tck"}, dataProvider="calendars")
-    public <C extends Chrono<C>> void test_ChronoLocalDateTimeSerialization(C chrono) throws Exception {
+    public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception {
         LocalDateTime ref = LocalDate.of(2000, 1, 5).atTime(12, 1, 2, 3);
-        ChronoLocalDateTime<C> orginal = chrono.date(ref).atTime(ref.getTime());
+        ChronoLocalDateTime<?> orginal = chrono.date(ref).atTime(ref.toLocalTime());
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream(baos);
         out.writeObject(orginal);
         out.close();
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         ObjectInputStream in = new ObjectInputStream(bais);
-        ChronoLocalDateTime<C> ser = (ChronoLocalDateTime<C>) in.readObject();
+        ChronoLocalDateTime<?> ser = (ChronoLocalDateTime<?>) in.readObject();
         assertEquals(ser, orginal, "deserialized date is wrong");
     }
 
@@ -342,7 +339,7 @@
      * FixedAdjusted returns a fixed Temporal in all adjustments.
      * Construct an adjuster with the Temporal that should be returned from adjust.
      */
-    static class FixedAdjuster implements TemporalAdjuster, TemporalAdder, TemporalSubtractor {
+    static class FixedAdjuster implements TemporalAdjuster, TemporalAmount {
         private Temporal datetime;
 
         FixedAdjuster(Temporal datetime) {
@@ -364,6 +361,16 @@
             return datetime;
         }
 
+        @Override
+        public long get(TemporalUnit unit) {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public List<TemporalUnit> getUnits() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
     }
 
     /**
@@ -393,18 +400,18 @@
         }
 
         @Override
-        public boolean isSupported(Temporal temporal) {
+        public boolean isSupportedBy(Temporal temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) {
+        public <R extends Temporal> R addTo(R temporal, long amount) {
             return (R) this.temporal;
         }
 
         @Override
-        public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) {
+        public long between(Temporal temporal1, Temporal temporal2) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
     }
@@ -440,30 +447,24 @@
         }
 
         @Override
-        public boolean doIsSupported(TemporalAccessor temporal) {
+        public boolean isSupportedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public ValueRange doRange(TemporalAccessor temporal) {
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public long doGet(TemporalAccessor temporal) {
+        public long getFrom(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doWith(R temporal, long newValue) {
+        public <R extends Temporal> R adjustInto(R temporal, long newValue) {
             return (R) this.temporal;
         }
-
-        @Override
-        public boolean resolve(DateTimeBuilder builder, long value) {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
     }
 }
diff --git a/jdk/test/java/time/tck/java/time/calendar/TestHijrahChrono.java b/jdk/test/java/time/tck/java/time/chrono/TestHijrahChronology.java
similarity index 71%
rename from jdk/test/java/time/tck/java/time/calendar/TestHijrahChrono.java
rename to jdk/test/java/time/tck/java/time/chrono/TestHijrahChronology.java
index 3157e82..1938c5e 100644
--- a/jdk/test/java/time/tck/java/time/calendar/TestHijrahChrono.java
+++ b/jdk/test/java/time/tck/java/time/chrono/TestHijrahChronology.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package tck.java.time.calendar;
+package tck.java.time.chrono;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
@@ -64,11 +64,12 @@
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.Month;
-import java.time.calendar.HijrahChrono;
-import java.time.temporal.ChronoLocalDate;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.HijrahDate;
+import java.time.chrono.ChronoLocalDate;
 import java.time.temporal.Adjusters;
-import java.time.temporal.Chrono;
-import java.time.temporal.ISOChrono;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
@@ -78,15 +79,15 @@
  * Test.
  */
 @Test
-public class TestHijrahChrono {
+public class TestHijrahChronology {
 
     //-----------------------------------------------------------------------
-    // Chrono.ofName("Hijrah")  Lookup by name
+    // Chronology.ofName("Hijrah")  Lookup by name
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_chrono_byName() {
-        Chrono<HijrahChrono> c = HijrahChrono.INSTANCE;
-        Chrono<?> test = Chrono.of("Hijrah");
+        Chronology c = HijrahChronology.INSTANCE;
+        Chronology test = Chronology.of("Hijrah");
         Assert.assertNotNull(test, "The Hijrah calendar could not be found byName");
         Assert.assertEquals(test.getId(), "Hijrah", "ID mismatch");
         Assert.assertEquals(test.getCalendarType(), "islamicc", "Type mismatch");
@@ -99,20 +100,20 @@
     @DataProvider(name="samples")
     Object[][] data_samples() {
         return new Object[][] {
-            {HijrahChrono.INSTANCE.date(1, 1, 1), LocalDate.of(622, 7, 19)},
-            {HijrahChrono.INSTANCE.date(1, 1, 2), LocalDate.of(622, 7, 20)},
-            {HijrahChrono.INSTANCE.date(1, 1, 3), LocalDate.of(622, 7, 21)},
+            {HijrahChronology.INSTANCE.date(1, 1, 1), LocalDate.of(622, 7, 19)},
+            {HijrahChronology.INSTANCE.date(1, 1, 2), LocalDate.of(622, 7, 20)},
+            {HijrahChronology.INSTANCE.date(1, 1, 3), LocalDate.of(622, 7, 21)},
 
-            {HijrahChrono.INSTANCE.date(2, 1, 1), LocalDate.of(623, 7, 8)},
-            {HijrahChrono.INSTANCE.date(3, 1, 1), LocalDate.of(624, 6, 27)},
-            {HijrahChrono.INSTANCE.date(3, 12, 6), LocalDate.of(625, 5, 23)},
-            {HijrahChrono.INSTANCE.date(4, 1, 1), LocalDate.of(625, 6, 16)},
-            {HijrahChrono.INSTANCE.date(4, 7, 3), LocalDate.of(625, 12, 12)},
-            {HijrahChrono.INSTANCE.date(4, 7, 4), LocalDate.of(625, 12, 13)},
-            {HijrahChrono.INSTANCE.date(5, 1, 1), LocalDate.of(626, 6, 5)},
-            {HijrahChrono.INSTANCE.date(1662, 3, 3), LocalDate.of(2234, 4, 3)},
-            {HijrahChrono.INSTANCE.date(1728, 10, 28), LocalDate.of(2298, 12, 03)},
-            {HijrahChrono.INSTANCE.date(1728, 10, 29), LocalDate.of(2298, 12, 04)},
+            {HijrahChronology.INSTANCE.date(2, 1, 1), LocalDate.of(623, 7, 8)},
+            {HijrahChronology.INSTANCE.date(3, 1, 1), LocalDate.of(624, 6, 27)},
+            {HijrahChronology.INSTANCE.date(3, 12, 6), LocalDate.of(625, 5, 23)},
+            {HijrahChronology.INSTANCE.date(4, 1, 1), LocalDate.of(625, 6, 16)},
+            {HijrahChronology.INSTANCE.date(4, 7, 3), LocalDate.of(625, 12, 12)},
+            {HijrahChronology.INSTANCE.date(4, 7, 4), LocalDate.of(625, 12, 13)},
+            {HijrahChronology.INSTANCE.date(5, 1, 1), LocalDate.of(626, 6, 5)},
+            {HijrahChronology.INSTANCE.date(1662, 3, 3), LocalDate.of(2234, 4, 3)},
+            {HijrahChronology.INSTANCE.date(1728, 10, 28), LocalDate.of(2298, 12, 03)},
+            {HijrahChronology.INSTANCE.date(1728, 10, 29), LocalDate.of(2298, 12, 04)},
         };
     }
 
@@ -123,7 +124,7 @@
 
     @Test(dataProvider="samples", groups={"tck"})
     public void test_fromCalendrical(ChronoLocalDate<?> hijrahDate, LocalDate iso) {
-        assertEquals(HijrahChrono.INSTANCE.date(iso), hijrahDate);
+        assertEquals(HijrahChronology.INSTANCE.date(iso), hijrahDate);
     }
 
     @DataProvider(name="badDates")
@@ -148,7 +149,7 @@
 
     @Test(dataProvider="badDates", groups={"tck"}, expectedExceptions=DateTimeException.class)
     public void test_badDates(int year, int month, int dom) {
-        HijrahChrono.INSTANCE.date(year, month, dom);
+        HijrahChronology.INSTANCE.date(year, month, dom);
     }
 
     //-----------------------------------------------------------------------
@@ -156,16 +157,16 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_adjust1() {
-        ChronoLocalDate<?> base = HijrahChrono.INSTANCE.date(1728, 10, 28);
+        ChronoLocalDate<?> base = HijrahChronology.INSTANCE.date(1728, 10, 28);
         ChronoLocalDate<?> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, HijrahChrono.INSTANCE.date(1728, 10, 29));
+        assertEquals(test, HijrahChronology.INSTANCE.date(1728, 10, 29));
     }
 
     @Test(groups={"tck"})
     public void test_adjust2() {
-        ChronoLocalDate<?> base = HijrahChrono.INSTANCE.date(1728, 12, 2);
+        ChronoLocalDate<?> base = HijrahChronology.INSTANCE.date(1728, 12, 2);
         ChronoLocalDate<?> test = base.with(Adjusters.lastDayOfMonth());
-        assertEquals(test, HijrahChrono.INSTANCE.date(1728, 12, 30));
+        assertEquals(test, HijrahChronology.INSTANCE.date(1728, 12, 30));
     }
 
     //-----------------------------------------------------------------------
@@ -173,14 +174,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_adjust_toLocalDate() {
-        ChronoLocalDate<?> hijrahDate = HijrahChrono.INSTANCE.date(1726, 1, 4);
+        ChronoLocalDate<?> hijrahDate = HijrahChronology.INSTANCE.date(1726, 1, 4);
         ChronoLocalDate<?> test = hijrahDate.with(LocalDate.of(2012, 7, 6));
-        assertEquals(test, HijrahChrono.INSTANCE.date(1433, 8, 16));
+        assertEquals(test, HijrahChronology.INSTANCE.date(1433, 8, 16));
     }
 
     @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
     public void test_adjust_toMonth() {
-        ChronoLocalDate<?> hijrahDate = HijrahChrono.INSTANCE.date(1726, 1, 4);
+        ChronoLocalDate<?> hijrahDate = HijrahChronology.INSTANCE.date(1726, 1, 4);
         hijrahDate.with(Month.APRIL);
     }
 
@@ -189,14 +190,14 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_LocalDate_adjustToHijrahDate() {
-        ChronoLocalDate<?> hijrahDate = HijrahChrono.INSTANCE.date(1728, 10, 29);
+        ChronoLocalDate<?> hijrahDate = HijrahChronology.INSTANCE.date(1728, 10, 29);
         LocalDate test = LocalDate.MIN.with(hijrahDate);
         assertEquals(test, LocalDate.of(2298, 12, 4));
     }
 
     @Test(groups={"tck"})
     public void test_LocalDateTime_adjustToHijrahDate() {
-        ChronoLocalDate<?> hijrahDate = HijrahChrono.INSTANCE.date(1728, 10, 29);
+        ChronoLocalDate<?> hijrahDate = HijrahChronology.INSTANCE.date(1728, 10, 29);
         LocalDateTime test = LocalDateTime.MIN.with(hijrahDate);
         assertEquals(test, LocalDateTime.of(2298, 12, 4, 0, 0));
     }
@@ -207,11 +208,11 @@
     @DataProvider(name="toString")
     Object[][] data_toString() {
         return new Object[][] {
-            {HijrahChrono.INSTANCE.date(1, 1, 1), "Hijrah AH 1-01-01"},
-            {HijrahChrono.INSTANCE.date(1728, 10, 28), "Hijrah AH 1728-10-28"},
-            {HijrahChrono.INSTANCE.date(1728, 10, 29), "Hijrah AH 1728-10-29"},
-            {HijrahChrono.INSTANCE.date(1727, 12, 5), "Hijrah AH 1727-12-05"},
-            {HijrahChrono.INSTANCE.date(1727, 12, 6), "Hijrah AH 1727-12-06"},
+            {HijrahChronology.INSTANCE.date(1, 1, 1), "Hijrah AH 1-01-01"},
+            {HijrahChronology.INSTANCE.date(1728, 10, 28), "Hijrah AH 1728-10-28"},
+            {HijrahChronology.INSTANCE.date(1728, 10, 29), "Hijrah AH 1728-10-29"},
+            {HijrahChronology.INSTANCE.date(1727, 12, 5), "Hijrah AH 1727-12-05"},
+            {HijrahChronology.INSTANCE.date(1727, 12, 6), "Hijrah AH 1727-12-06"},
         };
     }
 
@@ -225,12 +226,12 @@
     //-----------------------------------------------------------------------
     @Test(groups="tck")
     public void test_equals_true() {
-        assertTrue(HijrahChrono.INSTANCE.equals(HijrahChrono.INSTANCE));
+        assertTrue(HijrahChronology.INSTANCE.equals(HijrahChronology.INSTANCE));
     }
 
     @Test(groups="tck")
     public void test_equals_false() {
-        assertFalse(HijrahChrono.INSTANCE.equals(ISOChrono.INSTANCE));
+        assertFalse(HijrahChronology.INSTANCE.equals(IsoChronology.INSTANCE));
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/chrono/TestJapaneseChronology.java b/jdk/test/java/time/tck/java/time/chrono/TestJapaneseChronology.java
new file mode 100644
index 0000000..b3027df
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/chrono/TestJapaneseChronology.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.chrono;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.util.List;
+
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.Month;
+import java.time.Year;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.JapaneseDate;
+import java.time.chrono.Chronology;
+import java.time.chrono.Era;
+import java.time.chrono.IsoChronology;
+import java.time.temporal.Adjusters;
+import java.util.Locale;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test.
+ */
+@Test
+public class TestJapaneseChronology {
+    private static int YDIFF_HEISEI = 1988;
+    private static int YDIFF_MEIJI = 1867;
+    private static int YDIFF_SHOWA = 1925;
+    private static int YDIFF_TAISHO = 1911;
+
+    //-----------------------------------------------------------------------
+    // Chronology.of(String)
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_chrono_byName() {
+        Chronology c = JapaneseChronology.INSTANCE;
+        Chronology test = Chronology.of("Japanese");
+        Assert.assertNotNull(test, "The Japanese calendar could not be found byName");
+        Assert.assertEquals(test.getId(), "Japanese", "ID mismatch");
+        Assert.assertEquals(test.getCalendarType(), "japanese", "Type mismatch");
+        Assert.assertEquals(test, c);
+    }
+
+    //-----------------------------------------------------------------------
+    // Chronology.ofLocale(Locale)
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_chrono_byLocale_fullTag_japaneseCalendarFromJapan() {
+        Chronology test = Chronology.ofLocale(Locale.forLanguageTag("ja-JP-u-ca-japanese"));
+        Assert.assertEquals(test.getId(), "Japanese");
+        Assert.assertEquals(test, JapaneseChronology.INSTANCE);
+    }
+
+    @Test
+    public void test_chrono_byLocale_fullTag_japaneseCalendarFromElsewhere() {
+        Chronology test = Chronology.ofLocale(Locale.forLanguageTag("en-US-u-ca-japanese"));
+        Assert.assertEquals(test.getId(), "Japanese");
+        Assert.assertEquals(test, JapaneseChronology.INSTANCE);
+    }
+
+    @Test
+    public void test_chrono_byLocale_oldJP_noVariant() {
+        Chronology test = Chronology.ofLocale(new Locale("ja", "JP"));
+        Assert.assertEquals(test.getId(), "ISO");
+        Assert.assertEquals(test, IsoChronology.INSTANCE);
+    }
+
+    @Test
+    public void test_chrono_byLocale_oldJP_variant() {
+        Chronology test = Chronology.ofLocale(new Locale("ja", "JP", "JP"));
+        Assert.assertEquals(test.getId(), "Japanese");
+        Assert.assertEquals(test, JapaneseChronology.INSTANCE);
+    }
+
+    @Test
+    public void test_chrono_byLocale_iso() {
+        Assert.assertEquals(Chronology.ofLocale(new Locale("ja", "JP")).getId(), "ISO");
+        Assert.assertEquals(Chronology.ofLocale(Locale.forLanguageTag("ja-JP")).getId(), "ISO");
+        Assert.assertEquals(Chronology.ofLocale(Locale.forLanguageTag("ja-JP-JP")).getId(), "ISO");
+    }
+
+    //-----------------------------------------------------------------------
+    // creation, toLocalDate()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="samples")
+    Object[][] data_samples() {
+        return new Object[][] {
+            {JapaneseChronology.INSTANCE.date(1, 1, 1), LocalDate.of(1, 1, 1)},
+            {JapaneseChronology.INSTANCE.date(1, 1, 2), LocalDate.of(1, 1, 2)},
+            {JapaneseChronology.INSTANCE.date(1, 1, 3), LocalDate.of(1, 1, 3)},
+
+            {JapaneseChronology.INSTANCE.date(2, 1, 1), LocalDate.of(2, 1, 1)},
+            {JapaneseChronology.INSTANCE.date(3, 1, 1), LocalDate.of(3, 1, 1)},
+            {JapaneseChronology.INSTANCE.date(3, 12, 6), LocalDate.of(3, 12, 6)},
+            {JapaneseChronology.INSTANCE.date(4, 1, 1), LocalDate.of(4, 1, 1)},
+            {JapaneseChronology.INSTANCE.date(4, 7, 3), LocalDate.of(4, 7, 3)},
+            {JapaneseChronology.INSTANCE.date(4, 7, 4), LocalDate.of(4, 7, 4)},
+            {JapaneseChronology.INSTANCE.date(5, 1, 1), LocalDate.of(5, 1, 1)},
+            {JapaneseChronology.INSTANCE.date(1662, 3, 3), LocalDate.of(1662, 3, 3)},
+            {JapaneseChronology.INSTANCE.date(1728, 10, 28), LocalDate.of(1728, 10, 28)},
+            {JapaneseChronology.INSTANCE.date(1728, 10, 29), LocalDate.of(1728, 10, 29)},
+
+            {JapaneseChronology.INSTANCE.date(JapaneseChronology.ERA_HEISEI, 1996 - YDIFF_HEISEI, 2, 29), LocalDate.of(1996, 2, 29)},
+            {JapaneseChronology.INSTANCE.date(JapaneseChronology.ERA_HEISEI, 2000 - YDIFF_HEISEI, 2, 29), LocalDate.of(2000, 2, 29)},
+            {JapaneseChronology.INSTANCE.date(JapaneseChronology.ERA_MEIJI, 1868 - YDIFF_MEIJI, 2, 29), LocalDate.of(1868, 2, 29)},
+            {JapaneseChronology.INSTANCE.date(JapaneseChronology.ERA_SHOWA, 1928 - YDIFF_SHOWA, 2, 29), LocalDate.of(1928, 2, 29)},
+            {JapaneseChronology.INSTANCE.date(JapaneseChronology.ERA_TAISHO, 1912 - YDIFF_TAISHO, 2, 29), LocalDate.of(1912, 2, 29)},
+
+            {JapaneseChronology.INSTANCE.dateYearDay(1996, 60), LocalDate.of(1996, 2, 29)},
+            {JapaneseChronology.INSTANCE.dateYearDay(1868, 60), LocalDate.of(1868, 2, 29)},
+            {JapaneseChronology.INSTANCE.dateYearDay(1928, 60), LocalDate.of(1928, 2, 29)},
+            {JapaneseChronology.INSTANCE.dateYearDay(1912, 60), LocalDate.of(1912, 2, 29)},
+        };
+    }
+
+    @Test(dataProvider="samples", groups={"tck"})
+    public void test_toLocalDate(JapaneseDate jdate, LocalDate iso) {
+        assertEquals(LocalDate.from(jdate), iso);
+    }
+
+    @Test(dataProvider="samples", groups={"tck"})
+    public void test_fromCalendrical(JapaneseDate jdate, LocalDate iso) {
+        assertEquals(JapaneseChronology.INSTANCE.date(iso), jdate);
+    }
+
+    @DataProvider(name="badDates")
+    Object[][] data_badDates() {
+        return new Object[][] {
+            {1728, 0, 0},
+
+            {1728, -1, 1},
+            {1728, 0, 1},
+            {1728, 14, 1},
+            {1728, 15, 1},
+
+            {1728, 1, -1},
+            {1728, 1, 0},
+            {1728, 1, 32},
+
+            {1728, 12, -1},
+            {1728, 12, 0},
+            {1728, 12, 32},
+
+            {1725, 2, 29},
+            {500, 2, 29},
+            {2100, 2, 29},
+        };
+    }
+
+    @Test(dataProvider="badDates", groups={"tck"}, expectedExceptions=DateTimeException.class)
+    public void test_badDates(int year, int month, int dom) {
+        JapaneseChronology.INSTANCE.date(year, month, dom);
+    }
+
+    //-----------------------------------------------------------------------
+    // prolepticYear() and is LeapYear()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="prolepticYear")
+    Object[][] data_prolepticYear() {
+        return new Object[][] {
+            {2, JapaneseChronology.ERA_HEISEI, 1, 1 + YDIFF_HEISEI, false},
+            {2, JapaneseChronology.ERA_HEISEI, 100, 100 + YDIFF_HEISEI, true},
+            {2, JapaneseChronology.ERA_HEISEI, 0, YDIFF_HEISEI, true},
+            {2, JapaneseChronology.ERA_HEISEI, -10, -10 + YDIFF_HEISEI, false},
+
+            {-1, JapaneseChronology.ERA_MEIJI, 1, 1 + YDIFF_MEIJI, true},
+            {-1, JapaneseChronology.ERA_MEIJI, 100, 100 + YDIFF_MEIJI, false},
+            {-1, JapaneseChronology.ERA_MEIJI, 0, YDIFF_MEIJI, false},
+            {-1, JapaneseChronology.ERA_MEIJI, -10, -10 + YDIFF_MEIJI, false},
+
+            {1, JapaneseChronology.ERA_SHOWA, 1, 1 + YDIFF_SHOWA, false},
+            {1, JapaneseChronology.ERA_SHOWA, 100, 100 + YDIFF_SHOWA, false},
+            {1, JapaneseChronology.ERA_SHOWA, 0, YDIFF_SHOWA, false},
+            {1, JapaneseChronology.ERA_SHOWA, -5, -5 + YDIFF_SHOWA, true},
+
+            {0, JapaneseChronology.ERA_TAISHO, 1, 1 + YDIFF_TAISHO, true},
+            {0, JapaneseChronology.ERA_TAISHO, 100, 100 + YDIFF_TAISHO, false},
+            {0, JapaneseChronology.ERA_TAISHO, 0, YDIFF_TAISHO, false},
+            {0, JapaneseChronology.ERA_TAISHO, -10, -10 + YDIFF_TAISHO, false},
+
+        };
+    }
+
+    @Test(dataProvider="prolepticYear", groups={"tck"})
+    public void test_prolepticYear(int eraValue, Era  era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) {
+        Era eraObj = JapaneseChronology.INSTANCE.eraOf(eraValue) ;
+        assertTrue(JapaneseChronology.INSTANCE.eras().contains(eraObj));
+        assertEquals(eraObj, era);
+        assertEquals(JapaneseChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear);
+        assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ;
+        assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear).isLeap()) ;
+    }
+
+    //-----------------------------------------------------------------------
+    // with(WithAdjuster)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_adjust1() {
+        JapaneseDate base = JapaneseChronology.INSTANCE.date(1728, 10, 29);
+        JapaneseDate test = base.with(Adjusters.lastDayOfMonth());
+        assertEquals(test, JapaneseChronology.INSTANCE.date(1728, 10, 31));
+    }
+
+    @Test(groups={"tck"})
+    public void test_adjust2() {
+        JapaneseDate base = JapaneseChronology.INSTANCE.date(1728, 12, 2);
+        JapaneseDate test = base.with(Adjusters.lastDayOfMonth());
+        assertEquals(test, JapaneseChronology.INSTANCE.date(1728, 12, 31));
+    }
+
+    //-----------------------------------------------------------------------
+    // JapaneseDate.with(Local*)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_adjust_toLocalDate() {
+        JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1726, 1, 4);
+        JapaneseDate test = jdate.with(LocalDate.of(2012, 7, 6));
+        assertEquals(test, JapaneseChronology.INSTANCE.date(2012, 7, 6));
+    }
+
+    @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
+    public void test_adjust_toMonth() {
+        JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1726, 1, 4);
+        jdate.with(Month.APRIL);
+    }
+
+    //-----------------------------------------------------------------------
+    // LocalDate.with(JapaneseDate)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_LocalDate_adjustToJapaneseDate() {
+        JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1728, 10, 29);
+        LocalDate test = LocalDate.MIN.with(jdate);
+        assertEquals(test, LocalDate.of(1728, 10, 29));
+    }
+
+    @Test(groups={"tck"})
+    public void test_LocalDateTime_adjustToJapaneseDate() {
+        JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1728, 10, 29);
+        LocalDateTime test = LocalDateTime.MIN.with(jdate);
+        assertEquals(test, LocalDateTime.of(1728, 10, 29, 0, 0));
+    }
+
+    //-----------------------------------------------------------------------
+    // Check Japanese Eras
+    //-----------------------------------------------------------------------
+    @DataProvider(name="japaneseEras")
+    Object[][] data_japanseseEras() {
+        return new Object[][] {
+            { JapaneseChronology.ERA_SEIREKI, -999, "Seireki"},
+            { JapaneseChronology.ERA_MEIJI, -1, "Meiji"},
+            { JapaneseChronology.ERA_TAISHO, 0, "Taisho"},
+            { JapaneseChronology.ERA_SHOWA, 1, "Showa"},
+            { JapaneseChronology.ERA_HEISEI, 2, "Heisei"},
+        };
+    }
+
+    @Test(groups={"tck"}, dataProvider="japaneseEras")
+    public void test_Japanese_Eras(Era era, int eraValue, String name) {
+        assertEquals(era.getValue(), eraValue, "EraValue");
+        assertEquals(era.toString(), name, "Era Name");
+        assertEquals(era, JapaneseChronology.INSTANCE.eraOf(eraValue), "JapaneseChronology.eraOf()");
+        List<Era> eras = JapaneseChronology.INSTANCE.eras();
+        assertTrue(eras.contains(era), "Era is not present in JapaneseChronology.INSTANCE.eras()");
+    }
+
+    @Test(groups="tck")
+    public void test_Japanese_badEras() {
+        int badEras[] = {-1000, -998, -997, -2, 3, 4, 1000};
+        for (int badEra : badEras) {
+            try {
+                Era era = JapaneseChronology.INSTANCE.eraOf(badEra);
+                fail("JapaneseChronology.eraOf returned " + era + " + for invalid eraValue " + badEra);
+            } catch (DateTimeException ex) {
+                // ignore expected exception
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    // toString()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toString")
+    Object[][] data_toString() {
+        return new Object[][] {
+            {JapaneseChronology.INSTANCE.date(0001,  1,  1), "Japanese 0001-01-01"},
+            {JapaneseChronology.INSTANCE.date(1728, 10, 28), "Japanese 1728-10-28"},
+            {JapaneseChronology.INSTANCE.date(1728, 10, 29), "Japanese 1728-10-29"},
+            {JapaneseChronology.INSTANCE.date(1727, 12,  5), "Japanese 1727-12-05"},
+            {JapaneseChronology.INSTANCE.date(1727, 12,  6), "Japanese 1727-12-06"},
+            {JapaneseChronology.INSTANCE.date(1868,  9,  8), "Japanese Meiji 1-09-08"},
+            {JapaneseChronology.INSTANCE.date(1912,  7, 29), "Japanese Meiji 45-07-29"},
+            {JapaneseChronology.INSTANCE.date(1912,  7, 30), "Japanese Taisho 1-07-30"},
+            {JapaneseChronology.INSTANCE.date(1926, 12, 24), "Japanese Taisho 15-12-24"},
+            {JapaneseChronology.INSTANCE.date(1926, 12, 25), "Japanese Showa 1-12-25"},
+            {JapaneseChronology.INSTANCE.date(1989,  1,  7), "Japanese Showa 64-01-07"},
+            {JapaneseChronology.INSTANCE.date(1989,  1,  8), "Japanese Heisei 1-01-08"},
+            {JapaneseChronology.INSTANCE.date(2012, 12,  6), "Japanese Heisei 24-12-06"},
+        };
+    }
+
+    @Test(dataProvider="toString", groups={"tck"})
+    public void test_toString(JapaneseDate jdate, String expected) {
+        assertEquals(jdate.toString(), expected);
+    }
+
+    //-----------------------------------------------------------------------
+    // equals()
+    //-----------------------------------------------------------------------
+    @Test(groups="tck")
+    public void test_equals_true() {
+        assertTrue(JapaneseChronology.INSTANCE.equals(JapaneseChronology.INSTANCE));
+    }
+
+    @Test(groups="tck")
+    public void test_equals_false() {
+        assertFalse(JapaneseChronology.INSTANCE.equals(IsoChronology.INSTANCE));
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/chrono/TestMinguoChronology.java b/jdk/test/java/time/tck/java/time/chrono/TestMinguoChronology.java
new file mode 100644
index 0000000..5ea1979
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/chrono/TestMinguoChronology.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.chrono;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.Month;
+import java.time.ZoneOffset;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.MinguoDate;
+import java.time.temporal.Adjusters;
+import java.time.temporal.ChronoUnit;
+import java.time.chrono.ChronoZonedDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.Era;
+import java.time.Year;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test.
+ */
+@Test
+public class TestMinguoChronology {
+
+    private static final int YDIFF = 1911;
+    //-----------------------------------------------------------------------
+    // Chronology.ofName("Minguo")  Lookup by name
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_chrono_byName() {
+        Chronology c = MinguoChronology.INSTANCE;
+        Chronology test = Chronology.of("Minguo");
+        Assert.assertNotNull(test, "The Minguo calendar could not be found byName");
+        Assert.assertEquals(test.getId(), "Minguo", "ID mismatch");
+        Assert.assertEquals(test.getCalendarType(), "roc", "Type mismatch");
+        Assert.assertEquals(test, c);
+    }
+
+    //-----------------------------------------------------------------------
+    // creation, toLocalDate()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="samples")
+    Object[][] data_samples() {
+        return new Object[][] {
+            {MinguoChronology.INSTANCE.date(1, 1, 1), LocalDate.of(1 + YDIFF, 1, 1)},
+            {MinguoChronology.INSTANCE.date(1, 1, 2), LocalDate.of(1 + YDIFF, 1, 2)},
+            {MinguoChronology.INSTANCE.date(1, 1, 3), LocalDate.of(1 + YDIFF, 1, 3)},
+
+            {MinguoChronology.INSTANCE.date(2, 1, 1), LocalDate.of(2 + YDIFF, 1, 1)},
+            {MinguoChronology.INSTANCE.date(3, 1, 1), LocalDate.of(3 + YDIFF, 1, 1)},
+            {MinguoChronology.INSTANCE.date(3, 12, 6), LocalDate.of(3 + YDIFF, 12, 6)},
+            {MinguoChronology.INSTANCE.date(4, 1, 1), LocalDate.of(4 + YDIFF, 1, 1)},
+            {MinguoChronology.INSTANCE.date(4, 7, 3), LocalDate.of(4 + YDIFF, 7, 3)},
+            {MinguoChronology.INSTANCE.date(4, 7, 4), LocalDate.of(4 + YDIFF, 7, 4)},
+            {MinguoChronology.INSTANCE.date(5, 1, 1), LocalDate.of(5 + YDIFF, 1, 1)},
+            {MinguoChronology.INSTANCE.date(100, 3, 3), LocalDate.of(100 + YDIFF, 3, 3)},
+            {MinguoChronology.INSTANCE.date(101, 10, 28), LocalDate.of(101 + YDIFF, 10, 28)},
+            {MinguoChronology.INSTANCE.date(101, 10, 29), LocalDate.of(101 + YDIFF, 10, 29)},
+
+            {MinguoChronology.INSTANCE.dateYearDay(1916 - YDIFF, 60), LocalDate.of(1916, 2, 29)},
+            {MinguoChronology.INSTANCE.dateYearDay(1908 - YDIFF, 60), LocalDate.of(1908, 2, 29)},
+            {MinguoChronology.INSTANCE.dateYearDay(2000 - YDIFF, 60), LocalDate.of(2000, 2, 29)},
+            {MinguoChronology.INSTANCE.dateYearDay(2400 - YDIFF, 60), LocalDate.of(2400, 2, 29)},
+        };
+    }
+
+    @Test(dataProvider="samples", groups={"tck"})
+    public void test_toLocalDate(MinguoDate minguo, LocalDate iso) {
+        assertEquals(LocalDate.from(minguo), iso);
+    }
+
+    @Test(dataProvider="samples", groups={"tck"})
+    public void test_fromCalendrical(MinguoDate minguo, LocalDate iso) {
+        assertEquals(MinguoChronology.INSTANCE.date(iso), minguo);
+    }
+
+    @SuppressWarnings("unused")
+    @Test(dataProvider="samples", groups={"implementation"})
+    public void test_MinguoDate(MinguoDate minguoDate, LocalDate iso) {
+        MinguoDate hd = minguoDate;
+        ChronoLocalDateTime<MinguoDate> hdt = hd.atTime(LocalTime.NOON);
+        ZoneOffset zo = ZoneOffset.ofHours(1);
+        ChronoZonedDateTime<MinguoDate> hzdt = hdt.atZone(zo);
+        hdt = hdt.plus(1, ChronoUnit.YEARS);
+        hdt = hdt.plus(1, ChronoUnit.MONTHS);
+        hdt = hdt.plus(1, ChronoUnit.DAYS);
+        hdt = hdt.plus(1, ChronoUnit.HOURS);
+        hdt = hdt.plus(1, ChronoUnit.MINUTES);
+        hdt = hdt.plus(1, ChronoUnit.SECONDS);
+        hdt = hdt.plus(1, ChronoUnit.NANOS);
+        ChronoLocalDateTime<MinguoDate> a2 = hzdt.toLocalDateTime();
+        MinguoDate a3 = a2.toLocalDate();
+        MinguoDate a5 = hzdt.toLocalDate();
+        //System.out.printf(" d: %s, dt: %s; odt: %s; zodt: %s; a4: %s%n", date, hdt, hodt, hzdt, a5);
+    }
+
+    @Test()
+    public void test_MinguoChrono() {
+        MinguoDate h1 = (MinguoDate)MinguoChronology.ERA_ROC.date(1, 2, 3);
+        MinguoDate h2 = h1;
+        ChronoLocalDateTime<MinguoDate> h3 = h2.atTime(LocalTime.NOON);
+        @SuppressWarnings("unused")
+        ChronoZonedDateTime<MinguoDate> h4 = h3.atZone(ZoneOffset.UTC);
+    }
+
+    @DataProvider(name="badDates")
+    Object[][] data_badDates() {
+        return new Object[][] {
+            {1912, 0, 0},
+
+            {1912, -1, 1},
+            {1912, 0, 1},
+            {1912, 14, 1},
+            {1912, 15, 1},
+
+            {1912, 1, -1},
+            {1912, 1, 0},
+            {1912, 1, 32},
+            {1912, 2, 29},
+            {1912, 2, 30},
+
+            {1912, 12, -1},
+            {1912, 12, 0},
+            {1912, 12, 32},
+
+            {1907 - YDIFF, 2, 29},
+            {100 - YDIFF, 2, 29},
+            {2100 - YDIFF, 2, 29},
+            {2101 - YDIFF, 2, 29},
+            };
+    }
+
+    @Test(dataProvider="badDates", groups={"tck"}, expectedExceptions=DateTimeException.class)
+    public void test_badDates(int year, int month, int dom) {
+        MinguoChronology.INSTANCE.date(year, month, dom);
+    }
+
+    //-----------------------------------------------------------------------
+    // prolepticYear() and is LeapYear()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="prolepticYear")
+    Object[][] data_prolepticYear() {
+        return new Object[][] {
+            {1, MinguoChronology.ERA_ROC, 1912 - YDIFF, 1912 - YDIFF, true},
+            {1, MinguoChronology.ERA_ROC, 1916 - YDIFF, 1916 - YDIFF, true},
+            {1, MinguoChronology.ERA_ROC, 1914 - YDIFF, 1914 - YDIFF, false},
+            {1, MinguoChronology.ERA_ROC, 2000 - YDIFF, 2000 - YDIFF, true},
+            {1, MinguoChronology.ERA_ROC, 2100 - YDIFF, 2100 - YDIFF, false},
+            {1, MinguoChronology.ERA_ROC, 0, 0, false},
+            {1, MinguoChronology.ERA_ROC, 1908 - YDIFF, 1908 - YDIFF, true},
+            {1, MinguoChronology.ERA_ROC, 1900 - YDIFF, 1900 - YDIFF, false},
+            {1, MinguoChronology.ERA_ROC, 1600 - YDIFF, 1600 - YDIFF, true},
+
+            {0, MinguoChronology.ERA_BEFORE_ROC, YDIFF - 1911, 1912 - YDIFF, true},
+            {0, MinguoChronology.ERA_BEFORE_ROC, YDIFF - 1915, 1916 - YDIFF, true},
+            {0, MinguoChronology.ERA_BEFORE_ROC, YDIFF - 1913, 1914 - YDIFF, false},
+            {0, MinguoChronology.ERA_BEFORE_ROC, YDIFF - 1999, 2000 - YDIFF, true},
+            {0, MinguoChronology.ERA_BEFORE_ROC, YDIFF - 2099, 2100 - YDIFF, false},
+            {0, MinguoChronology.ERA_BEFORE_ROC, 1, 0, false},
+            {0, MinguoChronology.ERA_BEFORE_ROC, YDIFF - 1907, 1908 - YDIFF, true},
+            {0, MinguoChronology.ERA_BEFORE_ROC, YDIFF - 1899, 1900 - YDIFF, false},
+            {0, MinguoChronology.ERA_BEFORE_ROC, YDIFF - 1599, 1600 - YDIFF, true},
+
+        };
+    }
+
+    @Test(dataProvider="prolepticYear", groups={"tck"})
+    public void test_prolepticYear(int eraValue, Era  era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) {
+        Era eraObj = MinguoChronology.INSTANCE.eraOf(eraValue) ;
+        assertTrue(MinguoChronology.INSTANCE.eras().contains(eraObj));
+        assertEquals(eraObj, era);
+        assertEquals(MinguoChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear);
+        assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ;
+        assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear + YDIFF).isLeap()) ;
+    }
+
+    //-----------------------------------------------------------------------
+    // with(DateTimeAdjuster)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_adjust1() {
+        MinguoDate base = MinguoChronology.INSTANCE.date(2012, 10, 29);
+        MinguoDate test = base.with(Adjusters.lastDayOfMonth());
+        assertEquals(test, MinguoChronology.INSTANCE.date(2012, 10, 31));
+    }
+
+    @Test(groups={"tck"})
+    public void test_adjust2() {
+        MinguoDate base = MinguoChronology.INSTANCE.date(1728, 12, 2);
+        MinguoDate test = base.with(Adjusters.lastDayOfMonth());
+        assertEquals(test, MinguoChronology.INSTANCE.date(1728, 12, 31));
+    }
+
+    //-----------------------------------------------------------------------
+    // MinguoDate.with(Local*)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_adjust_toLocalDate() {
+        MinguoDate minguo = MinguoChronology.INSTANCE.date(99, 1, 4);
+        MinguoDate test = minguo.with(LocalDate.of(2012, 7, 6));
+        assertEquals(test, MinguoChronology.INSTANCE.date(101, 7, 6));
+    }
+
+    @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
+    public void test_adjust_toMonth() {
+        MinguoDate minguo = MinguoChronology.INSTANCE.date(1726, 1, 4);
+        minguo.with(Month.APRIL);
+    }
+
+    //-----------------------------------------------------------------------
+    // LocalDate.with(MinguoDate)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_LocalDate_adjustToMinguoDate() {
+        MinguoDate minguo = MinguoChronology.INSTANCE.date(101, 10, 29);
+        LocalDate test = LocalDate.MIN.with(minguo);
+        assertEquals(test, LocalDate.of(2012, 10, 29));
+    }
+
+    @Test(groups={"tck"})
+    public void test_LocalDateTime_adjustToMinguoDate() {
+        MinguoDate minguo = MinguoChronology.INSTANCE.date(101, 10, 29);
+        LocalDateTime test = LocalDateTime.MIN.with(minguo);
+        assertEquals(test, LocalDateTime.of(2012, 10, 29, 0, 0));
+    }
+
+    //-----------------------------------------------------------------------
+    // toString()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toString")
+    Object[][] data_toString() {
+        return new Object[][] {
+            {MinguoChronology.INSTANCE.date(1, 1, 1), "Minguo ROC 1-01-01"},
+            {MinguoChronology.INSTANCE.date(1728, 10, 28), "Minguo ROC 1728-10-28"},
+            {MinguoChronology.INSTANCE.date(1728, 10, 29), "Minguo ROC 1728-10-29"},
+            {MinguoChronology.INSTANCE.date(1727, 12, 5), "Minguo ROC 1727-12-05"},
+            {MinguoChronology.INSTANCE.date(1727, 12, 6), "Minguo ROC 1727-12-06"},
+        };
+    }
+
+    @Test(dataProvider="toString", groups={"tck"})
+    public void test_toString(MinguoDate minguo, String expected) {
+        assertEquals(minguo.toString(), expected);
+    }
+
+    //-----------------------------------------------------------------------
+    // equals()
+    //-----------------------------------------------------------------------
+    @Test(groups="tck")
+    public void test_equals_true() {
+        assertTrue(MinguoChronology.INSTANCE.equals(MinguoChronology.INSTANCE));
+    }
+
+    @Test(groups="tck")
+    public void test_equals_false() {
+        assertFalse(MinguoChronology.INSTANCE.equals(IsoChronology.INSTANCE));
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/chrono/TestThaiBuddhistChronology.java b/jdk/test/java/time/tck/java/time/chrono/TestThaiBuddhistChronology.java
new file mode 100644
index 0000000..32eae1e
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/chrono/TestThaiBuddhistChronology.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.chrono;
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_YEAR;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.YEAR;
+import static java.time.temporal.ChronoField.YEAR_OF_ERA;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.Month;
+import java.time.Year;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.ThaiBuddhistDate;
+import java.time.chrono.Chronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Era;
+import java.time.chrono.IsoChronology;
+import java.time.temporal.Adjusters;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ValueRange;
+import java.util.Locale;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test.
+ */
+@Test
+public class TestThaiBuddhistChronology {
+
+    private static final int YDIFF = 543;
+
+    //-----------------------------------------------------------------------
+    // Chronology.of(String)
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_chrono_byName() {
+        Chronology c = ThaiBuddhistChronology.INSTANCE;
+        Chronology test = Chronology.of("ThaiBuddhist");
+        Assert.assertNotNull(test, "The ThaiBuddhist calendar could not be found byName");
+        Assert.assertEquals(test.getId(), "ThaiBuddhist", "ID mismatch");
+        Assert.assertEquals(test.getCalendarType(), "buddhist", "Type mismatch");
+        Assert.assertEquals(test, c);
+    }
+
+    //-----------------------------------------------------------------------
+    // Chronology.ofLocale(Locale)
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_chrono_byLocale_fullTag_thaiCalendarFromThai() {
+        Chronology test = Chronology.ofLocale(Locale.forLanguageTag("th-TH-u-ca-buddhist"));
+        Assert.assertEquals(test.getId(), "ThaiBuddhist");
+        Assert.assertEquals(test, ThaiBuddhistChronology.INSTANCE);
+    }
+
+    @Test
+    public void test_chrono_byLocale_fullTag_thaiCalendarFromElsewhere() {
+        Chronology test = Chronology.ofLocale(Locale.forLanguageTag("en-US-u-ca-buddhist"));
+        Assert.assertEquals(test.getId(), "ThaiBuddhist");
+        Assert.assertEquals(test, ThaiBuddhistChronology.INSTANCE);
+    }
+
+    @Test
+    public void test_chrono_byLocale_oldTH_noVariant() {  // deliberately different to Calendar
+        Chronology test = Chronology.ofLocale(new Locale("th", "TH"));
+        Assert.assertEquals(test.getId(), "ISO");
+        Assert.assertEquals(test, IsoChronology.INSTANCE);
+    }
+
+    @Test
+    public void test_chrono_byLocale_oldTH_variant() {
+        Chronology test = Chronology.ofLocale(new Locale("th", "TH", "TH"));
+        Assert.assertEquals(test.getId(), "ISO");
+        Assert.assertEquals(test, IsoChronology.INSTANCE);
+    }
+
+    @Test
+    public void test_chrono_byLocale_iso() {
+        Assert.assertEquals(Chronology.ofLocale(new Locale("th", "TH")).getId(), "ISO");
+        Assert.assertEquals(Chronology.ofLocale(Locale.forLanguageTag("th-TH")).getId(), "ISO");
+        Assert.assertEquals(Chronology.ofLocale(Locale.forLanguageTag("th-TH-TH")).getId(), "ISO");
+    }
+
+    //-----------------------------------------------------------------------
+    // creation, toLocalDate()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="samples")
+    Object[][] data_samples() {
+        return new Object[][] {
+            {ThaiBuddhistChronology.INSTANCE.date(1 + YDIFF, 1, 1), LocalDate.of(1, 1, 1)},
+            {ThaiBuddhistChronology.INSTANCE.date(1 + YDIFF, 1, 2), LocalDate.of(1, 1, 2)},
+            {ThaiBuddhistChronology.INSTANCE.date(1 + YDIFF, 1, 3), LocalDate.of(1, 1, 3)},
+
+            {ThaiBuddhistChronology.INSTANCE.date(2 + YDIFF, 1, 1), LocalDate.of(2, 1, 1)},
+            {ThaiBuddhistChronology.INSTANCE.date(3 + YDIFF, 1, 1), LocalDate.of(3, 1, 1)},
+            {ThaiBuddhistChronology.INSTANCE.date(3 + YDIFF, 12, 6), LocalDate.of(3, 12, 6)},
+            {ThaiBuddhistChronology.INSTANCE.date(4 + YDIFF, 1, 1), LocalDate.of(4, 1, 1)},
+            {ThaiBuddhistChronology.INSTANCE.date(4 + YDIFF, 7, 3), LocalDate.of(4, 7, 3)},
+            {ThaiBuddhistChronology.INSTANCE.date(4 + YDIFF, 7, 4), LocalDate.of(4, 7, 4)},
+            {ThaiBuddhistChronology.INSTANCE.date(5 + YDIFF, 1, 1), LocalDate.of(5, 1, 1)},
+            {ThaiBuddhistChronology.INSTANCE.date(1662 + YDIFF, 3, 3), LocalDate.of(1662, 3, 3)},
+            {ThaiBuddhistChronology.INSTANCE.date(1728 + YDIFF, 10, 28), LocalDate.of(1728, 10, 28)},
+            {ThaiBuddhistChronology.INSTANCE.date(1728 + YDIFF, 10, 29), LocalDate.of(1728, 10, 29)},
+            {ThaiBuddhistChronology.INSTANCE.date(2555, 8, 29), LocalDate.of(2012, 8, 29)},
+
+            {ThaiBuddhistChronology.INSTANCE.dateYearDay(4 + YDIFF, 60), LocalDate.of(4, 2, 29)},
+            {ThaiBuddhistChronology.INSTANCE.dateYearDay(400 + YDIFF, 60), LocalDate.of(400, 2, 29)},
+            {ThaiBuddhistChronology.INSTANCE.dateYearDay(2000 + YDIFF, 60), LocalDate.of(2000, 2, 29)},
+
+        };
+    }
+
+    @Test(dataProvider="samples", groups={"tck"})
+    public void test_toLocalDate(ThaiBuddhistDate jdate, LocalDate iso) {
+        assertEquals(LocalDate.from(jdate), iso);
+    }
+
+    @Test(dataProvider="samples", groups={"tck"})
+    public void test_fromCalendrical(ThaiBuddhistDate jdate, LocalDate iso) {
+        assertEquals(ThaiBuddhistChronology.INSTANCE.date(iso), jdate);
+    }
+
+    @DataProvider(name="badDates")
+    Object[][] data_badDates() {
+        return new Object[][] {
+            {1728, 0, 0},
+
+            {1728, -1, 1},
+            {1728, 0, 1},
+            {1728, 14, 1},
+            {1728, 15, 1},
+
+            {1728, 1, -1},
+            {1728, 1, 0},
+            {1728, 1, 32},
+
+            {1728, 12, -1},
+            {1728, 12, 0},
+            {1728, 12, 32},
+
+            {3 + YDIFF, 2, 29},
+            {600 + YDIFF, 2, 29},
+            {1501 + YDIFF, 2, 29},
+        };
+    }
+
+    @Test(dataProvider="badDates", groups={"tck"}, expectedExceptions=DateTimeException.class)
+    public void test_badDates(int year, int month, int dom) {
+        ThaiBuddhistChronology.INSTANCE.date(year, month, dom);
+    }
+
+  //-----------------------------------------------------------------------
+  // prolepticYear() and is LeapYear()
+  //-----------------------------------------------------------------------
+  @DataProvider(name="prolepticYear")
+  Object[][] data_prolepticYear() {
+      return new Object[][] {
+          {1, ThaiBuddhistChronology.ERA_BE, 4 + YDIFF, 4 + YDIFF, true},
+          {1, ThaiBuddhistChronology.ERA_BE, 7 + YDIFF, 7 + YDIFF, false},
+          {1, ThaiBuddhistChronology.ERA_BE, 8 + YDIFF, 8 + YDIFF, true},
+          {1, ThaiBuddhistChronology.ERA_BE, 1000 + YDIFF, 1000 + YDIFF, false},
+          {1, ThaiBuddhistChronology.ERA_BE, 2000 + YDIFF, 2000 + YDIFF, true},
+          {1, ThaiBuddhistChronology.ERA_BE, 0, 0, false},
+          {1, ThaiBuddhistChronology.ERA_BE, -4 + YDIFF, -4 + YDIFF, true},
+          {1, ThaiBuddhistChronology.ERA_BE, -7 + YDIFF, -7 + YDIFF, false},
+          {1, ThaiBuddhistChronology.ERA_BE, -100 + YDIFF, -100 + YDIFF, false},
+          {1, ThaiBuddhistChronology.ERA_BE, -800 + YDIFF, -800 + YDIFF, true},
+
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, -3 - YDIFF, 4 + YDIFF, true},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, -6 - YDIFF, 7 + YDIFF, false},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, -7 - YDIFF, 8 + YDIFF, true},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, -999 - YDIFF, 1000 + YDIFF, false},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, -1999 - YDIFF, 2000 + YDIFF, true},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, 1, 0, false},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, 5 - YDIFF, -4 + YDIFF, true},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, 8 - YDIFF, -7 + YDIFF, false},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, 101 - YDIFF, -100 + YDIFF, false},
+          {0, ThaiBuddhistChronology.ERA_BEFORE_BE, 801 - YDIFF, -800 + YDIFF, true},
+
+      };
+  }
+
+  @Test(dataProvider="prolepticYear", groups={"tck"})
+  public void test_prolepticYear(int eraValue, Era  era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) {
+      Era eraObj = ThaiBuddhistChronology.INSTANCE.eraOf(eraValue) ;
+      assertTrue(ThaiBuddhistChronology.INSTANCE.eras().contains(eraObj));
+      assertEquals(eraObj, era);
+      assertEquals(ThaiBuddhistChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear);
+      assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ;
+      assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear - YDIFF).isLeap()) ;
+  }
+
+    //-----------------------------------------------------------------------
+    // with(WithAdjuster)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_adjust1() {
+        ThaiBuddhistDate base = ThaiBuddhistChronology.INSTANCE.date(1728, 10, 29);
+        ThaiBuddhistDate test = base.with(Adjusters.lastDayOfMonth());
+        assertEquals(test, ThaiBuddhistChronology.INSTANCE.date(1728, 10, 31));
+    }
+
+    @Test(groups={"tck"})
+    public void test_adjust2() {
+        ThaiBuddhistDate base = ThaiBuddhistChronology.INSTANCE.date(1728, 12, 2);
+        ThaiBuddhistDate test = base.with(Adjusters.lastDayOfMonth());
+        assertEquals(test, ThaiBuddhistChronology.INSTANCE.date(1728, 12, 31));
+    }
+
+    //-----------------------------------------------------------------------
+    // withYear()
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_withYear_BE() {
+        ThaiBuddhistDate base = ThaiBuddhistChronology.INSTANCE.date(2555, 8, 29);
+        ThaiBuddhistDate test = base.with(YEAR, 2554);
+        assertEquals(test, ThaiBuddhistChronology.INSTANCE.date(2554, 8, 29));
+    }
+
+    @Test(groups={"tck"})
+    public void test_withYear_BBE() {
+        ThaiBuddhistDate base = ThaiBuddhistChronology.INSTANCE.date(-2554, 8, 29);
+        ThaiBuddhistDate test = base.with(YEAR_OF_ERA, 2554);
+        assertEquals(test, ThaiBuddhistChronology.INSTANCE.date(-2553, 8, 29));
+    }
+
+    //-----------------------------------------------------------------------
+    // withEra()
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_withEra_BE() {
+        ThaiBuddhistDate base = ThaiBuddhistChronology.INSTANCE.date(2555, 8, 29);
+        ThaiBuddhistDate test = base.with(ChronoField.ERA, ThaiBuddhistChronology.ERA_BE.getValue());
+        assertEquals(test, ThaiBuddhistChronology.INSTANCE.date(2555, 8, 29));
+    }
+
+    @Test(groups={"tck"})
+    public void test_withEra_BBE() {
+        ThaiBuddhistDate base = ThaiBuddhistChronology.INSTANCE.date(-2554, 8, 29);
+        ThaiBuddhistDate test = base.with(ChronoField.ERA, ThaiBuddhistChronology.ERA_BEFORE_BE.getValue());
+        assertEquals(test, ThaiBuddhistChronology.INSTANCE.date(-2554, 8, 29));
+    }
+
+    @Test(groups={"tck"})
+    public void test_withEra_swap() {
+        ThaiBuddhistDate base = ThaiBuddhistChronology.INSTANCE.date(-2554, 8, 29);
+        ThaiBuddhistDate test = base.with(ChronoField.ERA, ThaiBuddhistChronology.ERA_BE.getValue());
+        assertEquals(test, ThaiBuddhistChronology.INSTANCE.date(2555, 8, 29));
+    }
+
+    //-----------------------------------------------------------------------
+    // BuddhistDate.with(Local*)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_adjust_toLocalDate() {
+        ThaiBuddhistDate jdate = ThaiBuddhistChronology.INSTANCE.date(1726, 1, 4);
+        ThaiBuddhistDate test = jdate.with(LocalDate.of(2012, 7, 6));
+        assertEquals(test, ThaiBuddhistChronology.INSTANCE.date(2555, 7, 6));
+    }
+
+    @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
+    public void test_adjust_toMonth() {
+        ThaiBuddhistDate jdate = ThaiBuddhistChronology.INSTANCE.date(1726, 1, 4);
+        jdate.with(Month.APRIL);
+    }
+
+    //-----------------------------------------------------------------------
+    // LocalDate.with(BuddhistDate)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_LocalDate_adjustToBuddhistDate() {
+        ThaiBuddhistDate jdate = ThaiBuddhistChronology.INSTANCE.date(2555, 10, 29);
+        LocalDate test = LocalDate.MIN.with(jdate);
+        assertEquals(test, LocalDate.of(2012, 10, 29));
+    }
+
+    @Test(groups={"tck"})
+    public void test_LocalDateTime_adjustToBuddhistDate() {
+        ThaiBuddhistDate jdate = ThaiBuddhistChronology.INSTANCE.date(2555, 10, 29);
+        LocalDateTime test = LocalDateTime.MIN.with(jdate);
+        assertEquals(test, LocalDateTime.of(2012, 10, 29, 0, 0));
+    }
+
+    //-----------------------------------------------------------------------
+    // toString()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toString")
+    Object[][] data_toString() {
+        return new Object[][] {
+            {ThaiBuddhistChronology.INSTANCE.date(544, 1, 1), "ThaiBuddhist BE 544-01-01"},
+            {ThaiBuddhistChronology.INSTANCE.date(2271, 10, 28), "ThaiBuddhist BE 2271-10-28"},
+            {ThaiBuddhistChronology.INSTANCE.date(2271, 10, 29), "ThaiBuddhist BE 2271-10-29"},
+            {ThaiBuddhistChronology.INSTANCE.date(2270, 12, 5), "ThaiBuddhist BE 2270-12-05"},
+            {ThaiBuddhistChronology.INSTANCE.date(2270, 12, 6), "ThaiBuddhist BE 2270-12-06"},
+        };
+    }
+
+    @Test(dataProvider="toString", groups={"tck"})
+    public void test_toString(ThaiBuddhistDate jdate, String expected) {
+        assertEquals(jdate.toString(), expected);
+    }
+
+    //-----------------------------------------------------------------------
+    // chronology range(ChronoField)
+    //-----------------------------------------------------------------------
+    @Test(groups={"tck"})
+    public void test_Chrono_range() {
+        long minYear = LocalDate.MIN.getYear() + YDIFF;
+        long maxYear = LocalDate.MAX.getYear() + YDIFF;
+        assertEquals(ThaiBuddhistChronology.INSTANCE.range(YEAR), ValueRange.of(minYear, maxYear));
+        assertEquals(ThaiBuddhistChronology.INSTANCE.range(YEAR_OF_ERA), ValueRange.of(1, -minYear + 1, maxYear));
+
+        assertEquals(ThaiBuddhistChronology.INSTANCE.range(DAY_OF_MONTH), DAY_OF_MONTH.range());
+        assertEquals(ThaiBuddhistChronology.INSTANCE.range(DAY_OF_YEAR), DAY_OF_YEAR.range());
+        assertEquals(ThaiBuddhistChronology.INSTANCE.range(MONTH_OF_YEAR), MONTH_OF_YEAR.range());
+    }
+
+    //-----------------------------------------------------------------------
+    // equals()
+    //-----------------------------------------------------------------------
+    @Test(groups="tck")
+    public void test_equals_true() {
+        assertTrue(ThaiBuddhistChronology.INSTANCE.equals(ThaiBuddhistChronology.INSTANCE));
+    }
+
+    @Test(groups="tck")
+    public void test_equals_false() {
+        assertFalse(ThaiBuddhistChronology.INSTANCE.equals(IsoChronology.INSTANCE));
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/format/TCKChronoPrinterParser.java b/jdk/test/java/time/tck/java/time/format/TCKChronoPrinterParser.java
new file mode 100644
index 0000000..e4e74f6
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/format/TCKChronoPrinterParser.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.format;
+
+import static org.testng.Assert.assertEquals;
+
+import java.text.ParsePosition;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.Queries;
+import java.time.temporal.TemporalAccessor;
+import java.util.Locale;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test formatter chrono.
+ */
+@Test
+public class TCKChronoPrinterParser {
+    // this test assumes ISO, ThaiBuddhist and Japanese are available
+
+    private DateTimeFormatterBuilder builder;
+    private ParsePosition pos;
+
+    @BeforeMethod
+    public void setUp() {
+        builder = new DateTimeFormatterBuilder();
+        pos = new ParsePosition(0);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(expectedExceptions=IndexOutOfBoundsException.class)
+    public void test_parse_negativePosition() {
+        builder.appendChronologyId().toFormatter().parseUnresolved("ISO", new ParsePosition(-1));
+    }
+
+    @Test(expectedExceptions=IndexOutOfBoundsException.class)
+    public void test_parse_offEndPosition() {
+        builder.appendChronologyId().toFormatter().parseUnresolved("ISO", new ParsePosition(4));
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="parseValid")
+    Object[][] data_parseValid() {
+        return new Object[][] {
+                {"ISO", IsoChronology.INSTANCE},
+                {"ThaiBuddhist", ThaiBuddhistChronology.INSTANCE},
+                {"Japanese", JapaneseChronology.INSTANCE},
+
+                {"ISO2012", IsoChronology.INSTANCE},
+                {"ThaiBuddhistXXX", ThaiBuddhistChronology.INSTANCE},
+                {"JapaneseXXX", JapaneseChronology.INSTANCE},
+        };
+    }
+
+    @Test(dataProvider="parseValid")
+    public void test_parseValid_caseSensitive(String text, Chronology expected) {
+        builder.appendChronologyId();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text, pos);
+        assertEquals(pos.getIndex(), expected.getId().length());
+        assertEquals(pos.getErrorIndex(), -1);
+        assertEquals(parsed.query(Queries.chronology()), expected);
+    }
+
+    @Test(dataProvider="parseValid")
+    public void test_parseValid_caseSensitive_lowercaseRejected(String text, Chronology expected) {
+        builder.appendChronologyId();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text.toLowerCase(Locale.ENGLISH), pos);
+        assertEquals(pos.getIndex(), 0);
+        assertEquals(pos.getErrorIndex(), 0);
+        assertEquals(parsed, null);
+    }
+
+    @Test(dataProvider="parseValid")
+    public void test_parseValid_caseInsensitive(String text, Chronology expected) {
+        builder.parseCaseInsensitive().appendChronologyId();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text.toLowerCase(Locale.ENGLISH), pos);
+        assertEquals(pos.getIndex(), expected.getId().length());
+        assertEquals(pos.getErrorIndex(), -1);
+        assertEquals(parsed.query(Queries.chronology()), expected);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="parseInvalid")
+    Object[][] data_parseInvalid() {
+        return new Object[][] {
+                {"Rubbish"},
+                {"IS"},
+                {"Thai"},
+                {"Japan"},
+        };
+    }
+
+    @Test(dataProvider="parseInvalid")
+    public void test_parseInvalid(String text) {
+        builder.appendChronologyId();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text, pos);
+        assertEquals(pos.getIndex(), 0);
+        assertEquals(pos.getErrorIndex(), 0);
+        assertEquals(parsed, null);
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatter.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatter.java
index e206a1f..f124d7e 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatter.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatter.java
@@ -61,12 +61,13 @@
 
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
-import java.io.IOException;
 import java.text.Format;
 import java.text.ParseException;
 import java.text.ParsePosition;
@@ -80,20 +81,16 @@
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
-import java.time.calendar.ThaiBuddhistChrono;
+import java.time.chrono.ThaiBuddhistChronology;
 import java.time.format.DateTimeFormatSymbols;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
-import java.time.format.DateTimePrintException;
 import java.time.format.SignStyle;
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.Chrono;
-import java.time.temporal.ISOChrono;
-import java.time.temporal.OffsetDate;
-import java.time.temporal.OffsetDateTime;
-import java.time.temporal.OffsetTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalQuery;
@@ -101,7 +98,6 @@
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import test.java.time.format.MockIOExceptionAppendable;
 
 /**
  * Test DateTimeFormatter.
@@ -113,8 +109,8 @@
     private static final ZoneOffset OFFSET_PTHREE = ZoneOffset.ofHours(3);
     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
 
-    private static final DateTimeFormatter BASIC_FORMATTER = DateTimeFormatters.pattern("'ONE'd");
-    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatters.pattern("'ONE'yyyy MM dd");
+    private static final DateTimeFormatter BASIC_FORMATTER = DateTimeFormatter.ofPattern("'ONE'd");
+    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("'ONE'yyyy MM dd");
 
     private DateTimeFormatter fmt;
 
@@ -141,13 +137,13 @@
 
     //-----------------------------------------------------------------------
     @Test
-    public void test_withChrono() {
+    public void test_withChronology() {
         DateTimeFormatter test = fmt;
-        assertEquals(test.getChrono(), null);
-        test = test.withChrono(ISOChrono.INSTANCE);
-        assertEquals(test.getChrono(), ISOChrono.INSTANCE);
-        test = test.withChrono(null);
-        assertEquals(test.getChrono(), null);
+        assertEquals(test.getChronology(), null);
+        test = test.withChronology(IsoChronology.INSTANCE);
+        assertEquals(test.getChronology(), IsoChronology.INSTANCE);
+        test = test.withChronology(null);
+        assertEquals(test.getChronology(), null);
     }
 
     //-----------------------------------------------------------------------
@@ -167,11 +163,10 @@
     // print
     //-----------------------------------------------------------------------
     @DataProvider(name="print")
-    Object[][] data_print() {
+    Object[][] data_format() {
         LocalDate ld = LocalDate.of(2008, 6, 30);
         LocalTime lt = LocalTime.of(11, 30);
         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 11, 30);
-        OffsetDate od = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
         OffsetTime ot = OffsetTime.of(LocalTime.of(11, 30), OFFSET_PONE);
         OffsetDateTime odt = OffsetDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30), OFFSET_PONE);
         ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30), ZONE_PARIS);
@@ -180,7 +175,6 @@
                 {null, null, ld, "2008::"},
                 {null, null, lt, ":11:"},
                 {null, null, ldt, "2008:11:"},
-                {null, null, od, "2008::+01:00"},
                 {null, null, ot, ":11:+01:00"},
                 {null, null, odt, "2008:11:+01:00"},
                 {null, null, zdt, "2008:11:+02:00Europe/Paris"},
@@ -189,7 +183,6 @@
                 {null, ZONE_PARIS, ld, "2008::"},
                 {null, ZONE_PARIS, lt, ":11:"},
                 {null, ZONE_PARIS, ldt, "2008:11:"},
-                {null, ZONE_PARIS, od, "2008::+01:00"},
                 {null, ZONE_PARIS, ot, ":11:+01:00"},
                 {null, ZONE_PARIS, odt, "2008:12:+02:00Europe/Paris"},
                 {null, ZONE_PARIS, zdt, "2008:11:+02:00Europe/Paris"},
@@ -198,61 +191,58 @@
                 {null, OFFSET_PTHREE, ld, "2008::"},
                 {null, OFFSET_PTHREE, lt, ":11:"},
                 {null, OFFSET_PTHREE, ldt, "2008:11:"},
-                {null, OFFSET_PTHREE, od, "2008::+01:00"},
                 {null, OFFSET_PTHREE, ot, ":11:+01:00"},
                 {null, OFFSET_PTHREE, odt, "2008:13:+03:00"},
                 {null, OFFSET_PTHREE, zdt, "2008:12:+03:00"},
                 {null, OFFSET_PTHREE, instant, "1970:04:+03:00"},
 
-                {ThaiBuddhistChrono.INSTANCE, null, ld, "2551::"},
-                {ThaiBuddhistChrono.INSTANCE, null, lt, ":11:"},
-                {ThaiBuddhistChrono.INSTANCE, null, ldt, "2551:11:"},
-                {ThaiBuddhistChrono.INSTANCE, null, od, "2551::+01:00"},
-                {ThaiBuddhistChrono.INSTANCE, null, ot, ":11:+01:00"},
-                {ThaiBuddhistChrono.INSTANCE, null, odt, "2551:11:+01:00"},
-                {ThaiBuddhistChrono.INSTANCE, null, zdt, "2551:11:+02:00Europe/Paris"},
-                {ThaiBuddhistChrono.INSTANCE, null, instant, "::"},
+                {ThaiBuddhistChronology.INSTANCE, null, ld, "2551::"},
+                {ThaiBuddhistChronology.INSTANCE, null, lt, ":11:"},
+                {ThaiBuddhistChronology.INSTANCE, null, ldt, "2551:11:"},
+                {ThaiBuddhistChronology.INSTANCE, null, ot, ":11:+01:00"},
+                {ThaiBuddhistChronology.INSTANCE, null, odt, "2551:11:+01:00"},
+                {ThaiBuddhistChronology.INSTANCE, null, zdt, "2551:11:+02:00Europe/Paris"},
+                {ThaiBuddhistChronology.INSTANCE, null, instant, "::"},
 
-                {ThaiBuddhistChrono.INSTANCE, ZONE_PARIS, ld, "2551::"},
-                {ThaiBuddhistChrono.INSTANCE, ZONE_PARIS, lt, ":11:"},
-                {ThaiBuddhistChrono.INSTANCE, ZONE_PARIS, ldt, "2551:11:"},
-                {ThaiBuddhistChrono.INSTANCE, ZONE_PARIS, od, "2551::+01:00"},
-                {ThaiBuddhistChrono.INSTANCE, ZONE_PARIS, ot, ":11:+01:00"},
-                {ThaiBuddhistChrono.INSTANCE, ZONE_PARIS, odt, "2551:12:+02:00Europe/Paris"},
-                {ThaiBuddhistChrono.INSTANCE, ZONE_PARIS, zdt, "2551:11:+02:00Europe/Paris"},
-                {ThaiBuddhistChrono.INSTANCE, ZONE_PARIS, instant, "1970:02:+01:00Europe/Paris"},
+                {ThaiBuddhistChronology.INSTANCE, ZONE_PARIS, ld, "2551::"},
+                {ThaiBuddhistChronology.INSTANCE, ZONE_PARIS, lt, ":11:"},
+                {ThaiBuddhistChronology.INSTANCE, ZONE_PARIS, ldt, "2551:11:"},
+                {ThaiBuddhistChronology.INSTANCE, ZONE_PARIS, ot, ":11:+01:00"},
+                {ThaiBuddhistChronology.INSTANCE, ZONE_PARIS, odt, "2551:12:+02:00Europe/Paris"},
+                {ThaiBuddhistChronology.INSTANCE, ZONE_PARIS, zdt, "2551:11:+02:00Europe/Paris"},
+                {ThaiBuddhistChronology.INSTANCE, ZONE_PARIS, instant, "1970:02:+01:00Europe/Paris"},
         };
     }
 
     @Test(dataProvider="print")
-    public void test_print_Temporal(Chrono<?> overrideChrono, ZoneId overrideZone, Temporal temporal, String expected) {
+    public void test_print_Temporal(Chronology overrideChrono, ZoneId overrideZone, Temporal temporal, String expected) {
         DateTimeFormatter test = new DateTimeFormatterBuilder()
                 .optionalStart().appendValue(YEAR, 4).optionalEnd()
                 .appendLiteral(':').optionalStart().appendValue(HOUR_OF_DAY, 2).optionalEnd()
                 .appendLiteral(':').optionalStart().appendOffsetId().optionalStart().appendZoneRegionId().optionalEnd().optionalEnd()
                 .toFormatter(Locale.ENGLISH)
-                .withChrono(overrideChrono).withZone(overrideZone);
-        String result = test.print(temporal);
+                .withChronology(overrideChrono).withZone(overrideZone);
+        String result = test.format(temporal);
         assertEquals(result, expected);
     }
 
     @Test
     public void test_print_Temporal_simple() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        String result = test.print(LocalDate.of(2008, 6, 30));
+        String result = test.format(LocalDate.of(2008, 6, 30));
         assertEquals(result, "ONE30");
     }
 
     @Test(expectedExceptions=DateTimeException.class)
     public void test_print_Temporal_noSuchField() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        test.print(LocalTime.of(11, 30));
+        test.format(LocalTime.of(11, 30));
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_print_Temporal_null() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        test.print((TemporalAccessor) null);
+        test.format((TemporalAccessor) null);
     }
 
     //-----------------------------------------------------------------------
@@ -260,7 +250,7 @@
     public void test_print_TemporalAppendable() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         StringBuilder buf = new StringBuilder();
-        test.printTo(LocalDate.of(2008, 6, 30), buf);
+        test.formatTo(LocalDate.of(2008, 6, 30), buf);
         assertEquals(buf.toString(), "ONE30");
     }
 
@@ -268,33 +258,117 @@
     public void test_print_TemporalAppendable_noSuchField() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         StringBuilder buf = new StringBuilder();
-        test.printTo(LocalTime.of(11, 30), buf);
+        test.formatTo(LocalTime.of(11, 30), buf);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_print_TemporalAppendable_nullTemporal() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         StringBuilder buf = new StringBuilder();
-        test.printTo((TemporalAccessor) null, buf);
+        test.formatTo((TemporalAccessor) null, buf);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void test_print_TemporalAppendable_nullAppendable() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        test.printTo(LocalDate.of(2008, 6, 30), (Appendable) null);
+        test.formatTo(LocalDate.of(2008, 6, 30), (Appendable) null);
     }
 
-    @Test(expectedExceptions=IOException.class)  // IOException
-    public void test_print_TemporalAppendable_ioError() throws Exception {
+    //-----------------------------------------------------------------------
+    // parse(CharSequence)
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_parse_CharSequence() {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        TemporalAccessor result = test.parse("ONE30");
+        assertEquals(result.isSupported(DAY_OF_MONTH), true);
+        assertEquals(result.getLong(DAY_OF_MONTH), 30L);
+        assertEquals(result.isSupported(HOUR_OF_DAY), false);
+    }
+
+    @Test
+    public void test_parse_CharSequence_resolved() {
+        DateTimeFormatter test = DateTimeFormatter.ISO_DATE;
+        TemporalAccessor result = test.parse("2012-06-30");
+        assertEquals(result.isSupported(YEAR), true);
+        assertEquals(result.isSupported(MONTH_OF_YEAR), true);
+        assertEquals(result.isSupported(DAY_OF_MONTH), true);
+        assertEquals(result.isSupported(HOUR_OF_DAY), false);
+        assertEquals(result.getLong(YEAR), 2012L);
+        assertEquals(result.getLong(MONTH_OF_YEAR), 6L);
+        assertEquals(result.getLong(DAY_OF_MONTH), 30L);
+        assertEquals(result.query(LocalDate::from), LocalDate.of(2012, 6, 30));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_parse_CharSequence_null() {
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        test.parse((String) null);
+    }
+
+    //-----------------------------------------------------------------------
+    // parse(CharSequence)
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_parse_CharSequence_ParsePosition() {
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        ParsePosition pos = new ParsePosition(3);
+        TemporalAccessor result = test.parse("XXXONE30XXX", pos);
+        assertEquals(pos.getIndex(), 8);
+        assertEquals(pos.getErrorIndex(), -1);
+        assertEquals(result.isSupported(DAY_OF_MONTH), true);
+        assertEquals(result.getLong(DAY_OF_MONTH), 30L);
+        assertEquals(result.isSupported(HOUR_OF_DAY), false);
+    }
+
+    @Test
+    public void test_parse_CharSequence_ParsePosition_resolved() {
+        DateTimeFormatter test = DateTimeFormatter.ISO_DATE;
+        ParsePosition pos = new ParsePosition(3);
+        TemporalAccessor result = test.parse("XXX2012-06-30XXX", pos);
+        assertEquals(pos.getIndex(), 13);
+        assertEquals(pos.getErrorIndex(), -1);
+        assertEquals(result.isSupported(YEAR), true);
+        assertEquals(result.isSupported(MONTH_OF_YEAR), true);
+        assertEquals(result.isSupported(DAY_OF_MONTH), true);
+        assertEquals(result.isSupported(HOUR_OF_DAY), false);
+        assertEquals(result.getLong(YEAR), 2012L);
+        assertEquals(result.getLong(MONTH_OF_YEAR), 6L);
+        assertEquals(result.getLong(DAY_OF_MONTH), 30L);
+        assertEquals(result.query(LocalDate::from), LocalDate.of(2012, 6, 30));
+    }
+
+    @Test(expectedExceptions=DateTimeParseException.class)
+    public void test_parse_CharSequence_ParsePosition_parseError() {
+        DateTimeFormatter test = DateTimeFormatter.ISO_DATE;
+        ParsePosition pos = new ParsePosition(3);
         try {
-            test.printTo(LocalDate.of(2008, 6, 30), new MockIOExceptionAppendable());
-        } catch (DateTimePrintException ex) {
-            assertEquals(ex.getCause() instanceof IOException, true);
-            ex.rethrowIOException();
+            test.parse("XXX2012XXX", pos);
+            fail();
+        } catch (DateTimeParseException ex) {
+            assertEquals(ex.getErrorIndex(), 7);
+            throw ex;
         }
     }
 
+    @Test(expectedExceptions=IndexOutOfBoundsException.class)
+    public void test_parse_CharSequence_ParsePosition_indexTooBig() {
+        DateTimeFormatter test = DateTimeFormatter.ISO_DATE;
+        test.parse("Text", new ParsePosition(5));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_parse_CharSequence_ParsePosition_nullText() {
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        test.parse((CharSequence) null, new ParsePosition(0));
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_parse_CharSequence_ParsePosition_nullParsePosition() {
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        test.parse("Text", (ParsePosition) null);
+    }
+
     //-----------------------------------------------------------------------
     // parse(Query)
     //-----------------------------------------------------------------------
@@ -363,23 +437,24 @@
     //-----------------------------------------------------------------------
     @Test
     public void test_parseBest_firstOption() throws Exception {
-        DateTimeFormatter test = DateTimeFormatters.pattern("yyyy-MM-dd[ZZZ]");
-        TemporalAccessor result = test.parseBest("2011-06-30+03:00", OffsetDate::from, LocalDate::from);
-        assertEquals(result, OffsetDate.of(LocalDate.of(2011, 6, 30), ZoneOffset.ofHours(3)));
+        DateTimeFormatter test = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm[XXX]");
+        TemporalAccessor result = test.parseBest("2011-06-30 12:30+03:00", ZonedDateTime::from, LocalDateTime::from);
+        LocalDateTime ldt = LocalDateTime.of(2011, 6, 30, 12, 30);
+        assertEquals(result, ZonedDateTime.of(ldt, ZoneOffset.ofHours(3)));
     }
 
     @Test
     public void test_parseBest_secondOption() throws Exception {
-        DateTimeFormatter test = DateTimeFormatters.pattern("yyyy-MM-dd[ZZZ]");
-        TemporalAccessor result = test.parseBest("2011-06-30", OffsetDate::from, LocalDate::from);
+        DateTimeFormatter test = DateTimeFormatter.ofPattern("yyyy-MM-dd[ HH:mm[XXX]]");
+        TemporalAccessor result = test.parseBest("2011-06-30", ZonedDateTime::from, LocalDate::from);
         assertEquals(result, LocalDate.of(2011, 6, 30));
     }
 
     @Test(expectedExceptions=DateTimeParseException.class)
     public void test_parseBest_String_parseError() throws Exception {
-        DateTimeFormatter test = DateTimeFormatters.pattern("yyyy-MM-dd[ZZZ]");
+        DateTimeFormatter test = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm[XXX]");
         try {
-            test.parseBest("2011-06-XX", OffsetDate::from, LocalDate::from);
+            test.parseBest("2011-06-XX", ZonedDateTime::from, LocalDateTime::from);
         } catch (DateTimeParseException ex) {
             assertEquals(ex.getMessage().contains("could not be parsed"), true);
             assertEquals(ex.getMessage().contains("XX"), true);
@@ -393,7 +468,7 @@
     public void test_parseBest_String_parseErrorLongText() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         try {
-            test.parseBest("ONEXXX67890123456789012345678901234567890123456789012345678901234567890123456789", LocalDate::from, OffsetDate::from);
+            test.parseBest("ONEXXX67890123456789012345678901234567890123456789012345678901234567890123456789", ZonedDateTime::from, LocalDate::from);
         } catch (DateTimeParseException ex) {
             assertEquals(ex.getMessage().contains("could not be parsed"), true);
             assertEquals(ex.getMessage().contains("ONEXXX6789012345678901234567890123456789012345678901234567890123..."), true);
@@ -407,7 +482,7 @@
     public void test_parseBest_String_parseIncomplete() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         try {
-            test.parseBest("ONE30SomethingElse", LocalDate::from, OffsetDate::from);
+            test.parseBest("ONE30SomethingElse", ZonedDateTime::from, LocalDate::from);
         } catch (DateTimeParseException ex) {
             assertEquals(ex.getMessage().contains("could not be parsed"), true);
             assertEquals(ex.getMessage().contains("ONE30SomethingElse"), true);
@@ -420,7 +495,7 @@
     @Test(expectedExceptions=NullPointerException.class)
     public void test_parseBest_String_nullText() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        test.parseBest((String) null, LocalDate::from, OffsetDate::from);
+        test.parseBest((String) null, ZonedDateTime::from, LocalDate::from);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
@@ -443,108 +518,65 @@
 
     //-----------------------------------------------------------------------
     @Test
-    public void test_parseToBuilder_String() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        DateTimeBuilder result = test.parseToBuilder("ONE30");
-        assertEquals(result.getFieldValueMap().size(), 1);
-        assertEquals(result.getFieldValue(DAY_OF_MONTH), 30L);
-        assertEquals(result.getCalendricalList().size(), 0);
-    }
-
-    @Test
-    public void test_parseToBuilder_CharSequence() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        DateTimeBuilder result = test.parseToBuilder(new StringBuilder("ONE30"));
-        assertEquals(result.getFieldValueMap().size(), 1);
-        assertEquals(result.getFieldValue(DAY_OF_MONTH), 30L);
-        assertEquals(result.getCalendricalList().size(), 0);
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class)
-    public void test_parseToBuilder_String_parseError() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        try {
-            test.parseToBuilder("ONEXXX");
-        } catch (DateTimeParseException ex) {
-            assertEquals(ex.getMessage().contains("ONEXXX"), true);
-            assertEquals(ex.getParsedString(), "ONEXXX");
-            assertEquals(ex.getErrorIndex(), 3);
-            throw ex;
-        }
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class)
-    public void test_parseToBuilder_String_parseErrorLongText() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        try {
-            test.parseToBuilder("ONEXXX67890123456789012345678901234567890123456789012345678901234567890123456789");
-        } catch (DateTimeParseException ex) {
-            assertEquals(ex.getMessage().contains("ONEXXX6789012345678901234567890123456789012345678901234567890123..."), true);
-            assertEquals(ex.getParsedString(), "ONEXXX67890123456789012345678901234567890123456789012345678901234567890123456789");
-            assertEquals(ex.getErrorIndex(), 3);
-            throw ex;
-        }
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class)
-    public void test_parseToBuilder_String_parseIncomplete() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        try {
-            test.parseToBuilder("ONE30SomethingElse");
-        } catch (DateTimeParseException ex) {
-            assertEquals(ex.getMessage().contains("ONE30SomethingElse"), true);
-            assertEquals(ex.getParsedString(), "ONE30SomethingElse");
-            assertEquals(ex.getErrorIndex(), 5);
-            throw ex;
-        }
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_parseToBuilder_String_null() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        test.parseToBuilder((String) null);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_parseToBuilder_StringParsePosition() throws Exception {
+    public void test_parseUnresolved_StringParsePosition() {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder result = test.parseToBuilder("ONE30XXX", pos);
+        TemporalAccessor result = test.parseUnresolved("ONE30XXX", pos);
         assertEquals(pos.getIndex(), 5);
         assertEquals(pos.getErrorIndex(), -1);
-        assertEquals(result.getFieldValueMap().size(), 1);
-        assertEquals(result.getFieldValueMap().get(DAY_OF_MONTH), Long.valueOf(30));
+        assertEquals(result.getLong(DAY_OF_MONTH), 30L);
     }
 
     @Test
-    public void test_parseToBuilder_StringParsePosition_parseError() throws Exception {
+    public void test_parseUnresolved_StringParsePosition_parseError() {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder result = test.parseToBuilder("ONEXXX", pos);
-        assertEquals(pos.getIndex(), 0);  // TODO: is this right?
+        TemporalAccessor result = test.parseUnresolved("ONEXXX", pos);
+        assertEquals(pos.getIndex(), 0);
         assertEquals(pos.getErrorIndex(), 3);
         assertEquals(result, null);
     }
 
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_parseToBuilder_StringParsePosition_nullString() throws Exception {
-        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        ParsePosition pos = new ParsePosition(0);
-        test.parseToBuilder((String) null, pos);
+    @Test
+    public void test_parseUnresolved_StringParsePosition_duplicateFieldSameValue() {
+        DateTimeFormatter test = new DateTimeFormatterBuilder()
+                .appendValue(MONTH_OF_YEAR).appendLiteral('-').appendValue(MONTH_OF_YEAR).toFormatter();
+        ParsePosition pos = new ParsePosition(3);
+        TemporalAccessor result = test.parseUnresolved("XXX6-6", pos);
+        assertEquals(pos.getIndex(), 6);
+        assertEquals(pos.getErrorIndex(), -1);
+        assertEquals(result.getLong(MONTH_OF_YEAR), 6);
+    }
+
+    @Test
+    public void test_parseUnresolved_StringParsePosition_duplicateFieldDifferentValue() {
+        DateTimeFormatter test = new DateTimeFormatterBuilder()
+                .appendValue(MONTH_OF_YEAR).appendLiteral('-').appendValue(MONTH_OF_YEAR).toFormatter();
+        ParsePosition pos = new ParsePosition(3);
+        TemporalAccessor result = test.parseUnresolved("XXX6-7", pos);
+        assertEquals(pos.getIndex(), 3);
+        assertEquals(pos.getErrorIndex(), 5);
+        assertEquals(result, null);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
-    public void test_parseToBuilder_StringParsePosition_nullParsePosition() throws Exception {
+    public void test_parseUnresolved_StringParsePosition_nullString() {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
-        test.parseToBuilder("ONE30", (ParsePosition) null);
+        ParsePosition pos = new ParsePosition(0);
+        test.parseUnresolved((String) null, pos);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_parseUnresolved_StringParsePosition_nullParsePosition() {
+        DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
+        test.parseUnresolved("ONE30", (ParsePosition) null);
     }
 
     @Test(expectedExceptions=IndexOutOfBoundsException.class)
-    public void test_parseToBuilder_StringParsePosition_invalidPosition() throws Exception {
+    public void test_parseUnresolved_StringParsePosition_invalidPosition() {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         ParsePosition pos = new ParsePosition(6);
-        test.parseToBuilder("ONE30", pos);
+        test.parseUnresolved("ONE30", pos);
     }
 
     //-----------------------------------------------------------------------
@@ -576,9 +608,9 @@
     public void test_toFormat_parseObject_String() throws Exception {
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         Format format = test.toFormat();
-        DateTimeBuilder result = (DateTimeBuilder) format.parseObject("ONE30");
-        assertEquals(result.getFieldValueMap().size(), 1);
-        assertEquals(result.getFieldValue(DAY_OF_MONTH), 30L);
+        TemporalAccessor result = (TemporalAccessor) format.parseObject("ONE30");
+        assertEquals(result.isSupported(DAY_OF_MONTH), true);
+        assertEquals(result.getLong(DAY_OF_MONTH), 30L);
     }
 
     @Test(expectedExceptions=ParseException.class)
@@ -621,11 +653,11 @@
         DateTimeFormatter test = fmt.withLocale(Locale.ENGLISH).withSymbols(DateTimeFormatSymbols.STANDARD);
         Format format = test.toFormat();
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder result = (DateTimeBuilder) format.parseObject("ONE30XXX", pos);
+        TemporalAccessor result = (TemporalAccessor) format.parseObject("ONE30XXX", pos);
         assertEquals(pos.getIndex(), 5);
         assertEquals(pos.getErrorIndex(), -1);
-        assertEquals(result.getFieldValueMap().size(), 1);
-        assertEquals(result.getFieldValue(DAY_OF_MONTH), 30L);
+        assertEquals(result.isSupported(DAY_OF_MONTH), true);
+        assertEquals(result.getLong(DAY_OF_MONTH), 30L);
     }
 
     @Test
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java
index 1fe79b1..0cb5cb1 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java
@@ -59,25 +59,24 @@
  */
 package tck.java.time.format;
 
-import java.time.LocalDate;
-import java.time.ZoneOffset;
-import java.time.format.*;
-
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
 
-import java.text.ParsePosition;
+import java.time.LocalDate;
+import java.time.YearMonth;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.SignStyle;
+import java.time.format.TextStyle;
+import java.time.temporal.Temporal;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.Temporal;
-
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -90,238 +89,116 @@
 
     private DateTimeFormatterBuilder builder;
 
-    @BeforeMethod(groups={"tck"})
+    @BeforeMethod
     public void setUp() {
         builder = new DateTimeFormatterBuilder();
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_toFormatter_empty() throws Exception {
         DateTimeFormatter f = builder.toFormatter();
         assertEquals(f.toString(), "");
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_parseCaseSensitive() throws Exception {
-        builder.parseCaseSensitive();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "ParseCaseSensitive(true)");
-    }
-
-    @Test(groups={"tck"})
-    public void test_parseCaseInsensitive() throws Exception {
-        builder.parseCaseInsensitive();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "ParseCaseSensitive(false)");
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_parseStrict() throws Exception {
-        builder.parseStrict();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "ParseStrict(true)");
-    }
-
-    @Test(groups={"tck"})
-    public void test_parseLenient() throws Exception {
-        builder.parseLenient();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "ParseStrict(false)");
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendValue_1arg() throws Exception {
-        builder.appendValue(DAY_OF_MONTH);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(DayOfMonth)");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendValue_1arg_null() throws Exception {
         builder.appendValue(null);
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendValue_2arg() throws Exception {
-        builder.appendValue(DAY_OF_MONTH, 3);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(DayOfMonth,3)");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendValue_2arg_null() throws Exception {
         builder.appendValue(null, 3);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendValue_2arg_widthTooSmall() throws Exception {
         builder.appendValue(DAY_OF_MONTH, 0);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendValue_2arg_widthTooBig() throws Exception {
         builder.appendValue(DAY_OF_MONTH, 20);
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendValue_3arg() throws Exception {
-        builder.appendValue(DAY_OF_MONTH, 2, 3, SignStyle.NORMAL);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(DayOfMonth,2,3,NORMAL)");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendValue_3arg_nullField() throws Exception {
         builder.appendValue(null, 2, 3, SignStyle.NORMAL);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendValue_3arg_minWidthTooSmall() throws Exception {
         builder.appendValue(DAY_OF_MONTH, 0, 2, SignStyle.NORMAL);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendValue_3arg_minWidthTooBig() throws Exception {
         builder.appendValue(DAY_OF_MONTH, 20, 2, SignStyle.NORMAL);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendValue_3arg_maxWidthTooSmall() throws Exception {
         builder.appendValue(DAY_OF_MONTH, 2, 0, SignStyle.NORMAL);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendValue_3arg_maxWidthTooBig() throws Exception {
         builder.appendValue(DAY_OF_MONTH, 2, 20, SignStyle.NORMAL);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendValue_3arg_maxWidthMinWidth() throws Exception {
         builder.appendValue(DAY_OF_MONTH, 4, 2, SignStyle.NORMAL);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendValue_3arg_nullSignStyle() throws Exception {
         builder.appendValue(DAY_OF_MONTH, 2, 3, null);
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendValue_subsequent2_parse3() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValue(DAY_OF_MONTH, 2);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)Value(DayOfMonth,2)");
-        DateTimeBuilder cal = f.parseToBuilder("123", new ParsePosition(0));
-        assertEquals(cal.getFieldValueMap().get(MONTH_OF_YEAR), Long.valueOf(1));
-        assertEquals(cal.getFieldValueMap().get(DAY_OF_MONTH), Long.valueOf(23));
-    }
-
-    @Test(groups={"tck"})
-    public void test_appendValue_subsequent2_parse4() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValue(DAY_OF_MONTH, 2);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)Value(DayOfMonth,2)");
-        DateTimeBuilder cal = f.parseToBuilder("0123", new ParsePosition(0));
-        assertEquals(cal.getFieldValueMap().get(MONTH_OF_YEAR), Long.valueOf(1));
-        assertEquals(cal.getFieldValueMap().get(DAY_OF_MONTH), Long.valueOf(23));
-    }
-
-    @Test(groups={"tck"})
-    public void test_appendValue_subsequent2_parse5() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValue(DAY_OF_MONTH, 2).appendLiteral('4');
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)Value(DayOfMonth,2)'4'");
-        DateTimeBuilder cal = f.parseToBuilder("01234", new ParsePosition(0));
-        assertEquals(cal.getFieldValueMap().get(MONTH_OF_YEAR), Long.valueOf(1));
-        assertEquals(cal.getFieldValueMap().get(DAY_OF_MONTH), Long.valueOf(23));
-    }
-
-    @Test(groups={"tck"})
-    public void test_appendValue_subsequent3_parse6() throws Exception {
-        builder
-            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
-            .appendValue(MONTH_OF_YEAR, 2)
-            .appendValue(DAY_OF_MONTH, 2);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(Year,4,10,EXCEEDS_PAD)Value(MonthOfYear,2)Value(DayOfMonth,2)");
-        DateTimeBuilder cal = f.parseToBuilder("20090630", new ParsePosition(0));
-        assertEquals(cal.getFieldValueMap().get(YEAR), Long.valueOf(2009));
-        assertEquals(cal.getFieldValueMap().get(MONTH_OF_YEAR), Long.valueOf(6));
-        assertEquals(cal.getFieldValueMap().get(DAY_OF_MONTH), Long.valueOf(30));
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendValueReduced_null() throws Exception {
         builder.appendValueReduced(null, 2, 2000);
     }
 
-    @Test(groups={"tck"})
-    public void test_appendValueReduced() throws Exception {
-        builder.appendValueReduced(YEAR, 2, 2000);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "ReducedValue(Year,2,2000)");
-        DateTimeBuilder cal = f.parseToBuilder("12", new ParsePosition(0));
-        assertEquals(cal.getFieldValueMap().get(YEAR), Long.valueOf(2012));
-    }
-
-    @Test(groups={"tck"})
-    public void test_appendValueReduced_subsequent_parse() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValueReduced(YEAR, 2, 2000);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)ReducedValue(Year,2,2000)");
-        DateTimeBuilder cal = f.parseToBuilder("123", new ParsePosition(0));
-        assertEquals(cal.getFieldValueMap().get(MONTH_OF_YEAR), Long.valueOf(1));
-        assertEquals(cal.getFieldValueMap().get(YEAR), Long.valueOf(2023));
-    }
-
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendFraction_4arg() throws Exception {
-        builder.appendFraction(MINUTE_OF_HOUR, 1, 9, false);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Fraction(MinuteOfHour,1,9)");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendFraction_4arg_nullRule() throws Exception {
         builder.appendFraction(null, 1, 9, false);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendFraction_4arg_invalidRuleNotFixedSet() throws Exception {
         builder.appendFraction(DAY_OF_MONTH, 1, 9, false);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendFraction_4arg_minTooSmall() throws Exception {
         builder.appendFraction(MINUTE_OF_HOUR, -1, 9, false);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendFraction_4arg_minTooBig() throws Exception {
         builder.appendFraction(MINUTE_OF_HOUR, 10, 9, false);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendFraction_4arg_maxTooSmall() throws Exception {
         builder.appendFraction(MINUTE_OF_HOUR, 0, -1, false);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendFraction_4arg_maxTooBig() throws Exception {
         builder.appendFraction(MINUTE_OF_HOUR, 1, 10, false);
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_appendFraction_4arg_maxWidthMinWidth() throws Exception {
         builder.appendFraction(MINUTE_OF_HOUR, 9, 3, false);
     }
@@ -329,63 +206,29 @@
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendText_1arg() throws Exception {
-        builder.appendText(MONTH_OF_YEAR);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Text(MonthOfYear)");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendText_1arg_null() throws Exception {
         builder.appendText(null);
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendText_2arg() throws Exception {
-        builder.appendText(MONTH_OF_YEAR, TextStyle.SHORT);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Text(MonthOfYear,SHORT)");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendText_2arg_nullRule() throws Exception {
         builder.appendText(null, TextStyle.SHORT);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendText_2arg_nullStyle() throws Exception {
         builder.appendText(MONTH_OF_YEAR, (TextStyle) null);
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendTextMap() throws Exception {
-        Map<Long, String> map = new HashMap<Long, String>();
-        map.put(1L, "JNY");
-        map.put(2L, "FBY");
-        map.put(3L, "MCH");
-        map.put(4L, "APL");
-        map.put(5L, "MAY");
-        map.put(6L, "JUN");
-        map.put(7L, "JLY");
-        map.put(8L, "AGT");
-        map.put(9L, "SPT");
-        map.put(10L, "OBR");
-        map.put(11L, "NVR");
-        map.put(12L, "DBR");
-        builder.appendText(MONTH_OF_YEAR, map);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Text(MonthOfYear)");  // TODO: toString should be different?
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendTextMap_nullRule() throws Exception {
-        builder.appendText(null, new HashMap<Long, String>());
+        builder.appendText(null, new HashMap<>());
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendTextMap_nullStyle() throws Exception {
         builder.appendText(MONTH_OF_YEAR, (Map<Long, String>) null);
     }
@@ -393,13 +236,6 @@
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendOffsetId() throws Exception {
-        builder.appendOffsetId();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Offset('Z',+HH:MM:ss)");
-    }
-
     @DataProvider(name="offsetPatterns")
     Object[][] data_offsetPatterns() {
         return new Object[][] {
@@ -447,21 +283,20 @@
         };
     }
 
-    @Test(dataProvider="offsetPatterns", groups={"tck"})
-    public void test_appendOffset_print(String pattern, int h, int m, int s, String expected) throws Exception {
+    @Test(dataProvider="offsetPatterns")
+    public void test_appendOffset_format(String pattern, int h, int m, int s, String expected) throws Exception {
         builder.appendOffset(pattern, "Z");
         DateTimeFormatter f = builder.toFormatter();
         ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(h, m, s);
-        assertEquals(f.print(offset), expected);
+        assertEquals(f.format(offset), expected);
     }
 
-    @Test(dataProvider="offsetPatterns", groups={"tck"})
+    @Test(dataProvider="offsetPatterns")
     public void test_appendOffset_parse(String pattern, int h, int m, int s, String expected) throws Exception {
         builder.appendOffset(pattern, "Z");
         DateTimeFormatter f = builder.toFormatter();
-        ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(h, m, s);
         ZoneOffset parsed = f.parse(expected, ZoneOffset::from);
-        assertEquals(f.print(parsed), expected);
+        assertEquals(f.format(parsed), expected);
     }
 
     @DataProvider(name="badOffsetPatterns")
@@ -481,17 +316,17 @@
         };
     }
 
-    @Test(dataProvider="badOffsetPatterns", expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(dataProvider="badOffsetPatterns", expectedExceptions=IllegalArgumentException.class)
     public void test_appendOffset_badPattern(String pattern) throws Exception {
         builder.appendOffset(pattern, "Z");
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendOffset_3arg_nullText() throws Exception {
         builder.appendOffset("+HH:MM", null);
     }
 
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendOffset_3arg_nullPattern() throws Exception {
         builder.appendOffset(null, "Z");
     }
@@ -499,21 +334,7 @@
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_appendZoneId() throws Exception {
-        builder.appendZoneId();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "ZoneId()");
-    }
-
-    @Test(groups={"tck"})
-    public void test_appendZoneText_1arg() throws Exception {
-        builder.appendZoneText(TextStyle.FULL);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "ZoneText(FULL)");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_appendZoneText_1arg_nullText() throws Exception {
         builder.appendZoneText(null);
     }
@@ -521,101 +342,43 @@
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_padNext_1arg() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).padNext(2).appendValue(DAY_OF_MONTH).appendValue(DAY_OF_WEEK);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)Pad(Value(DayOfMonth),2)Value(DayOfWeek)");
+    @Test
+    public void test_padNext_1arg() {
+        builder.appendValue(MONTH_OF_YEAR).appendLiteral(':').padNext(2).appendValue(DAY_OF_MONTH);
+        assertEquals(builder.toFormatter().format(LocalDate.of(2013, 2, 1)), "2: 1");
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_padNext_1arg_invalidWidth() throws Exception {
         builder.padNext(0);
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_padNext_2arg_dash() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).padNext(2, '-').appendValue(DAY_OF_MONTH).appendValue(DAY_OF_WEEK);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)Pad(Value(DayOfMonth),2,'-')Value(DayOfWeek)");
+        builder.appendValue(MONTH_OF_YEAR).appendLiteral(':').padNext(2, '-').appendValue(DAY_OF_MONTH);
+        assertEquals(builder.toFormatter().format(LocalDate.of(2013, 2, 1)), "2:-1");
     }
 
-    @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalArgumentException.class)
     public void test_padNext_2arg_invalidWidth() throws Exception {
         builder.padNext(0, '-');
     }
 
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_padOptional() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).padNext(5).optionalStart().appendValue(DAY_OF_MONTH).optionalEnd().appendValue(DAY_OF_WEEK);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)Pad([Value(DayOfMonth)],5)Value(DayOfWeek)");
+        builder.appendValue(MONTH_OF_YEAR).appendLiteral(':')
+                .padNext(5).optionalStart().appendValue(DAY_OF_MONTH).optionalEnd()
+                .appendLiteral(':').appendValue(YEAR);
+        assertEquals(builder.toFormatter().format(LocalDate.of(2013, 2, 1)), "2:    1:2013");
+        assertEquals(builder.toFormatter().format(YearMonth.of(2013, 2)), "2:     :2013");
     }
 
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_optionalStart_noEnd() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).optionalStart().appendValue(DAY_OF_MONTH).appendValue(DAY_OF_WEEK);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)[Value(DayOfMonth)Value(DayOfWeek)]");
-    }
-
-    @Test(groups={"tck"})
-    public void test_optionalStart2_noEnd() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).optionalStart().appendValue(DAY_OF_MONTH).optionalStart().appendValue(DAY_OF_WEEK);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)[Value(DayOfMonth)[Value(DayOfWeek)]]");
-    }
-
-    @Test(groups={"tck"})
-    public void test_optionalStart_doubleStart() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).optionalStart().optionalStart().appendValue(DAY_OF_MONTH);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)[[Value(DayOfMonth)]]");
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_optionalEnd() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).optionalStart().appendValue(DAY_OF_MONTH).optionalEnd().appendValue(DAY_OF_WEEK);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)[Value(DayOfMonth)]Value(DayOfWeek)");
-    }
-
-    @Test(groups={"tck"})
-    public void test_optionalEnd2() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).optionalStart().appendValue(DAY_OF_MONTH)
-            .optionalStart().appendValue(DAY_OF_WEEK).optionalEnd().appendValue(DAY_OF_MONTH).optionalEnd();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)[Value(DayOfMonth)[Value(DayOfWeek)]Value(DayOfMonth)]");
-    }
-
-    @Test(groups={"tck"})
-    public void test_optionalEnd_doubleStartSingleEnd() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).optionalStart().optionalStart().appendValue(DAY_OF_MONTH).optionalEnd();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)[[Value(DayOfMonth)]]");
-    }
-
-    @Test(groups={"tck"})
-    public void test_optionalEnd_doubleStartDoubleEnd() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).optionalStart().optionalStart().appendValue(DAY_OF_MONTH).optionalEnd().optionalEnd();
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)[[Value(DayOfMonth)]]");
-    }
-
-    @Test(groups={"tck"})
-    public void test_optionalStartEnd_immediateStartEnd() throws Exception {
-        builder.appendValue(MONTH_OF_YEAR).optionalStart().optionalEnd().appendValue(DAY_OF_MONTH);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), "Value(MonthOfYear)Value(DayOfMonth)");
-    }
-
-    @Test(expectedExceptions=IllegalStateException.class, groups={"tck"})
+    @Test(expectedExceptions=IllegalStateException.class)
     public void test_optionalEnd_noStart() throws Exception {
         builder.optionalEnd();
     }
@@ -626,157 +389,149 @@
     @DataProvider(name="validPatterns")
     Object[][] dataValid() {
         return new Object[][] {
-            {"'a'", "'a'"},
-            {"''", "''"},
-            {"'!'", "'!'"},
-            {"!", "'!'"},
+            {"'a'"},
+            {"''"},
+            {"'!'"},
+            {"!"},
 
-            {"'hello_people,][)('", "'hello_people,][)('"},
-            {"'hi'", "'hi'"},
-            {"'yyyy'", "'yyyy'"},
-            {"''''", "''"},
-            {"'o''clock'", "'o''clock'"},
+            {"'hello_people,][)('"},
+            {"'hi'"},
+            {"'yyyy'"},
+            {"''''"},
+            {"'o''clock'"},
 
-            {"G", "Value(Era)"},
-            {"GG", "Value(Era,2)"},
-            {"GGG", "Text(Era,SHORT)"},
-            {"GGGG", "Text(Era)"},
-            {"GGGGG", "Text(Era,NARROW)"},
+            {"G"},
+            {"GG"},
+            {"GGG"},
+            {"GGGG"},
+            {"GGGGG"},
 
-            {"y", "Value(Year)"},
-            {"yy", "ReducedValue(Year,2,2000)"},
-            {"yyy", "Value(Year,3,19,NORMAL)"},
-            {"yyyy", "Value(Year,4,19,EXCEEDS_PAD)"},
-            {"yyyyy", "Value(Year,5,19,EXCEEDS_PAD)"},
+            {"y"},
+            {"yy"},
+            {"yyy"},
+            {"yyyy"},
+            {"yyyyy"},
 
-//            {"Y", "Value(WeekBasedYear)"},
-//            {"YY", "ReducedValue(WeekBasedYear,2,2000)"},
-//            {"YYY", "Value(WeekBasedYear,3,19,NORMAL)"},
-//            {"YYYY", "Value(WeekBasedYear,4,19,EXCEEDS_PAD)"},
-//            {"YYYYY", "Value(WeekBasedYear,5,19,EXCEEDS_PAD)"},
+            {"M"},
+            {"MM"},
+            {"MMM"},
+            {"MMMM"},
+            {"MMMMM"},
 
-            {"M", "Value(MonthOfYear)"},
-            {"MM", "Value(MonthOfYear,2)"},
-            {"MMM", "Text(MonthOfYear,SHORT)"},
-            {"MMMM", "Text(MonthOfYear)"},
-            {"MMMMM", "Text(MonthOfYear,NARROW)"},
+            {"D"},
+            {"DD"},
+            {"DDD"},
 
-            {"D", "Value(DayOfYear)"},
-            {"DD", "Value(DayOfYear,2)"},
-            {"DDD", "Value(DayOfYear,3)"},
+            {"d"},
+            {"dd"},
+            {"ddd"},
 
-            {"d", "Value(DayOfMonth)"},
-            {"dd", "Value(DayOfMonth,2)"},
-            {"ddd", "Value(DayOfMonth,3)"},
+            {"F"},
+            {"FF"},
+            {"FFF"},
 
-            {"F", "Value(AlignedWeekOfMonth)"},
-            {"FF", "Value(AlignedWeekOfMonth,2)"},
-            {"FFF", "Value(AlignedWeekOfMonth,3)"},
+            {"Q"},
+            {"QQ"},
+            {"QQQ"},
+            {"QQQQ"},
+            {"QQQQQ"},
 
-            {"Q", "Value(QuarterOfYear)"},
-            {"QQ", "Value(QuarterOfYear,2)"},
-            {"QQQ", "Text(QuarterOfYear,SHORT)"},
-            {"QQQQ", "Text(QuarterOfYear)"},
-            {"QQQQQ", "Text(QuarterOfYear,NARROW)"},
+            {"E"},
+            {"EE"},
+            {"EEE"},
+            {"EEEE"},
+            {"EEEEE"},
 
-            {"E", "Value(DayOfWeek)"},
-            {"EE", "Value(DayOfWeek,2)"},
-            {"EEE", "Text(DayOfWeek,SHORT)"},
-            {"EEEE", "Text(DayOfWeek)"},
-            {"EEEEE", "Text(DayOfWeek,NARROW)"},
+            {"a"},
+            {"aa"},
+            {"aaa"},
+            {"aaaa"},
+            {"aaaaa"},
 
-            {"a", "Text(AmPmOfDay,SHORT)"},
-            {"aa", "Text(AmPmOfDay,SHORT)"},
-            {"aaa", "Text(AmPmOfDay,SHORT)"},
-            {"aaaa", "Text(AmPmOfDay)"},
-            {"aaaaa", "Text(AmPmOfDay,NARROW)"},
+            {"H"},
+            {"HH"},
+            {"HHH"},
 
-            {"H", "Value(HourOfDay)"},
-            {"HH", "Value(HourOfDay,2)"},
-            {"HHH", "Value(HourOfDay,3)"},
+            {"K"},
+            {"KK"},
+            {"KKK"},
 
-            {"K", "Value(HourOfAmPm)"},
-            {"KK", "Value(HourOfAmPm,2)"},
-            {"KKK", "Value(HourOfAmPm,3)"},
+            {"k"},
+            {"kk"},
+            {"kkk"},
 
-            {"k", "Value(ClockHourOfDay)"},
-            {"kk", "Value(ClockHourOfDay,2)"},
-            {"kkk", "Value(ClockHourOfDay,3)"},
+            {"h"},
+            {"hh"},
+            {"hhh"},
 
-            {"h", "Value(ClockHourOfAmPm)"},
-            {"hh", "Value(ClockHourOfAmPm,2)"},
-            {"hhh", "Value(ClockHourOfAmPm,3)"},
+            {"m"},
+            {"mm"},
+            {"mmm"},
 
-            {"m", "Value(MinuteOfHour)"},
-            {"mm", "Value(MinuteOfHour,2)"},
-            {"mmm", "Value(MinuteOfHour,3)"},
+            {"s"},
+            {"ss"},
+            {"sss"},
 
-            {"s", "Value(SecondOfMinute)"},
-            {"ss", "Value(SecondOfMinute,2)"},
-            {"sss", "Value(SecondOfMinute,3)"},
+            {"S"},
+            {"SS"},
+            {"SSS"},
+            {"SSSSSSSSS"},
 
-            {"S", "Fraction(NanoOfSecond,1,1)"},
-            {"SS", "Fraction(NanoOfSecond,2,2)"},
-            {"SSS", "Fraction(NanoOfSecond,3,3)"},
-            {"SSSSSSSSS", "Fraction(NanoOfSecond,9,9)"},
+            {"A"},
+            {"AA"},
+            {"AAA"},
 
-            {"A", "Value(MilliOfDay)"},
-            {"AA", "Value(MilliOfDay,2)"},
-            {"AAA", "Value(MilliOfDay,3)"},
+            {"n"},
+            {"nn"},
+            {"nnn"},
 
-            {"n", "Value(NanoOfSecond)"},
-            {"nn", "Value(NanoOfSecond,2)"},
-            {"nnn", "Value(NanoOfSecond,3)"},
+            {"N"},
+            {"NN"},
+            {"NNN"},
 
-            {"N", "Value(NanoOfDay)"},
-            {"NN", "Value(NanoOfDay,2)"},
-            {"NNN", "Value(NanoOfDay,3)"},
+            {"z"},
+            {"zz"},
+            {"zzz"},
+            {"zzzz"},
 
-            {"z", "ZoneText(SHORT)"},
-            {"zz", "ZoneText(SHORT)"},
-            {"zzz", "ZoneText(SHORT)"},
-            {"zzzz", "ZoneText(FULL)"},
-            {"zzzzz", "ZoneText(FULL)"},
+            {"VV"},
 
-            {"I", "ZoneId()"},
-            {"II", "ZoneId()"},
-            {"III", "ZoneId()"},
-            {"IIII", "ZoneId()"},
-            {"IIIII", "ZoneId()"},
+            {"Z"},
+            {"ZZ"},
+            {"ZZZ"},
 
-            {"Z", "Offset('+0000',+HHMM)"},  // SimpleDateFormat compatible
-            {"ZZ", "Offset('+0000',+HHMM)"},
-            {"ZZZ", "Offset('+00:00',+HH:MM)"},
+            {"X"},
+            {"XX"},
+            {"XXX"},
+            {"XXXX"},
+            {"XXXXX"},
 
-            {"X", "Offset('Z',+HH)"},
-            {"XX", "Offset('Z',+HHMM)"},
-            {"XXX", "Offset('Z',+HH:MM)"},
-            {"XXXX", "Offset('Z',+HHMMss)"},
-            {"XXXXX", "Offset('Z',+HH:MM:ss)"},
+            {"x"},
+            {"xx"},
+            {"xxx"},
+            {"xxxx"},
+            {"xxxxx"},
 
-            {"ppH", "Pad(Value(HourOfDay),2)"},
-            {"pppDD", "Pad(Value(DayOfYear,2),3)"},
+            {"ppH"},
+            {"pppDD"},
 
-            {"yyyy[-MM[-dd", "Value(Year,4,19,EXCEEDS_PAD)['-'Value(MonthOfYear,2)['-'Value(DayOfMonth,2)]]"},
-            {"yyyy[-MM[-dd]]", "Value(Year,4,19,EXCEEDS_PAD)['-'Value(MonthOfYear,2)['-'Value(DayOfMonth,2)]]"},
-            {"yyyy[-MM[]-dd]", "Value(Year,4,19,EXCEEDS_PAD)['-'Value(MonthOfYear,2)'-'Value(DayOfMonth,2)]"},
+            {"yyyy[-MM[-dd"},
+            {"yyyy[-MM[-dd]]"},
+            {"yyyy[-MM[]-dd]"},
 
-            {"yyyy-MM-dd'T'HH:mm:ss.SSS", "Value(Year,4,19,EXCEEDS_PAD)'-'Value(MonthOfYear,2)'-'Value(DayOfMonth,2)" +
-                "'T'Value(HourOfDay,2)':'Value(MinuteOfHour,2)':'Value(SecondOfMinute,2)'.'Fraction(NanoOfSecond,3,3)"},
+            {"yyyy-MM-dd'T'HH:mm:ss.SSS"},
 
-            {"e", "WeekBased(e1)"},
-            {"w", "WeekBased(w1)"},
-            {"W", "WeekBased(W1)"},
-            {"WW", "WeekBased(W2)"},
+            {"e"},
+            {"w"},
+            {"W"},
+            {"WW"},
 
         };
     }
 
-    @Test(dataProvider="validPatterns", groups={"implementation"})
-    public void test_appendPattern_valid(String input, String expected) throws Exception {
-        builder.appendPattern(input);
-        DateTimeFormatter f = builder.toFormatter();
-        assertEquals(f.toString(), expected);
+    @Test(dataProvider="validPatterns")
+    public void test_appendPattern_valid(String input) throws Exception {
+        builder.appendPattern(input);  // test is for no error here
     }
 
     //-----------------------------------------------------------------------
@@ -801,6 +556,7 @@
             {"aaaaaa"},
             {"ZZZZ"},
             {"XXXXXX"},
+            {"zzzzz"},
 
             {"RO"},
 
@@ -821,13 +577,9 @@
         };
     }
 
-    @Test(dataProvider="invalidPatterns", expectedExceptions=IllegalArgumentException.class, groups={"tck"})
+    @Test(dataProvider="invalidPatterns", expectedExceptions=IllegalArgumentException.class)
     public void test_appendPattern_invalid(String input) throws Exception {
-        try {
-            builder.appendPattern(input);
-        } catch (IllegalArgumentException ex) {
-            throw ex;
-        }
+        builder.appendPattern(input);  // test is for error here
     }
 
     //-----------------------------------------------------------------------
@@ -842,10 +594,10 @@
         };
     }
 
-    @Test(dataProvider="patternPrint", groups={"tck"})
+    @Test(dataProvider="patternPrint")
     public void test_appendPattern_patternPrint(String input, Temporal temporal, String expected) throws Exception {
         DateTimeFormatter f = builder.appendPattern(input).toFormatter(Locale.UK);
-        String test = f.print(temporal);
+        String test = f.format(temporal);
         assertEquals(test, expected);
     }
 
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java
index cbb79b9..4554877 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java
@@ -74,37 +74,33 @@
 import static org.testng.Assert.fail;
 
 import java.text.ParsePosition;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.Year;
+import java.time.YearMonth;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
-import java.time.format.DateTimeBuilder;
+import java.time.chrono.Chronology;
 import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
 import java.time.format.DateTimeParseException;
-import java.time.format.DateTimePrintException;
-import java.time.temporal.ISOFields;
+import java.time.temporal.IsoFields;
 import java.time.temporal.Queries;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
-import java.time.temporal.Year;
-import java.time.temporal.YearMonth;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 /**
- * Test DateTimeFormatters.
+ * Test DateTimeFormatter.
  */
 @Test
 public class TCKDateTimeFormatters {
@@ -116,7 +112,7 @@
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_print_nullCalendrical() {
-        DateTimeFormatters.isoDate().print((TemporalAccessor) null);
+        DateTimeFormatter.ISO_DATE.format((TemporalAccessor) null);
     }
 
     //-----------------------------------------------------------------------
@@ -124,19 +120,19 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_pattern_String() {
-        DateTimeFormatter test = DateTimeFormatters.pattern("d MMM yyyy");
+        DateTimeFormatter test = DateTimeFormatter.ofPattern("d MMM yyyy");
         assertEquals(test.toString(), "Value(DayOfMonth)' 'Text(MonthOfYear,SHORT)' 'Value(Year,4,19,EXCEEDS_PAD)");
         assertEquals(test.getLocale(), Locale.getDefault());
     }
 
     @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
     public void test_pattern_String_invalid() {
-        DateTimeFormatters.pattern("p");
+        DateTimeFormatter.ofPattern("p");
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_pattern_String_null() {
-        DateTimeFormatters.pattern(null);
+        DateTimeFormatter.ofPattern(null);
     }
 
     //-----------------------------------------------------------------------
@@ -144,24 +140,24 @@
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_pattern_StringLocale() {
-        DateTimeFormatter test = DateTimeFormatters.pattern("d MMM yyyy", Locale.UK);
+        DateTimeFormatter test = DateTimeFormatter.ofPattern("d MMM yyyy", Locale.UK);
         assertEquals(test.toString(), "Value(DayOfMonth)' 'Text(MonthOfYear,SHORT)' 'Value(Year,4,19,EXCEEDS_PAD)");
         assertEquals(test.getLocale(), Locale.UK);
     }
 
     @Test(expectedExceptions=IllegalArgumentException.class, groups={"tck"})
     public void test_pattern_StringLocale_invalid() {
-        DateTimeFormatters.pattern("p", Locale.UK);
+        DateTimeFormatter.ofPattern("p", Locale.UK);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_pattern_StringLocale_nullPattern() {
-        DateTimeFormatters.pattern(null, Locale.UK);
+        DateTimeFormatter.ofPattern(null, Locale.UK);
     }
 
     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
     public void test_pattern_StringLocale_nullLocale() {
-        DateTimeFormatters.pattern("yyyy", null);
+        DateTimeFormatter.ofPattern("yyyy", null);
     }
 
     //-----------------------------------------------------------------------
@@ -193,10 +189,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(year, month, day, null, null, null, null, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoLocalDate().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoLocalDate().print(test);
+                DateTimeFormatter.ISO_LOCAL_DATE.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -209,23 +205,23 @@
             Integer year, Integer month, Integer day, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createDate(year, month, day);
+            Expected expected = createDate(year, month, day);
             // offset/zone not expected to be parsed
-            assertParseMatch(DateTimeFormatters.isoLocalDate().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
     @Test(groups={"tck"})
     public void test_parse_isoLocalDate_999999999() {
-        DateTimeBuilder expected = createDate(999999999, 8, 6);
-        assertParseMatch(DateTimeFormatters.isoLocalDate().parseToBuilder("+999999999-08-06", new ParsePosition(0)), expected);
+        Expected expected = createDate(999999999, 8, 6);
+        assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved("+999999999-08-06", new ParsePosition(0)), expected);
         assertEquals(LocalDate.parse("+999999999-08-06"), LocalDate.of(999999999, 8, 6));
     }
 
     @Test(groups={"tck"})
     public void test_parse_isoLocalDate_1000000000() {
-        DateTimeBuilder expected = createDate(1000000000, 8, 6);
-        assertParseMatch(DateTimeFormatters.isoLocalDate().parseToBuilder("+1000000000-08-06", new ParsePosition(0)), expected);
+        Expected expected = createDate(1000000000, 8, 6);
+        assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved("+1000000000-08-06", new ParsePosition(0)), expected);
     }
 
     @Test(expectedExceptions = DateTimeException.class, groups={"tck"})
@@ -235,15 +231,15 @@
 
     @Test(groups={"tck"})
     public void test_parse_isoLocalDate_M999999999() {
-        DateTimeBuilder expected = createDate(-999999999, 8, 6);
-        assertParseMatch(DateTimeFormatters.isoLocalDate().parseToBuilder("-999999999-08-06", new ParsePosition(0)), expected);
+        Expected expected = createDate(-999999999, 8, 6);
+        assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved("-999999999-08-06", new ParsePosition(0)), expected);
         assertEquals(LocalDate.parse("-999999999-08-06"), LocalDate.of(-999999999, 8, 6));
     }
 
     @Test(groups={"tck"})
     public void test_parse_isoLocalDate_M1000000000() {
-        DateTimeBuilder expected = createDate(-1000000000, 8, 6);
-        assertParseMatch(DateTimeFormatters.isoLocalDate().parseToBuilder("-1000000000-08-06", new ParsePosition(0)), expected);
+        Expected expected = createDate(-1000000000, 8, 6);
+        assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved("-1000000000-08-06", new ParsePosition(0)), expected);
     }
 
     @Test(expectedExceptions = DateTimeException.class, groups={"tck"})
@@ -280,10 +276,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(year, month, day, null, null, null, null, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoOffsetDate().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_OFFSET_DATE.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoOffsetDate().print(test);
+                DateTimeFormatter.ISO_OFFSET_DATE.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -296,9 +292,9 @@
             Integer year, Integer month, Integer day, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createDate(year, month, day);
+            Expected expected = createDate(year, month, day);
             buildCalendrical(expected, offsetId, null);  // zone not expected to be parsed
-            assertParseMatch(DateTimeFormatters.isoOffsetDate().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_OFFSET_DATE.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -331,10 +327,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(year, month, day, null, null, null, null, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoDate().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_DATE.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoDate().print(test);
+                DateTimeFormatter.ISO_DATE.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -347,11 +343,11 @@
             Integer year, Integer month, Integer day, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createDate(year, month, day);
+            Expected expected = createDate(year, month, day);
             if (offsetId != null) {
-                expected.addFieldValue(OFFSET_SECONDS, ZoneOffset.of(offsetId).getTotalSeconds());
+                expected.add(ZoneOffset.of(offsetId));
             }
-            assertParseMatch(DateTimeFormatters.isoDate().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_DATE.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -396,10 +392,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(null, null, null, hour, min, sec, nano, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoLocalTime().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_LOCAL_TIME.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoLocalTime().print(test);
+                DateTimeFormatter.ISO_LOCAL_TIME.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -412,9 +408,9 @@
             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createTime(hour, min, sec, nano);
+            Expected expected = createTime(hour, min, sec, nano);
             // offset/zone not expected to be parsed
-            assertParseMatch(DateTimeFormatters.isoLocalTime().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_LOCAL_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -459,10 +455,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(null, null, null, hour, min, sec, nano, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoOffsetTime().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_OFFSET_TIME.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoOffsetTime().print(test);
+                DateTimeFormatter.ISO_OFFSET_TIME.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -475,9 +471,9 @@
             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createTime(hour, min, sec, nano);
+            Expected expected = createTime(hour, min, sec, nano);
             buildCalendrical(expected, offsetId, null);  // zoneId is not expected from parse
-            assertParseMatch(DateTimeFormatters.isoOffsetTime().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_OFFSET_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -522,10 +518,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(null, null, null, hour, min, sec, nano, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoTime().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_TIME.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoTime().print(test);
+                DateTimeFormatter.ISO_TIME.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -538,11 +534,11 @@
             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createTime(hour, min, sec, nano);
+            Expected expected = createTime(hour, min, sec, nano);
             if (offsetId != null) {
-                expected.addFieldValue(OFFSET_SECONDS, ZoneOffset.of(offsetId).getTotalSeconds());
+                expected.add(ZoneOffset.of(offsetId));
             }
-            assertParseMatch(DateTimeFormatters.isoTime().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -596,10 +592,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(year, month, day, hour, min, sec, nano, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoLocalDateTime().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoLocalDateTime().print(test);
+                DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -613,8 +609,8 @@
             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createDateTime(year, month, day, hour, min, sec, nano);
-            assertParseMatch(DateTimeFormatters.isoLocalDateTime().parseToBuilder(input, new ParsePosition(0)), expected);
+            Expected expected = createDateTime(year, month, day, hour, min, sec, nano);
+            assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -668,10 +664,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(year, month, day, hour, min, sec, nano, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoOffsetDateTime().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoOffsetDateTime().print(test);
+                DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -685,9 +681,9 @@
             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createDateTime(year, month, day, hour, min, sec, nano);
+            Expected expected = createDateTime(year, month, day, hour, min, sec, nano);
             buildCalendrical(expected, offsetId, null);  // zone not expected to be parsed
-            assertParseMatch(DateTimeFormatters.isoOffsetDateTime().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_OFFSET_DATE_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -750,10 +746,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(year, month, day, hour, min, sec, nano, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoZonedDateTime().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoZonedDateTime().print(test);
+                DateTimeFormatter.ISO_ZONED_DATE_TIME.format(test);
                 fail(test.toString());
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -767,13 +763,13 @@
             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createDateTime(year, month, day, hour, min, sec, nano);
+            Expected expected = createDateTime(year, month, day, hour, min, sec, nano);
             if (offsetId.equals(zoneId)) {
                 buildCalendrical(expected, offsetId, null);
             } else {
                 buildCalendrical(expected, offsetId, zoneId);
             }
-            assertParseMatch(DateTimeFormatters.isoZonedDateTime().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_ZONED_DATE_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -827,10 +823,10 @@
             String expected, Class<?> expectedEx) {
         TemporalAccessor test = buildAccessor(year, month, day, hour, min, sec, nano, offsetId, zoneId);
         if (expectedEx == null) {
-            assertEquals(DateTimeFormatters.isoDateTime().print(test), expected);
+            assertEquals(DateTimeFormatter.ISO_DATE_TIME.format(test), expected);
         } else {
             try {
-                DateTimeFormatters.isoDateTime().print(test);
+                DateTimeFormatter.ISO_DATE_TIME.format(test);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -844,14 +840,14 @@
             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
             String input, Class<?> invalid) {
         if (input != null) {
-            DateTimeBuilder expected = createDateTime(year, month, day, hour, min, sec, nano);
+            Expected expected = createDateTime(year, month, day, hour, min, sec, nano);
             if (offsetId != null) {
-                expected.addFieldValue(OFFSET_SECONDS, ZoneOffset.of(offsetId).getTotalSeconds());
+                expected.add(ZoneOffset.of(offsetId));
                 if (zoneId != null) {
-                    expected.addCalendrical(ZoneId.of(zoneId));
+                    expected.zone = ZoneId.of(zoneId);
                 }
             }
-            assertParseMatch(DateTimeFormatters.isoDateTime().parseToBuilder(input, new ParsePosition(0)), expected);
+            assertParseMatch(DateTimeFormatter.ISO_DATE_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
         }
     }
 
@@ -861,50 +857,66 @@
     @Test(groups={"tck"})
     public void test_print_isoOrdinalDate() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), null, null);
-        assertEquals(DateTimeFormatters.isoOrdinalDate().print(test), "2008-155");
+        assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "2008-155");
     }
 
     @Test(groups={"tck"})
     public void test_print_isoOrdinalDate_offset() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), "Z", null);
-        assertEquals(DateTimeFormatters.isoOrdinalDate().print(test), "2008-155Z");
+        assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "2008-155Z");
     }
 
     @Test(groups={"tck"})
     public void test_print_isoOrdinalDate_zoned() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), "+02:00", "Europe/Paris");
-        assertEquals(DateTimeFormatters.isoOrdinalDate().print(test), "2008-155+02:00");
+        assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "2008-155+02:00");
     }
 
     @Test(groups={"tck"})
     public void test_print_isoOrdinalDate_zoned_largeYear() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(123456, 6, 3, 11, 5, 30), "Z", null);
-        assertEquals(DateTimeFormatters.isoOrdinalDate().print(test), "+123456-155Z");
+        assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "+123456-155Z");
     }
 
-    @Test(groups={"tck"})
+    @Test
     public void test_print_isoOrdinalDate_fields() {
-        TemporalAccessor test = new DateTimeBuilder(YEAR, 2008).addFieldValue(DAY_OF_YEAR, 231);
-        assertEquals(DateTimeFormatters.isoOrdinalDate().print(test), "2008-231");
+        // mock for testing that does not fully comply with TemporalAccessor contract
+        TemporalAccessor test = new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                return field == YEAR || field == DAY_OF_YEAR;
+            }
+            @Override
+            public long getLong(TemporalField field) {
+                if (field == YEAR) {
+                    return 2008;
+                }
+                if (field == DAY_OF_YEAR) {
+                    return 231;
+                }
+                throw new DateTimeException("Unsupported");
+            }
+        };
+        assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "2008-231");
     }
 
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
+    @Test(expectedExceptions=DateTimeException.class)
     public void test_print_isoOrdinalDate_missingField() {
         TemporalAccessor test = Year.of(2008);
-        DateTimeFormatters.isoOrdinalDate().print(test);
+        DateTimeFormatter.ISO_ORDINAL_DATE.format(test);
     }
 
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_parse_isoOrdinalDate() {
-        DateTimeBuilder expected = new DateTimeBuilder(YEAR, 2008).addFieldValue(DAY_OF_YEAR, 123);
-        assertParseMatch(DateTimeFormatters.isoOrdinalDate().parseToBuilder("2008-123", new ParsePosition(0)), expected);
+        Expected expected = new Expected(YEAR, 2008, DAY_OF_YEAR, 123);
+        assertParseMatch(DateTimeFormatter.ISO_ORDINAL_DATE.parseUnresolved("2008-123", new ParsePosition(0)), expected);
     }
 
     @Test(groups={"tck"})
     public void test_parse_isoOrdinalDate_largeYear() {
-        DateTimeBuilder expected = new DateTimeBuilder(YEAR, 123456).addFieldValue(DAY_OF_YEAR, 123);
-        assertParseMatch(DateTimeFormatters.isoOrdinalDate().parseToBuilder("+123456-123", new ParsePosition(0)), expected);
+        Expected expected = new Expected(YEAR, 123456, DAY_OF_YEAR, 123);
+        assertParseMatch(DateTimeFormatter.ISO_ORDINAL_DATE.parseUnresolved("+123456-123", new ParsePosition(0)), expected);
     }
 
     //-----------------------------------------------------------------------
@@ -913,51 +925,51 @@
     @Test(groups={"tck"})
     public void test_print_basicIsoDate() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), null, null);
-        assertEquals(DateTimeFormatters.basicIsoDate().print(test), "20080603");
+        assertEquals(DateTimeFormatter.BASIC_ISO_DATE.format(test), "20080603");
     }
 
     @Test(groups={"tck"})
     public void test_print_basicIsoDate_offset() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), "Z", null);
-        assertEquals(DateTimeFormatters.basicIsoDate().print(test), "20080603Z");
+        assertEquals(DateTimeFormatter.BASIC_ISO_DATE.format(test), "20080603Z");
     }
 
     @Test(groups={"tck"})
     public void test_print_basicIsoDate_zoned() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), "+02:00", "Europe/Paris");
-        assertEquals(DateTimeFormatters.basicIsoDate().print(test), "20080603+0200");
+        assertEquals(DateTimeFormatter.BASIC_ISO_DATE.format(test), "20080603+0200");
     }
 
-    @Test(expectedExceptions=DateTimePrintException.class, groups={"tck"})
+    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
     public void test_print_basicIsoDate_largeYear() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(123456, 6, 3, 11, 5, 30), "Z", null);
-        DateTimeFormatters.basicIsoDate().print(test);
+        DateTimeFormatter.BASIC_ISO_DATE.format(test);
     }
 
     @Test(groups={"tck"})
     public void test_print_basicIsoDate_fields() {
         TemporalAccessor test = buildAccessor(LocalDate.of(2008, 6, 3), null, null);
-        assertEquals(DateTimeFormatters.basicIsoDate().print(test), "20080603");
+        assertEquals(DateTimeFormatter.BASIC_ISO_DATE.format(test), "20080603");
     }
 
     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
     public void test_print_basicIsoDate_missingField() {
         TemporalAccessor test = YearMonth.of(2008, 6);
-        DateTimeFormatters.basicIsoDate().print(test);
+        DateTimeFormatter.BASIC_ISO_DATE.format(test);
     }
 
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_parse_basicIsoDate() {
         LocalDate expected = LocalDate.of(2008, 6, 3);
-        assertEquals(DateTimeFormatters.basicIsoDate().parse("20080603", LocalDate::from), expected);
+        assertEquals(DateTimeFormatter.BASIC_ISO_DATE.parse("20080603", LocalDate::from), expected);
     }
 
     @Test(expectedExceptions=DateTimeParseException.class, groups={"tck"})
     public void test_parse_basicIsoDate_largeYear() {
         try {
             LocalDate expected = LocalDate.of(123456, 6, 3);
-            assertEquals(DateTimeFormatters.basicIsoDate().parse("+1234560603", LocalDate::from), expected);
+            assertEquals(DateTimeFormatter.BASIC_ISO_DATE.parse("+1234560603", LocalDate::from), expected);
         } catch (DateTimeParseException ex) {
             assertEquals(ex.getErrorIndex(), 0);
             assertEquals(ex.getParsedString(), "+1234560603");
@@ -1002,40 +1014,40 @@
 
     @Test(dataProvider="weekDate", groups={"tck"})
     public void test_print_isoWeekDate(TemporalAccessor test, String expected) {
-        assertEquals(DateTimeFormatters.isoWeekDate().print(test), expected);
+        assertEquals(DateTimeFormatter.ISO_WEEK_DATE.format(test), expected);
     }
 
     @Test(groups={"tck"})
     public void test_print_isoWeekDate_zoned_largeYear() {
         TemporalAccessor test = buildAccessor(LocalDateTime.of(123456, 6, 3, 11, 5, 30), "Z", null);
-        assertEquals(DateTimeFormatters.isoWeekDate().print(test), "+123456-W23-2Z");
+        assertEquals(DateTimeFormatter.ISO_WEEK_DATE.format(test), "+123456-W23-2Z");
     }
 
     @Test(groups={"tck"})
     public void test_print_isoWeekDate_fields() {
         TemporalAccessor test = buildAccessor(LocalDate.of(2004, 1, 27), null, null);
-        assertEquals(DateTimeFormatters.isoWeekDate().print(test), "2004-W05-2");
+        assertEquals(DateTimeFormatter.ISO_WEEK_DATE.format(test), "2004-W05-2");
     }
 
     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
     public void test_print_isoWeekDate_missingField() {
         TemporalAccessor test = YearMonth.of(2008, 6);
-        DateTimeFormatters.isoWeekDate().print(test);
+        DateTimeFormatter.ISO_WEEK_DATE.format(test);
     }
 
     //-----------------------------------------------------------------------
     @Test(groups={"tck"})
     public void test_parse_weekDate() {
         LocalDate expected = LocalDate.of(2004, 1, 28);
-        assertEquals(DateTimeFormatters.isoWeekDate().parse("2004-W05-3", LocalDate::from), expected);
+        assertEquals(DateTimeFormatter.ISO_WEEK_DATE.parse("2004-W05-3", LocalDate::from), expected);
     }
 
     @Test(groups={"tck"})
     public void test_parse_weekDate_largeYear() {
-        DateTimeBuilder builder = DateTimeFormatters.isoWeekDate().parseToBuilder("+123456-W04-5", new ParsePosition(0));
-        assertEquals(builder.getFieldValue(ISOFields.WEEK_BASED_YEAR), 123456);
-        assertEquals(builder.getFieldValue(ISOFields.WEEK_OF_WEEK_BASED_YEAR), 4);
-        assertEquals(builder.getFieldValue(DAY_OF_WEEK), 5);
+        TemporalAccessor parsed = DateTimeFormatter.ISO_WEEK_DATE.parseUnresolved("+123456-W04-5", new ParsePosition(0));
+        assertEquals(parsed.getLong(IsoFields.WEEK_BASED_YEAR), 123456L);
+        assertEquals(parsed.getLong(IsoFields.WEEK_OF_WEEK_BASED_YEAR), 4L);
+        assertEquals(parsed.getLong(DAY_OF_WEEK), 5L);
     }
 
     //-----------------------------------------------------------------------
@@ -1054,79 +1066,79 @@
     @Test(groups={"tck"}, dataProvider="rfc")
     public void test_print_rfc1123(LocalDateTime base, String offsetId, String expected) {
         TemporalAccessor test = buildAccessor(base, offsetId, null);
-        assertEquals(DateTimeFormatters.rfc1123().print(test), expected);
+        assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.format(test), expected);
     }
 
     @Test(groups={"tck"}, dataProvider="rfc")
     public void test_print_rfc1123_french(LocalDateTime base, String offsetId, String expected) {
         TemporalAccessor test = buildAccessor(base, offsetId, null);
-        assertEquals(DateTimeFormatters.rfc1123().withLocale(Locale.FRENCH).print(test), expected);
+        assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.withLocale(Locale.FRENCH).format(test), expected);
     }
 
     @Test(groups={"tck"}, expectedExceptions=DateTimeException.class)
     public void test_print_rfc1123_missingField() {
         TemporalAccessor test = YearMonth.of(2008, 6);
-        DateTimeFormatters.rfc1123().print(test);
+        DateTimeFormatter.RFC_1123_DATE_TIME.format(test);
     }
 
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    private DateTimeBuilder createDate(Integer year, Integer month, Integer day) {
-        DateTimeBuilder test = new DateTimeBuilder();
+    private Expected createDate(Integer year, Integer month, Integer day) {
+        Expected test = new Expected();
         if (year != null) {
-            test.addFieldValue(YEAR, year);
+            test.fieldValues.put(YEAR, (long) year);
         }
         if (month != null) {
-            test.addFieldValue(MONTH_OF_YEAR, month);
+            test.fieldValues.put(MONTH_OF_YEAR, (long) month);
         }
         if (day != null) {
-            test.addFieldValue(DAY_OF_MONTH, day);
+            test.fieldValues.put(DAY_OF_MONTH, (long) day);
         }
         return test;
     }
 
-    private DateTimeBuilder createTime(Integer hour, Integer min, Integer sec, Integer nano) {
-        DateTimeBuilder test = new DateTimeBuilder();
+    private Expected createTime(Integer hour, Integer min, Integer sec, Integer nano) {
+        Expected test = new Expected();
         if (hour != null) {
-            test.addFieldValue(HOUR_OF_DAY, hour);
+            test.fieldValues.put(HOUR_OF_DAY, (long) hour);
         }
         if (min != null) {
-            test.addFieldValue(MINUTE_OF_HOUR, min);
+            test.fieldValues.put(MINUTE_OF_HOUR, (long) min);
         }
         if (sec != null) {
-            test.addFieldValue(SECOND_OF_MINUTE, sec);
+            test.fieldValues.put(SECOND_OF_MINUTE, (long) sec);
         }
         if (nano != null) {
-            test.addFieldValue(NANO_OF_SECOND, nano);
+            test.fieldValues.put(NANO_OF_SECOND, (long) nano);
         }
         return test;
     }
 
-    private DateTimeBuilder createDateTime(
+    private Expected createDateTime(
             Integer year, Integer month, Integer day,
             Integer hour, Integer min, Integer sec, Integer nano) {
-        DateTimeBuilder test = new DateTimeBuilder();
+        Expected test = new Expected();
         if (year != null) {
-            test.addFieldValue(YEAR, year);
+            test.fieldValues.put(YEAR, (long) year);
         }
         if (month != null) {
-            test.addFieldValue(MONTH_OF_YEAR, month);
+            test.fieldValues.put(MONTH_OF_YEAR, (long) month);
         }
         if (day != null) {
-            test.addFieldValue(DAY_OF_MONTH, day);
+            test.fieldValues.put(DAY_OF_MONTH, (long) day);
         }
         if (hour != null) {
-            test.addFieldValue(HOUR_OF_DAY, hour);
+            test.fieldValues.put(HOUR_OF_DAY, (long) hour);
         }
         if (min != null) {
-            test.addFieldValue(MINUTE_OF_HOUR, min);
+            test.fieldValues.put(MINUTE_OF_HOUR, (long) min);
         }
         if (sec != null) {
-            test.addFieldValue(SECOND_OF_MINUTE, sec);
+            test.fieldValues.put(SECOND_OF_MINUTE, (long) sec);
         }
         if (nano != null) {
-            test.addFieldValue(NANO_OF_SECOND, nano);
+            test.fieldValues.put(NANO_OF_SECOND, (long) nano);
         }
         return test;
     }
@@ -1178,23 +1190,22 @@
         return mock;
     }
 
-    private void buildCalendrical(DateTimeBuilder cal, String offsetId, String zoneId) {
+    private void buildCalendrical(Expected expected, String offsetId, String zoneId) {
         if (offsetId != null) {
-            cal.addFieldValue(OFFSET_SECONDS, ZoneOffset.of(offsetId).getTotalSeconds());
+            expected.add(ZoneOffset.of(offsetId));
         }
         if (zoneId != null) {
-            cal.addCalendrical(ZoneId.of(zoneId));
+            expected.zone = ZoneId.of(zoneId);
         }
     }
 
-    private void assertParseMatch(DateTimeBuilder parsed, DateTimeBuilder expected) {
-        Map<TemporalField, Long> parsedFVMap = parsed.getFieldValueMap();
-        Map<TemporalField, Long> expectedFVMap = expected.getFieldValueMap();
-        assertEquals(parsedFVMap, expectedFVMap);
-
-        List<Object> parsedCMap = parsed.getCalendricalList();
-        List<Object> expectedCMap = expected.getCalendricalList();
-        assertEquals(parsedCMap, expectedCMap);
+    private void assertParseMatch(TemporalAccessor parsed, Expected expected) {
+        for (TemporalField field : expected.fieldValues.keySet()) {
+            assertEquals(parsed.isSupported(field), true);
+            parsed.getLong(field);
+        }
+        assertEquals(parsed.query(Queries.chronology()), expected.chrono);
+        assertEquals(parsed.query(Queries.zoneId()), expected.zone);
     }
 
     //-------------------------------------------------------------------------
@@ -1211,8 +1222,8 @@
                 fields.put(DAY_OF_MONTH, (long) dt.getDayOfMonth());
                 fields.put(DAY_OF_YEAR, (long) dt.getDayOfYear());
                 fields.put(DAY_OF_WEEK, (long) dt.getDayOfWeek().getValue());
-                fields.put(ISOFields.WEEK_BASED_YEAR, dt.getLong(ISOFields.WEEK_BASED_YEAR));
-                fields.put(ISOFields.WEEK_OF_WEEK_BASED_YEAR, dt.getLong(ISOFields.WEEK_OF_WEEK_BASED_YEAR));
+                fields.put(IsoFields.WEEK_BASED_YEAR, dt.getLong(IsoFields.WEEK_BASED_YEAR));
+                fields.put(IsoFields.WEEK_OF_WEEK_BASED_YEAR, dt.getLong(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
             }
         }
 
@@ -1223,8 +1234,8 @@
                 fields.put(DAY_OF_MONTH, (long) dt.getDayOfMonth());
                 fields.put(DAY_OF_YEAR, (long) dt.getDayOfYear());
                 fields.put(DAY_OF_WEEK, (long) dt.getDayOfWeek().getValue());
-                fields.put(ISOFields.WEEK_BASED_YEAR, dt.getLong(ISOFields.WEEK_BASED_YEAR));
-                fields.put(ISOFields.WEEK_OF_WEEK_BASED_YEAR, dt.getLong(ISOFields.WEEK_OF_WEEK_BASED_YEAR));
+                fields.put(IsoFields.WEEK_BASED_YEAR, dt.getLong(IsoFields.WEEK_BASED_YEAR));
+                fields.put(IsoFields.WEEK_OF_WEEK_BASED_YEAR, dt.getLong(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
                 fields.put(HOUR_OF_DAY, (long) dt.getHour());
                 fields.put(MINUTE_OF_HOUR, (long) dt.getMinute());
                 fields.put(SECOND_OF_MINUTE, (long) dt.getSecond());
@@ -1273,4 +1284,22 @@
         }
     }
 
+    //-----------------------------------------------------------------------
+    static class Expected {
+        Map<TemporalField, Long> fieldValues = new HashMap<>();
+        ZoneId zone;
+        Chronology chrono;
+
+        Expected() {
+        }
+
+        Expected(TemporalField field1, long value1, TemporalField field2, long value2) {
+            fieldValues.put(field1, value1);
+            fieldValues.put(field2, value2);
+        }
+
+        void add(ZoneOffset offset) {
+            fieldValues.put(OFFSET_SECONDS, (long) offset.getTotalSeconds());
+        }
+    }
 }
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimePrintException.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimePrintException.java
deleted file mode 100644
index 0117629..0000000
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimePrintException.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package tck.java.time.format;
-
-import java.time.format.*;
-import test.java.time.format.*;
-
-import static org.testng.Assert.assertEquals;
-
-import java.io.IOException;
-
-import org.testng.annotations.Test;
-
-/**
- * Test DateTimePrintException.
- */
-@Test
-public class TCKDateTimePrintException {
-
-    @Test(groups={"tck"})
-    public void test_constructor_String() throws Exception {
-        DateTimePrintException ex = new DateTimePrintException("TEST");
-        assertEquals(ex.getMessage(), "TEST");
-    }
-
-    @Test(groups={"tck"})
-    public void test_constructor_StringThrowable_notIOException_equal() throws Exception {
-        IllegalArgumentException iaex = new IllegalArgumentException("INNER");
-        DateTimePrintException ex = new DateTimePrintException("TEST", iaex);
-        assertEquals(ex.getMessage(), "TEST");
-        assertEquals(ex.getCause(), iaex);
-        ex.rethrowIOException();  // no effect
-    }
-
-    @Test(expectedExceptions=IOException.class, groups={"tck"})
-    public void test_constructor_StringThrowable_IOException() throws Exception {
-        IOException ioex = new IOException("INNER");
-        DateTimePrintException ex = new DateTimePrintException("TEST", ioex);
-        assertEquals(ex.getMessage(), "TEST");
-        assertEquals(ex.getCause(), ioex);
-        ex.rethrowIOException();  // rethrows
-    }
-
-}
diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeTextPrinting.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeTextPrinting.java
index 5af0ebf..d436fb4 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeTextPrinting.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeTextPrinting.java
@@ -136,21 +136,21 @@
     }
 
     @Test(dataProvider="printText", groups={"tck"})
-    public void test_appendText2arg_print(TemporalField field, TextStyle style, int value, String expected) throws Exception {
+    public void test_appendText2arg_format(TemporalField field, TextStyle style, int value, String expected) throws Exception {
         DateTimeFormatter f = builder.appendText(field, style).toFormatter(Locale.ENGLISH);
         LocalDateTime dt = LocalDateTime.of(2010, 1, 1, 0, 0);
         dt = dt.with(field, value);
-        String text = f.print(dt);
+        String text = f.format(dt);
         assertEquals(text, expected);
     }
 
     @Test(dataProvider="printText", groups={"tck"})
-    public void test_appendText1arg_print(TemporalField field, TextStyle style, int value, String expected) throws Exception {
+    public void test_appendText1arg_format(TemporalField field, TextStyle style, int value, String expected) throws Exception {
         if (style == TextStyle.FULL) {
             DateTimeFormatter f = builder.appendText(field).toFormatter(Locale.ENGLISH);
             LocalDateTime dt = LocalDateTime.of(2010, 1, 1, 0, 0);
             dt = dt.with(field, value);
-            String text = f.print(dt);
+            String text = f.format(dt);
             assertEquals(text, expected);
         }
     }
@@ -160,7 +160,7 @@
     public void test_print_appendText2arg_french_long() throws Exception {
         DateTimeFormatter f = builder.appendText(MONTH_OF_YEAR, TextStyle.FULL).toFormatter(Locale.FRENCH);
         LocalDateTime dt = LocalDateTime.of(2010, 1, 1, 0, 0);
-        String text = f.print(dt);
+        String text = f.format(dt);
         assertEquals(text, "janvier");
     }
 
@@ -168,7 +168,7 @@
     public void test_print_appendText2arg_french_short() throws Exception {
         DateTimeFormatter f = builder.appendText(MONTH_OF_YEAR, TextStyle.SHORT).toFormatter(Locale.FRENCH);
         LocalDateTime dt = LocalDateTime.of(2010, 1, 1, 0, 0);
-        String text = f.print(dt);
+        String text = f.format(dt);
         assertEquals(text, "janv.");
     }
 
@@ -192,7 +192,7 @@
         DateTimeFormatter f = builder.toFormatter();
         LocalDateTime dt = LocalDateTime.of(2010, 1, 1, 0, 0);
         for (Month month : Month.values()) {
-            assertEquals(f.print(dt.with(month)), map.get((long) month.getValue()));
+            assertEquals(f.format(dt.with(month)), map.get((long) month.getValue()));
         }
     }
 
@@ -205,9 +205,9 @@
         builder.appendText(DAY_OF_MONTH, map);
         DateTimeFormatter f = builder.toFormatter();
         LocalDateTime dt = LocalDateTime.of(2010, 1, 1, 0, 0);
-        assertEquals(f.print(dt.withDayOfMonth(1)), "1st");
-        assertEquals(f.print(dt.withDayOfMonth(2)), "2nd");
-        assertEquals(f.print(dt.withDayOfMonth(3)), "3rd");
+        assertEquals(f.format(dt.withDayOfMonth(1)), "1st");
+        assertEquals(f.format(dt.withDayOfMonth(2)), "2nd");
+        assertEquals(f.format(dt.withDayOfMonth(3)), "3rd");
     }
 
     @Test(groups={"tck"})
@@ -217,7 +217,7 @@
         builder.appendText(MONTH_OF_YEAR, map);
         DateTimeFormatter f = builder.toFormatter();
         LocalDateTime dt = LocalDateTime.of(2010, 2, 1, 0, 0);
-        assertEquals(f.print(dt), "2");
+        assertEquals(f.format(dt), "2");
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldParser.java b/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldParser.java
index d6f5f16..0d7975a 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldParser.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldParser.java
@@ -59,22 +59,21 @@
  */
 package tck.java.time.format;
 
-import java.time.format.*;
-
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
 
 import java.text.ParsePosition;
-import java.time.format.DateTimeBuilder;
-
 import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.WeekFields;
 
-import test.java.time.format.AbstractTestPrinterParser;
-
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import test.java.time.format.AbstractTestPrinterParser;
 
 /**
  * Test TCKLocalizedFieldParser.
@@ -114,12 +113,12 @@
         DateTimeFormatterBuilder b
                 = new DateTimeFormatterBuilder().appendPattern(pattern);
         DateTimeFormatter dtf = b.toFormatter(locale);
-        DateTimeBuilder dtb = dtf.parseToBuilder(text, ppos);
+        TemporalAccessor parsed = dtf.parseUnresolved(text, ppos);
         if (ppos.getErrorIndex() != -1) {
             assertEquals(ppos.getErrorIndex(), expectedPos);
         } else {
             assertEquals(ppos.getIndex(), expectedPos, "Incorrect ending parse position");
-            long value = dtb.getLong(field);
+            long value = parsed.getLong(field);
             assertEquals(value, expectedValue, "Value incorrect for " + field);
         }
     }
@@ -143,20 +142,23 @@
                 "Date: 2012, day-of-week: 6, week-of-year: 29", 0, 44, LocalDate.of(2012, 7, 20)},
         };
     }
+
    @Test(dataProvider="LocalDatePatterns",groups={"tck"})
     public void test_parse_textLocalDate(String pattern, String text, int pos, int expectedPos, LocalDate expectedValue) {
-        WeekFields weekDef = WeekFields.of(locale);
         ParsePosition ppos = new ParsePosition(pos);
-        DateTimeFormatterBuilder b
-                = new DateTimeFormatterBuilder().appendPattern(pattern);
+        DateTimeFormatterBuilder b = new DateTimeFormatterBuilder().appendPattern(pattern);
         DateTimeFormatter dtf = b.toFormatter(locale);
-        DateTimeBuilder dtb = dtf.parseToBuilder(text, ppos);
+        TemporalAccessor parsed = dtf.parseUnresolved(text, ppos);
         if (ppos.getErrorIndex() != -1) {
             assertEquals(ppos.getErrorIndex(), expectedPos);
         } else {
             assertEquals(ppos.getIndex(), expectedPos, "Incorrect ending parse position");
-            dtb.resolve();
-            LocalDate result = dtb.query(LocalDate::from);
+            assertEquals(parsed.isSupported(YEAR), true);
+            assertEquals(parsed.isSupported(WeekFields.of(locale).dayOfWeek()), true);
+            assertEquals(parsed.isSupported(WeekFields.of(locale).weekOfMonth()) ||
+                    parsed.isSupported(WeekFields.of(locale).weekOfYear()), true);
+            // ensure combination resolves into a date
+            LocalDate result = LocalDate.parse(text, dtf);
             assertEquals(result, expectedValue, "LocalDate incorrect for " + pattern);
         }
     }
diff --git a/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldPrinter.java b/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldPrinter.java
index dac65b6..3be85a9 100644
--- a/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldPrinter.java
+++ b/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldPrinter.java
@@ -98,7 +98,7 @@
                 = new DateTimeFormatterBuilder().appendPattern(pattern);
         LocalDate date = LocalDate.of(2012, 7, 20);
 
-        String result = b.toFormatter(locale).print(date);
+        String result = b.toFormatter(locale).format(date);
         assertEquals(result, expected, "Wrong output for pattern '" + pattern + "'.");
     }
 
diff --git a/jdk/test/java/time/tck/java/time/format/TCKLocalizedPrinterParser.java b/jdk/test/java/time/tck/java/time/format/TCKLocalizedPrinterParser.java
new file mode 100644
index 0000000..cb348b2
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/format/TCKLocalizedPrinterParser.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.format;
+
+import static org.testng.Assert.assertEquals;
+
+import java.text.DateFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
+import java.time.temporal.TemporalAccessor;
+import java.util.Date;
+import java.util.Locale;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test localized behavior of formatter.
+ */
+@Test
+public class TCKLocalizedPrinterParser {
+
+    private DateTimeFormatterBuilder builder;
+    private ParsePosition pos;
+
+    @BeforeMethod
+    public void setUp() {
+        builder = new DateTimeFormatterBuilder();
+        pos = new ParsePosition(0);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_parse_negativePosition() {
+        builder.appendLocalized(null, null);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="date")
+    Object[][] data_date() {
+        return new Object[][] {
+                {LocalDate.of(2012, 6, 30), FormatStyle.SHORT, DateFormat.SHORT, Locale.UK},
+                {LocalDate.of(2012, 6, 30), FormatStyle.SHORT, DateFormat.SHORT, Locale.US},
+                {LocalDate.of(2012, 6, 30), FormatStyle.SHORT, DateFormat.SHORT, Locale.FRANCE},
+                {LocalDate.of(2012, 6, 30), FormatStyle.SHORT, DateFormat.SHORT, Locale.JAPAN},
+
+                {LocalDate.of(2012, 6, 30), FormatStyle.MEDIUM, DateFormat.MEDIUM, Locale.UK},
+                {LocalDate.of(2012, 6, 30), FormatStyle.MEDIUM, DateFormat.MEDIUM, Locale.US},
+                {LocalDate.of(2012, 6, 30), FormatStyle.MEDIUM, DateFormat.MEDIUM, Locale.FRANCE},
+                {LocalDate.of(2012, 6, 30), FormatStyle.MEDIUM, DateFormat.MEDIUM, Locale.JAPAN},
+
+                {LocalDate.of(2012, 6, 30), FormatStyle.LONG, DateFormat.LONG, Locale.UK},
+                {LocalDate.of(2012, 6, 30), FormatStyle.LONG, DateFormat.LONG, Locale.US},
+                {LocalDate.of(2012, 6, 30), FormatStyle.LONG, DateFormat.LONG, Locale.FRANCE},
+                {LocalDate.of(2012, 6, 30), FormatStyle.LONG, DateFormat.LONG, Locale.JAPAN},
+
+                {LocalDate.of(2012, 6, 30), FormatStyle.FULL, DateFormat.FULL, Locale.UK},
+                {LocalDate.of(2012, 6, 30), FormatStyle.FULL, DateFormat.FULL, Locale.US},
+                {LocalDate.of(2012, 6, 30), FormatStyle.FULL, DateFormat.FULL, Locale.FRANCE},
+                {LocalDate.of(2012, 6, 30), FormatStyle.FULL, DateFormat.FULL, Locale.JAPAN},
+        };
+    }
+
+    @SuppressWarnings("deprecated")
+    @Test(dataProvider="date")
+    public void test_date_print(LocalDate date, FormatStyle dateStyle, int dateStyleOld, Locale locale) {
+        DateFormat old = DateFormat.getDateInstance(dateStyleOld, locale);
+        Date oldDate = new Date(date.getYear() - 1900, date.getMonthValue() - 1, date.getDayOfMonth());
+        String text = old.format(oldDate);
+
+        DateTimeFormatter f = builder.appendLocalized(dateStyle, null).toFormatter(locale);
+        String formatted = f.format(date);
+        assertEquals(formatted, text);
+    }
+
+    @SuppressWarnings("deprecated")
+    @Test(dataProvider="date")
+    public void test_date_parse(LocalDate date, FormatStyle dateStyle, int dateStyleOld, Locale locale) {
+        DateFormat old = DateFormat.getDateInstance(dateStyleOld, locale);
+        Date oldDate = new Date(date.getYear() - 1900, date.getMonthValue() - 1, date.getDayOfMonth());
+        String text = old.format(oldDate);
+
+        DateTimeFormatter f = builder.appendLocalized(dateStyle, null).toFormatter(locale);
+        TemporalAccessor parsed = f.parse(text, pos);
+        assertEquals(pos.getIndex(), text.length());
+        assertEquals(pos.getErrorIndex(), -1);
+        assertEquals(LocalDate.from(parsed), date);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="time")
+    Object[][] data_time() {
+        return new Object[][] {
+                {LocalTime.of(11, 30), FormatStyle.SHORT, DateFormat.SHORT, Locale.UK},
+                {LocalTime.of(11, 30), FormatStyle.SHORT, DateFormat.SHORT, Locale.US},
+                {LocalTime.of(11, 30), FormatStyle.SHORT, DateFormat.SHORT, Locale.FRANCE},
+                {LocalTime.of(11, 30), FormatStyle.SHORT, DateFormat.SHORT, Locale.JAPAN},
+
+                {LocalTime.of(11, 30), FormatStyle.MEDIUM, DateFormat.MEDIUM, Locale.UK},
+                {LocalTime.of(11, 30), FormatStyle.MEDIUM, DateFormat.MEDIUM, Locale.US},
+                {LocalTime.of(11, 30), FormatStyle.MEDIUM, DateFormat.MEDIUM, Locale.FRANCE},
+                {LocalTime.of(11, 30), FormatStyle.MEDIUM, DateFormat.MEDIUM, Locale.JAPAN},
+
+                // these localized patterns include "z" which isn't available from LocalTime
+//                {LocalTime.of(11, 30), FormatStyle.LONG, DateFormat.LONG, Locale.UK},
+//                {LocalTime.of(11, 30), FormatStyle.LONG, DateFormat.LONG, Locale.US},
+//                {LocalTime.of(11, 30), FormatStyle.LONG, DateFormat.LONG, Locale.FRANCE},
+//                {LocalTime.of(11, 30), FormatStyle.LONG, DateFormat.LONG, Locale.JAPAN},
+//
+//                {LocalTime.of(11, 30), FormatStyle.FULL, DateFormat.FULL, Locale.UK},
+//                {LocalTime.of(11, 30), FormatStyle.FULL, DateFormat.FULL, Locale.US},
+//                {LocalTime.of(11, 30), FormatStyle.FULL, DateFormat.FULL, Locale.FRANCE},
+//                {LocalTime.of(11, 30), FormatStyle.FULL, DateFormat.FULL, Locale.JAPAN},
+        };
+    }
+
+    @SuppressWarnings("deprecated")
+    @Test(dataProvider="time")
+    public void test_time_print(LocalTime time, FormatStyle timeStyle, int timeStyleOld, Locale locale) {
+        DateFormat old = DateFormat.getTimeInstance(timeStyleOld, locale);
+        Date oldDate = new Date(1970, 0, 0, time.getHour(), time.getMinute(), time.getSecond());
+        String text = old.format(oldDate);
+
+        DateTimeFormatter f = builder.appendLocalized(null, timeStyle).toFormatter(locale);
+        String formatted = f.format(time);
+        assertEquals(formatted, text);
+    }
+
+    @SuppressWarnings("deprecated")
+    @Test(dataProvider="time")
+    public void test_time_parse(LocalTime time, FormatStyle timeStyle, int timeStyleOld, Locale locale) {
+        DateFormat old = DateFormat.getTimeInstance(timeStyleOld, locale);
+        Date oldDate = new Date(1970, 0, 0, time.getHour(), time.getMinute(), time.getSecond());
+        String text = old.format(oldDate);
+
+        DateTimeFormatter f = builder.appendLocalized(null, timeStyle).toFormatter(locale);
+        TemporalAccessor parsed = f.parse(text, pos);
+        assertEquals(pos.getIndex(), text.length());
+        assertEquals(pos.getErrorIndex(), -1);
+        assertEquals(LocalTime.from(parsed), time);
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/format/TCKOffsetPrinterParser.java b/jdk/test/java/time/tck/java/time/format/TCKOffsetPrinterParser.java
new file mode 100644
index 0000000..0ebc718
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/format/TCKOffsetPrinterParser.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.format;
+
+import static org.testng.Assert.assertEquals;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test DateTimeFormatterBuilder.appendOffset().
+ */
+@Test
+public class TCKOffsetPrinterParser {
+
+    private static final ZoneOffset OFFSET_UTC = ZoneOffset.UTC;
+    private static final ZoneOffset OFFSET_P0100 = ZoneOffset.ofHours(1);
+    private static final ZoneOffset OFFSET_P0123 = ZoneOffset.ofHoursMinutes(1, 23);
+    private static final ZoneOffset OFFSET_P0023 = ZoneOffset.ofHoursMinutes(0, 23);
+    private static final ZoneOffset OFFSET_P012345 = ZoneOffset.ofHoursMinutesSeconds(1, 23, 45);
+    private static final ZoneOffset OFFSET_P000045 = ZoneOffset.ofHoursMinutesSeconds(0, 0, 45);
+    private static final ZoneOffset OFFSET_M0100 = ZoneOffset.ofHours(-1);
+    private static final ZoneOffset OFFSET_M0123 = ZoneOffset.ofHoursMinutes(-1, -23);
+    private static final ZoneOffset OFFSET_M0023 = ZoneOffset.ofHoursMinutes(0, -23);
+    private static final ZoneOffset OFFSET_M012345 = ZoneOffset.ofHoursMinutesSeconds(-1, -23, -45);
+    private static final ZoneOffset OFFSET_M000045 = ZoneOffset.ofHoursMinutesSeconds(0, 0, -45);
+    private static final LocalDateTime DT_2012_06_30_12_30_40 = LocalDateTime.of(2012, 6, 30, 12, 30, 40);
+
+    private DateTimeFormatterBuilder builder;
+
+    @BeforeMethod
+    public void setUp() {
+        builder = new DateTimeFormatterBuilder();
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="print")
+    Object[][] data_print() {
+        return new Object[][] {
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+01"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "Z"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+01"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "Z"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-01"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "Z"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-01"},
+                {"+HH", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "Z"},
+
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+0123"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0023"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+0123"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "Z"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-0123"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0023"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-0123"},
+                {"+HHmm", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "Z"},
+
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+0100"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+0123"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0023"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+0123"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "Z"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-0100"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-0123"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0023"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-0123"},
+                {"+HHMM", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "Z"},
+
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01:00"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+01:23"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+00:23"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+01:23"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "Z"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01:00"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-01:23"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-00:23"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-01:23"},
+                {"+HH:MM", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "Z"},
+
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+0100"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+0123"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0023"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+012345"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "+000045"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-0100"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-0123"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0023"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-012345"},
+                {"+HHMMss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-000045"},
+
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01:00"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+01:23"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+00:23"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+01:23:45"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01:00"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-01:23"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-00:23"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-01:23:45"},
+                {"+HH:MM:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
+
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+010000"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+012300"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+002300"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+012345"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-000045"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-010000"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-012300"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-002300"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-012345"},
+                {"+HHMMSS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-000045"},
+
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01:00:00"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+01:23:00"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+00:23:00"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+01:23:45"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01:00:00"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-01:23:00"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-00:23:00"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-01:23:45"},
+                {"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
+        };
+    }
+
+    @Test(dataProvider="print")
+    public void test_print(String offsetPattern, String noOffset, LocalDateTime ldt, ZoneId zone, String expected) {
+        ZonedDateTime zdt = ldt.atZone(zone);
+        builder.appendOffset(offsetPattern, noOffset);
+        String output = builder.toFormatter().format(zdt);
+        assertEquals(output, expected);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="print")
+    public void test_print_pattern_X(String offsetPattern, String noOffset, LocalDateTime ldt, ZoneId zone, String expected) {
+        String pattern = null;
+        if (offsetPattern.equals("+HHmm") && noOffset.equals("Z")) {
+            pattern = "X";
+        } else if (offsetPattern.equals("+HHMM") && noOffset.equals("Z")) {
+            pattern = "XX";
+        } else if (offsetPattern.equals("+HH:MM") && noOffset.equals("Z")) {
+            pattern = "XXX";
+        } else if (offsetPattern.equals("+HHMMss") && noOffset.equals("Z")) {
+            pattern = "XXXX";
+        } else if (offsetPattern.equals("+HH:MM:ss") && noOffset.equals("Z")) {
+            pattern = "XXXXX";
+        }
+        if (pattern != null) {
+            ZonedDateTime zdt = ldt.atZone(zone);
+            builder.appendPattern(pattern);
+            String output = builder.toFormatter().format(zdt);
+            assertEquals(output, expected);
+        }
+    }
+
+    @Test(dataProvider="print")
+    public void test_print_pattern_x(String offsetPattern, String noOffset, LocalDateTime ldt, ZoneId zone, String expected) {
+        String pattern = null;
+        String zero = null;
+        if (offsetPattern.equals("+HHmm") && noOffset.equals("Z")) {
+            pattern = "x";
+            zero = "+00";
+        } else if (offsetPattern.equals("+HHMM") && noOffset.equals("Z")) {
+            pattern = "xx";
+            zero = "+0000";
+        } else if (offsetPattern.equals("+HH:MM") && noOffset.equals("Z")) {
+            pattern = "xxx";
+            zero = "+00:00";
+        } else if (offsetPattern.equals("+HHMMss") && noOffset.equals("Z")) {
+            pattern = "xxxx";
+            zero = "+0000";
+        } else if (offsetPattern.equals("+HH:MM:ss") && noOffset.equals("Z")) {
+            pattern = "xxxxx";
+            zero = "+00:00";
+        }
+        if (pattern != null) {
+            ZonedDateTime zdt = ldt.atZone(zone);
+            builder.appendPattern(pattern);
+            String output = builder.toFormatter().format(zdt);
+            assertEquals(output, (expected.equals("Z") ? zero : expected));
+        }
+    }
+
+    @Test(dataProvider="print")
+    public void test_print_pattern_Z(String offsetPattern, String noOffset, LocalDateTime ldt, ZoneId zone, String expected) {
+        String pattern = null;
+        if (offsetPattern.equals("+HHMM") && noOffset.equals("Z")) {
+            ZonedDateTime zdt = ldt.atZone(zone);
+            DateTimeFormatter f1 = new DateTimeFormatterBuilder().appendPattern("Z").toFormatter();
+            String output1 = f1.format(zdt);
+            assertEquals(output1, (expected.equals("Z") ? "+0000" : expected));
+
+            DateTimeFormatter f2 = new DateTimeFormatterBuilder().appendPattern("ZZ").toFormatter();
+            String output2 = f2.format(zdt);
+            assertEquals(output2, (expected.equals("Z") ? "+0000" : expected));
+
+            DateTimeFormatter f3 = new DateTimeFormatterBuilder().appendPattern("ZZZ").toFormatter();
+            String output3 = f3.format(zdt);
+            assertEquals(output3, (expected.equals("Z") ? "+0000" : expected));
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_print_pattern_X6rejected() {
+        builder.appendPattern("XXXXXX");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_print_pattern_x6rejected() {
+        builder.appendPattern("xxxxxx");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_print_pattern_Z4rejected() {
+        builder.appendPattern("ZZZZ");
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/format/TCKPadPrinterParser.java b/jdk/test/java/time/tck/java/time/format/TCKPadPrinterParser.java
new file mode 100644
index 0000000..d6641f6
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/format/TCKPadPrinterParser.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.format;
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.text.ParsePosition;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.SignStyle;
+import java.time.temporal.TemporalAccessor;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test padding behavior of formatter.
+ */
+@Test
+public class TCKPadPrinterParser {
+
+    private DateTimeFormatterBuilder builder;
+    private ParsePosition pos;
+
+    @BeforeMethod
+    public void setUp() {
+        builder = new DateTimeFormatterBuilder();
+        pos = new ParsePosition(0);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(expectedExceptions=IndexOutOfBoundsException.class)
+    public void test_parse_negativePosition() {
+        builder.padNext(3, '-').appendLiteral('Z');
+        builder.toFormatter().parseUnresolved("--Z", new ParsePosition(-1));
+    }
+
+    @Test(expectedExceptions=IndexOutOfBoundsException.class)
+    public void test_parse_offEndPosition() {
+        builder.padNext(3, '-').appendLiteral('Z');
+        builder.toFormatter().parseUnresolved("--Z", new ParsePosition(4));
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="parseStrict")
+    Object[][] data_parseStrict() {
+        return new Object[][] {
+                {"222", 3, -1, 222},
+                {"222X", 3, -1, 222},
+                {"#22", 3, -1, 22},
+                {"#22X", 3, -1, 22},
+                {"##2", 3, -1, 2},
+                {"##2X", 3, -1, 2},
+                {"##22", 3, -1, 2},
+                {"-22", 3, -1, -22},
+                {"#-2", 3, -1, -2},
+                {"3", 0, 0, null},
+                {"3X", 0, 0, null},
+                {"#3", 0, 0, null},
+                {"#3X", 0, 1, null},
+                {"##A", 0, 2, null},
+                {"  3", 0, 0, null},
+                {"##", 0, 0, null},
+                {"#", 0, 0, null},
+                {"", 0, 0, null},
+        };
+    }
+
+    @Test(dataProvider="parseStrict")
+    public void test_parseStrict(String text, int expectedIndex, int expectedErrorIndex, Number expectedMonth) {
+        builder.padNext(3, '#').appendValue(MONTH_OF_YEAR, 1, 3, SignStyle.NORMAL);
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text, pos);
+        assertEquals(pos.getIndex(), expectedIndex);
+        assertEquals(pos.getErrorIndex(), expectedErrorIndex);
+        if (expectedMonth != null) {
+            assertEquals(parsed.isSupported(MONTH_OF_YEAR), true);
+            assertEquals(parsed.getLong(MONTH_OF_YEAR), expectedMonth.longValue());
+        } else {
+            assertEquals(parsed, null);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="parseLenient")
+    Object[][] data_parseLenient() {
+        return new Object[][] {
+                {"222", 3, -1, 222},
+                {"222X", 3, -1, 222},
+                {"#22", 3, -1, 22},
+                {"#22X", 3, -1, 22},
+                {"##2", 3, -1, 2},
+                {"##2X", 3, -1, 2},
+                {"##22", 3, -1, 2},
+                {"-22", 3, -1, -22},
+                {"#-2", 3, -1, -2},
+                {"3", 1, -1, 3},
+                {"3X", 1, -1, 3},
+                {"33", 2, -1, 33},
+                {"33X", 2, -1, 33},
+                {"#3", 2, -1, 3},
+                {"#3X", 2, -1, 3},
+                {"##A", 0, 2, null},
+                {"  1", 0, 0, null},
+                {"##", 0, 2, null},
+                {"#", 0, 1, null},
+                {"", 0, 0, null},
+        };
+    }
+
+    @Test(dataProvider="parseLenient")
+    public void test_parseLenient(String text, int expectedIndex, int expectedErrorIndex, Number expectedMonth) {
+        builder.parseLenient().padNext(3, '#').appendValue(MONTH_OF_YEAR, 1, 3, SignStyle.NORMAL);
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text, pos);
+        assertEquals(pos.getIndex(), expectedIndex);
+        assertEquals(pos.getErrorIndex(), expectedErrorIndex);
+        if (expectedMonth != null) {
+            assertEquals(parsed.isSupported(MONTH_OF_YEAR), true);
+            assertEquals(parsed.getLong(MONTH_OF_YEAR), expectedMonth.longValue());
+        } else {
+            assertEquals(parsed, null);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_parse_decoratedStartsWithPad() {
+        builder.padNext(8, '-').appendLiteral("-HELLO-");
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved("--HELLO-", pos);
+        assertEquals(pos.getIndex(), 0);
+        assertEquals(pos.getErrorIndex(), 2);
+        assertEquals(parsed, null);
+    }
+
+    @Test
+    public void test_parse_decoratedStartsWithPad_number() {
+        builder.padNext(3, '-').appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL);
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved("--2", pos);
+        assertEquals(pos.getIndex(), 3);
+        assertEquals(pos.getErrorIndex(), -1);
+        assertEquals(parsed.isSupported(MONTH_OF_YEAR), true);
+        assertEquals(parsed.getLong(MONTH_OF_YEAR), 2L);  // +2, not -2
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_parse_decoratedEmpty_strict() {
+        builder.padNext(4, '-').optionalStart().appendValue(DAY_OF_MONTH).optionalEnd();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved("----", pos);
+        assertEquals(pos.getIndex(), 4);
+        assertEquals(pos.getErrorIndex(), -1);
+        assertNotNull(parsed);
+    }
+
+    @Test
+    public void test_parse_decoratedEmpty_lenient() {
+        builder.parseLenient().padNext(4, '-').optionalStart().appendValue(DAY_OF_MONTH).optionalEnd();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved("----", pos);
+        assertEquals(pos.getIndex(), 4);
+        assertEquals(pos.getErrorIndex(), -1);
+        assertNotNull(parsed);
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java b/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java
new file mode 100644
index 0000000..e346742
--- /dev/null
+++ b/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package tck.java.time.format;
+
+import static org.testng.Assert.assertEquals;
+
+import java.text.ParsePosition;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.Queries;
+import java.time.temporal.TemporalAccessor;
+import java.util.Locale;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test DateTimeFormatterBuilder.appendZoneId().
+ */
+@Test
+public class TCKZoneIdPrinterParser {
+
+    private static final ZoneOffset OFFSET_UTC = ZoneOffset.UTC;
+    private static final ZoneOffset OFFSET_P0123 = ZoneOffset.ofHoursMinutes(1, 23);
+    private static final ZoneId EUROPE_PARIS = ZoneId.of("Europe/Paris");
+    private static final ZoneId AMERICA_NEW_YORK = ZoneId.of("America/New_York");
+    private static final LocalDateTime DT_2012_06_30_12_30_40 = LocalDateTime.of(2012, 6, 30, 12, 30, 40);
+
+    private DateTimeFormatterBuilder builder;
+    private ParsePosition pos;
+
+    @BeforeMethod
+    public void setUp() {
+        builder = new DateTimeFormatterBuilder();
+        pos = new ParsePosition(0);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="print")
+    Object[][] data_print() {
+        return new Object[][] {
+                {DT_2012_06_30_12_30_40, EUROPE_PARIS, "Europe/Paris"},
+                {DT_2012_06_30_12_30_40, AMERICA_NEW_YORK, "America/New_York"},
+                {DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
+                {DT_2012_06_30_12_30_40, OFFSET_P0123, "+01:23"},
+        };
+    }
+
+    @Test(dataProvider="print")
+    public void test_print(LocalDateTime ldt, ZoneId zone, String expected) {
+        ZonedDateTime zdt = ldt.atZone(zone);
+        builder.appendZoneId();
+        String output = builder.toFormatter().format(zdt);
+        assertEquals(output, expected);
+    }
+
+    @Test(dataProvider="print")
+    public void test_print_pattern_VV(LocalDateTime ldt, ZoneId zone, String expected) {
+        ZonedDateTime zdt = ldt.atZone(zone);
+        builder.appendPattern("VV");
+        String output = builder.toFormatter().format(zdt);
+        assertEquals(output, expected);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_print_pattern_V1rejected() {
+        builder.appendPattern("V");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_print_pattern_V3rejected() {
+        builder.appendPattern("VVV");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_print_pattern_V4rejected() {
+        builder.appendPattern("VVVV");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_print_pattern_V5rejected() {
+        builder.appendPattern("VVVVV");
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="parseSuccess")
+    Object[][] data_parseSuccess() {
+        return new Object[][] {
+                {"Z", 1, -1, ZoneOffset.UTC},
+                {"UTC", 3, -1, ZoneOffset.UTC},
+                {"UT", 2, -1, ZoneOffset.UTC},
+                {"GMT", 3, -1, ZoneOffset.UTC},
+                {"UTC0", 4, -1, ZoneOffset.UTC},
+                {"UT0", 3, -1, ZoneOffset.UTC},
+                {"GMT0", 4, -1, ZoneOffset.UTC},
+
+                {"+00:00", 6, -1, ZoneOffset.UTC},
+                {"UTC+00:00", 9, -1, ZoneOffset.UTC},
+                {"UT+00:00", 8, -1, ZoneOffset.UTC},
+                {"GMT+00:00", 9, -1, ZoneOffset.UTC},
+                {"-00:00", 6, -1, ZoneOffset.UTC},
+                {"UTC-00:00", 9, -1, ZoneOffset.UTC},
+                {"UT-00:00", 8, -1, ZoneOffset.UTC},
+                {"GMT-00:00", 9, -1, ZoneOffset.UTC},
+
+                {"+01:30", 6, -1, ZoneOffset.ofHoursMinutes(1, 30)},
+                {"UTC+01:30", 9, -1, ZoneOffset.ofHoursMinutes(1, 30)},
+                {"UT+02:30", 8, -1, ZoneOffset.ofHoursMinutes(2, 30)},
+                {"GMT+03:30", 9, -1, ZoneOffset.ofHoursMinutes(3, 30)},
+                {"-01:30", 6, -1, ZoneOffset.ofHoursMinutes(-1, -30)},
+                {"UTC-01:30", 9, -1, ZoneOffset.ofHoursMinutes(-1, -30)},
+                {"UT-02:30", 8, -1, ZoneOffset.ofHoursMinutes(-2, -30)},
+                {"GMT-03:30", 9, -1, ZoneOffset.ofHoursMinutes(-3, -30)},
+
+                // fallback to UTC
+                {"UTC-01:WW", 3, -1, ZoneOffset.UTC},
+                {"UT-02:WW", 2, -1, ZoneOffset.UTC},
+                {"GMT-03:WW", 3, -1, ZoneOffset.UTC},
+                {"Z0", 1, -1, ZoneOffset.UTC},
+                {"UTC1", 3, -1, ZoneOffset.UTC},
+
+                // Z not parsed as zero
+                {"UTCZ", 3, -1, ZoneOffset.UTC},
+                {"UTZ", 2, -1, ZoneOffset.UTC},
+                {"GMTZ", 3, -1, ZoneOffset.UTC},
+
+                // fail to parse
+                {"", 0, 0, null},
+                {"A", 0, 0, null},
+                {"UZ", 0, 0, null},
+                {"GMA", 0, 0, null},
+                {"0", 0, 0, null},
+                {"+", 0, 0, null},
+                {"-", 0, 0, null},
+
+                // zone IDs
+                {"Europe/London", 13, -1, ZoneId.of("Europe/London")},
+                {"America/New_York", 16, -1, ZoneId.of("America/New_York")},
+                {"America/Bogusville", 0, 0, null},
+        };
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void test_parseSuccess_plain(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) {
+        builder.appendZoneId();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text, pos);
+        assertEquals(pos.getErrorIndex(), expectedErrorIndex);
+        assertEquals(pos.getIndex(), expectedIndex);
+        if (expected != null) {
+            assertEquals(parsed.query(Queries.zoneId()), expected);
+            assertEquals(parsed.query(Queries.offset()), null);
+            assertEquals(parsed.query(Queries.zone()), expected);
+        } else {
+            assertEquals(parsed, null);
+        }
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void test_parseSuccess_prefix(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) {
+        builder.appendZoneId();
+        pos.setIndex(3);
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved("XXX" + text, pos);
+        assertEquals(pos.getErrorIndex(), expectedErrorIndex >= 0  ? expectedErrorIndex + 3 : expectedErrorIndex);
+        assertEquals(pos.getIndex(), expectedIndex + 3);
+        if (expected != null) {
+            assertEquals(parsed.query(Queries.zoneId()), expected);
+            assertEquals(parsed.query(Queries.offset()), null);
+            assertEquals(parsed.query(Queries.zone()), expected);
+        } else {
+            assertEquals(parsed, null);
+        }
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void test_parseSuccess_suffix(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) {
+        builder.appendZoneId();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text + "XXX", pos);
+        assertEquals(pos.getErrorIndex(), expectedErrorIndex);
+        assertEquals(pos.getIndex(), expectedIndex);
+        if (expected != null) {
+            assertEquals(parsed.query(Queries.zoneId()), expected);
+            assertEquals(parsed.query(Queries.offset()), null);
+            assertEquals(parsed.query(Queries.zone()), expected);
+        } else {
+            assertEquals(parsed, null);
+        }
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void test_parseSuccess_caseSensitive(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) {
+        builder.parseCaseSensitive().appendZoneId();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text.toLowerCase(Locale.ENGLISH), pos);
+        if (text.matches("[^A-Z]*[A-Z].*")) {  // if input has letters
+            assertEquals(pos.getErrorIndex() >= 0, true);
+            assertEquals(pos.getIndex(), 0);
+            assertEquals(parsed, null);
+        } else {
+            // case sensitive made no difference
+            assertEquals(pos.getIndex(), expectedIndex);
+            assertEquals(pos.getErrorIndex(), expectedErrorIndex);
+            if (expected != null) {
+                assertEquals(parsed.query(Queries.zoneId()), expected);
+                assertEquals(parsed.query(Queries.offset()), null);
+                assertEquals(parsed.query(Queries.zone()), expected);
+            } else {
+                assertEquals(parsed, null);
+            }
+        }
+    }
+
+    @Test(dataProvider="parseSuccess")
+    public void test_parseSuccess_caseInsensitive(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) {
+        builder.parseCaseInsensitive().appendZoneId();
+        TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text.toLowerCase(Locale.ENGLISH), pos);
+        assertEquals(pos.getErrorIndex(), expectedErrorIndex);
+        assertEquals(pos.getIndex(), expectedIndex);
+        if (expected != null) {
+            assertEquals(parsed.query(Queries.zoneId()), expected);
+            assertEquals(parsed.query(Queries.offset()), null);
+            assertEquals(parsed.query(Queries.zone()), expected);
+        } else {
+            assertEquals(parsed, null);
+        }
+    }
+
+}
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKISOFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java
similarity index 65%
rename from jdk/test/java/time/tck/java/time/temporal/TCKISOFields.java
rename to jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java
index c3acbdb..359aac1 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKISOFields.java
+++ b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java
@@ -56,9 +56,6 @@
  */
 package tck.java.time.temporal;
 
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.*;
-
 import static java.time.DayOfWeek.FRIDAY;
 import static java.time.DayOfWeek.MONDAY;
 import static java.time.DayOfWeek.SATURDAY;
@@ -69,10 +66,13 @@
 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
 
 import java.time.DayOfWeek;
 import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.IsoFields;
+import java.time.temporal.ValueRange;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -81,7 +81,7 @@
  * Test.
  */
 @Test(groups={"tck"})
-public class TCKISOFields {
+public class TCKIsoFields {
 
     @DataProvider(name="quarter")
     Object[][] data_quarter() {
@@ -117,8 +117,8 @@
     //-----------------------------------------------------------------------
     @Test(dataProvider="quarter")
     public void test_DOQ(LocalDate date, int doq, int qoy) {
-        assertEquals(ISOFields.DAY_OF_QUARTER.doGet(date), doq);
-        assertEquals(date.get(ISOFields.DAY_OF_QUARTER), doq);
+        assertEquals(IsoFields.DAY_OF_QUARTER.getFrom(date), doq);
+        assertEquals(date.get(IsoFields.DAY_OF_QUARTER), doq);
     }
 
     //-----------------------------------------------------------------------
@@ -126,21 +126,61 @@
     //-----------------------------------------------------------------------
     @Test(dataProvider="quarter")
     public void test_QOY(LocalDate date, int doq, int qoy) {
-        assertEquals(ISOFields.QUARTER_OF_YEAR.doGet(date), qoy);
-        assertEquals(date.get(ISOFields.QUARTER_OF_YEAR), qoy);
+        assertEquals(IsoFields.QUARTER_OF_YEAR.getFrom(date), qoy);
+        assertEquals(date.get(IsoFields.QUARTER_OF_YEAR), qoy);
     }
 
     //-----------------------------------------------------------------------
-    // builder
+    // parse quarters
     //-----------------------------------------------------------------------
     @Test(dataProvider="quarter")
-    public void test_builder_quarters(LocalDate date, int doq, int qoy) {
-        DateTimeBuilder builder = new DateTimeBuilder();
-        builder.addFieldValue(ISOFields.DAY_OF_QUARTER, doq);
-        builder.addFieldValue(ISOFields.QUARTER_OF_YEAR, qoy);
-        builder.addFieldValue(YEAR, date.getYear());
-        builder.resolve();
-        assertEquals(builder.query(LocalDate::from), date);
+    public void test_parse_quarters(LocalDate date, int doq, int qoy) {
+        DateTimeFormatter f = new DateTimeFormatterBuilder()
+                .appendValue(YEAR).appendLiteral('-')
+                .appendValue(IsoFields.QUARTER_OF_YEAR).appendLiteral('-')
+                .appendValue(IsoFields.DAY_OF_QUARTER).toFormatter();
+        LocalDate parsed = LocalDate.parse(date.getYear() + "-" + qoy + "-" + doq, f);
+        assertEquals(parsed, date);
+    }
+
+    //-----------------------------------------------------------------------
+    // quarters between
+    //-----------------------------------------------------------------------
+    @DataProvider(name="quartersBetween")
+    Object[][] data_quartersBetween() {
+        return new Object[][] {
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 1), 0},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 2), 0},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 2, 1), 0},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 3, 1), 0},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 3, 31), 0},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 4, 1), 1},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 4, 2), 1},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 6, 30), 1},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 7, 1), 2},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 10, 1), 3},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 12, 31), 3},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2001, 1, 1), 4},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(2002, 1, 1), 8},
+
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 12, 31), 0},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 10, 2), 0},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 10, 1), -1},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 7, 2), -1},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 7, 1), -2},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 4, 2), -2},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 4, 1), -3},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 1, 2), -3},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 1, 1), -4},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 12, 31), -4},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 2), -4},
+                {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 1), -5},
+        };
+    }
+
+    @Test(dataProvider="quartersBetween")
+    public void test_quarters_between(LocalDate start, LocalDate end, long expected) {
+        assertEquals(IsoFields.QUARTER_YEARS.between(start, end), expected);
     }
 
     //-----------------------------------------------------------------------
@@ -170,8 +210,8 @@
     @Test(dataProvider="week")
     public void test_WOWBY(LocalDate date, DayOfWeek dow, int week, int wby) {
         assertEquals(date.getDayOfWeek(), dow);
-        assertEquals(ISOFields.WEEK_OF_WEEK_BASED_YEAR.doGet(date), week);
-        assertEquals(date.get(ISOFields.WEEK_OF_WEEK_BASED_YEAR), week);
+        assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.getFrom(date), week);
+        assertEquals(date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR), week);
     }
 
     //-----------------------------------------------------------------------
@@ -180,21 +220,21 @@
     @Test(dataProvider="week")
     public void test_WBY(LocalDate date, DayOfWeek dow, int week, int wby) {
         assertEquals(date.getDayOfWeek(), dow);
-        assertEquals(ISOFields.WEEK_BASED_YEAR.doGet(date), wby);
-        assertEquals(date.get(ISOFields.WEEK_BASED_YEAR), wby);
+        assertEquals(IsoFields.WEEK_BASED_YEAR.getFrom(date), wby);
+        assertEquals(date.get(IsoFields.WEEK_BASED_YEAR), wby);
     }
 
     //-----------------------------------------------------------------------
-    // builder
+    // parse weeks
     //-----------------------------------------------------------------------
     @Test(dataProvider="week")
-    public void test_builder_weeks(LocalDate date, DayOfWeek dow, int week, int wby) {
-        DateTimeBuilder builder = new DateTimeBuilder();
-        builder.addFieldValue(ISOFields.WEEK_BASED_YEAR, wby);
-        builder.addFieldValue(ISOFields.WEEK_OF_WEEK_BASED_YEAR, week);
-        builder.addFieldValue(DAY_OF_WEEK, dow.getValue());
-        builder.resolve();
-        assertEquals(builder.query(LocalDate::from), date);
+    public void test_parse_weeks(LocalDate date, DayOfWeek dow, int week, int wby) {
+        DateTimeFormatter f = new DateTimeFormatterBuilder()
+                .appendValue(IsoFields.WEEK_BASED_YEAR).appendLiteral('-')
+                .appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR).appendLiteral('-')
+                .appendValue(DAY_OF_WEEK).toFormatter();
+        LocalDate parsed = LocalDate.parse(wby + "-" + week + "-" + dow.getValue(), f);
+        assertEquals(parsed, date);
     }
 
     //-----------------------------------------------------------------------
@@ -220,11 +260,11 @@
                     wby++;
                 }
             }
-            assertEquals(ISOFields.WEEK_OF_WEEK_BASED_YEAR.doRange(date), ValueRange.of(1, weekLen), "Failed on " + date + " " + date.getDayOfWeek());
-            assertEquals(ISOFields.WEEK_OF_WEEK_BASED_YEAR.doGet(date), week, "Failed on " + date + " " + date.getDayOfWeek());
-            assertEquals(date.get(ISOFields.WEEK_OF_WEEK_BASED_YEAR), week, "Failed on " + date + " " + date.getDayOfWeek());
-            assertEquals(ISOFields.WEEK_BASED_YEAR.doGet(date), wby, "Failed on " + date + " " + date.getDayOfWeek());
-            assertEquals(date.get(ISOFields.WEEK_BASED_YEAR), wby, "Failed on " + date + " " + date.getDayOfWeek());
+            assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.rangeRefinedBy(date), ValueRange.of(1, weekLen), "Failed on " + date + " " + date.getDayOfWeek());
+            assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.getFrom(date), week, "Failed on " + date + " " + date.getDayOfWeek());
+            assertEquals(date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR), week, "Failed on " + date + " " + date.getDayOfWeek());
+            assertEquals(IsoFields.WEEK_BASED_YEAR.getFrom(date), wby, "Failed on " + date + " " + date.getDayOfWeek());
+            assertEquals(date.get(IsoFields.WEEK_BASED_YEAR), wby, "Failed on " + date + " " + date.getDayOfWeek());
             date = date.plusDays(1);
         }
     }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java
index 81e8109..94399e0 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java
+++ b/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java
@@ -60,38 +60,30 @@
 package tck.java.time.temporal;
 
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertSame;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
 import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoField;
+import java.time.temporal.JulianFields;
+import java.time.temporal.TemporalField;
 
-import java.time.temporal.*;
-
-
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
 
 /**
  * Test.
  */
 @Test
-public class TCKJulianFields {
+public class TCKJulianFields extends AbstractTCKTest {
 
     private static final LocalDate JAN01_1970 = LocalDate.of(1970, 1, 1);
     private static final LocalDate DEC31_1969 = LocalDate.of(1969, 12, 31);
     private static final LocalDate NOV12_1945 = LocalDate.of(1945, 11, 12);
     private static final LocalDate JAN01_0001 = LocalDate.of(1, 1, 1);
 
-    @BeforeMethod
-    public void setUp() {
-    }
-
     //-----------------------------------------------------------------------
     @DataProvider(name="julian_fields")
     Object[][] julian_samples() {
@@ -127,42 +119,33 @@
         };
     }
 
-    @Test(dataProvider="samples", groups={"tck"})
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="julian_fields")
+    public void test_serializable(TemporalField field) throws IOException, ClassNotFoundException {
+        assertSerializable(field);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="samples")
     public void test_samples_get(TemporalField field, LocalDate date, long expected) {
         assertEquals(date.getLong(field), expected);
     }
 
-    @Test(dataProvider="samples", groups={"tck"})
+    @Test(dataProvider="samples")
     public void test_samples_set(TemporalField field, LocalDate date, long value) {
-        assertEquals(field.doWith(LocalDate.MAX, value), date);
-        assertEquals(field.doWith(LocalDate.MIN, value), date);
-        assertEquals(field.doWith(JAN01_1970, value), date);
-        assertEquals(field.doWith(DEC31_1969, value), date);
-        assertEquals(field.doWith(NOV12_1945, value), date);
+        assertEquals(field.adjustInto(LocalDate.MAX, value), date);
+        assertEquals(field.adjustInto(LocalDate.MIN, value), date);
+        assertEquals(field.adjustInto(JAN01_1970, value), date);
+        assertEquals(field.adjustInto(DEC31_1969, value), date);
+        assertEquals(field.adjustInto(NOV12_1945, value), date);
     }
 
     //-----------------------------------------------------------------------
-    // toString()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_toString() {
-        assertEquals(JulianFields.JULIAN_DAY.toString(), "JulianDay");
-        assertEquals(JulianFields.MODIFIED_JULIAN_DAY.toString(), "ModifiedJulianDay");
-        assertEquals(JulianFields.RATA_DIE.toString(), "RataDie");
-    }
-
-    @Test(groups = {"tck"},dataProvider="julian_fields")
-    public void test_JulianFieldsSingleton(TemporalField field) throws IOException, ClassNotFoundException {
-        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                ObjectOutputStream oos = new ObjectOutputStream(baos)) {
-            oos.writeObject(field);
-
-            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
-                    baos.toByteArray()));
-            TemporalField result = (TemporalField)ois.readObject();
-            assertSame(result, field, "Deserialized object same as serialized.");
-        }
-        // Exceptions will be handled as failures by TestNG
+    @Test(dataProvider="samples")
+    public void test_samples_parse(TemporalField field, LocalDate date, long value) {
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter();
+        LocalDate parsed = LocalDate.parse(Long.toString(value), f);
+        assertEquals(parsed, date);
     }
 
 }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKOffsetDate.java b/jdk/test/java/time/tck/java/time/temporal/TCKOffsetDate.java
deleted file mode 100644
index 7772022..0000000
--- a/jdk/test/java/time/tck/java/time/temporal/TCKOffsetDate.java
+++ /dev/null
@@ -1,1949 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
-9 * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package tck.java.time.temporal;
-
-import static java.time.Month.DECEMBER;
-import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
-import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
-import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
-import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.DAY_OF_WEEK;
-import static java.time.temporal.ChronoField.DAY_OF_YEAR;
-import static java.time.temporal.ChronoField.EPOCH_DAY;
-import static java.time.temporal.ChronoField.EPOCH_MONTH;
-import static java.time.temporal.ChronoField.ERA;
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.OFFSET_SECONDS;
-import static java.time.temporal.ChronoField.YEAR;
-import static java.time.temporal.ChronoField.YEAR_OF_ERA;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.Month;
-import java.time.Period;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
-import java.time.format.DateTimeParseException;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.ISOChrono;
-import java.time.temporal.JulianFields;
-import java.time.temporal.OffsetDate;
-import java.time.temporal.OffsetDateTime;
-import java.time.temporal.Queries;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
-import java.time.temporal.TemporalAdjuster;
-import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.Year;
-
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-import tck.java.time.AbstractDateTimeTest;
-import test.java.time.MockSimplePeriod;
-
-/**
- * Test OffsetDate.
- */
-@Test
-public class TCKOffsetDate extends AbstractDateTimeTest {
-    private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
-    private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
-
-    private OffsetDate TEST_2007_07_15_PONE;
-
-    @BeforeMethod(groups={"tck","implementation"})
-    public void setUp() {
-        TEST_2007_07_15_PONE = OffsetDate.of(LocalDate.of(2007, 7, 15), OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    protected List<TemporalAccessor> samples() {
-        TemporalAccessor[] array = {TEST_2007_07_15_PONE, OffsetDate.MIN, OffsetDate.MAX};
-        return Arrays.asList(array);
-    }
-
-    @Override
-    protected List<TemporalField> validFields() {
-        TemporalField[] array = {
-            DAY_OF_WEEK,
-            ALIGNED_DAY_OF_WEEK_IN_MONTH,
-            ALIGNED_DAY_OF_WEEK_IN_YEAR,
-            DAY_OF_MONTH,
-            DAY_OF_YEAR,
-            EPOCH_DAY,
-            ALIGNED_WEEK_OF_MONTH,
-            ALIGNED_WEEK_OF_YEAR,
-            MONTH_OF_YEAR,
-            EPOCH_MONTH,
-            YEAR_OF_ERA,
-            YEAR,
-            ERA,
-            OFFSET_SECONDS,
-            JulianFields.JULIAN_DAY,
-            JulianFields.MODIFIED_JULIAN_DAY,
-            JulianFields.RATA_DIE,
-        };
-        return Arrays.asList(array);
-    }
-
-    @Override
-    protected List<TemporalField> invalidFields() {
-        List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
-        list.removeAll(validFields());
-        return list;
-    }
-
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws ClassNotFoundException, IOException {
-        assertSerializable(TEST_2007_07_15_PONE);
-        assertSerializable(OffsetDate.MIN);
-        assertSerializable(OffsetDate.MAX);
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(1);
-        }
-        byte[] bytes = baos.toByteArray();
-        ByteArrayOutputStream baosDate = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baosDate) ) {
-            dos.writeByte(3);
-            dos.writeInt(2012);
-            dos.writeByte(9);
-            dos.writeByte(16);
-        }
-        byte[] bytesDate = baosDate.toByteArray();
-        ByteArrayOutputStream baosOffset = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baosOffset) ) {
-            dos.writeByte(8);
-            dos.writeByte(4);  // quarter hours stored: 3600 / 900
-        }
-        byte[] bytesOffset = baosOffset.toByteArray();
-        assertSerializedBySer(OffsetDate.of(LocalDate.of(2012, 9, 16), ZoneOffset.ofHours(1)), bytes,
-                bytesDate, bytesOffset);
-    }
-
-    //-----------------------------------------------------------------------
-    // constants
-    //-----------------------------------------------------------------------
-    @Test
-    public void constant_MIN() {
-        check(OffsetDate.MIN, Year.MIN_VALUE, 1, 1, ZoneOffset.MAX);
-    }
-
-    @Test
-    public void constant_MAX() {
-        check(OffsetDate.MAX, Year.MAX_VALUE, 12, 31, ZoneOffset.MIN);
-    }
-
-    //-----------------------------------------------------------------------
-    // now()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void now() {
-        OffsetDate expected = OffsetDate.now(Clock.systemDefaultZone());
-        OffsetDate test = OffsetDate.now();
-        for (int i = 0; i < 100; i++) {
-            if (expected.equals(test)) {
-                return;
-            }
-            expected = OffsetDate.now(Clock.systemDefaultZone());
-            test = OffsetDate.now();
-        }
-        assertEquals(test, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void now_Clock_allSecsInDay_utc() {
-        for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
-            Instant instant = Instant.ofEpochSecond(i);
-            Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
-            OffsetDate test = OffsetDate.now(clock);
-            check(test, 1970, 1, (i < 24 * 60 * 60 ? 1 : 2), ZoneOffset.UTC);
-        }
-    }
-
-    @Test(groups={"tck"})
-    public void now_Clock_allSecsInDay_beforeEpoch() {
-        for (int i =-1; i >= -(2 * 24 * 60 * 60); i--) {
-            Instant instant = Instant.ofEpochSecond(i);
-            Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
-            OffsetDate test = OffsetDate.now(clock);
-            check(test, 1969, 12, (i >= -24 * 60 * 60 ? 31 : 30), ZoneOffset.UTC);
-        }
-    }
-
-    @Test(groups={"tck"})
-    public void now_Clock_offsets() {
-        Instant base = LocalDateTime.of(1970, 1, 1, 12, 0).toInstant(ZoneOffset.UTC);
-        for (int i = -9; i < 15; i++) {
-            ZoneOffset offset = ZoneOffset.ofHours(i);
-            Clock clock = Clock.fixed(base, offset);
-            OffsetDate test = OffsetDate.now(clock);
-            check(test, 1970, 1, (i >= 12 ? 2 : 1), offset);
-        }
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void now_Clock_nullZoneId() {
-        OffsetDate.now((ZoneId) null);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void now_Clock_nullClock() {
-        OffsetDate.now((Clock) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // factories
-    //-----------------------------------------------------------------------
-    private void check(OffsetDate test, int y, int mo, int d, ZoneOffset offset) {
-        assertEquals(test.getDate(), LocalDate.of(y, mo, d));
-        assertEquals(test.getOffset(), offset);
-
-        assertEquals(test.getYear(), y);
-        assertEquals(test.getMonth().getValue(), mo);
-        assertEquals(test.getDayOfMonth(), d);
-
-        assertEquals(test, test);
-        assertEquals(test.hashCode(), test.hashCode());
-        assertEquals(OffsetDate.of(LocalDate.of(y, mo, d), offset), test);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_intMonthInt() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(2007, Month.JULY, 15), OFFSET_PONE);
-        check(test, 2007, 7, 15, OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_ints() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(2007, 7, 15), OFFSET_PONE);
-        check(test, 2007, 7, 15, OFFSET_PONE);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_intsMonthOffset() {
-        assertEquals(TEST_2007_07_15_PONE, OffsetDate.of(LocalDate.of(2007, Month.JULY, 15), OFFSET_PONE));
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_of_intsMonthOffset_dayTooLow() {
-        OffsetDate.of(LocalDate.of(2007, Month.JANUARY, 0), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_of_intsMonthOffset_dayTooHigh() {
-        OffsetDate.of(LocalDate.of(2007, Month.JANUARY, 32), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_of_intsMonthOffset_nullMonth() {
-        OffsetDate.of(LocalDate.of(2007, null, 30), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_of_intsMonthOffset_yearTooLow() {
-        OffsetDate.of(LocalDate.of(Integer.MIN_VALUE, Month.JANUARY, 1), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_of_intsMonthOffset_nullOffset() {
-        OffsetDate.of(LocalDate.of(2007, Month.JANUARY, 30), null);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_intsOffset() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(2007, 7, 15), OFFSET_PONE);
-        check(test, 2007, 7, 15, OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_of_ints_dayTooLow() {
-        OffsetDate.of(LocalDate.of(2007, 1, 0), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_of_ints_dayTooHigh() {
-        OffsetDate.of(LocalDate.of(2007, 1, 32), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_of_ints_monthTooLow() {
-        OffsetDate.of(LocalDate.of(2007, 0, 1), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_of_ints_monthTooHigh() {
-        OffsetDate.of(LocalDate.of(2007, 13, 1), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void factory_of_ints_yearTooLow() {
-        OffsetDate.of(LocalDate.of(Integer.MIN_VALUE, 1, 1), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_of_ints_nullOffset() {
-        OffsetDate.of(LocalDate.of(2007, 1, 1), (ZoneOffset) null);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_of_LocalDateZoneOffset() {
-        LocalDate localDate = LocalDate.of(2008, 6, 30);
-        OffsetDate test = OffsetDate.of(localDate, OFFSET_PONE);
-        check(test, 2008, 6, 30, OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_of_LocalDateZoneOffset_nullDate() {
-        OffsetDate.of((LocalDate) null, OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_of_LocalDateZoneOffset_nullOffset() {
-        LocalDate localDate = LocalDate.of(2008, 6, 30);
-        OffsetDate.of(localDate, (ZoneOffset) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // from(TemporalAccessor)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_from_TemporalAccessor_OD() {
-        assertEquals(OffsetDate.from(TEST_2007_07_15_PONE), TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_from_TemporalAccessor_ZDT() {
-        ZonedDateTime base = LocalDateTime.of(2007, 7, 15, 17, 30).atZone(OFFSET_PONE);
-        assertEquals(OffsetDate.from(base), TEST_2007_07_15_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_from_TemporalAccessor_invalid_noDerive() {
-        OffsetDate.from(LocalTime.of(12, 30));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_from_TemporalAccessor_null() {
-        OffsetDate.from((TemporalAccessor) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // parse()
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="sampleToString", groups={"tck"})
-    public void factory_parse_validText(int y, int m, int d, String offsetId, String parsable) {
-        OffsetDate t = OffsetDate.parse(parsable);
-        assertNotNull(t, parsable);
-        assertEquals(t.getYear(), y, parsable);
-        assertEquals(t.getMonth().getValue(), m, parsable);
-        assertEquals(t.getDayOfMonth(), d, parsable);
-        assertEquals(t.getOffset(), ZoneOffset.of(offsetId));
-    }
-
-    @DataProvider(name="sampleBadParse")
-    Object[][] provider_sampleBadParse() {
-        return new Object[][]{
-                {"2008/07/05"},
-                {"10000-01-01"},
-                {"2008-1-1"},
-                {"2008--01"},
-                {"ABCD-02-01"},
-                {"2008-AB-01"},
-                {"2008-02-AB"},
-                {"-0000-02-01"},
-                {"2008-02-01Y"},
-                {"2008-02-01+19:00"},
-                {"2008-02-01+01/00"},
-                {"2008-02-01+1900"},
-                {"2008-02-01+01:60"},
-                {"2008-02-01+01:30:123"},
-                {"2008-02-01"},
-                {"2008-02-01+01:00[Europe/Paris]"},
-        };
-    }
-
-    @Test(dataProvider="sampleBadParse", expectedExceptions=DateTimeParseException.class, groups={"tck"})
-    public void factory_parse_invalidText(String unparsable) {
-        OffsetDate.parse(unparsable);
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class, groups={"tck"})
-    public void factory_parse_illegalValue() {
-        OffsetDate.parse("2008-06-32+01:00");
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class, groups={"tck"})
-    public void factory_parse_invalidValue() {
-        OffsetDate.parse("2008-06-31+01:00");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_parse_nullText() {
-        OffsetDate.parse((String) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // parse(DateTimeFormatter)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void factory_parse_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d XXX");
-        OffsetDate test = OffsetDate.parse("2010 12 3 +01:00", f);
-        assertEquals(test, OffsetDate.of(LocalDate.of(2010, 12, 3), ZoneOffset.ofHours(1)));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_parse_formatter_nullText() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d");
-        OffsetDate.parse((String) null, f);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void factory_parse_formatter_nullFormatter() {
-        OffsetDate.parse("ANY", null);
-    }
-
-    //-----------------------------------------------------------------------
-    // constructor
-    //-----------------------------------------------------------------------
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void constructor_nullDate() throws Throwable  {
-        Constructor<OffsetDate> con = OffsetDate.class.getDeclaredConstructor(LocalDate.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(null, OFFSET_PONE);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void constructor_nullOffset() throws Throwable  {
-        Constructor<OffsetDate> con = OffsetDate.class.getDeclaredConstructor(LocalDate.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(LocalDate.of(2008, 6, 30), null);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    // basics
-    //-----------------------------------------------------------------------
-    @DataProvider(name="sampleDates")
-    Object[][] provider_sampleDates() {
-        return new Object[][] {
-            {2008, 7, 5, OFFSET_PTWO},
-            {2007, 7, 5, OFFSET_PONE},
-            {2006, 7, 5, OFFSET_PTWO},
-            {2005, 7, 5, OFFSET_PONE},
-            {2004, 1, 1, OFFSET_PTWO},
-            {-1, 1, 2, OFFSET_PONE},
-            {999999, 11, 20, ZoneOffset.ofHoursMinutesSeconds(6, 9, 12)},
-        };
-    }
-
-    @Test(dataProvider="sampleDates", groups={"tck"})
-    public void test_get_OffsetDate(int y, int m, int d, ZoneOffset offset) {
-        LocalDate localDate = LocalDate.of(y, m, d);
-        OffsetDate a = OffsetDate.of(localDate, offset);
-
-        assertEquals(a.getDate(), localDate);
-        assertEquals(a.getOffset(), offset);
-        assertEquals(a.toString(), localDate.toString() + offset.toString());
-        assertEquals(a.getYear(), localDate.getYear());
-        assertEquals(a.getMonth(), localDate.getMonth());
-        assertEquals(a.getDayOfMonth(), localDate.getDayOfMonth());
-        assertEquals(a.getDayOfYear(), localDate.getDayOfYear());
-        assertEquals(a.getDayOfWeek(), localDate.getDayOfWeek());
-    }
-
-    //-----------------------------------------------------------------------
-    // get(TemporalField)
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_get_TemporalField() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        assertEquals(test.get(ChronoField.YEAR), 2008);
-        assertEquals(test.get(ChronoField.MONTH_OF_YEAR), 6);
-        assertEquals(test.get(ChronoField.DAY_OF_MONTH), 30);
-        assertEquals(test.get(ChronoField.DAY_OF_WEEK), 1);
-        assertEquals(test.get(ChronoField.DAY_OF_YEAR), 182);
-
-        assertEquals(test.get(ChronoField.OFFSET_SECONDS), 3600);
-    }
-
-    @Test
-    public void test_getLong_TemporalField() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        assertEquals(test.getLong(ChronoField.YEAR), 2008);
-        assertEquals(test.getLong(ChronoField.MONTH_OF_YEAR), 6);
-        assertEquals(test.getLong(ChronoField.DAY_OF_MONTH), 30);
-        assertEquals(test.getLong(ChronoField.DAY_OF_WEEK), 1);
-        assertEquals(test.getLong(ChronoField.DAY_OF_YEAR), 182);
-
-        assertEquals(test.getLong(ChronoField.OFFSET_SECONDS), 3600);
-    }
-
-    //-----------------------------------------------------------------------
-    // query(TemporalQuery)
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_query_chrono() {
-        assertEquals(TEST_2007_07_15_PONE.query(Queries.chrono()), ISOChrono.INSTANCE);
-        assertEquals(Queries.chrono().queryFrom(TEST_2007_07_15_PONE), ISOChrono.INSTANCE);
-    }
-
-    @Test
-    public void test_query_zoneId() {
-        assertEquals(TEST_2007_07_15_PONE.query(Queries.zoneId()), null);
-        assertEquals(Queries.zoneId().queryFrom(TEST_2007_07_15_PONE), null);
-    }
-
-    @Test
-    public void test_query_precision() {
-        assertEquals(TEST_2007_07_15_PONE.query(Queries.precision()), ChronoUnit.DAYS);
-        assertEquals(Queries.precision().queryFrom(TEST_2007_07_15_PONE), ChronoUnit.DAYS);
-    }
-
-    @Test
-    public void test_query_offset() {
-        assertEquals(TEST_2007_07_15_PONE.query(Queries.offset()), OFFSET_PONE);
-        assertEquals(Queries.offset().queryFrom(TEST_2007_07_15_PONE), OFFSET_PONE);
-    }
-
-    @Test
-    public void test_query_zone() {
-        assertEquals(TEST_2007_07_15_PONE.query(Queries.zone()), OFFSET_PONE);
-        assertEquals(Queries.zone().queryFrom(TEST_2007_07_15_PONE), OFFSET_PONE);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_query_null() {
-        TEST_2007_07_15_PONE.query(null);
-    }
-
-    //-----------------------------------------------------------------------
-    // withOffset()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_withOffset() {
-        OffsetDate base = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        OffsetDate test = base.withOffset(OFFSET_PTWO);
-        assertEquals(test.getDate(), base.getDate());
-        assertEquals(test.getOffset(), OFFSET_PTWO);
-    }
-
-    @Test(groups={"tck"})
-    public void test_withOffset_noChange() {
-        OffsetDate base = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        OffsetDate test = base.withOffset(OFFSET_PONE);
-        assertEquals(test, base);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_withOffset_null() {
-        TEST_2007_07_15_PONE.withOffset(null);
-    }
-
-    //-----------------------------------------------------------------------
-    // with(WithAdjuster)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_with_adjustment() {
-        final OffsetDate sample = OffsetDate.of(LocalDate.of(2012, 3, 4), OFFSET_PONE);
-        TemporalAdjuster adjuster = new TemporalAdjuster() {
-            @Override
-            public Temporal adjustInto(Temporal dateTime) {
-                return sample;
-            }
-        };
-        assertEquals(TEST_2007_07_15_PONE.with(adjuster), sample);
-    }
-
-    @Test(groups={"tck"})
-    public void test_with_adjustment_LocalDate() {
-        OffsetDate test = TEST_2007_07_15_PONE.with(LocalDate.of(2008, 6, 30));
-        assertEquals(test, OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_with_adjustment_OffsetDate() {
-        OffsetDate test = TEST_2007_07_15_PONE.with(OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PTWO));
-        assertEquals(test, OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PTWO));
-    }
-
-    @Test(groups={"tck"})
-    public void test_with_adjustment_ZoneOffset() {
-        OffsetDate test = TEST_2007_07_15_PONE.with(OFFSET_PTWO);
-        assertEquals(test, OffsetDate.of(LocalDate.of(2007, 7, 15), OFFSET_PTWO));
-    }
-
-    @Test(groups={"tck"})
-    public void test_with_adjustment_Month() {
-        OffsetDate test = TEST_2007_07_15_PONE.with(DECEMBER);
-        assertEquals(test, OffsetDate.of(LocalDate.of(2007, 12, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_with_adjustment_offsetUnchanged() {
-        OffsetDate base = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        OffsetDate test = base.with(Year.of(2008));
-        assertEquals(test, base);
-    }
-
-    @Test(groups={"tck"})
-    public void test_with_adjustment_noChange() {
-        LocalDate date = LocalDate.of(2008, 6, 30);
-        OffsetDate base = OffsetDate.of(date, OFFSET_PONE);
-        OffsetDate test = base.with(date);
-        assertEquals(test, base);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_with_adjustment_null() {
-        TEST_2007_07_15_PONE.with((TemporalAdjuster) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // with(TemporalField, long)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_with_TemporalField() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        assertEquals(test.with(ChronoField.YEAR, 2009), OffsetDate.of(LocalDate.of(2009, 6, 30), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.MONTH_OF_YEAR, 7), OffsetDate.of(LocalDate.of(2008, 7, 30), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.DAY_OF_MONTH, 1), OffsetDate.of(LocalDate.of(2008, 6, 1), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.DAY_OF_WEEK, 2), OffsetDate.of(LocalDate.of(2008, 7, 1), OFFSET_PONE));
-        assertEquals(test.with(ChronoField.DAY_OF_YEAR, 183), OffsetDate.of(LocalDate.of(2008, 7, 1), OFFSET_PONE));
-
-        assertEquals(test.with(ChronoField.OFFSET_SECONDS, 7205), OffsetDate.of(LocalDate.of(2008, 6, 30), ZoneOffset.ofHoursMinutesSeconds(2, 0, 5)));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"} )
-    public void test_with_TemporalField_null() {
-        TEST_2007_07_15_PONE.with((TemporalField) null, 0);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"} )
-    public void test_with_TemporalField_invalidField() {
-        TEST_2007_07_15_PONE.with(ChronoField.AMPM_OF_DAY, 0);
-    }
-
-    //-----------------------------------------------------------------------
-    // withYear()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_withYear_int_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.withYear(2008);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2008, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_withYear_int_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.withYear(2007);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_withYear_int_invalid() {
-        TEST_2007_07_15_PONE.withYear(Year.MIN_VALUE - 1);
-    }
-
-    @Test(groups={"tck"})
-    public void test_withYear_int_adjustDay() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PONE).withYear(2007);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(2007, 2, 28), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    //-----------------------------------------------------------------------
-    // withMonth()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_withMonth_int_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.withMonth(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 1, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_withMonth_int_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.withMonth(7);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_withMonth_int_invalid() {
-        TEST_2007_07_15_PONE.withMonth(13);
-    }
-
-    @Test(groups={"tck"})
-    public void test_withMonth_int_adjustDay() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2007, 12, 31), OFFSET_PONE).withMonth(11);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(2007, 11, 30), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    //-----------------------------------------------------------------------
-    // withDayOfMonth()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_withDayOfMonth_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.withDayOfMonth(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 1), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_withDayOfMonth_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.withDayOfMonth(15);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_withDayOfMonth_invalidForMonth() {
-        OffsetDate.of(LocalDate.of(2007, 11, 30), OFFSET_PONE).withDayOfMonth(31);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_withDayOfMonth_invalidAlways() {
-        OffsetDate.of(LocalDate.of(2007, 11, 30), OFFSET_PONE).withDayOfMonth(32);
-    }
-
-    //-----------------------------------------------------------------------
-    // withDayOfYear(int)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_withDayOfYear_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.withDayOfYear(33);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 2, 2), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_withDayOfYear_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.withDayOfYear(31 + 28 + 31 + 30 + 31 + 30 + 15);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_withDayOfYear_illegal() {
-        TEST_2007_07_15_PONE.withDayOfYear(367);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_withDayOfYear_invalid() {
-        TEST_2007_07_15_PONE.withDayOfYear(366);
-    }
-
-    //-----------------------------------------------------------------------
-    // plus(PlusAdjuster)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_plus_PlusAdjuster() {
-        MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
-        OffsetDate t = TEST_2007_07_15_PONE.plus(period);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2008, 2, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plus_PlusAdjuster_noChange() {
-        MockSimplePeriod period = MockSimplePeriod.of(0, ChronoUnit.MONTHS);
-        OffsetDate t = TEST_2007_07_15_PONE.plus(period);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plus_PlusAdjuster_zero() {
-        OffsetDate t = TEST_2007_07_15_PONE.plus(Period.ZERO);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_plus_PlusAdjuster_null() {
-        TEST_2007_07_15_PONE.plus((TemporalAdder) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusYears()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_plusYears_long_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusYears(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2008, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusYears_long_negative() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusYears(-1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2006, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusYears_long_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusYears(0);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusYears_long_adjustDay() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PONE).plusYears(1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(2009, 2, 28), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusYears_long_big() {
-        long years = 20L + Year.MAX_VALUE;
-        OffsetDate test = OffsetDate.of(LocalDate.of(-40, 6, 1), OFFSET_PONE).plusYears(years);
-        assertEquals(test, OffsetDate.of(LocalDate.of((int) (-40L + years), 6, 1), OFFSET_PONE));
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_plusYears_long_invalidTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 1, 1), OFFSET_PONE).plusYears(1);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_plusYears_long_invalidTooLargeMaxAddMax() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE);
-        test.plusYears(Long.MAX_VALUE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_plusYears_long_invalidTooLargeMaxAddMin() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE);
-        test.plusYears(Long.MIN_VALUE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_plusYears_long_invalidTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE).plusYears(-1);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusMonths()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusMonths(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 8, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_overYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusMonths(25);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2009, 8, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_negative() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusMonths(-1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 6, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_negativeAcrossYear() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusMonths(-7);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2006, 12, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_negativeOverYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusMonths(-31);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2004, 12, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusMonths(0);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_adjustDayFromLeapYear() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PONE).plusMonths(12);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(2009, 2, 28), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_adjustDayFromMonthLength() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2007, 3, 31), OFFSET_PONE).plusMonths(1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(2007, 4, 30), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusMonths_long_big() {
-        long months = 20L + Integer.MAX_VALUE;
-        OffsetDate test = OffsetDate.of(LocalDate.of(-40, 6, 1), OFFSET_PONE).plusMonths(months);
-        assertEquals(test, OffsetDate.of(LocalDate.of((int) (-40L + months / 12), 6 + (int) (months % 12), 1), OFFSET_PONE));
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_plusMonths_long_invalidTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE).plusMonths(1);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_plusMonths_long_invalidTooLargeMaxAddMax() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE);
-        test.plusMonths(Long.MAX_VALUE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_plusMonths_long_invalidTooLargeMaxAddMin() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE);
-        test.plusMonths(Long.MIN_VALUE);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_plusMonths_long_invalidTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE).plusMonths(-1);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusWeeks()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="samplePlusWeeksSymmetry")
-    Object[][] provider_samplePlusWeeksSymmetry() {
-        return new Object[][] {
-            {OffsetDate.of(LocalDate.of(-1, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(-1, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(-1, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(-1, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(0, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 2, 29), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(0, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2007, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2007, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2007, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2007, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2008, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2008, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2099, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2099, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2099, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2099, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2100, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2100, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2100, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2100, 12, 31), OFFSET_PTWO)},
-        };
-    }
-
-    @Test(dataProvider="samplePlusWeeksSymmetry", groups={"tck"})
-    public void test_plusWeeks_symmetry(OffsetDate reference) {
-        for (int weeks = 0; weeks < 365 * 8; weeks++) {
-            OffsetDate t = reference.plusWeeks(weeks).plusWeeks(-weeks);
-            assertEquals(t, reference);
-
-            t = reference.plusWeeks(-weeks).plusWeeks(weeks);
-            assertEquals(t, reference);
-        }
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusWeeks(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 22), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_overMonths() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusWeeks(9);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 9, 16), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_overYears() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2006, 7, 16), OFFSET_PONE).plusWeeks(52);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_overLeapYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusYears(-1).plusWeeks(104);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2008, 7, 12), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_negative() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusWeeks(-1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 8), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_negativeAcrossYear() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusWeeks(-28);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2006, 12, 31), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_negativeOverYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusWeeks(-104);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2005, 7, 17), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusWeeks(0);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_maximum() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 24), OFFSET_PONE).plusWeeks(1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 31), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusWeeks_minimum() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 8), OFFSET_PONE).plusWeeks(-1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_plusWeeks_invalidTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 25), OFFSET_PONE).plusWeeks(1);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_plusWeeks_invalidTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 7), OFFSET_PONE).plusWeeks(-1);
-    }
-
-    @Test(expectedExceptions={ArithmeticException.class}, groups={"tck"})
-    public void test_plusWeeks_invalidMaxMinusMax() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 25), OFFSET_PONE).plusWeeks(Long.MAX_VALUE);
-    }
-
-    @Test(expectedExceptions={ArithmeticException.class}, groups={"tck"})
-    public void test_plusWeeks_invalidMaxMinusMin() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 25), OFFSET_PONE).plusWeeks(Long.MIN_VALUE);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusDays()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="samplePlusDaysSymmetry")
-    Object[][] provider_samplePlusDaysSymmetry() {
-        return new Object[][] {
-            {OffsetDate.of(LocalDate.of(-1, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(-1, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(-1, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(-1, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(0, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 2, 29), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(0, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2007, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2007, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2007, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2007, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2008, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2008, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2099, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2099, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2099, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2099, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2100, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2100, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2100, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2100, 12, 31), OFFSET_PTWO)},
-        };
-    }
-
-    @Test(dataProvider="samplePlusDaysSymmetry", groups={"tck"})
-    public void test_plusDays_symmetry(OffsetDate reference) {
-        for (int days = 0; days < 365 * 8; days++) {
-            OffsetDate t = reference.plusDays(days).plusDays(-days);
-            assertEquals(t, reference);
-
-            t = reference.plusDays(-days).plusDays(days);
-            assertEquals(t, reference);
-        }
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusDays(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 16), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_overMonths() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusDays(62);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 9, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_overYears() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2006, 7, 14), OFFSET_PONE).plusDays(366);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_overLeapYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusYears(-1).plusDays(365 + 366);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2008, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_negative() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusDays(-1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 14), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_negativeAcrossYear() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusDays(-196);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2006, 12, 31), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_negativeOverYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusDays(-730);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2005, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusDays(0);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_maximum() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 30), OFFSET_PONE).plusDays(1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 31), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_plusDays_minimum() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 2), OFFSET_PONE).plusDays(-1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_plusDays_invalidTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 31), OFFSET_PONE).plusDays(1);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_plusDays_invalidTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE).plusDays(-1);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class, groups={"tck"})
-    public void test_plusDays_overflowTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 31), OFFSET_PONE).plusDays(Long.MAX_VALUE);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class, groups={"tck"})
-    public void test_plusDays_overflowTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE).plusDays(Long.MIN_VALUE);
-    }
-
-    //-----------------------------------------------------------------------
-    // minus(MinusAdjuster)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_minus_MinusAdjuster() {
-        MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
-        OffsetDate t = TEST_2007_07_15_PONE.minus(period);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2006, 12, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minus_MinusAdjuster_noChange() {
-        MockSimplePeriod period = MockSimplePeriod.of(0, ChronoUnit.MONTHS);
-        OffsetDate t = TEST_2007_07_15_PONE.minus(period);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minus_MinusAdjuster_zero() {
-        OffsetDate t = TEST_2007_07_15_PONE.minus(Period.ZERO);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_plus_MinusAdjuster_null() {
-        TEST_2007_07_15_PONE.minus((TemporalSubtractor) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusYears()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_minusYears_long_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusYears(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2006, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusYears_long_negative() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusYears(-1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2008, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusYears_long_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusYears(0);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusYears_long_adjustDay() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PONE).minusYears(1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(2007, 2, 28), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusYears_long_big() {
-        long years = 20L + Year.MAX_VALUE;
-        OffsetDate test = OffsetDate.of(LocalDate.of(40, 6, 1), OFFSET_PONE).minusYears(years);
-        assertEquals(test, OffsetDate.of(LocalDate.of((int) (40L - years), 6, 1), OFFSET_PONE));
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_minusYears_long_invalidTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 1, 1), OFFSET_PONE).minusYears(-1);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_minusYears_long_invalidTooLargeMaxAddMax() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE);
-        test.minusYears(Long.MAX_VALUE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_minusYears_long_invalidTooLargeMaxAddMin() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE);
-        test.minusYears(Long.MIN_VALUE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_minusYears_long_invalidTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE).minusYears(1);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusMonths()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusMonths(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 6, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_overYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusMonths(25);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2005, 6, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_negative() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusMonths(-1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 8, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_negativeAcrossYear() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusMonths(-7);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2008, 2, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_negativeOverYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusMonths(-31);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2010, 2, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusMonths(0);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_adjustDayFromLeapYear() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PONE).minusMonths(12);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(2007, 2, 28), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_adjustDayFromMonthLength() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2007, 3, 31), OFFSET_PONE).minusMonths(1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(2007, 2, 28), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusMonths_long_big() {
-        long months = 20L + Integer.MAX_VALUE;
-        OffsetDate test = OffsetDate.of(LocalDate.of(40, 6, 1), OFFSET_PONE).minusMonths(months);
-        assertEquals(test, OffsetDate.of(LocalDate.of((int) (40L - months / 12), 6 - (int) (months % 12), 1), OFFSET_PONE));
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_minusMonths_long_invalidTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE).minusMonths(-1);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_minusMonths_long_invalidTooLargeMaxAddMax() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE);
-        test.minusMonths(Long.MAX_VALUE);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
-    public void test_minusMonths_long_invalidTooLargeMaxAddMin() {
-        OffsetDate test = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 1), OFFSET_PONE);
-        test.minusMonths(Long.MIN_VALUE);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_minusMonths_long_invalidTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE).minusMonths(1);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusWeeks()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="sampleMinusWeeksSymmetry")
-    Object[][] provider_sampleMinusWeeksSymmetry() {
-        return new Object[][] {
-            {OffsetDate.of(LocalDate.of(-1, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(-1, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(-1, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(-1, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(0, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 2, 29), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(0, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2007, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2007, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2007, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2007, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2008, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2008, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2099, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2099, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2099, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2099, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2100, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2100, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2100, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2100, 12, 31), OFFSET_PTWO)},
-        };
-    }
-
-    @Test(dataProvider="sampleMinusWeeksSymmetry", groups={"tck"})
-    public void test_minusWeeks_symmetry(OffsetDate reference) {
-        for (int weeks = 0; weeks < 365 * 8; weeks++) {
-            OffsetDate t = reference.minusWeeks(weeks).minusWeeks(-weeks);
-            assertEquals(t, reference);
-
-            t = reference.minusWeeks(-weeks).minusWeeks(weeks);
-            assertEquals(t, reference);
-        }
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusWeeks(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 8), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_overMonths() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusWeeks(9);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 5, 13), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_overYears() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 7, 13), OFFSET_PONE).minusWeeks(52);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_overLeapYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusYears(-1).minusWeeks(104);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2006, 7, 18), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_negative() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusWeeks(-1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 22), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_negativeAcrossYear() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusWeeks(-28);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2008, 1, 27), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_negativeOverYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusWeeks(-104);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2009, 7, 12), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusWeeks(0);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_maximum() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 24), OFFSET_PONE).minusWeeks(-1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 31), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusWeeks_minimum() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 8), OFFSET_PONE).minusWeeks(1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_minusWeeks_invalidTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 25), OFFSET_PONE).minusWeeks(-1);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_minusWeeks_invalidTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 7), OFFSET_PONE).minusWeeks(1);
-    }
-
-    @Test(expectedExceptions={ArithmeticException.class}, groups={"tck"})
-    public void test_minusWeeks_invalidMaxMinusMax() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 25), OFFSET_PONE).minusWeeks(Long.MAX_VALUE);
-    }
-
-    @Test(expectedExceptions={ArithmeticException.class}, groups={"tck"})
-    public void test_minusWeeks_invalidMaxMinusMin() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 25), OFFSET_PONE).minusWeeks(Long.MIN_VALUE);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusDays()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="sampleMinusDaysSymmetry")
-    Object[][] provider_sampleMinusDaysSymmetry() {
-        return new Object[][] {
-            {OffsetDate.of(LocalDate.of(-1, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(-1, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(-1, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(-1, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(0, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 2, 29), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(0, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(0, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2007, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2007, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2007, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2007, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2008, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 2, 29), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2008, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2008, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2099, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2099, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2099, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2099, 12, 31), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2100, 1, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2100, 2, 28), OFFSET_PTWO)},
-            {OffsetDate.of(LocalDate.of(2100, 3, 1), OFFSET_PONE)},
-            {OffsetDate.of(LocalDate.of(2100, 12, 31), OFFSET_PTWO)},
-        };
-    }
-
-    @Test(dataProvider="sampleMinusDaysSymmetry", groups={"tck"})
-    public void test_minusDays_symmetry(OffsetDate reference) {
-        for (int days = 0; days < 365 * 8; days++) {
-            OffsetDate t = reference.minusDays(days).minusDays(-days);
-            assertEquals(t, reference);
-
-            t = reference.minusDays(-days).minusDays(days);
-            assertEquals(t, reference);
-        }
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_normal() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusDays(1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 14), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_overMonths() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusDays(62);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 5, 14), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_overYears() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 7, 16), OFFSET_PONE).minusDays(367);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_overLeapYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.plusYears(2).minusDays(365 + 366);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_negative() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusDays(-1);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 7, 16), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_negativeAcrossYear() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusDays(-169);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2007, 12, 31), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_negativeOverYears() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusDays(-731);
-        assertEquals(t, OffsetDate.of(LocalDate.of(2009, 7, 15), OFFSET_PONE));
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_noChange() {
-        OffsetDate t = TEST_2007_07_15_PONE.minusDays(0);
-        assertEquals(t, TEST_2007_07_15_PONE);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_maximum() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 30), OFFSET_PONE).minusDays(-1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 31), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(groups={"tck"})
-    public void test_minusDays_minimum() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 2), OFFSET_PONE).minusDays(1);
-        OffsetDate expected = OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE);
-        assertEquals(t, expected);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_minusDays_invalidTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 31), OFFSET_PONE).minusDays(-1);
-    }
-
-    @Test(expectedExceptions={DateTimeException.class}, groups={"tck"})
-    public void test_minusDays_invalidTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE).minusDays(1);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class, groups={"tck"})
-    public void test_minusDays_overflowTooLarge() {
-        OffsetDate.of(LocalDate.of(Year.MAX_VALUE, 12, 31), OFFSET_PONE).minusDays(Long.MIN_VALUE);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class, groups={"tck"})
-    public void test_minusDays_overflowTooSmall() {
-        OffsetDate.of(LocalDate.of(Year.MIN_VALUE, 1, 1), OFFSET_PONE).minusDays(Long.MAX_VALUE);
-    }
-
-    //-----------------------------------------------------------------------
-    // atTime()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_atTime_Local() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PTWO);
-        assertEquals(t.atTime(LocalTime.of(11, 30)),
-                OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30), OFFSET_PTWO));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_atTime_Local_nullLocalTime() {
-        OffsetDate t = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PTWO);
-        t.atTime((LocalTime) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // getDate()
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="sampleDates", groups={"tck"})
-    public void test_getDate(int year, int month, int day, ZoneOffset offset) {
-        LocalDate t = LocalDate.of(year, month, day);
-        assertEquals(OffsetDate.of(LocalDate.of(year, month, day), offset).getDate(), t);
-    }
-
-    //-----------------------------------------------------------------------
-    // compareTo()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_compareTo_date() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 29), OFFSET_PONE);
-        OffsetDate b = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);  // a is before b due to date
-        assertEquals(a.compareTo(b) < 0, true);
-        assertEquals(b.compareTo(a) > 0, true);
-        assertEquals(a.compareTo(a) == 0, true);
-        assertEquals(b.compareTo(b) == 0, true);
-        assertEquals(a.atTime(LocalTime.MIDNIGHT).toInstant().compareTo(b.atTime(LocalTime.MIDNIGHT).toInstant()) < 0, true);
-    }
-
-    @Test(groups={"tck"})
-    public void test_compareTo_offset() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PTWO);
-        OffsetDate b = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);  // a is before b due to offset
-        assertEquals(a.compareTo(b) < 0, true);
-        assertEquals(b.compareTo(a) > 0, true);
-        assertEquals(a.compareTo(a) == 0, true);
-        assertEquals(b.compareTo(b) == 0, true);
-        assertEquals(a.atTime(LocalTime.MIDNIGHT).toInstant().compareTo(b.atTime(LocalTime.MIDNIGHT).toInstant()) < 0, true);
-    }
-
-    @Test(groups={"tck"})
-    public void test_compareTo_both() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 29), OFFSET_PTWO);
-        OffsetDate b = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);  // a is before b on instant scale
-        assertEquals(a.compareTo(b) < 0, true);
-        assertEquals(b.compareTo(a) > 0, true);
-        assertEquals(a.compareTo(a) == 0, true);
-        assertEquals(b.compareTo(b) == 0, true);
-        assertEquals(a.atTime(LocalTime.MIDNIGHT).toInstant().compareTo(b.atTime(LocalTime.MIDNIGHT).toInstant()) < 0, true);
-    }
-
-    @Test(groups={"tck"})
-    public void test_compareTo_24hourDifference() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 29), ZoneOffset.ofHours(-12));
-        OffsetDate b = OffsetDate.of(LocalDate.of(2008, 6, 30), ZoneOffset.ofHours(12));  // a is before b despite being same time-line time
-        assertEquals(a.compareTo(b) < 0, true);
-        assertEquals(b.compareTo(a) > 0, true);
-        assertEquals(a.compareTo(a) == 0, true);
-        assertEquals(b.compareTo(b) == 0, true);
-        assertEquals(a.atTime(LocalTime.MIDNIGHT).toInstant().compareTo(b.atTime(LocalTime.MIDNIGHT).toInstant()) == 0, true);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_compareTo_null() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        a.compareTo(null);
-    }
-
-    @Test(expectedExceptions=ClassCastException.class, groups={"tck"})
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    public void compareToNonOffsetDate() {
-       Comparable c = TEST_2007_07_15_PONE;
-       c.compareTo(new Object());
-    }
-
-    //-----------------------------------------------------------------------
-    // isAfter() / isBefore() / isEqual()
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_isBeforeIsAfterIsEqual1() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 29), OFFSET_PONE);
-        OffsetDate b = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);  // a is before b due to time
-        assertEquals(a.isBefore(b), true);
-        assertEquals(a.isEqual(b), false);
-        assertEquals(a.isAfter(b), false);
-
-        assertEquals(b.isBefore(a), false);
-        assertEquals(b.isEqual(a), false);
-        assertEquals(b.isAfter(a), true);
-
-        assertEquals(a.isBefore(a), false);
-        assertEquals(b.isBefore(b), false);
-
-        assertEquals(a.isEqual(a), true);
-        assertEquals(b.isEqual(b), true);
-
-        assertEquals(a.isAfter(a), false);
-        assertEquals(b.isAfter(b), false);
-    }
-
-    @Test(groups={"tck"})
-    public void test_isBeforeIsAfterIsEqual2() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PTWO);
-        OffsetDate b = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);  // a is before b due to offset
-        assertEquals(a.isBefore(b), true);
-        assertEquals(a.isEqual(b), false);
-        assertEquals(a.isAfter(b), false);
-
-        assertEquals(b.isBefore(a), false);
-        assertEquals(b.isEqual(a), false);
-        assertEquals(b.isAfter(a), true);
-
-        assertEquals(a.isBefore(a), false);
-        assertEquals(b.isBefore(b), false);
-
-        assertEquals(a.isEqual(a), true);
-        assertEquals(b.isEqual(b), true);
-
-        assertEquals(a.isAfter(a), false);
-        assertEquals(b.isAfter(b), false);
-    }
-
-    @Test(groups={"tck"})
-    public void test_isBeforeIsAfterIsEqual_instantComparison() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 30), ZoneOffset.ofHours(12));
-        OffsetDate b = OffsetDate.of(LocalDate.of(2008, 6, 29), ZoneOffset.ofHours(-12));  // a is same instant as b
-        assertEquals(a.isBefore(b), false);
-        assertEquals(a.isEqual(b), true);
-        assertEquals(a.isAfter(b), false);
-
-        assertEquals(b.isBefore(a), false);
-        assertEquals(b.isEqual(a), true);
-        assertEquals(b.isAfter(a), false);
-
-        assertEquals(a.isBefore(a), false);
-        assertEquals(b.isBefore(b), false);
-
-        assertEquals(a.isEqual(a), true);
-        assertEquals(b.isEqual(b), true);
-
-        assertEquals(a.isAfter(a), false);
-        assertEquals(b.isAfter(b), false);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_isBefore_null() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        a.isBefore(null);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_isAfter_null() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        a.isAfter(null);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_isEqual_null() {
-        OffsetDate a = OffsetDate.of(LocalDate.of(2008, 6, 30), OFFSET_PONE);
-        a.isEqual(null);
-    }
-
-    //-----------------------------------------------------------------------
-    // equals() / hashCode()
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="sampleDates", groups={"tck"})
-    public void test_equals_true(int y, int m, int d, ZoneOffset offset) {
-        OffsetDate a = OffsetDate.of(LocalDate.of(y, m, d), offset);
-        OffsetDate b = OffsetDate.of(LocalDate.of(y, m, d), offset);
-        assertEquals(a.equals(b), true);
-        assertEquals(a.hashCode() == b.hashCode(), true);
-    }
-    @Test(dataProvider="sampleDates", groups={"tck"})
-    public void test_equals_false_year_differs(int y, int m, int d, ZoneOffset offset) {
-        OffsetDate a = OffsetDate.of(LocalDate.of(y, m, d), offset);
-        OffsetDate b = OffsetDate.of(LocalDate.of(y + 1, m, d), offset);
-        assertEquals(a.equals(b), false);
-    }
-
-    @Test(dataProvider="sampleDates", groups={"tck"})
-    public void test_equals_false_month_differs(int y, int m, int d, ZoneOffset offset) {
-        OffsetDate a = OffsetDate.of(LocalDate.of(y, m, d), offset);
-        OffsetDate b = OffsetDate.of(LocalDate.of(y, m + 1, d), offset);
-        assertEquals(a.equals(b), false);
-    }
-
-    @Test(dataProvider="sampleDates", groups={"tck"})
-    public void test_equals_false_day_differs(int y, int m, int d, ZoneOffset offset) {
-        OffsetDate a = OffsetDate.of(LocalDate.of(y, m, d), offset);
-        OffsetDate b = OffsetDate.of(LocalDate.of(y, m, d + 1), offset);
-        assertEquals(a.equals(b), false);
-    }
-
-    @Test(dataProvider="sampleDates", groups={"tck"})
-    public void test_equals_false_offset_differs(int y, int m, int d, ZoneOffset ignored) {
-        OffsetDate a = OffsetDate.of(LocalDate.of(y, m, d), OFFSET_PONE);
-        OffsetDate b = OffsetDate.of(LocalDate.of(y, m, d), OFFSET_PTWO);
-        assertEquals(a.equals(b), false);
-    }
-
-    @Test(groups={"tck"})
-    public void test_equals_itself_true() {
-        assertEquals(TEST_2007_07_15_PONE.equals(TEST_2007_07_15_PONE), true);
-    }
-
-    @Test(groups={"tck"})
-    public void test_equals_string_false() {
-        assertEquals(TEST_2007_07_15_PONE.equals("2007-07-15"), false);
-    }
-
-    //-----------------------------------------------------------------------
-    // toString()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="sampleToString")
-    Object[][] provider_sampleToString() {
-        return new Object[][] {
-            {2008, 7, 5, "Z", "2008-07-05Z"},
-            {2008, 7, 5, "+00", "2008-07-05Z"},
-            {2008, 7, 5, "+0000", "2008-07-05Z"},
-            {2008, 7, 5, "+00:00", "2008-07-05Z"},
-            {2008, 7, 5, "+000000", "2008-07-05Z"},
-            {2008, 7, 5, "+00:00:00", "2008-07-05Z"},
-            {2008, 7, 5, "-00", "2008-07-05Z"},
-            {2008, 7, 5, "-0000", "2008-07-05Z"},
-            {2008, 7, 5, "-00:00", "2008-07-05Z"},
-            {2008, 7, 5, "-000000", "2008-07-05Z"},
-            {2008, 7, 5, "-00:00:00", "2008-07-05Z"},
-            {2008, 7, 5, "+01", "2008-07-05+01:00"},
-            {2008, 7, 5, "+0100", "2008-07-05+01:00"},
-            {2008, 7, 5, "+01:00", "2008-07-05+01:00"},
-            {2008, 7, 5, "+010000", "2008-07-05+01:00"},
-            {2008, 7, 5, "+01:00:00", "2008-07-05+01:00"},
-            {2008, 7, 5, "+0130", "2008-07-05+01:30"},
-            {2008, 7, 5, "+01:30", "2008-07-05+01:30"},
-            {2008, 7, 5, "+013000", "2008-07-05+01:30"},
-            {2008, 7, 5, "+01:30:00", "2008-07-05+01:30"},
-            {2008, 7, 5, "+013040", "2008-07-05+01:30:40"},
-            {2008, 7, 5, "+01:30:40", "2008-07-05+01:30:40"},
-        };
-    }
-
-    @Test(dataProvider="sampleToString", groups={"tck"})
-    public void test_toString(int y, int m, int d, String offsetId, String expected) {
-        OffsetDate t = OffsetDate.of(LocalDate.of(y, m, d), ZoneOffset.of(offsetId));
-        String str = t.toString();
-        assertEquals(str, expected);
-    }
-
-    //-----------------------------------------------------------------------
-    // toString(DateTimeFormatter)
-    //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_toString_formatter() {
-        DateTimeFormatter f = DateTimeFormatters.pattern("y M d");
-        String t = OffsetDate.of(LocalDate.of(2010, 12, 3), OFFSET_PONE).toString(f);
-        assertEquals(t, "2010 12 3");
-    }
-
-    @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
-    public void test_toString_formatter_null() {
-        OffsetDate.of(LocalDate.of(2010, 12, 3), OFFSET_PONE).toString(null);
-    }
-
-}
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKSimplePeriod.java b/jdk/test/java/time/tck/java/time/temporal/TCKSimplePeriod.java
deleted file mode 100644
index d67e6aa..0000000
--- a/jdk/test/java/time/tck/java/time/temporal/TCKSimplePeriod.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package tck.java.time.temporal;
-
-import static java.time.temporal.ChronoUnit.DAYS;
-import static java.time.temporal.ChronoUnit.MONTHS;
-import static java.time.temporal.ChronoUnit.NANOS;
-import static java.time.temporal.ChronoUnit.SECONDS;
-import static java.time.temporal.ChronoUnit.YEARS;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertSame;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-import java.time.LocalDate;
-import java.time.Period;
-import java.time.temporal.ISOFields;
-import java.time.temporal.SimplePeriod;
-import java.time.temporal.TemporalUnit;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-import tck.java.time.AbstractTCKTest;
-
-/**
- * Test.
- */
-@Test
-public class TCKSimplePeriod extends AbstractTCKTest {
-
-    private static final SimplePeriod TEST_12_MONTHS = SimplePeriod.of(12, MONTHS);
-
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="samples")
-    public void test_serialization(long amount, TemporalUnit unit) throws ClassNotFoundException, IOException {
-        SimplePeriod test = SimplePeriod.of(amount, unit);
-        assertSerializable(test);
-    }
-
-    @Test
-    public void test_serialization_format_zoneOffset() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(10);
-            dos.writeLong(12);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(TEST_12_MONTHS, bytes, new byte[0]);
-    }
-
-    //-----------------------------------------------------------------------
-    // of(long, TenmporalUnit)
-    //-----------------------------------------------------------------------
-    @DataProvider(name="samples")
-    Object[][] data_samples() {
-        return new Object[][] {
-                {0, YEARS},
-                {1, YEARS},
-                {-1, YEARS},
-                {2, MONTHS},
-                {-2, MONTHS},
-                {43, ISOFields.WEEK_BASED_YEARS},
-                {Long.MAX_VALUE, NANOS},
-                {Long.MIN_VALUE, NANOS},
-        };
-    }
-
-    @Test(dataProvider="samples")
-    public void factory_of(long amount, TemporalUnit unit) {
-        SimplePeriod test = SimplePeriod.of(amount, unit);
-        assertEquals(test.getAmount(), amount);
-        assertEquals(test.getUnit(), unit);
-    }
-
-    //-----------------------------------------------------------------------
-    // addTo()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="addTo")
-    Object[][] data_addTo() {
-        return new Object[][] {
-            {SimplePeriod.of(0, DAYS),  date(2012, 6, 30), date(2012, 6, 30)},
-
-            {SimplePeriod.of(1, DAYS),  date(2012, 6, 30), date(2012, 7, 1)},
-            {SimplePeriod.of(-1, DAYS),  date(2012, 6, 30), date(2012, 6, 29)},
-
-            {SimplePeriod.of(2, DAYS),  date(2012, 6, 30), date(2012, 7, 2)},
-            {SimplePeriod.of(-2, DAYS),  date(2012, 6, 30), date(2012, 6, 28)},
-
-            {SimplePeriod.of(3, MONTHS),  date(2012, 5, 31), date(2012, 8, 31)},
-            {SimplePeriod.of(4, MONTHS),  date(2012, 5, 31), date(2012, 9, 30)},
-            {SimplePeriod.of(-3, MONTHS),  date(2012, 5, 31), date(2012, 2, 29)},
-            {SimplePeriod.of(-4, MONTHS),  date(2012, 5, 31), date(2012, 1, 31)},
-        };
-    }
-
-    @Test(dataProvider="addTo")
-    public void test_addTo(SimplePeriod period, LocalDate baseDate, LocalDate expected) {
-        assertEquals(period.addTo(baseDate), expected);
-    }
-
-    @Test(dataProvider="addTo")
-    public void test_addTo_usingLocalDatePlus(SimplePeriod period, LocalDate baseDate, LocalDate expected) {
-        assertEquals(baseDate.plus(period), expected);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_addTo_nullZero() {
-        SimplePeriod.of(0, DAYS).addTo(null);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_addTo_nullNonZero() {
-        SimplePeriod.of(2, DAYS).addTo(null);
-    }
-
-    //-----------------------------------------------------------------------
-    // subtractFrom()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="subtractFrom")
-    Object[][] data_subtractFrom() {
-        return new Object[][] {
-            {SimplePeriod.of(0, DAYS),  date(2012, 6, 30), date(2012, 6, 30)},
-
-            {SimplePeriod.of(1, DAYS),  date(2012, 6, 30), date(2012, 6, 29)},
-            {SimplePeriod.of(-1, DAYS),  date(2012, 6, 30), date(2012, 7, 1)},
-
-            {SimplePeriod.of(2, DAYS),  date(2012, 6, 30), date(2012, 6, 28)},
-            {SimplePeriod.of(-2, DAYS),  date(2012, 6, 30), date(2012, 7, 2)},
-
-            {SimplePeriod.of(3, MONTHS),  date(2012, 5, 31), date(2012, 2, 29)},
-            {SimplePeriod.of(4, MONTHS),  date(2012, 5, 31), date(2012, 1, 31)},
-            {SimplePeriod.of(-3, MONTHS),  date(2012, 5, 31), date(2012, 8, 31)},
-            {SimplePeriod.of(-4, MONTHS),  date(2012, 5, 31), date(2012, 9, 30)},
-        };
-    }
-
-    @Test(dataProvider="subtractFrom")
-    public void test_subtractFrom(SimplePeriod period, LocalDate baseDate, LocalDate expected) {
-        assertEquals(period.subtractFrom(baseDate), expected);
-    }
-
-    @Test(dataProvider="subtractFrom")
-    public void test_subtractFrom_usingLocalDateMinus(SimplePeriod period, LocalDate baseDate, LocalDate expected) {
-        assertEquals(baseDate.minus(period), expected);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_subtractFrom_nullZero() {
-        SimplePeriod.of(0, DAYS).subtractFrom(null);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_subtractFrom_nullNonZero() {
-        SimplePeriod.of(2, DAYS).subtractFrom(null);
-    }
-
-    //-----------------------------------------------------------------------
-    // abs()
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="samples")
-    public void test_abs(long amount, TemporalUnit unit) {
-        SimplePeriod test = SimplePeriod.of(amount, unit);
-        if (amount >= 0) {
-            assertSame(test.abs(), test);  // spec requires assertSame
-        } else if (amount == Long.MIN_VALUE) {
-            // ignore, separately tested
-        } else {
-            assertEquals(test.abs(), SimplePeriod.of(-amount, unit));
-        }
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_abs_minValue() {
-        SimplePeriod.of(Long.MIN_VALUE, SECONDS).abs();
-    }
-
-    //-----------------------------------------------------------------------
-    // equals() / hashCode()
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="samples")
-    public void test_equals(long amount, TemporalUnit unit) {
-        SimplePeriod test1 = SimplePeriod.of(amount, unit);
-        SimplePeriod test2 = SimplePeriod.of(amount, unit);
-        assertEquals(test1, test2);
-    }
-
-    @Test(dataProvider="samples")
-    public void test_equals_self(long amount, TemporalUnit unit) {
-        SimplePeriod test = SimplePeriod.of(amount, unit);
-        assertEquals(test.equals(test), true);
-    }
-
-    public void test_equals_null() {
-        assertEquals(TEST_12_MONTHS.equals(null), false);
-    }
-
-    public void test_equals_otherClass() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6);
-        assertEquals(test.equals(""), false);
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_hashCode() {
-        SimplePeriod test5 = SimplePeriod.of(5, DAYS);
-        SimplePeriod test6 = SimplePeriod.of(6, DAYS);
-        SimplePeriod test5M = SimplePeriod.of(5, MONTHS);
-        SimplePeriod test5Y = SimplePeriod.of(5, YEARS);
-        assertEquals(test5.hashCode() == test5.hashCode(), true);
-        assertEquals(test5.hashCode() == test6.hashCode(), false);
-        assertEquals(test5.hashCode() == test5M.hashCode(), false);
-        assertEquals(test5.hashCode() == test5Y.hashCode(), false);
-    }
-
-    //-----------------------------------------------------------------------
-    // toString()
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="samples")
-    public void test_toString(long amount, TemporalUnit unit) {
-        SimplePeriod test = SimplePeriod.of(amount, unit);
-        assertEquals(test.toString(), amount + " " + unit.getName());
-    }
-
-    private static LocalDate date(int y, int m, int d) {
-        return LocalDate.of(y, m, d);
-    }
-
-}
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java
index 9119a70..76789cd 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java
+++ b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java
@@ -56,310 +56,349 @@
  */
 package tck.java.time.temporal;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.fail;
-
-import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.YEAR;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
 import java.time.DayOfWeek;
 import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
 import java.time.temporal.TemporalField;
-import java.time.format.DateTimeBuilder;
 import java.time.temporal.ValueRange;
 import java.time.temporal.WeekFields;
 
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
 
 /**
  * Test WeekFields.
  */
 @Test
-public class TCKWeekFields {
+public class TCKWeekFields extends AbstractTCKTest {
 
-    @Test(groups={"tck"})
-    public void test_WeekFieldsOf() {
-        for (DayOfWeek dow : DayOfWeek.values()) {
-            for (int minDays = 1; minDays <= 7; minDays++) {
-                WeekFields week = WeekFields.of(dow, minDays);
-                assertEquals(week.getFirstDayOfWeek(), dow, "Incorrect firstDayOfWeek");
-                assertEquals(week.getMinimalDaysInFirstWeek(), minDays, "Incorrect MinimalDaysInFirstWeek");
-            }
-        }
+    @Test(dataProvider="weekFields")
+    public void test_of_DayOfWeek_int_singleton(DayOfWeek firstDayOfWeek, int minDays) {
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        assertEquals(week.getFirstDayOfWeek(), firstDayOfWeek, "Incorrect firstDayOfWeek");
+        assertEquals(week.getMinimalDaysInFirstWeek(), minDays, "Incorrect MinimalDaysInFirstWeek");
+        assertSame(WeekFields.of(firstDayOfWeek, minDays), week);
     }
 
-    @Test(groups={"tck"})
-    public void test_DayOfWeek() {
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_dayOfWeekField_simpleGet() {
+        LocalDate date = LocalDate.of(2000, 1, 10);  // Known to be ISO Monday
+        assertEquals(date.get(WeekFields.ISO.dayOfWeek()), 1);
+        assertEquals(date.get(WeekFields.of(DayOfWeek.MONDAY, 1).dayOfWeek()), 1);
+        assertEquals(date.get(WeekFields.of(DayOfWeek.MONDAY, 7).dayOfWeek()), 1);
+        assertEquals(date.get(WeekFields.SUNDAY_START.dayOfWeek()), 2);
+        assertEquals(date.get(WeekFields.of(DayOfWeek.SUNDAY, 1).dayOfWeek()), 2);
+        assertEquals(date.get(WeekFields.of(DayOfWeek.SUNDAY, 7).dayOfWeek()), 2);
+        assertEquals(date.get(WeekFields.of(DayOfWeek.SATURDAY, 1).dayOfWeek()), 3);
+        assertEquals(date.get(WeekFields.of(DayOfWeek.FRIDAY, 1).dayOfWeek()), 4);
+        assertEquals(date.get(WeekFields.of(DayOfWeek.TUESDAY, 1).dayOfWeek()), 7);
+    }
+
+    @Test
+    public void test_dayOfWeekField_simpleSet() {
+        LocalDate date = LocalDate.of(2000, 1, 10);  // Known to be ISO Monday
+        assertEquals(date.with(WeekFields.ISO.dayOfWeek(), 2), LocalDate.of(2000, 1, 11));
+        assertEquals(date.with(WeekFields.ISO.dayOfWeek(), 7), LocalDate.of(2000, 1, 16));
+
+        assertEquals(date.with(WeekFields.SUNDAY_START.dayOfWeek(), 3), LocalDate.of(2000, 1, 11));
+        assertEquals(date.with(WeekFields.SUNDAY_START.dayOfWeek(), 7), LocalDate.of(2000, 1, 15));
+
+        assertEquals(date.with(WeekFields.of(DayOfWeek.SATURDAY, 1).dayOfWeek(), 4), LocalDate.of(2000, 1, 11));
+        assertEquals(date.with(WeekFields.of(DayOfWeek.TUESDAY, 1).dayOfWeek(), 1), LocalDate.of(2000, 1, 4));
+    }
+
+    @Test(dataProvider="weekFields")
+    public void test_dayOfWeekField(DayOfWeek firstDayOfWeek, int minDays) {
         LocalDate day = LocalDate.of(2000, 1, 10);  // Known to be ISO Monday
-        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
-            for (int minDays = 1; minDays <= 7; minDays++) {
-                WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
-                TemporalField f = week.dayOfWeek();
-                //System.out.printf("  Week: %s; field: %s%n", week, f);
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField f = week.dayOfWeek();
+        //System.out.printf("  Week: %s; field: %s%n", week, f);
 
-                for (int i = 1; i <= 7; i++) {
-                    //System.out.printf("  ISO Dow: %s, WeekDOW ordinal: %s%n", day.getDayOfWeek(), day.get(f));
-                    assertEquals(day.get(f), (7 + day.getDayOfWeek().getValue() - firstDayOfWeek.getValue()) % 7 + 1);
-                    day = day.plusDays(1);
-                }
-            }
+        for (int i = 1; i <= 7; i++) {
+            //System.out.printf("  ISO Dow: %s, WeekDOW ordinal: %s%n", day.getDayOfWeek(), day.get(f));
+            assertEquals(day.get(f), (7 + day.getDayOfWeek().getValue() - firstDayOfWeek.getValue()) % 7 + 1);
+            day = day.plusDays(1);
         }
     }
 
-    @Test(groups={"tck"})
-    public void test_WeekOfMonth() {
-        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
-            for (int minDays = 1; minDays <= 7; minDays++) {
-                LocalDate day = LocalDate.of(2012, 12, 31);  // Known to be ISO Monday
-                WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
-                TemporalField dowField = week.dayOfWeek();
-                TemporalField womField = week.weekOfMonth();
-                //System.err.printf("%n  Week: %s; dowField: %s, domField: %s%n", week, dowField, womField);
+    @Test(dataProvider="weekFields")
+    public void test_weekOfMonthField(DayOfWeek firstDayOfWeek, int minDays) {
+        LocalDate day = LocalDate.of(2012, 12, 31);  // Known to be ISO Monday
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField dowField = week.dayOfWeek();
+        TemporalField womField = week.weekOfMonth();
+        //System.err.printf("%n  Week: %s; dowField: %s, domField: %s%n", week, dowField, womField);
 
-                DayOfWeek isoDOW = day.getDayOfWeek();
-                int dow = (7 + isoDOW.getValue() - firstDayOfWeek.getValue()) % 7 + 1;
+        DayOfWeek isoDOW = day.getDayOfWeek();
+        int dow = (7 + isoDOW.getValue() - firstDayOfWeek.getValue()) % 7 + 1;
 
-                for (int i = 1; i <= 15; i++) {
-                    int actualDOW = day.get(dowField);
-                    int actualWOM = day.get(womField);
+        for (int i = 1; i <= 15; i++) {
+            int actualDOW = day.get(dowField);
+            int actualWOM = day.get(womField);
 
-                    // Verify that the combination of day of week and week of month can be used
-                    // to reconstruct the same date.
-                    LocalDate day1 = day.withDayOfMonth(1);
-                    int offset = - (day1.get(dowField) - 1);
-                    //System.err.printf("   refDay: %s%n", day1.plusDays(offset));
-                    int week1 = day1.get(womField);
-                    if (week1 == 0) {
-                        // week of the 1st is partial; start with first full week
-                        offset += 7;
-                    }
-                    //System.err.printf("   refDay2: %s, offset: %d, week1: %d%n", day1.plusDays(offset), offset, week1);
-                    offset += actualDOW - 1;
-                    //System.err.printf("   refDay3: %s%n", day1.plusDays(offset));
-                    offset += (actualWOM - 1) * 7;
-                    //System.err.printf("   refDay4: %s%n", day1.plusDays(offset));
-                    LocalDate result = day1.plusDays(offset);
-
-                    if (!day.equals(result)) {
-                        System.err.printf("FAIL ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n",
-                                day.getDayOfWeek(), offset, actualDOW, actualWOM, day, result);
-                    }
-                    assertEquals(result, day, "Incorrect dayOfWeek or weekOfMonth: "
-                            + String.format("%s, ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n",
-                            week, day.getDayOfWeek(), offset, actualDOW, actualWOM, day, result));
-                    day = day.plusDays(1);
-                }
+            // Verify that the combination of day of week and week of month can be used
+            // to reconstruct the same date.
+            LocalDate day1 = day.withDayOfMonth(1);
+            int offset = - (day1.get(dowField) - 1);
+            //System.err.printf("   refDay: %s%n", day1.plusDays(offset));
+            int week1 = day1.get(womField);
+            if (week1 == 0) {
+                // week of the 1st is partial; start with first full week
+                offset += 7;
             }
+            //System.err.printf("   refDay2: %s, offset: %d, week1: %d%n", day1.plusDays(offset), offset, week1);
+            offset += actualDOW - 1;
+            //System.err.printf("   refDay3: %s%n", day1.plusDays(offset));
+            offset += (actualWOM - 1) * 7;
+            //System.err.printf("   refDay4: %s%n", day1.plusDays(offset));
+            LocalDate result = day1.plusDays(offset);
+
+            if (!day.equals(result)) {
+                System.err.printf("FAIL ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n",
+                        day.getDayOfWeek(), offset, actualDOW, actualWOM, day, result);
+            }
+            assertEquals(result, day, "Incorrect dayOfWeek or weekOfMonth: "
+                    + String.format("%s, ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n",
+                    week, day.getDayOfWeek(), offset, actualDOW, actualWOM, day, result));
+            day = day.plusDays(1);
         }
     }
 
-    @Test(groups={"tck"})
-    public void test_WeekOfYear() {
-        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
-            for (int minDays = 1; minDays <= 7; minDays++) {
-                LocalDate day = LocalDate.of(2012, 12, 31);  // Known to be ISO Monday
-                WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
-                TemporalField dowField = week.dayOfWeek();
-                TemporalField woyField = week.weekOfYear();
-                //System.err.printf("%n  Year: %s; dowField: %s, woyField: %s%n", week, dowField, woyField);
+    @Test(dataProvider="weekFields")
+    public void test_weekOfYearField(DayOfWeek firstDayOfWeek, int minDays) {
+        LocalDate day = LocalDate.of(2012, 12, 31);  // Known to be ISO Monday
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField dowField = week.dayOfWeek();
+        TemporalField woyField = week.weekOfYear();
+        //System.err.printf("%n  Year: %s; dowField: %s, woyField: %s%n", week, dowField, woyField);
 
-                DayOfWeek isoDOW = day.getDayOfWeek();
-                int dow = (7 + isoDOW.getValue() - firstDayOfWeek.getValue()) % 7 + 1;
+        DayOfWeek isoDOW = day.getDayOfWeek();
+        int dow = (7 + isoDOW.getValue() - firstDayOfWeek.getValue()) % 7 + 1;
 
-                for (int i = 1; i <= 15; i++) {
-                    int actualDOW = day.get(dowField);
-                    int actualWOY = day.get(woyField);
+        for (int i = 1; i <= 15; i++) {
+            int actualDOW = day.get(dowField);
+            int actualWOY = day.get(woyField);
 
-                    // Verify that the combination of day of week and week of month can be used
-                    // to reconstruct the same date.
-                    LocalDate day1 = day.withDayOfYear(1);
-                    int offset = - (day1.get(dowField) - 1);
-                    //System.err.printf("   refDay: %s%n", day1.plusDays(offset));
-                    int week1 = day1.get(woyField);
-                    if (week1 == 0) {
-                        // week of the 1st is partial; start with first full week
-                        offset += 7;
-                    }
-                    //System.err.printf("   refDay2: %s, offset: %d, week1: %d%n", day1.plusDays(offset), offset, week1);
-                    offset += actualDOW - 1;
-                    //System.err.printf("   refDay3: %s%n", day1.plusDays(offset));
-                    offset += (actualWOY - 1) * 7;
-                    //System.err.printf("   refDay4: %s%n", day1.plusDays(offset));
-                    LocalDate result = day1.plusDays(offset);
-
-
-                    if (!day.equals(result)) {
-                        System.err.printf("FAIL  ISO Dow: %s, offset: %s, actualDOW: %s, actualWOY: %s, expected: %s, result: %s%n",
-                                day.getDayOfWeek(), offset, actualDOW, actualWOY, day, result);
-                    }
-                    assertEquals(result, day, "Incorrect dayOfWeek or weekOfYear "
-                            + String.format("%s, ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n",
-                            week, day.getDayOfWeek(), offset, actualDOW, actualWOY, day, result));
-                    day = day.plusDays(1);
-                }
+            // Verify that the combination of day of week and week of month can be used
+            // to reconstruct the same date.
+            LocalDate day1 = day.withDayOfYear(1);
+            int offset = - (day1.get(dowField) - 1);
+            //System.err.printf("   refDay: %s%n", day1.plusDays(offset));
+            int week1 = day1.get(woyField);
+            if (week1 == 0) {
+                // week of the 1st is partial; start with first full week
+                offset += 7;
             }
+            //System.err.printf("   refDay2: %s, offset: %d, week1: %d%n", day1.plusDays(offset), offset, week1);
+            offset += actualDOW - 1;
+            //System.err.printf("   refDay3: %s%n", day1.plusDays(offset));
+            offset += (actualWOY - 1) * 7;
+            //System.err.printf("   refDay4: %s%n", day1.plusDays(offset));
+            LocalDate result = day1.plusDays(offset);
+
+
+            if (!day.equals(result)) {
+                System.err.printf("FAIL  ISO Dow: %s, offset: %s, actualDOW: %s, actualWOY: %s, expected: %s, result: %s%n",
+                        day.getDayOfWeek(), offset, actualDOW, actualWOY, day, result);
+            }
+            assertEquals(result, day, "Incorrect dayOfWeek or weekOfYear "
+                    + String.format("%s, ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n",
+                    week, day.getDayOfWeek(), offset, actualDOW, actualWOY, day, result));
+            day = day.plusDays(1);
         }
     }
 
-    @Test(groups={"tck"})
-    public void test_fieldRanges() {
-        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
-            for (int minDays = 1; minDays <= 7; minDays++) {
-                WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays);
-                TemporalField dowField = weekDef.dayOfWeek();
-                TemporalField womField = weekDef.weekOfMonth();
-                TemporalField woyField = weekDef.weekOfYear();
+    @Test(dataProvider="weekFields")
+    public void test_fieldRanges(DayOfWeek firstDayOfWeek, int minDays) {
+        WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField womField = weekDef.weekOfMonth();
+        TemporalField woyField = weekDef.weekOfYear();
 
-                LocalDate day = LocalDate.of(2012, 11, 30);
-                LocalDate endDay = LocalDate.of(2013, 1, 2);
-                while (day.isBefore(endDay)) {
-                    LocalDate last = day.with(DAY_OF_MONTH, day.lengthOfMonth());
-                    int lastWOM = last.get(womField);
-                    LocalDate first = day.with(DAY_OF_MONTH, 1);
-                    int firstWOM = first.get(womField);
-                    ValueRange rangeWOM = day.range(womField);
-                    assertEquals(rangeWOM.getMinimum(), firstWOM,
-                            "Range min should be same as WeekOfMonth for first day of month: "
-                            + first + ", " + weekDef);
-                    assertEquals(rangeWOM.getMaximum(), lastWOM,
-                            "Range max should be same as WeekOfMonth for last day of month: "
-                            + last + ", " + weekDef);
+        LocalDate day = LocalDate.of(2012, 11, 30);
+        LocalDate endDay = LocalDate.of(2013, 1, 2);
+        while (day.isBefore(endDay)) {
+            LocalDate last = day.with(DAY_OF_MONTH, day.lengthOfMonth());
+            int lastWOM = last.get(womField);
+            LocalDate first = day.with(DAY_OF_MONTH, 1);
+            int firstWOM = first.get(womField);
+            ValueRange rangeWOM = day.range(womField);
+            assertEquals(rangeWOM.getMinimum(), firstWOM,
+                    "Range min should be same as WeekOfMonth for first day of month: "
+                    + first + ", " + weekDef);
+            assertEquals(rangeWOM.getMaximum(), lastWOM,
+                    "Range max should be same as WeekOfMonth for last day of month: "
+                    + last + ", " + weekDef);
 
-                    last = day.with(DAY_OF_YEAR, day.lengthOfYear());
-                    int lastWOY = last.get(woyField);
-                    first = day.with(DAY_OF_YEAR, 1);
-                    int firstWOY = first.get(woyField);
-                    ValueRange rangeWOY = day.range(woyField);
-                    assertEquals(rangeWOY.getMinimum(), firstWOY,
-                            "Range min should be same as WeekOfYear for first day of Year: "
-                            + day + ", " + weekDef);
-                    assertEquals(rangeWOY.getMaximum(), lastWOY,
-                            "Range max should be same as WeekOfYear for last day of Year: "
-                            + day + ", " + weekDef);
+            last = day.with(DAY_OF_YEAR, day.lengthOfYear());
+            int lastWOY = last.get(woyField);
+            first = day.with(DAY_OF_YEAR, 1);
+            int firstWOY = first.get(woyField);
+            ValueRange rangeWOY = day.range(woyField);
+            assertEquals(rangeWOY.getMinimum(), firstWOY,
+                    "Range min should be same as WeekOfYear for first day of Year: "
+                    + day + ", " + weekDef);
+            assertEquals(rangeWOY.getMaximum(), lastWOY,
+                    "Range max should be same as WeekOfYear for last day of Year: "
+                    + day + ", " + weekDef);
 
-                    day = day.plusDays(1);
-                }
-            }
+            day = day.plusDays(1);
         }
     }
 
     //-----------------------------------------------------------------------
     // withDayOfWeek()
     //-----------------------------------------------------------------------
-    @Test(groups = {"tck"})
-    public void test_withDayOfWeek() {
-        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
-            for (int minDays = 1; minDays <= 7; minDays++) {
-                LocalDate day = LocalDate.of(2012, 12, 15);  // Safely in the middle of a month
-                WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+    @Test(dataProvider="weekFields")
+    public void test_withDayOfWeek(DayOfWeek firstDayOfWeek, int minDays) {
+        LocalDate day = LocalDate.of(2012, 12, 15);  // Safely in the middle of a month
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField dowField = week.dayOfWeek();
+        TemporalField womField = week.weekOfMonth();
+        TemporalField woyField = week.weekOfYear();
 
-                TemporalField dowField = week.dayOfWeek();
-                TemporalField womField = week.weekOfMonth();
-                TemporalField woyField = week.weekOfYear();
-                int wom = day.get(womField);
-                int woy = day.get(woyField);
-                for (int dow = 1; dow <= 7; dow++) {
-                    LocalDate result = day.with(dowField, dow);
-                    if (result.get(dowField) != dow) {
-                        System.err.printf(" DOW actual: %d, expected: %d, week:%s%n",
-                                result.get(dowField), dow, week);
-                    }
-                    if (result.get(womField) != wom) {
-                        System.err.printf(" WOM actual: %d, expected: %d, week:%s%n",
-                                result.get(womField), wom, week);
-                    }
-                    if (result.get(woyField) != woy) {
-                        System.err.printf(" WOY actual: %d, expected: %d, week:%s%n",
-                                result.get(woyField), woy, week);
-                    }
-                    assertEquals(result.get(dowField), dow, String.format("Incorrect new Day of week: %s", result));
-                    assertEquals(result.get(womField), wom, "Week of Month should not change");
-                    assertEquals(result.get(woyField), woy, "Week of Year should not change");
-                }
+        int wom = day.get(womField);
+        int woy = day.get(woyField);
+        for (int dow = 1; dow <= 7; dow++) {
+            LocalDate result = day.with(dowField, dow);
+            if (result.get(dowField) != dow) {
+                System.err.printf(" DOW actual: %d, expected: %d, week:%s%n",
+                        result.get(dowField), dow, week);
             }
+            if (result.get(womField) != wom) {
+                System.err.printf(" WOM actual: %d, expected: %d, week:%s%n",
+                        result.get(womField), wom, week);
+            }
+            if (result.get(woyField) != woy) {
+                System.err.printf(" WOY actual: %d, expected: %d, week:%s%n",
+                        result.get(woyField), woy, week);
+            }
+            assertEquals(result.get(dowField), dow, String.format("Incorrect new Day of week: %s", result));
+            assertEquals(result.get(womField), wom, "Week of Month should not change");
+            assertEquals(result.get(woyField), woy, "Week of Year should not change");
         }
     }
 
-    @Test()
-    public void test_computedFieldResolver() {
-        // For all starting days of week, for all minDays, for two weeks in Dec 2012
-        // Test that when supplied with partial values, that the resolver
-        // fills in the month
-        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
-            for (int minDays = 1; minDays <= 7; minDays++) {
-                LocalDate day = LocalDate.of(2012, 12, 15);  // Safely in the middle of a month
-                WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="weekFields")
+    public void test_parse_resolve_localizedWom(DayOfWeek firstDayOfWeek, int minDays) {
+        LocalDate date = LocalDate.of(2012, 12, 15);
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField womField = week.weekOfMonth();
 
-                TemporalField dowField = week.dayOfWeek();
-                TemporalField womField = week.weekOfMonth();
-                TemporalField woyField = week.weekOfYear();
-                int wom = day.get(womField);
-                int woy = day.get(woyField);
-                for (int dow = 1; dow <= 15; dow++) {
-                    // Test that with dayOfWeek and Week of month it computes the day of month
-                    DateTimeBuilder builder = new DateTimeBuilder();
-                    builder.addFieldValue(YEAR, day.get(YEAR));
-                    builder.addFieldValue(MONTH_OF_YEAR, day.get(MONTH_OF_YEAR));
-                    builder.addFieldValue(DAY_OF_WEEK, day.get(DAY_OF_WEEK));
-                    builder.addFieldValue(dowField, day.get(dowField));
-                    builder.addFieldValue(womField, day.get(womField));
+        for (int i = 1; i <= 60; i++) {
+            // Test that with dayOfWeek and Week of month it computes the date
+            DateTimeFormatter f = new DateTimeFormatterBuilder()
+                    .appendValue(YEAR).appendLiteral('-')
+                    .appendValue(MONTH_OF_YEAR).appendLiteral('-')
+                    .appendValue(womField).appendLiteral('-')
+                    .appendValue(DAY_OF_WEEK).toFormatter();
+            String str = date.getYear() + "-" + date.getMonthValue() + "-" +
+                    date.get(womField) + "-" + date.get(DAY_OF_WEEK);
+            LocalDate parsed = LocalDate.parse(str, f);
+            assertEquals(parsed, date, " ::" + str + "::" + i);
 
-                    boolean res1 = dowField.resolve(builder, day.get(dowField));
-                    boolean res2 = womField.resolve(builder, day.get(womField));
-                    assertEquals(day.get(DAY_OF_MONTH), day.get(DAY_OF_MONTH));
-                    assertEquals(day.get(DAY_OF_YEAR), day.get(DAY_OF_YEAR));
-
-                    day = day.plusDays(1);
-                }
-                day = LocalDate.of(2012, 12, 15);  // Safely in the middle of a month
-                for (int dow = 1; dow <= 15; dow++) {
-                    // Test that with dayOfWeek and Week of year it computes the day of year
-                    DateTimeBuilder builder = new DateTimeBuilder();
-                    builder.addFieldValue(YEAR, day.get(YEAR));
-                    builder.addFieldValue(DAY_OF_WEEK, day.get(DAY_OF_WEEK));
-                    builder.addFieldValue(dowField, day.get(dowField));
-                    builder.addFieldValue(woyField, day.get(woyField));
-
-                    boolean res1 = dowField.resolve(builder, day.get(dowField));
-                    boolean res2 = woyField.resolve(builder, day.get(woyField));
-
-                    assertEquals(day.get(DAY_OF_MONTH), day.get(DAY_OF_MONTH));
-                    assertEquals(day.get(DAY_OF_YEAR), day.get(DAY_OF_YEAR));
-
-                    day = day.plusDays(1);
-                }
-            }
+            date = date.plusDays(1);
         }
     }
 
-    @Test(groups = {"tck"})
-    public void test_WeekFieldsSingleton() throws IOException, ClassNotFoundException {
-        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
-            for (int minDays = 1; minDays <= 7; minDays++) {
-                WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays);
-                WeekFields weekDef2 = WeekFields.of(firstDayOfWeek, minDays);
-                assertSame(weekDef2, weekDef, "WeekFields same parameters should be same instance");
-                try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                     ObjectOutputStream oos = new ObjectOutputStream(baos)) {
-                    oos.writeObject(weekDef);
+    @Test(dataProvider="weekFields")
+    public void test_parse_resolve_localizedWomDow(DayOfWeek firstDayOfWeek, int minDays) {
+        LocalDate date = LocalDate.of(2012, 12, 15);
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField dowField = week.dayOfWeek();
+        TemporalField womField = week.weekOfMonth();
 
-                    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
-                        baos.toByteArray()));
-                    WeekFields result = (WeekFields)ois.readObject();
-                    assertSame(result, weekDef, "Deserialized object same as serialized.");
-                }
-                // Exceptions will be handled as failures by TestNG
-            }
+        for (int i = 1; i <= 15; i++) {
+            // Test that with dayOfWeek and Week of month it computes the date
+            DateTimeFormatter f = new DateTimeFormatterBuilder()
+                    .appendValue(YEAR).appendLiteral('-')
+                    .appendValue(MONTH_OF_YEAR).appendLiteral('-')
+                    .appendValue(womField).appendLiteral('-')
+                    .appendValue(dowField).toFormatter();
+            String str = date.getYear() + "-" + date.getMonthValue() + "-" +
+                    date.get(womField) + "-" + date.get(dowField);
+            LocalDate parsed = LocalDate.parse(str, f);
+            assertEquals(parsed, date, " :: " + str + " " + i);
+
+            date = date.plusDays(1);
         }
     }
+
+    @Test(dataProvider="weekFields")
+    public void test_parse_resolve_localizedWoy(DayOfWeek firstDayOfWeek, int minDays) {
+        LocalDate date = LocalDate.of(2012, 12, 15);
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField woyField = week.weekOfYear();
+
+        for (int i = 1; i <= 60; i++) {
+            // Test that with dayOfWeek and Week of month it computes the date
+            DateTimeFormatter f = new DateTimeFormatterBuilder()
+                    .appendValue(YEAR).appendLiteral('-')
+                    .appendValue(MONTH_OF_YEAR).appendLiteral('-')
+                    .appendValue(woyField).appendLiteral('-')
+                    .appendValue(DAY_OF_WEEK).toFormatter();
+            String str = date.getYear() + "-" + date.getMonthValue() + "-" +
+                    date.get(woyField) + "-" + date.get(DAY_OF_WEEK);
+            LocalDate parsed = LocalDate.parse(str, f);
+            assertEquals(parsed, date, " :: " + str + " " + i);
+
+            date = date.plusDays(1);
+        }
+    }
+
+    @Test(dataProvider="weekFields")
+    public void test_parse_resolve_localizedWoyDow(DayOfWeek firstDayOfWeek, int minDays) {
+        LocalDate date = LocalDate.of(2012, 12, 15);
+        WeekFields week = WeekFields.of(firstDayOfWeek, minDays);
+        TemporalField dowField = week.dayOfWeek();
+        TemporalField woyField = week.weekOfYear();
+
+        for (int i = 1; i <= 60; i++) {
+            // Test that with dayOfWeek and Week of month it computes the date
+            DateTimeFormatter f = new DateTimeFormatterBuilder()
+                    .appendValue(YEAR).appendLiteral('-')
+                    .appendValue(MONTH_OF_YEAR).appendLiteral('-')
+                    .appendValue(woyField).appendLiteral('-')
+                    .appendValue(dowField).toFormatter();
+            String str = date.getYear() + "-" + date.getMonthValue() + "-" +
+                    date.get(woyField) + "-" + date.get(dowField);
+            LocalDate parsed = LocalDate.parse(str, f);
+            assertEquals(parsed, date, " :: " + str + " " + i);
+
+            date = date.plusDays(1);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="weekFields")
+    public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException {
+        WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays);
+        assertSerializableSame(weekDef);  // spec state singleton
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="weekFields")
+    Object[][] data_weekFields() {
+        Object[][] objects = new Object[49][];
+        int i = 0;
+        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
+            for (int minDays = 1; minDays <= 7; minDays++) {
+                objects[i++] = new Object[] {firstDayOfWeek, minDays};
+            }
+        }
+        return objects;
+    }
+
 }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TestChronoLocalDate.java b/jdk/test/java/time/tck/java/time/temporal/TestChronoLocalDate.java
index 95caf57..6d15683 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TestChronoLocalDate.java
+++ b/jdk/test/java/time/tck/java/time/temporal/TestChronoLocalDate.java
@@ -63,27 +63,23 @@
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.chrono.Chronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.IsoChronology;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import java.time.Duration;
-import java.time.LocalDate;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDate;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.SimplePeriod;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAccessor;
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.TemporalAdder;
-import java.time.temporal.TemporalAdjuster;
-import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.ValueRange;
-import java.time.temporal.TemporalUnit;
-import java.time.temporal.ISOChrono;
-
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -98,19 +94,19 @@
     // regular data factory for names and descriptions of ISO calendar
     //-----------------------------------------------------------------------
     @DataProvider(name = "calendars")
-    Chrono<?>[][] data_of_calendars() {
-        return new Chrono[][]{
-            {ISOChrono.INSTANCE},
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+            {IsoChronology.INSTANCE},
         };
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badWithAdjusterChrono(Chrono<?> chrono) {
+    public void test_badWithAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
-        ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
-            ChronoLocalDate<?> date2 = chrono2.date(refDate);
+        ChronoLocalDate date = chrono.date(refDate);
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
+            ChronoLocalDate date2 = chrono2.date(refDate);
             TemporalAdjuster adjuster = new FixedAdjuster(date2);
             if (chrono != chrono2) {
                 try {
@@ -121,20 +117,20 @@
                 }
             } else {
                 // Same chronology,
-                ChronoLocalDate<?> result = date.with(adjuster);
+                ChronoLocalDate result = date.with(adjuster);
                 assertEquals(result, date2, "WithAdjuster failed to replace date");
             }
         }
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusAdjusterChrono(Chrono<?> chrono) {
+    public void test_badPlusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
-        ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
-            ChronoLocalDate<?> date2 = chrono2.date(refDate);
-            TemporalAdder adjuster = new FixedAdjuster(date2);
+        ChronoLocalDate date = chrono.date(refDate);
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
+            ChronoLocalDate date2 = chrono2.date(refDate);
+            TemporalAmount adjuster = new FixedAdjuster(date2);
             if (chrono != chrono2) {
                 try {
                     date.plus(adjuster);
@@ -144,20 +140,20 @@
                 }
             } else {
                 // Same chronology,
-                ChronoLocalDate<?> result = date.plus(adjuster);
+                ChronoLocalDate result = date.plus(adjuster);
                 assertEquals(result, date2, "WithAdjuster failed to replace date");
             }
         }
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusAdjusterChrono(Chrono<?> chrono) {
+    public void test_badMinusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
-        ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
-            ChronoLocalDate<?> date2 = chrono2.date(refDate);
-            TemporalSubtractor adjuster = new FixedAdjuster(date2);
+        ChronoLocalDate date = chrono.date(refDate);
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
+            ChronoLocalDate date2 = chrono2.date(refDate);
+            TemporalAmount adjuster = new FixedAdjuster(date2);
             if (chrono != chrono2) {
                 try {
                     date.minus(adjuster);
@@ -167,19 +163,19 @@
                 }
             } else {
                 // Same chronology,
-                ChronoLocalDate<?> result = date.minus(adjuster);
+                ChronoLocalDate result = date.minus(adjuster);
                 assertEquals(result, date2, "WithAdjuster failed to replace date");
             }
         }
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusTemporalUnitChrono(Chrono<?> chrono) {
+    public void test_badPlusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
-        ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
-            ChronoLocalDate<?> date2 = chrono2.date(refDate);
+        ChronoLocalDate date = chrono.date(refDate);
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
+            ChronoLocalDate date2 = chrono2.date(refDate);
             TemporalUnit adjuster = new FixedTemporalUnit(date2);
             if (chrono != chrono2) {
                 try {
@@ -191,19 +187,19 @@
                 }
             } else {
                 // Same chronology,
-                ChronoLocalDate<?> result = date.plus(1, adjuster);
+                ChronoLocalDate result = date.plus(1, adjuster);
                 assertEquals(result, date2, "WithAdjuster failed to replace date");
             }
         }
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusTemporalUnitChrono(Chrono<?> chrono) {
+    public void test_badMinusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
-        ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
-            ChronoLocalDate<?> date2 = chrono2.date(refDate);
+        ChronoLocalDate date = chrono.date(refDate);
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
+            ChronoLocalDate date2 = chrono2.date(refDate);
             TemporalUnit adjuster = new FixedTemporalUnit(date2);
             if (chrono != chrono2) {
                 try {
@@ -215,19 +211,19 @@
                 }
             } else {
                 // Same chronology,
-                ChronoLocalDate<?> result = date.minus(1, adjuster);
+                ChronoLocalDate result = date.minus(1, adjuster);
                 assertEquals(result, date2, "WithAdjuster failed to replace date");
             }
         }
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badTemporalFieldChrono(Chrono<?> chrono) {
+    public void test_badTemporalFieldChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
-        ChronoLocalDate<?> date = chrono.date(refDate);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
-            ChronoLocalDate<?> date2 = chrono2.date(refDate);
+        ChronoLocalDate date = chrono.date(refDate);
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
+            ChronoLocalDate date2 = chrono2.date(refDate);
             TemporalField adjuster = new FixedTemporalField(date2);
             if (chrono != chrono2) {
                 try {
@@ -239,7 +235,7 @@
                 }
             } else {
                 // Same chronology,
-                ChronoLocalDate<?> result = date.with(adjuster, 1);
+                ChronoLocalDate result = date.with(adjuster, 1);
                 assertEquals(result, date2, "TemporalField doWith() failed to replace date");
             }
         }
@@ -249,10 +245,10 @@
     // isBefore, isAfter, isEqual, DATE_COMPARATOR
     //-----------------------------------------------------------------------
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_date_comparisons(Chrono<?> chrono) {
-        List<ChronoLocalDate<?>> dates = new ArrayList<>();
+    public void test_date_comparisons(Chronology chrono) {
+        List<ChronoLocalDate> dates = new ArrayList<>();
 
-        ChronoLocalDate<?> date = chrono.date(LocalDate.of(1900, 1, 1));
+        ChronoLocalDate date = chrono.date(LocalDate.of(1900, 1, 1));
 
         // Insert dates in order, no duplicates
         dates.add(date.minus(1000, ChronoUnit.YEARS));
@@ -272,18 +268,18 @@
         dates.add(date.plus(1000, ChronoUnit.YEARS));
 
         // Check these dates against the corresponding dates for every calendar
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            List<ChronoLocalDate<?>> otherDates = new ArrayList<>();
-            Chrono<?> chrono2 = clist[0];
-            for (ChronoLocalDate<?> d : dates) {
+        for (Chronology[] clist : data_of_calendars()) {
+            List<ChronoLocalDate> otherDates = new ArrayList<>();
+            Chronology chrono2 = clist[0];
+            for (ChronoLocalDate d : dates) {
                 otherDates.add(chrono2.date(d));
             }
 
             // Now compare  the sequence of original dates with the sequence of converted dates
             for (int i = 0; i < dates.size(); i++) {
-                ChronoLocalDate<?> a = dates.get(i);
+                ChronoLocalDate a = dates.get(i);
                 for (int j = 0; j < otherDates.size(); j++) {
-                    ChronoLocalDate<?> b = otherDates.get(j);
+                    ChronoLocalDate b = otherDates.get(j);
                     int cmp = ChronoLocalDate.DATE_COMPARATOR.compare(a, b);
                     if (i < j) {
                         assertTrue(cmp < 0, a + " compare " + b);
@@ -307,8 +303,8 @@
     }
 
     public void test_date_comparator_checkGenerics_ISO() {
-        List<ChronoLocalDate<ISOChrono>> dates = new ArrayList<>();
-        ChronoLocalDate<ISOChrono> date = LocalDate.of(1900, 1, 1);
+        List<LocalDate> dates = new ArrayList<>();
+        LocalDate date = LocalDate.of(1900, 1, 1);
 
         // Insert dates in order, no duplicates
         dates.add(date.minus(10, ChronoUnit.YEARS));
@@ -323,7 +319,7 @@
         dates.add(date.plus(1, ChronoUnit.YEARS));
         dates.add(date.plus(10, ChronoUnit.YEARS));
 
-        List<ChronoLocalDate<ISOChrono>> copy = new ArrayList<>(dates);
+        List<LocalDate> copy = new ArrayList<>(dates);
         Collections.shuffle(copy);
         Collections.sort(copy, ChronoLocalDate.DATE_COMPARATOR);
         assertEquals(copy, dates);
@@ -358,9 +354,9 @@
     // Test Serialization of ISO via chrono API
     //-----------------------------------------------------------------------
     @Test( groups={"tck"}, dataProvider="calendars")
-    public <C extends Chrono<C>> void test_ChronoSerialization(C chrono) throws Exception {
+    public void test_ChronoSerialization(Chronology chrono) throws Exception {
         LocalDate ref = LocalDate.of(2000, 1, 5);
-        ChronoLocalDate<C> orginal = chrono.date(ref);
+        ChronoLocalDate orginal = chrono.date(ref);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream(baos);
         out.writeObject(orginal);
@@ -368,7 +364,7 @@
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         ObjectInputStream in = new ObjectInputStream(bais);
         @SuppressWarnings("unchecked")
-        ChronoLocalDate<C> ser = (ChronoLocalDate<C>) in.readObject();
+        ChronoLocalDate ser = (ChronoLocalDate) in.readObject();
         assertEquals(ser, orginal, "deserialized date is wrong");
     }
 
@@ -376,7 +372,7 @@
      * FixedAdjusted returns a fixed Temporal in all adjustments.
      * Construct an adjuster with the Temporal that should be returned from adjust.
      */
-    static class FixedAdjuster implements TemporalAdjuster, TemporalAdder, TemporalSubtractor {
+    static class FixedAdjuster implements TemporalAdjuster, TemporalAmount {
         private Temporal datetime;
 
         FixedAdjuster(Temporal datetime) {
@@ -398,11 +394,21 @@
             return datetime;
         }
 
+        @Override
+        public long get(TemporalUnit unit) {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public List<TemporalUnit> getUnits() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
     }
 
     /**
      * FixedTemporalUnit returns a fixed Temporal in all adjustments.
-     * Construct an FixedTemporalUnit with the Temporal that should be returned from doPlus.
+     * Construct an FixedTemporalUnit with the Temporal that should be returned from addTo.
      */
     static class FixedTemporalUnit implements TemporalUnit {
         private Temporal temporal;
@@ -427,25 +433,25 @@
         }
 
         @Override
-        public boolean isSupported(Temporal temporal) {
+        public boolean isSupportedBy(Temporal temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) {
+        public <R extends Temporal> R addTo(R temporal, long amount) {
             return (R) this.temporal;
         }
 
         @Override
-        public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) {
+        public long between(Temporal temporal1, Temporal temporal2) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
     }
 
     /**
      * FixedTemporalField returns a fixed Temporal in all adjustments.
-     * Construct an FixedTemporalField with the Temporal that should be returned from doWith.
+     * Construct an FixedTemporalField with the Temporal that should be returned from adjustInto.
      */
     static class FixedTemporalField implements TemporalField {
         private Temporal temporal;
@@ -474,30 +480,24 @@
         }
 
         @Override
-        public boolean doIsSupported(TemporalAccessor temporal) {
+        public boolean isSupportedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public ValueRange doRange(TemporalAccessor temporal) {
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public long doGet(TemporalAccessor temporal) {
+        public long getFrom(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doWith(R temporal, long newValue) {
+        public <R extends Temporal> R adjustInto(R temporal, long newValue) {
             return (R) this.temporal;
         }
-
-        @Override
-        public boolean resolve(DateTimeBuilder builder, long value) {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
     }
 }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TestChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/temporal/TestChronoLocalDateTime.java
index c51be6c..46335ce 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TestChronoLocalDateTime.java
+++ b/jdk/test/java/time/tck/java/time/temporal/TestChronoLocalDateTime.java
@@ -63,31 +63,28 @@
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
-import java.time.temporal.Chrono;
-import java.time.temporal.ChronoLocalDateTime;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.SimplePeriod;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.ValueRange;
 import java.time.temporal.TemporalUnit;
-import java.time.temporal.ISOChrono;
-import java.time.calendar.HijrahChrono;
-import java.time.calendar.JapaneseChrono;
-import java.time.calendar.MinguoChrono;
-import java.time.calendar.ThaiBuddhistChrono;
+import java.time.temporal.ValueRange;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
@@ -103,21 +100,21 @@
     // regular data factory for names and descriptions of available calendars
     //-----------------------------------------------------------------------
     @DataProvider(name = "calendars")
-    Chrono<?>[][] data_of_calendars() {
-        return new Chrono<?>[][]{
-                    {HijrahChrono.INSTANCE},
-                    {ISOChrono.INSTANCE},
-                    {JapaneseChrono.INSTANCE},
-                    {MinguoChrono.INSTANCE},
-                    {ThaiBuddhistChrono.INSTANCE}};
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+                    {HijrahChronology.INSTANCE},
+                    {IsoChronology.INSTANCE},
+                    {JapaneseChronology.INSTANCE},
+                    {MinguoChronology.INSTANCE},
+                    {ThaiBuddhistChronology.INSTANCE}};
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badWithAdjusterChrono(Chrono<?> chrono) {
+    public void test_badWithAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime<?> cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
             TemporalAdjuster adjuster = new FixedAdjuster(cdt2);
             if (chrono != chrono2) {
@@ -137,13 +134,13 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusAdjusterChrono(Chrono<?> chrono) {
+    public void test_badPlusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime<?> cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
-            TemporalAdder adjuster = new FixedAdjuster(cdt2);
+            TemporalAmount adjuster = new FixedAdjuster(cdt2);
             if (chrono != chrono2) {
                 try {
                     cdt.plus(adjuster);
@@ -161,13 +158,13 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusAdjusterChrono(Chrono<?> chrono) {
+    public void test_badMinusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime<?> cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
-            TemporalSubtractor adjuster = new FixedAdjuster(cdt2);
+            TemporalAmount adjuster = new FixedAdjuster(cdt2);
             if (chrono != chrono2) {
                 try {
                     cdt.minus(adjuster);
@@ -185,11 +182,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusTemporalUnitChrono(Chrono<?> chrono) {
+    public void test_badPlusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime<?> cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
             TemporalUnit adjuster = new FixedTemporalUnit(cdt2);
             if (chrono != chrono2) {
@@ -209,11 +206,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusTemporalUnitChrono(Chrono<?> chrono) {
+    public void test_badMinusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime<?> cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
             TemporalUnit adjuster = new FixedTemporalUnit(cdt2);
             if (chrono != chrono2) {
@@ -233,11 +230,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badTemporalFieldChrono(Chrono<?> chrono) {
+    public void test_badTemporalFieldChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoLocalDateTime<?> cdt = chrono.date(refDate).atTime(LocalTime.NOON);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON);
             TemporalField adjuster = new FixedTemporalField(cdt2);
             if (chrono != chrono2) {
@@ -260,7 +257,7 @@
     // isBefore, isAfter, isEqual
     //-----------------------------------------------------------------------
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_datetime_comparisons(Chrono<?> chrono) {
+    public void test_datetime_comparisons(Chronology chrono) {
         List<ChronoLocalDateTime<?>> dates = new ArrayList<>();
 
         ChronoLocalDateTime<?> date = chrono.date(LocalDate.of(1900, 1, 1)).atTime(LocalTime.MIN);
@@ -287,11 +284,11 @@
         dates.add(date.plus(100, ChronoUnit.YEARS));
 
         // Check these dates against the corresponding dates for every calendar
-        for (Chrono<?>[] clist : data_of_calendars()) {
+        for (Chronology[] clist : data_of_calendars()) {
             List<ChronoLocalDateTime<?>> otherDates = new ArrayList<>();
-            Chrono<?> chrono2 = clist[0];
+            Chronology chrono2 = clist[0];
             for (ChronoLocalDateTime<?> d : dates) {
-                otherDates.add(chrono2.date(d).atTime(d.getTime()));
+                otherDates.add(chrono2.date(d).atTime(d.toLocalTime()));
             }
 
             // Now compare  the sequence of original dates with the sequence of converted dates
@@ -325,9 +322,9 @@
     // Test Serialization of ISO via chrono API
     //-----------------------------------------------------------------------
     @Test( groups={"tck"}, dataProvider="calendars")
-    public <C extends Chrono<C>> void test_ChronoLocalDateTimeSerialization(C chrono) throws Exception {
+    public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception {
         LocalDateTime ref = LocalDate.of(2000, 1, 5).atTime(12, 1, 2, 3);
-        ChronoLocalDateTime<C> orginal = chrono.date(ref).atTime(ref.getTime());
+        ChronoLocalDateTime<?> orginal = chrono.date(ref).atTime(ref.toLocalTime());
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream(baos);
         out.writeObject(orginal);
@@ -335,7 +332,7 @@
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         ObjectInputStream in = new ObjectInputStream(bais);
         @SuppressWarnings("unchecked")
-        ChronoLocalDateTime<C> ser = (ChronoLocalDateTime<C>) in.readObject();
+        ChronoLocalDateTime<?> ser = (ChronoLocalDateTime<?>) in.readObject();
         assertEquals(ser, orginal, "deserialized date is wrong");
     }
 
@@ -343,7 +340,7 @@
      * FixedAdjusted returns a fixed Temporal in all adjustments.
      * Construct an adjuster with the Temporal that should be returned from adjust.
      */
-    static class FixedAdjuster implements TemporalAdjuster, TemporalAdder, TemporalSubtractor {
+    static class FixedAdjuster implements TemporalAdjuster, TemporalAmount {
         private Temporal datetime;
 
         FixedAdjuster(Temporal datetime) {
@@ -365,11 +362,21 @@
             return datetime;
         }
 
+        @Override
+        public long get(TemporalUnit unit) {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public List<TemporalUnit> getUnits() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
     }
 
     /**
      * FixedTemporalUnit returns a fixed Temporal in all adjustments.
-     * Construct an FixedTemporalUnit with the Temporal that should be returned from doPlus.
+     * Construct an FixedTemporalUnit with the Temporal that should be returned from addTo.
      */
     static class FixedTemporalUnit implements TemporalUnit {
         private Temporal temporal;
@@ -394,25 +401,25 @@
         }
 
         @Override
-        public boolean isSupported(Temporal temporal) {
+        public boolean isSupportedBy(Temporal temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) {
+        public <R extends Temporal> R addTo(R temporal, long amount) {
             return (R) this.temporal;
         }
 
         @Override
-        public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) {
+        public long between(Temporal temporal1, Temporal temporal2) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
     }
 
     /**
      * FixedTemporalField returns a fixed Temporal in all adjustments.
-     * Construct an FixedTemporalField with the Temporal that should be returned from doWith.
+     * Construct an FixedTemporalField with the Temporal that should be returned from adjustInto.
      */
     static class FixedTemporalField implements TemporalField {
         private Temporal temporal;
@@ -441,30 +448,24 @@
         }
 
         @Override
-        public boolean doIsSupported(TemporalAccessor temporal) {
+        public boolean isSupportedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public ValueRange doRange(TemporalAccessor temporal) {
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public long doGet(TemporalAccessor temporal) {
+        public long getFrom(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doWith(R temporal, long newValue) {
+        public <R extends Temporal> R adjustInto(R temporal, long newValue) {
             return (R) this.temporal;
         }
-
-        @Override
-        public boolean resolve(DateTimeBuilder builder, long value) {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
     }
 }
diff --git a/jdk/test/java/time/tck/java/time/temporal/TestChronoZonedDateTime.java b/jdk/test/java/time/tck/java/time/temporal/TestChronoZonedDateTime.java
index e89725b..c97a018 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TestChronoZonedDateTime.java
+++ b/jdk/test/java/time/tck/java/time/temporal/TestChronoZonedDateTime.java
@@ -63,33 +63,30 @@
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
-import java.time.temporal.Chrono;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoZonedDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ChronoZonedDateTime;
-import java.time.temporal.SimplePeriod;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.TemporalAdder;
 import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.ValueRange;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.TemporalUnit;
-import java.time.calendar.HijrahChrono;
-import java.time.calendar.JapaneseChrono;
-import java.time.calendar.MinguoChrono;
-import java.time.calendar.ThaiBuddhistChrono;
+import java.time.temporal.ValueRange;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
@@ -105,22 +102,22 @@
     // regular data factory for names and descriptions of available calendars
     //-----------------------------------------------------------------------
     @DataProvider(name = "calendars")
-    Chrono<?>[][] data_of_calendars() {
-        return new Chrono<?>[][]{
-                    {HijrahChrono.INSTANCE},
-                    {ISOChrono.INSTANCE},
-                    {JapaneseChrono.INSTANCE},
-                    {MinguoChrono.INSTANCE},
-                    {ThaiBuddhistChrono.INSTANCE},
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+                    {HijrahChronology.INSTANCE},
+                    {IsoChronology.INSTANCE},
+                    {JapaneseChronology.INSTANCE},
+                    {MinguoChronology.INSTANCE},
+                    {ThaiBuddhistChronology.INSTANCE},
         };
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badWithAdjusterChrono(Chrono<?> chrono) {
+    public void test_badWithAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoZonedDateTime<?> czdt = chrono.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoZonedDateTime<?> czdt2 = chrono2.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
             TemporalAdjuster adjuster = new FixedAdjuster(czdt2);
             if (chrono != chrono2) {
@@ -139,13 +136,13 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusAdjusterChrono(Chrono<?> chrono) {
+    public void test_badPlusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoZonedDateTime<?> czdt = chrono.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoZonedDateTime<?> czdt2 = chrono2.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
-            TemporalAdder adjuster = new FixedAdjuster(czdt2);
+            TemporalAmount adjuster = new FixedAdjuster(czdt2);
             if (chrono != chrono2) {
                 try {
                     czdt.plus(adjuster);
@@ -163,13 +160,13 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusAdjusterChrono(Chrono<?> chrono) {
+    public void test_badMinusAdjusterChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoZonedDateTime<?> czdt = chrono.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoZonedDateTime<?> czdt2 = chrono2.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
-            TemporalSubtractor adjuster = new FixedAdjuster(czdt2);
+            TemporalAmount adjuster = new FixedAdjuster(czdt2);
             if (chrono != chrono2) {
                 try {
                     czdt.minus(adjuster);
@@ -187,11 +184,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badPlusTemporalUnitChrono(Chrono<?> chrono) {
+    public void test_badPlusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoZonedDateTime<?> czdt = chrono.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoZonedDateTime<?> czdt2 = chrono2.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
             TemporalUnit adjuster = new FixedTemporalUnit(czdt2);
             if (chrono != chrono2) {
@@ -211,11 +208,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badMinusTemporalUnitChrono(Chrono<?> chrono) {
+    public void test_badMinusTemporalUnitChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoZonedDateTime<?> czdt = chrono.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoZonedDateTime<?> czdt2 = chrono2.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
             TemporalUnit adjuster = new FixedTemporalUnit(czdt2);
             if (chrono != chrono2) {
@@ -235,11 +232,11 @@
     }
 
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_badTemporalFieldChrono(Chrono<?> chrono) {
+    public void test_badTemporalFieldChrono(Chronology chrono) {
         LocalDate refDate = LocalDate.of(1900, 1, 1);
         ChronoZonedDateTime<?> czdt = chrono.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
-        for (Chrono<?>[] clist : data_of_calendars()) {
-            Chrono<?> chrono2 = clist[0];
+        for (Chronology[] clist : data_of_calendars()) {
+            Chronology chrono2 = clist[0];
             ChronoZonedDateTime<?> czdt2 = chrono2.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC);
             TemporalField adjuster = new FixedTemporalField(czdt2);
             if (chrono != chrono2) {
@@ -259,10 +256,10 @@
     }
 
     //-----------------------------------------------------------------------
-    // isBefore, isAfter, isEqual, INSTANT_COMPARATOR  test a Chrono<?> against the other Chronos
+    // isBefore, isAfter, isEqual, INSTANT_COMPARATOR  test a Chronology against the other Chronos
     //-----------------------------------------------------------------------
     @Test(groups={"tck"}, dataProvider="calendars")
-    public void test_zonedDateTime_comparisons(Chrono<?> chrono) {
+    public void test_zonedDateTime_comparisons(Chronology chrono) {
         List<ChronoZonedDateTime<?>> dates = new ArrayList<>();
 
         ChronoZonedDateTime<?> date = chrono.date(LocalDate.of(1900, 1, 1))
@@ -291,11 +288,11 @@
         dates.add(date.plus(100, ChronoUnit.YEARS));
 
         // Check these dates against the corresponding dates for every calendar
-        for (Chrono<?>[] clist : data_of_calendars()) {
+        for (Chronology[] clist : data_of_calendars()) {
             List<ChronoZonedDateTime<?>> otherDates = new ArrayList<>();
-            Chrono<?> chrono2 = ISOChrono.INSTANCE; //clist[0];
+            Chronology chrono2 = IsoChronology.INSTANCE; //clist[0];
             for (ChronoZonedDateTime<?> d : dates) {
-                otherDates.add(chrono2.date(d).atTime(d.getTime()).atZone(d.getZone()));
+                otherDates.add(chrono2.date(d).atTime(d.toLocalTime()).atZone(d.getZone()));
             }
 
             // Now compare  the sequence of original dates with the sequence of converted dates
@@ -329,9 +326,9 @@
     // Test Serialization of ISO via chrono API
     //-----------------------------------------------------------------------
     @Test( groups={"tck"}, dataProvider="calendars")
-    public <C extends Chrono<C>> void test_ChronoZonedDateTimeSerialization(C chrono) throws Exception {
+    public void test_ChronoZonedDateTimeSerialization(Chronology chrono) throws Exception {
         ZonedDateTime ref = LocalDate.of(2000, 1, 5).atTime(12, 1, 2, 3).atZone(ZoneId.of("GMT+01:23"));
-        ChronoZonedDateTime<C> orginal = chrono.date(ref).atTime(ref.getTime()).atZone(ref.getZone());
+        ChronoZonedDateTime<?> orginal = chrono.date(ref).atTime(ref.toLocalTime()).atZone(ref.getZone());
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream(baos);
         out.writeObject(orginal);
@@ -339,7 +336,7 @@
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         ObjectInputStream in = new ObjectInputStream(bais);
         @SuppressWarnings("unchecked")
-        ChronoZonedDateTime<C> ser = (ChronoZonedDateTime<C>) in.readObject();
+        ChronoZonedDateTime<?> ser = (ChronoZonedDateTime<?>) in.readObject();
         assertEquals(ser, orginal, "deserialized date is wrong");
     }
 
@@ -348,7 +345,7 @@
      * FixedAdjusted returns a fixed Temporal in all adjustments.
      * Construct an adjuster with the Temporal that should be returned from adjust.
      */
-    static class FixedAdjuster implements TemporalAdjuster, TemporalAdder, TemporalSubtractor {
+    static class FixedAdjuster implements TemporalAdjuster, TemporalAmount {
         private Temporal datetime;
 
         FixedAdjuster(Temporal datetime) {
@@ -370,11 +367,21 @@
             return datetime;
         }
 
+        @Override
+        public long get(TemporalUnit unit) {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public List<TemporalUnit> getUnits() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
     }
 
     /**
      * FixedTemporalUnit returns a fixed Temporal in all adjustments.
-     * Construct an FixedTemporalUnit with the Temporal that should be returned from doPlus.
+     * Construct an FixedTemporalUnit with the Temporal that should be returned from addTo.
      */
     static class FixedTemporalUnit implements TemporalUnit {
         private Temporal temporal;
@@ -399,25 +406,25 @@
         }
 
         @Override
-        public boolean isSupported(Temporal temporal) {
+        public boolean isSupportedBy(Temporal temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) {
+        public <R extends Temporal> R addTo(R temporal, long amount) {
             return (R) this.temporal;
         }
 
         @Override
-        public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) {
+        public long between(Temporal temporal1, Temporal temporal2) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
     }
 
     /**
      * FixedTemporalField returns a fixed Temporal in all adjustments.
-     * Construct an FixedTemporalField with the Temporal that should be returned from doWith.
+     * Construct an FixedTemporalField with the Temporal that should be returned from adjustInto.
      */
     static class FixedTemporalField implements TemporalField {
         private Temporal temporal;
@@ -446,30 +453,24 @@
         }
 
         @Override
-        public boolean doIsSupported(TemporalAccessor temporal) {
+        public boolean isSupportedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public ValueRange doRange(TemporalAccessor temporal) {
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @Override
-        public long doGet(TemporalAccessor temporal) {
+        public long getFrom(TemporalAccessor temporal) {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
         @SuppressWarnings("unchecked")
         @Override
-        public <R extends Temporal> R doWith(R temporal, long newValue) {
+        public <R extends Temporal> R adjustInto(R temporal, long newValue) {
             return (R) this.temporal;
         }
-
-        @Override
-        public boolean resolve(DateTimeBuilder builder, long value) {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
     }
 }
diff --git a/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java b/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java
index 08617ba..3cf6053 100644
--- a/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java
+++ b/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java
@@ -59,9 +59,6 @@
  */
 package tck.java.time.zone;
 
-import java.time.zone.*;
-import test.java.time.zone.*;
-
 import static org.testng.Assert.assertEquals;
 
 import java.io.ByteArrayInputStream;
@@ -75,7 +72,10 @@
 import java.time.LocalTime;
 import java.time.Month;
 import java.time.ZoneOffset;
+import java.time.zone.ZoneOffsetTransition;
+import java.time.zone.ZoneOffsetTransitionRule;
 import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
+import java.time.zone.ZoneRules;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java
index 36dc4ba..f98b82f 100644
--- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java
+++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java
@@ -59,19 +59,15 @@
  */
 package tck.java.time.zone;
 
-import java.time.temporal.Year;
-import java.time.zone.*;
-
 import static java.time.temporal.ChronoUnit.HOURS;
 import static org.testng.Assert.assertEquals;
 
-import java.io.IOException;
-
 import tck.java.time.AbstractTCKTest;
 import java.time.Duration;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
-
+import java.time.Year;
+import java.time.zone.ZoneOffsetTransition;
 import org.testng.annotations.Test;
 
 /**
diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java
index f98d714..c98ddf0 100644
--- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java
+++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java
@@ -59,22 +59,16 @@
  */
 package tck.java.time.zone;
 
-import java.time.ZoneId;
-import java.time.zone.*;
-import test.java.time.zone.*;
-
 import static org.testng.Assert.assertEquals;
 
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
 import tck.java.time.AbstractTCKTest;
 import java.time.DayOfWeek;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Month;
 import java.time.ZoneOffset;
+import java.time.zone.ZoneOffsetTransition;
+import java.time.zone.ZoneOffsetTransitionRule;
 import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
 
 import org.testng.annotations.Test;
diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java
index 294e2e0..5feac51 100644
--- a/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java
+++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java
@@ -59,9 +59,6 @@
  */
 package tck.java.time.zone;
 
-import java.time.temporal.Year;
-import java.time.zone.*;
-
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
@@ -81,10 +78,14 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Month;
+import java.time.Year;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.time.zone.ZoneOffsetTransition;
+import java.time.zone.ZoneOffsetTransitionRule;
 import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
+import java.time.zone.ZoneRules;
 
 import org.testng.annotations.Test;
 
@@ -142,7 +143,7 @@
         Instant instant = old.toInstant();
         ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(0, -1, -15);
         assertEquals(test.getOffset(instant), offset);
-        checkOffset(test, old.getDateTime(), offset, 1);
+        checkOffset(test, old.toLocalDateTime(), offset, 1);
         assertEquals(test.getStandardOffset(instant), offset);
         assertEquals(test.getDaylightSavings(instant), Duration.ZERO);
         assertEquals(test.isDaylightSavings(instant), false);
@@ -522,7 +523,7 @@
         Instant instant = old.toInstant();
         ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(0, 9, 21);
         assertEquals(test.getOffset(instant), offset);
-        checkOffset(test, old.getDateTime(), offset, 1);
+        checkOffset(test, old.toLocalDateTime(), offset, 1);
         assertEquals(test.getStandardOffset(instant), offset);
         assertEquals(test.getDaylightSavings(instant), Duration.ZERO);
         assertEquals(test.isDaylightSavings(instant), false);
@@ -672,13 +673,13 @@
         ZonedDateTime zdt = createZDT(1840, 1, 1, ZoneOffset.UTC);
         while (zdt.getYear() < 2010) {
             Instant instant = zdt.toInstant();
-            if (zdt.getDate().isBefore(LocalDate.of(1911, 3, 11))) {
+            if (zdt.toLocalDate().isBefore(LocalDate.of(1911, 3, 11))) {
                 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHoursMinutesSeconds(0, 9, 21));
-            } else if (zdt.getDate().isBefore(LocalDate.of(1940, 6, 14))) {
+            } else if (zdt.toLocalDate().isBefore(LocalDate.of(1940, 6, 14))) {
                 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO);
-            } else if (zdt.getDate().isBefore(LocalDate.of(1944, 8, 25))) {
+            } else if (zdt.toLocalDate().isBefore(LocalDate.of(1944, 8, 25))) {
                 assertEquals(test.getStandardOffset(instant), OFFSET_PONE);
-            } else if (zdt.getDate().isBefore(LocalDate.of(1945, 9, 16))) {
+            } else if (zdt.toLocalDate().isBefore(LocalDate.of(1945, 9, 16))) {
                 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO);
             } else {
                 assertEquals(test.getStandardOffset(instant), OFFSET_PONE);
@@ -705,7 +706,7 @@
         Instant instant = old.toInstant();
         ZoneOffset offset = ZoneOffset.of("-04:56:02");
         assertEquals(test.getOffset(instant), offset);
-        checkOffset(test, old.getDateTime(), offset, 1);
+        checkOffset(test, old.toLocalDateTime(), offset, 1);
         assertEquals(test.getStandardOffset(instant), offset);
         assertEquals(test.getDaylightSavings(instant), Duration.ZERO);
         assertEquals(test.isDaylightSavings(instant), false);
@@ -878,7 +879,7 @@
         ZonedDateTime dateTime = createZDT(1860, 1, 1, ZoneOffset.UTC);
         while (dateTime.getYear() < 2010) {
             Instant instant = dateTime.toInstant();
-            if (dateTime.getDate().isBefore(LocalDate.of(1883, 11, 18))) {
+            if (dateTime.toLocalDate().isBefore(LocalDate.of(1883, 11, 18))) {
                 assertEquals(test.getStandardOffset(instant), ZoneOffset.of("-04:56:02"));
             } else {
                 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHours(-5));
diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneRulesProvider.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneRulesProvider.java
index 2d245f6..a808126 100644
--- a/jdk/test/java/time/tck/java/time/zone/TCKZoneRulesProvider.java
+++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneRulesProvider.java
@@ -59,8 +59,7 @@
  */
 package tck.java.time.zone;
 
-import java.time.zone.*;
-import test.java.time.zone.*;
+import java.time.ZoneId;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -73,6 +72,9 @@
 import java.util.TreeMap;
 
 import java.time.ZoneOffset;
+import java.time.zone.ZoneRules;
+import java.time.zone.ZoneRulesException;
+import java.time.zone.ZoneRulesProvider;
 
 import org.testng.annotations.Test;
 
@@ -87,7 +89,7 @@
     //-----------------------------------------------------------------------
     // getAvailableZoneIds()
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_getAvailableGroupIds() {
         Set<String> zoneIds = ZoneRulesProvider.getAvailableZoneIds();
         assertEquals(zoneIds.contains("Europe/London"), true);
@@ -98,34 +100,48 @@
     }
 
     //-----------------------------------------------------------------------
-    // getRules(String)
+    // getRules(String, boolean)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
-    public void test_getRules_String() {
-        ZoneRules rules = ZoneRulesProvider.getRules("Europe/London");
+    @Test
+    public void test_getRules_StringBoolean() {
+        ZoneRules rules = ZoneRulesProvider.getRules("Europe/London", false);
         assertNotNull(rules);
-        ZoneRules rules2 = ZoneRulesProvider.getRules("Europe/London");
+        ZoneRules rules2 = ZoneRulesProvider.getRules("Europe/London", false);
         assertEquals(rules2, rules);
     }
 
-    @Test(groups={"tck"}, expectedExceptions=ZoneRulesException.class)
-    public void test_getRules_String_unknownId() {
-        ZoneRulesProvider.getRules("Europe/Lon");
+    @Test(expectedExceptions=ZoneRulesException.class)
+    public void test_getRules_StringBoolean_unknownId() {
+        ZoneRulesProvider.getRules("Europe/Lon", false);
     }
 
-    @Test(groups={"tck"}, expectedExceptions=NullPointerException.class)
-    public void test_getRules_String_null() {
-        ZoneRulesProvider.getRules(null);
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_getRules_StringBoolean_null() {
+        ZoneRulesProvider.getRules(null, false);
+    }
+
+    @Test
+    public void test_getRules_StringBoolean_dynamic() {
+        MockDynamicProvider dynamicProvider = new MockDynamicProvider();
+        ZoneRulesProvider.registerProvider(dynamicProvider);
+
+        assertEquals(dynamicProvider.count, 0);
+        ZoneRules rules1 = ZoneId.of("DynamicLocation").getRules();
+        assertEquals(dynamicProvider.count, 2);
+        assertEquals(rules1, dynamicProvider.BASE);
+        ZoneRules rules2 = ZoneId.of("DynamicLocation").getRules();
+        assertEquals(dynamicProvider.count, 4);
+        assertEquals(rules2, dynamicProvider.ALTERNATE);
     }
 
     //-----------------------------------------------------------------------
     // getVersions(String)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_getVersions_String() {
         NavigableMap<String, ZoneRules> versions = ZoneRulesProvider.getVersions("Europe/London");
         assertTrue(versions.size() >= 1);
-        ZoneRules rules = ZoneRulesProvider.getRules("Europe/London");
+        ZoneRules rules = ZoneRulesProvider.getRules("Europe/London", false);
         assertEquals(versions.lastEntry().getValue(), rules);
 
         NavigableMap<String, ZoneRules> copy = new TreeMap<>(versions);
@@ -135,12 +151,12 @@
         assertEquals(versions2, copy);
     }
 
-    @Test(groups={"tck"}, expectedExceptions=ZoneRulesException.class)
+    @Test(expectedExceptions=ZoneRulesException.class)
     public void test_getVersions_String_unknownId() {
         ZoneRulesProvider.getVersions("Europe/Lon");
     }
 
-    @Test(groups={"tck"}, expectedExceptions=NullPointerException.class)
+    @Test(expectedExceptions=NullPointerException.class)
     public void test_getVersions_String_null() {
         ZoneRulesProvider.getVersions(null);
     }
@@ -148,7 +164,7 @@
     //-----------------------------------------------------------------------
     // refresh()
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_refresh() {
         assertEquals(ZoneRulesProvider.refresh(), false);
     }
@@ -164,8 +180,7 @@
         assertEquals(pre.contains("FooLocation"), false);
         Set<String> post = ZoneRulesProvider.getAvailableZoneIds();
         assertEquals(post.contains("FooLocation"), true);
-
-        assertEquals(ZoneRulesProvider.getRules("FooLocation"), ZoneOffset.of("+01:45").getRules());
+        assertEquals(ZoneRulesProvider.getRules("FooLocation", false), ZoneOffset.of("+01:45").getRules());
     }
 
     static class MockTempProvider extends ZoneRulesProvider {
@@ -175,17 +190,13 @@
             return new HashSet<String>(Collections.singleton("FooLocation"));
         }
         @Override
-        protected ZoneRulesProvider provideBind(String zoneId) {
-            return this;
-        }
-        @Override
         protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
             NavigableMap<String, ZoneRules> result = new TreeMap<>();
             result.put("BarVersion", rules);
             return result;
         }
         @Override
-        protected ZoneRules provideRules(String zoneId) {
+        protected ZoneRules provideRules(String zoneId, boolean forCaching) {
             if (zoneId.equals("FooLocation")) {
                 return rules;
             }
@@ -193,4 +204,31 @@
         }
     }
 
+    static class MockDynamicProvider extends ZoneRulesProvider {
+        final ZoneRules BASE = ZoneOffset.of("+01:15").getRules();
+        final ZoneRules ALTERNATE = ZoneOffset.of("+01:30").getRules();
+        int count = 0;
+        @Override
+        public Set<String> provideZoneIds() {
+            return new HashSet<>(Collections.singleton("DynamicLocation"));
+        }
+        @Override
+        protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
+            NavigableMap<String, ZoneRules> result = new TreeMap<>();
+            result.put("DynamicVersion1", BASE);
+            if (count > 2) {
+                result.put("DynamicVersion2", ALTERNATE);
+            }
+            return result;
+        }
+        @Override
+        protected ZoneRules provideRules(String zoneId, boolean forCaching) {
+            count++;
+            if (zoneId.equals("DynamicLocation")) {
+                return (forCaching ? null : (count > 2 ? ALTERNATE : BASE));
+            }
+            throw new ZoneRulesException("Invalid");
+        }
+    }
+
 }
diff --git a/jdk/test/java/time/test/java/time/MockSimplePeriod.java b/jdk/test/java/time/test/java/time/MockSimplePeriod.java
index 1c5d872..662c8b1 100644
--- a/jdk/test/java/time/test/java/time/MockSimplePeriod.java
+++ b/jdk/test/java/time/test/java/time/MockSimplePeriod.java
@@ -68,15 +68,16 @@
 import java.util.Objects;
 
 import java.time.temporal.Temporal;
-import java.time.temporal.TemporalSubtractor;
-import java.time.temporal.TemporalAdder;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalAmount;
 import java.time.temporal.TemporalUnit;
+import java.util.List;
 
 /**
  * Mock period of time measured using a single unit, such as {@code 3 Days}.
  */
 public final class MockSimplePeriod
-        implements TemporalAdder, TemporalSubtractor, Comparable<MockSimplePeriod> {
+        implements TemporalAmount, Comparable<MockSimplePeriod> {
 
     /**
      * A constant for a period of zero, measured in days.
@@ -119,6 +120,16 @@
         this.unit = unit;
     }
 
+    @Override
+    public long get(TemporalUnit unit) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public List<TemporalUnit> getUnits() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
     //-----------------------------------------------------------------------
     public long getAmount() {
         return amount;
diff --git a/jdk/test/java/time/test/java/time/TestDuration.java b/jdk/test/java/time/test/java/time/TestDuration.java
index 2b2d810..786bfc0 100644
--- a/jdk/test/java/time/test/java/time/TestDuration.java
+++ b/jdk/test/java/time/test/java/time/TestDuration.java
@@ -218,18 +218,12 @@
                 Duration b = durations[j];
                 if (i < j) {
                     assertEquals(a.compareTo(b)< 0, true, a + " <=> " + b);
-                    assertEquals(a.isLessThan(b), true, a + " <=> " + b);
-                    assertEquals(a.isGreaterThan(b), false, a + " <=> " + b);
                     assertEquals(a.equals(b), false, a + " <=> " + b);
                 } else if (i > j) {
                     assertEquals(a.compareTo(b) > 0, true, a + " <=> " + b);
-                    assertEquals(a.isLessThan(b), false, a + " <=> " + b);
-                    assertEquals(a.isGreaterThan(b), true, a + " <=> " + b);
                     assertEquals(a.equals(b), false, a + " <=> " + b);
                 } else {
                     assertEquals(a.compareTo(b), 0, a + " <=> " + b);
-                    assertEquals(a.isLessThan(b), false, a + " <=> " + b);
-                    assertEquals(a.isGreaterThan(b), false, a + " <=> " + b);
                     assertEquals(a.equals(b), true, a + " <=> " + b);
                 }
             }
diff --git a/jdk/test/java/time/test/java/time/TestLocalDateTime.java b/jdk/test/java/time/test/java/time/TestLocalDateTime.java
index d850be5..90c3927 100644
--- a/jdk/test/java/time/test/java/time/TestLocalDateTime.java
+++ b/jdk/test/java/time/test/java/time/TestLocalDateTime.java
@@ -124,15 +124,15 @@
     @Test(groups={"implementation"})
     public void test_withYear_int_noChange() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.withYear(2007);
-        assertSame(t.getDate(), TEST_2007_07_15_12_30_40_987654321.getDate());
-        assertSame(t.getTime(), TEST_2007_07_15_12_30_40_987654321.getTime());
+        assertSame(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate());
+        assertSame(t.toLocalTime(), TEST_2007_07_15_12_30_40_987654321.toLocalTime());
     }
 
     @Test(groups={"implementation"})
     public void test_withMonth_int_noChange() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.withMonth(7);
-        assertSame(t.getDate(), TEST_2007_07_15_12_30_40_987654321.getDate());
-        assertSame(t.getTime(), TEST_2007_07_15_12_30_40_987654321.getTime());
+        assertSame(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate());
+        assertSame(t.toLocalTime(), TEST_2007_07_15_12_30_40_987654321.toLocalTime());
     }
 
     @Test(groups={"implementation"})
@@ -156,13 +156,13 @@
     @Test(groups={"implementation"})
     public void test_withHour_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(1, 0)).withHour(0);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_withHour_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(1, 0)).withHour(12);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -174,13 +174,13 @@
     @Test(groups={"implementation"})
     public void test_withMinute_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(0, 1)).withMinute(0);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_withMinute_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(12, 1)).withMinute(0);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -192,13 +192,13 @@
     @Test(groups={"implementation"})
     public void test_withSecond_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(0, 0, 1)).withSecond(0);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_withSecond_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(12, 0, 1)).withSecond(0);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -210,13 +210,13 @@
     @Test(groups={"implementation"})
     public void test_withNanoOfSecond_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(0, 0, 0, 1)).withNano(0);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_withNanoOfSecond_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(12, 0, 0, 1)).withNano(0);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -270,13 +270,13 @@
     @Test(groups={"implementation"})
     public void test_plusHours_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(23, 0)).plusHours(1);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_plusHours_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(11, 0)).plusHours(1);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -288,19 +288,19 @@
     @Test(groups={"implementation"})
     public void test_plusMinutes_noChange_oneDay_same() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusMinutes(24 * 60);
-        assertSame(t.getTime(), TEST_2007_07_15_12_30_40_987654321.getTime());
+        assertSame(t.toLocalTime(), TEST_2007_07_15_12_30_40_987654321.toLocalTime());
     }
 
     @Test(groups={"implementation"})
     public void test_plusMinutes_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(23, 59)).plusMinutes(1);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_plusMinutes_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(11, 59)).plusMinutes(1);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -312,19 +312,19 @@
     @Test(groups={"implementation"})
     public void test_plusSeconds_noChange_oneDay_same() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusSeconds(24 * 60 * 60);
-        assertSame(t.getTime(), TEST_2007_07_15_12_30_40_987654321.getTime());
+        assertSame(t.toLocalTime(), TEST_2007_07_15_12_30_40_987654321.toLocalTime());
     }
 
     @Test(groups={"implementation"})
     public void test_plusSeconds_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(23, 59, 59)).plusSeconds(1);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_plusSeconds_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(11, 59, 59)).plusSeconds(1);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -336,19 +336,19 @@
     @Test(groups={"implementation"})
     public void test_plusNanos_noChange_oneDay_same() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusNanos(24 * 60 * 60 * 1000000000L);
-        assertSame(t.getTime(), TEST_2007_07_15_12_30_40_987654321.getTime());
+        assertSame(t.toLocalTime(), TEST_2007_07_15_12_30_40_987654321.toLocalTime());
     }
 
     @Test(groups={"implementation"})
     public void test_plusNanos_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(23, 59, 59, 999999999)).plusNanos(1);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_plusNanos_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(11, 59, 59, 999999999)).plusNanos(1);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -402,13 +402,13 @@
     @Test(groups={"implementation"})
     public void test_minusHours_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(1, 0)).minusHours(1);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_minusHours_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(13, 0)).minusHours(1);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -420,19 +420,19 @@
     @Test(groups={"implementation"})
     public void test_minusMinutes_noChange_oneDay_same() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusMinutes(24 * 60);
-        assertSame(t.getTime(), TEST_2007_07_15_12_30_40_987654321.getTime());
+        assertSame(t.toLocalTime(), TEST_2007_07_15_12_30_40_987654321.toLocalTime());
     }
 
     @Test(groups={"implementation"})
     public void test_minusMinutes_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(0, 1)).minusMinutes(1);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_minusMinutes_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(12, 1)).minusMinutes(1);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -444,20 +444,20 @@
     @Test(groups={"implementation"})
     public void test_minusSeconds_noChange_oneDay() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusSeconds(24 * 60 * 60);
-        assertEquals(t.getDate(), TEST_2007_07_15_12_30_40_987654321.getDate().minusDays(1));
-        assertSame(t.getTime(), TEST_2007_07_15_12_30_40_987654321.getTime());
+        assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1));
+        assertSame(t.toLocalTime(), TEST_2007_07_15_12_30_40_987654321.toLocalTime());
     }
 
     @Test(groups={"implementation"})
     public void test_minusSeconds_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(0, 0, 1)).minusSeconds(1);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_minusSeconds_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(12, 0, 1)).minusSeconds(1);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     @Test(groups={"implementation"})
@@ -469,40 +469,40 @@
     @Test(groups={"implementation"})
     public void test_minusNanos_noChange_oneDay() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusNanos(24 * 60 * 60 * 1000000000L);
-        assertEquals(t.getDate(), TEST_2007_07_15_12_30_40_987654321.getDate().minusDays(1));
-        assertSame(t.getTime(), TEST_2007_07_15_12_30_40_987654321.getTime());
+        assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1));
+        assertSame(t.toLocalTime(), TEST_2007_07_15_12_30_40_987654321.toLocalTime());
     }
 
     @Test(groups={"implementation"})
     public void test_minusNanos_toMidnight() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(0, 0, 0, 1)).minusNanos(1);
-        assertSame(t.getTime(), LocalTime.MIDNIGHT);
+        assertSame(t.toLocalTime(), LocalTime.MIDNIGHT);
     }
 
     @Test(groups={"implementation"})
     public void test_minusNanos_toMidday() {
         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(12, 0, 0, 1)).minusNanos(1);
-        assertSame(t.getTime(), LocalTime.NOON);
+        assertSame(t.toLocalTime(), LocalTime.NOON);
     }
 
     //-----------------------------------------------------------------------
-    // getDate()
+    // toLocalDate()
     //-----------------------------------------------------------------------
     @Test(dataProvider="sampleDates", groups={"implementation"})
     public void test_getDate(int year, int month, int day) {
         LocalDate d = LocalDate.of(year, month, day);
         LocalDateTime dt = LocalDateTime.of(d, LocalTime.MIDNIGHT);
-        assertSame(dt.getDate(), d);
+        assertSame(dt.toLocalDate(), d);
     }
 
     //-----------------------------------------------------------------------
-    // getTime()
+    // toLocalTime()
     //-----------------------------------------------------------------------
     @Test(dataProvider="sampleTimes", groups={"implementation"})
     public void test_getTime(int h, int m, int s, int ns) {
         LocalTime t = LocalTime.of(h, m, s, ns);
         LocalDateTime dt = LocalDateTime.of(LocalDate.of(2011, 7, 30), t);
-        assertSame(dt.getTime(), t);
+        assertSame(dt.toLocalTime(), t);
     }
 
     void test_comparisons_LocalDateTime(LocalDate... localDates) {
diff --git a/jdk/test/java/time/test/java/time/TestLocalTime.java b/jdk/test/java/time/test/java/time/TestLocalTime.java
index 0a0b277..47aa94a 100644
--- a/jdk/test/java/time/test/java/time/TestLocalTime.java
+++ b/jdk/test/java/time/test/java/time/TestLocalTime.java
@@ -168,15 +168,6 @@
     }
 
     @Test(groups={"implementation"})
-    public void factory_ofSecondOfDay7_long_int_singletons() {
-        for (int i = 0; i < 24; i++) {
-            LocalTime test1 = LocalTime.ofSecondOfDay(i * 60L * 60L, 0);
-            LocalTime test2 = LocalTime.of(i, 0);
-            assertSame(test1, test2);
-        }
-    }
-
-    @Test(groups={"implementation"})
     public void factory_ofNanoOfDay_singletons() {
         for (int i = 0; i < 24; i++) {
             LocalTime test1 = LocalTime.ofNanoOfDay(i * 1000000000L * 60L * 60L);
diff --git a/jdk/test/java/time/test/java/time/temporal/TestMonthDay.java b/jdk/test/java/time/test/java/time/TestMonthDay.java
similarity index 97%
rename from jdk/test/java/time/test/java/time/temporal/TestMonthDay.java
rename to jdk/test/java/time/test/java/time/TestMonthDay.java
index 002d4f7..ebfdc6d 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestMonthDay.java
+++ b/jdk/test/java/time/test/java/time/TestMonthDay.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package test.java.time;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertSame;
@@ -65,11 +65,10 @@
 
 import java.time.LocalDate;
 import java.time.Month;
-import java.time.temporal.MonthDay;
+import java.time.MonthDay;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-import test.java.time.AbstractTest;
 
 /**
  * Test MonthDay.
diff --git a/jdk/test/java/time/test/java/time/temporal/TestOffsetDateTime.java b/jdk/test/java/time/test/java/time/TestOffsetDateTime.java
similarity index 97%
rename from jdk/test/java/time/test/java/time/temporal/TestOffsetDateTime.java
rename to jdk/test/java/time/test/java/time/TestOffsetDateTime.java
index 9ee4672..7766b5f 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestOffsetDateTime.java
+++ b/jdk/test/java/time/test/java/time/TestOffsetDateTime.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package test.java.time;
 
 import static org.testng.Assert.assertSame;
 
@@ -65,13 +65,11 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.ZoneOffset;
-import java.time.temporal.OffsetDateTime;
+import java.time.OffsetDateTime;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import test.java.time.AbstractTest;
-import test.java.time.MockSimplePeriod;
 
 /**
  * Test OffsetDateTime.
@@ -114,9 +112,9 @@
         OffsetDateTime a = OffsetDateTime.of(localDateTime, offset);
 
         assertSame(a.getOffset(), offset);
-        assertSame(a.getDate(), localDate);
-        assertSame(a.getTime(), localTime);
-        assertSame(a.getDateTime(), localDateTime);
+        assertSame(a.toLocalDate(), localDate);
+        assertSame(a.toLocalTime(), localTime);
+        assertSame(a.toLocalDateTime(), localDateTime);
     }
 
     //-----------------------------------------------------------------------
@@ -126,7 +124,7 @@
     public void test_withOffsetSameLocal() {
         OffsetDateTime base = OffsetDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 59), OFFSET_PONE);
         OffsetDateTime test = base.withOffsetSameLocal(OFFSET_PTWO);
-        assertSame(test.getDateTime(), base.getDateTime());
+        assertSame(test.toLocalDateTime(), base.toLocalDateTime());
         assertSame(test.getOffset(), OFFSET_PTWO);
     }
 
diff --git a/jdk/test/java/time/test/java/time/temporal/TestOffsetDateTime_instants.java b/jdk/test/java/time/test/java/time/TestOffsetDateTime_instants.java
similarity index 98%
rename from jdk/test/java/time/test/java/time/temporal/TestOffsetDateTime_instants.java
rename to jdk/test/java/time/test/java/time/TestOffsetDateTime_instants.java
index 7922c37..86c887ac 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestOffsetDateTime_instants.java
+++ b/jdk/test/java/time/test/java/time/TestOffsetDateTime_instants.java
@@ -57,7 +57,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package test.java.time;
 
 import java.time.DateTimeException;
 import java.time.Instant;
@@ -66,15 +66,15 @@
 import java.time.Month;
 import java.time.ZoneOffset;
 
-import java.time.temporal.OffsetDateTime;
-import java.time.temporal.Year;
+import java.time.OffsetDateTime;
+import java.time.Year;
 
 import static org.testng.Assert.assertEquals;
 
 import org.testng.annotations.Test;
 
 /**
- * Test OffsetDate creation.
+ * Test OffsetDateTime creation.
  */
 @Test
 public class TestOffsetDateTime_instants {
@@ -243,7 +243,7 @@
             try {
                 OffsetDateTime test = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
                 assertEquals(test, expected);
-                if (expected.getDate().equals(maxDate) == false) {
+                if (expected.toLocalDate().equals(maxDate) == false) {
                     expected = expected.plusDays(1);
                 }
             } catch (RuntimeException|Error ex) {
diff --git a/jdk/test/java/time/test/java/time/temporal/TestOffsetTime.java b/jdk/test/java/time/test/java/time/TestOffsetTime.java
similarity index 96%
rename from jdk/test/java/time/test/java/time/temporal/TestOffsetTime.java
rename to jdk/test/java/time/test/java/time/TestOffsetTime.java
index d6e9eff..41116a7 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestOffsetTime.java
+++ b/jdk/test/java/time/test/java/time/TestOffsetTime.java
@@ -57,12 +57,11 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package test.java.time;
 
-import java.time.temporal.OffsetTime;
+import java.time.OffsetTime;
 
 import org.testng.annotations.Test;
-import test.java.time.AbstractTest;
 
 /**
  * Test OffsetTime.
diff --git a/jdk/test/java/time/test/java/time/TestPeriod.java b/jdk/test/java/time/test/java/time/TestPeriod.java
index f7caf9e..6559947 100644
--- a/jdk/test/java/time/test/java/time/TestPeriod.java
+++ b/jdk/test/java/time/test/java/time/TestPeriod.java
@@ -59,35 +59,11 @@
  */
 package test.java.time;
 
-import static java.time.temporal.ChronoUnit.DAYS;
-import static java.time.temporal.ChronoUnit.HALF_DAYS;
-import static java.time.temporal.ChronoUnit.HOURS;
-import static java.time.temporal.ChronoUnit.MICROS;
-import static java.time.temporal.ChronoUnit.MILLIS;
-import static java.time.temporal.ChronoUnit.MINUTES;
-import static java.time.temporal.ChronoUnit.MONTHS;
-import static java.time.temporal.ChronoUnit.NANOS;
-import static java.time.temporal.ChronoUnit.SECONDS;
-import static java.time.temporal.ChronoUnit.YEARS;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-
-import java.time.DateTimeException;
-import java.time.Duration;
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.Month;
 import java.time.Period;
-import java.time.temporal.YearMonth;
 
-import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 /**
@@ -96,39 +72,6 @@
 @Test
 public class TestPeriod extends AbstractTest {
 
-    //-----------------------------------------------------------------------
-    // basics
-    //-----------------------------------------------------------------------
-    public void test_interfaces() {
-        assertTrue(Serializable.class.isAssignableFrom(Period.class));
-    }
-
-    @DataProvider(name="serialization")
-    Object[][] data_serialization() {
-        return new Object[][] {
-            {Period.ZERO},
-            {Period.of(0, DAYS)},
-            {Period.of(1, DAYS)},
-            {Period.of(1, 2, 3, 4, 5, 6)},
-        };
-    }
-
-    @Test(dataProvider="serialization")
-    public void test_serialization(Period period) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(baos);
-        oos.writeObject(period);
-        oos.close();
-
-        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
-                baos.toByteArray()));
-        if (period.isZero()) {
-            assertSame(ois.readObject(), period);
-        } else {
-            assertEquals(ois.readObject(), period);
-        }
-    }
-
     @Test
     public void test_immutable() {
         assertImmutable(Period.class);
@@ -139,1437 +82,24 @@
     //-----------------------------------------------------------------------
     public void factory_zeroSingleton() {
         assertSame(Period.ZERO, Period.ZERO);
-        assertSame(Period.of(0, 0, 0, 0, 0, 0), Period.ZERO);
-        assertSame(Period.of(0, 0, 0, 0, 0, 0, 0), Period.ZERO);
-        assertSame(Period.ofDate(0, 0, 0), Period.ZERO);
-        assertSame(Period.ofTime(0, 0, 0), Period.ZERO);
-        assertSame(Period.ofTime(0, 0, 0, 0), Period.ZERO);
-        assertSame(Period.of(0, YEARS), Period.ZERO);
-        assertSame(Period.of(0, MONTHS), Period.ZERO);
-        assertSame(Period.of(0, DAYS), Period.ZERO);
-        assertSame(Period.of(0, HOURS), Period.ZERO);
-        assertSame(Period.of(0, MINUTES), Period.ZERO);
-        assertSame(Period.of(0, SECONDS), Period.ZERO);
-        assertSame(Period.of(0, NANOS), Period.ZERO);
+        assertSame(Period.ofYears(0), Period.ZERO);
+        assertSame(Period.ofMonths(0), Period.ZERO);
+        assertSame(Period.ofDays(0), Period.ZERO);
+        assertSame(Period.of(0, 0, 0), Period.ZERO);
     }
 
     //-----------------------------------------------------------------------
-    // of(PeriodProvider)
-    //-----------------------------------------------------------------------
-    public void factory_of_ints() {
-        assertPeriod(Period.of(1, 2, 3, 4, 5, 6), 1, 2, 3, 4, 5, 6, 0);
-        assertPeriod(Period.of(0, 2, 3, 4, 5, 6), 0, 2, 3, 4, 5, 6, 0);
-        assertPeriod(Period.of(1, 0, 0, 0, 0, 0), 1, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(0, 0, 0, 0, 0, 0), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(-1, -2, -3, -4, -5, -6), -1, -2, -3, -4, -5, -6, 0);
-    }
-
-    //-----------------------------------------------------------------------
-    // ofDate
-    //-----------------------------------------------------------------------
-    public void factory_ofDate_ints() {
-        assertPeriod(Period.ofDate(1, 2, 3), 1, 2, 3, 0, 0, 0, 0);
-        assertPeriod(Period.ofDate(0, 2, 3), 0, 2, 3, 0, 0, 0, 0);
-        assertPeriod(Period.ofDate(1, 0, 0), 1, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.ofDate(0, 0, 0), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.ofDate(-1, -2, -3), -1, -2, -3, 0, 0, 0, 0);
-    }
-
-    //-----------------------------------------------------------------------
-    // ofTime
-    //-----------------------------------------------------------------------
-    public void factory_ofTime_3ints() {
-        assertPeriod(Period.ofTime(1, 2, 3), 0, 0, 0, 1, 2, 3, 0);
-        assertPeriod(Period.ofTime(0, 2, 3), 0, 0, 0, 0, 2, 3, 0);
-        assertPeriod(Period.ofTime(1, 0, 0), 0, 0, 0, 1, 0, 0, 0);
-        assertPeriod(Period.ofTime(0, 0, 0), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.ofTime(-1, -2, -3), 0, 0, 0, -1, -2, -3, 0);
-    }
-
-    public void factory_ofTime_4ints() {
-        assertPeriod(Period.ofTime(1, 2, 3, 4), 0, 0, 0, 1, 2, 3, 4);
-        assertPeriod(Period.ofTime(0, 2, 3, 4), 0, 0, 0, 0, 2, 3, 4);
-        assertPeriod(Period.ofTime(1, 0, 0, 0), 0, 0, 0, 1, 0, 0, 0);
-        assertPeriod(Period.ofTime(0, 0, 0, 0), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.ofTime(-1, -2, -3, -4), 0, 0, 0, -1, -2, -3, -4);
-    }
-
-    //-----------------------------------------------------------------------
-    // of one field
-    //-----------------------------------------------------------------------
-    public void test_factory_of_intPeriodUnit() {
-        assertEquals(Period.of(1, YEARS), Period.of(1, YEARS));
-        assertEquals(Period.of(2, MONTHS), Period.of(2, MONTHS));
-        assertEquals(Period.of(3, DAYS), Period.of(3, DAYS));
-
-        assertEquals(Period.of(1, HALF_DAYS), Period.of(12, HOURS));
-        assertEquals(Period.of(Integer.MAX_VALUE / (3600 * 8), HOURS), Period.of(Integer.MAX_VALUE / (3600 * 8), HOURS));
-        assertEquals(Period.of(-1, MINUTES), Period.of(-1, MINUTES));
-        assertEquals(Period.of(-2, SECONDS), Period.of(-2, SECONDS));
-        assertEquals(Period.of(Integer.MIN_VALUE, NANOS), Period.of(Integer.MIN_VALUE, NANOS));
-        assertEquals(Period.of(2, MILLIS), Period.of(2000000, NANOS));
-        assertEquals(Period.of(2, MICROS), Period.of(2000, NANOS));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_factory_of_intPeriodUnit_null() {
-        Period.of(1, null);
-    }
-
-    //-----------------------------------------------------------------------
-    public void factory_years() {
-        assertPeriod(Period.of(1, YEARS), 1, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(0, YEARS), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(-1, YEARS), -1, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(Integer.MAX_VALUE, YEARS), Integer.MAX_VALUE, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(Integer.MIN_VALUE, YEARS), Integer.MIN_VALUE, 0, 0, 0, 0, 0, 0);
-    }
-
-    public void factory_months() {
-        assertPeriod(Period.of(1, MONTHS), 0, 1, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(0, MONTHS), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(-1, MONTHS), 0, -1, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(Integer.MAX_VALUE, MONTHS), 0, Integer.MAX_VALUE, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(Integer.MIN_VALUE, MONTHS), 0, Integer.MIN_VALUE, 0, 0, 0, 0, 0);
-    }
-
-    public void factory_days() {
-        assertPeriod(Period.of(1, DAYS), 0, 0, 1, 0, 0, 0, 0);
-        assertPeriod(Period.of(0, DAYS), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(-1, DAYS), 0, 0, -1, 0, 0, 0, 0);
-        assertPeriod(Period.of(Integer.MAX_VALUE, DAYS), 0, 0, Integer.MAX_VALUE, 0, 0, 0, 0);
-        assertPeriod(Period.of(Integer.MIN_VALUE, DAYS), 0, 0, Integer.MIN_VALUE, 0, 0, 0, 0);
-    }
-
-    public void factory_hours() {
-        assertPeriod(Period.of(1, HOURS), 0, 0, 0, 1, 0, 0, 0);
-        assertPeriod(Period.of(0, HOURS), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(-1, HOURS), 0, 0, 0, -1, 0, 0, 0);
-        assertPeriod(Period.of(Integer.MAX_VALUE / (3600 * 8), HOURS), 0, 0, 0, Integer.MAX_VALUE / (3600 * 8), 0, 0, 0);
-        assertPeriod(Period.of(Integer.MIN_VALUE / (3600 * 8), HOURS), 0, 0, 0, Integer.MIN_VALUE / (3600 * 8), 0, 0, 0);
-    }
-
-    public void factory_minutes() {
-        assertPeriod(Period.of(1, MINUTES), 0, 0, 0, 0, 1, 0, 0);
-        assertPeriod(Period.of(0, MINUTES), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(-1, MINUTES), 0, 0, 0, 0, -1, 0, 0);
-        int val = Integer.MAX_VALUE / (60 * 8);
-        assertPeriod(Period.of(val, MINUTES), 0, 0, 0,
-                        (int) (val / 60L),
-                        (int) (val % 60),
-                        0, 0);
-        val = Integer.MIN_VALUE / (60 * 8);
-        assertPeriod(Period.of(val, MINUTES), 0, 0, 0,
-                        (int) (val / 60L),
-                        (int) (val % 60),
-                        0, 0);
-    }
-
-    public void factory_seconds() {
-        assertPeriod(Period.of(1, SECONDS), 0, 0, 0, 0, 0, 1, 0);
-        assertPeriod(Period.of(0, SECONDS), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(-1, SECONDS), 0, 0, 0, 0, 0, -1, 0);
-        assertPeriod(Period.of(Integer.MAX_VALUE, SECONDS), 0, 0, 0,
-                        (int) (Integer.MAX_VALUE / 3600L),
-                        (int) ((Integer.MAX_VALUE / 60L) % 60),
-                        (int) (Integer.MAX_VALUE % 60),
-                        0);
-        assertPeriod(Period.of(Integer.MIN_VALUE, SECONDS), 0, 0, 0,
-                        (int) (Integer.MIN_VALUE / 3600L),
-                        (int) ((Integer.MIN_VALUE / 60L) % 60),
-                        (int) (Integer.MIN_VALUE % 60),
-                        0);
-    }
-
-    public void factory_nanos() {
-        assertPeriod(Period.of(1, NANOS), 0, 0, 0, 0, 0, 0, 1);
-        assertPeriod(Period.of(0, NANOS), 0, 0, 0, 0, 0, 0, 0);
-        assertPeriod(Period.of(-1, NANOS), 0, 0, 0, 0, 0, 0, -1);
-        assertPeriod(Period.of(Long.MAX_VALUE, NANOS), 0, 0, 0,
-                        (int) (Long.MAX_VALUE / 3600_000_000_000L),
-                        (int) ((Long.MAX_VALUE / 60_000_000_000L) % 60),
-                        (int) ((Long.MAX_VALUE / 1_000_000_000L) % 60),
-                        Long.MAX_VALUE % 1_000_000_000L);
-        assertPeriod(Period.of(Long.MIN_VALUE, NANOS), 0, 0, 0,
-                        (int) (Long.MIN_VALUE / 3600_000_000_000L),
-                        (int) ((Long.MIN_VALUE / 60_000_000_000L) % 60),
-                        (int) ((Long.MIN_VALUE / 1_000_000_000L) % 60),
-                        Long.MIN_VALUE % 1_000_000_000L);
-    }
-
-    //-----------------------------------------------------------------------
-    // of(Duration)
-    //-----------------------------------------------------------------------
-    public void factory_duration() {
-        assertPeriod(Period.of(Duration.ofSeconds(2, 3)), 0, 0, 0, 0, 0, 2, 3);
-        assertPeriod(Period.of(Duration.ofSeconds(59, 3)), 0, 0, 0, 0, 0, 59, 3);
-        assertPeriod(Period.of(Duration.ofSeconds(60, 3)), 0, 0, 0, 0, 1, 0, 3);
-        assertPeriod(Period.of(Duration.ofSeconds(61, 3)), 0, 0, 0, 0, 1, 1, 3);
-        assertPeriod(Period.of(Duration.ofSeconds(3599, 3)), 0, 0, 0, 0, 59, 59, 3);
-        assertPeriod(Period.of(Duration.ofSeconds(3600, 3)), 0, 0, 0, 1, 0, 0, 3);
-    }
-
-    public void factory_duration_negative() {
-        assertPeriod(Period.of(Duration.ofSeconds(-2, 3)), 0, 0, 0, 0, 0, -1, -999999997);
-        assertPeriod(Period.of(Duration.ofSeconds(-59, 3)), 0, 0, 0, 0, 0, -58, -999999997);
-        assertPeriod(Period.of(Duration.ofSeconds(-60, 3)), 0, 0, 0, 0, 0, -59, -999999997);
-        assertPeriod(Period.of(Duration.ofSeconds(-60, -3)), 0, 0, 0, 0, -1, 0, -3);
-
-        assertPeriod(Period.of(Duration.ofSeconds(2, -3)), 0, 0, 0, 0, 0, 1, 999999997);
-    }
-
-    public void factory_duration_big() {
-        Duration dur = Duration.ofSeconds(Integer.MAX_VALUE, 3);
-        long secs = Integer.MAX_VALUE;
-        assertPeriod(Period.of(dur), 0, 0, 0, (int) (secs / 3600), (int) ((secs % 3600) / 60), (int) (secs % 60), 3);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void factory_duration_null() {
-        Period.of((Duration) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // between
-    //-----------------------------------------------------------------------
-    @DataProvider(name="betweenDates")
-    Object[][] data_betweenDates() {
-        return new Object[][] {
-            {2010, 1, 1, 2010, 1, 1,  0, 0, 0},
-            {2010, 1, 1, 2010, 1, 2,  0, 0, 1},
-            {2010, 1, 1, 2010, 2, 1,  0, 1, 0},
-            {2010, 1, 1, 2010, 2, 2,  0, 1, 1},
-            {2010, 1, 1, 2011, 1, 1,  1, 0, 0},
-
-            {2010, 6, 12, 2010, 1, 1,  0, -5, -11},
-            {2010, 6, 12, 2010, 1, 2,  0, -5, -10},
-            {2010, 6, 12, 2010, 2, 1,  0, -4, -11},
-            {2010, 6, 12, 2010, 9, 24,  0, 3, 12},
-
-            {2010, 6, 12, 2009, 1, 1,  -1, -5, -11},
-            {2010, 6, 12, 2009, 1, 2,  -1, -5, -10},
-            {2010, 6, 12, 2009, 2, 1,  -1, -4, -11},
-            {2010, 6, 12, 2009, 9, 24,  0, -9, 12},
-
-            {2010, 6, 12, 2008, 1, 1,  -2, -5, -11},
-            {2010, 6, 12, 2008, 1, 2,  -2, -5, -10},
-            {2010, 6, 12, 2008, 2, 1,  -2, -4, -11},
-            {2010, 6, 12, 2008, 9, 24,  -1, -9, 12},
-        };
-    }
-
-    @Test(dataProvider="betweenDates")
-    public void factory_between_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
-        LocalDate start = LocalDate.of(y1, m1, d1);
-        LocalDate end = LocalDate.of(y2, m2, d2);
-        Period test = Period.between(start, end);
-        assertPeriod(test, ye, me, de, 0, 0, 0, 0);
-        //assertEquals(start.plus(test), end);
-    }
-
-    @DataProvider(name="betweenTimes")
-    Object[][] data_betweenTimes() {
-        return new Object[][] {
-            {12, 30, 40, 12, 30, 45,  0, 0, 5},
-            {12, 30, 40, 12, 35, 40,  0, 5, 0},
-            {12, 30, 40, 13, 30, 40,  1, 0, 0},
-
-            {12, 30, 40, 12, 30, 35,  0, 0, -5},
-            {12, 30, 40, 12, 25, 40,  0, -5, 0},
-            {12, 30, 40, 11, 30, 40,  -1, 0, 0},
-        };
-    }
-
-    @Test(dataProvider="betweenTimes")
-    public void factory_between_LocalTime(int h1, int m1, int s1, int h2, int m2, int s2, int he, int me, int se) {
-        LocalTime start = LocalTime.of(h1, m1, s1);
-        LocalTime end = LocalTime.of(h2, m2, s2);
-        Period test = Period.between(start, end);
-        assertPeriod(test, 0, 0, 0, he, me, se, 0);
-        //assertEquals(start.plus(test), end);
-    }
-
-    public void factory_between_YearMonth() {
-        assertPeriod(Period.between(YearMonth.of(2012, 6), YearMonth.of(2013, 7)), 1, 1, 0, 0, 0, 0, 0);
-        assertPeriod(Period.between(YearMonth.of(2012, 6), YearMonth.of(2013, 3)), 0, 9, 0, 0, 0, 0, 0);
-        assertPeriod(Period.between(YearMonth.of(2012, 6), YearMonth.of(2011, 7)), 0, -11, 0, 0, 0, 0, 0);
-    }
-
-    public void factory_between_Month() {
-        assertPeriod(Period.between(Month.FEBRUARY, Month.MAY), 0, 3, 0, 0, 0, 0, 0);
-        assertPeriod(Period.between(Month.NOVEMBER, Month.MAY), 0, -6, 0, 0, 0, 0, 0);
-    }
-
-    //-----------------------------------------------------------------------
-    // betweenISO
-    //-----------------------------------------------------------------------
-    @DataProvider(name="betweenISO")
-    Object[][] data_betweenISO() {
-        return new Object[][] {
-            {2010, 1, 1, 2010, 1, 1, 0, 0, 0},
-            {2010, 1, 1, 2010, 1, 2, 0, 0, 1},
-            {2010, 1, 1, 2010, 1, 31, 0, 0, 30},
-            {2010, 1, 1, 2010, 2, 1, 0, 1, 0},
-            {2010, 1, 1, 2010, 2, 28, 0, 1, 27},
-            {2010, 1, 1, 2010, 3, 1, 0, 2, 0},
-            {2010, 1, 1, 2010, 12, 31, 0, 11, 30},
-            {2010, 1, 1, 2011, 1, 1, 1, 0, 0},
-            {2010, 1, 1, 2011, 12, 31, 1, 11, 30},
-            {2010, 1, 1, 2012, 1, 1, 2, 0, 0},
-
-            {2010, 1, 10, 2010, 1, 1, 0, 0, -9},
-            {2010, 1, 10, 2010, 1, 2, 0, 0, -8},
-            {2010, 1, 10, 2010, 1, 9, 0, 0, -1},
-            {2010, 1, 10, 2010, 1, 10, 0, 0, 0},
-            {2010, 1, 10, 2010, 1, 11, 0, 0, 1},
-            {2010, 1, 10, 2010, 1, 31, 0, 0, 21},
-            {2010, 1, 10, 2010, 2, 1, 0, 0, 22},
-            {2010, 1, 10, 2010, 2, 9, 0, 0, 30},
-            {2010, 1, 10, 2010, 2, 10, 0, 1, 0},
-            {2010, 1, 10, 2010, 2, 28, 0, 1, 18},
-            {2010, 1, 10, 2010, 3, 1, 0, 1, 19},
-            {2010, 1, 10, 2010, 3, 9, 0, 1, 27},
-            {2010, 1, 10, 2010, 3, 10, 0, 2, 0},
-            {2010, 1, 10, 2010, 12, 31, 0, 11, 21},
-            {2010, 1, 10, 2011, 1, 1, 0, 11, 22},
-            {2010, 1, 10, 2011, 1, 9, 0, 11, 30},
-            {2010, 1, 10, 2011, 1, 10, 1, 0, 0},
-
-            {2010, 3, 30, 2011, 5, 1, 1, 1, 1},
-            {2010, 4, 30, 2011, 5, 1, 1, 0, 1},
-
-            {2010, 2, 28, 2012, 2, 27, 1, 11, 30},
-            {2010, 2, 28, 2012, 2, 28, 2, 0, 0},
-            {2010, 2, 28, 2012, 2, 29, 2, 0, 1},
-
-            {2012, 2, 28, 2014, 2, 27, 1, 11, 30},
-            {2012, 2, 28, 2014, 2, 28, 2, 0, 0},
-            {2012, 2, 28, 2014, 3, 1, 2, 0, 1},
-
-            {2012, 2, 29, 2014, 2, 28, 1, 11, 30},
-            {2012, 2, 29, 2014, 3, 1, 2, 0, 1},
-            {2012, 2, 29, 2014, 3, 2, 2, 0, 2},
-
-            {2012, 2, 29, 2016, 2, 28, 3, 11, 30},
-            {2012, 2, 29, 2016, 2, 29, 4, 0, 0},
-            {2012, 2, 29, 2016, 3, 1, 4, 0, 1},
-
-            {2010, 1, 1, 2009, 12, 31, 0, 0, -1},
-            {2010, 1, 1, 2009, 12, 30, 0, 0, -2},
-            {2010, 1, 1, 2009, 12, 2, 0, 0, -30},
-            {2010, 1, 1, 2009, 12, 1, 0, -1, 0},
-            {2010, 1, 1, 2009, 11, 30, 0, -1, -1},
-            {2010, 1, 1, 2009, 11, 2, 0, -1, -29},
-            {2010, 1, 1, 2009, 11, 1, 0, -2, 0},
-            {2010, 1, 1, 2009, 1, 2, 0, -11, -30},
-            {2010, 1, 1, 2009, 1, 1, -1, 0, 0},
-
-            {2010, 1, 15, 2010, 1, 15, 0, 0, 0},
-            {2010, 1, 15, 2010, 1, 14, 0, 0, -1},
-            {2010, 1, 15, 2010, 1, 1, 0, 0, -14},
-            {2010, 1, 15, 2009, 12, 31, 0, 0, -15},
-            {2010, 1, 15, 2009, 12, 16, 0, 0, -30},
-            {2010, 1, 15, 2009, 12, 15, 0, -1, 0},
-            {2010, 1, 15, 2009, 12, 14, 0, -1, -1},
-
-            {2010, 2, 28, 2009, 3, 1, 0, -11, -27},
-            {2010, 2, 28, 2009, 2, 28, -1, 0, 0},
-            {2010, 2, 28, 2009, 2, 27, -1, 0, -1},
-
-            {2010, 2, 28, 2008, 2, 29, -1, -11, -28},
-            {2010, 2, 28, 2008, 2, 28, -2, 0, 0},
-            {2010, 2, 28, 2008, 2, 27, -2, 0, -1},
-
-            {2012, 2, 29, 2009, 3, 1, -2, -11, -28},
-            {2012, 2, 29, 2009, 2, 28, -3, 0, -1},
-            {2012, 2, 29, 2009, 2, 27, -3, 0, -2},
-
-            {2012, 2, 29, 2008, 3, 1, -3, -11, -28},
-            {2012, 2, 29, 2008, 2, 29, -4, 0, 0},
-            {2012, 2, 29, 2008, 2, 28, -4, 0, -1},
-        };
-    }
-
-    @Test(dataProvider="betweenISO")
-    public void factory_betweenISO_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
-        LocalDate start = LocalDate.of(y1, m1, d1);
-        LocalDate end = LocalDate.of(y2, m2, d2);
-        Period test = Period.betweenISO(start, end);
-        assertPeriod(test, ye, me, de, 0, 0, 0, 0);
-        //assertEquals(start.plus(test), end);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void factory_betweenISO_LocalDate_nullFirst() {
-        Period.betweenISO((LocalDate) null, LocalDate.of(2010, 1, 1));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void factory_betweenISO_LocalDate_nullSecond() {
-        Period.betweenISO(LocalDate.of(2010, 1, 1), (LocalDate) null);
-    }
-
-    //-------------------------------------------------------------------------
-    @Test(expectedExceptions=NullPointerException.class)
-    public void factory_betweenISO_LocalTime_nullFirst() {
-        Period.betweenISO((LocalTime) null, LocalTime.of(12, 30));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void factory_betweenISO_LocalTime_nullSecond() {
-        Period.betweenISO(LocalTime.of(12, 30), (LocalTime) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // parse()
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="toStringAndParse")
-    public void test_parse(Period test, String expected) {
-        assertEquals(test, Period.parse(expected));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_parse_nullText() {
-        Period.parse((String) null);
-    }
-
-    //-----------------------------------------------------------------------
-    // isZero()
-    //-----------------------------------------------------------------------
-    public void test_isZero() {
-        assertEquals(Period.of(1, 2, 3, 4, 5, 6, 7).isZero(), false);
-        assertEquals(Period.of(1, 2, 3, 0, 0, 0, 0).isZero(), false);
-        assertEquals(Period.of(0, 0, 0, 4, 5, 6, 7).isZero(), false);
-        assertEquals(Period.of(1, 0, 0, 0, 0, 0, 0).isZero(), false);
-        assertEquals(Period.of(0, 2, 0, 0, 0, 0, 0).isZero(), false);
-        assertEquals(Period.of(0, 0, 3, 0, 0, 0, 0).isZero(), false);
-        assertEquals(Period.of(0, 0, 0, 4, 0, 0, 0).isZero(), false);
-        assertEquals(Period.of(0, 0, 0, 0, 5, 0, 0).isZero(), false);
-        assertEquals(Period.of(0, 0, 0, 0, 0, 6, 0).isZero(), false);
-        assertEquals(Period.of(0, 0, 0, 0, 0, 0, 7).isZero(), false);
-        assertEquals(Period.of(0, 0, 0, 0, 0, 0).isZero(), true);
-    }
-
-    //-----------------------------------------------------------------------
-    // isPositive()
-    //-----------------------------------------------------------------------
-    public void test_isPositive() {
-        assertEquals(Period.of(1, 2, 3, 4, 5, 6, 7).isPositive(), true);
-        assertEquals(Period.of(1, 2, 3, 0, 0, 0, 0).isPositive(), true);
-        assertEquals(Period.of(0, 0, 0, 4, 5, 6, 7).isPositive(), true);
-        assertEquals(Period.of(1, 0, 0, 0, 0, 0, 0).isPositive(), true);
-        assertEquals(Period.of(0, 2, 0, 0, 0, 0, 0).isPositive(), true);
-        assertEquals(Period.of(0, 0, 3, 0, 0, 0, 0).isPositive(), true);
-        assertEquals(Period.of(0, 0, 0, 4, 0, 0, 0).isPositive(), true);
-        assertEquals(Period.of(0, 0, 0, 0, 5, 0, 0).isPositive(), true);
-        assertEquals(Period.of(0, 0, 0, 0, 0, 6, 0).isPositive(), true);
-        assertEquals(Period.of(0, 0, 0, 0, 0, 0, 7).isPositive(), true);
-        assertEquals(Period.of(-1, -2, -3, -4, -5, -6, -7).isPositive(), false);
-        assertEquals(Period.of(-1, -2, 3, 4, -5, -6, -7).isPositive(), false);
-        assertEquals(Period.of(-1, 0, 0, 0, 0, 0, 0).isPositive(), false);
-        assertEquals(Period.of(0, -2, 0, 0, 0, 0, 0).isPositive(), false);
-        assertEquals(Period.of(0, 0, -3, 0, 0, 0, 0).isPositive(), false);
-        assertEquals(Period.of(0, 0, 0, -4, 0, 0, 0).isPositive(), false);
-        assertEquals(Period.of(0, 0, 0, 0, -5, 0, 0).isPositive(), false);
-        assertEquals(Period.of(0, 0, 0, 0, 0, -6, 0).isPositive(), false);
-        assertEquals(Period.of(0, 0, 0, 0, 0, 0, -7).isPositive(), false);
-        assertEquals(Period.of(0, 0, 0, 0, 0, 0).isPositive(), false);
-    }
-
-    //-----------------------------------------------------------------------
-    // withYears()
-    //-----------------------------------------------------------------------
-    public void test_withYears() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.withYears(10), 10, 2, 3, 4, 5, 6, 7);
-    }
-
-    public void test_withYears_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.withYears(1), test);
-    }
-
-    public void test_withYears_toZero() {
-        Period test = Period.of(1, YEARS);
-        assertSame(test.withYears(0), Period.ZERO);
-    }
-
-    //-----------------------------------------------------------------------
-    // withMonths()
-    //-----------------------------------------------------------------------
-    public void test_withMonths() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.withMonths(10), 1, 10, 3, 4, 5, 6, 7);
-    }
-
-    public void test_withMonths_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.withMonths(2), test);
-    }
-
-    public void test_withMonths_toZero() {
-        Period test = Period.of(1, MONTHS);
-        assertSame(test.withMonths(0), Period.ZERO);
-    }
-
-    //-----------------------------------------------------------------------
-    // withDays()
-    //-----------------------------------------------------------------------
-    public void test_withDays() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.withDays(10), 1, 2, 10, 4, 5, 6, 7);
-    }
-
-    public void test_withDays_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.withDays(3), test);
-    }
-
-    public void test_withDays_toZero() {
-        Period test = Period.of(1, DAYS);
-        assertSame(test.withDays(0), Period.ZERO);
-    }
-
-    //-----------------------------------------------------------------------
-    // withTimeNanos()
-    //-----------------------------------------------------------------------
-    public void test_withNanos() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.withTimeNanos(10), 1, 2, 3, 0, 0, 0, 10);
-    }
-
-    public void test_withNanos_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.withTimeNanos(((4 * 60 + 5) * 60 + 6) * 1_000_000_000L + 7), test);
-    }
-
-    public void test_withNanos_toZero() {
-        Period test = Period.of(1, NANOS);
-        assertSame(test.withTimeNanos(0), Period.ZERO);
-    }
-
-
-
-    //-----------------------------------------------------------------------
-    // plusYears()
-    //-----------------------------------------------------------------------
-    public void test_plusYears() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(10, YEARS), 11, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(Period.of(10, YEARS)), 11, 2, 3, 4, 5, 6, 7);
-    }
-
-    public void test_plusYears_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.plus(0, YEARS), test);
-        assertPeriod(test.plus(Period.of(0, YEARS)), 1, 2, 3, 4, 5, 6, 7);
-    }
-
-    public void test_plusYears_toZero() {
-        Period test = Period.of(-1, YEARS);
-        assertSame(test.plus(1, YEARS), Period.ZERO);
-        assertSame(test.plus(Period.of(1, YEARS)), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusYears_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE, YEARS);
-        test.plus(1, YEARS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusYears_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE, YEARS);
-        test.plus(-1, YEARS);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusMonths()
-    //-----------------------------------------------------------------------
-    public void test_plusMonths() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(10, MONTHS), 1, 12, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(Period.of(10, MONTHS)), 1, 12, 3, 4, 5, 6, 7);
-    }
-
-    public void test_plusMonths_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.plus(0, MONTHS), test);
-        assertEquals(test.plus(Period.of(0, MONTHS)), test);
-    }
-
-    public void test_plusMonths_toZero() {
-        Period test = Period.of(-1, MONTHS);
-        assertSame(test.plus(1, MONTHS), Period.ZERO);
-        assertSame(test.plus(Period.of(1, MONTHS)), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusMonths_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE, MONTHS);
-        test.plus(1, MONTHS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusMonths_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE, MONTHS);
-        test.plus(-1, MONTHS);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusDays()
-    //-----------------------------------------------------------------------
-    public void test_plusDays() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(10, DAYS), 1, 2, 13, 4, 5, 6, 7);
-    }
-
-    public void test_plusDays_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.plus(0, DAYS), test);
-    }
-
-    public void test_plusDays_toZero() {
-        Period test = Period.of(-1, DAYS);
-        assertSame(test.plus(1, DAYS), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusDays_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE, DAYS);
-        test.plus(1, DAYS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusDays_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE, DAYS);
-        test.plus(-1, DAYS);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusHours()
-    //-----------------------------------------------------------------------
-    public void test_plusHours() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(10, HOURS), 1, 2, 3, 14, 5, 6, 7);
-    }
-
-    public void test_plusHours_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.plus(0, HOURS), test);
-    }
-
-    public void test_plusHours_toZero() {
-        Period test = Period.of(-1, HOURS);
-        assertSame(test.plus(1, HOURS), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusHours_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE, HOURS);
-        test.plus(1, HOURS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusHours_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE, HOURS);
-        test.plus(-1, HOURS);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusMinutes()
-    //-----------------------------------------------------------------------
-    public void test_plusMinutes() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(10, MINUTES), 1, 2, 3, 4, 15, 6, 7);
-    }
-
-    public void test_plusMinutes_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.plus(0, MINUTES), test);
-    }
-
-    public void test_plusMinutes_toZero() {
-        Period test = Period.of(-1, MINUTES);
-        assertSame(test.plus(1, MINUTES), Period.ZERO);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusSeconds()
-    //-----------------------------------------------------------------------
-    public void test_plusSeconds() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(10, SECONDS), 1, 2, 3, 4, 5, 16, 7);
-    }
-
-    public void test_plusSeconds_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.plus(0, SECONDS), test);
-    }
-
-    public void test_plusSeconds_toZero() {
-        Period test = Period.of(-1, SECONDS);
-        assertSame(test.plus(1, SECONDS), Period.ZERO);
-    }
-
-    //-----------------------------------------------------------------------
-    // plusNanos()
-    //-----------------------------------------------------------------------
-    public void test_plusNanos() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.plus(10, NANOS), 1, 2, 3, 4, 5, 6, 17);
-    }
-
-    public void test_plusNanos_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.plus(0, NANOS), test);
-    }
-
-    public void test_plusNanos_toZero() {
-        Period test = Period.of(-1, NANOS);
-        assertSame(test.plus(1, NANOS), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusNanos_overflowTooBig() {
-        Period test = Period.of(Long.MAX_VALUE, NANOS);
-        test.plus(1, NANOS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_plusNanos_overflowTooSmall() {
-        Period test = Period.of(Long.MIN_VALUE, NANOS);
-        test.plus(-1, NANOS);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusYears()
-    //-----------------------------------------------------------------------
-    public void test_minusYears() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.minus(10, YEARS), -9, 2, 3, 4, 5, 6, 7);
-    }
-
-    public void test_minusYears_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.minus(0, YEARS), test);
-    }
-
-    public void test_minusYears_toZero() {
-        Period test = Period.of(1, YEARS);
-        assertSame(test.minus(1, YEARS), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusYears_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE, YEARS);
-        test.minus(-1, YEARS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusYears_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE, YEARS);
-        test.minus(1, YEARS);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusMonths()
-    //-----------------------------------------------------------------------
-    public void test_minusMonths() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.minus(10, MONTHS), 1, -8, 3, 4, 5, 6, 7);
-    }
-
-    public void test_minusMonths_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.minus(0, MONTHS), test);
-    }
-
-    public void test_minusMonths_toZero() {
-        Period test = Period.of(1, MONTHS);
-        assertSame(test.minus(1, MONTHS), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusMonths_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE, MONTHS);
-        test.minus(-1, MONTHS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusMonths_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE, MONTHS);
-        test.minus(1, MONTHS);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusDays()
-    //-----------------------------------------------------------------------
-    public void test_minusDays() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.minus(10, DAYS), 1, 2, -7, 4, 5, 6, 7);
-    }
-
-    public void test_minusDays_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.minus(0, DAYS), test);
-    }
-
-    public void test_minusDays_toZero() {
-        Period test = Period.of(1, DAYS);
-        assertSame(test.minus(1, DAYS), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusDays_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE, DAYS);
-        test.minus(-1, DAYS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusDays_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE, DAYS);
-        test.minus(1, DAYS);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusHours()
-    //-----------------------------------------------------------------------
-    public void test_minusHours() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.minus(10, HOURS), 1, 2, 3, -5, -54, -53, -999999993);
-        assertEquals(test.minus(10, HOURS).plus(10, HOURS), test);
-    }
-
-    public void test_minusHours_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.minus(0, HOURS), test);
-    }
-
-    public void test_minusHours_toZero() {
-        Period test = Period.of(1, HOURS);
-        assertSame(test.minus(1, HOURS), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusHours_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE, HOURS);
-        test.minus(-1, HOURS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusHours_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE, HOURS);
-        test.minus(1, HOURS);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusMinutes()
-    //-----------------------------------------------------------------------
-    public void test_minusMinutes() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.minus(10, MINUTES), 1, 2, 3, 3, 55, 6, 7);
-        assertEquals(test.minus(10, MINUTES).plus(10, MINUTES), test);
-    }
-
-    public void test_minusMinutes_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.minus(0, MINUTES), test);
-    }
-
-    public void test_minusMinutes_toZero() {
-        Period test = Period.of(1, MINUTES);
-        assertSame(test.minus(1, MINUTES), Period.ZERO);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusSeconds()
-    //-----------------------------------------------------------------------
-    public void test_minusSeconds() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.minus(10, SECONDS), 1, 2, 3, 4, 4, 56, 7);
-        assertEquals(test.minus(10, SECONDS).plus(10, SECONDS), test);
-    }
-
-    public void test_minusSeconds_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.minus(0, SECONDS), test);
-    }
-
-    public void test_minusSeconds_toZero() {
-        Period test = Period.of(1, SECONDS);
-        assertSame(test.minus(1, SECONDS), Period.ZERO);
-    }
-
-    //-----------------------------------------------------------------------
-    // minusNanos()
-    //-----------------------------------------------------------------------
-    public void test_minusNanos() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.minus(10, NANOS), 1, 2, 3, 4, 5, 5, 999999997);
-    }
-
-    public void test_minusNanos_noChange() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.minus(0, NANOS), test);
-    }
-
-    public void test_minusNanos_toZero() {
-        Period test = Period.of(1, NANOS);
-        assertSame(test.minus(1, NANOS), Period.ZERO);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusNanos_overflowTooBig() {
-        Period test = Period.of(Long.MAX_VALUE, NANOS);
-        test.minus(-1, NANOS);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_minusNanos_overflowTooSmall() {
-        Period test = Period.of(Long.MIN_VALUE, NANOS);
-        test.minus(1, NANOS);
-    }
-
-    //-----------------------------------------------------------------------
-    // multipliedBy()
-    //-----------------------------------------------------------------------
-    public void test_multipliedBy() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.multipliedBy(2), 2, 4, 6, 8, 10, 12, 14);
-        assertPeriod(test.multipliedBy(-3), -3, -6, -9, -12, -15, -18, -21);
-    }
-
-    public void test_multipliedBy_zeroBase() {
-        assertSame(Period.ZERO.multipliedBy(2), Period.ZERO);
-    }
-
-    public void test_multipliedBy_zero() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.multipliedBy(0), Period.ZERO);
-    }
-
-    public void test_multipliedBy_one() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertSame(test.multipliedBy(1), test);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_multipliedBy_overflowTooBig() {
-        Period test = Period.of(Integer.MAX_VALUE / 2 + 1, YEARS);
-        test.multipliedBy(2);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_multipliedBy_overflowTooSmall() {
-        Period test = Period.of(Integer.MIN_VALUE / 2 - 1, YEARS);
-        test.multipliedBy(2);
-    }
-
-    //-----------------------------------------------------------------------
-    // negated()
-    //-----------------------------------------------------------------------
-    public void test_negated() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6, 7);
-        assertPeriod(test.negated(), -1, -2, -3, -4, -5, -6, -7);
-    }
-
-    public void test_negated_zero() {
-        assertSame(Period.ZERO.negated(), Period.ZERO);
-    }
-
-    public void test_negated_max() {
-        assertPeriod(Period.of(Integer.MAX_VALUE, YEARS).negated(), -Integer.MAX_VALUE, 0, 0, 0, 0, 0, 0);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_negated_overflow() {
-        Period.of(Integer.MIN_VALUE, YEARS).negated();
-    }
-
-    //-----------------------------------------------------------------------
-    // normalizedHoursToDays()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="normalizedHoursToDays")
-    Object[][] data_normalizedHoursToDays() {
-        return new Object[][] {
-            {0, 0,  0, 0},
-            {1, 0,  1, 0},
-            {-1, 0,  -1, 0},
-
-            {1, 1,  1, 1},
-            {1, 23,  1, 23},
-            {1, 24,  2, 0},
-            {1, 25,  2, 1},
-
-            {1, -1,  0, 23},
-            {1, -23,  0, 1},
-            {1, -24,  0, 0},
-            {1, -25,  0, -1},
-            {1, -47,  0, -23},
-            {1, -48,  -1, 0},
-            {1, -49,  -1, -1},
-
-            {-1, 1,  0, -23},
-            {-1, 23,  0, -1},
-            {-1, 24,  0, 0},
-            {-1, 25,  0, 1},
-            {-1, 47,  0, 23},
-            {-1, 48,  1, 0},
-            {-1, 49,  1, 1},
-
-            {-1, -1,  -1, -1},
-            {-1, -23,  -1, -23},
-            {-1, -24,  -2, 0},
-            {-1, -25,  -2, -1},
-        };
-    }
-
-    @Test(dataProvider="normalizedHoursToDays")
-    public void test_normalizedHoursToDays(int inputDays, int inputHours, int expectedDays, int expectedHours) {
-        assertPeriod(Period.of(0, 0, inputDays, inputHours, 0, 0, 0).normalizedHoursToDays(), 0, 0, expectedDays, expectedHours, 0, 0, 0);
-    }
-
-    @Test(dataProvider="normalizedHoursToDays")
-    public void test_normalizedHoursToDays_yearsMonthsUnaffected(int inputDays, int inputHours, int expectedDays, int expectedHours) {
-        assertPeriod(Period.of(12, 6, inputDays, inputHours, 0, 0, 0).normalizedHoursToDays(), 12, 6, expectedDays, expectedHours, 0, 0, 0);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_normalizedHoursToDays_min() {
-        Period base = Period.of(0, 0, Integer.MIN_VALUE, -24, 0, 0, 0);
-        base.normalizedHoursToDays();
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_normalizedHoursToDays_max() {
-        Period base = Period.of(0, 0, Integer.MAX_VALUE, 24, 0, 0, 0);
-        base.normalizedHoursToDays();
-    }
-
-    //-----------------------------------------------------------------------
-    // normalizedDaysToHours()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="normalizedDaysToHours")
-    Object[][] data_normalizedDaysToHours() {
-        return new Object[][] {
-            {0, 0, 0,  0, 0},
-
-            {1, 0, 0,  24, 0},
-            {1, 1, 0,  25, 0},
-            {1, 23, 0,  47, 0},
-            {1, 24, 0,  48, 0},
-            {1, 25, 0,  49, 0},
-            {2, 23, 0,  71, 0},
-            {2, 24, 0,  72, 0},
-            {2, 25, 0,  73, 0},
-
-            {1, 0, 0,  24, 0},
-            {1, -1, 0,  23, 0},
-            {1, -23, 0,  1, 0},
-            {1, -24, 0,  0, 0},
-            {1, -25, 0,  -1, 0},
-            {2, -23, 0,  25, 0},
-            {2, -24, 0,  24, 0},
-            {2, -25, 0,  23, 0},
-
-            {-1, 0, 0,  -24, 0},
-            {-1, 1, 0,  -23, 0},
-            {-1, 23, 0,  -1, 0},
-            {-1, 24, 0,  0, 0},
-            {-1, 25, 0,  1, 0},
-            {-2, 23, 0,  -25, 0},
-            {-2, 24, 0,  -24, 0},
-            {-2, 25, 0,  -23, 0},
-
-            {-1, 0, 0,  -24, 0},
-            {-1, -1, 0,  -25, 0},
-            {-1, -23, 0,  -47, 0},
-            {-1, -24, 0,  -48, 0},
-            {-1, -25, 0,  -49, 0},
-
-            // minutes
-            {1, -1, -1,  22, 59},
-            {1, -23, -1,  0, 59},
-            {1, -24, -1,  0, -1},
-            {1, -25, -1,  -1, -1},
-            {-1, 1, 1,  -22, -59},
-            {-1, 23, 1,  0, -59},
-            {-1, 24, 1,  0, 1},
-            {-1, 25, 1,  1, 1},
-        };
-    }
-
-    @Test(dataProvider="normalizedDaysToHours")
-    public void test_normalizedDaysToHours(int inputDays, int inputHours, int inputMinutes, int expectedHours, int expectedMinutes) {
-        assertPeriod(Period.of(0, 0, inputDays, inputHours, inputMinutes, 0).normalizedDaysToHours(), 0, 0, 0, expectedHours, expectedMinutes, 0, 0);
-    }
-
-    @Test(dataProvider="normalizedDaysToHours")
-    public void test_normalizedDaysToHours_yearsMonthsUnaffected(int inputDays, int inputHours, int inputMinutes, int expectedHours, int expectedMinutes) {
-        assertPeriod(Period.of(12, 6, inputDays, inputHours, inputMinutes, 0).normalizedDaysToHours(), 12, 6, 0, expectedHours, expectedMinutes, 0, 0);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_normalizedDaysToHours_min() {
-        Period base = Period.of(0, 0, -1_000, -10_000_000, 0, 0, 0);
-        base.normalizedDaysToHours();
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_normalizedDaysToHours_max() {
-        Period base = Period.of(0, 0, 1_000, 10_000_000, 0, 0, 0);
-        base.normalizedDaysToHours();
-    }
-
-    //-----------------------------------------------------------------------
-    // normalizedMonthsISO()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="normalizedMonthsISO")
-    Object[][] data_normalizedMonthsISO() {
-        return new Object[][] {
-            {0, 0,  0, 0},
-            {1, 0,  1, 0},
-            {-1, 0,  -1, 0},
-
-            {1, 1,  1, 1},
-            {1, 2,  1, 2},
-            {1, 11,  1, 11},
-            {1, 12,  2, 0},
-            {1, 13,  2, 1},
-            {1, 23,  2, 11},
-            {1, 24,  3, 0},
-            {1, 25,  3, 1},
-
-            {1, -1,  0, 11},
-            {1, -2,  0, 10},
-            {1, -11,  0, 1},
-            {1, -12,  0, 0},
-            {1, -13,  0, -1},
-            {1, -23,  0, -11},
-            {1, -24,  -1, 0},
-            {1, -25,  -1, -1},
-            {1, -35,  -1, -11},
-            {1, -36,  -2, 0},
-            {1, -37,  -2, -1},
-
-            {-1, 1,  0, -11},
-            {-1, 11,  0, -1},
-            {-1, 12,  0, 0},
-            {-1, 13,  0, 1},
-            {-1, 23,  0, 11},
-            {-1, 24,  1, 0},
-            {-1, 25,  1, 1},
-
-            {-1, -1,  -1, -1},
-            {-1, -11,  -1, -11},
-            {-1, -12,  -2, 0},
-            {-1, -13,  -2, -1},
-        };
-    }
-
-    @Test(dataProvider="normalizedMonthsISO")
-    public void test_normalizedMonthsISO(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
-        assertPeriod(Period.ofDate(inputYears, inputMonths, 0).normalizedMonthsISO(), expectedYears, expectedMonths, 0, 0, 0, 0, 0);
-    }
-
-    @Test(dataProvider="normalizedMonthsISO")
-    public void test_normalizedMonthsISO_daysTimeUnaffected(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
-        assertPeriod(Period.of(inputYears, inputMonths, 5, 12, 30, 0, 0).normalizedMonthsISO(), expectedYears, expectedMonths, 5, 12, 30, 0, 0);
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_normalizedMonthsISO_min() {
-        Period base = Period.ofDate(Integer.MIN_VALUE, -12, 0);
-        base.normalizedMonthsISO();
-    }
-
-    @Test(expectedExceptions=ArithmeticException.class)
-    public void test_normalizedMonthsISO_max() {
-        Period base = Period.ofDate(Integer.MAX_VALUE, 12, 0);
-        base.normalizedMonthsISO();
-    }
-
-    //-----------------------------------------------------------------------
-    // addTo()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="addTo")
-    Object[][] data_addTo() {
-        return new Object[][] {
-            {pymd(0, 0, 0),  date(2012, 6, 30), date(2012, 6, 30)},
-
-            {pymd(1, 0, 0),  date(2012, 6, 10), date(2013, 6, 10)},
-            {pymd(0, 1, 0),  date(2012, 6, 10), date(2012, 7, 10)},
-            {pymd(0, 0, 1),  date(2012, 6, 10), date(2012, 6, 11)},
-
-            {pymd(-1, 0, 0),  date(2012, 6, 10), date(2011, 6, 10)},
-            {pymd(0, -1, 0),  date(2012, 6, 10), date(2012, 5, 10)},
-            {pymd(0, 0, -1),  date(2012, 6, 10), date(2012, 6, 9)},
-
-            {pymd(1, 2, 3),  date(2012, 6, 27), date(2013, 8, 30)},
-            {pymd(1, 2, 3),  date(2012, 6, 28), date(2013, 8, 31)},
-            {pymd(1, 2, 3),  date(2012, 6, 29), date(2013, 9, 1)},
-            {pymd(1, 2, 3),  date(2012, 6, 30), date(2013, 9, 2)},
-            {pymd(1, 2, 3),  date(2012, 7, 1), date(2013, 9, 4)},
-
-            {pymd(1, 0, 0),  date(2011, 2, 28), date(2012, 2, 28)},
-            {pymd(4, 0, 0),  date(2011, 2, 28), date(2015, 2, 28)},
-            {pymd(1, 0, 0),  date(2012, 2, 29), date(2013, 2, 28)},
-            {pymd(4, 0, 0),  date(2012, 2, 29), date(2016, 2, 29)},
-
-            {pymd(1, 1, 0),  date(2011, 1, 29), date(2012, 2, 29)},
-            {pymd(1, 2, 0),  date(2012, 2, 29), date(2013, 4, 29)},
-        };
-    }
-
-    @Test(dataProvider="addTo")
-    public void test_addTo(Period period, LocalDate baseDate, LocalDate expected) {
-        assertEquals(period.addTo(baseDate), expected);
-    }
-
-    @Test(dataProvider="addTo")
-    public void test_addTo_usingLocalDatePlus(Period period, LocalDate baseDate, LocalDate expected) {
-        assertEquals(baseDate.plus(period), expected);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_addTo_nullZero() {
-        Period.ZERO.addTo(null);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_addTo_nullNonZero() {
-        Period.of(2, DAYS).addTo(null);
-    }
-
-    //-----------------------------------------------------------------------
-    // subtractFrom()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="subtractFrom")
-    Object[][] data_subtractFrom() {
-        return new Object[][] {
-            {pymd(0, 0, 0),  date(2012, 6, 30), date(2012, 6, 30)},
-
-            {pymd(1, 0, 0),  date(2012, 6, 10), date(2011, 6, 10)},
-            {pymd(0, 1, 0),  date(2012, 6, 10), date(2012, 5, 10)},
-            {pymd(0, 0, 1),  date(2012, 6, 10), date(2012, 6, 9)},
-
-            {pymd(-1, 0, 0),  date(2012, 6, 10), date(2013, 6, 10)},
-            {pymd(0, -1, 0),  date(2012, 6, 10), date(2012, 7, 10)},
-            {pymd(0, 0, -1),  date(2012, 6, 10), date(2012, 6, 11)},
-
-            {pymd(1, 2, 3),  date(2012, 8, 30), date(2011, 6, 27)},
-            {pymd(1, 2, 3),  date(2012, 8, 31), date(2011, 6, 27)},
-            {pymd(1, 2, 3),  date(2012, 9, 1), date(2011, 6, 28)},
-            {pymd(1, 2, 3),  date(2012, 9, 2), date(2011, 6, 29)},
-            {pymd(1, 2, 3),  date(2012, 9, 3), date(2011, 6, 30)},
-            {pymd(1, 2, 3),  date(2012, 9, 4), date(2011, 7, 1)},
-
-            {pymd(1, 0, 0),  date(2011, 2, 28), date(2010, 2, 28)},
-            {pymd(4, 0, 0),  date(2011, 2, 28), date(2007, 2, 28)},
-            {pymd(1, 0, 0),  date(2012, 2, 29), date(2011, 2, 28)},
-            {pymd(4, 0, 0),  date(2012, 2, 29), date(2008, 2, 29)},
-
-            {pymd(1, 1, 0),  date(2013, 3, 29), date(2012, 2, 29)},
-            {pymd(1, 2, 0),  date(2012, 2, 29), date(2010, 12, 29)},
-        };
-    }
-
-    @Test(dataProvider="subtractFrom")
-    public void test_subtractFrom(Period period, LocalDate baseDate, LocalDate expected) {
-        assertEquals(period.subtractFrom(baseDate), expected);
-    }
-
-    @Test(dataProvider="subtractFrom")
-    public void test_subtractFrom_usingLocalDateMinus(Period period, LocalDate baseDate, LocalDate expected) {
-        assertEquals(baseDate.minus(period), expected);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_subtractFrom_nullZero() {
-        Period.ZERO.subtractFrom(null);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_subtractFrom_nullNonZero() {
-        Period.of(2, DAYS).subtractFrom(null);
-    }
-
-    //-----------------------------------------------------------------------
-    // toDuration()
-    //-----------------------------------------------------------------------
-    public void test_toDuration() {
-        assertEquals(Period.ZERO.toDuration(), Duration.of(0, SECONDS));
-        assertEquals(Period.of(0, 0, 0, 4, 5, 6, 7).toDuration(), Duration.ofSeconds((4 * 60 + 5) * 60L + 6, 7));
-    }
-
-    public void test_toDuration_calculation() {
-        assertEquals(Period.of(0, 0, 0, 2, 0, 0, 0).toDuration(), Duration.ofSeconds(2 * 3600));
-        assertEquals(Period.of(0, 0, 0, 0, 2, 0, 0).toDuration(), Duration.of(120, SECONDS));
-        assertEquals(Period.of(0, 0, 0, 0, 0, 2, 0).toDuration(), Duration.of(2, SECONDS));
-
-        assertEquals(Period.of(0, 0, 0, 0, 0, 3, 1000000000L - 1).toDuration(), Duration.ofSeconds(3, 999999999));
-        assertEquals(Period.of(0, 0, 0, 0, 0, 3, 1000000000L).toDuration(), Duration.ofSeconds(4, 0));
-    }
-
-    public void test_toDuration_negatives() {
-        assertEquals(Period.of(0, 0, 0, 0, 0, 2, 1).toDuration(), Duration.ofSeconds(2, 1));
-        assertEquals(Period.of(0, 0, 0, 0, 0, 2, -1).toDuration(), Duration.ofSeconds(1, 999999999));
-        assertEquals(Period.of(0, 0, 0, 0, 0, -2, 1).toDuration(), Duration.ofSeconds(-2, 1));
-        assertEquals(Period.of(0, 0, 0, 0, 0, -2, -1).toDuration(), Duration.ofSeconds(-3, 999999999));
-    }
-
-    @Test(expectedExceptions=DateTimeException.class)
-    public void test_toDuration_years() {
-        Period.of(1, 0, 0, 4, 5, 6, 7).toDuration();
-    }
-
-    @Test(expectedExceptions=DateTimeException.class)
-    public void test_toDuration_months() {
-        Period.of(0, 1, 0, 4, 5, 6, 7).toDuration();
-    }
-
-    @Test(expectedExceptions=DateTimeException.class)
-    public void test_toDuration_days() {
-        Duration test = Period.of(0, 0, 1, 4, 5, 6, 7).toDuration();
-        assertEquals(test, Duration.ofSeconds(101106, 7L));
-    }
-
-    //-----------------------------------------------------------------------
-    // equals() / hashCode()
-    //-----------------------------------------------------------------------
-    public void test_equals() {
-        assertEquals(Period.of(1, 0, 0, 0, 0, 0).equals(Period.of(1, YEARS)), true);
-        assertEquals(Period.of(0, 1, 0, 0, 0, 0).equals(Period.of(1, MONTHS)), true);
-        assertEquals(Period.of(0, 0, 1, 0, 0, 0).equals(Period.of(1, DAYS)), true);
-        assertEquals(Period.of(0, 0, 0, 1, 0, 0).equals(Period.of(1, HOURS)), true);
-        assertEquals(Period.of(0, 0, 0, 0, 1, 0).equals(Period.of(1, MINUTES)), true);
-        assertEquals(Period.of(0, 0, 0, 0, 0, 1).equals(Period.of(1, SECONDS)), true);
-        assertEquals(Period.of(1, 2, 3, 0, 0, 0).equals(Period.ofDate(1, 2, 3)), true);
-        assertEquals(Period.of(0, 0, 0, 1, 2, 3).equals(Period.ofTime(1, 2, 3)), true);
-        assertEquals(Period.of(1, 2, 3, 4, 5, 6).equals(Period.of(1, 2, 3, 4, 5, 6)), true);
-
-        assertEquals(Period.of(1, YEARS).equals(Period.of(1, YEARS)), true);
-        assertEquals(Period.of(1, YEARS).equals(Period.of(2, YEARS)), false);
-
-        assertEquals(Period.of(1, MONTHS).equals(Period.of(1, MONTHS)), true);
-        assertEquals(Period.of(1, MONTHS).equals(Period.of(2, MONTHS)), false);
-
-        assertEquals(Period.of(1, DAYS).equals(Period.of(1, DAYS)), true);
-        assertEquals(Period.of(1, DAYS).equals(Period.of(2, DAYS)), false);
-
-        assertEquals(Period.of(1, HOURS).equals(Period.of(1, HOURS)), true);
-        assertEquals(Period.of(1, HOURS).equals(Period.of(2, HOURS)), false);
-
-        assertEquals(Period.of(1, MINUTES).equals(Period.of(1, MINUTES)), true);
-        assertEquals(Period.of(1, MINUTES).equals(Period.of(2, MINUTES)), false);
-
-        assertEquals(Period.of(1, SECONDS).equals(Period.of(1, SECONDS)), true);
-        assertEquals(Period.of(1, SECONDS).equals(Period.of(2, SECONDS)), false);
-
-        assertEquals(Period.ofDate(1, 2, 3).equals(Period.ofDate(1, 2, 3)), true);
-        assertEquals(Period.ofDate(1, 2, 3).equals(Period.ofDate(0, 2, 3)), false);
-        assertEquals(Period.ofDate(1, 2, 3).equals(Period.ofDate(1, 0, 3)), false);
-        assertEquals(Period.ofDate(1, 2, 3).equals(Period.ofDate(1, 2, 0)), false);
-
-        assertEquals(Period.ofTime(1, 2, 3).equals(Period.ofTime(1, 2, 3)), true);
-        assertEquals(Period.ofTime(1, 2, 3).equals(Period.ofTime(0, 2, 3)), false);
-        assertEquals(Period.ofTime(1, 2, 3).equals(Period.ofTime(1, 0, 3)), false);
-        assertEquals(Period.ofTime(1, 2, 3).equals(Period.ofTime(1, 2, 0)), false);
-    }
-
-    public void test_equals_self() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6);
-        assertEquals(test.equals(test), true);
-    }
-
-    public void test_equals_null() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6);
-        assertEquals(test.equals(null), false);
-    }
-
-    public void test_equals_otherClass() {
-        Period test = Period.of(1, 2, 3, 4, 5, 6);
-        assertEquals(test.equals(""), false);
-    }
-
+    // hashCode()
     //-----------------------------------------------------------------------
     public void test_hashCode() {
-        Period test5 = Period.of(5, DAYS);
-        Period test6 = Period.of(6, DAYS);
-        Period test5M = Period.of(5, MONTHS);
-        Period test5Y = Period.of(5, YEARS);
+        Period test5 = Period.ofDays(5);
+        Period test6 = Period.ofDays(6);
+        Period test5M = Period.ofMonths(5);
+        Period test5Y = Period.ofYears(5);
         assertEquals(test5.hashCode() == test5.hashCode(), true);
         assertEquals(test5.hashCode() == test6.hashCode(), false);
         assertEquals(test5.hashCode() == test5M.hashCode(), false);
         assertEquals(test5.hashCode() == test5Y.hashCode(), false);
     }
 
-    //-----------------------------------------------------------------------
-    // toString()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="toStringAndParse")
-    Object[][] data_toString() {
-        return new Object[][] {
-            {Period.ZERO, "PT0S"},
-            {Period.of(0, DAYS), "PT0S"},
-            {Period.of(1, YEARS), "P1Y"},
-            {Period.of(1, MONTHS), "P1M"},
-            {Period.of(1, DAYS), "P1D"},
-            {Period.of(1, HOURS), "PT1H"},
-            {Period.of(1, MINUTES), "PT1M"},
-            {Period.of(1, SECONDS), "PT1S"},
-            {Period.of(12, SECONDS), "PT12S"},
-            {Period.of(123, SECONDS), "PT2M3S"},
-            {Period.of(1234, SECONDS), "PT20M34S"},
-            {Period.of(-1, SECONDS), "PT-1S"},
-            {Period.of(-12, SECONDS), "PT-12S"},
-            {Period.of(-123, SECONDS), "PT-2M-3S"},
-            {Period.of(-1234, SECONDS), "PT-20M-34S"},
-            {Period.of(1, 2, 3, 4, 5, 6), "P1Y2M3DT4H5M6S"},
-            {Period.of(1, 2, 3, 4, 5, 6, 700000000), "P1Y2M3DT4H5M6.7S"},
-            {Period.of(0, 0, 0, 0, 0, 0, 100000000), "PT0.1S"},
-            {Period.of(0, 0, 0, 0, 0, 0, -100000000), "PT-0.1S"},
-            {Period.of(0, 0, 0, 0, 0, 1, -900000000), "PT0.1S"},
-            {Period.of(0, 0, 0, 0, 0, -1, 900000000), "PT-0.1S"},
-            {Period.of(0, 0, 0, 0, 0, 1, 100000000), "PT1.1S"},
-            {Period.of(0, 0, 0, 0, 0, 1, -100000000), "PT0.9S"},
-            {Period.of(0, 0, 0, 0, 0, -1, 100000000), "PT-0.9S"},
-            {Period.of(0, 0, 0, 0, 0, -1, -100000000), "PT-1.1S"},
-            {Period.of(0, 0, 0, 0, 0, 0, 10000000), "PT0.01S"},
-            {Period.of(0, 0, 0, 0, 0, 0, -10000000), "PT-0.01S"},
-            {Period.of(0, 0, 0, 0, 0, 0, 1000000), "PT0.001S"},
-            {Period.of(0, 0, 0, 0, 0, 0, -1000000), "PT-0.001S"},
-            {Period.of(0, 0, 0, 0, 0, 0, 1000), "PT0.000001S"},
-            {Period.of(0, 0, 0, 0, 0, 0, -1000), "PT-0.000001S"},
-            {Period.of(0, 0, 0, 0, 0, 0, 1), "PT0.000000001S"},
-            {Period.of(0, 0, 0, 0, 0, 0, -1), "PT-0.000000001S"},
-        };
-    }
-
-    @Test(groups="tck", dataProvider="toStringAndParse")
-    public void test_toString(Period input, String expected) {
-        assertEquals(input.toString(), expected);
-    }
-
-    //-----------------------------------------------------------------------
-    private void assertPeriod(Period test, int y, int mo, int d, int h, int mn, int s, long n) {
-        assertEquals(test.getYears(), y, "years");
-        assertEquals(test.getMonths(), mo, "months");
-        assertEquals(test.getDays(), d, "days");
-        assertEquals(test.getHours(), h, "hours");
-        assertEquals(test.getMinutes(), mn, "mins");
-        assertEquals(test.getSeconds(), s, "secs");
-        assertEquals(test.getNanos(), n, "nanos");
-        assertEquals(test.getTimeNanos(), (((h * 60L + mn) * 60 + s) * 1_000_000_000L + n), "total nanos");
-    }
-
-    private static Period pymd(int y, int m, int d) {
-        return Period.ofDate(y, m, d);
-    }
-
-    private static LocalDate date(int y, int m, int d) {
-        return LocalDate.of(y, m, d);
-    }
-
 }
diff --git a/jdk/test/java/time/test/java/time/TestPeriodParser.java b/jdk/test/java/time/test/java/time/TestPeriodParser.java
deleted file mode 100644
index 1d3a8ab..0000000
--- a/jdk/test/java/time/test/java/time/TestPeriodParser.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package test.java.time;
-
-import java.time.*;
-
-import static java.time.temporal.ChronoUnit.DAYS;
-import static java.time.temporal.ChronoUnit.HOURS;
-import static java.time.temporal.ChronoUnit.MINUTES;
-import static java.time.temporal.ChronoUnit.MONTHS;
-import static java.time.temporal.ChronoUnit.NANOS;
-import static java.time.temporal.ChronoUnit.SECONDS;
-import static java.time.temporal.ChronoUnit.YEARS;
-import static org.testng.Assert.assertEquals;
-
-import java.time.format.DateTimeParseException;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * Test PeriodParser.
- */
-@Test
-public class TestPeriodParser {
-
-    //-----------------------------------------------------------------------
-    // parse(String)
-    //-----------------------------------------------------------------------
-    @DataProvider(name="Parse")
-    Object[][] provider_factory_parse() {
-        return new Object[][] {
-            {"Pt0S", Period.ZERO},
-            {"pT0S", Period.ZERO},
-            {"PT0S", Period.ZERO},
-            {"Pt0s", Period.ZERO},
-            {"pt0s", Period.ZERO},
-            {"P0Y0M0DT0H0M0.0S", Period.ZERO},
-
-            {"P1Y", Period.of(1, YEARS)},
-            {"P100Y", Period.of(100, YEARS)},
-            {"P-25Y", Period.of(-25, YEARS)},
-            {"P" + Integer.MAX_VALUE + "Y", Period.of(Integer.MAX_VALUE, YEARS)},
-            {"P" + Integer.MIN_VALUE + "Y", Period.of(Integer.MIN_VALUE, YEARS)},
-
-            {"P1M", Period.of(1, MONTHS)},
-            {"P0M", Period.of(0, MONTHS)},
-            {"P-1M", Period.of(-1, MONTHS)},
-            {"P" + Integer.MAX_VALUE + "M", Period.of(Integer.MAX_VALUE, MONTHS)},
-            {"P" + Integer.MIN_VALUE + "M", Period.of(Integer.MIN_VALUE, MONTHS)},
-
-            {"P1D", Period.of(1, DAYS)},
-            {"P0D", Period.of(0, DAYS)},
-            {"P-1D", Period.of(-1, DAYS)},
-            {"P" + Integer.MAX_VALUE + "D", Period.of(Integer.MAX_VALUE, DAYS)},
-            {"P" + Integer.MIN_VALUE + "D", Period.of(Integer.MIN_VALUE, DAYS)},
-
-            {"P2Y3M25D", Period.ofDate(2, 3, 25)},
-
-            {"PT1H", Period.of(1, HOURS)},
-            {"PT-1H", Period.of(-1, HOURS)},
-            {"PT24H", Period.of(24, HOURS)},
-            {"PT-24H", Period.of(-24, HOURS)},
-            {"PT" + Integer.MAX_VALUE / (3600 * 8) + "H", Period.of(Integer.MAX_VALUE / (3600 * 8), HOURS)},
-            {"PT" + Integer.MIN_VALUE / (3600 * 8) + "H", Period.of(Integer.MIN_VALUE / (3600 * 8), HOURS)},
-
-            {"PT1M", Period.of(1, MINUTES)},
-            {"PT-1M", Period.of(-1, MINUTES)},
-            {"PT60M", Period.of(60, MINUTES)},
-            {"PT-60M", Period.of(-60, MINUTES)},
-            {"PT" + Integer.MAX_VALUE / (60 * 8) + "M", Period.of(Integer.MAX_VALUE / (60 * 8), MINUTES)},
-            {"PT" + Integer.MIN_VALUE / (60 * 8) + "M", Period.of(Integer.MIN_VALUE / (60 * 8), MINUTES)},
-
-            {"PT1S", Period.of(1, SECONDS)},
-            {"PT-1S", Period.of(-1, SECONDS)},
-            {"PT60S", Period.of(60, SECONDS)},
-            {"PT-60S", Period.of(-60, SECONDS)},
-            {"PT" + Integer.MAX_VALUE + "S", Period.of(Integer.MAX_VALUE, SECONDS)},
-            {"PT" + Integer.MIN_VALUE + "S", Period.of(Integer.MIN_VALUE, SECONDS)},
-
-            {"PT0.1S", Period.of( 0, 0, 0, 0, 0, 0, 100000000 ) },
-            {"PT-0.1S", Period.of( 0, 0, 0, 0, 0, 0, -100000000 ) },
-            {"PT1.1S", Period.of( 0, 0, 0, 0, 0, 1, 100000000 ) },
-            {"PT-1.1S", Period.of( 0, 0, 0, 0, 0, -1, -100000000 ) },
-            {"PT1.0001S", Period.of(1, SECONDS).plus( 100000, NANOS ) },
-            {"PT1.0000001S", Period.of(1, SECONDS).plus( 100, NANOS ) },
-            {"PT1.123456789S", Period.of( 0, 0, 0, 0, 0, 1, 123456789 ) },
-            {"PT1.999999999S", Period.of( 0, 0, 0, 0, 0, 1, 999999999 ) },
-
-        };
-    }
-
-    @Test(dataProvider="Parse")
-    public void factory_parse(String text, Period expected) {
-        Period p = Period.parse(text);
-        assertEquals(p, expected);
-    }
-
-    @Test(dataProvider="Parse")
-    public void factory_parse_comma(String text, Period expected) {
-        if (text.contains(".")) {
-            text = text.replace('.', ',');
-            Period p = Period.parse(text);
-            assertEquals(p, expected);
-        }
-    }
-
-    @DataProvider(name="ParseFailures")
-    Object[][] provider_factory_parseFailures() {
-        return new Object[][] {
-            {"", 0},
-            {"PTS", 2},
-            {"AT0S", 0},
-            {"PA0S", 1},
-            {"PT0A", 3},
-
-            {"PT+S", 2},
-            {"PT-S", 2},
-            {"PT.S", 2},
-            {"PTAS", 2},
-
-            {"PT+0S", 2},
-            {"PT-0S", 2},
-            {"PT+1S", 2},
-            {"PT-.S", 2},
-
-            {"PT1ABC2S", 3},
-            {"PT1.1ABC2S", 5},
-
-            {"PT123456789123456789123456789S", 2},
-            {"PT0.1234567891S", 4},
-            {"PT1.S", 2},
-            {"PT.1S", 2},
-
-            {"PT2.-3S", 2},
-            {"PT-2.-3S", 2},
-
-            {"P1Y1MT1DT1M1S", 7},
-            {"P1Y1MT1HT1M1S", 8},
-            {"P1YMD", 3},
-            {"PT1ST1D", 4},
-            {"P1Y2Y", 4},
-            {"PT1M+3S", 4},
-
-            {"PT1S1", 4},
-            {"PT1S.", 4},
-            {"PT1SA", 4},
-            {"PT1M1", 4},
-            {"PT1M.", 4},
-            {"PT1MA", 4},
-        };
-    }
-
-    @Test(dataProvider="ParseFailures", expectedExceptions=DateTimeParseException.class)
-    public void factory_parseFailures(String text, int errPos) {
-        try {
-            Period.parse(text);
-        } catch (DateTimeParseException ex) {
-            assertEquals(ex.getParsedString(), text);
-            assertEquals(ex.getErrorIndex(), errPos);
-            throw ex;
-        }
-    }
-
-    @Test(dataProvider="ParseFailures", expectedExceptions=DateTimeParseException.class)
-    public void factory_parseFailures_comma(String text, int errPos) {
-        text = text.replace('.', ',');
-        try {
-            Period.parse(text);
-        } catch (DateTimeParseException ex) {
-            assertEquals(ex.getParsedString(), text);
-            assertEquals(ex.getErrorIndex(), errPos);
-            throw ex;
-        }
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class)
-    public void factory_parse_tooBig() {
-        String text = "PT" + Long.MAX_VALUE + "1S";
-        Period.parse(text);
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class)
-    public void factory_parse_tooBig_decimal() {
-        String text = "PT" + Long.MAX_VALUE + "1.1S";
-        Period.parse(text);
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class)
-    public void factory_parse_tooSmall() {
-        String text = "PT" + Long.MIN_VALUE + "1S";
-        Period.parse(text);
-    }
-
-    @Test(expectedExceptions=DateTimeParseException.class)
-    public void factory_parse_tooSmall_decimal() {
-        String text = "PT" + Long.MIN_VALUE + ".1S";
-        Period.parse(text);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void factory_parse_null() {
-        Period.parse(null);
-    }
-
-    @DataProvider(name="ParseSequenceFailures")
-    Object[][] provider_factory_parseSequenceFailures() {
-        return new Object[][] {
-            {"P0M0Y0DT0H0M0.0S"},
-            {"P0M0D0YT0H0M0.0S"},
-            {"P0S0D0YT0S0M0.0H"},
-            {"PT0M0H0.0S"},
-            {"PT0M0H"},
-            {"PT0S0M"},
-            {"PT0.0M2S"},
-        };
-    }
-
-    @Test(dataProvider="ParseSequenceFailures", expectedExceptions=DateTimeParseException.class)
-    public void factory_parse_badSequence(String text) {
-        Period.parse(text);
-    }
-
-}
diff --git a/jdk/test/java/time/test/java/time/temporal/TestYear.java b/jdk/test/java/time/test/java/time/TestYear.java
similarity index 96%
rename from jdk/test/java/time/test/java/time/temporal/TestYear.java
rename to jdk/test/java/time/test/java/time/TestYear.java
index 5880ac4..71791ab 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestYear.java
+++ b/jdk/test/java/time/test/java/time/TestYear.java
@@ -57,12 +57,11 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package test.java.time;
 
-import java.time.temporal.Year;
+import java.time.Year;
 
 import org.testng.annotations.Test;
-import test.java.time.AbstractTest;
 
 /**
  * Test Year.
diff --git a/jdk/test/java/time/test/java/time/temporal/TestYearMonth.java b/jdk/test/java/time/test/java/time/TestYearMonth.java
similarity index 96%
rename from jdk/test/java/time/test/java/time/temporal/TestYearMonth.java
rename to jdk/test/java/time/test/java/time/TestYearMonth.java
index ab0d7f4..f02ed96 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestYearMonth.java
+++ b/jdk/test/java/time/test/java/time/TestYearMonth.java
@@ -57,12 +57,11 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package test.java.time;
 
-import java.time.temporal.YearMonth;
+import java.time.YearMonth;
 
 import org.testng.annotations.Test;
-import test.java.time.AbstractTest;
 
 /**
  * Test YearMonth.
diff --git a/jdk/test/java/time/test/java/time/TestZoneId.java b/jdk/test/java/time/test/java/time/TestZoneId.java
index 5e93803..6aa3732 100644
--- a/jdk/test/java/time/test/java/time/TestZoneId.java
+++ b/jdk/test/java/time/test/java/time/TestZoneId.java
@@ -59,32 +59,28 @@
  */
 package test.java.time;
 
-import java.time.*;
-
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
-import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.SimpleTimeZone;
-import java.util.TimeZone;
-
-import java.time.temporal.Queries;
-import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalField;
+import java.time.DateTimeException;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
 import java.time.format.TextStyle;
 import java.time.zone.ZoneOffsetTransition;
 import java.time.zone.ZoneRules;
 import java.time.zone.ZoneRulesException;
+import java.util.List;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -95,8 +91,6 @@
 @Test
 public class TestZoneId extends AbstractTest {
 
-    private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
-    public static final String LATEST_TZDB = "2010i";
     private static final int OVERLAP = 2;
     private static final int GAP = 0;
 
@@ -104,6 +98,7 @@
     // Basics
     //-----------------------------------------------------------------------
     public void test_immutable() {
+        // cannot use standard test as ZoneId is abstract
         Class<ZoneId> cls = ZoneId.class;
         assertTrue(Modifier.isPublic(cls.getModifiers()));
         Field[] fields = cls.getDeclaredFields();
@@ -116,33 +111,13 @@
         }
     }
 
-    public void test_serialization_UTC() throws Exception {
-        ZoneId test = ZoneOffset.UTC;
-        assertSerializableAndSame(test);
-    }
-
-    public void test_serialization_fixed() throws Exception {
-        ZoneId test = ZoneId.of("UTC+01:30");
-        assertSerializable(test);
-    }
-
-    public void test_serialization_Europe() throws Exception {
-        ZoneId test = ZoneId.of("Europe/London");
-        assertSerializable(test);
-    }
-
-    public void test_serialization_America() throws Exception {
-        ZoneId test = ZoneId.of("America/Chicago");
-        assertSerializable(test);
-    }
-
     //-----------------------------------------------------------------------
     // UTC
     //-----------------------------------------------------------------------
     public void test_constant_UTC() {
         ZoneId test = ZoneOffset.UTC;
         assertEquals(test.getId(), "Z");
-        assertEquals(test.getText(TextStyle.FULL, Locale.UK), "Z");
+        assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), "Z");
         assertEquals(test.getRules().isFixedOffset(), true);
         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), ZoneOffset.UTC);
         checkOffset(test.getRules(), createLDT(2008, 6, 30), ZoneOffset.UTC, 1);
@@ -150,93 +125,13 @@
     }
 
     //-----------------------------------------------------------------------
-    // OLD_IDS_PRE_2005
-    //-----------------------------------------------------------------------
-    public void test_constant_OLD_IDS_PRE_2005() {
-        Map<String, String> ids = ZoneId.OLD_IDS_PRE_2005;
-        assertEquals(ids.get("EST"), "America/Indianapolis");
-        assertEquals(ids.get("MST"), "America/Phoenix");
-        assertEquals(ids.get("HST"), "Pacific/Honolulu");
-        assertEquals(ids.get("ACT"), "Australia/Darwin");
-        assertEquals(ids.get("AET"), "Australia/Sydney");
-        assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires");
-        assertEquals(ids.get("ART"), "Africa/Cairo");
-        assertEquals(ids.get("AST"), "America/Anchorage");
-        assertEquals(ids.get("BET"), "America/Sao_Paulo");
-        assertEquals(ids.get("BST"), "Asia/Dhaka");
-        assertEquals(ids.get("CAT"), "Africa/Harare");
-        assertEquals(ids.get("CNT"), "America/St_Johns");
-        assertEquals(ids.get("CST"), "America/Chicago");
-        assertEquals(ids.get("CTT"), "Asia/Shanghai");
-        assertEquals(ids.get("EAT"), "Africa/Addis_Ababa");
-        assertEquals(ids.get("ECT"), "Europe/Paris");
-        assertEquals(ids.get("IET"), "America/Indiana/Indianapolis");
-        assertEquals(ids.get("IST"), "Asia/Kolkata");
-        assertEquals(ids.get("JST"), "Asia/Tokyo");
-        assertEquals(ids.get("MIT"), "Pacific/Apia");
-        assertEquals(ids.get("NET"), "Asia/Yerevan");
-        assertEquals(ids.get("NST"), "Pacific/Auckland");
-        assertEquals(ids.get("PLT"), "Asia/Karachi");
-        assertEquals(ids.get("PNT"), "America/Phoenix");
-        assertEquals(ids.get("PRT"), "America/Puerto_Rico");
-        assertEquals(ids.get("PST"), "America/Los_Angeles");
-        assertEquals(ids.get("SST"), "Pacific/Guadalcanal");
-        assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh");
-    }
-
-    @Test(expectedExceptions=UnsupportedOperationException.class)
-    public void test_constant_OLD_IDS_PRE_2005_immutable() {
-        Map<String, String> ids = ZoneId.OLD_IDS_PRE_2005;
-        ids.clear();
-    }
-
-    //-----------------------------------------------------------------------
-    // OLD_IDS_POST_2005
-    //-----------------------------------------------------------------------
-    public void test_constant_OLD_IDS_POST_2005() {
-        Map<String, String> ids = ZoneId.OLD_IDS_POST_2005;
-        assertEquals(ids.get("EST"), "-05:00");
-        assertEquals(ids.get("MST"), "-07:00");
-        assertEquals(ids.get("HST"), "-10:00");
-        assertEquals(ids.get("ACT"), "Australia/Darwin");
-        assertEquals(ids.get("AET"), "Australia/Sydney");
-        assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires");
-        assertEquals(ids.get("ART"), "Africa/Cairo");
-        assertEquals(ids.get("AST"), "America/Anchorage");
-        assertEquals(ids.get("BET"), "America/Sao_Paulo");
-        assertEquals(ids.get("BST"), "Asia/Dhaka");
-        assertEquals(ids.get("CAT"), "Africa/Harare");
-        assertEquals(ids.get("CNT"), "America/St_Johns");
-        assertEquals(ids.get("CST"), "America/Chicago");
-        assertEquals(ids.get("CTT"), "Asia/Shanghai");
-        assertEquals(ids.get("EAT"), "Africa/Addis_Ababa");
-        assertEquals(ids.get("ECT"), "Europe/Paris");
-        assertEquals(ids.get("IET"), "America/Indiana/Indianapolis");
-        assertEquals(ids.get("IST"), "Asia/Kolkata");
-        assertEquals(ids.get("JST"), "Asia/Tokyo");
-        assertEquals(ids.get("MIT"), "Pacific/Apia");
-        assertEquals(ids.get("NET"), "Asia/Yerevan");
-        assertEquals(ids.get("NST"), "Pacific/Auckland");
-        assertEquals(ids.get("PLT"), "Asia/Karachi");
-        assertEquals(ids.get("PNT"), "America/Phoenix");
-        assertEquals(ids.get("PRT"), "America/Puerto_Rico");
-        assertEquals(ids.get("PST"), "America/Los_Angeles");
-        assertEquals(ids.get("SST"), "Pacific/Guadalcanal");
-        assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh");
-    }
-
-    @Test(expectedExceptions=UnsupportedOperationException.class)
-    public void test_constant_OLD_IDS_POST_2005_immutable() {
-        Map<String, String> ids = ZoneId.OLD_IDS_POST_2005;
-        ids.clear();
-    }
-
-    //-----------------------------------------------------------------------
     // system default
     //-----------------------------------------------------------------------
     public void test_systemDefault() {
         ZoneId test = ZoneId.systemDefault();
-        assertEquals(test.getId(), TimeZone.getDefault().getID());
+        assertEquals(test.getId(), TimeZone.getDefault()
+                                           .getID()
+                                           .replaceAll("GMT|UTC|UT", "Z"));
     }
 
     @Test(expectedExceptions = DateTimeException.class)
@@ -262,71 +157,9 @@
     }
 
     //-----------------------------------------------------------------------
-    // mapped factory
-    //-----------------------------------------------------------------------
-    public void test_of_string_Map() {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("LONDON", "Europe/London");
-        map.put("PARIS", "Europe/Paris");
-        ZoneId test = ZoneId.of("LONDON", map);
-        assertEquals(test.getId(), "Europe/London");
-    }
-
-    public void test_of_string_Map_lookThrough() {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("LONDON", "Europe/London");
-        map.put("PARIS", "Europe/Paris");
-        ZoneId test = ZoneId.of("Europe/Madrid", map);
-        assertEquals(test.getId(), "Europe/Madrid");
-    }
-
-    public void test_of_string_Map_emptyMap() {
-        Map<String, String> map = new HashMap<String, String>();
-        ZoneId test = ZoneId.of("Europe/Madrid", map);
-        assertEquals(test.getId(), "Europe/Madrid");
-    }
-
-    @Test(expectedExceptions=DateTimeException.class)
-    public void test_of_string_Map_badFormat() {
-        Map<String, String> map = new HashMap<String, String>();
-        ZoneId.of("Not kknown", map);
-    }
-
-    @Test(expectedExceptions=ZoneRulesException.class)
-    public void test_of_string_Map_unknown() {
-        Map<String, String> map = new HashMap<String, String>();
-        ZoneId.of("Unknown", map);
-    }
-
-    //-----------------------------------------------------------------------
-    // regular factory
-    //-----------------------------------------------------------------------
-    @DataProvider(name="String_UTC")
-    Object[][] data_of_string_UTC() {
-        return new Object[][] {
-            {""}, {"Z"},
-            {"+00"},{"+0000"},{"+00:00"},{"+000000"},{"+00:00:00"},
-            {"-00"},{"-0000"},{"-00:00"},{"-000000"},{"-00:00:00"},
-        };
-    }
-
-    @Test(dataProvider="String_UTC")
-    public void test_of_string_UTC(String id) {
-        ZoneId test = ZoneId.of("UTC" + id);
-        assertSame(test, ZoneOffset.UTC);
-    }
-
-    @Test(dataProvider="String_UTC")
-    public void test_of_string_GMT(String id) {
-        ZoneId test = ZoneId.of("GMT" + id);
-        assertSame(test, ZoneOffset.UTC);
-    }
-
-    //-----------------------------------------------------------------------
     @DataProvider(name="String_Fixed")
     Object[][] data_of_string_Fixed() {
         return new Object[][] {
-            {"Z", "Z"},
             {"+0", "Z"},
             {"+5", "+05:00"},
             {"+01", "+01:00"},
@@ -346,7 +179,7 @@
     public void test_of_string_offset(String input, String id) {
         ZoneId test = ZoneId.of(input);
         assertEquals(test.getId(), id);
-        assertEquals(test.getText(TextStyle.FULL, Locale.UK), id);
+        assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), id);
         assertEquals(test.getRules().isFixedOffset(), true);
         ZoneOffset offset = ZoneOffset.of(id);
         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
@@ -357,7 +190,7 @@
     public void test_of_string_FixedUTC(String input, String id) {
         ZoneId test = ZoneId.of("UTC" + input);
         assertEquals(test.getId(), id);
-        assertEquals(test.getText(TextStyle.FULL, Locale.UK), id);
+        assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), id);
         assertEquals(test.getRules().isFixedOffset(), true);
         ZoneOffset offset = ZoneOffset.of(id);
         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
@@ -368,7 +201,7 @@
     public void test_of_string_FixedGMT(String input, String id) {
         ZoneId test = ZoneId.of("GMT" + input);
         assertEquals(test.getId(), id);
-        assertEquals(test.getText(TextStyle.FULL, Locale.UK), id);
+        assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), id);
         assertEquals(test.getRules().isFixedOffset(), true);
         ZoneOffset offset = ZoneOffset.of(id);
         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
@@ -376,136 +209,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @DataProvider(name="String_UTC_Invalid")
-    Object[][] data_of_string_UTC_invalid() {
-        return new Object[][] {
-                {"A"}, {"B"}, {"C"}, {"D"}, {"E"}, {"F"}, {"G"}, {"H"}, {"I"}, {"J"}, {"K"}, {"L"}, {"M"},
-                {"N"}, {"O"}, {"P"}, {"Q"}, {"R"}, {"S"}, {"T"}, {"U"}, {"V"}, {"W"}, {"X"}, {"Y"},
-                {"+0:00"}, {"+00:0"}, {"+0:0"},
-                {"+000"}, {"+00000"},
-                {"+0:00:00"}, {"+00:0:00"}, {"+00:00:0"}, {"+0:0:0"}, {"+0:0:00"}, {"+00:0:0"}, {"+0:00:0"},
-                {"+01_00"}, {"+01;00"}, {"+01@00"}, {"+01:AA"},
-                {"+19"}, {"+19:00"}, {"+18:01"}, {"+18:00:01"}, {"+1801"}, {"+180001"},
-                {"-0:00"}, {"-00:0"}, {"-0:0"},
-                {"-000"}, {"-00000"},
-                {"-0:00:00"}, {"-00:0:00"}, {"-00:00:0"}, {"-0:0:0"}, {"-0:0:00"}, {"-00:0:0"}, {"-0:00:0"},
-                {"-19"}, {"-19:00"}, {"-18:01"}, {"-18:00:01"}, {"-1801"}, {"-180001"},
-                {"-01_00"}, {"-01;00"}, {"-01@00"}, {"-01:AA"},
-                {"@01:00"},
-        };
-    }
-
-    @Test(dataProvider="String_UTC_Invalid", expectedExceptions=DateTimeException.class)
-    public void test_of_string_UTC_invalid(String id) {
-        ZoneId.of("UTC" + id);
-    }
-
-    @Test(dataProvider="String_UTC_Invalid", expectedExceptions=DateTimeException.class)
-    public void test_of_string_GMT_invalid(String id) {
-        ZoneId.of("GMT" + id);
-    }
-
-    //-----------------------------------------------------------------------
-    @DataProvider(name="String_Invalid")
-    Object[][] data_of_string_invalid() {
-        // \u00ef is a random unicode character
-        return new Object[][] {
-                {""}, {":"}, {"#"},
-                {"\u00ef"}, {"`"}, {"!"}, {"\""}, {"\u00ef"}, {"$"}, {"^"}, {"&"}, {"*"}, {"("}, {")"}, {"="},
-                {"\\"}, {"|"}, {","}, {"<"}, {">"}, {"?"}, {";"}, {"'"}, {"["}, {"]"}, {"{"}, {"}"},
-                {"\u00ef:A"}, {"`:A"}, {"!:A"}, {"\":A"}, {"\u00ef:A"}, {"$:A"}, {"^:A"}, {"&:A"}, {"*:A"}, {"(:A"}, {"):A"}, {"=:A"}, {"+:A"},
-                {"\\:A"}, {"|:A"}, {",:A"}, {"<:A"}, {">:A"}, {"?:A"}, {";:A"}, {"::A"}, {"':A"}, {"@:A"}, {"~:A"}, {"[:A"}, {"]:A"}, {"{:A"}, {"}:A"},
-                {"A:B#\u00ef"}, {"A:B#`"}, {"A:B#!"}, {"A:B#\""}, {"A:B#\u00ef"}, {"A:B#$"}, {"A:B#^"}, {"A:B#&"}, {"A:B#*"},
-                {"A:B#("}, {"A:B#)"}, {"A:B#="}, {"A:B#+"},
-                {"A:B#\\"}, {"A:B#|"}, {"A:B#,"}, {"A:B#<"}, {"A:B#>"}, {"A:B#?"}, {"A:B#;"}, {"A:B#:"},
-                {"A:B#'"}, {"A:B#@"}, {"A:B#~"}, {"A:B#["}, {"A:B#]"}, {"A:B#{"}, {"A:B#}"},
-        };
-    }
-
-    @Test(dataProvider="String_Invalid", expectedExceptions=DateTimeException.class)
-    public void test_of_string_invalid(String id) {
-        ZoneId.of(id);
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_of_string_GMT0() {
-        ZoneId test = ZoneId.of("GMT0");
-        assertEquals(test.getId(), "Z");
-        assertEquals(test.getRules().isFixedOffset(), true);
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_of_string_London() {
-        ZoneId test = ZoneId.of("Europe/London");
-        assertEquals(test.getId(), "Europe/London");
-        assertEquals(test.getRules().isFixedOffset(), false);
-    }
-
-    //-----------------------------------------------------------------------
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_of_string_null() {
-        ZoneId.of((String) null);
-    }
-
-    @Test(expectedExceptions=ZoneRulesException.class)
-    public void test_of_string_unknown_simple() {
-        ZoneId.of("Unknown");
-    }
-
-    //-------------------------------------------------------------------------
-    // TODO: test by deserialization
-//    public void test_ofUnchecked_string_invalidNotChecked() {
-//        ZoneRegion test = ZoneRegion.ofLenient("Unknown");
-//        assertEquals(test.getId(), "Unknown");
-//    }
-//
-//    public void test_ofUnchecked_string_invalidNotChecked_unusualCharacters() {
-//        ZoneRegion test = ZoneRegion.ofLenient("QWERTYUIOPASDFGHJKLZXCVBNM~/._+-");
-//        assertEquals(test.getId(), "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-");
-//    }
-
-    //-----------------------------------------------------------------------
-    // from(TemporalAccessor)
-    //-----------------------------------------------------------------------
-    public void test_factory_from_DateTimeAccessor_zoneId() {
-        TemporalAccessor mock = new TemporalAccessor() {
-            @Override
-            public boolean isSupported(TemporalField field) {
-                return false;
-            }
-
-            @Override
-            public long getLong(TemporalField field) {
-                throw new DateTimeException("Mock");
-            }
-
-            @Override
-            public <R> R query(TemporalQuery<R> query) {
-                if (query == Queries.zoneId()) {
-                    return (R) ZONE_PARIS;
-                }
-                return TemporalAccessor.super.query(query);
-            }
-        };
-        assertEquals(ZoneId.from(mock), ZONE_PARIS);
-    }
-
-    public void test_factory_from_DateTimeAccessor_offset() {
-        ZoneOffset offset = ZoneOffset.ofHours(1);
-        assertEquals(ZoneId.from(offset), offset);
-    }
-
-    @Test(expectedExceptions=DateTimeException.class)
-    public void test_factory_from_DateTimeAccessor_invalid_noDerive() {
-        ZoneId.from(LocalTime.of(12, 30));
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void test_factory_from_DateTimeAccessor_null() {
-        ZoneId.from((TemporalAccessor) null);
-    }
-
-    //-----------------------------------------------------------------------
     // Europe/London
     //-----------------------------------------------------------------------
     public void test_London() {
@@ -999,53 +702,6 @@
     }
 
     //-----------------------------------------------------------------------
-    // equals() / hashCode()
-    //-----------------------------------------------------------------------
-    public void test_equals() {
-        ZoneId test1 = ZoneId.of("Europe/London");
-        ZoneId test2 = ZoneId.of("Europe/Paris");
-        ZoneId test2b = ZoneId.of("Europe/Paris");
-        assertEquals(test1.equals(test2), false);
-        assertEquals(test2.equals(test1), false);
-
-        assertEquals(test1.equals(test1), true);
-        assertEquals(test2.equals(test2), true);
-        assertEquals(test2.equals(test2b), true);
-
-        assertEquals(test1.hashCode() == test1.hashCode(), true);
-        assertEquals(test2.hashCode() == test2.hashCode(), true);
-        assertEquals(test2.hashCode() == test2b.hashCode(), true);
-    }
-
-    public void test_equals_null() {
-        assertEquals(ZoneId.of("Europe/London").equals(null), false);
-    }
-
-    public void test_equals_notTimeZone() {
-        assertEquals(ZoneId.of("Europe/London").equals("Europe/London"), false);
-    }
-
-    //-----------------------------------------------------------------------
-    // toString()
-    //-----------------------------------------------------------------------
-    @DataProvider(name="ToString")
-    Object[][] data_toString() {
-        return new Object[][] {
-            {"Europe/London", "Europe/London"},
-            {"Europe/Paris", "Europe/Paris"},
-            {"Europe/Berlin", "Europe/Berlin"},
-            {"UTC", "Z"},
-            {"UTC+01:00", "+01:00"},
-        };
-    }
-
-    @Test(dataProvider="ToString")
-    public void test_toString(String id, String expected) {
-        ZoneId test = ZoneId.of(id);
-        assertEquals(test.toString(), expected);
-    }
-
-    //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     private Instant createInstant(int year, int month, int day, ZoneOffset offset) {
diff --git a/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java b/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java
new file mode 100644
index 0000000..bfdec45
--- /dev/null
+++ b/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012, 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.  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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package test.java.time.chrono;
+
+import java.time.LocalTime;
+import java.time.chrono.HijrahDate;
+import java.time.chrono.ThaiBuddhistDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Chronology;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+/**
+ * Test case verify that the example code in the package-info.java compiles
+ * and runs.
+ */
+public class TestExampleCode {
+
+    @Test
+    public void test_chronoPackageExample() {
+        // Print the Thai Buddhist date
+        ChronoLocalDate<?> now1 = Chronology.of("ThaiBuddhist").dateNow();
+        int day = now1.get(ChronoField.DAY_OF_MONTH);
+        int dow = now1.get(ChronoField.DAY_OF_WEEK);
+        int month = now1.get(ChronoField.MONTH_OF_YEAR);
+        int year = now1.get(ChronoField.YEAR);
+        System.out.printf("  Today is %s %s %d-%s-%d%n", now1.getChronology().getId(),
+                dow, day, month, year);
+
+        // Enumerate the list of available calendars and print today for each
+        Set<Chronology> chronos = Chronology.getAvailableChronologies();
+        for (Chronology chrono : chronos) {
+            ChronoLocalDate<?> date = chrono.dateNow();
+            System.out.printf("   %20s: %s%n", chrono.getId(), date.toString());
+        }
+
+        // Print today's date and the last day of the year for the Thai Buddhist Calendar.
+        ChronoLocalDate<?> first = now1
+                .with(ChronoField.DAY_OF_MONTH, 1)
+                .with(ChronoField.MONTH_OF_YEAR, 1);
+        ChronoLocalDate<?> last = first
+                .plus(1, ChronoUnit.YEARS)
+                .minus(1, ChronoUnit.DAYS);
+        System.out.printf("  %s: 1st of year: %s; end of year: %s%n", last.getChronology().getId(),
+                first, last);
+    }
+
+    @Test
+    public void test_calendarPackageExample() {
+
+        // Enumerate the list of available calendars and print today for each
+        Set<Chronology> chronos = Chronology.getAvailableChronologies();
+        for (Chronology chrono : chronos) {
+            ChronoLocalDate<?> date = chrono.dateNow();
+            System.out.printf("   %20s: %s%n", chrono.getId(), date.toString());
+        }
+
+        // Print the Thai Buddhist date
+        ThaiBuddhistDate now1 = ThaiBuddhistDate.now();
+        int day = now1.get(ChronoField.DAY_OF_MONTH);
+        int dow = now1.get(ChronoField.DAY_OF_WEEK);
+        int month = now1.get(ChronoField.MONTH_OF_YEAR);
+        int year = now1.get(ChronoField.YEAR);
+        System.out.printf("  Today is %s %s %d-%s-%d%n", now1.getChronology().getId(),
+                dow, day, month, year);
+
+        // Print today's date and the last day of the year for the Thai Buddhist Calendar.
+        ThaiBuddhistDate first = now1
+                .with(ChronoField.DAY_OF_MONTH, 1)
+                .with(ChronoField.MONTH_OF_YEAR, 1);
+        ThaiBuddhistDate last = first
+                .plus(1, ChronoUnit.YEARS)
+                .minus(1, ChronoUnit.DAYS);
+        System.out.printf("  %s: 1st of year: %s; end of year: %s%n", last.getChronology().getId(),
+                first, last);
+    }
+
+    @Test
+    public void test_library() {
+        HijrahDate date = HijrahDate.now();
+        HijrahDate next = next(date);
+        ChronoLocalDateTime<HijrahDate> noonTomorrow = tomorrowNoon(date);
+        System.out.printf("  now: %s, noon tomorrow: %s%n", date, noonTomorrow);
+    }
+
+    /**
+     * Simple function based on a date, returning a ChronoDate of the same type.
+     * @param <D> a parameterized ChronoLocalDate
+     * @param date a specific date extending ChronoLocalDate
+     * @return a new date in the same chronology.
+     */
+    private <D extends ChronoLocalDate<D>> D next(D date) {
+        return date.plus(1, ChronoUnit.DAYS);
+    }
+
+    /**
+     * Simple function based on a date, returning a ChronoLocalDateTime of the
+     * same chronology.
+     * @param <D> a parameterized ChronoLocalDate
+     * @param date a specific date extending ChronoLocalDate
+     * @return a [@code ChronoLocalDateTime<D>} using the change chronology.
+     */
+    private <D extends ChronoLocalDate<D>> ChronoLocalDateTime<D> tomorrowNoon(D date) {
+        return date.plus(1, ChronoUnit.DAYS).atTime(LocalTime.of(12, 0));
+    }
+}
diff --git a/jdk/test/java/time/test/java/time/temporal/TestISOChronoImpl.java b/jdk/test/java/time/test/java/time/chrono/TestIsoChronoImpl.java
similarity index 94%
rename from jdk/test/java/time/test/java/time/temporal/TestISOChronoImpl.java
rename to jdk/test/java/time/test/java/time/chrono/TestIsoChronoImpl.java
index 9fc0155..1e66574 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestISOChronoImpl.java
+++ b/jdk/test/java/time/test/java/time/chrono/TestIsoChronoImpl.java
@@ -54,7 +54,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package test.java.time.chrono;
 
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
@@ -69,10 +69,10 @@
 
 import java.time.DayOfWeek;
 import java.time.LocalDate;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.IsoChronology;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ISOChrono;
 import java.time.temporal.WeekFields;
-import java.time.temporal.ChronoLocalDate;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -81,7 +81,7 @@
  * Test.
  */
 @Test
-public class TestISOChronoImpl {
+public class TestIsoChronoImpl {
 
     @DataProvider(name = "RangeVersusCalendar")
     Object[][] provider_rangeVersusCalendar() {
@@ -95,10 +95,10 @@
     // Verify  ISO Calendar matches java.util.Calendar for range
     //-----------------------------------------------------------------------
     @Test(groups = {"implementation"}, dataProvider = "RangeVersusCalendar")
-    public void test_ISOChrono_vsCalendar(LocalDate isoStartDate, LocalDate isoEndDate) {
+    public void test_IsoChrono_vsCalendar(LocalDate isoStartDate, LocalDate isoEndDate) {
         GregorianCalendar cal = new GregorianCalendar();
         assertEquals(cal.getCalendarType(), "gregory", "Unexpected calendar type");
-        ChronoLocalDate<ISOChrono> isoDate = ISOChrono.INSTANCE.date(isoStartDate);
+        LocalDate isoDate = IsoChronology.INSTANCE.date(isoStartDate);
 
         cal.setTimeZone(TimeZone.getTimeZone("GMT+00"));
         cal.set(Calendar.YEAR, isoDate.get(YEAR));
@@ -120,10 +120,10 @@
     // DayOfWeek, WeekOfMonth, WeekOfYear for range
     //-----------------------------------------------------------------------
     @Test(groups = {"implementation"}, dataProvider = "RangeVersusCalendar")
-    public void test_DayOfWeek_ISOChrono_vsCalendar(LocalDate isoStartDate, LocalDate isoEndDate) {
+    public void test_DayOfWeek_IsoChronology_vsCalendar(LocalDate isoStartDate, LocalDate isoEndDate) {
         GregorianCalendar cal = new GregorianCalendar();
         assertEquals(cal.getCalendarType(), "gregory", "Unexpected calendar type");
-        ChronoLocalDate<ISOChrono> isoDate = ISOChrono.INSTANCE.date(isoStartDate);
+        LocalDate isoDate = IsoChronology.INSTANCE.date(isoStartDate);
 
         for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
             for (int minDays = 1; minDays <= 7; minDays++) {
diff --git a/jdk/test/java/time/test/java/time/temporal/TestOffsetDate.java b/jdk/test/java/time/test/java/time/chrono/TestServiceLoader.java
similarity index 76%
copy from jdk/test/java/time/test/java/time/temporal/TestOffsetDate.java
copy to jdk/test/java/time/test/java/time/chrono/TestServiceLoader.java
index 5ba0032..99304a7 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestOffsetDate.java
+++ b/jdk/test/java/time/test/java/time/chrono/TestServiceLoader.java
@@ -1,5 +1,4 @@
 /*
- * Copyright (c) 2012, 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
@@ -27,7 +26,7 @@
  * However, the following notice accompanied the original version of this
  * file:
  *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos
  *
  * All rights reserved.
  *
@@ -57,22 +56,31 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-package test.java.time.temporal;
+package test.java.time.chrono;
 
-import java.time.temporal.OffsetDate;
+import static org.testng.Assert.assertNotNull;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.time.chrono.Chronology;
 import org.testng.annotations.Test;
-import test.java.time.AbstractTest;
 
 /**
- * Test OffsetDate.
+ * Tests that a custom Chronology is available via the ServiceLoader.
+ * The CopticChronology is configured via META-INF/services/java.time.chrono.Chronology.
  */
 @Test
-public class TestOffsetDate extends AbstractTest {
+public class TestServiceLoader {
 
-    @Test
-    public void test_immutable() {
-        assertImmutable(OffsetDate.class);
+    @Test(groups="implementation")
+    public void test_copticServiceLoader() {
+        Map<String, Chronology> chronos = new HashMap<>();
+        ServiceLoader<Chronology> loader = ServiceLoader.load(Chronology.class, null);
+        for (Chronology chrono : loader) {
+            chronos.put(chrono.getId(), chrono);
+        }
+        assertNotNull(chronos.get("Coptic"), "CopticChronology not found");
     }
 
 }
diff --git a/jdk/test/java/time/test/java/time/format/TestCharLiteralParser.java b/jdk/test/java/time/test/java/time/format/TestCharLiteralParser.java
index c2fe629..ff73696 100644
--- a/jdk/test/java/time/test/java/time/format/TestCharLiteralParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestCharLiteralParser.java
@@ -59,11 +59,15 @@
  */
 package test.java.time.format;
 
+import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
-import java.time.format.DateTimeBuilder;
 import java.text.ParsePosition;
+import java.time.temporal.Queries;
+import java.time.temporal.TemporalAccessor;
+
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
@@ -101,13 +105,14 @@
                                    String text, int pos, int expectedPos) {
         setCaseSensitive(caseSensitive);
         ParsePosition ppos = new ParsePosition(pos);
-        DateTimeBuilder result =
-               getFormatter(c).parseToBuilder(text, ppos);
+        TemporalAccessor parsed = getFormatter(c).parseUnresolved(text, ppos);
         if (ppos.getErrorIndex() != -1) {
             assertEquals(ppos.getIndex(), expectedPos);
         } else {
             assertEquals(ppos.getIndex(), expectedPos);
-            assertEquals(result.getCalendricalList().size(), 0);
+            assertEquals(parsed.isSupported(YEAR), false);
+            assertEquals(parsed.query(Queries.chronology()), null);
+            assertEquals(parsed.query(Queries.zoneId()), null);
         }
     }
 
@@ -123,9 +128,9 @@
     @Test(dataProvider="error")
     public void test_parse_error(char c, String text, int pos, Class<?> expected) {
         try {
-            DateTimeBuilder result =
-               getFormatter(c).parseToBuilder(text, new ParsePosition(pos));
-            assertTrue(false);
+            ParsePosition ppos = new ParsePosition(pos);
+            getFormatter(c).parseUnresolved(text, ppos);
+            fail();
         } catch (RuntimeException ex) {
             assertTrue(expected.isInstance(ex));
         }
diff --git a/jdk/test/java/time/test/java/time/format/TestCharLiteralPrinter.java b/jdk/test/java/time/test/java/time/format/TestCharLiteralPrinter.java
index f2c1f7d..780c04d 100644
--- a/jdk/test/java/time/test/java/time/format/TestCharLiteralPrinter.java
+++ b/jdk/test/java/time/test/java/time/format/TestCharLiteralPrinter.java
@@ -74,18 +74,18 @@
     //-----------------------------------------------------------------------
     public void test_print_emptyCalendrical() throws Exception {
         buf.append("EXISTING");
-        getFormatter('a').printTo(EMPTY_DTA, buf);
+        getFormatter('a').formatTo(EMPTY_DTA, buf);
         assertEquals(buf.toString(), "EXISTINGa");
     }
 
     public void test_print_dateTime() throws Exception {
         buf.append("EXISTING");
-        getFormatter('a').printTo(dta, buf);
+        getFormatter('a').formatTo(dta, buf);
         assertEquals(buf.toString(), "EXISTINGa");
     }
 
     public void test_print_emptyAppendable() throws Exception {
-        getFormatter('a').printTo(dta, buf);
+        getFormatter('a').formatTo(dta, buf);
         assertEquals(buf.toString(), "a");
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java
new file mode 100644
index 0000000..ec0d16e
--- /dev/null
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java
@@ -0,0 +1,864 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package test.java.time.format;
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.YEAR;
+import static org.testng.Assert.assertEquals;
+
+import java.text.ParsePosition;
+import java.time.LocalDate;
+import java.time.YearMonth;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.SignStyle;
+import java.time.format.TextStyle;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test DateTimeFormatterBuilder.
+ */
+@Test
+public class TestDateTimeFormatterBuilder {
+
+    private DateTimeFormatterBuilder builder;
+
+    @BeforeMethod
+    public void setUp() {
+        builder = new DateTimeFormatterBuilder();
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_toFormatter_empty() throws Exception {
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "");
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_parseCaseSensitive() throws Exception {
+        builder.parseCaseSensitive();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "ParseCaseSensitive(true)");
+    }
+
+    @Test
+    public void test_parseCaseInsensitive() throws Exception {
+        builder.parseCaseInsensitive();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "ParseCaseSensitive(false)");
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_parseStrict() throws Exception {
+        builder.parseStrict();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "ParseStrict(true)");
+    }
+
+    @Test
+    public void test_parseLenient() throws Exception {
+        builder.parseLenient();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "ParseStrict(false)");
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendValue_1arg() throws Exception {
+        builder.appendValue(DAY_OF_MONTH);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(DayOfMonth)");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendValue_1arg_null() throws Exception {
+        builder.appendValue(null);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendValue_2arg() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 3);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(DayOfMonth,3)");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendValue_2arg_null() throws Exception {
+        builder.appendValue(null, 3);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendValue_2arg_widthTooSmall() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 0);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendValue_2arg_widthTooBig() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 20);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendValue_3arg() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 2, 3, SignStyle.NORMAL);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(DayOfMonth,2,3,NORMAL)");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendValue_3arg_nullField() throws Exception {
+        builder.appendValue(null, 2, 3, SignStyle.NORMAL);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendValue_3arg_minWidthTooSmall() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 0, 2, SignStyle.NORMAL);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendValue_3arg_minWidthTooBig() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 20, 2, SignStyle.NORMAL);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendValue_3arg_maxWidthTooSmall() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 2, 0, SignStyle.NORMAL);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendValue_3arg_maxWidthTooBig() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 2, 20, SignStyle.NORMAL);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendValue_3arg_maxWidthMinWidth() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 4, 2, SignStyle.NORMAL);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendValue_3arg_nullSignStyle() throws Exception {
+        builder.appendValue(DAY_OF_MONTH, 2, 3, null);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendValue_subsequent2_parse3() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValue(DAY_OF_MONTH, 2);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)Value(DayOfMonth,2)");
+        TemporalAccessor parsed = f.parseUnresolved("123", new ParsePosition(0));
+        assertEquals(parsed.getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(parsed.getLong(DAY_OF_MONTH), 23L);
+    }
+
+    @Test
+    public void test_appendValue_subsequent2_parse4() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValue(DAY_OF_MONTH, 2);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)Value(DayOfMonth,2)");
+        TemporalAccessor parsed = f.parseUnresolved("0123", new ParsePosition(0));
+        assertEquals(parsed.getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(parsed.getLong(DAY_OF_MONTH), 23L);
+    }
+
+    @Test
+    public void test_appendValue_subsequent2_parse5() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValue(DAY_OF_MONTH, 2).appendLiteral('4');
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)Value(DayOfMonth,2)'4'");
+        TemporalAccessor parsed = f.parseUnresolved("01234", new ParsePosition(0));
+        assertEquals(parsed.getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(parsed.getLong(DAY_OF_MONTH), 23L);
+    }
+
+    @Test
+    public void test_appendValue_subsequent3_parse6() throws Exception {
+        builder
+            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
+            .appendValue(MONTH_OF_YEAR, 2)
+            .appendValue(DAY_OF_MONTH, 2);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(Year,4,10,EXCEEDS_PAD)Value(MonthOfYear,2)Value(DayOfMonth,2)");
+        TemporalAccessor parsed = f.parseUnresolved("20090630", new ParsePosition(0));
+        assertEquals(parsed.getLong(YEAR), 2009L);
+        assertEquals(parsed.getLong(MONTH_OF_YEAR), 6L);
+        assertEquals(parsed.getLong(DAY_OF_MONTH), 30L);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendValueReduced_null() throws Exception {
+        builder.appendValueReduced(null, 2, 2000);
+    }
+
+    @Test
+    public void test_appendValueReduced() throws Exception {
+        builder.appendValueReduced(YEAR, 2, 2000);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "ReducedValue(Year,2,2000)");
+        TemporalAccessor parsed = f.parseUnresolved("12", new ParsePosition(0));
+        assertEquals(parsed.getLong(YEAR), 2012L);
+    }
+
+    @Test
+    public void test_appendValueReduced_subsequent_parse() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL).appendValueReduced(YEAR, 2, 2000);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear,1,2,NORMAL)ReducedValue(Year,2,2000)");
+        TemporalAccessor parsed = f.parseUnresolved("123", new ParsePosition(0));
+        assertEquals(parsed.getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(parsed.getLong(YEAR), 2023L);
+    }
+
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendFraction_4arg() throws Exception {
+        builder.appendFraction(MINUTE_OF_HOUR, 1, 9, false);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Fraction(MinuteOfHour,1,9)");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendFraction_4arg_nullRule() throws Exception {
+        builder.appendFraction(null, 1, 9, false);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendFraction_4arg_invalidRuleNotFixedSet() throws Exception {
+        builder.appendFraction(DAY_OF_MONTH, 1, 9, false);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendFraction_4arg_minTooSmall() throws Exception {
+        builder.appendFraction(MINUTE_OF_HOUR, -1, 9, false);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendFraction_4arg_minTooBig() throws Exception {
+        builder.appendFraction(MINUTE_OF_HOUR, 10, 9, false);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendFraction_4arg_maxTooSmall() throws Exception {
+        builder.appendFraction(MINUTE_OF_HOUR, 0, -1, false);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendFraction_4arg_maxTooBig() throws Exception {
+        builder.appendFraction(MINUTE_OF_HOUR, 1, 10, false);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_appendFraction_4arg_maxWidthMinWidth() throws Exception {
+        builder.appendFraction(MINUTE_OF_HOUR, 9, 3, false);
+    }
+
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendText_1arg() throws Exception {
+        builder.appendText(MONTH_OF_YEAR);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Text(MonthOfYear)");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendText_1arg_null() throws Exception {
+        builder.appendText(null);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendText_2arg() throws Exception {
+        builder.appendText(MONTH_OF_YEAR, TextStyle.SHORT);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Text(MonthOfYear,SHORT)");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendText_2arg_nullRule() throws Exception {
+        builder.appendText(null, TextStyle.SHORT);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendText_2arg_nullStyle() throws Exception {
+        builder.appendText(MONTH_OF_YEAR, (TextStyle) null);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendTextMap() throws Exception {
+        Map<Long, String> map = new HashMap<>();
+        map.put(1L, "JNY");
+        map.put(2L, "FBY");
+        map.put(3L, "MCH");
+        map.put(4L, "APL");
+        map.put(5L, "MAY");
+        map.put(6L, "JUN");
+        map.put(7L, "JLY");
+        map.put(8L, "AGT");
+        map.put(9L, "SPT");
+        map.put(10L, "OBR");
+        map.put(11L, "NVR");
+        map.put(12L, "DBR");
+        builder.appendText(MONTH_OF_YEAR, map);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Text(MonthOfYear)");  // TODO: toString should be different?
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendTextMap_nullRule() throws Exception {
+        builder.appendText(null, new HashMap<Long, String>());
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendTextMap_nullStyle() throws Exception {
+        builder.appendText(MONTH_OF_YEAR, (Map<Long, String>) null);
+    }
+
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendOffsetId() throws Exception {
+        builder.appendOffsetId();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Offset(+HH:MM:ss,'Z')");
+    }
+
+    @DataProvider(name="offsetPatterns")
+    Object[][] data_offsetPatterns() {
+        return new Object[][] {
+                {"+HH", 2, 0, 0, "+02"},
+                {"+HH", -2, 0, 0, "-02"},
+                {"+HH", 2, 30, 0, "+02"},
+                {"+HH", 2, 0, 45, "+02"},
+                {"+HH", 2, 30, 45, "+02"},
+
+                {"+HHMM", 2, 0, 0, "+0200"},
+                {"+HHMM", -2, 0, 0, "-0200"},
+                {"+HHMM", 2, 30, 0, "+0230"},
+                {"+HHMM", 2, 0, 45, "+0200"},
+                {"+HHMM", 2, 30, 45, "+0230"},
+
+                {"+HH:MM", 2, 0, 0, "+02:00"},
+                {"+HH:MM", -2, 0, 0, "-02:00"},
+                {"+HH:MM", 2, 30, 0, "+02:30"},
+                {"+HH:MM", 2, 0, 45, "+02:00"},
+                {"+HH:MM", 2, 30, 45, "+02:30"},
+
+                {"+HHMMss", 2, 0, 0, "+0200"},
+                {"+HHMMss", -2, 0, 0, "-0200"},
+                {"+HHMMss", 2, 30, 0, "+0230"},
+                {"+HHMMss", 2, 0, 45, "+020045"},
+                {"+HHMMss", 2, 30, 45, "+023045"},
+
+                {"+HH:MM:ss", 2, 0, 0, "+02:00"},
+                {"+HH:MM:ss", -2, 0, 0, "-02:00"},
+                {"+HH:MM:ss", 2, 30, 0, "+02:30"},
+                {"+HH:MM:ss", 2, 0, 45, "+02:00:45"},
+                {"+HH:MM:ss", 2, 30, 45, "+02:30:45"},
+
+                {"+HHMMSS", 2, 0, 0, "+020000"},
+                {"+HHMMSS", -2, 0, 0, "-020000"},
+                {"+HHMMSS", 2, 30, 0, "+023000"},
+                {"+HHMMSS", 2, 0, 45, "+020045"},
+                {"+HHMMSS", 2, 30, 45, "+023045"},
+
+                {"+HH:MM:SS", 2, 0, 0, "+02:00:00"},
+                {"+HH:MM:SS", -2, 0, 0, "-02:00:00"},
+                {"+HH:MM:SS", 2, 30, 0, "+02:30:00"},
+                {"+HH:MM:SS", 2, 0, 45, "+02:00:45"},
+                {"+HH:MM:SS", 2, 30, 45, "+02:30:45"},
+        };
+    }
+
+    @Test(dataProvider="offsetPatterns")
+    public void test_appendOffset_format(String pattern, int h, int m, int s, String expected) throws Exception {
+        builder.appendOffset(pattern, "Z");
+        DateTimeFormatter f = builder.toFormatter();
+        ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(h, m, s);
+        assertEquals(f.format(offset), expected);
+    }
+
+    @Test(dataProvider="offsetPatterns")
+    public void test_appendOffset_parse(String pattern, int h, int m, int s, String expected) throws Exception {
+        builder.appendOffset(pattern, "Z");
+        DateTimeFormatter f = builder.toFormatter();
+        ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(h, m, s);
+        ZoneOffset parsed = f.parse(expected, ZoneOffset::from);
+        assertEquals(f.format(parsed), expected);
+    }
+
+    @DataProvider(name="badOffsetPatterns")
+    Object[][] data_badOffsetPatterns() {
+        return new Object[][] {
+            {"HH"},
+            {"HHMM"},
+            {"HH:MM"},
+            {"HHMMss"},
+            {"HH:MM:ss"},
+            {"HHMMSS"},
+            {"HH:MM:SS"},
+            {"+H"},
+            {"+HMM"},
+            {"+HHM"},
+            {"+A"},
+        };
+    }
+
+    @Test(dataProvider="badOffsetPatterns", expectedExceptions=IllegalArgumentException.class)
+    public void test_appendOffset_badPattern(String pattern) throws Exception {
+        builder.appendOffset(pattern, "Z");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendOffset_3arg_nullText() throws Exception {
+        builder.appendOffset("+HH:MM", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendOffset_3arg_nullPattern() throws Exception {
+        builder.appendOffset(null, "Z");
+    }
+
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_appendZoneId() throws Exception {
+        builder.appendZoneId();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "ZoneId()");
+    }
+
+    @Test
+    public void test_appendZoneText_1arg() throws Exception {
+        builder.appendZoneText(TextStyle.FULL);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "ZoneText(FULL)");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_appendZoneText_1arg_nullText() throws Exception {
+        builder.appendZoneText(null);
+    }
+
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_padNext_1arg() {
+        builder.appendValue(MONTH_OF_YEAR).appendLiteral(':').padNext(2).appendValue(DAY_OF_MONTH);
+        assertEquals(builder.toFormatter().format(LocalDate.of(2013, 2, 1)), "2: 1");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_padNext_1arg_invalidWidth() throws Exception {
+        builder.padNext(0);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_padNext_2arg_dash() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).appendLiteral(':').padNext(2, '-').appendValue(DAY_OF_MONTH);
+        assertEquals(builder.toFormatter().format(LocalDate.of(2013, 2, 1)), "2:-1");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void test_padNext_2arg_invalidWidth() throws Exception {
+        builder.padNext(0, '-');
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_padOptional() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).appendLiteral(':')
+                .padNext(5).optionalStart().appendValue(DAY_OF_MONTH).optionalEnd()
+                .appendLiteral(':').appendValue(YEAR);
+        assertEquals(builder.toFormatter().format(LocalDate.of(2013, 2, 1)), "2:    1:2013");
+        assertEquals(builder.toFormatter().format(YearMonth.of(2013, 2)), "2:     :2013");
+    }
+
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_optionalStart_noEnd() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).optionalStart().appendValue(DAY_OF_MONTH).appendValue(DAY_OF_WEEK);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear)[Value(DayOfMonth)Value(DayOfWeek)]");
+    }
+
+    @Test
+    public void test_optionalStart2_noEnd() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).optionalStart().appendValue(DAY_OF_MONTH).optionalStart().appendValue(DAY_OF_WEEK);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear)[Value(DayOfMonth)[Value(DayOfWeek)]]");
+    }
+
+    @Test
+    public void test_optionalStart_doubleStart() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).optionalStart().optionalStart().appendValue(DAY_OF_MONTH);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear)[[Value(DayOfMonth)]]");
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_optionalEnd() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).optionalStart().appendValue(DAY_OF_MONTH).optionalEnd().appendValue(DAY_OF_WEEK);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear)[Value(DayOfMonth)]Value(DayOfWeek)");
+    }
+
+    @Test
+    public void test_optionalEnd2() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).optionalStart().appendValue(DAY_OF_MONTH)
+            .optionalStart().appendValue(DAY_OF_WEEK).optionalEnd().appendValue(DAY_OF_MONTH).optionalEnd();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear)[Value(DayOfMonth)[Value(DayOfWeek)]Value(DayOfMonth)]");
+    }
+
+    @Test
+    public void test_optionalEnd_doubleStartSingleEnd() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).optionalStart().optionalStart().appendValue(DAY_OF_MONTH).optionalEnd();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear)[[Value(DayOfMonth)]]");
+    }
+
+    @Test
+    public void test_optionalEnd_doubleStartDoubleEnd() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).optionalStart().optionalStart().appendValue(DAY_OF_MONTH).optionalEnd().optionalEnd();
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear)[[Value(DayOfMonth)]]");
+    }
+
+    @Test
+    public void test_optionalStartEnd_immediateStartEnd() throws Exception {
+        builder.appendValue(MONTH_OF_YEAR).optionalStart().optionalEnd().appendValue(DAY_OF_MONTH);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), "Value(MonthOfYear)Value(DayOfMonth)");
+    }
+
+    @Test(expectedExceptions=IllegalStateException.class)
+    public void test_optionalEnd_noStart() throws Exception {
+        builder.optionalEnd();
+    }
+
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    @DataProvider(name="validPatterns")
+    Object[][] dataValid() {
+        return new Object[][] {
+            {"'a'", "'a'"},
+            {"''", "''"},
+            {"'!'", "'!'"},
+            {"!", "'!'"},
+
+            {"'hello_people,][)('", "'hello_people,][)('"},
+            {"'hi'", "'hi'"},
+            {"'yyyy'", "'yyyy'"},
+            {"''''", "''"},
+            {"'o''clock'", "'o''clock'"},
+
+            {"G", "Text(Era,SHORT)"},
+            {"GG", "Text(Era,SHORT)"},
+            {"GGG", "Text(Era,SHORT)"},
+            {"GGGG", "Text(Era)"},
+            {"GGGGG", "Text(Era,NARROW)"},
+
+            {"y", "Value(Year)"},
+            {"yy", "ReducedValue(Year,2,2000)"},
+            {"yyy", "Value(Year,3,19,NORMAL)"},
+            {"yyyy", "Value(Year,4,19,EXCEEDS_PAD)"},
+            {"yyyyy", "Value(Year,5,19,EXCEEDS_PAD)"},
+
+//            {"Y", "Value(WeekBasedYear)"},
+//            {"YY", "ReducedValue(WeekBasedYear,2,2000)"},
+//            {"YYY", "Value(WeekBasedYear,3,19,NORMAL)"},
+//            {"YYYY", "Value(WeekBasedYear,4,19,EXCEEDS_PAD)"},
+//            {"YYYYY", "Value(WeekBasedYear,5,19,EXCEEDS_PAD)"},
+
+            {"M", "Value(MonthOfYear)"},
+            {"MM", "Value(MonthOfYear,2)"},
+            {"MMM", "Text(MonthOfYear,SHORT)"},
+            {"MMMM", "Text(MonthOfYear)"},
+            {"MMMMM", "Text(MonthOfYear,NARROW)"},
+
+            {"D", "Value(DayOfYear)"},
+            {"DD", "Value(DayOfYear,2)"},
+            {"DDD", "Value(DayOfYear,3)"},
+
+            {"d", "Value(DayOfMonth)"},
+            {"dd", "Value(DayOfMonth,2)"},
+            {"ddd", "Value(DayOfMonth,3)"},
+
+            {"F", "Value(AlignedWeekOfMonth)"},
+            {"FF", "Value(AlignedWeekOfMonth,2)"},
+            {"FFF", "Value(AlignedWeekOfMonth,3)"},
+
+            {"Q", "Value(QuarterOfYear)"},
+            {"QQ", "Value(QuarterOfYear,2)"},
+            {"QQQ", "Text(QuarterOfYear,SHORT)"},
+            {"QQQQ", "Text(QuarterOfYear)"},
+            {"QQQQQ", "Text(QuarterOfYear,NARROW)"},
+
+            {"E", "Value(DayOfWeek)"},
+            {"EE", "Value(DayOfWeek,2)"},
+            {"EEE", "Text(DayOfWeek,SHORT)"},
+            {"EEEE", "Text(DayOfWeek)"},
+            {"EEEEE", "Text(DayOfWeek,NARROW)"},
+
+            {"a", "Text(AmPmOfDay,SHORT)"},
+            {"aa", "Text(AmPmOfDay,SHORT)"},
+            {"aaa", "Text(AmPmOfDay,SHORT)"},
+            {"aaaa", "Text(AmPmOfDay)"},
+            {"aaaaa", "Text(AmPmOfDay,NARROW)"},
+
+            {"H", "Value(HourOfDay)"},
+            {"HH", "Value(HourOfDay,2)"},
+            {"HHH", "Value(HourOfDay,3)"},
+
+            {"K", "Value(HourOfAmPm)"},
+            {"KK", "Value(HourOfAmPm,2)"},
+            {"KKK", "Value(HourOfAmPm,3)"},
+
+            {"k", "Value(ClockHourOfDay)"},
+            {"kk", "Value(ClockHourOfDay,2)"},
+            {"kkk", "Value(ClockHourOfDay,3)"},
+
+            {"h", "Value(ClockHourOfAmPm)"},
+            {"hh", "Value(ClockHourOfAmPm,2)"},
+            {"hhh", "Value(ClockHourOfAmPm,3)"},
+
+            {"m", "Value(MinuteOfHour)"},
+            {"mm", "Value(MinuteOfHour,2)"},
+            {"mmm", "Value(MinuteOfHour,3)"},
+
+            {"s", "Value(SecondOfMinute)"},
+            {"ss", "Value(SecondOfMinute,2)"},
+            {"sss", "Value(SecondOfMinute,3)"},
+
+            {"S", "Fraction(NanoOfSecond,1,1)"},
+            {"SS", "Fraction(NanoOfSecond,2,2)"},
+            {"SSS", "Fraction(NanoOfSecond,3,3)"},
+            {"SSSSSSSSS", "Fraction(NanoOfSecond,9,9)"},
+
+            {"A", "Value(MilliOfDay)"},
+            {"AA", "Value(MilliOfDay,2)"},
+            {"AAA", "Value(MilliOfDay,3)"},
+
+            {"n", "Value(NanoOfSecond)"},
+            {"nn", "Value(NanoOfSecond,2)"},
+            {"nnn", "Value(NanoOfSecond,3)"},
+
+            {"N", "Value(NanoOfDay)"},
+            {"NN", "Value(NanoOfDay,2)"},
+            {"NNN", "Value(NanoOfDay,3)"},
+
+            {"z", "ZoneText(SHORT)"},
+            {"zz", "ZoneText(SHORT)"},
+            {"zzz", "ZoneText(SHORT)"},
+            {"zzzz", "ZoneText(FULL)"},
+
+            {"VV", "ZoneId()"},
+
+            {"Z", "Offset(+HHMM,'+0000')"},  // SimpleDateFormat
+            {"ZZ", "Offset(+HHMM,'+0000')"},  // SimpleDateFormat
+            {"ZZZ", "Offset(+HHMM,'+0000')"},  // SimpleDateFormat
+
+            {"X", "Offset(+HHmm,'Z')"},  // LDML/almost SimpleDateFormat
+            {"XX", "Offset(+HHMM,'Z')"},  // LDML/SimpleDateFormat
+            {"XXX", "Offset(+HH:MM,'Z')"},  // LDML/SimpleDateFormat
+            {"XXXX", "Offset(+HHMMss,'Z')"},  // LDML
+            {"XXXXX", "Offset(+HH:MM:ss,'Z')"},  // LDML
+
+            {"x", "Offset(+HHmm,'+00')"},  // LDML
+            {"xx", "Offset(+HHMM,'+0000')"},  // LDML
+            {"xxx", "Offset(+HH:MM,'+00:00')"},  // LDML
+            {"xxxx", "Offset(+HHMMss,'+0000')"},  // LDML
+            {"xxxxx", "Offset(+HH:MM:ss,'+00:00')"},  // LDML
+
+            {"ppH", "Pad(Value(HourOfDay),2)"},
+            {"pppDD", "Pad(Value(DayOfYear,2),3)"},
+
+            {"yyyy[-MM[-dd", "Value(Year,4,19,EXCEEDS_PAD)['-'Value(MonthOfYear,2)['-'Value(DayOfMonth,2)]]"},
+            {"yyyy[-MM[-dd]]", "Value(Year,4,19,EXCEEDS_PAD)['-'Value(MonthOfYear,2)['-'Value(DayOfMonth,2)]]"},
+            {"yyyy[-MM[]-dd]", "Value(Year,4,19,EXCEEDS_PAD)['-'Value(MonthOfYear,2)'-'Value(DayOfMonth,2)]"},
+
+            {"yyyy-MM-dd'T'HH:mm:ss.SSS", "Value(Year,4,19,EXCEEDS_PAD)'-'Value(MonthOfYear,2)'-'Value(DayOfMonth,2)" +
+                "'T'Value(HourOfDay,2)':'Value(MinuteOfHour,2)':'Value(SecondOfMinute,2)'.'Fraction(NanoOfSecond,3,3)"},
+
+            {"e", "WeekBased(e1)"},
+            {"w", "WeekBased(w1)"},
+            {"W", "WeekBased(W1)"},
+            {"WW", "WeekBased(W2)"},
+
+        };
+    }
+
+    @Test(dataProvider="validPatterns", groups={"implementation"})
+    public void test_appendPattern_valid(String input, String expected) throws Exception {
+        builder.appendPattern(input);
+        DateTimeFormatter f = builder.toFormatter();
+        assertEquals(f.toString(), expected);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="invalidPatterns")
+    Object[][] dataInvalid() {
+        return new Object[][] {
+            {"'"},
+            {"'hello"},
+            {"'hel''lo"},
+            {"'hello''"},
+            {"{"},
+            {"}"},
+            {"{}"},
+            {"]"},
+            {"yyyy]"},
+            {"yyyy]MM"},
+            {"yyyy[MM]]"},
+
+            {"MMMMMM"},
+            {"QQQQQQ"},
+            {"EEEEEE"},
+            {"aaaaaa"},
+            {"ZZZZ"},
+            {"XXXXXX"},
+            {"zzzzz"},
+            {"V"},
+            {"VVV"},
+            {"VVVV"},
+            {"VVVVV"},
+
+            {"RO"},
+
+            {"p"},
+            {"pp"},
+            {"p:"},
+
+            {"f"},
+            {"ff"},
+            {"f:"},
+            {"fy"},
+            {"fa"},
+            {"fM"},
+
+            {"ww"},
+            {"ee"},
+            {"WWW"},
+        };
+    }
+
+    @Test(dataProvider="invalidPatterns", expectedExceptions=IllegalArgumentException.class)
+    public void test_appendPattern_invalid(String input) throws Exception {
+        try {
+            builder.appendPattern(input);
+        } catch (IllegalArgumentException ex) {
+            throw ex;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="patternPrint")
+    Object[][] data_patternPrint() {
+        return new Object[][] {
+            {"Q", date(2012, 2, 10), "1"},
+            {"QQ", date(2012, 2, 10), "01"},
+//            {"QQQ", date(2012, 2, 10), "Q1"},  // TODO: data for quarters?
+//            {"QQQQ", date(2012, 2, 10), "Q1"},
+//            {"QQQQQ", date(2012, 2, 10), "Q1"},
+        };
+    }
+
+    @Test(dataProvider="patternPrint")
+    public void test_appendPattern_patternPrint(String input, Temporal temporal, String expected) throws Exception {
+        DateTimeFormatter f = builder.appendPattern(input).toFormatter(Locale.UK);
+        String test = f.format(temporal);
+        assertEquals(test, expected);
+    }
+
+    private static Temporal date(int y, int m, int d) {
+        return LocalDate.of(y, m, d);
+    }
+
+}
diff --git a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatters.java b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatters.java
deleted file mode 100644
index 5e7ab3e..0000000
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatters.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package test.java.time.format;
-
-import java.time.format.*;
-
-import static org.testng.Assert.assertTrue;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.util.Collections;
-
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-/**
- * Test DateTimeFormatters.
- */
-@Test
-public class TestDateTimeFormatters {
-
-    @BeforeMethod
-    public void setUp() {
-    }
-
-    @Test(groups={"implementation"})
-    @SuppressWarnings("rawtypes")
-    public void test_constructor() throws Exception {
-        for (Constructor constructor : DateTimeFormatters.class.getDeclaredConstructors()) {
-            assertTrue(Modifier.isPrivate(constructor.getModifiers()));
-            //constructor.setAccessible(true);
-            //constructor.newInstance(Collections.nCopies(constructor.getParameterTypes().length, null).toArray());
-        }
-    }
-
-}
diff --git a/jdk/test/java/time/test/java/time/format/TestDateTimePrintException.java b/jdk/test/java/time/test/java/time/format/TestDateTimePrintException.java
deleted file mode 100644
index 3a737f3..0000000
--- a/jdk/test/java/time/test/java/time/format/TestDateTimePrintException.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package test.java.time.format;
-
-import java.time.format.*;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertSame;
-
-import java.io.IOException;
-
-import org.testng.annotations.Test;
-
-/**
- * Test DateTimePrintException.
- */
-@Test
-public class TestDateTimePrintException {
-
-    @Test(groups={"implementation"})
-    public void test_constructor_StringThrowable_notIOException_same() throws Exception {
-        IllegalArgumentException iaex = new IllegalArgumentException("INNER");
-        DateTimePrintException ex = new DateTimePrintException("TEST", iaex);
-        assertEquals(ex.getMessage(), "TEST");
-        assertSame(ex.getCause(), iaex);
-        ex.rethrowIOException();  // no effect
-    }
-
-    @Test(expectedExceptions=IOException.class, groups={"implementation"})
-    public void test_constructor_StringThrowable_IOException_same() throws Exception {
-        IOException ioex = new IOException("INNER");
-        DateTimePrintException ex = new DateTimePrintException("TEST", ioex);
-        assertEquals(ex.getMessage(), "TEST");
-        assertSame(ex.getCause(), ioex);
-        ex.rethrowIOException();  // rethrows
-    }
-
-}
diff --git a/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java
index ab8cec3..1d34a2d 100644
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java
@@ -180,7 +180,7 @@
     @Test(dataProvider = "Text")
     public void test_getText(TemporalField field, Number value, TextStyle style, Locale locale, String expected) {
           DateTimeFormatter fmt = getFormatter(field, style).withLocale(locale);
-          assertEquals(fmt.print(ZonedDateTime.now().with(field, value.longValue())), expected);
+          assertEquals(fmt.format(ZonedDateTime.now().with(field, value.longValue())), expected);
     }
 
 }
diff --git a/jdk/test/java/time/test/java/time/format/TestFractionPrinterParser.java b/jdk/test/java/time/test/java/time/format/TestFractionPrinterParser.java
index 4be3b6c..2925c9f 100644
--- a/jdk/test/java/time/test/java/time/format/TestFractionPrinterParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestFractionPrinterParser.java
@@ -59,8 +59,6 @@
  */
 package test.java.time.format;
 
-import java.time.format.*;
-
 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
 import static org.testng.Assert.assertEquals;
@@ -69,13 +67,13 @@
 import java.text.ParsePosition;
 import java.time.DateTimeException;
 import java.time.LocalTime;
-import java.time.format.DateTimeBuilder;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 
-import test.java.time.temporal.MockFieldValue;
-
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import test.java.time.temporal.MockFieldValue;
 
 /**
  * Test FractionPrinterParser.
@@ -92,12 +90,12 @@
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=DateTimeException.class)
     public void test_print_emptyCalendrical() throws Exception {
-        getFormatter(NANO_OF_SECOND, 0, 9, true).printTo(EMPTY_DTA, buf);
+        getFormatter(NANO_OF_SECOND, 0, 9, true).formatTo(EMPTY_DTA, buf);
     }
 
     public void test_print_append() throws Exception {
         buf.append("EXISTING");
-        getFormatter(NANO_OF_SECOND, 0, 9, true).printTo(LocalTime.of(12, 30, 40, 3), buf);
+        getFormatter(NANO_OF_SECOND, 0, 9, true).formatTo(LocalTime.of(12, 30, 40, 3), buf);
         assertEquals(buf.toString(), "EXISTING.000000003");
     }
 
@@ -180,7 +178,7 @@
 
     @Test(dataProvider="Nanos")
     public void test_print_nanos(int minWidth, int maxWidth, int value, String result) throws Exception {
-        getFormatter(NANO_OF_SECOND,  minWidth, maxWidth, true).printTo(new MockFieldValue(NANO_OF_SECOND, value), buf);
+        getFormatter(NANO_OF_SECOND,  minWidth, maxWidth, true).formatTo(new MockFieldValue(NANO_OF_SECOND, value), buf);
         if (result == null) {
             fail("Expected exception");
         }
@@ -189,7 +187,7 @@
 
     @Test(dataProvider="Nanos")
     public void test_print_nanos_noDecimalPoint(int minWidth, int maxWidth, int value, String result) throws Exception {
-        getFormatter(NANO_OF_SECOND,  minWidth, maxWidth, false).printTo(new MockFieldValue(NANO_OF_SECOND, value), buf);
+        getFormatter(NANO_OF_SECOND,  minWidth, maxWidth, false).formatTo(new MockFieldValue(NANO_OF_SECOND, value), buf);
         if (result == null) {
             fail("Expected exception");
         }
@@ -222,7 +220,7 @@
 
     @Test(dataProvider="Seconds")
     public void test_print_seconds(int minWidth, int maxWidth, int value, String result) throws Exception {
-        getFormatter(SECOND_OF_MINUTE, minWidth, maxWidth, true).printTo(new MockFieldValue(SECOND_OF_MINUTE, value), buf);
+        getFormatter(SECOND_OF_MINUTE, minWidth, maxWidth, true).formatTo(new MockFieldValue(SECOND_OF_MINUTE, value), buf);
         if (result == null) {
             fail("Expected exception");
         }
@@ -231,7 +229,7 @@
 
     @Test(dataProvider="Seconds")
     public void test_print_seconds_noDecimalPoint(int minWidth, int maxWidth, int value, String result) throws Exception {
-        getFormatter(SECOND_OF_MINUTE, minWidth, maxWidth, false).printTo(new MockFieldValue(SECOND_OF_MINUTE, value), buf);
+        getFormatter(SECOND_OF_MINUTE, minWidth, maxWidth, false).formatTo(new MockFieldValue(SECOND_OF_MINUTE, value), buf);
         if (result == null) {
             fail("Expected exception");
         }
@@ -245,27 +243,27 @@
     public void test_reverseParse(int minWidth, int maxWidth, int value, String result) throws Exception {
         ParsePosition pos = new ParsePosition(0);
         int expectedValue = fixParsedValue(maxWidth, value);
-        DateTimeBuilder dtb = getFormatter(NANO_OF_SECOND, minWidth, maxWidth, true).parseToBuilder(result, pos);
+        TemporalAccessor parsed = getFormatter(NANO_OF_SECOND, minWidth, maxWidth, true).parseUnresolved(result, pos);
         assertEquals(pos.getIndex(), result.length());
-        assertParsed(dtb, NANO_OF_SECOND, value == 0 && minWidth == 0 ? null : (long) expectedValue);
+        assertParsed(parsed, NANO_OF_SECOND, value == 0 && minWidth == 0 ? null : (long) expectedValue);
     }
 
     @Test(dataProvider="Nanos")
     public void test_reverseParse_noDecimalPoint(int minWidth, int maxWidth, int value, String result) throws Exception {
         ParsePosition pos = new ParsePosition((result.startsWith(".") ? 1 : 0));
-        DateTimeBuilder dtb = getFormatter(NANO_OF_SECOND, minWidth, maxWidth, false).parseToBuilder(result, pos);
+        TemporalAccessor parsed = getFormatter(NANO_OF_SECOND, minWidth, maxWidth, false).parseUnresolved(result, pos);
         assertEquals(pos.getIndex(), result.length());
         int expectedValue = fixParsedValue(maxWidth, value);
-        assertParsed(dtb, NANO_OF_SECOND, value == 0 && minWidth == 0 ? null : (long) expectedValue);
+        assertParsed(parsed, NANO_OF_SECOND, value == 0 && minWidth == 0 ? null : (long) expectedValue);
     }
 
     @Test(dataProvider="Nanos")
     public void test_reverseParse_followedByNonDigit(int minWidth, int maxWidth, int value, String result) throws Exception {
         ParsePosition pos = new ParsePosition(0);
         int expectedValue = fixParsedValue(maxWidth, value);
-        DateTimeBuilder dtb = getFormatter(NANO_OF_SECOND, minWidth, maxWidth, true).parseToBuilder(result + " ", pos);
+        TemporalAccessor parsed = getFormatter(NANO_OF_SECOND, minWidth, maxWidth, true).parseUnresolved(result + " ", pos);
         assertEquals(pos.getIndex(), result.length());
-        assertParsed(dtb, NANO_OF_SECOND, value == 0 && minWidth == 0 ? null : (long) expectedValue);
+        assertParsed(parsed, NANO_OF_SECOND, value == 0 && minWidth == 0 ? null : (long) expectedValue);
     }
 
 //    @Test(dataProvider="Nanos")
@@ -281,9 +279,9 @@
     public void test_reverseParse_preceededByNonDigit(int minWidth, int maxWidth, int value, String result) throws Exception {
         ParsePosition pos = new ParsePosition(1);
         int expectedValue = fixParsedValue(maxWidth, value);
-        DateTimeBuilder dtb = getFormatter(NANO_OF_SECOND, minWidth, maxWidth, true).parseToBuilder(" " + result, pos);
+        TemporalAccessor parsed = getFormatter(NANO_OF_SECOND, minWidth, maxWidth, true).parseUnresolved(" " + result, pos);
         assertEquals(pos.getIndex(), result.length() + 1);
-        assertParsed(dtb, NANO_OF_SECOND, value == 0 && minWidth == 0 ? null : (long) expectedValue);
+        assertParsed(parsed, NANO_OF_SECOND, value == 0 && minWidth == 0 ? null : (long) expectedValue);
     }
 
     private int fixParsedValue(int maxWidth, int value) {
@@ -297,16 +295,17 @@
     @Test(dataProvider="Seconds")
     public void test_reverseParse_seconds(int minWidth, int maxWidth, int value, String result) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(SECOND_OF_MINUTE, minWidth, maxWidth, true).parseToBuilder(result, pos);
+        TemporalAccessor parsed = getFormatter(SECOND_OF_MINUTE, minWidth, maxWidth, true).parseUnresolved(result, pos);
         assertEquals(pos.getIndex(), result.length());
-        assertParsed(dtb, SECOND_OF_MINUTE, value == 0 && minWidth == 0 ? null : (long) value);
+        assertParsed(parsed, SECOND_OF_MINUTE, value == 0 && minWidth == 0 ? null : (long) value);
     }
 
-    private void assertParsed(DateTimeBuilder dtb, TemporalField field, Long value) {
+    private void assertParsed(TemporalAccessor parsed, TemporalField field, Long value) {
         if (value == null) {
-            assertEquals(dtb.containsFieldValue(field), false);
+            assertEquals(parsed.isSupported(field), false);
         } else {
-            assertEquals(dtb.getLong(field), (long)value);
+            assertEquals(parsed.isSupported(field), true);
+            assertEquals(parsed.getLong(field), (long) value);
         }
     }
 
@@ -327,8 +326,9 @@
     @Test(dataProvider = "ParseNothing")
     public void test_parse_nothing(TemporalField field, int min, int max, boolean decimalPoint, String text, int pos, int expected) {
         ParsePosition ppos = new ParsePosition(pos);
-        DateTimeBuilder dtb = getFormatter(field, min, max, decimalPoint).parseToBuilder(text, ppos);
+        TemporalAccessor parsed = getFormatter(field, min, max, decimalPoint).parseUnresolved(text, ppos);
         assertEquals(ppos.getErrorIndex(), expected);
+        assertEquals(parsed, null);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java
new file mode 100644
index 0000000..43a603c
--- /dev/null
+++ b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.java.time.format;
+
+import java.time.*;
+import java.time.chrono.*;
+import java.time.format.*;
+import java.time.temporal.*;
+import java.util.Locale;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Test DateTimeFormatter with non-ISO chronology.
+ *
+ * Strings in test data are all dependent on CLDR data which may change
+ * in future CLDR releases.
+ */
+@Test(groups={"implementation"})
+public class TestNonIsoFormatter {
+    private static final Chronology JAPANESE = JapaneseChronology.INSTANCE;
+    private static final Chronology HIJRAH = HijrahChronology.INSTANCE;
+    private static final Chronology MINGUO = MinguoChronology.INSTANCE;
+    private static final Chronology BUDDHIST = ThaiBuddhistChronology.INSTANCE;
+
+    private static final LocalDate IsoDate = LocalDate.of(2013, 2, 11);
+
+    private static final Locale ARABIC = new Locale("ar");
+    private static final Locale thTH = new Locale("th", "TH");
+    private static final Locale thTHTH = new Locale("th", "TH", "TH");
+
+    @BeforeMethod
+    public void setUp() {
+    }
+
+    @DataProvider(name="format_data")
+    Object[][] formatData() {
+        return new Object[][] {
+            // Chronology, Locale, ChronoLocalDate, expected string
+            { JAPANESE, Locale.JAPANESE, JAPANESE.date(IsoDate),
+              "\u5e73\u621025\u5e742\u670811\u65e5\u6708\u66dc\u65e5" }, // Japanese Heisei 25-02-11 (Mon)
+            { HIJRAH, ARABIC, HIJRAH.date(IsoDate),
+              "\u0627\u0644\u0627\u062b\u0646\u064a\u0646\u060c 30 \u0631\u0628\u064a\u0639 "
+              + "\u0627\u0644\u0623\u0648\u0644 1434" }, // Hijrah AH 1434-03-30 (Mon)
+            { MINGUO, Locale.TAIWAN, MINGUO.date(IsoDate),
+              "\u6c11\u570b102\u5e742\u670811\u65e5\u661f\u671f\u4e00" }, // Minguo ROC 102-02-11 (Mon)
+            { BUDDHIST, thTH, BUDDHIST.date(IsoDate),
+              "\u0e27\u0e31\u0e19\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c\u0e17\u0e35\u0e48"
+              + " 11 \u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c"
+              + " \u0e1e.\u0e28. 2556" }, // ThaiBuddhist BE 2556-02-11
+         // { BUDDHIST, thTHTH, BUDDHIST.date(IsoDate), "<TBS>" }, // doesn't work
+        };
+    }
+
+    @DataProvider(name="invalid_text")
+    Object[][] invalidText() {
+        return new Object[][] {
+            // TODO: currently fixed Chronology and Locale.
+            { "\u662d\u548c64\u5e741\u67089\u65e5\u6708\u66dc\u65e5" }, // S64.01.09 (Mon)
+            { "\u662d\u548c65\u5e741\u67081\u65e5\u6708\u66dc\u65e5" }, // S65.01.01 (Mon)
+        };
+    }
+
+    @Test(dataProvider="format_data")
+    public void test_formatLocalizedDate(Chronology chrono, Locale locale, ChronoLocalDate<?> date, String expected) {
+        DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
+            .withChronology(chrono).withLocale(locale);
+        String text = dtf.format(date);
+        assertEquals(text, expected);
+    }
+
+    @Test(dataProvider="format_data")
+    public void test_parseLocalizedText(Chronology chrono, Locale locale, ChronoLocalDate<?> expected, String text) {
+        DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
+            .withChronology(chrono).withLocale(locale);
+        TemporalAccessor temporal = dtf.parse(text);
+        ChronoLocalDate<?> date = chrono.date(temporal);
+        assertEquals(date, expected);
+    }
+
+    @Test(dataProvider="invalid_text", expectedExceptions=DateTimeParseException.class)
+    public void test_parseInvalidText(String text) {
+        DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
+            .withChronology(JAPANESE).withLocale(Locale.JAPANESE);
+        TemporalAccessor temporal = dtf.parse(text);
+    }
+}
diff --git a/jdk/test/java/time/test/java/time/format/TestNumberParser.java b/jdk/test/java/time/test/java/time/format/TestNumberParser.java
index af4b3b6..5dca693 100644
--- a/jdk/test/java/time/test/java/time/format/TestNumberParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestNumberParser.java
@@ -59,19 +59,20 @@
  */
 package test.java.time.format;
 
-import java.time.format.*;
-
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 import java.text.ParsePosition;
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.TemporalField;
 import java.time.format.DateTimeFormatter;
+import java.time.format.SignStyle;
+import java.time.temporal.Queries;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalField;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -94,8 +95,8 @@
     @Test(dataProvider="error")
     public void test_parse_error(TemporalField field, int min, int max, SignStyle style, String text, int pos, Class<?> expected) {
         try {
-            getFormatter(field, min, max, style).parseToBuilder(text, new ParsePosition(pos));
-            assertTrue(false);
+            getFormatter(field, min, max, style).parseUnresolved(text, new ParsePosition(pos));
+            fail();
         } catch (RuntimeException ex) {
             assertTrue(expected.isInstance(ex));
         }
@@ -170,13 +171,15 @@
             // hacky, to reserve space
             dtf = builder.appendValue(DAY_OF_YEAR, subsequentWidth).toFormatter(locale).withSymbols(symbols);
         }
-        DateTimeBuilder dtb = dtf.parseToBuilder(text, ppos);
+        TemporalAccessor parsed = dtf.parseUnresolved(text, ppos);
         if (ppos.getErrorIndex() != -1) {
             assertEquals(ppos.getErrorIndex(), expectedPos);
         } else {
             assertTrue(subsequentWidth >= 0);
             assertEquals(ppos.getIndex(), expectedPos + subsequentWidth);
-            assertEquals(dtb.getLong(DAY_OF_MONTH), expectedValue);
+            assertEquals(parsed.getLong(DAY_OF_MONTH), expectedValue);
+            assertEquals(parsed.query(Queries.chronology()), null);
+            assertEquals(parsed.query(Queries.zoneId()), null);
         }
     }
 
@@ -188,13 +191,15 @@
             // hacky, to reserve space
             dtf = builder.appendValue(DAY_OF_YEAR, subsequentWidth).toFormatter(locale).withSymbols(symbols);
         }
-        DateTimeBuilder dtb = dtf.parseToBuilder(text, ppos);
+        TemporalAccessor parsed = dtf.parseUnresolved(text, ppos);
         if (ppos.getErrorIndex() != -1) {
             assertEquals(ppos.getErrorIndex(), expectedPos);
         } else {
             assertTrue(subsequentWidth >= 0);
             assertEquals(ppos.getIndex(), expectedPos + subsequentWidth);
-            assertEquals(dtb.getLong(DAY_OF_WEEK), expectedValue);
+            assertEquals(parsed.getLong(DAY_OF_WEEK), expectedValue);
+            assertEquals(parsed.query(Queries.chronology()), null);
+            assertEquals(parsed.query(Queries.zoneId()), null);
         }
     }
 
@@ -302,12 +307,14 @@
     @Test(dataProvider="parseSignsStrict")
     public void test_parseSignsStrict(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(DAY_OF_MONTH, min, max, style).parseToBuilder(input, pos);
+        TemporalAccessor parsed = getFormatter(DAY_OF_MONTH, min, max, style).parseUnresolved(input, pos);
         if (pos.getErrorIndex() != -1) {
             assertEquals(pos.getErrorIndex(), parseLen);
         } else {
             assertEquals(pos.getIndex(), parseLen);
-            assertEquals(dtb.getLong(DAY_OF_MONTH), (long)parseVal);
+            assertEquals(parsed.getLong(DAY_OF_MONTH), (long)parseVal);
+            assertEquals(parsed.query(Queries.chronology()), null);
+            assertEquals(parsed.query(Queries.zoneId()), null);
         }
     }
 
@@ -410,12 +417,14 @@
     public void test_parseSignsLenient(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal) throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(DAY_OF_MONTH, min, max, style).parseToBuilder(input, pos);
+        TemporalAccessor parsed = getFormatter(DAY_OF_MONTH, min, max, style).parseUnresolved(input, pos);
         if (pos.getErrorIndex() != -1) {
             assertEquals(pos.getErrorIndex(), parseLen);
         } else {
             assertEquals(pos.getIndex(), parseLen);
-            assertEquals(dtb.getLong(DAY_OF_MONTH), (long)parseVal);
+            assertEquals(parsed.getLong(DAY_OF_MONTH), (long)parseVal);
+            assertEquals(parsed.query(Queries.chronology()), null);
+            assertEquals(parsed.query(Queries.zoneId()), null);
         }
     }
 
@@ -499,12 +508,14 @@
     public void test_parseDigitsLenient(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal) throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(DAY_OF_MONTH, min, max, style).parseToBuilder(input, pos);
+        TemporalAccessor parsed = getFormatter(DAY_OF_MONTH, min, max, style).parseUnresolved(input, pos);
         if (pos.getErrorIndex() != -1) {
             assertEquals(pos.getErrorIndex(), parseLen);
         } else {
             assertEquals(pos.getIndex(), parseLen);
-            assertEquals(dtb.getLong(DAY_OF_MONTH), (long)parseVal);
+            assertEquals(parsed.getLong(DAY_OF_MONTH), (long)parseVal);
+            assertEquals(parsed.query(Queries.chronology()), null);
+            assertEquals(parsed.query(Queries.zoneId()), null);
         }
     }
 
@@ -534,13 +545,15 @@
         DateTimeFormatter f = builder
                 .appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL)
                 .appendValue(DAY_OF_MONTH, 2).toFormatter(locale).withSymbols(symbols);
-        DateTimeBuilder dtb = f.parseToBuilder(input, pos);
+        TemporalAccessor parsed = f.parseUnresolved(input, pos);
         if (pos.getErrorIndex() != -1) {
             assertEquals(pos.getErrorIndex(), parseLen);
         } else {
             assertEquals(pos.getIndex(), parseLen);
-            assertEquals(dtb.getLong(MONTH_OF_YEAR), (long) parseMonth);
-            assertEquals(dtb.getLong(DAY_OF_MONTH), (long) parsedDay);
+            assertEquals(parsed.getLong(MONTH_OF_YEAR), (long) parseMonth);
+            assertEquals(parsed.getLong(DAY_OF_MONTH), (long) parsedDay);
+            assertEquals(parsed.query(Queries.chronology()), null);
+            assertEquals(parsed.query(Queries.zoneId()), null);
         }
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestNumberPrinter.java b/jdk/test/java/time/test/java/time/format/TestNumberPrinter.java
index 80c05b8..9d68647 100644
--- a/jdk/test/java/time/test/java/time/format/TestNumberPrinter.java
+++ b/jdk/test/java/time/test/java/time/format/TestNumberPrinter.java
@@ -59,8 +59,6 @@
  */
 package test.java.time.format;
 
-import java.time.format.*;
-
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
 import static org.testng.Assert.assertEquals;
@@ -68,10 +66,11 @@
 
 import java.time.DateTimeException;
 import java.time.LocalDate;
-import test.java.time.temporal.MockFieldValue;
+import java.time.format.SignStyle;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import test.java.time.temporal.MockFieldValue;
 
 /**
  * Test SimpleNumberPrinterParser.
@@ -82,12 +81,12 @@
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=DateTimeException.class)
     public void test_print_emptyCalendrical() throws Exception {
-        getFormatter(DAY_OF_MONTH, 1, 2, SignStyle.NEVER).printTo(EMPTY_DTA, buf);
+        getFormatter(DAY_OF_MONTH, 1, 2, SignStyle.NEVER).formatTo(EMPTY_DTA, buf);
     }
 
     public void test_print_append() throws Exception {
         buf.append("EXISTING");
-        getFormatter(DAY_OF_MONTH, 1, 2, SignStyle.NEVER).printTo(LocalDate.of(2012, 1, 3), buf);
+        getFormatter(DAY_OF_MONTH, 1, 2, SignStyle.NEVER).formatTo(LocalDate.of(2012, 1, 3), buf);
         assertEquals(buf.toString(), "EXISTING3");
     }
 
@@ -185,12 +184,12 @@
     @Test(dataProvider="Pad")
     public void test_pad_NOT_NEGATIVE(int minPad, int maxPad, long value, String result) throws Exception {
         try {
-            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.NOT_NEGATIVE).printTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
+            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.NOT_NEGATIVE).formatTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
             if (result == null || value < 0) {
                 fail("Expected exception");
             }
             assertEquals(buf.toString(), result);
-        } catch (DateTimePrintException ex) {
+        } catch (DateTimeException ex) {
             if (result == null || value < 0) {
                 assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true);
             } else {
@@ -202,12 +201,12 @@
     @Test(dataProvider="Pad")
     public void test_pad_NEVER(int minPad, int maxPad, long value, String result) throws Exception {
         try {
-            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.NEVER).printTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
+            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.NEVER).formatTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
             if (result == null) {
                 fail("Expected exception");
             }
             assertEquals(buf.toString(), result);
-        } catch (DateTimePrintException ex) {
+        } catch (DateTimeException ex) {
             if (result != null) {
                 throw ex;
             }
@@ -218,12 +217,12 @@
     @Test(dataProvider="Pad")
     public void test_pad_NORMAL(int minPad, int maxPad, long value, String result) throws Exception {
         try {
-            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.NORMAL).printTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
+            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.NORMAL).formatTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
             if (result == null) {
                 fail("Expected exception");
             }
             assertEquals(buf.toString(), (value < 0 ? "-" + result : result));
-        } catch (DateTimePrintException ex) {
+        } catch (DateTimeException ex) {
             if (result != null) {
                 throw ex;
             }
@@ -234,12 +233,12 @@
     @Test(dataProvider="Pad")
     public void test_pad_ALWAYS(int minPad, int maxPad, long value, String result) throws Exception {
         try {
-            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.ALWAYS).printTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
+            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.ALWAYS).formatTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
             if (result == null) {
                 fail("Expected exception");
             }
             assertEquals(buf.toString(), (value < 0 ? "-" + result : "+" + result));
-        } catch (DateTimePrintException ex) {
+        } catch (DateTimeException ex) {
             if (result != null) {
                 throw ex;
             }
@@ -250,7 +249,7 @@
     @Test(dataProvider="Pad")
     public void test_pad_EXCEEDS_PAD(int minPad, int maxPad, long value, String result) throws Exception {
         try {
-            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.EXCEEDS_PAD).printTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
+            getFormatter(DAY_OF_MONTH, minPad, maxPad, SignStyle.EXCEEDS_PAD).formatTo(new MockFieldValue(DAY_OF_MONTH, value), buf);
             if (result == null) {
                 fail("Expected exception");
                 return;  // unreachable
@@ -259,7 +258,7 @@
                 result = (value < 0 ? "-" + result : "+" + result);
             }
             assertEquals(buf.toString(), result);
-        } catch (DateTimePrintException ex) {
+        } catch (DateTimeException ex) {
             if (result != null) {
                 throw ex;
             }
diff --git a/jdk/test/java/time/test/java/time/format/TestPadParserDecorator.java b/jdk/test/java/time/test/java/time/format/TestPadParserDecorator.java
deleted file mode 100644
index 08a9e24..0000000
--- a/jdk/test/java/time/test/java/time/format/TestPadParserDecorator.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package test.java.time.format;
-
-import java.time.format.*;
-
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static org.testng.Assert.assertEquals;
-
-import java.text.ParsePosition;
-import java.time.format.DateTimeBuilder;
-
-import org.testng.annotations.Test;
-
-/**
- * Test PadPrinterParserDecorator.
- */
-@Test(groups={"implementation"})
-public class TestPadParserDecorator extends AbstractTestPrinterParser {
-
-    //-----------------------------------------------------------------------
-    @Test(expectedExceptions=IndexOutOfBoundsException.class)
-    public void test_parse_negativePosition() throws Exception {
-        builder.padNext(3, '-').appendLiteral('Z');
-        getFormatter().parseToBuilder("--Z", new ParsePosition(-1));
-    }
-
-    @Test(expectedExceptions=IndexOutOfBoundsException.class)
-    public void test_parse_offEndPosition() throws Exception {
-        builder.padNext(3, '-').appendLiteral('Z');
-        getFormatter().parseToBuilder("--Z", new ParsePosition(4));
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_parse() throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        builder.padNext(3, '-').appendValue(MONTH_OF_YEAR, 1, 3, SignStyle.NEVER);
-        DateTimeBuilder dtb = getFormatter().parseToBuilder("--2", pos);
-        assertEquals(pos.getIndex(), 3);
-        assertEquals(dtb.getFieldValueMap().size(), 1);
-        assertEquals(dtb.getLong(MONTH_OF_YEAR), 2L);
-    }
-
-    public void test_parse_noReadBeyond() throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        builder.padNext(3, '-').appendValue(MONTH_OF_YEAR, 1, 3, SignStyle.NEVER);
-        DateTimeBuilder dtb = getFormatter().parseToBuilder("--22", pos);
-        assertEquals(pos.getIndex(), 3);
-        assertEquals(dtb.getFieldValueMap().size(), 1);
-        assertEquals(dtb.getLong(MONTH_OF_YEAR), 2L);
-    }
-
-    public void test_parse_textLessThanPadWidth() throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        builder.padNext(3, '-').appendValue(MONTH_OF_YEAR, 1, 3, SignStyle.NEVER);
-        DateTimeBuilder dtb = getFormatter().parseToBuilder("-1", pos);
-        assertEquals(pos.getErrorIndex(), 0);
-    }
-
-    public void test_parse_decoratedErrorPassedBack() throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        builder.padNext(3, '-').appendValue(MONTH_OF_YEAR, 1, 3, SignStyle.NEVER);
-        DateTimeBuilder dtb = getFormatter().parseToBuilder("--A", pos);
-        assertEquals(pos.getErrorIndex(), 2);
-    }
-
-    public void test_parse_decoratedDidNotParseToPadWidth() throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        builder.padNext(3, '-').appendValue(MONTH_OF_YEAR, 1, 3, SignStyle.NEVER);
-        DateTimeBuilder dtb = getFormatter().parseToBuilder("-1X", pos);
-        assertEquals(pos.getErrorIndex(), 0);
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_parse_decoratedStartsWithPad() throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        builder.padNext(8, '-').appendLiteral("-HELLO-");
-        DateTimeBuilder dtb = getFormatter().parseToBuilder("--HELLO-", pos);
-        assertEquals(pos.getIndex(), 8);
-        assertEquals(dtb.getFieldValueMap().size(), 0);
-    }
-
-}
diff --git a/jdk/test/java/time/test/java/time/format/TestPadPrinterDecorator.java b/jdk/test/java/time/test/java/time/format/TestPadPrinterDecorator.java
index d6302ae..c8dcbf3 100644
--- a/jdk/test/java/time/test/java/time/format/TestPadPrinterDecorator.java
+++ b/jdk/test/java/time/test/java/time/format/TestPadPrinterDecorator.java
@@ -59,10 +59,9 @@
  */
 package test.java.time.format;
 
-import java.time.format.*;
-
 import static org.testng.Assert.assertEquals;
 
+import java.time.DateTimeException;
 import java.time.LocalDate;
 
 import org.testng.annotations.Test;
@@ -76,52 +75,52 @@
     //-----------------------------------------------------------------------
     public void test_print_emptyCalendrical() throws Exception {
         builder.padNext(3, '-').appendLiteral('Z');
-        getFormatter().printTo(EMPTY_DTA, buf);
+        getFormatter().formatTo(EMPTY_DTA, buf);
         assertEquals(buf.toString(), "--Z");
     }
 
     public void test_print_fullDateTime() throws Exception {
         builder.padNext(3, '-').appendLiteral('Z');
-        getFormatter().printTo(LocalDate.of(2008, 12, 3), buf);
+        getFormatter().formatTo(LocalDate.of(2008, 12, 3), buf);
         assertEquals(buf.toString(), "--Z");
     }
 
     public void test_print_append() throws Exception {
         buf.append("EXISTING");
         builder.padNext(3, '-').appendLiteral('Z');
-        getFormatter().printTo(EMPTY_DTA, buf);
+        getFormatter().formatTo(EMPTY_DTA, buf);
         assertEquals(buf.toString(), "EXISTING--Z");
     }
 
     //-----------------------------------------------------------------------
     public void test_print_noPadRequiredSingle() throws Exception {
         builder.padNext(1, '-').appendLiteral('Z');
-        getFormatter().printTo(EMPTY_DTA, buf);
+        getFormatter().formatTo(EMPTY_DTA, buf);
         assertEquals(buf.toString(), "Z");
     }
 
     public void test_print_padRequiredSingle() throws Exception {
         builder.padNext(5, '-').appendLiteral('Z');
-        getFormatter().printTo(EMPTY_DTA, buf);
+        getFormatter().formatTo(EMPTY_DTA, buf);
         assertEquals(buf.toString(), "----Z");
     }
 
     public void test_print_noPadRequiredMultiple() throws Exception {
         builder.padNext(4, '-').appendLiteral("WXYZ");
-        getFormatter().printTo(EMPTY_DTA, buf);
+        getFormatter().formatTo(EMPTY_DTA, buf);
         assertEquals(buf.toString(), "WXYZ");
     }
 
     public void test_print_padRequiredMultiple() throws Exception {
         builder.padNext(5, '-').appendLiteral("WXYZ");
-        getFormatter().printTo(EMPTY_DTA, buf);
+        getFormatter().formatTo(EMPTY_DTA, buf);
         assertEquals(buf.toString(), "-WXYZ");
     }
 
-    @Test(expectedExceptions=DateTimePrintException.class)
+    @Test(expectedExceptions=DateTimeException.class)
     public void test_print_overPad() throws Exception {
         builder.padNext(3, '-').appendLiteral("WXYZ");
-        getFormatter().printTo(EMPTY_DTA, buf);
+        getFormatter().formatTo(EMPTY_DTA, buf);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/test/java/time/format/TestReducedParser.java b/jdk/test/java/time/test/java/time/format/TestReducedParser.java
index bcd3830..c1a41bb 100644
--- a/jdk/test/java/time/test/java/time/format/TestReducedParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestReducedParser.java
@@ -59,15 +59,14 @@
  */
 package test.java.time.format;
 
-import java.time.format.*;
-
 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
 import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
 import java.text.ParsePosition;
-import java.time.format.DateTimeBuilder;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 
 import org.testng.annotations.DataProvider;
@@ -95,7 +94,7 @@
     @Test(dataProvider="error")
     public void test_parse_error(TemporalField field, int width, int baseValue, String text, int pos, Class<?> expected) {
         try {
-            getFormatter0(field, width, baseValue).parseToBuilder(text, new ParsePosition(pos));
+            getFormatter0(field, width, baseValue).parseUnresolved(text, new ParsePosition(pos));
         } catch (RuntimeException ex) {
             assertTrue(expected.isInstance(ex));
         }
@@ -104,9 +103,9 @@
     //-----------------------------------------------------------------------
     public void test_parse_fieldRangeIgnored() throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter0(DAY_OF_YEAR, 3, 10).parseToBuilder("456", pos);
+        TemporalAccessor parsed = getFormatter0(DAY_OF_YEAR, 3, 10).parseUnresolved("456", pos);
         assertEquals(pos.getIndex(), 3);
-        assertParsed(dtb, DAY_OF_YEAR, 456L);  // parsed dayOfYear=456
+        assertParsed(parsed, DAY_OF_YEAR, 456L);  // parsed dayOfYear=456
     }
 
     //-----------------------------------------------------------------------
@@ -165,12 +164,12 @@
     @Test(dataProvider="Parse")
     public void test_parse(TemporalField field, int width, int baseValue, String input, int pos, int parseLen, Integer parseVal) {
         ParsePosition ppos = new ParsePosition(pos);
-        DateTimeBuilder dtb = getFormatter0(field, width, baseValue).parseToBuilder(input, ppos);
+        TemporalAccessor parsed = getFormatter0(field, width, baseValue).parseUnresolved(input, ppos);
         if (ppos.getErrorIndex() != -1) {
             assertEquals(ppos.getErrorIndex(), parseLen);
         } else {
             assertEquals(ppos.getIndex(), parseLen);
-            assertParsed(dtb, YEAR, parseVal != null ? (long) parseVal : null);
+            assertParsed(parsed, YEAR, parseVal != null ? (long) parseVal : null);
         }
     }
 
@@ -178,20 +177,21 @@
     public void test_parseLenient(TemporalField field, int width, int baseValue, String input, int pos, int parseLen, Integer parseVal) {
         setStrict(false);
         ParsePosition ppos = new ParsePosition(pos);
-        DateTimeBuilder dtb = getFormatter0(field, width, baseValue).parseToBuilder(input, ppos);
+        TemporalAccessor parsed = getFormatter0(field, width, baseValue).parseUnresolved(input, ppos);
         if (ppos.getErrorIndex() != -1) {
             assertEquals(ppos.getErrorIndex(), parseLen);
         } else {
             assertEquals(ppos.getIndex(), parseLen);
-            assertParsed(dtb, YEAR, parseVal != null ? (long) parseVal : null);
+            assertParsed(parsed, YEAR, parseVal != null ? (long) parseVal : null);
         }
     }
 
-    private void assertParsed(DateTimeBuilder dtb, TemporalField field, Long value) {
+    private void assertParsed(TemporalAccessor parsed, TemporalField field, Long value) {
         if (value == null) {
-            assertEquals(dtb, null);
+            assertEquals(parsed, null);
         } else {
-            assertEquals(dtb.getLong(field), (long)value);
+            assertEquals(parsed.isSupported(field), true);
+            assertEquals(parsed.getLong(field), (long) value);
         }
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java b/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java
index 698496d..7606069 100644
--- a/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java
+++ b/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java
@@ -86,13 +86,13 @@
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=DateTimeException.class)
     public void test_print_emptyCalendrical() throws Exception {
-        getFormatter0(YEAR, 2, 2010).printTo(EMPTY_DTA, buf);
+        getFormatter0(YEAR, 2, 2010).formatTo(EMPTY_DTA, buf);
     }
 
     //-----------------------------------------------------------------------
     public void test_print_append() throws Exception {
         buf.append("EXISTING");
-        getFormatter0(YEAR, 2, 2010).printTo(LocalDate.of(2012, 1, 1), buf);
+        getFormatter0(YEAR, 2, 2010).formatTo(LocalDate.of(2012, 1, 1), buf);
         assertEquals(buf.toString(), "EXISTING12");
     }
 
@@ -159,12 +159,12 @@
     @Test(dataProvider="Pivot")
     public void test_pivot(int width, int baseValue, int value, String result) throws Exception {
         try {
-            getFormatter0(YEAR, width, baseValue).printTo(new MockFieldValue(YEAR, value), buf);
+            getFormatter0(YEAR, width, baseValue).formatTo(new MockFieldValue(YEAR, value), buf);
             if (result == null) {
                 fail("Expected exception");
             }
             assertEquals(buf.toString(), result);
-        } catch (DateTimePrintException ex) {
+        } catch (DateTimeException ex) {
             if (result == null || value < 0) {
                 assertEquals(ex.getMessage().contains(YEAR.getName()), true);
             } else {
diff --git a/jdk/test/java/time/test/java/time/format/TestSettingsParser.java b/jdk/test/java/time/test/java/time/format/TestSettingsParser.java
index 4b639aa..ed3b0a5 100644
--- a/jdk/test/java/time/test/java/time/format/TestSettingsParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestSettingsParser.java
@@ -59,12 +59,9 @@
  */
 package test.java.time.format;
 
-import java.time.format.*;
-
 import static org.testng.Assert.assertEquals;
 
 import java.text.ParsePosition;
-import java.time.ZoneOffset;
 
 import org.testng.annotations.Test;
 
@@ -77,20 +74,20 @@
     //-----------------------------------------------------------------------
     public void test_print_sensitive() throws Exception {
         setCaseSensitive(true);
-        getFormatter().printTo(dta, buf);
+        getFormatter().formatTo(dta, buf);
         assertEquals(buf.toString(), "");
     }
 
     public void test_print_strict() throws Exception {
         setStrict(true);
-        getFormatter().printTo(dta, buf);
+        getFormatter().formatTo(dta, buf);
         assertEquals(buf.toString(), "");
     }
 
     /*
     public void test_print_nulls() throws Exception {
         setCaseSensitive(true);
-        getFormatter().printTo(null, null);
+        getFormatter().formatTo(null, null);
     }
     */
 
@@ -98,28 +95,28 @@
     public void test_parse_changeStyle_sensitive() throws Exception {
         setCaseSensitive(true);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter().parseToBuilder("a", pos);
+        getFormatter().parseUnresolved("a", pos);
         assertEquals(pos.getIndex(), 0);
     }
 
     public void test_parse_changeStyle_insensitive() throws Exception {
         setCaseSensitive(false);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter().parseToBuilder("a", pos);
+        getFormatter().parseUnresolved("a", pos);
         assertEquals(pos.getIndex(), 0);
     }
 
     public void test_parse_changeStyle_strict() throws Exception {
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter().parseToBuilder("a", pos);
+        getFormatter().parseUnresolved("a", pos);
         assertEquals(pos.getIndex(), 0);
     }
 
     public void test_parse_changeStyle_lenient() throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter().parseToBuilder("a", pos);
+        getFormatter().parseUnresolved("a", pos);
         assertEquals(pos.getIndex(), 0);
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestStringLiteralParser.java b/jdk/test/java/time/test/java/time/format/TestStringLiteralParser.java
index bd67eab..a209652 100644
--- a/jdk/test/java/time/test/java/time/format/TestStringLiteralParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestStringLiteralParser.java
@@ -59,11 +59,14 @@
  */
 package test.java.time.format;
 
+import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
-import java.time.format.DateTimeBuilder;
 import java.text.ParsePosition;
+import java.time.temporal.Queries;
+import java.time.temporal.TemporalAccessor;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -105,13 +108,14 @@
     public void test_parse_success(String s, boolean caseSensitive, String text, int pos, int expectedPos) {
         setCaseSensitive(caseSensitive);
         ParsePosition ppos = new ParsePosition(pos);
-        DateTimeBuilder result =
-               getFormatter(s).parseToBuilder(text, ppos);
+        TemporalAccessor parsed = getFormatter(s).parseUnresolved(text, ppos);
         if (ppos.getErrorIndex() != -1) {
             assertEquals(ppos.getIndex(), expectedPos);
         } else {
             assertEquals(ppos.getIndex(), expectedPos);
-            assertEquals(result.getCalendricalList().size(), 0);
+            assertEquals(parsed.isSupported(YEAR), false);
+            assertEquals(parsed.query(Queries.chronology()), null);
+            assertEquals(parsed.query(Queries.zoneId()), null);
         }
     }
 
@@ -127,9 +131,9 @@
     @Test(dataProvider="error")
     public void test_parse_error(String s, String text, int pos, Class<?> expected) {
         try {
-            DateTimeBuilder result =
-               getFormatter(s).parseToBuilder(text, new ParsePosition(pos));
-            assertTrue(false);
+            ParsePosition ppos = new ParsePosition(pos);
+            getFormatter(s).parseUnresolved(text, ppos);
+            fail();
         } catch (RuntimeException ex) {
             assertTrue(expected.isInstance(ex));
         }
diff --git a/jdk/test/java/time/test/java/time/format/TestStringLiteralPrinter.java b/jdk/test/java/time/test/java/time/format/TestStringLiteralPrinter.java
index df01870..62d6a4e 100644
--- a/jdk/test/java/time/test/java/time/format/TestStringLiteralPrinter.java
+++ b/jdk/test/java/time/test/java/time/format/TestStringLiteralPrinter.java
@@ -74,13 +74,13 @@
     //-----------------------------------------------------------------------
     public void test_print_emptyCalendrical() throws Exception {
         buf.append("EXISTING");
-        getFormatter("hello").printTo(EMPTY_DTA, buf);
+        getFormatter("hello").formatTo(EMPTY_DTA, buf);
         assertEquals(buf.toString(), "EXISTINGhello");
     }
 
     public void test_print_dateTime() throws Exception {
         buf.append("EXISTING");
-        getFormatter("hello").printTo(dta, buf);
+        getFormatter("hello").formatTo(dta, buf);
         assertEquals(buf.toString(), "EXISTINGhello");
     }
 
@@ -88,7 +88,7 @@
 
 
     public void test_print_emptyAppendable() throws Exception {
-        getFormatter("hello").printTo(dta, buf);
+        getFormatter("hello").formatTo(dta, buf);
         assertEquals(buf.toString(), "hello");
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestTextParser.java b/jdk/test/java/time/test/java/time/format/TestTextParser.java
index 7961b27..9e9c3f7 100644
--- a/jdk/test/java/time/test/java/time/format/TestTextParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestTextParser.java
@@ -59,8 +59,6 @@
  */
 package test.java.time.format;
 
-import java.time.format.*;
-
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
@@ -68,9 +66,10 @@
 import static org.testng.Assert.assertTrue;
 
 import java.text.ParsePosition;
-import java.util.Locale;
-import java.time.format.DateTimeBuilder;
+import java.time.format.TextStyle;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
+import java.util.Locale;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -93,7 +92,7 @@
     @Test(dataProvider="error")
     public void test_parse_error(TemporalField field, TextStyle style, String text, int pos, Class<?> expected) {
         try {
-            getFormatter(field, style).parseToBuilder(text, new ParsePosition(pos));
+            getFormatter(field, style).parseUnresolved(text, new ParsePosition(pos));
         } catch (RuntimeException ex) {
             assertTrue(expected.isInstance(ex));
         }
@@ -103,7 +102,7 @@
     public void test_parse_midStr() throws Exception {
         ParsePosition pos = new ParsePosition(3);
         assertEquals(getFormatter(DAY_OF_WEEK, TextStyle.FULL)
-                     .parseToBuilder("XxxMondayXxx", pos)
+                     .parseUnresolved("XxxMondayXxx", pos)
                      .getLong(DAY_OF_WEEK), 1L);
         assertEquals(pos.getIndex(), 9);
     }
@@ -111,7 +110,7 @@
     public void test_parse_remainderIgnored() throws Exception {
         ParsePosition pos = new ParsePosition(0);
         assertEquals(getFormatter(DAY_OF_WEEK, TextStyle.SHORT)
-                     .parseToBuilder("Wednesday", pos)
+                     .parseUnresolved("Wednesday", pos)
                      .getLong(DAY_OF_WEEK), 3L);
         assertEquals(pos.getIndex(), 3);
     }
@@ -119,23 +118,26 @@
     //-----------------------------------------------------------------------
     public void test_parse_noMatch1() throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb =
-            getFormatter(DAY_OF_WEEK, TextStyle.FULL).parseToBuilder("Munday", pos);
+        TemporalAccessor parsed =
+            getFormatter(DAY_OF_WEEK, TextStyle.FULL).parseUnresolved("Munday", pos);
         assertEquals(pos.getErrorIndex(), 0);
+        assertEquals(parsed, null);
     }
 
     public void test_parse_noMatch2() throws Exception {
         ParsePosition pos = new ParsePosition(3);
-        DateTimeBuilder dtb =
-            getFormatter(DAY_OF_WEEK, TextStyle.FULL).parseToBuilder("Monday", pos);
+        TemporalAccessor parsed =
+            getFormatter(DAY_OF_WEEK, TextStyle.FULL).parseUnresolved("Monday", pos);
         assertEquals(pos.getErrorIndex(), 3);
+        assertEquals(parsed, null);
     }
 
     public void test_parse_noMatch_atEnd() throws Exception {
         ParsePosition pos = new ParsePosition(6);
-        DateTimeBuilder dtb =
-            getFormatter(DAY_OF_WEEK, TextStyle.FULL).parseToBuilder("Monday", pos);
+        TemporalAccessor parsed =
+            getFormatter(DAY_OF_WEEK, TextStyle.FULL).parseUnresolved("Monday", pos);
         assertEquals(pos.getErrorIndex(), 6);
+        assertEquals(parsed, null);
     }
 
     //-----------------------------------------------------------------------
@@ -184,14 +186,14 @@
     @Test(dataProvider="parseText")
     public void test_parseText(TemporalField field, TextStyle style, int value, String input) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(field, style).parseToBuilder(input, pos).getLong(field), (long) value);
+        assertEquals(getFormatter(field, style).parseUnresolved(input, pos).getLong(field), (long) value);
         assertEquals(pos.getIndex(), input.length());
     }
 
     @Test(dataProvider="parseNumber")
     public void test_parseNumber(TemporalField field, TextStyle style, int value, String input) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(field, style).parseToBuilder(input, pos).getLong(field), (long) value);
+        assertEquals(getFormatter(field, style).parseUnresolved(input, pos).getLong(field), (long) value);
         assertEquals(pos.getIndex(), input.length());
     }
 
@@ -200,7 +202,7 @@
     public void test_parse_strict_caseSensitive_parseUpper(TemporalField field, TextStyle style, int value, String input) throws Exception {
         setCaseSensitive(true);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter(field, style).parseToBuilder(input.toUpperCase(), pos);
+        getFormatter(field, style).parseUnresolved(input.toUpperCase(), pos);
         assertEquals(pos.getErrorIndex(), 0);
     }
 
@@ -208,7 +210,7 @@
     public void test_parse_strict_caseInsensitive_parseUpper(TemporalField field, TextStyle style, int value, String input) throws Exception {
         setCaseSensitive(false);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(field, style).parseToBuilder(input.toUpperCase(), pos).getLong(field), (long) value);
+        assertEquals(getFormatter(field, style).parseUnresolved(input.toUpperCase(), pos).getLong(field), (long) value);
         assertEquals(pos.getIndex(), input.length());
     }
 
@@ -217,7 +219,7 @@
     public void test_parse_strict_caseSensitive_parseLower(TemporalField field, TextStyle style, int value, String input) throws Exception {
         setCaseSensitive(true);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter(field, style).parseToBuilder(input.toLowerCase(), pos);
+        getFormatter(field, style).parseUnresolved(input.toLowerCase(), pos);
         assertEquals(pos.getErrorIndex(), 0);
     }
 
@@ -225,7 +227,7 @@
     public void test_parse_strict_caseInsensitive_parseLower(TemporalField field, TextStyle style, int value, String input) throws Exception {
         setCaseSensitive(false);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(field, style).parseToBuilder(input.toLowerCase(), pos).getLong(field), (long) value);
+        assertEquals(getFormatter(field, style).parseUnresolved(input.toLowerCase(), pos).getLong(field), (long) value);
         assertEquals(pos.getIndex(), input.length());
     }
 
@@ -235,21 +237,21 @@
     public void test_parse_full_strict_full_match() throws Exception {
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseToBuilder("January", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseUnresolved("January", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 7);
     }
 
     public void test_parse_full_strict_short_noMatch() throws Exception {
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseToBuilder("Janua", pos);
+        getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseUnresolved("Janua", pos);
         assertEquals(pos.getErrorIndex(), 0);
     }
 
     public void test_parse_full_strict_number_noMatch() throws Exception {
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseToBuilder("1", pos);
+        getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseUnresolved("1", pos);
         assertEquals(pos.getErrorIndex(), 0);
     }
 
@@ -257,21 +259,21 @@
     public void test_parse_short_strict_full_match() throws Exception {
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseToBuilder("January", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseUnresolved("January", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 3);
     }
 
     public void test_parse_short_strict_short_match() throws Exception {
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseToBuilder("Janua", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseUnresolved("Janua", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 3);
     }
 
     public void test_parse_short_strict_number_noMatch() throws Exception {
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
-        getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseToBuilder("1", pos);
+        getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseUnresolved("1", pos);
         assertEquals(pos.getErrorIndex(), 0);
     }
 
@@ -280,7 +282,7 @@
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
         getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
-                                                    .parseToBuilder("janvier", pos);
+                                                    .parseUnresolved("janvier", pos);
         assertEquals(pos.getErrorIndex(), 0);
     }
 
@@ -288,7 +290,7 @@
         setStrict(true);
         ParsePosition pos = new ParsePosition(0);
         assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
-                                                                 .parseToBuilder("janv.", pos)
+                                                                 .parseUnresolved("janv.", pos)
                                                                  .getLong(MONTH_OF_YEAR),
                      1L);
         assertEquals(pos.getIndex(), 5);
@@ -298,21 +300,21 @@
     public void test_parse_full_lenient_full_match() throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseToBuilder("January.", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseUnresolved("January.", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 7);
     }
 
     public void test_parse_full_lenient_short_match() throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseToBuilder("Janua", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseUnresolved("Janua", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 3);
     }
 
     public void test_parse_full_lenient_number_match() throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseToBuilder("1", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).parseUnresolved("1", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 1);
     }
 
@@ -320,21 +322,21 @@
     public void test_parse_short_lenient_full_match() throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseToBuilder("January", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseUnresolved("January", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 7);
     }
 
     public void test_parse_short_lenient_short_match() throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseToBuilder("Janua", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseUnresolved("Janua", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 3);
     }
 
     public void test_parse_short_lenient_number_match() throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseToBuilder("1", pos).getLong(MONTH_OF_YEAR), 1L);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).parseUnresolved("1", pos).getLong(MONTH_OF_YEAR), 1L);
         assertEquals(pos.getIndex(), 1);
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestTextPrinter.java b/jdk/test/java/time/test/java/time/format/TestTextPrinter.java
index cc93f46..43f2df3 100644
--- a/jdk/test/java/time/test/java/time/format/TestTextPrinter.java
+++ b/jdk/test/java/time/test/java/time/format/TestTextPrinter.java
@@ -64,6 +64,7 @@
 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.ERA;
 import static org.testng.Assert.assertEquals;
 
 import java.util.Locale;
@@ -71,6 +72,7 @@
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.temporal.TemporalField;
+import java.time.chrono.JapaneseChronology;
 import test.java.time.temporal.MockFieldValue;
 
 import org.testng.annotations.DataProvider;
@@ -85,12 +87,12 @@
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=DateTimeException.class)
     public void test_print_emptyCalendrical() throws Exception {
-        getFormatter(DAY_OF_WEEK, TextStyle.FULL).printTo(EMPTY_DTA, buf);
+        getFormatter(DAY_OF_WEEK, TextStyle.FULL).formatTo(EMPTY_DTA, buf);
     }
 
     public void test_print_append() throws Exception {
         buf.append("EXISTING");
-        getFormatter(DAY_OF_WEEK, TextStyle.FULL).printTo(LocalDate.of(2012, 4, 18), buf);
+        getFormatter(DAY_OF_WEEK, TextStyle.FULL).formatTo(LocalDate.of(2012, 4, 18), buf);
         assertEquals(buf.toString(), "EXISTINGWednesday");
     }
 
@@ -163,23 +165,46 @@
             {MONTH_OF_YEAR, TextStyle.SHORT, 10, "Oct"},
             {MONTH_OF_YEAR, TextStyle.SHORT, 11, "Nov"},
             {MONTH_OF_YEAR, TextStyle.SHORT, 12, "Dec"},
+
+            {ERA,           TextStyle.FULL, 0, "Before Christ"},
+            {ERA,           TextStyle.FULL, 1, "Anno Domini"},
+            {ERA,           TextStyle.SHORT, 0, "BC"},
+            {ERA,           TextStyle.SHORT, 1, "AD"},
+            {ERA,           TextStyle.NARROW, 0, "B"},
+            {ERA,           TextStyle.NARROW, 1, "A"},
        };
     }
 
+    @DataProvider(name="print_JapaneseChronology")
+    Object[][] provider_japaneseEra() {
+       return new Object[][] {
+            {ERA,           TextStyle.FULL, 2, "Heisei"}, // Note: CLDR doesn't define "wide" Japanese era names.
+            {ERA,           TextStyle.SHORT, 2, "Heisei"},
+            {ERA,           TextStyle.NARROW, 2, "H"},
+       };
+    };
+
     @Test(dataProvider="print")
-    public void test_print(TemporalField field, TextStyle style, int value, String expected) throws Exception {
-        getFormatter(field, style).printTo(new MockFieldValue(field, value), buf);
+    public void test_format(TemporalField field, TextStyle style, int value, String expected) throws Exception {
+        getFormatter(field, style).formatTo(new MockFieldValue(field, value), buf);
+        assertEquals(buf.toString(), expected);
+    }
+
+    @Test(dataProvider="print_JapaneseChronology")
+    public void test_formatJapaneseEra(TemporalField field, TextStyle style, int value, String expected) throws Exception {
+        LocalDate ld = LocalDate.of(2013, 1, 31);
+        getFormatter(field, style).withChronology(JapaneseChronology.INSTANCE).formatTo(ld, buf);
         assertEquals(buf.toString(), expected);
     }
 
     //-----------------------------------------------------------------------
     public void test_print_french_long() throws Exception {
-        getFormatter(MONTH_OF_YEAR, TextStyle.FULL).withLocale(Locale.FRENCH).printTo(LocalDate.of(2012, 1, 1), buf);
+        getFormatter(MONTH_OF_YEAR, TextStyle.FULL).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
         assertEquals(buf.toString(), "janvier");
     }
 
     public void test_print_french_short() throws Exception {
-        getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH).printTo(LocalDate.of(2012, 1, 1), buf);
+        getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
         assertEquals(buf.toString(), "janv.");
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestZoneIdParser.java b/jdk/test/java/time/test/java/time/format/TestZoneIdParser.java
deleted file mode 100644
index 99ee93b..0000000
--- a/jdk/test/java/time/test/java/time/format/TestZoneIdParser.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package test.java.time.format;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Set;
-
-import java.text.ParsePosition;
-import java.time.ZoneId;
-import java.time.format.DateTimeBuilder;
-import java.time.format.DateTimeFormatter;
-import java.time.format.TextStyle;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.temporal.Queries;
-import java.time.zone.ZoneRulesProvider;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * Test ZonePrinterParser.
- */
-@Test(groups={"implementation"})
-public class TestZoneIdParser extends AbstractTestPrinterParser {
-
-    private static final String AMERICA_DENVER = "America/Denver";
-    private static final ZoneId TIME_ZONE_DENVER = ZoneId.of(AMERICA_DENVER);
-
-    private DateTimeFormatter getFormatter0(TextStyle style) {
-        if (style == null)
-            return builder.appendZoneId().toFormatter(locale).withSymbols(symbols);
-        return builder.appendZoneText(style).toFormatter(locale).withSymbols(symbols);
-    }
-
-    //-----------------------------------------------------------------------
-    @DataProvider(name="error")
-    Object[][] data_error() {
-        return new Object[][] {
-            {null, "hello", -1, IndexOutOfBoundsException.class},
-            {null, "hello", 6, IndexOutOfBoundsException.class},
-        };
-    }
-
-    @Test(dataProvider="error")
-    public void test_parse_error(TextStyle style, String text, int pos, Class<?> expected) {
-        try {
-            getFormatter0(style).parseToBuilder(text, new ParsePosition(pos));
-            assertTrue(false);
-        } catch (RuntimeException ex) {
-            assertTrue(expected.isInstance(ex));
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_parse_exactMatch_Denver() throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder(AMERICA_DENVER, pos);
-        assertEquals(pos.getIndex(), AMERICA_DENVER.length());
-        assertParsed(dtb, TIME_ZONE_DENVER);
-    }
-
-    public void test_parse_startStringMatch_Denver() throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder(AMERICA_DENVER + "OTHER", pos);
-        assertEquals(pos.getIndex(), AMERICA_DENVER.length());
-        assertParsed(dtb, TIME_ZONE_DENVER);
-    }
-
-    public void test_parse_midStringMatch_Denver() throws Exception {
-        ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder("OTHER" + AMERICA_DENVER + "OTHER", pos);
-        assertEquals(pos.getIndex(), 5 + AMERICA_DENVER.length());
-        assertParsed(dtb, TIME_ZONE_DENVER);
-    }
-
-    public void test_parse_endStringMatch_Denver() throws Exception {
-        ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder("OTHER" + AMERICA_DENVER, pos);
-        assertEquals(pos.getIndex(), 5 + AMERICA_DENVER.length());
-        assertParsed(dtb, TIME_ZONE_DENVER);
-    }
-
-    public void test_parse_partialMatch() throws Exception {
-        ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder("OTHERAmerica/Bogusville", pos);
-        assertEquals(pos.getErrorIndex(), 5);  // TBD: -6 ?
-        assertEquals(dtb, null);
-    }
-
-    //-----------------------------------------------------------------------
-    @DataProvider(name="zones")
-    Object[][] populateTestData() {
-        Set<String> ids = ZoneRulesProvider.getAvailableZoneIds();
-        Object[][] rtnval = new Object[ids.size()][];
-        int i = 0;
-        for (String id : ids) {
-            rtnval[i++] = new Object[] { id, ZoneId.of(id) };
-        }
-        return rtnval;
-    }
-
-    @Test(dataProvider="zones")
-    public void test_parse_exactMatch(String parse, ZoneId expected) throws Exception {
-        ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder(parse, pos);
-        assertEquals(pos.getIndex(), parse.length());
-        assertParsed(dtb, expected);
-    }
-
-    @Test(dataProvider="zones")
-    public void test_parse_startMatch(String parse, ZoneId expected) throws Exception {
-        String append = " OTHER";
-        parse += append;
-        ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder(parse, pos);
-        assertEquals(pos.getIndex(), parse.length() - append.length());
-        assertParsed(dtb, expected);
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_parse_caseInsensitive() throws Exception {
-        DateTimeFormatter fmt = new DateTimeFormatterBuilder().appendZoneId().toFormatter();
-        DateTimeFormatter fmtCI = new DateTimeFormatterBuilder().parseCaseInsensitive()
-                                                                .appendZoneId()
-                                                                .toFormatter();
-        for (String zidStr : ZoneRulesProvider.getAvailableZoneIds()) {
-            ZoneId zid = ZoneId.of(zidStr);
-            assertEquals(fmt.parse(zidStr, Queries.zoneId()), zid);
-            assertEquals(fmtCI.parse(zidStr.toLowerCase(), Queries.zoneId()), zid);
-            assertEquals(fmtCI.parse(zidStr.toUpperCase(), Queries.zoneId()), zid);
-            ParsePosition pos = new ParsePosition(5);
-            assertEquals(fmtCI.parseToBuilder("OTHER" + zidStr.toLowerCase() + "OTHER", pos)
-                              .query(Queries.zoneId()), zid);
-            assertEquals(pos.getIndex(), zidStr.length() + 5);
-            pos = new ParsePosition(5);
-            assertEquals(fmtCI.parseToBuilder("OTHER" + zidStr.toUpperCase() + "OTHER", pos)
-                              .query(Queries.zoneId()), zid);
-            assertEquals(pos.getIndex(), zidStr.length() + 5);
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /*
-    public void test_parse_endStringMatch_utc() throws Exception {
-        ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder("OTHERUTC", pos);
-        assertEquals(pos.getIndex(), 8);
-        assertParsed(dtb, ZoneOffset.UTC);
-    }
-
-    public void test_parse_endStringMatch_utc_plus1() throws Exception {
-        ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder("OTHERUTC+01:00", pos);
-        assertEquals(pos.getIndex(), 14);
-        assertParsed(dtb, ZoneId.of("UTC+01:00"));
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_parse_midStringMatch_utc() throws Exception {
-        ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder("OTHERUTCOTHER", pos);
-        assertEquals(pos.getIndex(), 8);
-        assertParsed(dtb, ZoneOffset.UTC);
-    }
-
-    public void test_parse_midStringMatch_utc_plus1() throws Exception {
-        ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter0(null).parseToBuilder("OTHERUTC+01:00OTHER", pos);
-        assertEquals(pos.getIndex(), 14);
-        assertParsed(dtb, ZoneId.of("UTC+01:00"));
-    }
-    */
-    //-----------------------------------------------------------------------
-    public void test_toString_id() {
-        assertEquals(getFormatter0(null).toString(), "ZoneId()");
-    }
-
-    public void test_toString_text() {
-        assertEquals(getFormatter0(TextStyle.FULL).toString(), "ZoneText(FULL)");
-    }
-
-    private void assertParsed(DateTimeBuilder dtb, ZoneId expectedZone) {
-        assertEquals(dtb.query(ZoneId::from), expectedZone);
-    }
-
-}
diff --git a/jdk/test/java/time/test/java/time/format/TestZoneOffsetParser.java b/jdk/test/java/time/test/java/time/format/TestZoneOffsetParser.java
index 300411c..2c9065b 100644
--- a/jdk/test/java/time/test/java/time/format/TestZoneOffsetParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestZoneOffsetParser.java
@@ -65,7 +65,7 @@
 
 import java.text.ParsePosition;
 import java.time.ZoneOffset;
-import java.time.format.DateTimeBuilder;
+import java.time.temporal.TemporalAccessor;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -88,7 +88,7 @@
     @Test(dataProvider="error")
     public void test_parse_error(String pattern, String noOffsetText, String text, int pos, Class<?> expected) {
         try {
-            getFormatter(pattern, noOffsetText).parseToBuilder(text, new ParsePosition(pos));
+            getFormatter(pattern, noOffsetText).parseUnresolved(text, new ParsePosition(pos));
         } catch (RuntimeException ex) {
             assertTrue(expected.isInstance(ex));
         }
@@ -97,59 +97,59 @@
     //-----------------------------------------------------------------------
     public void test_parse_exactMatch_UTC() throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("Z", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("Z", pos);
         assertEquals(pos.getIndex(), 1);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     public void test_parse_startStringMatch_UTC() throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("ZOTHER", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("ZOTHER", pos);
         assertEquals(pos.getIndex(), 1);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     public void test_parse_midStringMatch_UTC() throws Exception {
         ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("OTHERZOTHER", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("OTHERZOTHER", pos);
         assertEquals(pos.getIndex(), 6);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     public void test_parse_endStringMatch_UTC() throws Exception {
         ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("OTHERZ", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("OTHERZ", pos);
         assertEquals(pos.getIndex(), 6);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     //-----------------------------------------------------------------------
     public void test_parse_exactMatch_UTC_EmptyUTC() throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "").parseToBuilder("", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "").parseUnresolved("", pos);
         assertEquals(pos.getIndex(), 0);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     public void test_parse_startStringMatch_UTC_EmptyUTC() throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "").parseToBuilder("OTHER", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "").parseUnresolved("OTHER", pos);
         assertEquals(pos.getIndex(), 0);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     public void test_parse_midStringMatch_UTC_EmptyUTC() throws Exception {
         ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "").parseToBuilder("OTHEROTHER", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "").parseUnresolved("OTHEROTHER", pos);
         assertEquals(pos.getIndex(), 5);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     public void test_parse_endStringMatch_UTC_EmptyUTC() throws Exception {
         ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "").parseToBuilder("OTHER", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "").parseUnresolved("OTHER", pos);
         assertEquals(pos.getIndex(), 5);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     //-----------------------------------------------------------------------
@@ -231,65 +231,65 @@
     @Test(dataProvider="offsets")
     public void test_parse_exactMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder(parse, pos);
+        TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved(parse, pos);
         assertEquals(pos.getIndex(), parse.length());
-        assertParsed(dtb, expected);
+        assertParsed(parsed, expected);
     }
 
     @Test(dataProvider="offsets")
     public void test_parse_startStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder(parse + ":OTHER", pos);
+        TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved(parse + ":OTHER", pos);
         assertEquals(pos.getIndex(), parse.length());
-        assertParsed(dtb, expected);
+        assertParsed(parsed, expected);
     }
 
     @Test(dataProvider="offsets")
     public void test_parse_midStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
         ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder("OTHER" + parse + ":OTHER", pos);
+        TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved("OTHER" + parse + ":OTHER", pos);
         assertEquals(pos.getIndex(), parse.length() + 5);
-        assertParsed(dtb, expected);
+        assertParsed(parsed, expected);
     }
 
     @Test(dataProvider="offsets")
     public void test_parse_endStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
         ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder("OTHER" + parse, pos);
+        TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved("OTHER" + parse, pos);
         assertEquals(pos.getIndex(), parse.length() + 5);
-        assertParsed(dtb, expected);
+        assertParsed(parsed, expected);
     }
 
     @Test(dataProvider="offsets")
     public void test_parse_exactMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder(parse, pos);
+        TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved(parse, pos);
         assertEquals(pos.getIndex(), parse.length());
-        assertParsed(dtb, expected);
+        assertParsed(parsed, expected);
     }
 
     @Test(dataProvider="offsets")
     public void test_parse_startStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder(parse + ":OTHER", pos);
+        TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved(parse + ":OTHER", pos);
         assertEquals(pos.getIndex(), parse.length());
-        assertParsed(dtb, expected);
+        assertParsed(parsed, expected);
     }
 
     @Test(dataProvider="offsets")
     public void test_parse_midStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
         ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder("OTHER" + parse + ":OTHER", pos);
+        TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved("OTHER" + parse + ":OTHER", pos);
         assertEquals(pos.getIndex(), parse.length() + 5);
-        assertParsed(dtb, expected);
+        assertParsed(parsed, expected);
     }
 
     @Test(dataProvider="offsets")
     public void test_parse_endStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
         ParsePosition pos = new ParsePosition(5);
-        DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder("OTHER" + parse, pos);
+        TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved("OTHER" + parse, pos);
         assertEquals(pos.getIndex(), parse.length() + 5);
-        assertParsed(dtb, expected);
+        assertParsed(parsed, expected);
     }
 
     //-----------------------------------------------------------------------
@@ -322,9 +322,9 @@
     @Test(dataProvider="bigOffsets")
     public void test_parse_bigOffsets(String pattern, String parse, long offsetSecs) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder(parse, pos);
+        TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved(parse, pos);
         assertEquals(pos.getIndex(), parse.length());
-        assertEquals(dtb.getLong(OFFSET_SECONDS), offsetSecs);
+        assertEquals(parsed.getLong(OFFSET_SECONDS), offsetSecs);
     }
 
     //-----------------------------------------------------------------------
@@ -393,8 +393,9 @@
     @Test(dataProvider="badOffsets")
     public void test_parse_invalid(String pattern, String parse, int expectedPosition) throws Exception {
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder(parse, pos);
+        TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved(parse, pos);
         assertEquals(pos.getErrorIndex(), expectedPosition);
+        assertEquals(parsed, null);
     }
 
     //-----------------------------------------------------------------------
@@ -403,41 +404,41 @@
     public void test_parse_caseSensitiveUTC_matchedCase() throws Exception {
         setCaseSensitive(true);
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("Z", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("Z", pos);
         assertEquals(pos.getIndex(), 1);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     public void test_parse_caseSensitiveUTC_unmatchedCase() throws Exception {
         setCaseSensitive(true);
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("z", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("z", pos);
         assertEquals(pos.getErrorIndex(), 0);
-        assertEquals(dtb, null);
+        assertEquals(parsed, null);
     }
 
     public void test_parse_caseInsensitiveUTC_matchedCase() throws Exception {
         setCaseSensitive(false);
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("Z", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("Z", pos);
         assertEquals(pos.getIndex(), 1);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
     public void test_parse_caseInsensitiveUTC_unmatchedCase() throws Exception {
         setCaseSensitive(false);
         ParsePosition pos = new ParsePosition(0);
-        DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("z", pos);
+        TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("z", pos);
         assertEquals(pos.getIndex(), 1);
-        assertParsed(dtb, ZoneOffset.UTC);
+        assertParsed(parsed, ZoneOffset.UTC);
     }
 
-    private void assertParsed(DateTimeBuilder dtb, ZoneOffset expectedOffset) {
+    private void assertParsed(TemporalAccessor parsed, ZoneOffset expectedOffset) {
         if (expectedOffset == null) {
-            assertEquals(dtb, null);
+            assertEquals(parsed, null);
         } else {
-            assertEquals(dtb.getFieldValueMap().size(), 1);
-            assertEquals(dtb.getLong(OFFSET_SECONDS), (long) expectedOffset.getTotalSeconds());
+            assertEquals(parsed.isSupported(OFFSET_SECONDS), true);
+            assertEquals(parsed.getLong(OFFSET_SECONDS), (long) expectedOffset.getTotalSeconds());
         }
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestZoneOffsetPrinter.java b/jdk/test/java/time/test/java/time/format/TestZoneOffsetPrinter.java
index e425090..c84ad05 100644
--- a/jdk/test/java/time/test/java/time/format/TestZoneOffsetPrinter.java
+++ b/jdk/test/java/time/test/java/time/format/TestZoneOffsetPrinter.java
@@ -59,12 +59,10 @@
  */
 package test.java.time.format;
 
-import static java.time.temporal.ChronoField.OFFSET_SECONDS;
 import static org.testng.Assert.assertEquals;
 
 import java.time.DateTimeException;
 import java.time.ZoneOffset;
-import java.time.format.DateTimeBuilder;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -150,25 +148,25 @@
     }
 
     @Test(dataProvider="offsets")
-    public void test_print(String pattern, String expected, ZoneOffset offset) throws Exception {
+    public void test_format(String pattern, String expected, ZoneOffset offset) throws Exception {
         buf.append("EXISTING");
-        getFormatter(pattern, "NO-OFFSET").printTo(new DateTimeBuilder(OFFSET_SECONDS, offset.getTotalSeconds()), buf);
+        getFormatter(pattern, "NO-OFFSET").formatTo(offset, buf);
         assertEquals(buf.toString(), "EXISTING" + expected);
     }
 
     @Test(dataProvider="offsets")
     public void test_toString(String pattern, String expected, ZoneOffset offset) throws Exception {
-        assertEquals(getFormatter(pattern, "NO-OFFSET").toString(), "Offset('NO-OFFSET'," + pattern + ")");
+        assertEquals(getFormatter(pattern, "NO-OFFSET").toString(), "Offset(" + pattern + ",'NO-OFFSET')");
     }
 
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=DateTimeException.class)
     public void test_print_emptyCalendrical() throws Exception {
-        getFormatter("+HH:MM:ss", "Z").printTo(EMPTY_DTA, buf);
+        getFormatter("+HH:MM:ss", "Z").formatTo(EMPTY_DTA, buf);
     }
 
     public void test_print_emptyAppendable() throws Exception {
-        getFormatter("+HH:MM:ss", "Z").printTo(new DateTimeBuilder(OFFSET_SECONDS, OFFSET_0130.getTotalSeconds()), buf);
+        getFormatter("+HH:MM:ss", "Z").formatTo(OFFSET_0130, buf);
         assertEquals(buf.toString(), "+01:30");
     }
 
diff --git a/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java b/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
index 0f58634..a7d63e8 100644
--- a/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
+++ b/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
@@ -23,7 +23,10 @@
 
 package test.java.time.format;
 
+import java.text.DateFormatSymbols;
+import java.util.Arrays;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Random;
 import java.util.Set;
@@ -32,12 +35,14 @@
 import java.time.ZonedDateTime;
 import java.time.ZoneId;
 import java.time.temporal.ChronoField;
+import java.time.temporal.Queries;
 import java.time.format.DateTimeFormatSymbols;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.TextStyle;
 import java.time.zone.ZoneRulesProvider;
 
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 import static org.testng.Assert.assertEquals;
 
@@ -65,6 +70,12 @@
             zdt = zdt.withDayOfYear(r.nextInt(365) + 1)
                      .with(ChronoField.SECOND_OF_DAY, r.nextInt(86400));
             for (String zid : zids) {
+                if (zid.equals("ROC") ||
+                    zid.startsWith("UTC") ||
+                    zid.startsWith("GMT") || zid.startsWith("Etc/GMT")) {
+                    // UTC, GMT are treated as zone offset
+                    continue;      // TBD: match jdk behavior?
+                }
                 zdt = zdt.withZoneSameLocal(ZoneId.of(zid));
                 TimeZone tz = TimeZone.getTimeZone(zid);
                 boolean isDST = tz.inDaylightTime(new Date(zdt.toInstant().toEpochMilli()));
@@ -79,10 +90,9 @@
     }
 
     private void printText(Locale locale, ZonedDateTime zdt, TextStyle style, String expected) {
-        String result = getFormatter(locale, style).print(zdt);
+        String result = getFormatter(locale, style).format(zdt);
         if (!result.equals(expected)) {
-            if (result.equals("FooLocation") || // from rules provider test if same vm
-                result.startsWith("Etc/GMT") || result.equals("ROC")) {  // TBD: match jdk behavior?
+            if (result.equals("FooLocation")) { // from rules provider test if same vm
                 return;
             }
             System.out.println("----------------");
@@ -92,4 +102,117 @@
         }
         assertEquals(result, expected);
     }
+
+    public void test_ParseText() {
+        Locale[] locales = new Locale[] { Locale.ENGLISH, Locale.JAPANESE, Locale.FRENCH };
+        Set<String> zids = ZoneRulesProvider.getAvailableZoneIds();
+        for (Locale locale : locales) {
+            parseText(zids, locale, TextStyle.FULL, false);
+            parseText(zids, locale, TextStyle.FULL, true);
+            parseText(zids, locale, TextStyle.SHORT, false);
+            parseText(zids, locale, TextStyle.SHORT, true);
+        }
+    }
+
+    private static Set<ZoneId> preferred = new HashSet<>(Arrays.asList(new ZoneId[] {
+        ZoneId.of("EST"),
+        ZoneId.of("Asia/Taipei"),
+        ZoneId.of("CET"),
+    }));
+
+    private static Set<ZoneId> preferred_s = new HashSet<>(Arrays.asList(new ZoneId[] {
+         ZoneId.of("EST"),
+         ZoneId.of("CET"),
+         ZoneId.of("Australia/South"),
+         ZoneId.of("Australia/West"),
+         ZoneId.of("Asia/Shanghai"),
+    }));
+
+    private static Set<ZoneId> none = new HashSet<>();
+
+    @DataProvider(name="preferredZones")
+    Object[][] data_preferredZones() {
+        return new Object[][] {
+            {"America/New_York", "Eastern Standard Time", none,      Locale.ENGLISH, TextStyle.FULL},
+            {"EST",              "Eastern Standard Time", preferred, Locale.ENGLISH, TextStyle.FULL},
+            {"Europe/Paris",     "Central European Time", none,      Locale.ENGLISH, TextStyle.FULL},
+            {"CET",              "Central European Time", preferred, Locale.ENGLISH, TextStyle.FULL},
+            {"Asia/Shanghai",    "China Standard Time",   none,      Locale.ENGLISH, TextStyle.FULL},
+            {"Asia/Taipei",      "China Standard Time",   preferred, Locale.ENGLISH, TextStyle.FULL},
+            {"America/Chicago",  "CST",                   none,      Locale.ENGLISH, TextStyle.SHORT},
+            {"Asia/Taipei",      "CST",                   preferred, Locale.ENGLISH, TextStyle.SHORT},
+            {"Australia/South",  "CST",                   preferred_s, Locale.ENGLISH, TextStyle.SHORT},
+            {"America/Chicago",  "CDT",                   none,        Locale.ENGLISH, TextStyle.SHORT},
+            {"Asia/Shanghai",    "CDT",                   preferred_s, Locale.ENGLISH, TextStyle.SHORT},
+       };
+    }
+
+    @Test(dataProvider="preferredZones")
+    public void test_ParseText(String expected, String text, Set<ZoneId> preferred, Locale locale, TextStyle style) {
+        DateTimeFormatter fmt = new DateTimeFormatterBuilder().appendZoneText(style, preferred)
+                                                              .toFormatter(locale)
+                                                              .withSymbols(DateTimeFormatSymbols.of(locale));
+
+        String ret = fmt.parse(text, Queries.zone()).getId();
+
+        System.out.printf("[%-5s %s] %24s -> %s(%s)%n",
+                          locale.toString(),
+                          style == TextStyle.FULL ? " full" :"short",
+                          text, ret, expected);
+
+        assertEquals(ret, expected);
+
+    }
+
+
+    private void parseText(Set<String> zids, Locale locale, TextStyle style, boolean ci) {
+        System.out.println("---------------------------------------");
+        DateTimeFormatter fmt = getFormatter(locale, style, ci);
+        for (String[] names : new DateFormatSymbols(locale).getZoneStrings()) {
+            if (!zids.contains(names[0])) {
+                continue;
+            }
+            String zid = names[0];
+            String expected = ZoneName.toZid(zid, locale);
+
+            parse(fmt, zid, expected, zid, locale, style, ci);
+            int i = style == TextStyle.FULL ? 1 : 2;
+            for (; i < names.length; i += 2) {
+                parse(fmt, zid, expected, names[i], locale, style, ci);
+            }
+        }
+    }
+
+    private void parse(DateTimeFormatter fmt,
+                       String zid, String expected, String text,
+                       Locale locale, TextStyle style, boolean ci) {
+        if (ci) {
+            text = text.toUpperCase();
+        }
+        String ret = fmt.parse(text, Queries.zone()).getId();
+        // TBD: need an excluding list
+        // assertEquals(...);
+        if (ret.equals(expected) ||
+            ret.equals(zid) ||
+            ret.equals(ZoneName.toZid(zid)) ||
+            ret.equals(expected.replace("UTC", "UCT"))) {
+            return;
+        }
+        System.out.printf("[%-5s %s %s %16s] %24s -> %s(%s)%n",
+                          locale.toString(),
+                          ci ? "ci" : "  ",
+                          style == TextStyle.FULL ? " full" :"short",
+                          zid, text, ret, expected);
+    }
+
+    private DateTimeFormatter getFormatter(Locale locale, TextStyle style, boolean ci) {
+        DateTimeFormatterBuilder db = new DateTimeFormatterBuilder();
+        if (ci) {
+            db = db.parseCaseInsensitive();
+        }
+        return db.appendZoneText(style)
+                 .toFormatter(locale)
+                 .withSymbols(DateTimeFormatSymbols.of(locale));
+    }
+
 }
diff --git a/jdk/test/java/time/test/java/time/format/ZoneName.java b/jdk/test/java/time/test/java/time/format/ZoneName.java
new file mode 100644
index 0000000..4ae5b43
--- /dev/null
+++ b/jdk/test/java/time/test/java/time/format/ZoneName.java
@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.time.format;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+class ZoneName {
+
+    public static String toZid(String zid, Locale locale) {
+        String mzone = zidToMzone.get(zid);
+        if (mzone == null && aliases.containsKey(zid)) {
+            zid = aliases.get(zid);
+            mzone = zidToMzone.get(zid);
+        }
+        if (mzone != null) {
+            Map<String, String> map = mzoneToZidL.get(mzone);
+            if (map != null && map.containsKey(locale.getCountry())) {
+                zid = map.get(locale.getCountry());
+            } else {
+                zid = mzoneToZid.get(mzone);
+            }
+        }
+        return toZid(zid);
+    }
+
+    public static String toZid(String zid) {
+        if (aliases.containsKey(zid)) {
+            return aliases.get(zid);
+        }
+        return zid;
+    }
+
+    private static final String[] zidMap = new String[] {
+        "Asia/Bangkok", "Indochina", "Asia/Saigon",
+        "Pacific/Pago_Pago", "Samoa", "Pacific/Apia",
+        "Africa/Blantyre", "Africa_Central", "Africa/Maputo",
+        "America/Argentina/San_Juan", "Argentina", "America/Buenos_Aires",
+        "America/Cancun", "America_Central", "America/Chicago",
+        "Pacific/Nauru", "Nauru", "Pacific/Nauru",
+        "America/Atikokan", "America_Eastern", "America/New_York",
+        "Africa/Asmara", "Africa_Eastern", "Africa/Nairobi",
+        "Europe/Berlin", "Europe_Central", "Europe/Paris",
+        "Asia/Kolkata", "India", "Asia/Calcutta",
+        "Australia/Darwin", "Australia_Central", "Australia/Adelaide",
+        "America/Guayaquil", "Ecuador", "America/Guayaquil",
+        "Europe/Vienna", "Europe_Central", "Europe/Paris",
+        "Atlantic/St_Helena", "GMT", "Atlantic/Reykjavik",
+        "Europe/London", "GMT", "Atlantic/Reykjavik",
+        "Europe/Moscow", "Moscow", "Europe/Moscow",
+        "America/St_Vincent", "Atlantic", "America/Halifax",
+        "America/Bogota", "Colombia", "America/Bogota",
+        "America/Marigot", "Atlantic", "America/Halifax",
+        "Europe/Sarajevo", "Europe_Central", "Europe/Paris",
+        "America/Hermosillo", "America_Mountain", "America/Denver",
+        "America/Winnipeg", "America_Central", "America/Chicago",
+        "America/Rainy_River", "America_Central", "America/Chicago",
+        "Indian/Mahe", "Seychelles", "Indian/Mahe",
+        "Africa/Freetown", "GMT", "Atlantic/Reykjavik",
+        "America/Grand_Turk", "America_Eastern", "America/New_York",
+        "America/Argentina/Ushuaia", "Argentina", "America/Buenos_Aires",
+        "Atlantic/Azores", "Azores", "Atlantic/Azores",
+        "Asia/Harbin", "China", "Asia/Shanghai",
+        "America/Cuiaba", "Amazon", "America/Manaus",
+        "Asia/Bahrain", "Arabian", "Asia/Riyadh",
+        "Asia/Katmandu", "Nepal", "Asia/Katmandu",
+        "Pacific/Galapagos", "Galapagos", "Pacific/Galapagos",
+        "Asia/Brunei", "Brunei", "Asia/Brunei",
+        "Africa/Kigali", "Africa_Central", "Africa/Maputo",
+        "Asia/Makassar", "Indonesia_Central", "Asia/Makassar",
+        "Africa/Maputo", "Africa_Central", "Africa/Maputo",
+        "Asia/Kamchatka", "Magadan", "Asia/Magadan",
+        "Atlantic/Faroe", "Europe_Western", "Atlantic/Canary",
+        "America/El_Salvador", "America_Central", "America/Chicago",
+        "Asia/Saigon", "Indochina", "Asia/Saigon",
+        "Africa/Kinshasa", "Africa_Western", "Africa/Lagos",
+        "Europe/Oslo", "Europe_Central", "Europe/Paris",
+        "Asia/Hong_Kong", "Hong_Kong", "Asia/Hong_Kong",
+        "Pacific/Midway", "Samoa", "Pacific/Apia",
+        "Africa/Douala", "Africa_Western", "Africa/Lagos",
+        "Europe/San_Marino", "Europe_Central", "Europe/Paris",
+        "Pacific/Chuuk", "Truk", "Pacific/Truk",
+        "Africa/Gaborone", "Africa_Central", "Africa/Maputo",
+        "Africa/Tunis", "Europe_Central", "Europe/Paris",
+        "Africa/Khartoum", "Africa_Eastern", "Africa/Nairobi",
+        "Europe/Isle_of_Man", "GMT", "Atlantic/Reykjavik",
+        "Europe/Skopje", "Europe_Central", "Europe/Paris",
+        "America/Merida", "America_Central", "America/Chicago",
+        "Antarctica/DumontDUrville", "DumontDUrville", "Antarctica/DumontDUrville",
+        "Atlantic/Reykjavik", "GMT", "Atlantic/Reykjavik",
+        "Indian/Mauritius", "Mauritius", "Indian/Mauritius",
+        "Africa/Malabo", "Africa_Western", "Africa/Lagos",
+        "Africa/Juba", "Africa_Eastern", "Africa/Nairobi",
+        "America/Resolute", "America_Central", "America/Chicago",
+        "Africa/Abidjan", "GMT", "Atlantic/Reykjavik",
+        "Antarctica/McMurdo", "New_Zealand", "Pacific/Auckland",
+        "Asia/Thimphu", "Bhutan", "Asia/Thimphu",
+        "Europe/Zaporozhye", "Europe_Eastern", "Europe/Bucharest",
+        "Antarctica/Davis", "Davis", "Antarctica/Davis",
+        "Indian/Antananarivo", "Africa_Eastern", "Africa/Nairobi",
+        "Africa/Harare", "Africa_Central", "Africa/Maputo",
+        "Pacific/Marquesas", "Marquesas", "Pacific/Marquesas",
+        "Africa/Tripoli", "Europe_Eastern", "Europe/Bucharest",
+        "America/North_Dakota/Beulah", "America_Central", "America/Chicago",
+        "America/Buenos_Aires", "Argentina", "America/Buenos_Aires",
+        "America/Tortola", "Atlantic", "America/Halifax",
+        "Asia/Kuwait", "Arabian", "Asia/Riyadh",
+        "Europe/Rome", "Europe_Central", "Europe/Paris",
+        "America/Eirunepe", "Amazon", "America/Manaus",
+        "Australia/Hobart", "Australia_Eastern", "Australia/Sydney",
+        "America/Thule", "Atlantic", "America/Halifax",
+        "Asia/Beirut", "Europe_Eastern", "Europe/Bucharest",
+        "America/Bahia_Banderas", "America_Central", "America/Chicago",
+        "Africa/Dar_es_Salaam", "Africa_Eastern", "Africa/Nairobi",
+        "America/Argentina/Tucuman", "Argentina", "America/Buenos_Aires",
+        "America/Paramaribo", "Suriname", "America/Paramaribo",
+        "Africa/Kampala", "Africa_Eastern", "Africa/Nairobi",
+        "Pacific/Port_Moresby", "Papua_New_Guinea", "Pacific/Port_Moresby",
+        "America/Mendoza", "Argentina", "America/Buenos_Aires",
+        "Asia/Dushanbe", "Tajikistan", "Asia/Dushanbe",
+        "Asia/Qyzylorda", "Kazakhstan_Eastern", "Asia/Almaty",
+        "Antarctica/Vostok", "Vostok", "Antarctica/Vostok",
+        "Pacific/Majuro", "Marshall_Islands", "Pacific/Majuro",
+        "Asia/Tehran", "Iran", "Asia/Tehran",
+        "Asia/Hovd", "Hovd", "Asia/Hovd",
+        "Antarctica/Rothera", "Rothera", "Antarctica/Rothera",
+        "Africa/Brazzaville", "Africa_Western", "Africa/Lagos",
+        "Europe/Tirane", "Europe_Central", "Europe/Paris",
+        "Asia/Urumqi", "China", "Asia/Shanghai",
+        "Asia/Krasnoyarsk", "Krasnoyarsk", "Asia/Krasnoyarsk",
+        "America/Tegucigalpa", "America_Central", "America/Chicago",
+        "Asia/Vientiane", "Indochina", "Asia/Saigon",
+        "Asia/Pontianak", "Indonesia_Western", "Asia/Jakarta",
+        "America/Bahia", "Brasilia", "America/Sao_Paulo",
+        "Asia/Choibalsan", "Choibalsan", "Asia/Choibalsan",
+        "America/Regina", "America_Central", "America/Chicago",
+        "Africa/Cairo", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Irkutsk", "Irkutsk", "Asia/Irkutsk",
+        "Europe/Luxembourg", "Europe_Central", "Europe/Paris",
+        "America/St_Kitts", "Atlantic", "America/Halifax",
+        "America/Manaus", "Amazon", "America/Manaus",
+        "America/Noronha", "Noronha", "America/Noronha",
+        "Pacific/Gambier", "Gambier", "Pacific/Gambier",
+        "America/Edmonton", "America_Mountain", "America/Denver",
+        "Pacific/Palau", "Palau", "Pacific/Palau",
+        "America/Lower_Princes", "Atlantic", "America/Halifax",
+        "Africa/Ouagadougou", "GMT", "Atlantic/Reykjavik",
+        "Asia/Yerevan", "Armenia", "Asia/Yerevan",
+        "America/Montevideo", "Uruguay", "America/Montevideo",
+        "Europe/Minsk", "Europe_Eastern", "Europe/Bucharest",
+        "Europe/Amsterdam", "Europe_Central", "Europe/Paris",
+        "Pacific/Efate", "Vanuatu", "Pacific/Efate",
+        "Asia/Manila", "Philippines", "Asia/Manila",
+        "America/Dawson", "America_Pacific", "America/Los_Angeles",
+        "America/Argentina/Cordoba", "Argentina", "America/Buenos_Aires",
+        "Australia/Melbourne", "Australia_Eastern", "Australia/Sydney",
+        "Asia/Rangoon", "Myanmar", "Asia/Rangoon",
+        "America/Los_Angeles", "America_Pacific", "America/Los_Angeles",
+        "Africa/Casablanca", "Europe_Western", "Atlantic/Canary",
+        "Africa/Porto-Novo", "Africa_Western", "Africa/Lagos",
+        "Asia/Macau", "China", "Asia/Shanghai",
+        "America/Boa_Vista", "Amazon", "America/Manaus",
+        "Europe/Guernsey", "GMT", "Atlantic/Reykjavik",
+        "Africa/Monrovia", "GMT", "Atlantic/Reykjavik",
+        "America/Godthab", "Greenland_Western", "America/Godthab",
+        "Africa/Ceuta", "Europe_Central", "Europe/Paris",
+        "Asia/Oral", "Kazakhstan_Western", "Asia/Aqtobe",
+        "America/Yakutat", "Alaska", "America/Juneau",
+        "Indian/Mayotte", "Africa_Eastern", "Africa/Nairobi",
+        "America/Denver", "America_Mountain", "America/Denver",
+        "America/New_York", "America_Eastern", "America/New_York",
+        "Pacific/Rarotonga", "Cook", "Pacific/Rarotonga",
+        "America/Louisville", "America_Eastern", "America/New_York",
+        "Africa/El_Aaiun", "Europe_Western", "Atlantic/Canary",
+        "Africa/Sao_Tome", "GMT", "Atlantic/Reykjavik",
+        "Pacific/Fiji", "Fiji", "Pacific/Fiji",
+        "Asia/Damascus", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Ulaanbaatar", "Mongolia", "Asia/Ulaanbaatar",
+        "America/Cayman", "America_Eastern", "America/New_York",
+        "America/Tijuana", "America_Pacific", "America/Los_Angeles",
+        "Atlantic/Bermuda", "Atlantic", "America/Halifax",
+        "Australia/Sydney", "Australia_Eastern", "Australia/Sydney",
+        "Asia/Aden", "Arabian", "Asia/Riyadh",
+        "Australia/Eucla", "Australia_CentralWestern", "Australia/Eucla",
+        "America/Indiana/Petersburg", "America_Eastern", "America/New_York",
+        "America/Panama", "America_Eastern", "America/New_York",
+        "Europe/Istanbul", "Europe_Eastern", "Europe/Bucharest",
+        "America/Kralendijk", "Atlantic", "America/Halifax",
+        "America/Catamarca", "Argentina", "America/Buenos_Aires",
+        "America/Nassau", "America_Eastern", "America/New_York",
+        "Europe/Paris", "Europe_Central", "Europe/Paris",
+        "Asia/Jakarta", "Indonesia_Western", "Asia/Jakarta",
+        "Australia/Lindeman", "Australia_Eastern", "Australia/Sydney",
+        "America/Sao_Paulo", "Brasilia", "America/Sao_Paulo",
+        "America/Juneau", "Alaska", "America/Juneau",
+        "America/Grenada", "Atlantic", "America/Halifax",
+        "America/Cayenne", "French_Guiana", "America/Cayenne",
+        "Antarctica/Casey", "Australia_Western", "Australia/Perth",
+        "Africa/Algiers", "Europe_Central", "Europe/Paris",
+        "America/Miquelon", "Pierre_Miquelon", "America/Miquelon",
+        "Asia/Tokyo", "Japan", "Asia/Tokyo",
+        "Africa/Windhoek", "Africa_Western", "Africa/Lagos",
+        "Africa/Bujumbura", "Africa_Central", "Africa/Maputo",
+        "America/Guatemala", "America_Central", "America/Chicago",
+        "Africa/Dakar", "GMT", "Atlantic/Reykjavik",
+        "Asia/Bishkek", "Kyrgystan", "Asia/Bishkek",
+        "America/Guadeloupe", "Atlantic", "America/Halifax",
+        "Africa/Ndjamena", "Africa_Western", "Africa/Lagos",
+        "Europe/Simferopol", "Europe_Eastern", "Europe/Bucharest",
+        "America/Santa_Isabel", "America_Pacific", "America/Los_Angeles",
+        "Asia/Dubai", "Gulf", "Asia/Dubai",
+        "America/Maceio", "Brasilia", "America/Sao_Paulo",
+        "America/Anchorage", "Alaska", "America/Juneau",
+        "Australia/Currie", "Australia_Eastern", "Australia/Sydney",
+        "Africa/Djibouti", "Africa_Eastern", "Africa/Nairobi",
+        "Europe/Budapest", "Europe_Central", "Europe/Paris",
+        "America/Argentina/Salta", "Argentina", "America/Buenos_Aires",
+        "Asia/Calcutta", "India", "Asia/Calcutta",
+        "America/Indiana/Winamac", "America_Eastern", "America/New_York",
+        "Asia/Yekaterinburg", "Yekaterinburg", "Asia/Yekaterinburg",
+        "America/Santiago", "Chile", "America/Santiago",
+        "Asia/Aqtobe", "Kazakhstan_Western", "Asia/Aqtobe",
+        "Asia/Dili", "East_Timor", "Asia/Dili",
+        "America/Detroit", "America_Eastern", "America/New_York",
+        "Africa/Libreville", "Africa_Western", "Africa/Lagos",
+        "Pacific/Ponape", "Ponape", "Pacific/Ponape",
+        "Pacific/Wallis", "Wallis", "Pacific/Wallis",
+        "Asia/Vladivostok", "Vladivostok", "Asia/Vladivostok",
+        "Africa/Lubumbashi", "Africa_Central", "Africa/Maputo",
+        "Africa/Asmera", "Africa_Eastern", "Africa/Nairobi",
+        "Pacific/Guam", "Chamorro", "Pacific/Saipan",
+        "America/Chicago", "America_Central", "America/Chicago",
+        "America/Swift_Current", "America_Central", "America/Chicago",
+        "America/Coral_Harbour", "America_Eastern", "America/New_York",
+        "America/Cambridge_Bay", "America_Mountain", "America/Denver",
+        "America/Costa_Rica", "America_Central", "America/Chicago",
+        "America/Curacao", "Atlantic", "America/Halifax",
+        "America/Recife", "Brasilia", "America/Sao_Paulo",
+        "Africa/Bangui", "Africa_Western", "Africa/Lagos",
+        "America/Cordoba", "Argentina", "America/Buenos_Aires",
+        "Asia/Baghdad", "Arabian", "Asia/Riyadh",
+        "America/Shiprock", "America_Mountain", "America/Denver",
+        "America/Glace_Bay", "Atlantic", "America/Halifax",
+        "America/North_Dakota/Center", "America_Central", "America/Chicago",
+        "Europe/Stockholm", "Europe_Central", "Europe/Paris",
+        "America/Halifax", "Atlantic", "America/Halifax",
+        "Atlantic/Canary", "Europe_Western", "Atlantic/Canary",
+        "Europe/Volgograd", "Volgograd", "Europe/Volgograd",
+        "America/Moncton", "Atlantic", "America/Halifax",
+        "Pacific/Tongatapu", "Tonga", "Pacific/Tongatapu",
+        "America/Argentina/Buenos_Aires", "Argentina", "America/Buenos_Aires",
+        "Asia/Samarkand", "Uzbekistan", "Asia/Tashkent",
+        "Pacific/Apia", "Samoa", "Pacific/Apia",
+        "America/Sitka", "Alaska", "America/Juneau",
+        "Europe/Warsaw", "Europe_Central", "Europe/Paris",
+        "Africa/Accra", "GMT", "Atlantic/Reykjavik",
+        "Europe/Bratislava", "Europe_Central", "Europe/Paris",
+        "Europe/Zurich", "Europe_Central", "Europe/Paris",
+        "Indian/Reunion", "Reunion", "Indian/Reunion",
+        "America/Mazatlan", "America_Mountain", "America/Denver",
+        "Pacific/Tarawa", "Gilbert_Islands", "Pacific/Tarawa",
+        "America/Indiana/Knox", "America_Central", "America/Chicago",
+        "Asia/Tbilisi", "Georgia", "Asia/Tbilisi",
+        "Asia/Novosibirsk", "Novosibirsk", "Asia/Novosibirsk",
+        "Atlantic/Faeroe", "Europe_Western", "Atlantic/Canary",
+        "Africa/Bissau", "GMT", "Atlantic/Reykjavik",
+        "Asia/Amman", "Europe_Eastern", "Europe/Bucharest",
+        "Africa/Lagos", "Africa_Western", "Africa/Lagos",
+        "Africa/Banjul", "GMT", "Atlantic/Reykjavik",
+        "America/Araguaina", "Brasilia", "America/Sao_Paulo",
+        "America/Nipigon", "America_Eastern", "America/New_York",
+        "Europe/Vilnius", "Europe_Eastern", "Europe/Bucharest",
+        "America/Montserrat", "Atlantic", "America/Halifax",
+        "Asia/Baku", "Azerbaijan", "Asia/Baku",
+        "Africa/Lusaka", "Africa_Central", "Africa/Maputo",
+        "Europe/Uzhgorod", "Europe_Eastern", "Europe/Bucharest",
+        "America/Argentina/Rio_Gallegos", "Argentina", "America/Buenos_Aires",
+        "America/Blanc-Sablon", "Atlantic", "America/Halifax",
+        "Asia/Kabul", "Afghanistan", "Asia/Kabul",
+        "America/Jamaica", "America_Eastern", "America/New_York",
+        "Europe/Vatican", "Europe_Central", "Europe/Paris",
+        "Africa/Nouakchott", "GMT", "Atlantic/Reykjavik",
+        "Africa/Addis_Ababa", "Africa_Eastern", "Africa/Nairobi",
+        "Europe/Athens", "Europe_Eastern", "Europe/Bucharest",
+        "Atlantic/Madeira", "Europe_Western", "Atlantic/Canary",
+        "America/Thunder_Bay", "America_Eastern", "America/New_York",
+        "Europe/Brussels", "Europe_Central", "Europe/Paris",
+        "Africa/Luanda", "Africa_Western", "Africa/Lagos",
+        "Africa/Mogadishu", "Africa_Eastern", "Africa/Nairobi",
+        "America/Matamoros", "America_Central", "America/Chicago",
+        "Pacific/Norfolk", "Norfolk", "Pacific/Norfolk",
+        "America/Scoresbysund", "Greenland_Eastern", "America/Scoresbysund",
+        "America/Indianapolis", "America_Eastern", "America/New_York",
+        "Pacific/Pitcairn", "Pitcairn", "Pacific/Pitcairn",
+        "Asia/Singapore", "Singapore", "Asia/Singapore",
+        "America/Port-au-Prince", "America_Eastern", "America/New_York",
+        "Pacific/Honolulu", "Hawaii_Aleutian", "Pacific/Honolulu",
+        "Antarctica/Syowa", "Syowa", "Antarctica/Syowa",
+        "Atlantic/Cape_Verde", "Cape_Verde", "Atlantic/Cape_Verde",
+        "America/Asuncion", "Paraguay", "America/Asuncion",
+        "America/Martinique", "Atlantic", "America/Halifax",
+        "Europe/Gibraltar", "Europe_Central", "Europe/Paris",
+        "Africa/Lome", "GMT", "Atlantic/Reykjavik",
+        "Australia/Lord_Howe", "Lord_Howe", "Australia/Lord_Howe",
+        "America/Argentina/La_Rioja", "Argentina", "America/Buenos_Aires",
+        "Europe/Jersey", "GMT", "Atlantic/Reykjavik",
+        "America/Kentucky/Louisville", "America_Eastern", "America/New_York",
+        "America/Monterrey", "America_Central", "America/Chicago",
+        "Europe/Belgrade", "Europe_Central", "Europe/Paris",
+        "Asia/Gaza", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Ho_Chi_Minh", "Indochina", "Asia/Saigon",
+        "Europe/Prague", "Europe_Central", "Europe/Paris",
+        "Indian/Christmas", "Christmas", "Indian/Christmas",
+        "Pacific/Fakaofo", "Tokelau", "Pacific/Fakaofo",
+        "America/Dominica", "Atlantic", "America/Halifax",
+        "America/Ojinaga", "America_Mountain", "America/Denver",
+        "Asia/Colombo", "India", "Asia/Calcutta",
+        "Asia/Nicosia", "Europe_Eastern", "Europe/Bucharest",
+        "Europe/Copenhagen", "Europe_Central", "Europe/Paris",
+        "America/Creston", "America_Mountain", "America/Denver",
+        "Asia/Ashgabat", "Turkmenistan", "Asia/Ashgabat",
+        "Asia/Shanghai", "China", "Asia/Shanghai",
+        "Pacific/Easter", "Easter", "Pacific/Easter",
+        "Africa/Maseru", "Africa_Southern", "Africa/Johannesburg",
+        "America/La_Paz", "Bolivia", "America/La_Paz",
+        "Pacific/Truk", "Truk", "Pacific/Truk",
+        "America/Inuvik", "America_Mountain", "America/Denver",
+        "America/Belem", "Brasilia", "America/Sao_Paulo",
+        "Asia/Hebron", "Europe_Eastern", "Europe/Bucharest",
+        "Asia/Jerusalem", "Israel", "Asia/Jerusalem",
+        "America/Belize", "America_Central", "America/Chicago",
+        "America/Rio_Branco", "Amazon", "America/Manaus",
+        "America/Dawson_Creek", "America_Mountain", "America/Denver",
+        "America/Anguilla", "Atlantic", "America/Halifax",
+        "America/Port_of_Spain", "Atlantic", "America/Halifax",
+        "America/St_Barthelemy", "Atlantic", "America/Halifax",
+        "America/Indiana/Marengo", "America_Eastern", "America/New_York",
+        "America/St_Johns", "Newfoundland", "America/St_Johns",
+        "Asia/Jayapura", "Indonesia_Eastern", "Asia/Jayapura",
+        "Europe/Riga", "Europe_Eastern", "Europe/Bucharest",
+        "America/Phoenix", "America_Mountain", "America/Denver",
+        "America/Boise", "America_Mountain", "America/Denver",
+        "Pacific/Kiritimati", "Line_Islands", "Pacific/Kiritimati",
+        "Africa/Johannesburg", "Africa_Southern", "Africa/Johannesburg",
+        "America/Pangnirtung", "America_Eastern", "America/New_York",
+        "America/Toronto", "America_Eastern", "America/New_York",
+        "Australia/Brisbane", "Australia_Eastern", "Australia/Sydney",
+        "Asia/Aqtau", "Kazakhstan_Western", "Asia/Aqtobe",
+        "America/Vancouver", "America_Pacific", "America/Los_Angeles",
+        "Africa/Mbabane", "Africa_Southern", "Africa/Johannesburg",
+        "Europe/Vaduz", "Europe_Central", "Europe/Paris",
+        "Asia/Karachi", "Pakistan", "Asia/Karachi",
+        "Asia/Riyadh", "Arabian", "Asia/Riyadh",
+        "Indian/Maldives", "Maldives", "Indian/Maldives",
+        "Asia/Anadyr", "Magadan", "Asia/Magadan",
+        "Europe/Helsinki", "Europe_Eastern", "Europe/Bucharest",
+        "America/Nome", "Alaska", "America/Juneau",
+        "Asia/Yakutsk", "Yakutsk", "Asia/Yakutsk",
+        "Africa/Conakry", "GMT", "Atlantic/Reykjavik",
+        "Asia/Seoul", "Korea", "Asia/Seoul",
+        "America/Antigua", "Atlantic", "America/Halifax",
+        "Asia/Almaty", "Kazakhstan_Eastern", "Asia/Almaty",
+        "America/Fortaleza", "Brasilia", "America/Sao_Paulo",
+        "Pacific/Tahiti", "Tahiti", "Pacific/Tahiti",
+        "Asia/Kashgar", "China", "Asia/Shanghai",
+        "America/Whitehorse", "America_Pacific", "America/Los_Angeles",
+        "Europe/Kaliningrad", "Europe_Eastern", "Europe/Bucharest",
+        "Pacific/Enderbury", "Phoenix_Islands", "Pacific/Enderbury",
+        "America/St_Lucia", "Atlantic", "America/Halifax",
+        "Atlantic/Stanley", "Falkland", "Atlantic/Stanley",
+        "Asia/Omsk", "Omsk", "Asia/Omsk",
+        "America/Menominee", "America_Central", "America/Chicago",
+        "Asia/Novokuznetsk", "Novosibirsk", "Asia/Novosibirsk",
+        "Asia/Sakhalin", "Sakhalin", "Asia/Sakhalin",
+        "Asia/Muscat", "Gulf", "Asia/Dubai",
+        "Pacific/Noumea", "New_Caledonia", "Pacific/Noumea",
+        "Asia/Phnom_Penh", "Indochina", "Asia/Saigon",
+        "Antarctica/Mawson", "Mawson", "Antarctica/Mawson",
+        "Indian/Cocos", "Cocos", "Indian/Cocos",
+        "Europe/Tallinn", "Europe_Eastern", "Europe/Bucharest",
+        "Africa/Nairobi", "Africa_Eastern", "Africa/Nairobi",
+        "Europe/Ljubljana", "Europe_Central", "Europe/Paris",
+        "America/Montreal", "America_Eastern", "America/New_York",
+        "Asia/Kuala_Lumpur", "Malaysia", "Asia/Kuching",
+        "Asia/Magadan", "Magadan", "Asia/Magadan",
+        "Africa/Bamako", "GMT", "Atlantic/Reykjavik",
+        "Australia/Broken_Hill", "Australia_Central", "Australia/Adelaide",
+        "America/Indiana/Indianapolis", "America_Eastern", "America/New_York",
+        "Asia/Taipei", "Taipei", "Asia/Taipei",
+        "Europe/Samara", "Moscow", "Europe/Moscow",
+        "America/Indiana/Vevay", "America_Eastern", "America/New_York",
+        "Atlantic/South_Georgia", "South_Georgia", "Atlantic/South_Georgia",
+        "Pacific/Wake", "Wake", "Pacific/Wake",
+        "Asia/Tashkent", "Uzbekistan", "Asia/Tashkent",
+        "America/St_Thomas", "Atlantic", "America/Halifax",
+        "America/Argentina/San_Luis", "Argentina_Western", "America/Argentina/San_Luis",
+        "Arctic/Longyearbyen", "Europe_Central", "Europe/Paris",
+        "Asia/Chongqing", "China", "Asia/Shanghai",
+        "Europe/Monaco", "Europe_Central", "Europe/Paris",
+        "Asia/Qatar", "Arabian", "Asia/Riyadh",
+        "America/Chihuahua", "America_Mountain", "America/Denver",
+        "America/Havana", "Cuba", "America/Havana",
+        "Pacific/Auckland", "New_Zealand", "Pacific/Auckland",
+        "America/Jujuy", "Argentina", "America/Buenos_Aires",
+        "America/Goose_Bay", "Atlantic", "America/Halifax",
+        "Africa/Niamey", "Africa_Western", "Africa/Lagos",
+        "Asia/Kathmandu", "Nepal", "Asia/Katmandu",
+        "America/Caracas", "Venezuela", "America/Caracas",
+        "Indian/Comoro", "Africa_Eastern", "Africa/Nairobi",
+        "America/Argentina/Jujuy", "Argentina", "America/Buenos_Aires",
+        "America/Guyana", "Guyana", "America/Guyana",
+        "America/Indiana/Tell_City", "America_Central", "America/Chicago",
+        "America/Metlakatla", "America_Pacific", "America/Los_Angeles",
+        "Europe/Mariehamn", "Europe_Eastern", "Europe/Bucharest",
+        "Europe/Dublin", "GMT", "Atlantic/Reykjavik",
+        "Europe/Lisbon", "Europe_Western", "Atlantic/Canary",
+        "America/Puerto_Rico", "Atlantic", "America/Halifax",
+        "Asia/Pyongyang", "Korea", "Asia/Seoul",
+        "America/North_Dakota/New_Salem", "America_Central", "America/Chicago",
+        "Asia/Dhaka", "Bangladesh", "Asia/Dhaka",
+        "America/Rankin_Inlet", "America_Central", "America/Chicago",
+        "America/Adak", "Hawaii_Aleutian", "Pacific/Honolulu",
+        "America/Campo_Grande", "Amazon", "America/Manaus",
+        "Europe/Chisinau", "Europe_Eastern", "Europe/Bucharest",
+        "Pacific/Saipan", "Chamorro", "Pacific/Saipan",
+        "Pacific/Niue", "Niue", "Pacific/Niue",
+        "Europe/Madrid", "Europe_Central", "Europe/Paris",
+        "Pacific/Kwajalein", "Marshall_Islands", "Pacific/Majuro",
+        "America/Porto_Velho", "Amazon", "America/Manaus",
+        "Indian/Kerguelen", "French_Southern", "Indian/Kerguelen",
+        "America/Santarem", "Brasilia", "America/Sao_Paulo",
+        "Asia/Kuching", "Malaysia", "Asia/Kuching",
+        "Australia/Adelaide", "Australia_Central", "Australia/Adelaide",
+        "Europe/Bucharest", "Europe_Eastern", "Europe/Bucharest",
+        "Australia/Perth", "Australia_Western", "Australia/Perth",
+        "Europe/Sofia", "Europe_Eastern", "Europe/Bucharest",
+        "Indian/Chagos", "Indian_Ocean", "Indian/Chagos",
+        "America/Yellowknife", "America_Mountain", "America/Denver",
+        "America/Managua", "America_Central", "America/Chicago",
+        "America/Iqaluit", "America_Eastern", "America/New_York",
+        "Pacific/Kosrae", "Kosrae", "Pacific/Kosrae",
+        "Pacific/Guadalcanal", "Solomon", "Pacific/Guadalcanal",
+        "America/Barbados", "Atlantic", "America/Halifax",
+        "America/Aruba", "Atlantic", "America/Halifax",
+        "Europe/Andorra", "Europe_Central", "Europe/Paris",
+        "Pacific/Chatham", "Chatham", "Pacific/Chatham",
+        "America/Santo_Domingo", "Atlantic", "America/Halifax",
+        "America/Indiana/Vincennes", "America_Eastern", "America/New_York",
+        "Europe/Kiev", "Europe_Eastern", "Europe/Bucharest",
+        "Pacific/Funafuti", "Tuvalu", "Pacific/Funafuti",
+        "America/Mexico_City", "America_Central", "America/Chicago",
+        "America/Kentucky/Monticello", "America_Eastern", "America/New_York",
+        "America/Argentina/Catamarca", "Argentina", "America/Buenos_Aires",
+        "Pacific/Johnston", "Hawaii_Aleutian", "Pacific/Honolulu",
+        "Europe/Podgorica", "Europe_Central", "Europe/Paris",
+        "Europe/Zagreb", "Europe_Central", "Europe/Paris",
+        "Pacific/Pohnpei", "Ponape", "Pacific/Ponape",
+        "Antarctica/Palmer", "Chile", "America/Santiago",
+        "America/Argentina/Mendoza", "Argentina", "America/Buenos_Aires",
+        "America/Lima", "Peru", "America/Lima",
+        "Antarctica/Macquarie", "Macquarie", "Antarctica/Macquarie",
+        "Europe/Malta", "Europe_Central", "Europe/Paris",
+        "America/Danmarkshavn", "GMT", "Atlantic/Reykjavik",
+    };
+    private static final String[] mzoneMap = new String[] {
+        "America_Eastern", "TC", "America/Grand_Turk",
+        "America_Eastern", "BS", "America/Nassau",
+        "America_Eastern", "CA", "America/Toronto",
+        "America_Eastern", "KY", "America/Cayman",
+        "America_Eastern", "PA", "America/Panama",
+        "America_Eastern", "JM", "America/Jamaica",
+        "America_Pacific", "CA", "America/Vancouver",
+        "America_Pacific", "MX", "America/Tijuana",
+        "Europe_Western", "FO", "Atlantic/Faeroe",
+        "Arabian", "YE", "Asia/Aden",
+        "Arabian", "BH", "Asia/Bahrain",
+        "Arabian", "KW", "Asia/Kuwait",
+        "Arabian", "QA", "Asia/Qatar",
+        "Arabian", "IQ", "Asia/Baghdad",
+        "Korea", "KP", "Asia/Pyongyang",
+        "Africa_Central", "ZW", "Africa/Harare",
+        "Africa_Central", "ZM", "Africa/Lusaka",
+        "Africa_Central", "MW", "Africa/Blantyre",
+        "Africa_Central", "BW", "Africa/Gaborone",
+        "Africa_Central", "CD", "Africa/Lubumbashi",
+        "Africa_Central", "BI", "Africa/Bujumbura",
+        "Africa_Central", "RW", "Africa/Kigali",
+        "Africa_Western", "CF", "Africa/Bangui",
+        "Africa_Western", "AO", "Africa/Luanda",
+        "Africa_Western", "NE", "Africa/Niamey",
+        "Africa_Western", "CD", "Africa/Kinshasa",
+        "Africa_Western", "CM", "Africa/Douala",
+        "Africa_Western", "CG", "Africa/Brazzaville",
+        "Africa_Western", "GQ", "Africa/Malabo",
+        "Africa_Western", "TD", "Africa/Ndjamena",
+        "Africa_Western", "GA", "Africa/Libreville",
+        "Atlantic", "PR", "America/Puerto_Rico",
+        "Atlantic", "AN", "America/Curacao",
+        "Atlantic", "VI", "America/St_Thomas",
+        "Atlantic", "GP", "America/Guadeloupe",
+        "Atlantic", "TT", "America/Port_of_Spain",
+        "Atlantic", "AG", "America/Antigua",
+        "Atlantic", "MF", "America/Marigot",
+        "Atlantic", "DM", "America/Dominica",
+        "Atlantic", "VG", "America/Tortola",
+        "Atlantic", "MQ", "America/Martinique",
+        "Atlantic", "GL", "America/Thule",
+        "Atlantic", "AI", "America/Anguilla",
+        "Atlantic", "BB", "America/Barbados",
+        "Atlantic", "BM", "Atlantic/Bermuda",
+        "Atlantic", "BQ", "America/Kralendijk",
+        "Atlantic", "LC", "America/St_Lucia",
+        "Atlantic", "MS", "America/Montserrat",
+        "Atlantic", "SX", "America/Lower_Princes",
+        "Atlantic", "GD", "America/Grenada",
+        "Atlantic", "VC", "America/St_Vincent",
+        "Atlantic", "KN", "America/St_Kitts",
+        "Atlantic", "AW", "America/Aruba",
+        "GMT", "GM", "Africa/Banjul",
+        "GMT", "LR", "Africa/Monrovia",
+        "GMT", "ML", "Africa/Bamako",
+        "GMT", "SH", "Atlantic/St_Helena",
+        "GMT", "TG", "Africa/Lome",
+        "GMT", "GB", "Europe/London",
+        "GMT", "MR", "Africa/Nouakchott",
+        "GMT", "GN", "Africa/Conakry",
+        "GMT", "SL", "Africa/Freetown",
+        "GMT", "BF", "Africa/Ouagadougou",
+        "GMT", "ST", "Africa/Sao_Tome",
+        "GMT", "SN", "Africa/Dakar",
+        "GMT", "CI", "Africa/Abidjan",
+        "GMT", "IE", "Europe/Dublin",
+        "GMT", "GH", "Africa/Accra",
+        "Chile", "AQ", "Antarctica/Palmer",
+        "America_Central", "CR", "America/Costa_Rica",
+        "America_Central", "HN", "America/Tegucigalpa",
+        "America_Central", "CA", "America/Winnipeg",
+        "America_Central", "SV", "America/El_Salvador",
+        "America_Central", "MX", "America/Mexico_City",
+        "America_Central", "BZ", "America/Belize",
+        "America_Central", "GT", "America/Guatemala",
+        "America_Mountain", "CA", "America/Edmonton",
+        "America_Mountain", "MX", "America/Hermosillo",
+        "New_Zealand", "AQ", "Antarctica/McMurdo",
+        "India", "LK", "Asia/Colombo",
+        "Gulf", "OM", "Asia/Muscat",
+        "China", "MO", "Asia/Macau",
+        "Africa_Eastern", "ER", "Africa/Asmera",
+        "Africa_Eastern", "TZ", "Africa/Dar_es_Salaam",
+        "Africa_Eastern", "SO", "Africa/Mogadishu",
+        "Africa_Eastern", "DJ", "Africa/Djibouti",
+        "Africa_Eastern", "MG", "Indian/Antananarivo",
+        "Africa_Eastern", "KM", "Indian/Comoro",
+        "Africa_Eastern", "UG", "Africa/Kampala",
+        "Africa_Eastern", "YT", "Indian/Mayotte",
+        "Africa_Eastern", "ET", "Africa/Addis_Ababa",
+        "Chamorro", "GU", "Pacific/Guam",
+        "Africa_Southern", "LS", "Africa/Maseru",
+        "Africa_Southern", "SZ", "Africa/Mbabane",
+        "Indochina", "KH", "Asia/Phnom_Penh",
+        "Indochina", "TH", "Asia/Bangkok",
+        "Indochina", "LA", "Asia/Vientiane",
+        "Europe_Central", "AT", "Europe/Vienna",
+        "Europe_Central", "SK", "Europe/Bratislava",
+        "Europe_Central", "BA", "Europe/Sarajevo",
+        "Europe_Central", "CZ", "Europe/Prague",
+        "Europe_Central", "BE", "Europe/Brussels",
+        "Europe_Central", "RS", "Europe/Belgrade",
+        "Europe_Central", "SE", "Europe/Stockholm",
+        "Europe_Central", "MT", "Europe/Malta",
+        "Europe_Central", "IT", "Europe/Rome",
+        "Europe_Central", "LU", "Europe/Luxembourg",
+        "Europe_Central", "HU", "Europe/Budapest",
+        "Europe_Central", "NO", "Europe/Oslo",
+        "Europe_Central", "ME", "Europe/Podgorica",
+        "Europe_Central", "MK", "Europe/Skopje",
+        "Europe_Central", "NL", "Europe/Amsterdam",
+        "Europe_Central", "LI", "Europe/Vaduz",
+        "Europe_Central", "PL", "Europe/Warsaw",
+        "Europe_Central", "ES", "Europe/Madrid",
+        "Europe_Central", "TN", "Africa/Tunis",
+        "Europe_Central", "SI", "Europe/Ljubljana",
+        "Europe_Central", "DE", "Europe/Berlin",
+        "Europe_Central", "GI", "Europe/Gibraltar",
+        "Europe_Central", "CH", "Europe/Zurich",
+        "Europe_Central", "MC", "Europe/Monaco",
+        "Europe_Central", "VA", "Europe/Vatican",
+        "Europe_Central", "HR", "Europe/Zagreb",
+        "Europe_Central", "AL", "Europe/Tirane",
+        "Europe_Central", "AD", "Europe/Andorra",
+        "Europe_Central", "DK", "Europe/Copenhagen",
+        "Europe_Central", "SM", "Europe/San_Marino",
+        "Europe_Eastern", "SY", "Asia/Damascus",
+        "Europe_Eastern", "FI", "Europe/Helsinki",
+        "Europe_Eastern", "AX", "Europe/Mariehamn",
+        "Europe_Eastern", "BG", "Europe/Sofia",
+        "Europe_Eastern", "EG", "Africa/Cairo",
+        "Europe_Eastern", "LB", "Asia/Beirut",
+        "Europe_Eastern", "GR", "Europe/Athens",
+        "Europe_Eastern", "JO", "Asia/Amman",
+        "Europe_Eastern", "CY", "Asia/Nicosia",
+    };
+    private static final String[] aliasMap = new String[] {
+        "Mexico/BajaNorte", "America/Tijuana",
+        "Antarctica/South_Pole", "Antarctica/McMurdo",
+        "US/Michigan", "America/Detroit",
+        "America/Porto_Acre", "America/Rio_Branco",
+        "US/Alaska", "America/Anchorage",
+        "Asia/Ujung_Pandang", "Asia/Makassar",
+        "Canada/Atlantic", "America/Halifax",
+        "W-SU", "Europe/Moscow",
+        "Kwajalein", "Pacific/Kwajalein",
+        "Europe/Bratislava", "Europe/Prague",
+        "Canada/Central", "America/Winnipeg",
+        "Canada/Mountain", "America/Edmonton",
+        "Iceland", "Atlantic/Reykjavik",
+        "Asia/Ulan_Bator", "Asia/Ulaanbaatar",
+        "UTC", "Etc/UTC",
+        "Europe/Guernsey", "Europe/London",
+        "Singapore", "Asia/Singapore",
+        "Atlantic/Faeroe", "Atlantic/Faroe",
+        "Greenwich", "Etc/GMT",
+        "America/Fort_Wayne", "America/Indiana/Indianapolis",
+        "Etc/Universal", "Etc/UTC",
+        "Chile/EasterIsland", "Pacific/Easter",
+        "Pacific/Samoa", "Pacific/Pago_Pago",
+        "Europe/Nicosia", "Asia/Nicosia",
+        "Etc/Zulu", "Etc/UTC",
+        "Asia/Ashkhabad", "Asia/Ashgabat",
+        "America/Louisville", "America/Kentucky/Louisville",
+        "Australia/North", "Australia/Darwin",
+        "America/Atka", "America/Adak",
+        "America/Marigot", "America/Guadeloupe",
+        "Brazil/DeNoronha", "America/Noronha",
+        "Turkey", "Europe/Istanbul",
+        "Zulu", "Etc/UTC",
+        "Europe/Vatican", "Europe/Rome",
+        "Israel", "Asia/Jerusalem",
+        "America/Rosario", "America/Argentina/Cordoba",
+        "Jamaica", "America/Jamaica",
+        "Asia/Katmandu", "Asia/Kathmandu",
+        "Canada/East-Saskatchewan", "America/Regina",
+        "ROK", "Asia/Seoul",
+        "Asia/Macao", "Asia/Macau",
+        "Australia/South", "Australia/Adelaide",
+        "US/Arizona", "America/Phoenix",
+        "Australia/Yancowinna", "Australia/Broken_Hill",
+        "Canada/Pacific", "America/Vancouver",
+        "Libya", "Africa/Tripoli",
+        "Japan", "Asia/Tokyo",
+        "Arctic/Longyearbyen", "Europe/Oslo",
+        "Africa/Timbuktu", "Africa/Bamako",
+        "America/Indianapolis", "America/Indiana/Indianapolis",
+        "Etc/Greenwich", "Etc/GMT",
+        "Australia/ACT", "Australia/Sydney",
+        "GMT", "Etc/GMT",
+        "Mexico/BajaSur", "America/Mazatlan",
+        "Cuba", "America/Havana",
+        "Brazil/West", "America/Manaus",
+        "Asia/Saigon", "Asia/Ho_Chi_Minh",
+        "America/Jujuy", "America/Argentina/Jujuy",
+        "Australia/Victoria", "Australia/Melbourne",
+        "America/Catamarca", "America/Argentina/Catamarca",
+        "America/Ensenada", "America/Tijuana",
+        "Europe/San_Marino", "Europe/Rome",
+        "Europe/Isle_of_Man", "Europe/London",
+        "Mexico/General", "America/Mexico_City",
+        "US/Hawaii", "Pacific/Honolulu",
+        "Europe/Mariehamn", "Europe/Helsinki",
+        "US/Indiana-Starke", "America/Indiana/Knox",
+        "Australia/NSW", "Australia/Sydney",
+        "Australia/West", "Australia/Perth",
+        "Brazil/Acre", "America/Rio_Branco",
+        "Australia/Tasmania", "Australia/Hobart",
+        "Atlantic/Jan_Mayen", "Europe/Oslo",
+        "America/Buenos_Aires", "America/Argentina/Buenos_Aires",
+        "Europe/Jersey", "Europe/London",
+        "Brazil/East", "America/Sao_Paulo",
+        "America/Virgin", "America/St_Thomas",
+        "Navajo", "America/Denver",
+        "GB", "Europe/London",
+        "Poland", "Europe/Warsaw",
+        "Pacific/Yap", "Pacific/Chuuk",
+        "America/Argentina/ComodRivadavia", "America/Argentina/Catamarca",
+        "Asia/Calcutta", "Asia/Kolkata",
+        "America/Mendoza", "America/Argentina/Mendoza",
+        "Universal", "Etc/UTC",
+        "Australia/Queensland", "Australia/Brisbane",
+        "Asia/Dacca", "Asia/Dhaka",
+        "US/Pacific", "America/Los_Angeles",
+        "Asia/Chungking", "Asia/Chongqing",
+        "Pacific/Truk", "Pacific/Chuuk",
+        "ROC", "Asia/Taipei",
+        "US/Aleutian", "America/Adak",
+        "Pacific/Ponape", "Pacific/Pohnpei",
+        "Canada/Yukon", "America/Whitehorse",
+        "PRC", "Asia/Shanghai",
+        "Africa/Asmera", "Africa/Asmara",
+        "GB-Eire", "Europe/London",
+        "America/St_Barthelemy", "America/Guadeloupe",
+        "US/Central", "America/Chicago",
+        "Egypt", "Africa/Cairo",
+        "Chile/Continental", "America/Santiago",
+        "Portugal", "Europe/Lisbon",
+        "Europe/Tiraspol", "Europe/Chisinau",
+        "America/Coral_Harbour", "America/Atikokan",
+        "Europe/Belfast", "Europe/London",
+        "America/Cordoba", "America/Argentina/Cordoba",
+        "America/Shiprock", "America/Denver",
+        "NZ-CHAT", "Pacific/Chatham",
+        "Eire", "Europe/Dublin",
+        "US/East-Indiana", "America/Indiana/Indianapolis",
+        "Australia/Canberra", "Australia/Sydney",
+        "Canada/Newfoundland", "America/St_Johns",
+        "UCT", "Etc/UCT",
+        "Australia/LHI", "Australia/Lord_Howe",
+        "Iran", "Asia/Tehran",
+        "US/Eastern", "America/New_York",
+        "Canada/Eastern", "America/Toronto",
+        "US/Samoa", "Pacific/Pago_Pago",
+        "America/Knox_IN", "America/Indiana/Knox",
+        "Canada/Saskatchewan", "America/Regina",
+        "Asia/Thimbu", "Asia/Thimphu",
+        "US/Mountain", "America/Denver",
+        "NZ", "Pacific/Auckland",
+        "Asia/Tel_Aviv", "Asia/Jerusalem",
+        "Hongkong", "Asia/Hong_Kong",
+    };
+
+    private static final Map<String, String> zidToMzone = new HashMap<>();
+    private static final Map<String, String> mzoneToZid = new HashMap<>();
+    private static final Map<String, Map<String, String>> mzoneToZidL = new HashMap<>();
+    private static final Map<String, String> aliases = new HashMap<>();
+
+    static {
+        for (int i = 0; i < zidMap.length; i += 3) {
+            zidToMzone.put(zidMap[i], zidMap[i + 1]);
+            mzoneToZid.put(zidMap[i + 1], zidMap[i + 2]);
+        }
+
+        for (int i = 0; i < mzoneMap.length; i += 3) {
+            String mzone = mzoneMap[i];
+            Map<String, String> map = mzoneToZidL.get(mzone);
+            if (map == null) {
+                map = new HashMap<>();
+                mzoneToZidL.put(mzone, map);
+            }
+            map.put(mzoneMap[i + 1], mzoneMap[i + 2]);
+        }
+
+        for (int i = 0; i < aliasMap.length; i += 2) {
+            aliases.put(aliasMap[i], aliasMap[i + 1]);
+        }
+    }
+}
diff --git a/jdk/test/java/time/test/java/time/temporal/MockFieldNoValue.java b/jdk/test/java/time/test/java/time/temporal/MockFieldNoValue.java
index 255735d..eb97313 100644
--- a/jdk/test/java/time/test/java/time/temporal/MockFieldNoValue.java
+++ b/jdk/test/java/time/test/java/time/temporal/MockFieldNoValue.java
@@ -59,13 +59,15 @@
  */
 package test.java.time.temporal;
 
-import java.time.format.DateTimeBuilder;
-import java.time.temporal.*;
-
 import static java.time.temporal.ChronoUnit.MONTHS;
 import static java.time.temporal.ChronoUnit.WEEKS;
 
 import java.time.DateTimeException;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
 
 /**
  * Mock TemporalField that returns null.
@@ -96,29 +98,23 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public boolean doIsSupported(TemporalAccessor temporal) {
+    public boolean isSupportedBy(TemporalAccessor temporal) {
         return true;
     }
 
     @Override
-    public ValueRange doRange(TemporalAccessor temporal) {
+    public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
         return ValueRange.of(1, 20);
     }
 
     @Override
-    public long doGet(TemporalAccessor temporal) {
+    public long getFrom(TemporalAccessor temporal) {
         throw new DateTimeException("Mock");
     }
 
     @Override
-    public <R extends Temporal> R doWith(R temporal, long newValue) {
+    public <R extends Temporal> R adjustInto(R temporal, long newValue) {
         throw new DateTimeException("Mock");
     }
 
-    //-----------------------------------------------------------------------
-    @Override
-    public boolean resolve(DateTimeBuilder dateTimeBuilder, long value) {
-        return false;
-    }
-
 }
diff --git a/jdk/test/java/time/test/java/time/temporal/MockFieldValue.java b/jdk/test/java/time/test/java/time/temporal/MockFieldValue.java
index 7f478a9..cceb4c8 100644
--- a/jdk/test/java/time/test/java/time/temporal/MockFieldValue.java
+++ b/jdk/test/java/time/test/java/time/temporal/MockFieldValue.java
@@ -90,7 +90,7 @@
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     @Override
diff --git a/jdk/test/java/time/test/java/time/temporal/TestChronoUnit.java b/jdk/test/java/time/test/java/time/temporal/TestChronoUnit.java
index b282cda..0f84d39 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestChronoUnit.java
+++ b/jdk/test/java/time/test/java/time/temporal/TestChronoUnit.java
@@ -106,35 +106,33 @@
 
     @Test(dataProvider = "yearsBetween")
     public void test_yearsBetween(LocalDate start, LocalDate end, long expected) {
-        assertEquals(YEARS.between(start, end).getAmount(), expected);
-        assertEquals(YEARS.between(start, end).getUnit(), YEARS);
+        assertEquals(YEARS.between(start, end), expected);
     }
 
     @Test(dataProvider = "yearsBetween")
     public void test_yearsBetweenReversed(LocalDate start, LocalDate end, long expected) {
-        assertEquals(YEARS.between(end, start).getAmount(), -expected);
-        assertEquals(YEARS.between(end, start).getUnit(), YEARS);
+        assertEquals(YEARS.between(end, start), -expected);
     }
 
     @Test(dataProvider = "yearsBetween")
     public void test_yearsBetween_LocalDateTimeSameTime(LocalDate start, LocalDate end, long expected) {
-        assertEquals(YEARS.between(start.atTime(12, 30), end.atTime(12, 30)).getAmount(), expected);
+        assertEquals(YEARS.between(start.atTime(12, 30), end.atTime(12, 30)), expected);
     }
 
     @Test(dataProvider = "yearsBetween")
     public void test_yearsBetween_LocalDateTimeLaterTime(LocalDate start, LocalDate end, long expected) {
-        assertEquals(YEARS.between(start.atTime(12, 30), end.atTime(12, 31)).getAmount(), expected);
+        assertEquals(YEARS.between(start.atTime(12, 30), end.atTime(12, 31)), expected);
     }
 
     @Test(dataProvider = "yearsBetween")
     public void test_yearsBetween_ZonedDateSameOffset(LocalDate start, LocalDate end, long expected) {
-        assertEquals(YEARS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(2))).getAmount(), expected);
+        assertEquals(YEARS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(2))), expected);
     }
 
     @Test(dataProvider = "yearsBetween")
     public void test_yearsBetween_ZonedDateLaterOffset(LocalDate start, LocalDate end, long expected) {
         // +01:00 is later than +02:00
-        assertEquals(YEARS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(1))).getAmount(), expected);
+        assertEquals(YEARS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(1))), expected);
     }
 
     //-----------------------------------------------------------------------
@@ -173,35 +171,33 @@
 
     @Test(dataProvider = "monthsBetween")
     public void test_monthsBetween(LocalDate start, LocalDate end, long expected) {
-        assertEquals(MONTHS.between(start, end).getAmount(), expected);
-        assertEquals(MONTHS.between(start, end).getUnit(), MONTHS);
+        assertEquals(MONTHS.between(start, end), expected);
     }
 
     @Test(dataProvider = "monthsBetween")
     public void test_monthsBetweenReversed(LocalDate start, LocalDate end, long expected) {
-        assertEquals(MONTHS.between(end, start).getAmount(), -expected);
-        assertEquals(MONTHS.between(end, start).getUnit(), MONTHS);
+        assertEquals(MONTHS.between(end, start), -expected);
     }
 
     @Test(dataProvider = "monthsBetween")
     public void test_monthsBetween_LocalDateTimeSameTime(LocalDate start, LocalDate end, long expected) {
-        assertEquals(MONTHS.between(start.atTime(12, 30), end.atTime(12, 30)).getAmount(), expected);
+        assertEquals(MONTHS.between(start.atTime(12, 30), end.atTime(12, 30)), expected);
     }
 
     @Test(dataProvider = "monthsBetween")
     public void test_monthsBetween_LocalDateTimeLaterTime(LocalDate start, LocalDate end, long expected) {
-        assertEquals(MONTHS.between(start.atTime(12, 30), end.atTime(12, 31)).getAmount(), expected);
+        assertEquals(MONTHS.between(start.atTime(12, 30), end.atTime(12, 31)), expected);
     }
 
     @Test(dataProvider = "monthsBetween")
     public void test_monthsBetween_ZonedDateSameOffset(LocalDate start, LocalDate end, long expected) {
-        assertEquals(MONTHS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(2))).getAmount(), expected);
+        assertEquals(MONTHS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(2))), expected);
     }
 
     @Test(dataProvider = "monthsBetween")
     public void test_monthsBetween_ZonedDateLaterOffset(LocalDate start, LocalDate end, long expected) {
         // +01:00 is later than +02:00
-        assertEquals(MONTHS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(1))).getAmount(), expected);
+        assertEquals(MONTHS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(1))), expected);
     }
 
     //-----------------------------------------------------------------------
@@ -234,14 +230,12 @@
 
     @Test(dataProvider = "weeksBetween")
     public void test_weeksBetween(LocalDate start, LocalDate end, long expected) {
-        assertEquals(WEEKS.between(start, end).getAmount(), expected);
-        assertEquals(WEEKS.between(start, end).getUnit(), WEEKS);
+        assertEquals(WEEKS.between(start, end), expected);
     }
 
     @Test(dataProvider = "weeksBetween")
     public void test_weeksBetweenReversed(LocalDate start, LocalDate end, long expected) {
-        assertEquals(WEEKS.between(end, start).getAmount(), -expected);
-        assertEquals(WEEKS.between(end, start).getUnit(), WEEKS);
+        assertEquals(WEEKS.between(end, start), -expected);
     }
 
     //-----------------------------------------------------------------------
@@ -279,35 +273,33 @@
 
     @Test(dataProvider = "daysBetween")
     public void test_daysBetween(LocalDate start, LocalDate end, long expected) {
-        assertEquals(DAYS.between(start, end).getAmount(), expected);
-        assertEquals(DAYS.between(start, end).getUnit(), DAYS);
+        assertEquals(DAYS.between(start, end), expected);
     }
 
     @Test(dataProvider = "daysBetween")
     public void test_daysBetweenReversed(LocalDate start, LocalDate end, long expected) {
-        assertEquals(DAYS.between(end, start).getAmount(), -expected);
-        assertEquals(DAYS.between(end, start).getUnit(), DAYS);
+        assertEquals(DAYS.between(end, start), -expected);
     }
 
     @Test(dataProvider = "daysBetween")
     public void test_daysBetween_LocalDateTimeSameTime(LocalDate start, LocalDate end, long expected) {
-        assertEquals(DAYS.between(start.atTime(12, 30), end.atTime(12, 30)).getAmount(), expected);
+        assertEquals(DAYS.between(start.atTime(12, 30), end.atTime(12, 30)), expected);
     }
 
     @Test(dataProvider = "daysBetween")
     public void test_daysBetween_LocalDateTimeLaterTime(LocalDate start, LocalDate end, long expected) {
-        assertEquals(DAYS.between(start.atTime(12, 30), end.atTime(12, 31)).getAmount(), expected);
+        assertEquals(DAYS.between(start.atTime(12, 30), end.atTime(12, 31)), expected);
     }
 
     @Test(dataProvider = "daysBetween")
     public void test_daysBetween_ZonedDateSameOffset(LocalDate start, LocalDate end, long expected) {
-        assertEquals(DAYS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(2))).getAmount(), expected);
+        assertEquals(DAYS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(2))), expected);
     }
 
     @Test(dataProvider = "daysBetween")
     public void test_daysBetween_ZonedDateLaterOffset(LocalDate start, LocalDate end, long expected) {
         // +01:00 is later than +02:00
-        assertEquals(DAYS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(1))).getAmount(), expected);
+        assertEquals(DAYS.between(start.atStartOfDay(ZoneOffset.ofHours(2)), end.atStartOfDay(ZoneOffset.ofHours(1))), expected);
     }
 
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/test/java/time/temporal/TestDateTimeBuilderCombinations.java b/jdk/test/java/time/test/java/time/temporal/TestDateTimeBuilderCombinations.java
index 328ead5..941e08e 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestDateTimeBuilderCombinations.java
+++ b/jdk/test/java/time/test/java/time/temporal/TestDateTimeBuilderCombinations.java
@@ -71,9 +71,13 @@
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
 
+import java.time.DateTimeException;
 import java.time.LocalDate;
-import java.time.format.DateTimeBuilder;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 
 import org.testng.annotations.DataProvider;
@@ -98,74 +102,110 @@
     }
 
     @Test(dataProvider = "combine")
-    public void test_derive(TemporalField field1, Number value1, TemporalField field2, Number value2,
-            TemporalField field3, Number value3, TemporalField field4, Number value4, Class<?> query, Object expectedVal) {
-        DateTimeBuilder builder = new DateTimeBuilder(field1, value1.longValue());
+    public void test_derive(final TemporalField field1, final Number value1,
+                            final TemporalField field2, final Number value2,
+                            final TemporalField field3, final Number value3,
+                            final TemporalField field4, final Number value4,
+                            Class<?> query, Object expectedVal) {
+        // mock for testing that does not fully comply with TemporalAccessor contract
+        TemporalAccessor test = new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                return field == field1 || field == field2 || field == field3 || field == field4;
+            }
+            @Override
+            public long getLong(TemporalField field) {
+                if (field == field1) {
+                    return value1.longValue();
+                }
+                if (field == field2) {
+                    return value2.longValue();
+                }
+                if (field == field3) {
+                    return value3.longValue();
+                }
+                if (field == field4) {
+                    return value4.longValue();
+                }
+                throw new DateTimeException("Unsupported");
+            }
+        };
+        String str = "";
+        DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
+        dtfb.appendValue(field1).appendLiteral('-');
+        str += value1 + "-";
         if (field2 != null) {
-            builder.addFieldValue(field2, value2.longValue());
+            dtfb.appendValue(field2).appendLiteral('-');
+            str += value2 + "-";
         }
         if (field3 != null) {
-            builder.addFieldValue(field3, value3.longValue());
+            dtfb.appendValue(field3).appendLiteral('-');
+            str += value3 + "-";
         }
         if (field4 != null) {
-            builder.addFieldValue(field4, value4.longValue());
+            dtfb.appendValue(field4).appendLiteral('-');
+            str += value4 + "-";
         }
-        builder.resolve();
-        assertEquals(builder.extract((Class<?>) query), expectedVal);
+        TemporalAccessor parsed = dtfb.toFormatter().parse(str);
+        if (query == LocalDate.class) {
+            if (expectedVal != null) {
+                assertEquals(parsed.query(LocalDate::from), expectedVal);
+            } else {
+                try {
+                    parsed.query(LocalDate::from);
+                    fail();
+                } catch (DateTimeException ex) {
+                    // expected
+                }
+            }
+        } else {
+            throw new IllegalArgumentException();
+        }
     }
 
     //-----------------------------------------------------------------------
     @DataProvider(name = "normalized")
     Object[][] data_normalized() {
         return new Object[][] {
-            {YEAR, 2127, null, null, null, null, YEAR, 2127},
-            {MONTH_OF_YEAR, 12, null, null, null, null, MONTH_OF_YEAR, 12},
-            {DAY_OF_YEAR, 127, null, null, null, null, DAY_OF_YEAR, 127},
-            {DAY_OF_MONTH, 23, null, null, null, null, DAY_OF_MONTH, 23},
-            {DAY_OF_WEEK, 127, null, null, null, null, DAY_OF_WEEK, 127L},
-            {ALIGNED_WEEK_OF_YEAR, 23, null, null, null, null, ALIGNED_WEEK_OF_YEAR, 23},
-            {ALIGNED_DAY_OF_WEEK_IN_YEAR, 4, null, null, null, null, ALIGNED_DAY_OF_WEEK_IN_YEAR, 4L},
-            {ALIGNED_WEEK_OF_MONTH, 4, null, null, null, null, ALIGNED_WEEK_OF_MONTH, 4},
-            {ALIGNED_DAY_OF_WEEK_IN_MONTH, 3, null, null, null, null, ALIGNED_DAY_OF_WEEK_IN_MONTH, 3},
-            {EPOCH_MONTH, 15, null, null, null, null, EPOCH_MONTH, null},
-            {EPOCH_MONTH, 15, null, null, null, null, YEAR, 1971},
-            {EPOCH_MONTH, 15, null, null, null, null, MONTH_OF_YEAR, 4},
+            {YEAR, 2127, YEAR, 2127},
+            {MONTH_OF_YEAR, 12, MONTH_OF_YEAR, 12},
+            {DAY_OF_YEAR, 127, DAY_OF_YEAR, 127},
+            {DAY_OF_MONTH, 23, DAY_OF_MONTH, 23},
+            {DAY_OF_WEEK, 127, DAY_OF_WEEK, 127L},
+            {ALIGNED_WEEK_OF_YEAR, 23, ALIGNED_WEEK_OF_YEAR, 23},
+            {ALIGNED_DAY_OF_WEEK_IN_YEAR, 4, ALIGNED_DAY_OF_WEEK_IN_YEAR, 4L},
+            {ALIGNED_WEEK_OF_MONTH, 4, ALIGNED_WEEK_OF_MONTH, 4},
+            {ALIGNED_DAY_OF_WEEK_IN_MONTH, 3, ALIGNED_DAY_OF_WEEK_IN_MONTH, 3},
+            {EPOCH_MONTH, 15, EPOCH_MONTH, null},
+            {EPOCH_MONTH, 15, YEAR, 1971},
+            {EPOCH_MONTH, 15, MONTH_OF_YEAR, 4},
         };
     }
 
     @Test(dataProvider = "normalized")
-    public void test_normalized(TemporalField field1, Number value1, TemporalField field2, Number value2,
-            TemporalField field3, Number value3, TemporalField query, Number expectedVal) {
-        DateTimeBuilder builder = new DateTimeBuilder(field1, value1.longValue());
-        if (field2 != null) {
-            builder.addFieldValue(field2, value2.longValue());
-        }
-        if (field3 != null) {
-            builder.addFieldValue(field3, value3.longValue());
-        }
-        builder.resolve();
+    public void test_normalized(final TemporalField field1, final Number value1, TemporalField expectedField, Number expectedVal) {
+        // mock for testing that does not fully comply with TemporalAccessor contract
+        TemporalAccessor test = new TemporalAccessor() {
+            @Override
+            public boolean isSupported(TemporalField field) {
+                return field == field1;
+            }
+            @Override
+            public long getLong(TemporalField field) {
+                if (field == field1) {
+                    return value1.longValue();
+                }
+                throw new DateTimeException("Unsupported");
+            }
+        };
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field1).toFormatter();
+        String str = value1.toString();
+        TemporalAccessor temporal = f.parse(str);
         if (expectedVal != null) {
-            assertEquals(builder.getLong(query), expectedVal.longValue());
+            assertEquals(temporal.getLong(expectedField), expectedVal.longValue());
         } else {
-            assertEquals(builder.containsFieldValue(query), false);
+            assertEquals(temporal.isSupported(expectedField), false);
         }
     }
 
-    //-----------------------------------------------------------------------
-    // TODO: maybe reinstate
-//    public void test_split() {
-//        DateTimeBuilder builder = new DateTimeBuilder();
-//        builder.addCalendrical(LocalDateTime.of(2012, 6, 30, 12, 30));
-//        builder.addCalendrical(ZoneOffset.ofHours(2));
-//        builder.resolve();
-//        assertEquals(builder.build(LocalDate.class), LocalDate.of(2012, 6, 30));
-//        assertEquals(builder.build(LocalTime.class), LocalTime.of(12, 30));
-//        assertEquals(builder.build(ZoneOffset.class), ZoneOffset.ofHours(2));
-//
-//        assertEquals(builder.build(LocalDateTime.class), LocalDateTime.of(2012, 6, 30, 12, 30));
-//        assertEquals(builder.build(OffsetDate.class), OffsetDate.of(LocalDate.of(2012, 6, 30), ZoneOffset.ofHours(2)));
-//        assertEquals(builder.build(OffsetTime.class), OffsetTime.of(LocalTime.of(12, 30), ZoneOffset.ofHours(2)));
-////        assertEquals(builder.build(OffsetDateTime.class), OffsetDateTime.of(2012, 6, 30, 12, 30, ZoneOffset.ofHours(2)));
-//    }
-
 }
diff --git a/jdk/test/java/time/test/java/time/temporal/TestJapaneseChronoImpl.java b/jdk/test/java/time/test/java/time/temporal/TestJapaneseChronoImpl.java
index cadd1a3..ababf14 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestJapaneseChronoImpl.java
+++ b/jdk/test/java/time/test/java/time/temporal/TestJapaneseChronoImpl.java
@@ -63,12 +63,13 @@
 import java.util.TimeZone;
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.time.temporal.OffsetDateTime;
+import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
 import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDate;
 import java.time.temporal.ChronoUnit;
-import java.time.calendar.JapaneseChrono;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.JapaneseDate;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -100,7 +101,7 @@
         Calendar cal = java.util.Calendar.getInstance(locale);
         assertEquals(cal.getCalendarType(), "japanese", "Unexpected calendar type");
 
-        ChronoLocalDate<JapaneseChrono> jDate = JapaneseChrono.INSTANCE.date(isoStartDate);
+        JapaneseDate jDate = JapaneseChronology.INSTANCE.date(isoStartDate);
 
         // Convert to millis and set Japanese Calendar to that start date (at GMT)
         OffsetDateTime jodt = OffsetDateTime.of(isoStartDate, LocalTime.MIN, ZoneOffset.UTC);
diff --git a/jdk/test/java/time/test/java/time/temporal/TestYearMonth.java b/jdk/test/java/time/test/java/time/temporal/TestJulianFields.java
similarity index 86%
copy from jdk/test/java/time/test/java/time/temporal/TestYearMonth.java
copy to jdk/test/java/time/test/java/time/temporal/TestJulianFields.java
index ab0d7f4..0d9d79e 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestYearMonth.java
+++ b/jdk/test/java/time/test/java/time/temporal/TestJulianFields.java
@@ -59,21 +59,26 @@
  */
 package test.java.time.temporal;
 
-import java.time.temporal.YearMonth;
+import static org.testng.Assert.assertEquals;
+
+import java.time.temporal.JulianFields;
 
 import org.testng.annotations.Test;
-import test.java.time.AbstractTest;
 
 /**
- * Test YearMonth.
+ * Test.
  */
 @Test
-public class TestYearMonth extends AbstractTest {
+public class TestJulianFields {
 
     //-----------------------------------------------------------------------
+    // toString()
+    //-----------------------------------------------------------------------
     @Test
-    public void test_immutable() {
-        assertImmutable(YearMonth.class);
+    public void test_toString() {
+        assertEquals(JulianFields.JULIAN_DAY.toString(), "JulianDay");
+        assertEquals(JulianFields.MODIFIED_JULIAN_DAY.toString(), "ModifiedJulianDay");
+        assertEquals(JulianFields.RATA_DIE.toString(), "RataDie");
     }
 
 }
diff --git a/jdk/test/java/time/test/java/time/temporal/TestThaiBuddhistChronoImpl.java b/jdk/test/java/time/test/java/time/temporal/TestThaiBuddhistChronoImpl.java
index 9fd69cf..14b0a45 100644
--- a/jdk/test/java/time/test/java/time/temporal/TestThaiBuddhistChronoImpl.java
+++ b/jdk/test/java/time/test/java/time/temporal/TestThaiBuddhistChronoImpl.java
@@ -65,8 +65,9 @@
 import java.time.LocalDate;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.ChronoLocalDate;
-import java.time.calendar.ThaiBuddhistChrono;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.ThaiBuddhistDate;
 
 import org.testng.annotations.Test;
 import org.testng.annotations.DataProvider;
@@ -97,7 +98,7 @@
         Calendar cal = java.util.Calendar.getInstance(locale);
         assertEquals(cal.getCalendarType(), "buddhist", "Unexpected calendar type");
 
-        ChronoLocalDate<ThaiBuddhistChrono> thaiDate = ThaiBuddhistChrono.INSTANCE.date(isoStartDate);
+        ThaiBuddhistDate thaiDate = ThaiBuddhistChronology.INSTANCE.date(isoStartDate);
 
         cal.setTimeZone(TimeZone.getTimeZone("GMT+00"));
         cal.set(Calendar.YEAR, thaiDate.get(ChronoField.YEAR));
diff --git a/jdk/test/java/time/test/java/time/zone/TestFixedZoneRules.java b/jdk/test/java/time/test/java/time/zone/TestFixedZoneRules.java
index 8056967..67b6e0a 100644
--- a/jdk/test/java/time/test/java/time/zone/TestFixedZoneRules.java
+++ b/jdk/test/java/time/test/java/time/zone/TestFixedZoneRules.java
@@ -59,7 +59,7 @@
  */
 package test.java.time.zone;
 
-import java.time.zone.*;
+import java.time.zone.ZoneRules;
 
 import static org.testng.Assert.assertEquals;
 
diff --git a/jdk/test/java/time/test/java/util/TestFormatter.java b/jdk/test/java/time/test/java/util/TestFormatter.java
index 54331ed..69c55f2 100644
--- a/jdk/test/java/time/test/java/util/TestFormatter.java
+++ b/jdk/test/java/time/test/java/util/TestFormatter.java
@@ -23,7 +23,7 @@
 package test.java.util;
 
 import java.time.Instant;
-import java.time.temporal.OffsetDateTime;
+import java.time.OffsetDateTime;
 import java.time.ZonedDateTime;
 import java.time.temporal.ChronoField;
 
@@ -129,10 +129,9 @@
         printFmtStr(locale, fmtStr);
         String expected = test(fmtStr, locale, null, cal);
         test(fmtStr, locale, expected, zdt);
-        test(fmtStr, locale, expected, OffsetDateTime.of(zdt));
-        test(fmtStr, locale, expected, zdt.getDateTime());
-        test(fmtStr, locale, expected, OffsetDateTime.of(zdt).toOffsetDate());
-        test(fmtStr, locale, expected, zdt.getDate());
+        test(fmtStr, locale, expected, zdt.toOffsetDateTime());
+        test(fmtStr, locale, expected, zdt.toLocalDateTime());
+        test(fmtStr, locale, expected, zdt.toLocalDate());
     }
 
     private void testTime(String fmtStr, Locale locale,
@@ -140,30 +139,34 @@
         printFmtStr(locale, fmtStr);
         String expected = test(fmtStr, locale, null, cal);
         test(fmtStr, locale, expected, zdt);
-        test(fmtStr, locale, expected, OffsetDateTime.of(zdt));
-        test(fmtStr, locale, expected, zdt.getDateTime());
-        test(fmtStr, locale, expected, OffsetDateTime.of(zdt).toOffsetTime());
-        test(fmtStr, locale, expected, zdt.getTime());
+        test(fmtStr, locale, expected, zdt.toOffsetDateTime());
+        test(fmtStr, locale, expected, zdt.toLocalDateTime());
+        test(fmtStr, locale, expected, zdt.toOffsetDateTime().toOffsetTime());
+        test(fmtStr, locale, expected, zdt.toLocalTime());
+    }
+
+    private String toZoneIdStr(String expected) {
+        return expected.replaceAll("(?:GMT|UTC)(?<off>[+\\-]?[0-9]{2}:[0-9]{2})", "${off}")
+                       .replaceAll("GMT|UTC|UT", "Z");
     }
 
     private void testZoneId(Locale locale, ZonedDateTime zdt, Calendar cal) {
         String fmtStr = "z:[%tz] z:[%1$Tz] Z:[%1$tZ] Z:[%1$TZ]";
         printFmtStr(locale, fmtStr);
-        String expected = test(fmtStr, locale, null, cal);
+        String expected = toZoneIdStr(test(fmtStr, locale, null, cal));
         test(fmtStr, locale, expected, zdt);
         // get a new cal with fixed tz
         Calendar cal0 = Calendar.getInstance();
         cal0.setTimeInMillis(zdt.toInstant().toEpochMilli());
         cal0.setTimeZone(TimeZone.getTimeZone("GMT" + zdt.getOffset().getId()));
-        expected = test(fmtStr, locale, null, cal0).replaceAll("GMT", "");
-        test(fmtStr, locale, expected, OffsetDateTime.of(zdt));
-        test(fmtStr, locale, expected, OffsetDateTime.of(zdt).toOffsetDate());
-        test(fmtStr, locale, expected, OffsetDateTime.of(zdt).toOffsetTime());
+        expected = toZoneIdStr(test(fmtStr, locale, null, cal0));
+        test(fmtStr, locale, expected, zdt.toOffsetDateTime());
+        test(fmtStr, locale, expected, zdt.toOffsetDateTime().toOffsetTime());
 
         // datetime + zid
         fmtStr = "c:[%tc] c:[%1$Tc]";
         printFmtStr(locale, fmtStr);
-        expected = test(fmtStr, locale, null, cal);
+        expected = toZoneIdStr(test(fmtStr, locale, null, cal));
         test(fmtStr, locale, expected, zdt);
     }
 
@@ -174,6 +177,6 @@
         String expected = test(fmtStr, locale, null, cal);
         test(fmtStr, locale, expected, instant);
         test(fmtStr, locale, expected, zdt);
-        test(fmtStr, locale, expected, OffsetDateTime.of(zdt));
+        test(fmtStr, locale, expected, zdt.toOffsetDateTime());
     }
 }
diff --git a/jdk/test/java/util/Calendar/Bug8007038.java b/jdk/test/java/util/Calendar/Bug8007038.java
new file mode 100644
index 0000000..e4f1a66
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug8007038.java
@@ -0,0 +1,108 @@
+/*
+ * 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 8007038
+ * @summary Verify ArrayIndexOutOfBoundsException is not thrown on
+ *     on calling localizedDateTime().print() with JapaneseChrono
+ * @compile -XDignore.symbol.file Bug8007038.java
+ * @run main Bug8007038
+ */
+
+import java.util.*;
+import static java.util.Calendar.*;
+import sun.util.locale.provider.CalendarDataUtility;
+
+public class Bug8007038 {
+    private final static String[] calTypes = {
+        "gregory",
+        "buddhist",
+        "japanese",
+        "roc",
+        "islamic",
+    };
+    private final static int[][] eraMinMax = {
+        {GregorianCalendar.BC, GregorianCalendar.AD},
+        {0, 1},
+        {0, 4},
+        {0, 1},
+        {0, 1},
+        {0, 1},
+    };
+    private final static Locale[] testLocs = {
+        Locale.ROOT,
+        Locale.forLanguageTag("ja-JP-u-ca-japanese"),
+        Locale.forLanguageTag("th-TH"),
+        Locale.forLanguageTag("th-TH-u-ca-buddhist"),
+        Locale.forLanguageTag("zh-TW-u-ca-roc"),
+        Locale.forLanguageTag("ar-EG-u-ca-islamic"),
+        Locale.forLanguageTag("xx-YY-u-ca-bogus"),
+    };
+
+    public static void main(String[] args) {
+        for (int calIdx  = 0; calIdx  < calTypes.length; calIdx++) {
+            for (int locIdx = 0; locIdx < testLocs.length; locIdx++) {
+                // era
+                for (int fieldIdx = eraMinMax[calIdx][0]; fieldIdx <= eraMinMax[calIdx][1]; fieldIdx++) {
+                    checkValueRange(calTypes[calIdx], ERA, fieldIdx, LONG, testLocs[locIdx], true);
+                }
+                checkValueRange(calTypes[calIdx], ERA, eraMinMax[calIdx][0]-1, LONG,
+                                testLocs[locIdx], false);
+                checkValueRange(calTypes[calIdx], ERA, eraMinMax[calIdx][1]+1,
+                                LONG, testLocs[locIdx], false);
+
+                // month
+                for (int fieldIdx = JANUARY; fieldIdx <= UNDECIMBER ; fieldIdx++) {
+                    checkValueRange(calTypes[calIdx], MONTH, fieldIdx, LONG, testLocs[locIdx], true);
+                }
+                checkValueRange(calTypes[calIdx], MONTH, JANUARY-1, LONG, testLocs[locIdx], false);
+                checkValueRange(calTypes[calIdx], MONTH, UNDECIMBER+1, LONG, testLocs[locIdx], false);
+
+                // day-of-week
+                for (int fieldIdx = SUNDAY; fieldIdx <= SATURDAY; fieldIdx++) {
+                    checkValueRange(calTypes[calIdx], DAY_OF_WEEK, fieldIdx, LONG, testLocs[locIdx], true);
+                }
+                checkValueRange(calTypes[calIdx], DAY_OF_WEEK, SUNDAY-1, LONG, testLocs[locIdx], false);
+                checkValueRange(calTypes[calIdx], DAY_OF_WEEK, SATURDAY+1, LONG, testLocs[locIdx], false);
+
+                // am/pm
+                for (int fieldIdx = AM; fieldIdx <= PM; fieldIdx++) {
+                    checkValueRange(calTypes[calIdx], AM_PM, fieldIdx, LONG, testLocs[locIdx], true);
+                }
+                checkValueRange(calTypes[calIdx], AM_PM, AM-1, LONG, testLocs[locIdx], false);
+                checkValueRange(calTypes[calIdx], AM_PM, PM+1, LONG, testLocs[locIdx], false);
+            }
+        }
+    }
+
+    private static void checkValueRange(String calType, int field, int value, int style, Locale l, boolean isNonNull) {
+        String ret = CalendarDataUtility.retrieveFieldValueName(calType, field, value, style, l);
+        System.out.print("retrieveFieldValueName("+calType+", "+field+", "+value+", "+style+", "+l+")");
+        if ((ret != null) == isNonNull) {
+            System.out.println(" returned "+ret);
+        } else {
+            throw new RuntimeException("The call returned "+ret);
+        }
+    }
+}
diff --git a/jdk/test/java/util/Calendar/JavatimeTest.java b/jdk/test/java/util/Calendar/JavatimeTest.java
new file mode 100644
index 0000000..5b9a710
--- /dev/null
+++ b/jdk/test/java/util/Calendar/JavatimeTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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 8007520
+ *@summary Test those bridge methods to/from java.time date/time classes
+ */
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Random;
+import java.util.TimeZone;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+
+public class JavatimeTest {
+
+    static final int NANOS_PER_SECOND = 1000_000_000;
+
+    public static void main(String[] args) throws Throwable {
+
+        int N = 10000;
+        long t1970 = new java.util.Date(70, 0, 01).getTime();
+        Random r = new Random();
+        for (int i = 0; i < N; i++) {
+            int days  = r.nextInt(50) * 365 + r.nextInt(365);
+            long secs = t1970 + days * 86400 + r.nextInt(86400);
+            int nanos = r.nextInt(NANOS_PER_SECOND);
+            int nanos_ms = nanos / 1000000 * 1000000; // millis precision
+            long millis = secs * 1000 + r.nextInt(1000);
+
+            LocalDateTime ldt = LocalDateTime.ofEpochSecond(secs, nanos, ZoneOffset.UTC);
+            LocalDateTime ldt_ms = LocalDateTime.ofEpochSecond(secs, nanos_ms, ZoneOffset.UTC);
+            Instant inst = Instant.ofEpochSecond(secs, nanos);
+            Instant inst_ms = Instant.ofEpochSecond(secs, nanos_ms);
+            //System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+
+            ///////////// java.util.Date /////////////////////////
+            Date jud = new java.util.Date(millis);
+            Instant inst0 = jud.toInstant();
+            if (jud.getTime() != inst0.toEpochMilli() ||
+                !jud.equals(Date.from(inst0))) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                throw new RuntimeException("FAILED: j.u.d -> instant -> j.u.d");
+            }
+            // roundtrip only with millis precision
+            Date jud0 = Date.from(inst_ms);
+            if (jud0.getTime() != inst_ms.toEpochMilli() ||
+                !inst_ms.equals(jud0.toInstant())) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                throw new RuntimeException("FAILED: instant -> j.u.d -> instant");
+            }
+            //////////// java.util.GregorianCalendar /////////////
+            GregorianCalendar cal = new GregorianCalendar();
+            cal.setGregorianChange(new java.util.Date(Long.MIN_VALUE));
+            cal.setFirstDayOfWeek(Calendar.MONDAY);
+            cal.setMinimalDaysInFirstWeek(4);
+            cal.setTimeInMillis(millis);
+            ZonedDateTime zdt0 = cal.toZonedDateTime();
+            if (cal.getTimeInMillis() != zdt0.toInstant().toEpochMilli() ||
+                !cal.equals(GregorianCalendar.from(zdt0))) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                throw new RuntimeException("FAILED: gcal -> zdt -> gcal");
+            }
+            inst0 = cal.toInstant();
+            if (cal.getTimeInMillis() != inst0.toEpochMilli()) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                throw new RuntimeException("FAILED: gcal -> zdt");
+            }
+            ZonedDateTime zdt = ZonedDateTime.of(ldt_ms, ZoneId.systemDefault());
+            GregorianCalendar cal0 = GregorianCalendar.from(zdt);
+            if (zdt.toInstant().toEpochMilli() != cal0.getTimeInMillis() ||
+                !zdt.equals(GregorianCalendar.from(zdt).toZonedDateTime())) {
+                System.out.printf("ms: %16d  ns: %10d  ldt:[%s]%n", millis, nanos, ldt);
+                throw new RuntimeException("FAILED: zdt -> gcal -> zdt");
+            }
+        }
+
+        ///////////// java.util.TimeZone /////////////////////////
+        for (String zidStr : TimeZone.getAvailableIDs()) {
+            // TBD: tzdt intergration
+            if (zidStr.startsWith("SystemV") ||
+                zidStr.contains("Riyadh8") ||
+                zidStr.equals("US/Pacific-New")) {
+                continue;
+            }
+            ZoneId zid = ZoneId.of(zidStr, ZoneId.OLD_IDS_POST_2005);
+            if (!zid.equals(TimeZone.getTimeZone(zid).toZoneId())) {
+                throw new RuntimeException("FAILED: zid -> tz -> zid :" + zidStr);
+            }
+            TimeZone tz = TimeZone.getTimeZone(zidStr);
+            // no round-trip for alias and "GMT"
+            if (!tz.equals(TimeZone.getTimeZone(tz.toZoneId())) &&
+                !ZoneId.OLD_IDS_POST_2005.containsKey(zidStr) &&
+                !zidStr.startsWith("GMT")) {
+                throw new RuntimeException("FAILED: tz -> zid -> tz :" + zidStr);
+            }
+        }
+        System.out.println("Passed!");
+    }
+}
diff --git a/jdk/test/java/util/TimeZone/OldIDMappingTest.java b/jdk/test/java/util/TimeZone/OldIDMappingTest.java
index e60ec53..35e19cb 100644
--- a/jdk/test/java/util/TimeZone/OldIDMappingTest.java
+++ b/jdk/test/java/util/TimeZone/OldIDMappingTest.java
@@ -51,17 +51,7 @@
             throw new RuntimeException("-old or -new must be specified; got " + arg);
         }
 
-        // Get a Field for TzIDOldMapping in sun.util.calendar.
-        Map<String, String> oldmap = null;
-        try {
-            Class<?> oldmapClass = Class.forName("sun.util.calendar.TzIDOldMapping");
-            Field map = oldmapClass.getDeclaredField("MAP");
-            map.setAccessible(true);
-            oldmap = (Map<String, String>) map.get(null);
-        } catch (Exception e) {
-            throw new RuntimeException("can't get TzIDOldMapping.MAP", e);
-        }
-
+        Map<String, String> oldmap = TzIDOldMapping.MAP;
         String prop = System.getProperty(MAPPING_PROPERTY_NAME);
         System.out.println(MAPPING_PROPERTY_NAME + "=" + prop);
 
diff --git a/jdk/src/share/classes/sun/util/calendar/TzIDOldMapping.java b/jdk/test/java/util/TimeZone/TzIDOldMapping.java
similarity index 98%
rename from jdk/src/share/classes/sun/util/calendar/TzIDOldMapping.java
rename to jdk/test/java/util/TimeZone/TzIDOldMapping.java
index 4f23007..e9ea6b5 100644
--- a/jdk/src/share/classes/sun/util/calendar/TzIDOldMapping.java
+++ b/jdk/test/java/util/TimeZone/TzIDOldMapping.java
@@ -23,8 +23,6 @@
  * questions.
  */
 
-package sun.util.calendar;
-
 import java.util.Map;
 import java.util.HashMap;
 
diff --git a/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java b/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java
new file mode 100644
index 0000000..8c9f236
--- /dev/null
+++ b/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java
@@ -0,0 +1,609 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/*
+ * @test
+ * @bug 8005697
+ * @summary Basic tests for StampedLock
+ * @author Chris Hegarty
+ */
+
+import java.util.Iterator;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.TimeUnit;
+import static java.util.concurrent.TimeUnit.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.StampedLock;
+
+public class Basic {
+
+    static void checkResult(Locker l, Class<? extends Throwable> c) {
+        Throwable t = l.thrown();
+        if (! ((t == null && c == null) || (c != null && c.isInstance(t)))) {
+            fail("Mismatch in thread " +
+                 l.getName() + ": " +
+                 t + ", " +
+                 (c == null ? "<null>" : c.getName()));
+        }
+
+        if (c == null)
+            check(l.stamp() != 0L);  // must have acquired the lock
+        else
+            check(l.stamp() == 0L);  // must NOT have acquired the lock
+    }
+
+    //----------------------------------------------------------------
+    // Mechanism to get all test threads into "running" mode.
+    //----------------------------------------------------------------
+    static void toTheStartingGate(Phaser gate) {
+        try {
+            gate.arriveAndAwaitAdvance();
+        } catch (Throwable t) {
+            unexpected(t);
+        }
+    }
+
+    static abstract class Locker extends Thread {
+        static AtomicInteger count = new AtomicInteger(1);
+        private volatile Throwable thrown;
+        private volatile long stamp;;
+        protected void thrown(Throwable thrown) { this.thrown = thrown; }
+        public Throwable thrown() { return thrown; }
+        protected void stamp(long stamp) { this.stamp = stamp; }
+        public long stamp() { return stamp; }
+
+        Locker() {
+            this("Locker");
+        }
+
+        Locker(String name) {
+            this.setName(name + ":" + count.getAndIncrement());
+            this.setDaemon(true);
+        }
+    }
+
+    static abstract class Reader extends Locker {
+        Reader() { super("Reader"); }
+        Reader(String name) { super(name); }
+    }
+
+    static Reader reader(final StampedLock sl, final Phaser gate) {
+        return new Reader() { public void run() {
+            if (gate != null ) toTheStartingGate(gate);
+            stamp(sl.readLock());
+            try {
+                check(sl.validate(stamp()));
+                check(sl.isReadLocked());
+                check(!sl.isWriteLocked());
+            } finally { sl.unlockRead(stamp()); } }};
+    }
+
+    static Reader readerView(final StampedLock sl, final Phaser gate) {
+        return new Reader("ReaderView") { public void run() {
+            if (gate != null ) toTheStartingGate(gate);
+            final Lock rl = sl.asReadLock();
+            rl.lock();
+            try {
+                stamp(1L);   // got the lock
+                check(sl.isReadLocked());
+                check(!sl.isWriteLocked());
+            } finally { rl.unlock(); } }};
+    }
+
+    static Reader reader(StampedLock sl, Phaser gate, boolean view) {
+        return view ? readerView(sl, gate) : reader(sl, gate);
+    }
+
+    static Reader interruptibleReader(final StampedLock sl,
+                                      final long timeout,
+                                      final TimeUnit unit,
+                                      final Phaser gate) {
+        return new Reader("InterruptibleReader") { public void run() {
+            if (gate != null ) toTheStartingGate(gate);
+            try {
+                if (timeout < 0)
+                    stamp(sl.readLockInterruptibly());
+                else
+                    stamp(sl.tryReadLock(timeout, unit));
+                check(sl.validate(stamp()));
+                check(sl.isReadLocked());
+                check(!sl.isWriteLocked());
+            } catch (Throwable x) { thrown(x);
+            } finally { if (stamp() != 0L) sl.unlockRead(stamp()); } }};
+    }
+
+    static Reader interruptibleReaderView(final StampedLock sl,
+                                          final long timeout,
+                                          final TimeUnit unit,
+                                          final Phaser gate) {
+        return new Reader("InterruptibleReaderView") { public void run() {
+            if (gate != null ) toTheStartingGate(gate);
+            final Lock rl = sl.asReadLock();
+
+            try {
+                if (timeout < 0)
+                    rl.lockInterruptibly();
+                else
+                    rl.tryLock(timeout, unit);
+                stamp(1L);  // got the lock
+                check(sl.isReadLocked());
+                check(!sl.isWriteLocked());
+            } catch (Throwable x) { thrown(x);
+            } finally { if (stamp() != 0L) rl.unlock(); } }};
+    }
+
+    static Reader interruptibleReader(final StampedLock sl,
+                                      final long timeout,
+                                      final TimeUnit unit,
+                                      final Phaser gate,
+                                      final boolean view) {
+        return view ? interruptibleReaderView(sl, timeout, unit, gate)
+                    : interruptibleReader(sl, timeout, unit, gate);
+    }
+
+    static abstract class Writer extends Locker {
+        Writer() { super("Writer"); }
+        Writer(String name) { super(name); }
+    }
+
+    static Writer writer(final StampedLock sl, final Phaser gate) {
+        return new Writer() { public void run() {
+            if (gate != null ) toTheStartingGate(gate);
+            try {
+                stamp(sl.writeLock());
+                check(sl.validate(stamp()));
+                check(!sl.isReadLocked());
+                check(sl.isWriteLocked());
+            } finally { sl.unlockWrite(stamp()); } }};
+    }
+
+    static Writer writerView(final StampedLock sl, final Phaser gate) {
+        return new Writer("WriterView") { public void run() {
+            if (gate != null ) toTheStartingGate(gate);
+            Lock wl = sl.asWriteLock();
+            wl.lock();
+            try {
+                stamp(1L);  // got the lock
+                check(!sl.isReadLocked());
+                check(sl.isWriteLocked());
+            } finally { wl.unlock(); } }};
+    }
+
+    static Writer writer(StampedLock sl, Phaser gate, boolean view) {
+        return view ? writerView(sl, gate) : writer(sl, gate);
+    }
+
+    static Writer interruptibleWriter(final StampedLock sl,
+                                      final long timeout,
+                                      final TimeUnit unit,
+                                      final Phaser gate) {
+        return new Writer("InterruptibleWriter") { public void run() {
+            if (gate != null ) toTheStartingGate(gate);
+            try {
+                if (timeout < 0)
+                    stamp(sl.writeLockInterruptibly());
+                else
+                    stamp(sl.tryWriteLock(timeout, unit));
+                check(sl.validate(stamp()));
+                check(!sl.isReadLocked());
+                check(sl.isWriteLocked());
+            } catch (Throwable x) { thrown(x);
+            } finally { if (stamp() != 0L) sl.unlockWrite(stamp()); } }};
+    }
+
+    static Writer interruptibleWriterView(final StampedLock sl,
+                                          final long timeout,
+                                          final TimeUnit unit,
+                                          final Phaser gate) {
+        return new Writer("InterruptibleWriterView") { public void run() {
+            if (gate != null ) toTheStartingGate(gate);
+            Lock wl = sl.asWriteLock();
+            try {
+                if (timeout < 0)
+                    wl.lockInterruptibly();
+                else
+                    wl.tryLock(timeout, unit);
+                stamp(1L);  // got the lock
+                check(!sl.isReadLocked());
+                check(sl.isWriteLocked());
+            } catch (Throwable x) { thrown(x);
+            } finally { if (stamp() != 0L) wl.unlock(); } }};
+    }
+
+    static Writer interruptibleWriter(final StampedLock sl,
+                                      final long timeout,
+                                      final TimeUnit unit,
+                                      final Phaser gate,
+                                      final boolean view) {
+        return view ? interruptibleWriterView(sl, timeout, unit, gate)
+                    : interruptibleWriter(sl, timeout, unit, gate);
+    }
+
+    // Returns an infinite lazy list of all possible reader combinations.
+    static Iterator<Reader> readerIterator(final StampedLock sl,
+                                           final Phaser gate) {
+        return new Iterator<Reader>() {
+            int i = 0;
+            boolean view = false;
+            public boolean hasNext() { return true; }
+            public Reader next() {
+                switch ((i++)&7) {
+                    case 1: case 4: case 7:
+                        return reader(sl, gate, view ^= true);
+                    case 2: case 5:
+                        return interruptibleReader(sl, -1, SECONDS, gate, view ^= true);
+                    default:
+                        return interruptibleReader(sl, 30, SECONDS, gate, view ^= true); }}
+            public void remove() {throw new UnsupportedOperationException();}};
+    }
+
+    // Returns an infinite lazy list of all possible writer combinations.
+    static Iterator<Writer> writerIterator(final StampedLock sl,
+                                           final Phaser gate) {
+        return new Iterator<Writer>() {
+            int i = 0;
+            boolean view = false;
+            public boolean hasNext() { return true; }
+            public Writer next() {
+                switch ((i++)&7) {
+                    case 1: case 4: case 7:
+                        return writer(sl, gate, view ^= true);
+                    case 2: case 5:
+                        return interruptibleWriter(sl, -1, SECONDS, gate, view ^= true);
+                    default:
+                        return interruptibleWriter(sl, 30, SECONDS, gate, view ^= true); }}
+            public void remove() {throw new UnsupportedOperationException();}};
+    }
+
+    private static void realMain(String[] args) throws Throwable {
+
+        Thread.currentThread().setName("mainThread");
+
+        //----------------------------------------------------------------
+        // Some basic sanity
+        //----------------------------------------------------------------
+        try {
+            final StampedLock sl = new StampedLock();
+            check(!sl.isReadLocked());
+            check(!sl.isWriteLocked());
+            long stamp = sl.tryOptimisticRead();
+            check(stamp != 0L);
+            check(sl.validate(stamp));
+            check(!sl.validate(0));
+
+            stamp = sl.writeLock();
+            try {
+                check(sl.validate(stamp));
+                check(!sl.isReadLocked());
+                check(sl.isWriteLocked());
+                check(sl.tryReadLock() == 0L);
+                check(sl.tryReadLock(100, MILLISECONDS) == 0L);
+                check(sl.tryOptimisticRead() == 0L);
+                check(sl.tryWriteLock() == 0L);
+                check(sl.tryWriteLock(100, MILLISECONDS) == 0L);
+                check(!sl.tryUnlockRead());
+                check(sl.tryConvertToWriteLock(stamp) == stamp);
+                try {
+                    sl.unlockRead(stamp);
+                    fail("Expected unlockRead to throw when not holding read lock");
+                } catch (IllegalMonitorStateException x) {
+                    pass();
+                }
+                check(sl.validate(stamp));
+            } finally {
+                sl.unlockWrite(stamp);
+            }
+            check(!sl.isWriteLocked());
+
+            stamp = sl.readLock();
+            try {
+                check(sl.validate(stamp));
+                check(sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(sl.tryOptimisticRead() != 0L);
+                check(sl.tryWriteLock() == 0L);
+                check(sl.tryWriteLock(100, MILLISECONDS) == 0L);
+                check(!sl.tryUnlockWrite());
+                check(sl.tryConvertToReadLock(stamp) == stamp);
+                try {
+                    sl.unlockWrite(stamp);
+                    fail("Expected unlockWrite to throw when not holding read lock");
+                } catch (IllegalMonitorStateException x) {
+                    pass();
+                }
+                check(sl.validate(stamp));
+            } finally {
+                sl.unlockRead(stamp);
+            }
+            check(!sl.isReadLocked());
+
+            stamp = sl.tryReadLock(100, MILLISECONDS);
+            try {
+                check(stamp != 0L);
+            } finally {
+                sl.unlockRead(stamp);
+            }
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // Multiple writers single reader
+        //----------------------------------------------------------------
+        try {
+            StampedLock sl = new StampedLock();
+            Phaser gate = new Phaser(102);
+            Iterator<Writer> writers = writerIterator(sl, gate);
+            Iterator<Reader> readers = readerIterator(sl, gate);
+            for (int i = 0; i < 10; i++) {
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(!sl.tryUnlockRead());
+                check(!sl.tryUnlockWrite());
+                check(sl.tryOptimisticRead() != 0L);
+                Locker[] wThreads = new Locker[100];;
+                for (int j=0; j<100; j++)
+                    wThreads[j] = writers.next();
+                for (int j=0; j<100; j++)
+                    wThreads[j].start();
+                Reader reader = readers.next(); reader.start();
+                toTheStartingGate(gate);
+                reader.join();
+                for (int j=0; j<100; j++)
+                    wThreads[j].join();
+                for (int j=0; j<100; j++)
+                    checkResult(wThreads[j], null);
+                checkResult(reader, null);
+            }
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // Multiple readers single writer
+        //----------------------------------------------------------------
+        try {
+            StampedLock sl = new StampedLock();
+            Phaser gate = new Phaser(102);
+            Iterator<Writer> writers = writerIterator(sl, gate);
+            Iterator<Reader> readers = readerIterator(sl, gate);
+            for (int i = 0; i < 10; i++) {
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(!sl.tryUnlockRead());
+                check(!sl.tryUnlockWrite());
+                check(sl.tryOptimisticRead() != 0L);
+                Locker[] rThreads = new Locker[100];;
+                for (int j=0; j<100; j++)
+                    rThreads[j] = readers.next();
+                for (int j=0; j<100; j++)
+                    rThreads[j].start();
+                Writer writer = writers.next(); writer.start();
+                toTheStartingGate(gate);
+                writer.join();
+                for (int j=0; j<100; j++)
+                    rThreads[j].join();
+                for (int j=0; j<100; j++)
+                    checkResult(rThreads[j], null);
+                checkResult(writer, null);
+            }
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // thread interrupted
+        //----------------------------------------------------------------
+        try {
+            boolean view = false;
+            StampedLock sl = new StampedLock();
+            for (long timeout : new long[] { -1L, 30L, -1L, 30L }) {
+                long stamp = sl.writeLock();
+                try {
+                    Reader r = interruptibleReader(sl, timeout, SECONDS, null, view);
+                    r.start();
+                    // allow r to block
+                    Thread.sleep(2000);
+                    r.interrupt();
+                    r.join();
+                    checkResult(r, InterruptedException.class);
+                } finally {
+                    sl.unlockWrite(stamp);
+                }
+                stamp = sl.readLock();
+                try {
+                    Writer w = interruptibleWriter(sl, timeout, SECONDS, null, view);
+                    w.start();
+                    // allow w to block
+                    Thread.sleep(2000);
+                    w.interrupt();
+                    w.join();
+                    checkResult(w, InterruptedException.class);
+                } finally {
+                    sl.unlockRead(stamp);
+                }
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(!sl.tryUnlockRead());
+                check(!sl.tryUnlockWrite());
+                check(sl.tryOptimisticRead() != 0L);
+                if (timeout == 30L)
+                    view = true;
+            }
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // timeout
+        //----------------------------------------------------------------
+        try {
+            StampedLock sl = new StampedLock();
+            for (long timeout : new long[] { 0L, 5L }) {
+                long stamp = sl.writeLock();
+                try {
+                    check(sl.tryReadLock(timeout, SECONDS) == 0L);
+                } finally {
+                    sl.unlockWrite(stamp);
+                }
+                stamp = sl.readLock();
+                try {
+                    check(sl.tryWriteLock(timeout, SECONDS) == 0L);
+                } finally {
+                    sl.unlockRead(stamp);
+                }
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(!sl.tryUnlockRead());
+                check(!sl.tryUnlockWrite());
+                check(sl.tryOptimisticRead() != 0L);
+            }
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // optimistic read
+        //----------------------------------------------------------------
+        try {
+            StampedLock sl = new StampedLock();
+            Iterator<Writer> writers = writerIterator(sl, null);
+            Iterator<Reader> readers = readerIterator(sl, null);
+            for (int i = 0; i < 10; i++) {
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(!sl.tryUnlockRead());
+                check(!sl.tryUnlockWrite());
+                long stamp = sl.tryOptimisticRead();
+                check(stamp != 0L);
+                check(sl.tryConvertToOptimisticRead(stamp) == stamp);
+                Reader r = readers.next(); r.start();
+                r.join();
+                checkResult(r, null);
+                check(sl.validate(stamp));
+                check(sl.tryConvertToOptimisticRead(stamp) == stamp);
+                Writer w = writers.next(); w.start();
+                w.join();
+                checkResult(w, null);
+                check(sl.validate(stamp) == false);
+            }
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // convert
+        //----------------------------------------------------------------
+        try {
+            StampedLock sl = new StampedLock();
+            for (int i = 0; i < 2; i++) {
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(!sl.tryUnlockRead());
+                check(!sl.tryUnlockWrite());
+                long stamp = sl.tryOptimisticRead();
+                check(stamp != 0L);
+                check((stamp = sl.tryConvertToReadLock(stamp)) != 0L);
+                check(sl.validate(stamp));
+                check(sl.isReadLocked());
+                check(sl.tryWriteLock() == 0L);
+                check(sl.tryWriteLock(1L, SECONDS) == 0L);
+                check((stamp = sl.tryConvertToWriteLock(stamp)) != 0L);
+                check(sl.validate(stamp));
+                check(!sl.isReadLocked());
+                check(sl.isWriteLocked());
+                check(sl.tryReadLock(1L, SECONDS) == 0L);
+                if (i != 0) {
+                    sl.unlockWrite(stamp);
+                    continue;
+                }
+                // convert down
+                check((stamp = sl.tryConvertToReadLock(stamp)) != 0L);
+                check(sl.validate(stamp));
+                check(sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(sl.tryWriteLock() == 0L);
+                check(sl.tryWriteLock(1L, SECONDS) == 0L);
+                check((stamp = sl.tryConvertToOptimisticRead(stamp)) != 0L);
+                check(sl.validate(stamp));
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+                check(sl.validate(stamp));
+            }
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // views
+        //----------------------------------------------------------------
+        try {
+            StampedLock sl = new StampedLock();
+
+            Lock rl = sl.asReadLock();
+            Lock wl = sl.asWriteLock();
+            for (int i = 0; i < 2; i++) {
+                rl.lock();
+                try {
+                    check(sl.isReadLocked());
+                    check(!sl.isWriteLocked());
+                    check(sl.tryWriteLock() == 0L);
+                    check(sl.tryWriteLock(1L, SECONDS) == 0L);
+                } finally {
+                    rl.unlock();
+                }
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+
+                wl.lock();
+                try {
+                    check(!sl.isReadLocked());
+                    check(sl.isWriteLocked());
+                    check(sl.tryWriteLock() == 0L);
+                    check(sl.tryWriteLock(1L, SECONDS) == 0L);
+                } finally {
+                    wl.unlock();
+                }
+                check(!sl.isReadLocked());
+                check(!sl.isWriteLocked());
+
+                ReadWriteLock rwl = sl.asReadWriteLock();
+                rl = rwl.readLock();
+                wl = rwl.writeLock();
+            }
+        } catch (Throwable t) { unexpected(t); }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void check(boolean cond) {if (cond) pass(); else fail();}
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/jdk/test/java/util/logging/Reflect.java b/jdk/test/java/util/logging/Reflect.java
new file mode 100644
index 0000000..393868f
--- /dev/null
+++ b/jdk/test/java/util/logging/Reflect.java
@@ -0,0 +1,44 @@
+/*
+ * 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 8004931
+ * @summary Invoke getDeclaredMethods on LogManager to ensure that
+ *    all types referenced in the method signatures is present.
+ */
+
+import java.util.logging.LogManager;
+import java.lang.reflect.Method;
+
+public class Reflect {
+    static void printMethods(Class<?> c) {
+        System.out.println(c);
+        for (Method m: c.getDeclaredMethods()) {
+            System.out.println("    " + m);
+        }
+    }
+    public static void main(String[] args) {
+        printMethods(java.util.logging.LogManager.class);
+        printMethods(java.util.logging.LogManager.getLogManager().getClass());
+    }
+}
diff --git a/jdk/test/javax/management/remote/mandatory/connection/NoIIOP.java b/jdk/test/javax/management/remote/mandatory/connection/NoIIOP.java
new file mode 100644
index 0000000..14858b1
--- /dev/null
+++ b/jdk/test/javax/management/remote/mandatory/connection/NoIIOP.java
@@ -0,0 +1,141 @@
+/*
+ * 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 8004502
+ * @summary Sanity check that attempts to use the IIOP transport or
+ *   RMIIIOPServerImpl when RMI/IIOP not present throws the expected exceptions
+ */
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.remote.*;
+import javax.management.remote.rmi.*;
+import java.net.MalformedURLException;
+import java.io.IOException;
+import javax.security.auth.Subject;
+import java.rmi.NoSuchObjectException;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServerFactory;
+
+public class NoIIOP {
+
+    /**
+     * RMIIIOPServerImpl implementation for testing purposes (methods are
+     * overridden to be public to allow for testing)
+     */
+    static class MyRMIIIOPServerImpl extends RMIIIOPServerImpl {
+        MyRMIIIOPServerImpl() throws IOException {
+            super(null);
+        }
+        @Override
+        public void export() throws IOException {
+            super.export();
+        }
+        @Override
+        public String getProtocol() {
+            return super.getProtocol();
+        }
+        @Override
+        public RMIConnection makeClient(String connectionId, Subject subject)
+            throws IOException
+        {
+            return super.makeClient(connectionId, subject);
+        }
+        @Override
+        public void closeClient(RMIConnection client) throws IOException {
+            super.closeClient(client);
+        }
+        @Override
+        public void closeServer() throws IOException {
+            super.closeServer();
+        }
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Class.forName("javax.management.remote.rmi._RMIConnectionImpl_Tie");
+            System.out.println("RMI/IIOP appears to be supported, test skipped");
+            return;
+        } catch (ClassNotFoundException okay) { }
+
+        JMXServiceURL url = new JMXServiceURL("service:jmx:iiop://");
+        MBeanServer mbs = MBeanServerFactory.createMBeanServer();
+
+
+        // test JMXConnectorFactory/JMXConnectorServerFactory
+
+        try {
+            JMXConnectorFactory.connect(url);
+            throw new RuntimeException("connect did not throw MalformedURLException");
+        } catch (MalformedURLException expected) { }
+
+        try {
+            JMXConnectorServerFactory.newJMXConnectorServer(url, null, null);
+            throw new RuntimeException("newJMXConnectorServer did not throw MalformedURLException");
+        } catch (MalformedURLException expected) { }
+
+
+        // test RMIConnector/RMIConnectorServer
+
+        RMIConnector connector = new RMIConnector(url, null);
+        try {
+            connector.connect();
+            throw new RuntimeException("connect did not throw IOException");
+        } catch (IOException expected) { }
+
+        RMIConnectorServer server = new RMIConnectorServer(url, null, mbs);
+        try {
+            server.start();
+            throw new RuntimeException("start did not throw IOException");
+        } catch (IOException expected) { }
+
+
+        // test RMIIIOPServerImpl
+
+        MyRMIIIOPServerImpl impl = new MyRMIIIOPServerImpl();
+        impl.setMBeanServer(mbs);
+        System.out.println(impl.getProtocol());
+
+        try {
+            impl.export();
+            throw new RuntimeException("export did not throw IOException");
+        } catch (IOException expected) { }
+
+        try {
+            impl.newClient(null);
+            throw new RuntimeException("newClient did not throw IOException");
+        } catch (IOException expected) { }
+
+        try {
+            impl.toStub();
+            throw new RuntimeException("toStub did not throw NoSuchObjectException");
+        } catch (NoSuchObjectException expected) { }
+
+        try {
+            impl.closeServer();
+            throw new RuntimeException("closeServer did not throw NoSuchObjectException");
+        } catch (NoSuchObjectException expected) { }
+    }
+}
diff --git a/jdk/test/javax/naming/InitialContext/NoApplet.java b/jdk/test/javax/naming/InitialContext/NoApplet.java
new file mode 100644
index 0000000..0c6969c
--- /dev/null
+++ b/jdk/test/javax/naming/InitialContext/NoApplet.java
@@ -0,0 +1,42 @@
+/*
+ * 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 8004502
+ * @summary Sanity check that specifying the APPLET property when creating an
+ *   InitialContext behaves as expected when java.awt.Applet is not present
+ */
+
+import javax.naming.*;
+import java.util.Hashtable;
+
+public class NoApplet {
+    public static void main(String[] args) throws NamingException {
+         Hashtable<Object,Object> env = new Hashtable<>();
+         env.put(Context.APPLET, new Object());
+         try {
+             Context ctxt = new InitialContext(env);
+             throw new RuntimeException("ClassCastException expected");
+         } catch (ClassCastException expected) { }
+    }
+}
diff --git a/jdk/test/javax/swing/JComboBox/4199622/bug4199622.java b/jdk/test/javax/swing/JComboBox/4199622/bug4199622.java
new file mode 100644
index 0000000..2c7dedd
--- /dev/null
+++ b/jdk/test/javax/swing/JComboBox/4199622/bug4199622.java
@@ -0,0 +1,243 @@
+/*
+ * 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 4199622
+   @summary RFE: JComboBox shouldn't send ActionEvents for keyboard navigation
+   @author Vladislav Karnaukhov
+   @run main bug4199622
+*/
+
+import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
+import sun.awt.OSInfo;
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.lang.reflect.InvocationTargetException;
+
+public class bug4199622 extends JFrame implements ActionListener {
+
+    static final int nElems = 20;
+    static JComboBox<String> cb = null;
+
+    bug4199622(LookAndFeel laf) {
+        super();
+
+        try {
+            UIManager.setLookAndFeel(laf);
+        } catch (UnsupportedLookAndFeelException e) {
+            throw new RuntimeException("Test failed", e);
+        }
+
+        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+        cb = new JComboBox<>();
+        for (int i = 0; i < nElems; i++) {
+            cb.addItem(String.valueOf(i + 1));
+        }
+        cb.addActionListener(this);
+        add(cb);
+
+        setSize(300, 300);
+        pack();
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (UIManager.getBoolean("ComboBox.noActionOnKeyNavigation") && cb.isPopupVisible()) {
+            throw new RuntimeException("Test failed. actionPerformed generated");
+        }
+    }
+
+    static Robot robot = null;
+    static SunToolkit toolkit = null;
+
+    static void doTest() {
+        if (robot == null) {
+            try {
+                robot = new Robot();
+                robot.setAutoDelay(20);
+            } catch (AWTException e) {
+                throw new RuntimeException("Can't create robot. Test failed", e);
+            }
+        }
+
+        toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        if (toolkit == null) {
+            throw new RuntimeException("Can't get the toolkit. Test failed");
+        }
+        toolkit.realSync();
+
+        doActualTest();
+
+        try {
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    cb.hidePopup();
+                    cb.setEditable(true);
+                    cb.updateUI();
+                }
+            });
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Test failed", e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException("Test failed", e);
+        }
+
+        toolkit.realSync();
+        doActualTest();
+    }
+
+    static void doActualTest() {
+        UIManager.put("ComboBox.noActionOnKeyNavigation", true);
+        doTestUpDown();
+        UIManager.put("ComboBox.noActionOnKeyNavigation", false);
+        doTestUpDown();
+
+        UIManager.put("ComboBox.noActionOnKeyNavigation", true);
+        doTestPgUpDown();
+        UIManager.put("ComboBox.noActionOnKeyNavigation", false);
+        doTestPgUpDown();
+
+        UIManager.put("ComboBox.noActionOnKeyNavigation", true);
+        doTestHomeEnd();
+        UIManager.put("ComboBox.noActionOnKeyNavigation", false);
+        doTestHomeEnd();
+    }
+
+    static void doTestHomeEnd() {
+        try {
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    cb.hidePopup();
+                    cb.setSelectedIndex(0);
+                }
+            });
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Test failed", e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException("Test failed", e);
+        }
+        toolkit.realSync();
+
+        robot.keyPress(KeyEvent.VK_END);
+        toolkit.realSync();
+        robot.keyPress(KeyEvent.VK_HOME);
+        toolkit.realSync();
+    }
+
+    static void doTestUpDown() {
+        try {
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    cb.hidePopup();
+                    cb.setSelectedIndex(0);
+                }
+            });
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Test failed", e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException("Test failed", e);
+        }
+        toolkit.realSync();
+
+        for (int i = 0; i < nElems; i++) {
+            robot.keyPress(KeyEvent.VK_DOWN);
+            toolkit.realSync();
+        }
+
+        for (int i = 0; i < nElems; i++) {
+            robot.keyPress(KeyEvent.VK_UP);
+            toolkit.realSync();
+        }
+    }
+
+    static void doTestPgUpDown() {
+        try {
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    cb.hidePopup();
+                    cb.setSelectedIndex(0);
+                }
+            });
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Test failed", e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException("Test failed", e);
+        }
+        toolkit.realSync();
+
+        int listHeight = cb.getMaximumRowCount();
+        for (int i = 0; i < nElems; i += listHeight) {
+            robot.keyPress(KeyEvent.VK_PAGE_DOWN);
+            toolkit.realSync();
+        }
+
+        for (int i = 0; i < nElems; i += listHeight) {
+            robot.keyPress(KeyEvent.VK_PAGE_UP);
+            toolkit.realSync();
+        }
+    }
+
+    public static void main(String[] args) {
+        try {
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    bug4199622 test = new bug4199622(new MetalLookAndFeel());
+                    test.setVisible(true);
+                }
+            });
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Test failed", e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException("Test failed", e);
+        }
+        doTest();
+
+        if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS) {
+            try {
+                SwingUtilities.invokeAndWait(new Runnable() {
+                    @Override
+                    public void run() {
+                        bug4199622 test = new bug4199622(new WindowsLookAndFeel());
+                        test.setVisible(true);
+                    }
+                });
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Test failed", e);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException("Test failed", e);
+            }
+            doTest();
+        }
+    }
+}
diff --git a/jdk/test/javax/swing/JLabel/6596966/bug6596966.java b/jdk/test/javax/swing/JLabel/6596966/bug6596966.java
index 5e94459..361cebc 100644
--- a/jdk/test/javax/swing/JLabel/6596966/bug6596966.java
+++ b/jdk/test/javax/swing/JLabel/6596966/bug6596966.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -24,16 +24,17 @@
 /* @test
    @bug 6596966
    @summary Some JFileChooser mnemonics do not work with sticky keys
+   @library ../../regtesthelpers
+   @build Util
    @run main bug6596966
    @author Pavel Porvatov
 */
 
-
-import sun.awt.SunToolkit;
-
-import javax.swing.*;
 import java.awt.*;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import javax.swing.*;
+import sun.awt.SunToolkit;
 
 public class bug6596966 {
     private static JFrame frame;
@@ -71,11 +72,14 @@
 
         toolkit.realSync();
 
-        robot.keyPress(KeyEvent.VK_ALT);
+        ArrayList<Integer> keys = Util.getSystemMnemonicKeyCodes();
+        for (int i = 0; i < keys.size(); ++i) {
+            robot.keyPress(keys.get(i));
+        }
+
         robot.keyPress(KeyEvent.VK_L);
 
         toolkit.realSync();
-
         toolkit.getSystemEventQueue().postEvent(new KeyEvent(label, KeyEvent.KEY_RELEASED,
                 EventQueue.getMostRecentEventTime(), 0, KeyEvent.VK_L, 'L'));
 
@@ -90,7 +94,11 @@
                 }
             });
         } finally {
-            robot.keyRelease(KeyEvent.VK_ALT);
+            robot.keyRelease(KeyEvent.VK_L);
+            for (int i = 0; i < keys.size(); ++i) {
+                robot.keyRelease(keys.get(i));
+            }
+            toolkit.realSync();
         }
     }
 }
diff --git a/jdk/test/javax/swing/regtesthelpers/Util.java b/jdk/test/javax/swing/regtesthelpers/Util.java
index a9df493..df7ab7a 100644
--- a/jdk/test/javax/swing/regtesthelpers/Util.java
+++ b/jdk/test/javax/swing/regtesthelpers/Util.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -23,11 +23,13 @@
 
 import javax.swing.*;
 import java.awt.*;
+import java.awt.event.*;
 import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.Callable;
+import sun.swing.*;
 
 /**
  * <p>This class contains utilities useful for regression testing.
@@ -212,4 +214,33 @@
 
         return result.get(0);
     }
+    /**
+     * Gets key codes from system mnemonic key mask
+     * @return key codes list
+     */
+    public static ArrayList<Integer> getSystemMnemonicKeyCodes() {
+        return Util.getKeyCodesFromKeyMask(SwingUtilities2.getSystemMnemonicKeyMask());
+    }
+
+    /**
+     * Gets the key codes list from modifiers
+     * @param modifiers an integer combination of the modifier constants
+     * @return key codes list
+     */
+    public static ArrayList<Integer> getKeyCodesFromKeyMask(int modifiers) {
+        ArrayList<Integer> result = new ArrayList<>();
+        if ((modifiers & InputEvent.CTRL_MASK) != 0) {
+            result.add(KeyEvent.VK_CONTROL);
+        }
+        if ((modifiers & InputEvent.ALT_MASK) != 0) {
+            result.add(KeyEvent.VK_ALT);
+        }
+        if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
+            result.add(KeyEvent.VK_SHIFT);
+        }
+        if ((modifiers & InputEvent.META_MASK) != 0) {
+            result.add(KeyEvent.VK_META);
+        }
+        return result;
+    }
 }
diff --git a/jdk/test/lib/testlibrary/OutputAnalyzerTest.java b/jdk/test/lib/testlibrary/OutputAnalyzerTest.java
new file mode 100644
index 0000000..f8ad49e
--- /dev/null
+++ b/jdk/test/lib/testlibrary/OutputAnalyzerTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test the OutputAnalyzer utility class
+ * @library /testlibrary
+ */
+
+import jdk.testlibrary.OutputAnalyzer;
+
+public class OutputAnalyzerTest {
+
+    public static void main(String args[]) throws Exception {
+
+        String stdout = "aaaaaa";
+        String stderr = "bbbbbb";
+        String nonExistingString = "cccc";
+
+        OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
+
+        if (!stdout.equals(output.getStdout())) {
+            throw new Exception("getStdout() returned '" + output.getStdout()
+                    + "', expected '" + stdout + "'");
+        }
+
+        if (!stderr.equals(output.getStderr())) {
+            throw new Exception("getStderr() returned '" + output.getStderr()
+                    + "', expected '" + stderr + "'");
+        }
+
+        try {
+            output.shouldContain(stdout);
+            output.stdoutShouldContain(stdout);
+            output.shouldContain(stderr);
+            output.stderrShouldContain(stderr);
+        } catch (RuntimeException e) {
+            throw new Exception("shouldContain() failed", e);
+        }
+
+        try {
+            output.shouldContain(nonExistingString);
+            throw new Exception("shouldContain() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.stdoutShouldContain(stderr);
+            throw new Exception(
+                    "stdoutShouldContain() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.stderrShouldContain(stdout);
+            throw new Exception(
+                    "stdoutShouldContain() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.shouldNotContain(nonExistingString);
+            output.stdoutShouldNotContain(nonExistingString);
+            output.stderrShouldNotContain(nonExistingString);
+        } catch (RuntimeException e) {
+            throw new Exception("shouldNotContain() failed", e);
+        }
+
+        try {
+            output.shouldNotContain(stdout);
+            throw new Exception("shouldContain() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.stdoutShouldNotContain(stdout);
+            throw new Exception("shouldContain() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.stderrShouldNotContain(stderr);
+            throw new Exception("shouldContain() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        String stdoutPattern = "[a]";
+        String stderrPattern = "[b]";
+        String nonExistingPattern = "[c]";
+
+        // Should match
+        try {
+            output.shouldMatch(stdoutPattern);
+            output.stdoutShouldMatch(stdoutPattern);
+            output.shouldMatch(stderrPattern);
+            output.stderrShouldMatch(stderrPattern);
+        } catch (RuntimeException e) {
+            throw new Exception("shouldMatch() failed", e);
+        }
+
+        try {
+            output.shouldMatch(nonExistingPattern);
+            throw new Exception("shouldMatch() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.stdoutShouldMatch(stderrPattern);
+            throw new Exception(
+                    "stdoutShouldMatch() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.stderrShouldMatch(stdoutPattern);
+            throw new Exception(
+                    "stderrShouldMatch() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        // Should not match
+        try {
+            output.shouldNotMatch(nonExistingPattern);
+            output.stdoutShouldNotMatch(nonExistingPattern);
+            output.stderrShouldNotMatch(nonExistingPattern);
+        } catch (RuntimeException e) {
+            throw new Exception("shouldNotMatch() failed", e);
+        }
+
+        try {
+            output.shouldNotMatch(stdoutPattern);
+            throw new Exception("shouldNotMatch() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.stdoutShouldNotMatch(stdoutPattern);
+            throw new Exception("shouldNotMatch() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        try {
+            output.stderrShouldNotMatch(stderrPattern);
+            throw new Exception("shouldNotMatch() failed to throw exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+    }
+
+}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java b/jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
new file mode 100644
index 0000000..de5807f
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.util.ArrayList;
+
+public class JcmdBase {
+
+    private static ProcessBuilder processBuilder = new ProcessBuilder();
+
+    /**
+     * Attach jcmd to the current process
+     *
+     * @param commandArgs
+     *            jcmd command line parameters, e.g. JFR.start
+     * @return jcmd output
+     * @throws Exception
+     */
+    public final static OutputAnalyzer jcmd(String... commandArgs)
+            throws Exception {
+        ArrayList<String> cmd = new ArrayList<String>();
+        String cmdString = "";
+
+        // jcmd from the jdk to be tested
+        String jcmdPath = JdkFinder.getTool("jcmd", false);
+        cmd.add(jcmdPath);
+        cmdString += jcmdPath;
+
+        String pid = Integer.toString(ProcessTools.getProcessId());
+        cmd.add(pid);
+        cmdString += " " + pid;
+
+        for (int i = 0; i < commandArgs.length; i++) {
+            cmd.add(commandArgs[i]);
+            cmdString += " " + commandArgs[i];
+        }
+
+        // Log command line for debugging purpose
+        System.out.println("Command line:");
+        System.out.println(cmdString);
+
+        processBuilder.command(cmd);
+        OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
+
+        // Log output for debugging purpose
+        System.out.println("Command output:");
+        System.out.println(output.getOutput());
+
+        if (output.getExitValue() != 0) {
+            throw new Exception(processBuilder.command()
+                    + " resulted in exit value " + output.getExitValue()
+                    + " , expected to get 0");
+        }
+
+        return output;
+    }
+
+}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/JdkFinder.java b/jdk/test/lib/testlibrary/jdk/testlibrary/JdkFinder.java
new file mode 100644
index 0000000..fa038fa
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JdkFinder.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.File;
+
+public final class JdkFinder {
+
+    private JdkFinder() {
+    }
+
+    private static String getExecutable(String executable, String property) {
+        String binPath = System.getProperty(property);
+        if (binPath == null) {
+            throw new RuntimeException(
+                    "System property '" + property + "' not set");
+        }
+
+        binPath += File.separatorChar + "bin" + File.separatorChar + executable;
+        File toolFile = new File(binPath);
+        if (!toolFile.exists()) {
+            throw new RuntimeException(binPath + " does not exist");
+        }
+
+        return binPath;
+    }
+
+    /**
+     * Returns the full path to a java launcher in jdk/bin based on system
+     * property.
+     *
+     * @param stableJdk
+     *            see {@link #getTool(String, boolean)}
+     * @return Full path to a java launcher in jdk/bin.
+     */
+    public static String getJavaLauncher(boolean stableJdk) {
+        return getTool("java", stableJdk);
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on system
+     * property. Depending on value of {@code stableJdk} the method will look for
+     * either 'compile.jdk' or 'test.jdk' system properties.
+     * 'test.jdk' is normally set by jtreg. When running test separately,
+     * set this property using '-Dtest.jdk=/path/to/jdk'.
+     *
+     * @param stableJdk
+     *            If {@code true} the {@code tool} will be retrieved
+     *            from the compile (stable) JDK.
+     *            If {@code false} the {@code tool} will be retrieved
+     *            from the test JDK.
+     * @return Full path to an executable in jdk/bin.
+     */
+    public static String getTool(String tool, boolean stableJdk) {
+        if (stableJdk) {
+            return getExecutable(tool, "compile.jdk");
+        } else {
+            return getExecutable(tool, "test.jdk");
+        }
+    }
+}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java b/jdk/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
new file mode 100644
index 0000000..ba02081
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class OutputAnalyzer {
+
+    private final String stdout;
+    private final String stderr;
+    private final int exitValue;
+
+    /**
+     * Create an OutputAnalyzer, a utility class for verifying output and exit
+     * value from a Process
+     *
+     * @param process
+     *            Process to analyze
+     * @throws IOException
+     *             If an I/O error occurs.
+     */
+    public OutputAnalyzer(Process process) throws IOException {
+        OutputBuffer output = ProcessTools.getOutput(process);
+        exitValue = process.exitValue();
+        this.stdout = output.getStdout();
+        this.stderr = output.getStderr();
+    }
+
+    /**
+     * Create an OutputAnalyzer, a utility class for verifying output
+     *
+     * @param buf
+     *            String buffer to analyze
+     */
+    public OutputAnalyzer(String buf) {
+        this(buf, buf);
+    }
+
+    /**
+     * Create an OutputAnalyzer, a utility class for verifying output
+     *
+     * @param stdout
+     *            stdout buffer to analyze
+     * @param stderr
+     *            stderr buffer to analyze
+     */
+    public OutputAnalyzer(String stdout, String stderr) {
+        this.stdout = stdout;
+        this.stderr = stderr;
+        exitValue = -1;
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer contains the
+     * string
+     *
+     * @param expectedString
+     *            String that buffer should contain
+     * @throws RuntimeException
+     *             If the string was not found
+     */
+    public void shouldContain(String expectedString) {
+        if (!stdout.contains(expectedString)
+                && !stderr.contains(expectedString)) {
+            throw new RuntimeException("'" + expectedString
+                    + "' missing from stdout/stderr: [" + stdout + stderr
+                    + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer contains the string
+     *
+     * @param expectedString
+     *            String that buffer should contain
+     * @throws RuntimeException
+     *             If the string was not found
+     */
+    public void stdoutShouldContain(String expectedString) {
+        if (!stdout.contains(expectedString)) {
+            throw new RuntimeException("'" + expectedString
+                    + "' missing from stdout: [" + stdout + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer contains the string
+     *
+     * @param expectedString
+     *            String that buffer should contain
+     * @throws RuntimeException
+     *             If the string was not found
+     */
+    public void stderrShouldContain(String expectedString) {
+        if (!stderr.contains(expectedString)) {
+            throw new RuntimeException("'" + expectedString
+                    + "' missing from stderr: [" + stderr + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer does not
+     * contain the string
+     *
+     * @param expectedString
+     *            String that the buffer should not contain
+     * @throws RuntimeException
+     *             If the string was found
+     */
+    public void shouldNotContain(String notExpectedString) {
+        if (stdout.contains(notExpectedString)) {
+            throw new RuntimeException("'" + notExpectedString
+                    + "' found in stdout: [" + stdout + "]\n");
+        }
+        if (stderr.contains(notExpectedString)) {
+            throw new RuntimeException("'" + notExpectedString
+                    + "' found in stderr: [" + stderr + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer does not contain the
+     * string
+     *
+     * @param expectedString
+     *            String that the buffer should not contain
+     * @throws RuntimeException
+     *             If the string was found
+     */
+    public void stdoutShouldNotContain(String notExpectedString) {
+        if (stdout.contains(notExpectedString)) {
+            throw new RuntimeException("'" + notExpectedString
+                    + "' found in stdout: [" + stdout + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer does not contain the
+     * string
+     *
+     * @param expectedString
+     *            String that the buffer should not contain
+     * @throws RuntimeException
+     *             If the string was found
+     */
+    public void stderrShouldNotContain(String notExpectedString) {
+        if (stderr.contains(notExpectedString)) {
+            throw new RuntimeException("'" + notExpectedString
+                    + "' found in stderr: [" + stderr + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer matches
+     * the pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was not found
+     */
+    public void shouldMatch(String pattern) {
+        Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (!stdoutMatcher.find() && !stderrMatcher.find()) {
+            throw new RuntimeException("'" + pattern
+                    + "' missing from stdout/stderr: [" + stdout + stderr
+                    + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer matches the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was not found
+     */
+    public void stdoutShouldMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        if (!matcher.find()) {
+            throw new RuntimeException("'" + pattern
+                    + "' missing from stdout: [" + stdout + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer matches the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was not found
+     */
+    public void stderrShouldMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (!matcher.find()) {
+            throw new RuntimeException("'" + pattern
+                    + "' missing from stderr: [" + stderr + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer does not
+     * match the pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was found
+     */
+    public void shouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        if (matcher.find()) {
+            throw new RuntimeException("'" + pattern
+                    + "' found in stdout: [" + stdout + "]\n");
+        }
+        matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (matcher.find()) {
+            throw new RuntimeException("'" + pattern
+                    + "' found in stderr: [" + stderr + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer does not match the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was found
+     */
+    public void stdoutShouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        if (matcher.find()) {
+            throw new RuntimeException("'" + pattern
+                    + "' found in stdout: [" + stdout + "]\n");
+        }
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer does not match the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException If the pattern was found
+     */
+    public void stderrShouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        if (matcher.find()) {
+            throw new RuntimeException("'" + pattern
+                    + "' found in stderr: [" + stderr + "]\n");
+        }
+    }
+
+    /**
+     * Verifiy the exit value of the process
+     *
+     * @param expectedExitValue
+     *            Expected exit value from process
+     * @throws RuntimeException
+     *             If the exit value from the process did not match the expected
+     *             value
+     */
+    public void shouldHaveExitValue(int expectedExitValue) {
+        if (getExitValue() != expectedExitValue) {
+            throw new RuntimeException("Exit value " + getExitValue()
+                    + " , expected to get " + expectedExitValue);
+        }
+    }
+
+    /**
+     * Get the contents of the output buffer (stdout and stderr)
+     *
+     * @return Content of the output buffer
+     */
+    public String getOutput() {
+        return stdout + stderr;
+    }
+
+    /**
+     * Get the contents of the stdout buffer
+     *
+     * @return Content of the stdout buffer
+     */
+    public String getStdout() {
+        return stdout;
+    }
+
+    /**
+     * Get the contents of the stderr buffer
+     *
+     * @return Content of the stderr buffer
+     */
+    public String getStderr() {
+        return stderr;
+    }
+
+    /**
+     * Get the process exit value
+     *
+     * @return Process exit value
+     */
+    public int getExitValue() {
+        return exitValue;
+    }
+}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/OutputBuffer.java b/jdk/test/lib/testlibrary/jdk/testlibrary/OutputBuffer.java
new file mode 100644
index 0000000..b5e021e
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/OutputBuffer.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+public class OutputBuffer {
+    private final String stdout;
+    private final String stderr;
+
+    /**
+     * Create an OutputBuffer, a class for storing and managing stdout and
+     * stderr results separately
+     *
+     * @param stdout
+     *            stdout result
+     * @param stderr
+     *            stderr result
+     */
+    public OutputBuffer(String stdout, String stderr) {
+        this.stdout = stdout;
+        this.stderr = stderr;
+    }
+
+    /**
+     * Returns the stdout result
+     *
+     * @return stdout result
+     */
+    public String getStdout() {
+        return stdout;
+    }
+
+    /**
+     * Returns the stderr result
+     *
+     * @return stderr result
+     */
+    public String getStderr() {
+        return stderr;
+    }
+}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
new file mode 100644
index 0000000..16783ae
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import sun.management.VMManagement;
+
+public final class ProcessTools {
+
+    private ProcessTools() {
+    }
+
+    /**
+     * Pumps stdout and stderr from running the process into a String.
+     *
+     * @param processHandler
+     *            ProcessHandler to run.
+     * @return Output from process.
+     * @throws IOException
+     *             If an I/O error occurs.
+     */
+    public static OutputBuffer getOutput(ProcessBuilder processBuilder)
+            throws IOException {
+        return getOutput(processBuilder.start());
+    }
+
+    /**
+     * Pumps stdout and stderr the running process into a String.
+     *
+     * @param process
+     *            Process to pump.
+     * @return Output from process.
+     * @throws IOException
+     *             If an I/O error occurs.
+     */
+    public static OutputBuffer getOutput(Process process) throws IOException {
+        ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream();
+        ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream();
+        StreamPumper outPumper = new StreamPumper(process.getInputStream(),
+                stdoutBuffer);
+        StreamPumper errPumper = new StreamPumper(process.getErrorStream(),
+                stderrBuffer);
+        Thread outPumperThread = new Thread(outPumper);
+        Thread errPumperThread = new Thread(errPumper);
+
+        outPumperThread.setDaemon(true);
+        errPumperThread.setDaemon(true);
+
+        outPumperThread.start();
+        errPumperThread.start();
+
+        try {
+            process.waitFor();
+            outPumperThread.join();
+            errPumperThread.join();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            return null;
+        }
+
+        return new OutputBuffer(stdoutBuffer.toString(),
+                stderrBuffer.toString());
+    }
+
+    /**
+     * Get the process id of the current running Java process
+     *
+     * @return Process id
+     */
+    public static int getProcessId() throws Exception {
+
+        // Get the current process id using a reflection hack
+        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+        Field jvm = runtime.getClass().getDeclaredField("jvm");
+
+        jvm.setAccessible(true);
+        VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+
+        Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
+
+        pid_method.setAccessible(true);
+
+        int pid = (Integer) pid_method.invoke(mgmt);
+
+        return pid;
+    }
+
+    /**
+     * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
+     *
+     * @return String[] with platform specific arguments, empty if there are
+     *         none
+     */
+    public static String[] getPlatformSpecificVMArgs() {
+        String osName = System.getProperty("os.name");
+        String dataModel = System.getProperty("sun.arch.data.model");
+
+        if (osName.equals("SunOS") && dataModel.equals("64")) {
+            return new String[] { "-d64" };
+        }
+
+        return new String[] {};
+    }
+
+    /**
+     * Create ProcessBuilder using the java launcher from the jdk to be tested
+     * and with any platform specific arguments prepended
+     */
+    public static ProcessBuilder createJavaProcessBuilder(String... command)
+            throws Exception {
+        String javapath = JdkFinder.getJavaLauncher(false);
+
+        ArrayList<String> args = new ArrayList<>();
+        args.add(javapath);
+        Collections.addAll(args, getPlatformSpecificVMArgs());
+        Collections.addAll(args, command);
+
+        return new ProcessBuilder(args.toArray(new String[args.size()]));
+
+    }
+
+}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java b/jdk/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java
new file mode 100644
index 0000000..60adca4
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+public final class StreamPumper implements Runnable {
+
+    private static final int BUF_SIZE = 256;
+
+    private final OutputStream out;
+    private final InputStream in;
+
+    /**
+     * Create a StreamPumper that reads from in and writes to out.
+     *
+     * @param in
+     *            The stream to read from.
+     * @param out
+     *            The stream to write to.
+     */
+    public StreamPumper(InputStream in, OutputStream out) {
+        this.in = in;
+        this.out = out;
+    }
+
+    /**
+     * Implements Thread.run(). Continuously read from {@code in} and write to
+     * {@code out} until {@code in} has reached end of stream. Abort on
+     * interruption. Abort on IOExceptions.
+     */
+    @Override
+    public void run() {
+        int length;
+        InputStream localIn = in;
+        OutputStream localOut = out;
+        byte[] buffer = new byte[BUF_SIZE];
+
+        try {
+            while ((length = localIn.read(buffer)) > 0 && !Thread.interrupted()) {
+                localOut.write(buffer, 0, length);
+            }
+        } catch (IOException e) {
+            // Just abort if something like this happens.
+            e.printStackTrace();
+        } finally {
+            try {
+                localOut.flush();
+                in.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/jdk/test/sun/management/jdp/JdpTest.sh b/jdk/test/sun/management/jdp/JdpTest.sh
index 2aded72..dfdea7c 100644
--- a/jdk/test/sun/management/jdp/JdpTest.sh
+++ b/jdk/test/sun/management/jdp/JdpTest.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/sh -x
 
 # Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -23,7 +23,7 @@
 
 # @test
 # @bug 7169888 
-# @build JdpUnitTest JdpClient JdpDoSomething 
+# @compile -XDignore.symbol.file JdpUnitTest.java JdpClient.java JdpDoSomething.java 
 # @run shell JdpTest.sh --jtreg --no-compile
 # @summary No word Failed expected in the test output
 
@@ -45,9 +45,13 @@
 _last_pid=""
 
 
-_compile(){
+_do_compile(){
+    # If the test run without JTReg, we have to compile it by our self
+    # Under JTReg see @compile statement above
+    # sun.* packages is not included to symbol file lib/ct.sym so we have 
+    # to ignore it
 
-    if [ ! -e ${_testclasses} ]
+    if [ ! -d ${_testclasses} ]
     then
 	  mkdir -p ${_testclasses}
     fi   
@@ -55,12 +59,13 @@
     rm -f ${_testclasses}/*.class
 
     # Compile testcase
-    ${TESTJAVA}/bin/javac -d ${_testclasses} JdpUnitTest.java \
+    ${COMPILEJAVA}/bin/javac -XDignore.symbol.file -d ${_testclasses} \
+                                             JdpUnitTest.java \
                                              JdpDoSomething.java  \
                                              JdpClient.java
 
    
-    if [ ! -e ${_testclasses}/JdpDoSomething.class -o ! -e ${_testclasses}/JdpClient.class -o ! -e ${_testclasses}/JdpUnitTest.class ]
+    if [ ! -f ${_testclasses}/JdpDoSomething.class -o ! -f ${_testclasses}/JdpClient.class -o ! -f ${_testclasses}/JdpUnitTest.class ]
     then
       echo "ERROR: Can't compile"
       exit -1
@@ -266,6 +271,13 @@
   exit
 fi
 
+# COMPILEJAVA variable is set when we test jre
+if [ "x${COMPILEJAVA}" = "x" ]
+then
+   COMPILEJAVA="${TESTJAVA}"
+fi
+
+
 #------------------------------------------------------------------------------
 # reading parameters 
 
@@ -283,12 +295,12 @@
  esac 
 done
 
-if [ ${_compile} = "yes" ]
+if [ "${_compile}" = "yes" ]
 then
- _compile
+ _do_compile
 fi
 
-if [ ${_jtreg} = "yes" ]
+if [ "${_jtreg}" = "yes" ]
 then
  _testclasses=${TESTCLASSES}
  _testsrc=${TESTSRC}
@@ -297,7 +309,7 @@
 
 # Make sure _tesclasses is absolute path
 tt=`echo ${_testclasses} | sed -e 's,/,,'`
-if [ ${tt} = ${_testclasses} ]
+if [ "${tt}" = "${_testclasses}" ]
 then
   _testclasses="${_pwd}/${_testclasses}"
 fi
@@ -307,7 +319,7 @@
 rm -f ${_logname}
 rm -f ${_policyname}
 
-if [ -e ${_testsrc}/policy.tpl ]
+if [ -f ${_testsrc}/policy.tpl ]
 then
 
 cat ${_testsrc}/policy.tpl | \
diff --git a/jdk/test/sun/net/www/protocol/http/NoNTLM.java b/jdk/test/sun/net/www/protocol/http/NoNTLM.java
new file mode 100644
index 0000000..d6f9f74
--- /dev/null
+++ b/jdk/test/sun/net/www/protocol/http/NoNTLM.java
@@ -0,0 +1,240 @@
+/*
+ * 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 8004502
+ * @summary Sanity check that NTLM will not be selected by the http protocol
+ *    handler when running on a profile that does not support NTLM
+ * @run main/othervm NoNTLM
+ */
+
+import java.net.*;
+import java.io.*;
+import sun.net.www.MessageHeader;
+
+public class NoNTLM {
+
+    static final String CRLF = "\r\n";
+
+    static final String OKAY =
+        "HTTP/1.1 200" + CRLF +
+        "Content-Length: 0" + CRLF +
+        "Connection: close" + CRLF +
+        CRLF;
+
+    static class Client implements Runnable {
+        private final URL url;
+        private volatile IOException ioe;
+        private volatile int respCode;
+
+        Client(int port) throws IOException {
+            this.url = new URL("http://127.0.0.1:" + port + "/foo.html");
+        }
+
+        public void run() {
+            try {
+                HttpURLConnection uc =
+                    (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
+                try {
+                    uc.getInputStream();
+                } catch (IOException x) {
+                    respCode = uc.getResponseCode();
+                    throw x;
+                }
+                uc.disconnect();
+            } catch (IOException x) {
+                if (respCode == 0)
+                    respCode = -1;
+                ioe = x;
+            }
+        }
+
+        IOException ioException() {
+            return ioe;
+        }
+
+        int respCode() {
+            return respCode;
+        }
+
+        static void start(int port) throws IOException {
+            Client client = new Client(port);
+            new Thread(client).start();
+        }
+    }
+
+    /**
+     * Return the http response with WWW-Authenticate headers for the given
+     * authentication schemes.
+     */
+    static String authReplyFor(String... schemes) {
+        // construct the server reply
+        String reply = "HTTP/1.1 401 Unauthorized" + CRLF +
+                       "Content-Length: 0"+ CRLF +
+                       "Connection: close" + CRLF;
+        for (String s: schemes) {
+            switch (s) {
+                case "Basic" :
+                    reply += "WWW-Authenticate: Basic realm=\"wallyworld\"" + CRLF;
+                    break;
+                case "Digest" :
+                    reply += "WWW-Authenticate: Digest" +
+                             " realm=\"wallyworld\"" +
+                             " domain=/" +
+                             " nonce=\"abcdefghijklmnopqrstuvwxyz\"" +
+                             " qop=\"auth\"" + CRLF;
+                    break;
+                case "NTLM" :
+                    reply += "WWW-Authenticate: NTLM" + CRLF;
+                    break;
+                default :
+                    throw new RuntimeException("Should not get here");
+            }
+        }
+        reply += CRLF;
+        return reply;
+    }
+
+    /**
+     * Test the http protocol handler with the given authentication schemes
+     * in the WWW-Authenticate header.
+     */
+    static void test(String... schemes) throws IOException {
+
+        // the authentication scheme that the client is expected to choose
+        String expected = null;
+        for (String s: schemes) {
+            if (expected == null) {
+                expected = s;
+            } else if (s.equals("Digest")) {
+                expected = s;
+            }
+        }
+
+        // server reply
+        String reply = authReplyFor(schemes);
+
+        System.out.println("====================================");
+        System.out.println("Expect client to choose: " + expected);
+        System.out.println(reply);
+
+        try (ServerSocket ss = new ServerSocket(0)) {
+            Client.start(ss.getLocalPort());
+
+            // client ---- GET ---> server
+            // client <--- 401 ---- server
+            try (Socket s = ss.accept()) {
+                new MessageHeader().parseHeader(s.getInputStream());
+                s.getOutputStream().write(reply.getBytes("US-ASCII"));
+            }
+
+            // client ---- GET ---> server
+            // client <--- 200 ---- server
+            String auth;
+            try (Socket s = ss.accept()) {
+                MessageHeader mh = new MessageHeader();
+                mh.parseHeader(s.getInputStream());
+                s.getOutputStream().write(OKAY.getBytes("US-ASCII"));
+                auth = mh.findValue("Authorization");
+            }
+
+            // check Authorization header
+            if (auth == null)
+                throw new RuntimeException("Authorization header not found");
+            System.out.println("Server received Authorization header: " + auth);
+            String[] values = auth.split(" ");
+            if (!values[0].equals(expected))
+                throw new RuntimeException("Unexpected value");
+        }
+    }
+
+    /**
+     * Test the http protocol handler with one WWW-Authenticate header with
+     * the value "NTLM".
+     */
+    static void testNTLM() throws Exception {
+        // server reply
+        String reply = authReplyFor("NTLM");
+
+        System.out.println("====================================");
+        System.out.println("Expect client to fail with 401 Unauthorized");
+        System.out.println(reply);
+
+        try (ServerSocket ss = new ServerSocket(0)) {
+            Client client = new Client(ss.getLocalPort());
+            Thread thr = new Thread(client);
+            thr.start();
+
+            // client ---- GET ---> server
+            // client <--- 401 ---- client
+            try (Socket s = ss.accept()) {
+                new MessageHeader().parseHeader(s.getInputStream());
+                s.getOutputStream().write(reply.getBytes("US-ASCII"));
+            }
+
+            // the client should fail with 401
+            System.out.println("Waiting for client to terminate");
+            thr.join();
+            IOException ioe = client.ioException();
+            if (ioe != null)
+                System.out.println("Client failed: " + ioe);
+            int respCode = client.respCode();
+            if (respCode != 0 && respCode != -1)
+                System.out.println("Client received HTTP response code: " + respCode);
+            if (respCode != HttpURLConnection.HTTP_UNAUTHORIZED)
+                throw new RuntimeException("Unexpected response code");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        // assume NTLM is not supported when Kerberos is not available
+        try {
+            Class.forName("javax.security.auth.kerberos.KerberosPrincipal");
+            System.out.println("Kerberos is present, assuming NTLM is supported too");
+            return;
+        } catch (ClassNotFoundException okay) { }
+
+        // setup Authenticator
+        Authenticator.setDefault(new Authenticator() {
+            @Override
+            protected PasswordAuthentication getPasswordAuthentication() {
+                return new PasswordAuthentication("user", "pass".toCharArray());
+            }
+        });
+
+        // test combinations of authentication schemes
+        test("Basic");
+        test("Digest");
+        test("Basic", "Digest");
+        test("Basic", "NTLM");
+        test("Digest", "NTLM");
+        test("Basic", "Digest", "NTLM");
+
+        // test NTLM only, this should fail with "401 Unauthorized"
+        testNTLM();
+
+        System.out.println();
+        System.out.println("TEST PASSED");
+    }
+}
+
diff --git a/jdk/test/sun/security/krb5/ServiceCredsCombination.java b/jdk/test/sun/security/krb5/ServiceCredsCombination.java
index 3208560..5c6ac4b 100644
--- a/jdk/test/sun/security/krb5/ServiceCredsCombination.java
+++ b/jdk/test/sun/security/krb5/ServiceCredsCombination.java
@@ -62,11 +62,38 @@
         check("b", "b", princ("a"), princ("b"), oldktab(), oldktab());
         check(null, null, princ("a"), princ("b"), oldktab(), oldktab());
         check("x", "NOCRED", princ("a"), princ("b"), oldktab(), oldktab());
+        // bound ktab
+        check("c", "c", princ("c"), ktab("c"));
+        check(null, "c", princ("c"), ktab("c"));
+        // unbound ktab
+        check("x", "x", ktab());
+        check(null, null, ktab());
+        // Two bound ktab
+        check("c1", "c1", princ("c1"), princ("c2"), ktab("c1"), ktab("c2"));
+        check("c2", "c2", princ("c1"), princ("c2"), ktab("c1"), ktab("c2"));
+        check("x", "NOCRED", princ("c1"), princ("c2"), ktab("c1"), ktab("c2"));
+        check(null, null, princ("c1"), princ("c2"), ktab("c1"), ktab("c2"));
+        // One bound, one unbound
+        check("c1", "c1", princ("c1"), ktab("c1"), ktab());
+        check("x", "x", princ("c1"), ktab("c1"), ktab());
+        check(null, null, princ("c1"), ktab("c1"), ktab());
+        // Two unbound ktab
+        check("x", "x", ktab(), ktab());
+        check(null, null, ktab(), ktab());
         // pass + old ktab
         check("a", "a", princ("a"), princ("b"), key("a"), oldktab());
         check("b", "b", princ("a"), princ("b"), key("a"), oldktab());
         check(null, null, princ("a"), princ("b"), key("a"), oldktab());
         check("x", "NOCRED", princ("a"), princ("b"), key("a"), oldktab());
+        // pass + bound ktab
+        check("a", "a", princ("a"), princ("c"), key("a"), ktab("c"));
+        check("c", "c", princ("a"), princ("c"), key("a"), ktab("c"));
+        check("x", "NOCRED", princ("a"), princ("c"), key("a"), ktab("c"));
+        check(null, null, princ("a"), princ("c"), key("a"), ktab("c"));
+        // pass + unbound ktab
+        check("a", "a", princ("a"), key("a"), ktab());
+        check("x", "x", princ("a"), key("a"), ktab());
+        check(null, null, princ("a"), key("a"), ktab());
         // Compatibility, automatically add princ for keys
         check(null, "a", key("a"));
         check("x", "NOCRED", key("a"));
@@ -130,4 +157,10 @@
     private static KeyTab oldktab() {
         return KeyTab.getInstance();
     }
+    static KeyTab ktab(String s) {
+        return KeyTab.getInstance(princ(s));
+    }
+    static KeyTab ktab() {
+        return KeyTab.getUnboundInstance();
+    }
 }
diff --git a/jdk/test/sun/security/krb5/auto/AcceptPermissions.java b/jdk/test/sun/security/krb5/auto/AcceptPermissions.java
index 3a6d422..1b562ea 100644
--- a/jdk/test/sun/security/krb5/auto/AcceptPermissions.java
+++ b/jdk/test/sun/security/krb5/auto/AcceptPermissions.java
@@ -26,7 +26,8 @@
  * @bug 9999999
  * @summary default principal can act as anyone
  * @compile -XDignore.symbol.file AcceptPermissions.java
- * @run main/othervm AcceptPermissions
+ * @run main/othervm AcceptPermissions two
+ * @run main/othervm AcceptPermissions unbound
  */
 
 import java.nio.file.Files;
@@ -83,15 +84,20 @@
     public static void main(String[] args) throws Exception {
         System.setSecurityManager(new AcceptPermissions());
         new OneKDC(null).writeJAASConf();
-        String two = "two {\n"
+        String moreEntries = "two {\n"
                 + " com.sun.security.auth.module.Krb5LoginModule required"
                 + "     principal=\"" + OneKDC.SERVER + "\" useKeyTab=true"
                 + "     isInitiator=false storeKey=true;\n"
                 + " com.sun.security.auth.module.Krb5LoginModule required"
                 + "     principal=\"" + OneKDC.BACKEND + "\" useKeyTab=true"
                 + "     isInitiator=false storeKey=true;\n"
+                + "};\n"
+                + "unbound {"
+                + " com.sun.security.auth.module.Krb5LoginModule required"
+                + "     principal=* useKeyTab=true"
+                + "     isInitiator=false storeKey=true;\n"
                 + "};\n";
-        Files.write(Paths.get(OneKDC.JAAS_CONF), two.getBytes(),
+        Files.write(Paths.get(OneKDC.JAAS_CONF), moreEntries.getBytes(),
                 StandardOpenOption.APPEND);
 
         Context c, s;
@@ -114,7 +120,7 @@
         // Named principal (even if there are 2 JAAS modules)
         initPerms(OneKDC.SERVER);
         c = Context.fromJAAS("client");
-        s = Context.fromJAAS("two");
+        s = Context.fromJAAS(args[0]);
         c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
         s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
         checkPerms();
@@ -136,7 +142,7 @@
         // Default principal with no predictable name
         initPerms();    // permission not needed for cred !!!
         c = Context.fromJAAS("client");
-        s = Context.fromJAAS("two");
+        s = Context.fromJAAS(args[0]);
         c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
         s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
         checkPerms();
diff --git a/jdk/test/sun/security/krb5/auto/GSSUnbound.java b/jdk/test/sun/security/krb5/auto/GSSUnbound.java
new file mode 100644
index 0000000..a1022d4
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/GSSUnbound.java
@@ -0,0 +1,61 @@
+/*
+ * 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 8001104
+ * @summary Unbound SASL service: the GSSAPI/krb5 mech
+ * @compile -XDignore.symbol.file GSSUnbound.java
+ * @run main/othervm GSSUnbound
+ */
+
+import java.security.Security;
+import sun.security.jgss.GSSUtil;
+
+// Testing JGSS without JAAS
+public class GSSUnbound {
+
+    public static void main(String[] args) throws Exception {
+
+        new OneKDC(null);
+
+        Context c, s;
+        c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+        s = Context.fromThinAir();
+
+        // This is the only setting needed for JGSS without JAAS. The default
+        // JAAS config entries are already created by OneKDC.
+        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
+
+        c.startAsClient(OneKDC.BACKEND, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+
+        Context.handshake(c, s);
+
+        Context.transmit("i say high --", c, s);
+        Context.transmit("   you say low", s, c);
+
+        s.dispose();
+        c.dispose();
+    }
+}
diff --git a/jdk/test/sun/security/krb5/auto/OneKDC.java b/jdk/test/sun/security/krb5/auto/OneKDC.java
index 5c87abb..90a7e8e 100644
--- a/jdk/test/sun/security/krb5/auto/OneKDC.java
+++ b/jdk/test/sun/security/krb5/auto/OneKDC.java
@@ -76,6 +76,8 @@
         Config.refresh();
 
         writeKtab(KTAB);
+        Security.setProperty("auth.login.defaultCallbackHandler",
+                "OneKDC$CallbackForClient");
     }
 
     /**
@@ -93,7 +95,7 @@
                 "    com.sun.security.auth.module.Krb5LoginModule required;\n};\n" +
                 "com.sun.security.jgss.krb5.accept {\n" +
                 "    com.sun.security.auth.module.Krb5LoginModule required\n" +
-                "    principal=\"" + SERVER + "\"\n" +
+                "    principal=\"*\"\n" +
                 "    useKeyTab=true\n" +
                 "    isInitiator=false\n" +
                 "    storeKey=true;\n};\n" +
@@ -112,7 +114,6 @@
                 "    isInitiator=false;\n};\n"
                 ).getBytes());
         fos.close();
-        Security.setProperty("auth.login.defaultCallbackHandler", "OneKDC$CallbackForClient");
     }
 
     /**
diff --git a/jdk/test/sun/security/krb5/auto/SaslUnbound.java b/jdk/test/sun/security/krb5/auto/SaslUnbound.java
new file mode 100644
index 0000000..64d9a1b
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/SaslUnbound.java
@@ -0,0 +1,113 @@
+/*
+ * 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 8001104
+ * @summary Unbound SASL service: the GSSAPI/krb5 mech
+ * @compile -XDignore.symbol.file SaslUnbound.java
+ * @run main/othervm SaslUnbound 0
+ * @run main/othervm/fail SaslUnbound 1
+ * @run main/othervm/fail SaslUnbound 2
+ * @run main/othervm/fail SaslUnbound 3
+ * @run main/othervm/fail SaslUnbound 4
+ */
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.*;
+
+public class SaslUnbound {
+
+    public static void main(String[] args) throws Exception {
+
+        String serverProtocol, serverName;
+        switch (args[0].charAt(0)) {
+            case '1':       // Using another protocol, should fail
+                serverProtocol = "serv";
+                serverName = null;
+                break;
+            case '2':       // Using another protocol, should fail
+                serverProtocol = "otherwise";
+                serverName = null;
+                break;
+            case '3':       // Using another protocol, should fail
+                serverProtocol = "otherwise";
+                serverName = "host." + OneKDC.REALM;
+                break;
+            case '4':       // Bound to another serverName, should fail.
+                serverProtocol = "server";
+                serverName = "host2." + OneKDC.REALM;
+                break;
+            default:        // Good unbound server
+                serverProtocol = "server";
+                serverName = null;
+                break;
+        }
+        new OneKDC(null).writeJAASConf();
+        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
+
+        HashMap clntprops = new HashMap();
+        clntprops.put(Sasl.QOP, "auth-conf");
+        SaslClient sc = Sasl.createSaslClient(
+                new String[]{"GSSAPI"}, null, "server",
+                "host." + OneKDC.REALM, clntprops, null);
+
+        final HashMap srvprops = new HashMap();
+        srvprops.put(Sasl.QOP, "auth,auth-int,auth-conf");
+        SaslServer ss = Sasl.createSaslServer("GSSAPI", serverProtocol,
+                serverName, srvprops,
+                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);
+                            }
+                        }
+                    }
+                });
+
+        byte[] token = new byte[0];
+        while (!sc.isComplete() || !ss.isComplete()) {
+            if (!sc.isComplete()) {
+                token = sc.evaluateChallenge(token);
+            }
+            if (!ss.isComplete()) {
+                token = ss.evaluateResponse(token);
+            }
+        }
+        System.out.println(ss.getNegotiatedProperty(Sasl.BOUND_SERVER_NAME));
+        byte[] hello = "hello".getBytes();
+        token = sc.wrap(hello, 0, hello.length);
+        token = ss.unwrap(token, 0, token.length);
+        if (!Arrays.equals(hello, token)) {
+            throw new Exception("Message altered");
+        }
+    }
+}
diff --git a/jdk/test/sun/security/krb5/auto/UnboundService.java b/jdk/test/sun/security/krb5/auto/UnboundService.java
new file mode 100644
index 0000000..c6d093c
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/UnboundService.java
@@ -0,0 +1,85 @@
+/*
+ * 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 8001104
+ * @summary Unbound SASL service: the GSSAPI/krb5 mech
+ * @compile -XDignore.symbol.file UnboundService.java
+ * @run main/othervm UnboundService null null
+ * @run main/othervm UnboundService server/host.rabbit.hole null
+ * @run main/othervm UnboundService server/host.rabbit.hole@RABBIT.HOLE null
+ * @run main/othervm/fail UnboundService backend/host.rabbit.hole null
+ * @run main/othervm UnboundService null server@host.rabbit.hole
+ * @run main/othervm UnboundService server/host.rabbit.hole server@host.rabbit.hole
+ * @run main/othervm UnboundService server/host.rabbit.hole@RABBIT.HOLE server@host.rabbit.hole
+ * @run main/othervm/fail UnboundService backend/host.rabbit.hole server@host.rabbit.hole
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import sun.security.jgss.GSSUtil;
+
+public class UnboundService {
+
+    /**
+     * @param args JAAS config pricipal and GSSCredential creation name
+     */
+    public static void main(String[] args) throws Exception {
+
+        String principal = args[0];
+        if (principal.equals("null")) principal = null;
+
+        String server = args[1];
+        if (server.equals("null")) server = null;
+
+        new OneKDC(null).writeJAASConf();
+        File f = new File(OneKDC.JAAS_CONF);
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            fos.write((
+                "client {\n" +
+                "    com.sun.security.auth.module.Krb5LoginModule required;\n};\n" +
+                "unbound {\n" +
+                "    com.sun.security.auth.module.Krb5LoginModule required\n" +
+                "    useKeyTab=true\n" +
+                "    principal=" +
+                    (principal==null? "*" :("\"" + principal + "\"")) + "\n" +
+                "    doNotPrompt=true\n" +
+                "    isInitiator=false\n" +
+                "    storeKey=true;\n};\n"
+                ).getBytes());
+        }
+
+        Context c, s;
+        c = Context.fromJAAS("client");
+        s = Context.fromJAAS("unbound");
+
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(server, GSSUtil.GSS_KRB5_MECH_OID);
+
+        Context.handshake(c, s);
+
+        s.dispose();
+        c.dispose();
+    }
+}
diff --git a/jdk/test/sun/security/provider/KeyStore/DKSTest.java b/jdk/test/sun/security/provider/KeyStore/DKSTest.java
new file mode 100644
index 0000000..c2b6baf
--- /dev/null
+++ b/jdk/test/sun/security/provider/KeyStore/DKSTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+/*
+ * see ./DKSTest.sh
+ */
+
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.security.KeyStore;
+import java.security.cert.*;
+import java.security.cert.Certificate;
+import java.util.*;
+
+// Load and store entries in domain keystores
+
+public class DKSTest {
+
+    private static final String TEST_SRC = System.getProperty("test.src");
+    private static final String CERT = TEST_SRC + "/../../pkcs12/trusted.pem";
+    private static final String CONFIG = "file://" + TEST_SRC + "/domains.cfg";
+    private static final Map<String, KeyStore.ProtectionParameter> PASSWORDS =
+        new HashMap<String, KeyStore.ProtectionParameter>() {{
+            put("keystore",
+                new KeyStore.PasswordProtection("test123".toCharArray()));
+            put("policy_keystore",
+                new KeyStore.PasswordProtection(
+                    "Alias.password".toCharArray()));
+            put("pw_keystore",
+                new KeyStore.PasswordProtection("test12".toCharArray()));
+            put("eckeystore1",
+                new KeyStore.PasswordProtection("password".toCharArray()));
+            put("eckeystore2",
+                new KeyStore.PasswordProtection("password".toCharArray()));
+            put("truststore",
+                new KeyStore.PasswordProtection("changeit".toCharArray()));
+            put("empty",
+                new KeyStore.PasswordProtection("passphrase".toCharArray()));
+        }};
+
+    public static void main(String[] args) throws Exception {
+        try {
+            main0();
+        } finally {
+            // cleanup
+            new File(TEST_SRC + "/empty.jks").delete();
+            new File(TEST_SRC + "/Alias.keystore_tmp").delete();
+            new File(TEST_SRC + "/pw.jks_tmp").delete();
+            new File(TEST_SRC + "/secp256r1server-secp384r1ca.p12_tmp").delete();
+            new File(TEST_SRC + "/sect193r1server-rsa1024ca.p12_tmp").delete();
+        }
+    }
+
+    private static void main0() throws Exception {
+        /*
+         * domain keystore: system
+         */
+        URI config = new URI(CONFIG + "#system");
+        int cacertsCount;
+        int expected;
+        KeyStore keystore = KeyStore.getInstance("DKS");
+        // load entries
+        keystore.load(
+            new KeyStore.DomainLoadStoreParameter(config, PASSWORDS));
+        cacertsCount = expected = keystore.size();
+        System.out.println("\nLoading domain keystore: " + config + "\t[" +
+            expected + " entries]");
+        checkEntries(keystore, expected);
+
+        /*
+         * domain keystore: system_plus
+         */
+        config = new URI(CONFIG + "#system_plus");
+        expected = cacertsCount + 1;
+        keystore = KeyStore.getInstance("DKS");
+        // load entries
+        keystore.load(
+            new KeyStore.DomainLoadStoreParameter(config, PASSWORDS));
+        System.out.println("\nLoading domain keystore: " + config + "\t[" +
+            expected + " entries]");
+        checkEntries(keystore, expected);
+
+        /*
+         * domain keystore: system_env
+         */
+        config = new URI(CONFIG + "#system_env");
+        expected = 1 + cacertsCount;
+        keystore = KeyStore.getInstance("DKS");
+        // load entries
+        keystore.load(
+            new KeyStore.DomainLoadStoreParameter(config,
+                Collections.<String, KeyStore.ProtectionParameter>emptyMap()));
+        System.out.println("\nLoading domain keystore: " + config + "\t[" +
+            expected + " entries]");
+        checkEntries(keystore, expected);
+
+        /*
+         * domain keystore: empty
+         */
+        KeyStore empty = KeyStore.getInstance("JKS");
+        empty.load(null, null);
+
+        try (OutputStream outStream =
+            new FileOutputStream(TEST_SRC + "/empty.jks")) {
+            empty.store(outStream, "passphrase".toCharArray());
+        }
+        config = new URI(CONFIG + "#empty");
+        expected = 0;
+        keystore = KeyStore.getInstance("DKS");
+        // load entries
+        keystore.load(
+            new KeyStore.DomainLoadStoreParameter(config, PASSWORDS));
+        System.out.println("\nLoading domain keystore: " + config + "\t[" +
+            expected + " entries]");
+        checkEntries(keystore, expected);
+
+        /*
+         * domain keystore: keystores
+         */
+        config = new URI(CONFIG + "#keystores");
+        expected = 2 + 1 + 1 + 1;
+        keystore = KeyStore.getInstance("DKS");
+        // load entries
+        keystore.load(
+            new KeyStore.DomainLoadStoreParameter(config, PASSWORDS));
+        System.out.println("\nLoading domain keystore: " + config + "\t[" +
+            expected + " entries]");
+        checkEntries(keystore, expected);
+        // set a new trusted certificate entry
+        Certificate cert = loadCertificate(CERT);
+        String alias = "pw_keystore tmp-cert";
+        System.out.println("Setting new trusted certificate entry: " + alias);
+        keystore.setEntry(alias,
+            new KeyStore.TrustedCertificateEntry(cert), null);
+        expected++;
+        // store entries
+        config = new URI(CONFIG + "#keystores_tmp");
+        System.out.println("Storing domain keystore: " + config + "\t[" +
+            expected + " entries]");
+        keystore.store(
+            new KeyStore.DomainLoadStoreParameter(config, PASSWORDS));
+        keystore = KeyStore.getInstance("DKS");
+        // reload entries
+        keystore.load(
+            new KeyStore.DomainLoadStoreParameter(config, PASSWORDS));
+        System.out.println("Reloading domain keystore: " + config + "\t[" +
+            expected + " entries]");
+        checkEntries(keystore, expected);
+        // get the new trusted certificate entry
+        System.out.println("Getting new trusted certificate entry: " + alias);
+        if (!keystore.isCertificateEntry(alias)) {
+            throw new Exception("Error: cannot retrieve certificate entry: " +
+                alias);
+        }
+        keystore.setEntry(alias,
+            new KeyStore.TrustedCertificateEntry(cert), null);
+    }
+
+    private static void checkEntries(KeyStore keystore, int expected)
+        throws Exception {
+        int i = 0;
+        for (String alias : Collections.list(keystore.aliases())) {
+            System.out.print(".");
+            i++;
+        }
+        System.out.println();
+        if (expected != i) {
+            throw new Exception("Error: unexpected entry count in keystore: " +
+                "loaded=" + i + ", expected=" + expected);
+        }
+    }
+
+    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/jdk/test/sun/security/provider/KeyStore/DKSTest.sh b/jdk/test/sun/security/provider/KeyStore/DKSTest.sh
new file mode 100644
index 0000000..b789e41
--- /dev/null
+++ b/jdk/test/sun/security/provider/KeyStore/DKSTest.sh
@@ -0,0 +1,84 @@
+#! /bin/sh
+
+#
+# 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 8007755
+# @summary Support the logical grouping of keystores
+
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+if [ "${TESTSRC}" = "" ] ; then
+   TESTSRC="."
+fi
+
+if [ "${TESTCLASSES}" = "" ] ; then
+   TESTCLASSES="."
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+   echo "TESTJAVA not set.  Test cannot execute."
+   echo "FAILED!!!"
+   exit 1
+fi
+
+if [ "${COMPILEJAVA}" = "" ]; then
+    COMPILEJAVA="${TESTJAVA}"
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS )
+    PS=":"
+    FS="/"
+    ;;
+  Linux )
+    PS=":"
+    FS="/"
+    ;;
+  Darwin )
+    PS=":"
+    FS="/"
+    ;;
+  CYGWIN* )
+    PS=";"
+    FS="/"
+    ;;
+  Windows* )
+    PS=";"
+    FS="\\"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+${COMPILEJAVA}${FS}bin${FS}javac -d .  ${TESTSRC}${FS}DKSTest.java
+
+KEYSTORE_PWD=test12 TRUSTSTORE_PWD=changeit \
+  ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Dtest.src=${TESTSRC} DKSTest
+
+exit $status
diff --git a/jdk/test/sun/security/provider/KeyStore/domains.cfg b/jdk/test/sun/security/provider/KeyStore/domains.cfg
new file mode 100644
index 0000000..203d9d0
--- /dev/null
+++ b/jdk/test/sun/security/provider/KeyStore/domains.cfg
@@ -0,0 +1,65 @@
+// domain containing a single keystore
+domain system {
+    keystore truststore 
+        keystoreType="JKS"
+        keystoreURI="${java.home}/lib/security/cacerts";
+};
+
+// domain containing two JKS keystores
+domain system_plus {
+    keystore truststore 
+        keystoreType="JKS"
+        keystoreURI="${java.home}/lib/security/cacerts";
+    keystore pw_keystore 
+        keystoreType="JKS"
+        keystoreURI="${test.src}/pw.jks";
+};
+
+// domain containing a mixture of keystores
+domain keystores
+    keystoreType="PKCS12" {
+        keystore policy_keystore 
+            keystoreType="JKS"
+            keystoreURI="${test.src}/../PolicyFile/Alias.keystore";
+        keystore pw_keystore 
+            keystoreType="CaseExactJKS"
+            keystoreURI="${test.src}/pw.jks";
+        keystore eckeystore1
+            keystoreURI="${test.src}/../../pkcs11/ec/pkcs12/sect193r1server-rsa1024ca.p12";
+        keystore eckeystore2 
+            keystoreURI="${test.src}/../../pkcs11/ec/pkcs12/secp256r1server-secp384r1ca.p12";
+};
+
+// domain containing a mixture of keystores
+domain keystores_tmp
+    keystoreType="PKCS12" {
+        keystore policy_keystore 
+            keystoreType="JKS"
+            keystoreURI="${test.src}/Alias.keystore_tmp";
+        keystore pw_keystore 
+            keystoreType="CaseExactJKS"
+            keystoreURI="${test.src}/pw.jks_tmp";
+        keystore eckeystore1
+            keystoreURI="${test.src}/sect193r1server-rsa1024ca.p12_tmp";
+        keystore eckeystore2 
+            keystoreURI="${test.src}/secp256r1server-secp384r1ca.p12_tmp";
+};
+
+// domain where passwords are supplied via environment variables
+domain system_env 
+    keystoreType="JKS"
+    keystorePasswordEnv="KEYSTORE_PWD" {
+        keystore env_keystore
+            keystoreURI="${test.src}/pw.jks";
+        keystore env_truststore
+            keystoreURI="${java.home}/lib/security/cacerts"
+            keystorePasswordEnv="TRUSTSTORE_PWD";
+};
+
+// empty domain
+domain empty
+    keystoreType="JKS"
+    keystoreProviderName="SUN" {
+        keystore empty
+            keystoreURI="${test.src}/empty.jks";
+};
diff --git a/jdk/test/sun/security/ssl/sanity/ciphersuites/NoKerberos.java b/jdk/test/sun/security/ssl/sanity/ciphersuites/NoKerberos.java
new file mode 100644
index 0000000..36c6a81
--- /dev/null
+++ b/jdk/test/sun/security/ssl/sanity/ciphersuites/NoKerberos.java
@@ -0,0 +1,103 @@
+/*
+ * 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 8004502
+ * @summary Sanity check to ensure that Kerberos cipher suites cannot be
+ *   negotiated when running on a compact profile that does not include Kerberos
+ */
+
+import java.net.*;
+import java.util.*;
+import javax.net.ssl.*;
+
+public class NoKerberos {
+
+    static final List<String> KERBEROS_CIPHER_SUITES = Arrays.asList(
+        "TLS_KRB5_WITH_RC4_128_SHA",
+        "TLS_KRB5_WITH_RC4_128_MD5",
+        "TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
+        "TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
+        "TLS_KRB5_WITH_DES_CBC_SHA",
+        "TLS_KRB5_WITH_DES_CBC_MD5",
+        "TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
+        "TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
+        "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
+        "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"
+    );
+
+    /**
+     * Checks that the given array of supported cipher suites does not include
+     * any Kerberos cipher suites.
+     */
+    static void checkNotSupported(String[] supportedSuites) {
+        for (String suites: supportedSuites) {
+            if (KERBEROS_CIPHER_SUITES.contains(suites)) {
+                throw new RuntimeException("Supported list of cipher suites " +
+                    " should not include Kerberos cipher suites");
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Class.forName("javax.security.auth.kerberos.KerberosPrincipal");
+            System.out.println("Kerberos is present, nothing to test");
+            return;
+        } catch (ClassNotFoundException okay) { }
+
+        // test SSLSocket
+        try (Socket s = SSLSocketFactory.getDefault().createSocket()) {
+            SSLSocket sslSocket = (SSLSocket)s;
+
+            checkNotSupported(sslSocket.getSupportedCipherSuites());
+
+            // attempt to enable each of the Kerberos cipher suites
+            for (String kcs: KERBEROS_CIPHER_SUITES) {
+                String[] suites = { kcs };
+                try {
+                    sslSocket.setEnabledCipherSuites(suites);
+                    throw new RuntimeException("SSLSocket.setEnabledCipherSuitessuites allowed " +
+                        kcs + " but Kerberos not supported");
+                } catch (IllegalArgumentException expected) { }
+            }
+        }
+
+        // test SSLServerSocket
+        try (ServerSocket ss = SSLServerSocketFactory.getDefault().createServerSocket()) {
+            SSLServerSocket sslSocket = (SSLServerSocket)ss;
+
+            checkNotSupported(sslSocket.getSupportedCipherSuites());
+
+            // attempt to enable each of the Kerberos cipher suites
+            for (String kcs: KERBEROS_CIPHER_SUITES) {
+                String[] suites = { kcs };
+                try {
+                    sslSocket.setEnabledCipherSuites(suites);
+                    throw new RuntimeException("SSLSocket.setEnabledCipherSuitessuites allowed " +
+                        kcs + " but Kerberos not supported");
+                } catch (IllegalArgumentException expected) { }
+            }
+        }
+    }
+}
diff --git a/jdk/test/sun/security/tools/keytool/AltProviderPath.sh b/jdk/test/sun/security/tools/keytool/AltProviderPath.sh
index 067a5eb..82bc657 100644
--- a/jdk/test/sun/security/tools/keytool/AltProviderPath.sh
+++ b/jdk/test/sun/security/tools/keytool/AltProviderPath.sh
@@ -73,7 +73,7 @@
     -keyalg "RSA" -keysize 1024 -sigalg "ShA1WithRSA" \
     -dname "cn=Dummy Test CA, ou=JSN, o=JavaSoft, c=US" -validity 3650 \
     -keypass storepass -keystore keystoreCA.dks -storepass storepass \
-    -storetype "dks" -provider "org.test.dummy.DummyProvider" \
+    -storetype "dummyks" -provider "org.test.dummy.DummyProvider" \
     -providerPath ${TESTCLASSES}
 
 if [ $? -ne 0 ]; then
@@ -82,7 +82,7 @@
 
 #Change keystore password
 ${TESTJAVA}${FS}bin${FS}keytool -storepasswd -new storepass2 \
-    -keystore keystoreCA.dks -storetype "dks" -storepass storepass \
+    -keystore keystoreCA.dks -storetype "dummyks" -storepass storepass \
     -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES}
 
 if [ $? -ne 0 ]; then
@@ -93,7 +93,7 @@
 #Change keystore key password
 ${TESTJAVA}${FS}bin${FS}keytool -keypasswd -alias "dummyTestCA" \
     -keypass storepass -new keypass -keystore keystoreCA.dks \
-    -storetype "dks" -storepass storepass2 \
+    -storetype "dummyks" -storepass storepass2 \
     -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES}
 
 if [ $? -ne 0 ]; then
@@ -102,7 +102,7 @@
 
 #Export certificate
 ${TESTJAVA}${FS}bin${FS}keytool -v -export -rfc -alias "dummyTestCA" \
-    -file "dummyTestCA.der" -keystore keystoreCA.dks -storetype "dks" \
+    -file "dummyTestCA.der" -keystore keystoreCA.dks -storetype "dummyks" \
     -storepass storepass2 -provider "org.test.dummy.DummyProvider" \
     -providerPath ${TESTCLASSES}
 
@@ -112,7 +112,7 @@
 
 #list keystore
 ${TESTJAVA}${FS}bin${FS}keytool -v -list -keystore keystoreCA.dks \
-    -storetype "dks" -storepass storepass2 \
+    -storetype "dummyks" -storepass storepass2 \
     -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES}
 
 if [ $? -ne 0 ]; then
diff --git a/jdk/test/sun/security/tools/keytool/DummyProvider.java b/jdk/test/sun/security/tools/keytool/DummyProvider.java
index ae71470..0c7ce10 100644
--- a/jdk/test/sun/security/tools/keytool/DummyProvider.java
+++ b/jdk/test/sun/security/tools/keytool/DummyProvider.java
@@ -40,7 +40,7 @@
         //
         // KeyStore
         //
-        put("KeyStore.DKS", "sun.security.provider.JavaKeyStore$JKS");
+        put("KeyStore.DummyKS", "sun.security.provider.JavaKeyStore$JKS");
 
         //
         // Signature engines
diff --git a/jdk/test/sun/util/calendar/zi/BackEnd.java b/jdk/test/sun/util/calendar/zi/BackEnd.java
new file mode 100644
index 0000000..29d0201
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/BackEnd.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2000, 2004, 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.
+ */
+
+/**
+ * <code>BackEnd</code> is an abstract base class for a back-end of compiling
+ * Olson's zoneinfo database and generating Java zoneinfo database.
+ *
+ * @since 1.4
+ */
+abstract class BackEnd {
+
+    /**
+     * Receives each zone's TimeZone information which was created by
+     * {@link Zoneinfo#parse} in class <code>Zoneinfo</code>,
+     * and processes it.
+     *
+     * @param tz Timezone object for each zone
+     * @return 0 if no error occurred, otherwise 1.
+     */
+    abstract int processZoneinfo(Timezone tz);
+
+    /**
+     * Receives whole information which is generated by JavaZic's front-end
+     * in the form of Mapping object and generates all Java zone information
+     * files.
+     *
+     * @param m Mappings object which is generated by
+     *          {@link Main#compile() Main.compile()}.
+     * @return 0 if no error occurred, otherwise 1.
+     */
+    abstract int generateSrc(Mappings m);
+
+    /**
+     * Decides which backend class should be used and returns its instance.
+     * @return an instance of backend class
+     */
+    static BackEnd getBackEnd() {
+        if (Zoneinfo.isYearForTimeZoneDataSpecified) {
+            return new Simple();
+        } else if (Main.outputDoc) {
+            return new GenDoc();
+        } else {
+            return new Gen();
+        }
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/Checksum.java b/jdk/test/sun/util/calendar/zi/Checksum.java
new file mode 100644
index 0000000..0123250
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Checksum.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2000, 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.
+ */
+
+import java.util.zip.CRC32;
+
+/**
+ * Checksum provides methods for calculating a CRC32 value for a
+ * transitions table.
+ *
+ * @since 1.4
+ */
+public class Checksum extends CRC32
+{
+    /**
+     * Updates the CRC32 value from each byte of the given int
+     * value. The bytes are used in the big endian order.
+     * @param val the int value
+     */
+    public void update(int val) {
+        byte[] b = new byte[4];
+        b[0] = (byte)((val >>> 24) & 0xff);
+        b[1] = (byte)((val >>> 16) & 0xff);
+        b[2] = (byte)((val >>> 8) & 0xff);
+        b[3] = (byte)(val & 0xff);
+        update(b);
+    }
+
+    /**
+     * Updates the CRC32 value from each byte of the given long
+     * value. The bytes are used in the big endian order.
+     * @param val the long value
+     */
+    void update(long val) {
+        byte[] b = new byte[8];
+        b[0] = (byte)((val >>> 56) & 0xff);
+        b[1] = (byte)((val >>> 48) & 0xff);
+        b[2] = (byte)((val >>> 40) & 0xff);
+        b[3] = (byte)((val >>> 32) & 0xff);
+        b[4] = (byte)((val >>> 24) & 0xff);
+        b[5] = (byte)((val >>> 16) & 0xff);
+        b[6] = (byte)((val >>> 8) & 0xff);
+        b[7] = (byte)(val & 0xff);
+        update(b);
+    }
+}
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java b/jdk/test/sun/util/calendar/zi/DayOfWeek.java
similarity index 64%
copy from jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java
copy to jdk/test/sun/util/calendar/zi/DayOfWeek.java
index 1124d12..9470d96 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java
+++ b/jdk/test/sun/util/calendar/zi/DayOfWeek.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2006, 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,17 +23,32 @@
  * questions.
  */
 
-package sun.lwawt.macosx;
+/**
+ * Day of week enum.
+ *
+ * @since 1.6
+ */
 
-// This exists strictly to work around the fact that java.awt.Conditional isn't a public class.
-// It uses java reflection to get the EventDispatchThread class and call a MacOSX only
-// method on it.
-//
-// NOTE: This uses reflection in its implementation, so it is not for performance critical code.
-//
-// See java.awt.EventDispatchThread and apple.awt.CPrintJob for more.
-//
-public abstract class EventDispatchAccess {
-    public native void pumpEventsAndWait();
-    public abstract boolean evaluate();
+enum DayOfWeek {
+    SUNDAY("Sun"),
+    MONDAY("Mon"),
+    TUESDAY("Tue"),
+    WEDNESDAY("Wed"),
+    THURSDAY("Thu"),
+    FRIDAY("Fri"),
+    SATURDAY("Sat");
+
+    private final String abbr;
+
+    private DayOfWeek(String abbr) {
+        this.abbr = abbr;
+    }
+
+    String getAbbr() {
+        return abbr;
+    }
+
+    int value() {
+        return ordinal() + 1;
+    }
 }
diff --git a/jdk/test/sun/util/calendar/zi/Gen.java b/jdk/test/sun/util/calendar/zi/Gen.java
new file mode 100644
index 0000000..70ad6b5
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Gen.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2000, 2011, 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.
+ */
+
+import  java.io.IOException;
+import  java.io.File;
+import  java.io.FileOutputStream;
+import  java.io.DataOutputStream;
+import  java.io.RandomAccessFile;
+import  java.util.List;
+import  java.util.Map;
+import  java.util.Set;
+
+/**
+ * <code>Gen</code> is one of back-end classes of javazic, and generates
+ * ZoneInfoMappings and zone-specific file for each zone.
+ */
+class Gen extends BackEnd {
+
+    /**
+     * Generates datafile in binary TLV format for each time zone.
+     * Regarding contents of output files, see {@link ZoneInfoFile}.
+     *
+     * @param Timezone
+     * @return 0 if no errors, or 1 if error occurred.
+     */
+    int processZoneinfo(Timezone tz) {
+        try {
+            int size;
+            String outputDir = Main.getOutputDir();
+            String zonefile = ZoneInfoFile.getFileName(tz.getName());
+
+            /* If outputDir doesn't end with file-separator, adds it. */
+            if (!outputDir.endsWith(File.separator)) {
+                outputDir += File.separatorChar;
+            }
+
+            /* If zonefile includes file-separator, it's treated as part of
+             * pathname. And make directory if necessary.
+             */
+            int index = zonefile.lastIndexOf(File.separatorChar);
+            if (index != -1) {
+                outputDir += zonefile.substring(0, index+1);
+            }
+            File outD = new File(outputDir);
+            outD.mkdirs();
+
+            FileOutputStream fos =
+                new FileOutputStream(outputDir + zonefile.substring(index+1));
+            DataOutputStream dos = new DataOutputStream(fos);
+
+            /* Output Label */
+            dos.write(ZoneInfoFile.JAVAZI_LABEL, 0,
+                      ZoneInfoFile.JAVAZI_LABEL.length);
+
+            /* Output Version of ZoneInfoFile */
+            dos.writeByte(ZoneInfoFile.JAVAZI_VERSION);
+
+            List<Long> transitions = tz.getTransitions();
+            if (transitions != null) {
+                List<Integer> dstOffsets = tz.getDstOffsets();
+                List<Integer> offsets = tz.getOffsets();
+
+                if ((dstOffsets == null && offsets != null) ||
+                    (dstOffsets != null && offsets == null)) {
+                    Main.panic("Data not exist. (dstOffsets or offsets)");
+                    return 1;
+                }
+
+                /* Output Transition records */
+                dos.writeByte(ZoneInfoFile.TAG_Transition);
+                size = transitions.size();
+                dos.writeShort((size * 8) & 0xFFFF);
+                int dstoffset;
+                for (int i = 0; i < size; i++) {
+                    /* if DST offset is 0, this means DST isn't used.
+                     * (NOT: offset's index is 0.)
+                     */
+                    if ((dstoffset = dstOffsets.get(i).intValue()) == -1) {
+                        dstoffset = 0;
+                    }
+
+                    dos.writeLong((transitions.get(i).longValue() << 12)
+                                  | (dstoffset << 4)
+                                  | offsets.get(i).intValue());
+
+                }
+
+                /* Output data for GMTOffset */
+                List<Integer> gmtoffset = tz.getGmtOffsets();
+                dos.writeByte(ZoneInfoFile.TAG_Offset);
+                size = gmtoffset.size();
+                dos.writeShort((size * 4) & 0xFFFF);
+                for (int i = 0; i < size; i++) {
+                    dos.writeInt(gmtoffset.get(i));
+                }
+            }
+
+            /* Output data for SimpleTimeZone */
+            List<RuleRec> stz = tz.getLastRules();
+            if (stz != null) {
+                RuleRec[] rr = new RuleRec[2];
+                boolean wall = true;
+
+                rr[0] = stz.get(0);
+                rr[1] = stz.get(1);
+
+                dos.writeByte(ZoneInfoFile.TAG_SimpleTimeZone);
+                wall = rr[0].getTime().isWall() && rr[1].getTime().isWall();
+                if (wall) {
+                    dos.writeShort(32);
+                } else {
+                    dos.writeShort(40);
+                }
+
+                for (int i = 0; i < 2; i++) {
+                    dos.writeInt(rr[i].getMonthNum() - 1); // 0-based month number
+                    dos.writeInt(rr[i].getDay().getDayForSimpleTimeZone());
+                    dos.writeInt(rr[i].getDay().getDayOfWeekForSimpleTimeZoneInt());
+                    dos.writeInt((int)rr[i].getTime().getTime());
+                    if (!wall) {
+                        dos.writeInt((rr[i].getTime().getType() & 0xFF) - 1);
+                    }
+                }
+            }
+
+            /* Output RawOffset */
+            dos.writeByte(ZoneInfoFile.TAG_RawOffset);
+            dos.writeShort(4);
+            dos.writeInt(tz.getRawOffset());
+
+            /* Output willGMTOffsetChange flag */
+            if (tz.willGMTOffsetChange()) {
+                dos.writeByte(ZoneInfoFile.TAG_GMTOffsetWillChange);
+                dos.writeShort(1);
+                dos.writeByte(1);
+            }
+
+            /* Output LastDSTSaving */
+            dos.writeByte(ZoneInfoFile.TAG_LastDSTSaving);
+            dos.writeShort(2);
+            dos.writeShort(tz.getLastDSTSaving()/1000);
+
+            /* Output checksum */
+            dos.writeByte(ZoneInfoFile.TAG_CRC32);
+            dos.writeShort(4);
+            dos.writeInt(tz.getCRC32());
+
+            fos.close();
+            dos.close();
+        } catch(IOException e) {
+            Main.panic("IO error: "+e.getMessage());
+            return 1;
+        }
+
+        return 0;
+    }
+
+    /**
+     * Generates ZoneInfoMappings in binary TLV format for each zone.
+     * Regarding contents of output files, see {@link ZoneInfoFile}.
+     *
+     * @param Mappings
+     * @return 0 if no errors, or 1 if error occurred.
+     */
+    int generateSrc(Mappings map) {
+        try {
+            int index;
+            int block_size;
+            int roi_size;
+            long fp;
+            String outputDir = Main.getOutputDir();
+
+            /* If outputDir doesn't end with file-separator, adds it. */
+            if (!outputDir.endsWith(File.separator)) {
+                outputDir += File.separatorChar;
+            }
+
+            File outD = new File(outputDir);
+            outD.mkdirs();
+
+            /* Open ZoneInfoMapping file to write. */
+            RandomAccessFile raf =
+                new RandomAccessFile(outputDir + ZoneInfoFile.JAVAZM_FILE_NAME, "rw");
+
+            /* Whether rawOffsetIndex list exists or not. */
+            List<Integer> roi = map.getRawOffsetsIndex();
+            if (roi == null) {
+                Main.panic("Data not exist. (rawOffsetsIndex)");
+                return 1;
+            }
+            roi_size = roi.size();
+
+            /* Whether rawOffsetIndexTable list exists or not. */
+            List<Set<String>> roit = map.getRawOffsetsIndexTable();
+            if (roit == null || roit.size() != roi_size) {
+                Main.panic("Data not exist. (rawOffsetsIndexTable) Otherwise, Invalid size");
+                return 1;
+            }
+
+            /* Output Label */
+            raf.write(ZoneInfoFile.JAVAZM_LABEL, 0,
+                      ZoneInfoFile.JAVAZM_LABEL.length);
+
+            /* Output Version */
+            raf.writeByte(ZoneInfoFile.JAVAZM_VERSION);
+
+            index = ZoneInfoFile.JAVAZM_LABEL.length + 2;
+
+            /* Output Version of Olson's tzdata */
+            byte[] b = Main.getVersionName().getBytes("UTF-8");
+            raf.writeByte(ZoneInfoFile.TAG_TZDataVersion);
+            raf.writeShort((b.length+1) & 0xFFFF);
+            raf.write(b);
+            raf.writeByte(0x00);
+            index += b.length + 4;
+
+            /* Output ID list. */
+            raf.writeByte(ZoneInfoFile.TAG_ZoneIDs);
+            block_size = 2;
+            raf.writeShort(block_size & 0xFFFF);
+            short nID = 0;
+            raf.writeShort(nID & 0xFFFF);
+            for (int i = 0; i < roi_size; i++) {
+                for (String key : roit.get(i)) {
+                    byte size = (byte)key.getBytes("UTF-8").length;
+                    raf.writeByte(size & 0xFF);
+                    raf.write(key.getBytes("UTF-8"), 0, size);
+                    block_size += 1 + size;
+                    nID++;
+                }
+            }
+            fp = raf.getFilePointer();
+            raf.seek(index);
+            raf.writeShort((block_size) & 0xFFFF);
+            raf.writeShort(nID & 0xFFFF);
+            raf.seek(fp);
+
+            /* Output sorted rawOffset list. */
+            raf.writeByte(ZoneInfoFile.TAG_RawOffsets);
+            index += 3 + block_size;
+            block_size = roi_size * 4;
+            raf.writeShort(block_size & 0xFFFF);
+            for (int i = 0; i < roi_size; i++) {
+                raf.writeInt(Integer.parseInt(roi.get(i).toString()));
+            }
+
+            /* Output sorted rawOffsetIndex list. */
+            raf.writeByte(ZoneInfoFile.TAG_RawOffsetIndices);
+            index += 3 + block_size;
+            block_size = 0;
+            raf.writeShort(block_size & 0xFFFF);
+            int num;
+            for (int i = 0; i < roi_size; i++) {
+                num = roit.get(i).size();
+                block_size += num;
+                for (int j = 0; j < num; j++) {
+                    raf.writeByte(i);
+                }
+            }
+            fp = raf.getFilePointer();
+            raf.seek(index);
+            raf.writeShort((block_size) & 0xFFFF);
+            raf.seek(fp);
+
+            /* Whether alias list exists or not. */
+            Map<String,String> a = map.getAliases();
+            if (a == null) {
+                Main.panic("Data not exist. (aliases)");
+                return 0;
+            }
+
+            /* Output ID list. */
+            raf.writeByte(ZoneInfoFile.TAG_ZoneAliases);
+            index += 3 + block_size;
+            block_size = 2;
+            raf.writeShort(block_size & 0xFFFF);
+            raf.writeShort(a.size() & 0xFFFF);
+            for (String key : a.keySet()) {
+                String alias = a.get(key);
+                byte key_size = (byte)key.length();
+                byte alias_size = (byte)alias.length();
+                raf.writeByte(key_size & 0xFF);
+                raf.write(key.getBytes("UTF-8"), 0, key_size);
+                raf.writeByte(alias_size & 0xFF);
+                raf.write(alias.getBytes("UTF-8"), 0, alias_size);
+                block_size += 2 + key_size + alias_size;
+            }
+            fp = raf.getFilePointer();
+            raf.seek(index);
+            raf.writeShort((block_size) & 0xFFFF);
+            raf.seek(fp);
+
+            /* Output the exclude list if it exists. */
+            List<String> excludedZones = map.getExcludeList();
+            if (excludedZones != null) {
+                raf.writeByte(ZoneInfoFile.TAG_ExcludedZones);
+                index += 3 + block_size;
+                block_size = 2;
+                raf.writeShort(block_size & 0xFFFF);  // place holder
+                raf.writeShort(excludedZones.size()); // the number of excluded zones
+                for (String name : excludedZones) {
+                    byte size = (byte) name.length();
+                    raf.writeByte(size);                 // byte length
+                    raf.write(name.getBytes("UTF-8"), 0, size); // zone name
+                    block_size += 1 + size;
+                }
+                fp = raf.getFilePointer();
+                raf.seek(index);
+                raf.writeShort(block_size & 0xFFFF);
+                raf.seek(fp);
+            }
+
+            /* Close ZoneInfoMapping file. */
+            raf.close();
+        } catch(IOException e) {
+            Main.panic("IO error: "+e.getMessage());
+            return 1;
+        }
+
+        return 0;
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/GenDoc.java b/jdk/test/sun/util/calendar/zi/GenDoc.java
new file mode 100644
index 0000000..c3b520c
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/GenDoc.java
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 2001, 2011, 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.
+ */
+
+import  java.io.BufferedReader;
+import  java.io.BufferedWriter;
+import  java.io.File;
+import  java.io.FileReader;
+import  java.io.FileWriter;
+import  java.io.IOException;
+import  java.util.Date;
+import  java.util.HashMap;
+import  java.util.List;
+import  java.util.Map;
+import  java.util.Set;
+import  java.util.SortedMap;
+import  java.util.StringTokenizer;
+import  java.util.TreeMap;
+import  java.util.TreeSet;
+
+/**
+ * <code>GenDoc</code> is one of back-end classes of javazic, and generates
+ * index.html and other html files which prints the detailed time zone
+ * information for each zone.
+ */
+class GenDoc extends BackEnd {
+
+    private static final String docDir = "doc";
+
+    private static final String header1 =
+        "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"" +
+        "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" +
+        "<HTML>\n<HEAD>\n<!-- Generated by javazic on ";
+    private static final String header2 =
+        "-->\n<TITLE>\n" +
+        "Java Platform, Standard Edition - TimeZone information based on ";
+    private static final String header3 =
+        "-->\n<TITLE>\n" +
+        "Java Platform, Standard Edition  TimeZone - ";
+    private static final String header4 =
+        "</TITLE>\n" +
+        "</HEAD>\n\n";
+
+    private static final String body1 =
+        "<BODY BGCOLOR=\"white\">\n";
+    private static final String body2 =
+        "</BODY>\n";
+
+    private static final String footer =
+        "</HTML>\n";
+
+
+    // list of time zone name and zonefile name/real time zone name
+    //   e.g.
+    //      key (String)       : value (String)
+    //      "America/Denver"   : "America/Denver.html" (real time zone)
+    //      "America/Shiprock" : "America/Denver"      (alias)
+    TreeMap<String,String> timezoneList = new TreeMap<String,String>();
+
+    // list of time zone's display name and time zone name
+    //   e.g.
+    //      key (String)                : value (String)
+    //      "Tokyo, Asia"               : "Asia/Tokyo"
+    //      "Marengo, Indiana, America" : "America/Indiana/Marengo"
+    //          (aliases included)
+    TreeMap<String,String> displayNameList = new TreeMap<String,String>();
+
+    // list of top level regions
+    //   e.g.
+    //      key (String) : value (String)
+    //      "America"    : "America.html"
+    //          (including entries in America/Indiana/, America/Kentucky/, ...)
+    TreeMap<String,String> regionList = new TreeMap<String,String>();
+
+    // mapping list from zone name to latitude & longitude
+    //   This list is generated from zone.tab.
+    //   e.g.
+    //      key (String) : value (LatitudeAndLongitude object)
+    //      "Asia/Tokyo" : latitude=35.3916, longitude=13.9444
+    //          (aliases not included)
+    HashMap<String,LatitudeAndLongitude> mapList = null;
+
+    // SortedMap of zone IDs sorted by their GMT offsets. If zone's GMT
+    // offset will change in the future, its last known offset is
+    // used.
+    SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<Integer, Set<String>>();
+
+    /**
+     * Generates HTML document for each zone.
+     * @param Timezone
+     * @return 0 if no errors, or 1 if error occurred.
+     */
+    int processZoneinfo(Timezone tz) {
+        try {
+            int size;
+            int index;
+            String outputDir = Main.getOutputDir();
+            String zonename = tz.getName();
+            String zonefile = ZoneInfoFile.getFileName(zonename) + ".html";
+            List<RuleRec> stz = tz.getLastRules();
+            timezoneList.put(zonename, zonefile);
+            displayNameList.put(transform(zonename), zonename);
+
+            // Populate zonesByOffset. (Zones that will change their
+            // GMT offsets are also added to zonesByOffset here.)
+            int lastKnownOffset = tz.getRawOffset();
+            Set<String> set = zonesByOffset.get(lastKnownOffset);
+            if (set == null) {
+                set = new TreeSet<String>();
+                zonesByOffset.put(lastKnownOffset, set);
+            }
+            set.add(zonename);
+
+            /* If outputDir doesn't end with file-separator, adds it. */
+            if (!outputDir.endsWith(File.separator)) {
+                outputDir += File.separatorChar;
+            }
+            outputDir += docDir + File.separatorChar;
+
+            index = zonename.indexOf('/');
+            if (index != -1) {
+                regionList.put(zonename.substring(0, index),
+                               zonename.substring(0, index) + ".html");
+            }
+
+            /* If zonefile includes file-separator, it's treated as part of
+             * pathname. And make directory if necessary.
+             */
+            index = zonefile.lastIndexOf('/');
+            if (index != -1) {
+                zonefile.replace('/', File.separatorChar);
+                outputDir += zonefile.substring(0, index+1);
+            }
+            File outD = new File(outputDir);
+            outD.mkdirs();
+
+            /* If mapfile is available, add a link to the appropriate map */
+            if ((mapList == null) && (Main.getMapFile() != null)) {
+                FileReader fr = new FileReader(Main.getMapFile());
+                BufferedReader in = new BufferedReader(fr);
+                mapList = new HashMap<String,LatitudeAndLongitude>();
+                String line;
+                while ((line = in.readLine()) != null) {
+                    // skip blank and comment lines
+                    if (line.length() == 0 || line.charAt(0) == '#') {
+                        continue;
+                    }
+                    StringTokenizer tokens = new StringTokenizer(line);
+                    String token = tokens.nextToken();  /* We don't use the first token. */
+                    token = tokens.nextToken();
+                    LatitudeAndLongitude location = new LatitudeAndLongitude(token);
+                    token = tokens.nextToken();
+                    mapList.put(token, location);
+                }
+                in.close();
+            }
+
+            /* Open zoneinfo file to write. */
+            FileWriter fw = new FileWriter(outputDir + zonefile.substring(index+1));
+            BufferedWriter out = new BufferedWriter(fw);
+
+            out.write(header1 + new Date() + header3 + zonename + header4);
+            out.write(body1 + "<FONT size=\"+2\"><B>" + zonename + "</B></FONT>");
+            LatitudeAndLongitude location = mapList.get(zonename);
+            if (location != null) {
+                int deg, min, sec;
+
+                deg = location.getLatDeg();
+                min = location.getLatMin();
+                sec = location.getLatSec();
+                if (deg < 0) {
+                    min = -min;
+                    sec = -sec;
+                } else if (min < 0) {
+                    sec = -sec;
+                }
+                out.write("&nbsp;&nbsp;&nbsp;" +
+                          "<A HREF=\"http://www.mapquest.com/maps/map.adp?" +
+                          "latlongtype=degrees" +
+                          "&latdeg=" + deg +
+                          "&latmin=" + min +
+                          "&latsec=" + sec);
+
+                deg = location.getLongDeg();
+                min = location.getLongMin();
+                sec = location.getLongSec();
+                if (deg < 0) {
+                    min = -min;
+                    sec = -sec;
+                } else if (min < 0) {
+                    sec = -sec;
+                }
+                out.write("&longdeg=" + deg +
+                          "&longmin=" + min +
+                          "&longsec=" + sec +
+                          "\" target=\"_blank\">[map]</A>");
+            }
+            out.write("\n<P>\n");
+
+            List<ZoneRec> zone = tz.getZones();
+            List<RuleRec> rule = tz.getRules();
+            if (rule != null && zone != null) {
+                out.write("<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">\n" +
+                          "<TR>\n" +
+                          "<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\"><BR>" +
+                          "<A HREF=\"#Rules\">Rules</A><BR></TD>\n" +
+                          "<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\">" +
+                          "<A HREF=\"#Zone\"><BR>Zone<BR></A></TD>\n" +
+                          "</TR>\n</TABLE>\n");
+            }
+
+            /* Output Rule records. */
+            if (rule != null) {
+                size = rule.size();
+                out.write("<P>\n<A NAME=\"Rules\">" +
+                          "<FONT SIZE=\"+1\"><B>Rules</B></FONT></A>\n" +
+                          "<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" +
+                          "<TR BGCOLOR=\"#CCCCFF\">\n" +
+                          "<TD>NAME</TD><TD>FROM</TD><TD>TO</TD><TD>TYPE</TD>" +
+                          "<TD>IN</TD><TD>ON</TD><TD>AT</TD><TD>SAVE</TD>" +
+                          "<TD>LETTER/S</TD><TD>NOTES</TD>\n</TR>\n");
+                for (int i = 0; i < size; i++) {
+                    out.write("<TR BGCOLOR=\"#FFFFFF\">\n");
+                    StringTokenizer st = new StringTokenizer(rule.get(i).getLine());
+                    String s;
+                    if (st.hasMoreTokens()) {   /* RULE - truncated */
+                        st.nextToken();
+                    }
+                    if (st.hasMoreTokens()) {   /* NAME */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* FROM */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* TO */
+                        s = st.nextToken();
+                        if (s.equals("min") || s.equals("max")) {
+                            out.write("<TD><FONT COLOR=\"red\">" + s + "</FONT></TD>");
+                        } else {
+                            out.write("<TD>" + s + "</TD>");
+                        }
+                    }
+                    if (st.hasMoreTokens()) {   /* TYPE */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* IN */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* ON */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* AT */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* SAVE */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* LETTER/S */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* NOTES */
+                        s = st.nextToken();
+                        while (st.hasMoreTokens()) {
+                            s += " " + st.nextToken();
+                        }
+                        index = s.indexOf('#');
+                        out.write("<TD>" + s.substring(index+1) + "</TD>\n");
+                    } else {
+                        out.write("<TD>&nbsp;</TD>\n");
+                    }
+                    out.write("</TR>\n");
+                }
+                out.write("</TABLE>\n<P>&nbsp;<P>\n");
+            }
+
+            /* Output Zone records. */
+            if (zone != null) {
+                size = zone.size();
+                out.write("<P>\n<A NAME=\"Zone\">" +
+                          "<FONT SIZE=\"+1\"><B>Zone</B></FONT></A>\n" +
+                          "<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" +
+                          "<TR BGCOLOR=\"#CCCCFF\">\n<TD>GMTOFF</TD>" +
+                          "<TD>RULES</TD><TD>FORMAT</TD><TD>UNTIL</TD>" +
+                          "<TD>NOTES</TD>\n</TR>\n");
+                for (int i = 0; i < size; i++) {
+                    out.write("<TR>\n");
+                    StringTokenizer st = new StringTokenizer(zone.get(i).getLine());
+                    String s = st.nextToken();
+                    if (s.equals("Zone")) {     /* NAME */
+                        s = st.nextToken();
+                        s = st.nextToken();
+                    }
+                    out.write("<TD>" + s + "</TD>");    /* GMTOFFSET */
+                    if (st.hasMoreTokens()) {   /* RULES */
+                        out.write("<TD>" + st.nextToken() + "</TD>");
+                    }
+                    if (st.hasMoreTokens()) {   /* FORMAT */
+                        s = st.nextToken();
+                        index = s.indexOf('#');
+                        if (index != -1) {
+                            if (index != 0) {
+                                out.write("<TD>" + s.substring(0, index-1) +
+                                          "</TD>");     /* FORMAT */
+                                s = s.substring(index+1);
+                            } else {
+                                out.write("<TD>&nbsp;</TD>");   /* FORMAT */
+                            }
+                            while (st.hasMoreTokens()) {
+                                s += " " + st.nextToken();
+                            }
+                            out.write("<TD>&nbsp;</TD>");       /* UNTIL */
+                            out.write("<TD>" + s + "</TD>\n</TR>\n");   /* NOTES */
+                            continue;
+                        } else {
+                            out.write("<TD>" + s + "</TD>");    /* FORMAT */
+                        }
+                    }
+
+                    if (st.hasMoreTokens()) {   /* UNTIL */
+                        s = st.nextToken();
+                        while (st.hasMoreTokens()) {
+                            s += " " + st.nextToken();
+                        }
+                        index = s.indexOf('#');
+                        if (index != -1) {
+                            if (index != 0) {
+                                out.write("<TD>" + s.substring(0, index-1) +
+                                          "</TD>");     /* UNTIL */
+                            } else {
+                                out.write("<TD>&nbsp;</TD>");   /* UNTIL */
+                            }
+                            out.write("<TD>" + s.substring(index+1) +
+                                      "</TD>\n");       /* NOTES */
+                        } else {
+                            out.write("<TD>" + s + "</TD>");    /* UNTIL */
+                            out.write("<TD>&nbsp;</TD>\n");     /* NOTES */
+                        }
+                    } else {
+                        out.write("<TD>&nbsp;</TD>");           /* UNTIL */
+                        out.write("<TD>&nbsp;</TD>\n");         /* NOTES */
+                    }
+                    out.write("</TR>\n");
+                }
+                out.write("</TABLE>\n");
+            }
+            out.write(body2 + footer);
+
+            out.close();
+            fw.close();
+        } catch(IOException e) {
+            Main.panic("IO error: "+e.getMessage());
+            return 1;
+        }
+
+        return 0;
+    }
+
+    /**
+     * Generates index.html and other top-level frame files.
+     * @param Mappings
+     * @return 0 if no errors, or 1 if error occurred.
+     */
+    int generateSrc(Mappings map) {
+        try {
+            int len;
+            Object o[];
+            String outputDir = Main.getOutputDir();
+            FileWriter fw1, fw2;
+            BufferedWriter out1, out2;
+
+            /* Whether alias list exists or not. */
+            Map<String,String> a = map.getAliases();
+            if (a == null) {
+                Main.panic("Data not exist. (aliases)");
+                return 1;
+            }
+
+            timezoneList.putAll(a);
+
+            /* If outputDir doesn't end with file-separator, adds it. */
+            if (!outputDir.endsWith(File.separator)) {
+                outputDir += File.separatorChar;
+            }
+            outputDir += docDir + File.separatorChar;
+
+            File outD = new File(outputDir);
+            outD.mkdirs();
+
+            /* Creates index.html */
+            fw1 = new FileWriter(outputDir + "index.html", false);
+            out1 = new BufferedWriter(fw1);
+
+            out1.write(header1 + new Date() + header2 + Main.getVersionName() +
+                       header4 +
+                       "<FRAMESET cols=\"20%,80%\">\n" +
+                       "<FRAMESET rows=\"30%,70%\">\n" +
+                       "<FRAME src=\"overview-frame.html\" name=\"TimeZoneListFrame\">\n" +
+                       "<FRAME src=\"allTimeZone-frame1.html\" name=\"allTimeZoneFrame\">\n" +
+                       "</FRAMESET>" +
+                       "<FRAME src=\"overview-summary.html\" name=\"rightFrame\">\n" +
+                       "</FRAMESET>\n" +
+                       "<NOFRAMES>\n" +
+                       "<H2>\nFrame Alert\n</H2>\n\n" +
+                       "<P>\n\n" +
+                       "This document is designed to be viewed using the frames feature. If you see this\n" +
+                       "message, you are using a non-frame-capable web client.\n" +
+                       "<BR>\n" +
+                       "Link to<A HREF=\"overview-summary.html\">Non-frame version.</A>\n" +
+                       "</NOFRAMES>\n" + footer);
+
+            out1.close();
+            fw1.close();
+
+
+            /* Creates overview-frame.html */
+            fw1 = new FileWriter(outputDir + "overview-frame.html", false);
+            out1 = new BufferedWriter(fw1);
+
+            out1.write(header1 + new Date() + header2 + Main.getVersionName() +
+                       header4 + body1 +
+                       "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n" +
+                       "<TD NOWRAP><FONT size=\"+1\">\n" +
+                       "<B>Java<sup><font size=-2>TM</font></sup>&nbsp;Platform<br>Standard&nbsp;Ed.</B></FONT></TD>\n" +
+                       "</TR>\n</TABLE>\n\n" +
+                       "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n<TD NOWRAP>" +
+                       "<P>\n<FONT size=\"+1\">\nAll Time Zones Sorted By:</FONT>\n<BR>\n" +
+                       "&nbsp;&nbsp;<A HREF=\"allTimeZone-frame1.html\" TARGET=\"allTimeZoneFrame\">GMT offsets</A></FONT>\n<BR>\n" +
+                       "&nbsp;&nbsp;<A HREF=\"allTimeZone-frame2.html\" TARGET=\"allTimeZoneFrame\">Zone names</A></FONT>\n<BR>" +
+                       "&nbsp;&nbsp;<A HREF=\"allTimeZone-frame3.html\" TARGET=\"allTimeZoneFrame\">City names</A></FONT>\n" +
+                       "<P>\n<FONT size=\"+1\">\nContinents and Oceans</FONT>\n<BR>\n");
+
+            for (String regionKey : regionList.keySet()) {
+                out1.write("&nbsp;&nbsp;<A HREF=\"" + regionList.get(regionKey) +
+                           "\" TARGET=\"allTimeZoneFrame\">" + regionKey +
+                           "</A><BR>\n");
+
+                fw2 = new FileWriter(outputDir + regionList.get(regionKey),
+                                     false);
+                out2 = new BufferedWriter(fw2);
+
+                out2.write(header1 + new Date() + header3 + regionKey +
+                           header4 + body1 + "<FONT size=\"+1\"><B>" +
+                           regionKey + "</B></FONT>\n<BR>\n<TABLE>\n<TR>\n<TD>");
+
+                boolean found = false;
+                for (String timezoneKey : timezoneList.keySet()) {
+                    int regionIndex = timezoneKey.indexOf('/');
+                    if (regionIndex == -1 ||
+                        !regionKey.equals(timezoneKey.substring(0, regionIndex))) {
+                        if (found) {
+                            break;
+                        } else {
+                            continue;
+                        }
+                    }
+
+                    found = true;
+                    if (a.containsKey(timezoneKey)) {
+                        Object realName = a.get(timezoneKey);
+                        while (a.containsKey(realName)) {
+                            realName = a.get(realName);
+                        }
+                        out2.write(timezoneKey +
+                                   " (alias for " + "<A HREF=\"" +
+                                   timezoneList.get(realName) +
+                                   "\" TARGET=\"rightFrame\">" +
+                                   realName + "</A>)");
+                    } else {
+                        out2.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
+                                   "\" TARGET=\"rightFrame\">" + timezoneKey +
+                                   "</A>");
+                    }
+                    out2.write("<BR>\n");
+                }
+                out2.write("</TD>\n</TR>\n</TABLE>\n" + body2 + footer);
+
+                out2.close();
+                fw2.close();
+            }
+            out1.write("</FONT></TD>\n</TR></TABLE>\n" + body2 + footer);
+
+            out1.close();
+            fw1.close();
+
+
+            /* Creates allTimeZone-frame1.html (Sorted by GMT offsets) */
+            fw1 = new FileWriter(outputDir + "allTimeZone-frame1.html", false);
+            out1 = new BufferedWriter(fw1);
+
+            out1.write(header1 + new Date() + header2 + Main.getVersionName() +
+                       header4 + body1 +
+                       "<FONT size=\"+1\"><B>Sorted by GMT offsets</B></FONT>\n" +
+                       "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
+                       "<TR>\n<TD NOWRAP>\n");
+
+            List<Integer> roi = map.getRawOffsetsIndex();
+            List<Set<String>> roit = map.getRawOffsetsIndexTable();
+
+            int index = 0;
+            for (Integer offset : zonesByOffset.keySet()) {
+                int off = roi.get(index);
+                Set<String> perRO = zonesByOffset.get(offset);
+                if (offset == off) {
+                    // Merge aliases into zonesByOffset
+                    perRO.addAll(roit.get(index));
+                }
+                index++;
+
+                for (String timezoneKey : perRO) {
+                    out1.write("<TR>\n<TD><FONT SIZE=\"-1\">(" +
+                               Time.toGMTFormat(offset.toString()) +
+                               ")</FONT></TD>\n<TD>");
+
+                    if (a.containsKey(timezoneKey)) {
+                        Object realName = a.get(timezoneKey);
+                        while (a.containsKey(realName)) {
+                            realName = a.get(realName);
+                        }
+                        out1.write(timezoneKey +
+                                   " (alias for " + "<A HREF=\"" +
+                                   timezoneList.get(realName) +
+                                   "\" TARGET=\"rightFrame\">" + realName +
+                                   "</A>)");
+                    } else {
+                        out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
+                                   "\" TARGET=\"rightFrame\">" + timezoneKey +
+                                   "</A>");
+                    }
+                    out1.write("</TD>\n</TR>\n");
+                }
+            }
+            out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
+
+            out1.close();
+            fw1.close();
+
+
+            /* Creates allTimeZone-frame2.html (Sorted by zone names) */
+            fw1 = new FileWriter(outputDir + "allTimeZone-frame2.html", false);
+            out1 = new BufferedWriter(fw1);
+
+            out1.write(header1 + new Date() + header2 + Main.getVersionName() +
+                       header4 + body1 +
+                       "<FONT size=\"+1\"><B>Sorted by zone names</B></FONT>\n" +
+                       "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
+                       "<TR>\n<TD NOWRAP>\n");
+            o = timezoneList.keySet().toArray();
+            len = timezoneList.size();
+            for (int i = 0; i < len; i++) {
+                Object timezoneKey = o[i];
+                if (a.containsKey(timezoneKey)) {
+                    Object realName = a.get(timezoneKey);
+                    while (a.containsKey(realName)) {
+                        realName = a.get(realName);
+                    }
+                    out1.write(timezoneKey +
+                               " (alias for " +
+                               "<A HREF=\"" + timezoneList.get(realName) +
+                               "\" TARGET=\"rightFrame\">" + realName +
+                               "</A>)");
+                } else {
+                    out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
+                               "\" TARGET=\"rightFrame\">" + timezoneKey +
+                               "</A>");
+                }
+                out1.write("<BR> \n");
+            }
+            out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
+
+            out1.close();
+            fw1.close();
+
+            /* Creates allTimeZone-frame3.html (Sorted by city names) */
+            fw1 = new FileWriter(outputDir + "allTimeZone-frame3.html", false);
+            out1 = new BufferedWriter(fw1);
+
+            out1.write(header1 + new Date() + header2 + Main.getVersionName() +
+                       header4 + body1 +
+                       "<FONT size=\"+1\"><B>Sorted by city names</B></FONT>\n" +
+                       "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
+                       "<TR>\n<TD NOWRAP>\n");
+
+            Set<String> aliasSet = a.keySet();
+            len = aliasSet.size();
+            String aliasNames[] = aliasSet.toArray(new String[0]);
+            for (int i = 0; i < len; i++) {
+                displayNameList.put(transform(aliasNames[i]),
+                                    aliasNames[i]);
+            }
+
+            o = displayNameList.keySet().toArray();
+            len = displayNameList.size();
+            for (int i = 0; i < len; i++) {
+                Object displayName = o[i];
+                Object timezoneKey = displayNameList.get(o[i]);
+                if (a.containsKey(timezoneKey)) {
+                    Object realName = a.get(timezoneKey);
+                    while (a.containsKey(realName)) {
+                        realName = a.get(realName);
+                    }
+                    out1.write(displayName +
+                               " (alias for " +
+                               "<A HREF=\"" + timezoneList.get(realName) +
+                               "\" TARGET=\"rightFrame\">" + realName +
+                               "</A>)");
+                } else {
+                    out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
+                               "\" TARGET=\"rightFrame\">" + displayName +
+                               "</A>");
+                }
+                out1.write("<BR> \n");
+            }
+
+            out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
+
+            out1.close();
+            fw1.close();
+
+            /* Creates overview-summary.html */
+            fw1 = new FileWriter(outputDir + "overview-summary.html", false);
+            out1 = new BufferedWriter(fw1);
+
+            out1.write(header1 + new Date() + header2 + Main.getVersionName() +
+                       header4 + body1 +
+                       "<p>This is the list of time zones generated from <B>" +
+                       Main.getVersionName() + "</B> for Java Platform, " +
+                       "Standard Edition. The source code can be obtained " +
+                       "from ftp site <a href=\"ftp://elsie.nci.nih.gov/pub/\">" +
+                       "ftp://elsie.nci.nih.gov/pub/</a>. A total of <B>" +
+                       len +
+                       "</B> time zones and aliases are supported " +
+                       "in this edition. For the " +
+                       "format of rules and zones, refer to the zic " +
+                       "(zoneinfo compiler) man page on " +
+                       "Solaris or Linux.</p>\n" +
+                       "<p>Note that the time zone data is not " +
+                       "a public interface of the Java Platform. No " +
+                       "applications should rely on the time zone data of " +
+                       "this document. Time zone names and data " +
+                       "may change without any prior notice.</p>\n" +
+                       body2 + footer);
+
+            out1.close();
+            fw1.close();
+        } catch(IOException e) {
+            Main.panic("IO error: "+e.getMessage());
+            return 1;
+        }
+
+        return 0;
+    }
+
+    String transform(String s) {
+        int index = s.lastIndexOf("/");
+
+        /* If the string doesn't include any delimiter, return */
+        if (index == -1) {
+            return s;
+        }
+
+        int lastIndex = index;
+        String str = s.substring(index+1);
+        do {
+            index = s.substring(0, lastIndex).lastIndexOf('/');
+            str += ", " + s.substring(index+1, lastIndex);
+            lastIndex = index;
+        } while (index > -1);
+
+        return str;
+    }
+
+    static class LatitudeAndLongitude {
+
+        private int latDeg, latMin, latSec, longDeg, longMin, longSec;
+
+        LatitudeAndLongitude(String s) {
+            try {
+                // First of all, check the string has the correct format:
+                //    either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS
+
+                if (!s.startsWith("+") && !s.startsWith("-")) {
+                    Main.warning("Wrong latitude&longitude data: " + s);
+                    return;
+                }
+                int index;
+                if (((index = s.lastIndexOf("+")) <= 0) &&
+                    ((index = s.lastIndexOf("-")) <= 0)) {
+                    Main.warning("Wrong latitude&longitude data: " + s);
+                    return;
+                }
+
+                if (index == 5) {
+                    latDeg = Integer.parseInt(s.substring(1, 3));
+                    latMin = Integer.parseInt(s.substring(3, 5));
+                    latSec = 0;
+                } else if (index == 7) {
+                    latDeg = Integer.parseInt(s.substring(1, 3));
+                    latMin = Integer.parseInt(s.substring(3, 5));
+                    latSec = Integer.parseInt(s.substring(5, 7));
+                } else {
+                    Main.warning("Wrong latitude&longitude data: " + s);
+                    return;
+                }
+                if (s.startsWith("-")){
+                        latDeg = -latDeg;
+                        latMin = -latMin;
+                        latSec = -latSec;
+                }
+
+                int len = s.length();
+                if (index == 5 && len == 11) {
+                    longDeg = Integer.parseInt(s.substring(index+1, index+4));
+                    longMin = Integer.parseInt(s.substring(index+4, index+6));
+                    longSec = 0;
+                } else if (index == 7 && len == 15) {
+                    longDeg = Integer.parseInt(s.substring(index+1, index+4));
+                    longMin = Integer.parseInt(s.substring(index+4, index+6));
+                    longSec = Integer.parseInt(s.substring(index+6, index+8));
+                } else {
+                    Main.warning("Wrong latitude&longitude data: " + s);
+                    return;
+                }
+                if (s.charAt(index) == '-'){
+                        longDeg = -longDeg;
+                        longMin = -longMin;
+                        longSec = -longSec;
+                }
+            } catch(Exception e) {
+                Main.warning("LatitudeAndLongitude() Parse error: " + s);
+            }
+        }
+
+        int getLatDeg() {
+            return latDeg;
+        }
+
+        int getLatMin() {
+            return latMin;
+        }
+
+        int getLatSec() {
+            return latSec;
+        }
+
+        int getLongDeg() {
+            return longDeg;
+        }
+
+        int getLongMin() {
+            return longMin;
+        }
+
+        int getLongSec() {
+            return longSec;
+        }
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/Main.java b/jdk/test/sun/util/calendar/zi/Main.java
new file mode 100644
index 0000000..6fde7cd
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Main.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2000, 2011, 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Main class for the javazic time zone data compiler.
+ *
+ * @since 1.4
+ */
+public class Main {
+
+    private static boolean verbose = false;
+    static boolean outputDoc = false;
+
+    private List<String> ziFiles = new ArrayList<String>();
+    private static String zoneNamesFile = null;
+    private static String versionName = "unknown";
+    private static String outputDir = "zoneinfo";
+    private static String mapFile = null;
+
+    /**
+     * Parses the specified arguments and sets up the variables.
+     * @param argv the arguments
+     */
+    void processArgs(String[] argv) {
+        for (int i = 0; i < argv.length; i++) {
+            String arg = argv[i];
+            if (arg.startsWith("-h")) {
+                usage();
+                System.exit(0);
+            } else if (arg.equals("-d")) {
+                outputDir = argv[++i];
+            } else if (arg.equals("-v")) {
+                verbose = true;
+            } else if (arg.equals("-V")) {
+                versionName = argv[++i];
+            } else if (arg.equals("-doc")) {
+                outputDoc = true;
+            } else if (arg.equals("-map")) {
+                outputDoc = true;
+                mapFile = argv[++i];
+            } else if (arg.equals("-f")) {
+                zoneNamesFile = argv[++i];
+            } else if (arg.equals("-S")) {
+                try {
+                    Zoneinfo.setYear(Integer.parseInt(argv[++i]));
+                } catch (Exception e) {
+                    error("invalid year: " + argv[i]);
+                    usage();
+                    System.exit(1);
+                }
+            } else {
+                boolean isStartYear = arg.equals("-s");
+                if (isStartYear || arg.equals("-e")) {
+                    try {
+                        int year = Integer.parseInt(argv[++i]);
+                        if (isStartYear) {
+                            Zoneinfo.setStartYear(year);
+                        } else {
+                            Zoneinfo.setEndYear(year);
+                        }
+                    } catch (Exception e) {
+                        error("invalid year: " + argv[i]);
+                        usage();
+                        System.exit(1);
+                    }
+                } else {
+                    // the rest of args are zoneinfo source files
+                    while (i < argv.length) {
+                        ziFiles.add(argv[i++]);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Parses zoneinfo source files
+     */
+    int compile() {
+        int nFiles = ziFiles.size();
+        int status = 0;
+        Mappings maps = new Mappings();
+        BackEnd backend = BackEnd.getBackEnd();
+
+        for (int i = 0; i < nFiles; i++) {
+            Zoneinfo frontend = Zoneinfo.parse(ziFiles.get(i));
+
+            for (String key : frontend.getZones().keySet()) {
+                info(key);
+
+                Timezone tz = frontend.phase2(key);
+                status |= backend.processZoneinfo(tz);
+            }
+
+            maps.add(frontend);
+        }
+
+        // special code for dealing with the conflicting name "MET"
+        Zone.addMET();
+
+        maps.resolve();
+
+        status |= backend.generateSrc(maps);
+
+        return status;
+    }
+
+    public static void main(String[] argv) {
+        Main zic = new Main();
+
+        /*
+         * Parse args
+         */
+        zic.processArgs(argv);
+
+        /*
+         * Read target zone names
+         */
+        if (zoneNamesFile != null) {
+            Zone.readZoneNames(zoneNamesFile);
+        }
+
+        zic.compile();
+    }
+
+    void usage() {
+        System.err.println("Usage: javazic [options] file...\n"+
+                           "         -f namefile  file containing zone names\n"+
+                           "                      to be generated (ie, generating subset)\n"+
+                           "         -d dir       output directory\n"+
+                           "         -v           verbose\n"+
+                           "         -V datavers  specifies the tzdata version string\n"+
+                           "                      (eg, \"tzdata2000g\")"+
+                           "         -S year      output only SimleTimeZone data of that year\n"+
+                           "         -s year      start year (default: 1900)\n"+
+                           "         -e year      end year (default: 2037)\n"+
+                           "         -doc         generates HTML documents\n"+
+                           "         -map mapfile generates HTML documents with map information\n"+
+                           "         file...      zoneinfo source file(s)");
+    }
+
+    /**
+     * @return the output directory path name
+     */
+    static String getOutputDir() {
+        return outputDir;
+    }
+
+    /**
+     * @return the map file's path and name
+     */
+    static String getMapFile() {
+        return mapFile;
+    }
+
+    /**
+     * Returns the time zone data version string specified by the -V
+     * option. If it is not specified, "unknown" is returned.
+     * @return the time zone data version string
+     */
+    static String getVersionName() {
+        return versionName;
+    }
+
+    /**
+     * Prints out the specified fatal error message and calls {@link
+     * java.lang.System#exit System.exit(1)}.
+     * @param msg the fatal error message
+     */
+    static void panic(String msg) {
+        printMessage("fatal error", msg);
+        System.exit(1);
+    }
+
+    /**
+     * Prints out the specified error message.
+     * @param msg the error message
+     */
+    static void error(String msg) {
+        printMessage("error", msg);
+    }
+
+    /**
+     * Prints out the specified warning message.
+     * @param msg the warning message
+     */
+    static void warning(String msg) {
+        printMessage("warning", msg);
+    }
+
+    /**
+     * Prints out the informative message.
+     * @param msg the informative message
+     */
+    static void info(String msg) {
+        if (verbose) {
+            printMessage(null, msg);
+        }
+    }
+
+    private static void printMessage(String type, String msg) {
+        if (type != null) {
+            type += ": ";
+        } else {
+            type = "";
+        }
+        System.err.println("javazic: " + type + msg);
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/Mappings.java b/jdk/test/sun/util/calendar/zi/Mappings.java
new file mode 100644
index 0000000..2e12d86
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Mappings.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2000, 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.  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.
+ */
+
+import  java.util.ArrayList;
+import  java.util.HashMap;
+import  java.util.LinkedList;
+import  java.util.List;
+import  java.util.Map;
+import  java.util.Set;
+import  java.util.TreeMap;
+import  java.util.TreeSet;
+
+/**
+ * <code>Mappings</code> generates two Maps and a List which are used by
+ * javazic BackEnd.
+ *
+ * @since 1.4
+ */
+class Mappings {
+    // All aliases specified by Link statements. It's alias name to
+    // real name mappings.
+    private Map<String,String> aliases;
+
+    private List<Integer> rawOffsetsIndex;
+
+    private List<Set<String>> rawOffsetsIndexTable;
+
+    // Zone names to be excluded from rawOffset table. Those have GMT
+    // offsets to change some future time.
+    private List<String> excludeList;
+
+    /**
+     * Constructor creates some necessary instances.
+     */
+    Mappings() {
+        aliases = new TreeMap<String,String>();
+        rawOffsetsIndex = new LinkedList<Integer>();
+        rawOffsetsIndexTable = new LinkedList<Set<String>>();
+    }
+
+    /**
+     * Generates aliases and rawOffsets tables.
+     * @param zi a Zoneinfo containing Zones
+     */
+    void add(Zoneinfo zi) {
+        Map<String,Zone> zones = zi.getZones();
+
+        for (String zoneName : zones.keySet()) {
+            Zone zone = zones.get(zoneName);
+            String zonename = zone.getName();
+            int rawOffset = zone.get(zone.size()-1).getGmtOffset();
+
+            // If the GMT offset of this Zone will change in some
+            // future time, this Zone is added to the exclude list.
+            boolean isExcluded = false;
+            for (int i = 0; i < zone.size(); i++) {
+                ZoneRec zrec = zone.get(i);
+                if ((zrec.getGmtOffset() != rawOffset)
+                    && (zrec.getUntilTime(0) > Time.getCurrentTime())) {
+                    if (excludeList == null) {
+                        excludeList = new ArrayList<String>();
+                    }
+                    excludeList.add(zone.getName());
+                    isExcluded = true;
+                    break;
+                }
+            }
+
+            if (!rawOffsetsIndex.contains(new Integer(rawOffset))) {
+                // Find the index to insert this raw offset zones
+                int n = rawOffsetsIndex.size();
+                int i;
+                for (i = 0; i < n; i++) {
+                    if (rawOffsetsIndex.get(i) > rawOffset) {
+                        break;
+                    }
+                }
+                rawOffsetsIndex.add(i, rawOffset);
+
+                Set<String> perRawOffset = new TreeSet<String>();
+                if (!isExcluded) {
+                    perRawOffset.add(zonename);
+                }
+                rawOffsetsIndexTable.add(i, perRawOffset);
+            } else if (!isExcluded) {
+                int i = rawOffsetsIndex.indexOf(new Integer(rawOffset));
+                Set<String> perRawOffset = rawOffsetsIndexTable.get(i);
+                perRawOffset.add(zonename);
+            }
+        }
+
+        Map<String,String> a = zi.getAliases();
+        // If there are time zone names which refer to any of the
+        // excluded zones, add those names to the excluded list.
+        if (excludeList != null) {
+            for (String zoneName : a.keySet()) {
+                String realname = a.get(zoneName);
+                if (excludeList.contains(realname)) {
+                    excludeList.add(zoneName);
+                }
+            }
+        }
+        aliases.putAll(a);
+    }
+
+    /**
+     * Adds valid aliases to one of per-RawOffset table and removes
+     * invalid aliases from aliases List. Aliases referring to
+     * excluded zones are not added to a per-RawOffset table.
+     */
+    void resolve() {
+        int index = rawOffsetsIndexTable.size();
+        List<String> toBeRemoved = new ArrayList<String>();
+        for (String key : aliases.keySet()) {
+            boolean validname = false;
+            for (int j = 0; j < index; j++) {
+                Set<String> perRO = rawOffsetsIndexTable.get(j);
+                boolean isExcluded = (excludeList == null) ?
+                                        false : excludeList.contains(key);
+
+                if ((perRO.contains(aliases.get(key)) || isExcluded)
+                    && Zone.isTargetZone(key)) {
+                    validname = true;
+                    if (!isExcluded) {
+                        perRO.add(key);
+                        Main.info("Alias <"+key+"> added to the list.");
+                    }
+                    break;
+                }
+            }
+
+            if (!validname) {
+                Main.info("Alias <"+key+"> removed from the list.");
+                toBeRemoved.add(key);
+            }
+        }
+
+        // Remove zones, if any, from the list.
+        for (String key : toBeRemoved) {
+            aliases.remove(key);
+        }
+        // Eliminate any alias-to-alias mappings. For example, if
+        // there are A->B and B->C, A->B is changed to A->C.
+        Map<String, String> newMap = new HashMap<String, String>();
+        for (String key : aliases.keySet()) {
+            String realid = aliases.get(key);
+            String leaf = realid;
+            while (aliases.get(leaf) != null) {
+                leaf = aliases.get(leaf);
+            }
+            if (!realid.equals(leaf)) {
+                newMap.put(key, leaf);
+            }
+        }
+        aliases.putAll(newMap);
+    }
+
+    Map<String,String> getAliases() {
+        return(aliases);
+    }
+
+    List<Integer> getRawOffsetsIndex() {
+        return(rawOffsetsIndex);
+    }
+
+    List<Set<String>> getRawOffsetsIndexTable() {
+        return(rawOffsetsIndexTable);
+    }
+
+    List<String> getExcludeList() {
+        return excludeList;
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/Month.java b/jdk/test/sun/util/calendar/zi/Month.java
new file mode 100644
index 0000000..f2db5f1
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Month.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2000, 2004, 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.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Month enum handles month related manipulation.
+ *
+ * @since 1.4
+ */
+enum Month {
+    JANUARY("Jan"),
+    FEBRUARY("Feb"),
+    MARCH("Mar"),
+    APRIL("Apr"),
+    MAY("May"),
+    JUNE("Jun"),
+    JULY("Jul"),
+    AUGUST("Aug"),
+    SEPTEMBER("Sep"),
+    OCTOBER("Oct"),
+    NOVEMBER("Nov"),
+    DECEMBER("Dec");
+
+    private final String abbr;
+
+    private static final Map<String,Month> abbreviations
+                                = new HashMap<String,Month>(12);
+
+    static {
+        for (Month m : Month.values()) {
+            abbreviations.put(m.abbr, m);
+        }
+    }
+
+    private Month(String abbr) {
+        this.abbr = abbr;
+    }
+
+    int value() {
+        return ordinal() + 1;
+    }
+
+    /**
+     * Parses the specified string as a month abbreviation.
+     * @param name the month abbreviation
+     * @return the Month value
+     */
+    static Month parse(String name) {
+        Month m = abbreviations.get(name);
+        if (m != null) {
+            return m;
+        }
+        return null;
+    }
+
+    /**
+     * @param month the nunmth number (1-based)
+     * @return the month name in uppercase of the specified month
+     */
+    static String toString(int month) {
+        if (month >= JANUARY.value() && month <= DECEMBER.value()) {
+            return "Calendar." + Month.values()[month - 1];
+        }
+        throw new IllegalArgumentException("wrong month number: " + month);
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/Rule.java b/jdk/test/sun/util/calendar/zi/Rule.java
new file mode 100644
index 0000000..8e3a118
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Rule.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2000, 2004, 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Rule manipulates Rule records.
+ *
+ * @since 1.4
+ */
+class Rule {
+
+    private List<RuleRec> list;
+    private String name;
+
+    /**
+     * Constructs a Rule which consists of a Rule record list. The
+     * specified name is given to this Rule.
+     * @param name the Rule name
+     */
+    Rule(String name) {
+        this.name = name;
+        list = new ArrayList<RuleRec>();
+    }
+
+    /**
+     * Added a RuleRec to the Rule record list.
+     */
+    void add(RuleRec rec) {
+        list.add(rec);
+    }
+
+    /**
+     * @return the Rule name
+     */
+    String getName() {
+        return name;
+    }
+
+    /**
+     * Gets all rule records that cover the given year.
+     *
+     * @param year the year number for which the rule is applicable.
+     * @return rules in List that are collated in time. If no rule is found, an empty
+     * List is returned.
+     */
+    List<RuleRec> getRules(int year) {
+        List<RuleRec> rules = new ArrayList<RuleRec>(3);
+        for (RuleRec rec : list) {
+            if (year >= rec.getFromYear() && year <= rec.getToYear()) {
+                if ((rec.isOdd() && year % 2 == 0) || (rec.isEven() && year % 2 == 1))
+                    continue;
+                rules.add(rec);
+            }
+        }
+        int n = rules.size();
+        if (n <= 1) {
+            return rules;
+        }
+        if (n == 2) {
+            RuleRec rec1 = rules.get(0);
+            RuleRec rec2 = rules.get(1);
+            if (rec1.getMonthNum() > rec2.getMonthNum()) {
+                rules.set(0, rec2);
+                rules.set(1, rec1);
+            } else if (rec1.getMonthNum() == rec2.getMonthNum()) {
+                // TODO: it's not accurate to ignore time types (STD, WALL, UTC)
+                long t1 = Time.getLocalTime(year, rec1.getMonth(),
+                                            rec1.getDay(), rec1.getTime().getTime());
+                long t2 = Time.getLocalTime(year, rec2.getMonth(),
+                                            rec2.getDay(), rec2.getTime().getTime());
+                if (t1 > t2) {
+                    rules.set(0, rec2);
+                    rules.set(1, rec1);
+                }
+            }
+            return rules;
+        }
+
+        final int y = year;
+        RuleRec[] recs = new RuleRec[rules.size()];
+        rules.toArray(recs);
+        Arrays.sort(recs, new Comparator<RuleRec>() {
+                public int compare(RuleRec r1, RuleRec r2) {
+                    int n = r1.getMonthNum() - r2.getMonthNum();
+                    if (n != 0) {
+                        return n;
+                    }
+                    // TODO: it's not accurate to ignore time types (STD, WALL, UTC)
+                    long t1 = Time.getLocalTime(y, r1.getMonth(),
+                                                r1.getDay(), r1.getTime().getTime());
+                    long t2 = Time.getLocalTime(y, r2.getMonth(),
+                                                r2.getDay(), r2.getTime().getTime());
+                    return (int)(t1 - t2);
+                }
+                public boolean equals(Object o) {
+                    return this == o;
+                }
+            });
+        rules.clear();
+        for (int i = 0; i < n; i++) {
+            rules.add(recs[i]);
+        }
+        return rules;
+    }
+
+    /**
+     * Gets rule records that have either "max" or cover the endYear
+     * value in its DST schedule.
+     *
+     * @return rules that contain last DST schedule. An empty
+     * ArrayList is returned if no last rules are found.
+     */
+    List<RuleRec> getLastRules() {
+        RuleRec start = null;
+        RuleRec end = null;
+
+        for (int i = 0; i < list.size(); i++) {
+            RuleRec rec = list.get(i);
+            if (rec.isLastRule()) {
+                if (rec.getSave() > 0) {
+                    start = rec;
+                } else {
+                    end = rec;
+                }
+            }
+        }
+        if (start == null || end == null) {
+            int endYear = Zoneinfo.getEndYear();
+            for (int i  = 0; i < list.size(); i++) {
+                RuleRec rec = list.get(i);
+                if (endYear >= rec.getFromYear() && endYear <= rec.getToYear()) {
+                    if (start == null && rec.getSave() > 0) {
+                        start = rec;
+                    } else {
+                        if (end == null && rec.getSave() == 0) {
+                            end = rec;
+                        }
+                    }
+                }
+            }
+        }
+
+        List<RuleRec> r = new ArrayList<RuleRec>(2);
+        if (start == null || end == null) {
+            if (start != null || end != null) {
+                Main.warning("found last rules for "+name+" inconsistent.");
+            }
+            return r;
+        }
+
+        r.add(start);
+        r.add(end);
+        return r;
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/RuleDay.java b/jdk/test/sun/util/calendar/zi/RuleDay.java
new file mode 100644
index 0000000..a9e83ac
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/RuleDay.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2000, 2010, 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.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RuleDay class represents the value of the "ON" field.  The day of
+ * week values start from 1 following the {@link java.util.Calendar}
+ * convention.
+ *
+ * @since 1.4
+ */
+class RuleDay {
+    private static final Map<String,DayOfWeek> abbreviations = new HashMap<String,DayOfWeek>(7);
+    static {
+        for (DayOfWeek day : DayOfWeek.values()) {
+            abbreviations.put(day.getAbbr(), day);
+        }
+    }
+
+    private String dayName = null;
+    private DayOfWeek dow;
+    private boolean lastOne = false;
+    private int soonerOrLater = 0;
+    private int thanDayOfMonth; // day of month (e.g., 8 for "Sun>=8")
+
+    RuleDay() {
+    }
+
+    RuleDay(int day) {
+        thanDayOfMonth = day;
+    }
+
+    int getDay() {
+        return thanDayOfMonth;
+    }
+
+    /**
+     * @return the day of week value (1-based)
+     */
+    int getDayOfWeekNum() {
+        return dow.value();
+    }
+
+    /**
+     * @return true if this rule day represents the last day of
+     * week. (e.g., lastSun).
+     */
+    boolean isLast() {
+        return lastOne;
+    }
+
+    /**
+     * @return true if this rule day represents the day of week on or
+     * later than (after) the {@link #getDay}. (e.g., Sun>=1)
+     */
+    boolean isLater() {
+        return soonerOrLater > 0;
+    }
+
+    /**
+     * @return true if this rule day represents the day of week on or
+     * earlier than (before) the {@link #getDay}. (e.g., Sun<=15)
+     */
+    boolean isEarlier() {
+        return soonerOrLater < 0;
+    }
+
+    /**
+     * @return true if this rule day represents an exact day.
+     */
+    boolean isExact() {
+        return soonerOrLater == 0;
+    }
+
+    /**
+     * Parses the "ON" field and constructs a RuleDay.
+     * @param day an "ON" field string (e.g., "Sun>=1")
+     * @return a RuleDay representing the given "ON" field
+     */
+    static RuleDay parse(String day) {
+        RuleDay d = new RuleDay();
+        if (day.startsWith("last")) {
+            d.lastOne = true;
+            d.dayName = day.substring(4);
+            d.dow = getDOW(d.dayName);
+        } else {
+            int index;
+            if ((index = day.indexOf(">=")) != -1) {
+                d.dayName = day.substring(0, index);
+                d.dow = getDOW(d.dayName);
+                d.soonerOrLater = 1; // greater or equal
+                d.thanDayOfMonth = Integer.parseInt(day.substring(index+2));
+            } else if ((index = day.indexOf("<=")) != -1) {
+                d.dayName = day.substring(0, index);
+                d.dow = getDOW(d.dayName);
+                d.soonerOrLater = -1; // less or equal
+                d.thanDayOfMonth = Integer.parseInt(day.substring(index+2));
+            } else {
+                // it should be an integer value.
+                d.thanDayOfMonth = Integer.parseInt(day);
+            }
+        }
+        return d;
+    }
+
+    /**
+     * Converts this RuleDay to the SimpleTimeZone day rule.
+     * @return the converted SimpleTimeZone day rule
+     */
+    int getDayForSimpleTimeZone() {
+        if (isLast()) {
+            return -1;
+        }
+        return isEarlier() ? -getDay() : getDay();
+    }
+
+    /**
+     * Converts this RuleDay to the SimpleTimeZone day-of-week rule.
+     * @return the SimpleTimeZone day-of-week rule value
+     */
+    int getDayOfWeekForSimpleTimeZoneInt() {
+        if (isEarlier() || isLater()) {
+            return -getDayOfWeekNum();
+        }
+        return isLast() ? getDayOfWeekNum() : 0;
+    }
+
+    /**
+     * @return the string representation of the {@link
+     * #getDayOfWeekForSimpleTimeZoneInt} value
+     */
+    String getDayOfWeekForSimpleTimeZone() {
+        int d = getDayOfWeekForSimpleTimeZoneInt();
+        if (d == 0) {
+            return "0";
+        }
+        String sign = "";
+        if (d < 0) {
+            sign = "-";
+            d = -d;
+        }
+        return sign + toString(d);
+    }
+
+    private static DayOfWeek getDOW(String abbr) {
+        return abbreviations.get(abbr);
+    }
+
+    /**
+     * Converts the specified day of week value to the day-of-week
+     * name defined in {@link java.util.Calenda}.
+     * @param dow 1-based day of week value
+     * @return the Calendar day of week name with "Calendar." prefix.
+     * @throws IllegalArgumentException if the specified dow value is out of range.
+     */
+    static String toString(int dow) {
+        if (dow >= DayOfWeek.SUNDAY.value() && dow <= DayOfWeek.SATURDAY.value()) {
+            return "Calendar." + DayOfWeek.values()[dow - 1];
+        }
+        throw new IllegalArgumentException("wrong Day_of_Week number: " + dow);
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/RuleRec.java b/jdk/test/sun/util/calendar/zi/RuleRec.java
new file mode 100644
index 0000000..c0a5785
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/RuleRec.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2000, 2004, 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.
+ */
+
+import java.util.StringTokenizer;
+
+/**
+ * RuleRec class represents one record of the Rule set.
+ *
+ * @since 1.4
+ */
+class RuleRec {
+    private int fromYear;
+    private int toYear;
+    private String type;
+    private Month inMonth;
+    private RuleDay onDay;
+    private Time atTime;
+    private int save;
+    private String letters;
+    private String line;
+    private boolean isLastRule;
+
+    int getFromYear() {
+        return fromYear;
+    }
+
+    int getToYear() {
+        return toYear;
+    }
+
+    Month getMonth() {
+        return inMonth;
+    }
+
+    int getMonthNum() {
+        return inMonth.value();
+    }
+
+    RuleDay getDay() {
+        return onDay;
+    }
+
+    Time getTime() {
+        return atTime;
+    }
+
+    int getSave() {
+        return save;
+    }
+
+    String getLine() {
+        return line;
+    }
+
+    /**
+     * Sets the line from the text file.
+     * @param line the text of the line
+     */
+    void setLine(String line) {
+        this.line = line;
+    }
+
+    /**
+     * @return true if the rule type is "odd".
+     */
+    boolean isOdd() {
+        return "odd".equals(type);
+    }
+
+    /**
+     * @return true if the rule type is "even".
+     */
+    boolean isEven() {
+        return "even".equals(type);
+    }
+
+    /**
+     * Determines if this rule record is the last DST schedule rule.
+     *
+     * @return true if this rule record has "max" as TO (year).
+     */
+    boolean isLastRule() {
+        return isLastRule;
+    }
+
+    /**
+     * Determines if the unadjusted until time of the specified ZoneRec
+     * is the same as the transition time of this rule in the same
+     * year as the ZoneRec until year.
+     *
+     * @param zrec ZoneRec to compare to
+     * @param save the amount of daylight saving in milliseconds
+     * @param gmtOffset the GMT offset value in milliseconds
+     * @return true if the unadjusted until time is the same as rule's
+     * transition time.
+     */
+    boolean isSameTransition(ZoneRec zrec, int save, int gmtOffset) {
+        long    until, transition;
+
+        if (zrec.getUntilTime().getType() != atTime.getType()) {
+            until = zrec.getLocalUntilTime(save, gmtOffset);
+            transition = Time.getLocalTime(zrec.getUntilYear(),
+                                           getMonth(),
+                                           getDay(),
+                                           save,
+                                           gmtOffset,
+                                           atTime);
+        } else {
+            until = zrec.getLocalUntilTime();
+            transition = Time.getLocalTime(zrec.getUntilYear(),
+                                           getMonth(),
+                                           getDay(),
+                                           atTime.getTime());
+        }
+
+        return until == transition;
+    }
+
+    /**
+     * Parses a Rule line and returns a RuleRec object.
+     *
+     * @param tokens a StringTokenizer object that should contain a
+     * token for the "FROM" field and the rest.
+     * @return a RuleRec object.
+     */
+    static RuleRec parse(StringTokenizer tokens) {
+        RuleRec rec = new RuleRec();
+        try {
+            // FROM
+            String token = tokens.nextToken();
+            try {
+                rec.fromYear = Integer.parseInt(token);
+            } catch (NumberFormatException e) {
+                // it's not integer
+                if ("min".equals(token) || "minimum".equals(token)) {
+                    rec.fromYear = Zoneinfo.getMinYear();
+                } else if ("max".equals(token) || "maximum".equals(token)) {
+                    rec.fromYear = Zoneinfo.getMaxYear();
+                } else {
+                    Main.panic("invalid year value: "+token);
+                }
+            }
+
+            // TO
+            token = tokens.nextToken();
+            rec.isLastRule = false;
+            try {
+                rec.toYear = Integer.parseInt(token);
+            } catch (NumberFormatException e) {
+                // it's not integer
+                if ("min".equals(token) || "minimum".equals(token)) {
+                    rec.fromYear = Zoneinfo.getMinYear();
+                } else if ("max".equals(token) || "maximum".equals(token)) {
+                    rec.toYear = Integer.MAX_VALUE;
+                    rec.isLastRule = true;
+                } else if ("only".equals(token)) {
+                    rec.toYear = rec.fromYear;
+                } else {
+                    Main.panic("invalid year value: "+token);
+                }
+            }
+
+            // TYPE
+            rec.type = tokens.nextToken();
+
+            // IN
+            rec.inMonth = Month.parse(tokens.nextToken());
+
+            // ON
+            rec.onDay = RuleDay.parse(tokens.nextToken());
+
+            // AT
+            rec.atTime = Time.parse(tokens.nextToken());
+
+            // SAVE
+            rec.save = (int) Time.parse(tokens.nextToken()).getTime();
+
+            // LETTER/S
+            rec.letters = tokens.nextToken();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return rec;
+    }
+
+    /**
+     * Calculates the transition time of the given year under this rule.
+     * @param year the year value
+     * @param gmtOffset the GMT offset value in milliseconds
+     * @param save the amount of daylight save time
+     * @return the transition time in milliseconds of the given year in UTC.
+     */
+    long getTransitionTime(int year, int gmtOffset, int save) {
+        long time = Time.getLocalTime(year, getMonth(),
+                                      getDay(), atTime.getTime());
+        if (atTime.isSTD()) {
+            time -= gmtOffset;
+        } else if (atTime.isWall()) {
+            time -= gmtOffset + save;
+        }
+        return time;
+    }
+
+    private static int getInt(StringTokenizer tokens) {
+        String token = tokens.nextToken();
+        return Integer.parseInt(token);
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/Simple.java b/jdk/test/sun/util/calendar/zi/Simple.java
new file mode 100644
index 0000000..b61ffea
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Simple.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2000, 2011, 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.
+ */
+
+import  java.io.BufferedWriter;
+import  java.io.File;
+import  java.io.FileWriter;
+import  java.io.IOException;
+import  java.util.HashMap;
+import  java.util.List;
+import  java.util.Map;
+import  java.util.Set;
+import  java.util.SortedMap;
+import  java.util.TreeMap;
+import  java.util.TreeSet;
+
+/**
+ * <code>Simple</code> generates TimeZoneData, which had been used as internal
+ * data of TimeZone before J2SDK1.3.
+ * Since J2SDK1.4 doesn't need TimeZoneData, this class is for maintenance
+ * of old JDK release.
+ */
+class Simple extends BackEnd {
+
+    /**
+     * Zone records which are applied for given year.
+     */
+    private static Map<String,ZoneRec> lastZoneRecs = new HashMap<>();
+
+    /**
+     * Rule records which are applied for given year.
+     */
+    private static Map<String,List<RuleRec>> lastRules = new TreeMap<>();
+
+    /**
+     * zone IDs sorted by their GMT offsets. If zone's GMT
+     * offset will change in the future, its last known offset is
+     * used.
+     */
+    private SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<>();
+
+    /**
+     * Sets last Rule records and Zone records for given timezone to
+     * each Map.
+     *
+     * @param tz Timezone object for each zone
+     * @return always 0
+     */
+    int processZoneinfo(Timezone tz) {
+        String zonename = tz.getName();
+
+        lastRules.put(zonename, tz.getLastRules());
+        lastZoneRecs.put(zonename, tz.getLastZoneRec());
+
+        // Populate zonesByOffset. (Zones that will change their
+        // GMT offsets are also added to zonesByOffset here.)
+        int lastKnownOffset = tz.getRawOffset();
+        Set<String> set = zonesByOffset.get(lastKnownOffset);
+        if (set == null) {
+            set = new TreeSet<>();
+            zonesByOffset.put(lastKnownOffset, set);
+        }
+        set.add(zonename);
+
+        return 0;
+    }
+
+    /**
+     * Generates TimeZoneData to output SimpleTimeZone data.
+     * @param map Mappings object which is generated by {@link Main#compile}.
+     * @return 0 if no error occurred, otherwise 1.
+     */
+    int generateSrc(Mappings map) {
+        try {
+            File outD = new File(Main.getOutputDir());
+            outD.mkdirs();
+
+            FileWriter fw =
+                new FileWriter(new File(outD, "TimeZoneData.java"), false);
+            BufferedWriter out = new BufferedWriter(fw);
+
+            out.write("import java.util.SimpleTimeZone;\n\n");
+            out.write("    static SimpleTimeZone zones[] = {\n");
+
+            Map<String,String> a = map.getAliases();
+            List<Integer> roi = map.getRawOffsetsIndex();
+            List<Set<String>> roit = map.getRawOffsetsIndexTable();
+
+            int index = 0;
+            for (int offset : zonesByOffset.keySet()) {
+                int o = roi.get(index);
+                Set<String> set = zonesByOffset.get(offset);
+                if (offset == o) {
+                    // Merge aliases into zonesByOffset
+                    set.addAll(roit.get(index));
+                }
+                index++;
+
+                for (String key : set) {
+                    ZoneRec zrec;
+                    String realname;
+                    List<RuleRec> stz;
+                    if ((realname = a.get(key)) != null) {
+                        // if this alias is not targeted, ignore it.
+                        if (!Zone.isTargetZone(key)) {
+                            continue;
+                        }
+                        stz = lastRules.get(realname);
+                        zrec = lastZoneRecs.get(realname);
+                    } else {
+                        stz = lastRules.get(key);
+                        zrec = lastZoneRecs.get(key);
+                    }
+
+                    out.write("\t//--------------------------------------------------------------------\n");
+                    String s = Time.toFormedString(offset);
+                    out.write("\tnew SimpleTimeZone(" +
+                        Time.toFormedString(offset) + ", \"" + key + "\"");
+                    if (realname != null) {
+                        out.write(" /* " + realname + " */");
+                    }
+
+                    if (stz == null) {
+                        out.write("),\n");
+                    } else {
+                        RuleRec rr0 = stz.get(0);
+                        RuleRec rr1 = stz.get(1);
+
+                        out.write(",\n\t  " + Month.toString(rr0.getMonthNum()) +
+                                  ", " + rr0.getDay().getDayForSimpleTimeZone() + ", " +
+                                  rr0.getDay().getDayOfWeekForSimpleTimeZone() + ", " +
+                                  Time.toFormedString((int)rr0.getTime().getTime()) + ", " +
+                                  rr0.getTime().getTypeForSimpleTimeZone() + ",\n" +
+
+                                  "\t  " + Month.toString(rr1.getMonthNum()) + ", " +
+                                  rr1.getDay().getDayForSimpleTimeZone() + ", " +
+                                  rr1.getDay().getDayOfWeekForSimpleTimeZone() + ", " +
+                                  Time.toFormedString((int)rr1.getTime().getTime())+ ", " +
+                                  rr1.getTime().getTypeForSimpleTimeZone() + ",\n" +
+
+                                  "\t  " + Time.toFormedString(rr0.getSave()) + "),\n");
+
+                        out.write("\t// " + rr0.getLine() + "\n");
+                        out.write("\t// " + rr1.getLine() + "\n");
+                    }
+
+                    String zline = zrec.getLine();
+                    if (zline.indexOf("Zone") == -1) {
+                        zline = "Zone " + key + "\t" + zline.trim();
+                    }
+                    out.write("\t// " + zline + "\n");
+                }
+            }
+            out.write("    };\n");
+
+            out.close();
+            fw.close();
+        } catch(IOException e) {
+            Main.panic("IO error: "+e.getMessage());
+            return 1;
+        }
+
+        return 0;
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java b/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java
new file mode 100644
index 0000000..f1191c6
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java
@@ -0,0 +1,231 @@
+/*
+ * 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 8007572 8008161
+ *@summary Test whether the TimeZone generated from JSR310 tzdb is the same
+ *as the one from the tz data from javazic
+ */
+
+import java.io.File;
+import java.lang.reflect.*;
+import java.nio.file.*;
+import java.util.*;
+import java.util.regex.*;
+import java.time.zone.*;
+import java.time.ZoneId;
+
+public class TestZoneInfo310 {
+
+    public static void main(String[] args) throws Throwable {
+
+        String TESTDIR = System.getProperty("test.dir", ".");
+        String SRCDIR = System.getProperty("test.src", ".");
+        String tzdir = SRCDIR + File.separator + "tzdata";
+        String tzfiles = "africa antarctica asia australasia europe northamerica pacificnew southamerica backward etcetera systemv";
+        String jdk_tzdir = SRCDIR + File.separator + "tzdata_jdk";
+        String jdk_tzfiles = "gmt jdk11_backward";
+        String zidir = TESTDIR + File.separator + "zi";
+        File fZidir = new File(zidir);
+        if (!fZidir.exists()) {
+            fZidir.mkdirs();
+        }
+        Matcher m = Pattern.compile("tzdata(?<ver>[0-9]{4}[A-z])")
+                           .matcher(new String(Files.readAllBytes(Paths.get(tzdir, "VERSION")), "ascii"));
+        String ver = m.find() ? m.group("ver") : "NULL";
+
+        ArrayList<String> alist = new ArrayList<>();
+        alist.add("-V");
+        alist.add(ver);
+        alist.add("-d");
+        alist.add(zidir);
+        for (String f : tzfiles.split(" ")) {
+            alist.add(tzdir + File.separator + f);
+        }
+        for (String f : jdk_tzfiles.split(" ")) {
+            alist.add(jdk_tzdir + File.separator + f);
+        }
+        System.out.println("Compiling tz files!");
+        Main.main(alist.toArray(new String[alist.size()]));
+        //////////////////////////////////
+
+        System.out.println("testing!");
+        ZoneInfoFile.ziDir = zidir;
+        long t0, t1;
+
+        t0 = System.nanoTime();
+        ZoneInfoOld.getTimeZone("America/Los_Angeles");
+        t1 = System.nanoTime();
+        System.out.printf("OLD.getZoneInfoOld()[1]=%d%n", (t1 - t0) / 1000);
+
+        t0 = System.nanoTime();
+        ZoneInfoOld.getTimeZone("America/New_York");
+        t1 = System.nanoTime();
+        System.out.printf("OLD.getZoneInfoOld()[2]=%d%n", (t1 - t0) / 1000);
+
+        t0 = System.nanoTime();
+        ZoneInfoOld.getTimeZone("America/Denver");
+        t1 = System.nanoTime();
+        System.out.printf("OLD.getZoneInfoOld()[3]=%d%n", (t1 - t0) / 1000);
+
+        t0 = System.nanoTime();
+        String[] zids_old = ZoneInfoOld.getAvailableIDs();
+        t1 = System.nanoTime();
+        System.out.printf("OLD.getAvailableIDs()=%d, total=%d%n",
+                          (t1 - t0) / 1000, zids_old.length);
+        Arrays.sort(zids_old);
+
+        t0 = System.nanoTime();
+        ZoneId.of("America/Los_Angeles").getRules();
+        t1 = System.nanoTime();
+        System.out.printf("NEW.getTimeZone()[1]=%d%n", (t1 - t0) / 1000);
+
+        t0 = System.nanoTime();
+        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+        t1 = System.nanoTime();
+        System.out.printf("NEW.getTimeZone()[1]=%d%n", (t1 - t0) / 1000);
+
+        t0 = System.nanoTime();
+        tz = TimeZone.getTimeZone("America/New_York");
+        t1 = System.nanoTime();
+        System.out.printf("NEW.getTimeZone()[2]=%d%n", (t1 - t0) / 1000);
+
+        t0 = System.nanoTime();
+        tz = TimeZone.getTimeZone("America/Denver");
+        t1 = System.nanoTime();
+        System.out.printf("NEW.getTimeZone()[3]=%d%n", (t1 - t0) / 1000);
+
+        t0 = System.nanoTime();
+        String[] zids_new = TimeZone.getAvailableIDs();
+        t1 = System.nanoTime();
+        System.out.printf("NEW.getAvailableIDs()=%d, total=%d%n",
+                          (t1 - t0) / 1000, zids_new.length);
+        Arrays.sort(zids_new);
+
+        t0 = System.currentTimeMillis();
+        for (String zid : zids_new) {
+            TimeZone.getTimeZone(zid);
+        }
+        t1 = System.currentTimeMillis();
+        System.out.printf("NEW.TotalTZ()=%d (ms)%n", t1 - t0);
+
+        t0 = System.currentTimeMillis();
+        for (String zid : zids_old) {
+            ZoneInfoOld.getTimeZone(zid);
+        }
+        t1 = System.currentTimeMillis();
+        System.out.printf("OLD.TotalTZ()=%d (ms)%n", t1 - t0);
+
+        if (!Arrays.equals(zids_old, zids_new)) {
+            throw new RuntimeException("  FAILED:  availableIds don't match");
+        }
+        for (String zid : zids_new) {
+            ZoneInfoOld zi = toZoneInfoOld(TimeZone.getTimeZone(zid));
+            ZoneInfoOld ziOLD = (ZoneInfoOld)ZoneInfoOld.getTimeZone(zid);
+            if (! zi.equalsTo(ziOLD)) {
+                System.out.println(zi.diffsTo(ziOLD));
+                throw new RuntimeException("  FAILED:  " + zid);
+            }
+        }
+        delete(fZidir);
+
+        // test tzdb version
+        if (!ver.equals(sun.util.calendar.ZoneInfoFile.getVersion())) {
+            System.out.printf("  FAILED:  ver=%s, expected=%s%n",
+                              sun.util.calendar.ZoneInfoFile.getVersion(), ver);
+            throw new RuntimeException("Version test failed");
+        }
+
+        // test getAvailableIDs(raw);
+        zids_new = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);
+        //Arrays.sort(zids_new);
+        zids_old = ZoneInfoOld.getAvailableIDs(-8 * 60 * 60 * 1000);
+        if (!Arrays.equals(zids_new, zids_old)) {
+            System.out.println("------------------------");
+            System.out.println("NEW.getAvailableIDs(-8:00)");
+            for (String zid : zids_new) {
+                System.out.println(zid);
+            }
+            System.out.println("------------------------");
+            System.out.println("OLD.getAvailableIDs(-8:00)");
+            for (String zid : zids_old) {
+                System.out.println(zid);
+            }
+            throw new RuntimeException("  FAILED:  availableIds(offset) don't match");
+        }
+    }
+
+    private static void delete(File f) {
+        if (f.isDirectory()) {
+            for (File f0 : f.listFiles()) {
+               delete(f0);
+            }
+        }
+        f.delete();
+     }
+
+    // to access sun.util.calendar.ZoneInfo's private fields
+    static Class<?> ziClz;
+    static Field rawOffset;
+    static Field checksum;
+    static Field dstSavings;
+    static Field transitions;
+    static Field offsets;
+    static Field simpleTimeZoneParams;
+    static Field willGMTOffsetChange;
+    static {
+        try {
+            ziClz = Class.forName("sun.util.calendar.ZoneInfo");
+            rawOffset = ziClz.getDeclaredField("rawOffset");
+            checksum = ziClz.getDeclaredField("checksum");
+            dstSavings = ziClz.getDeclaredField("dstSavings");
+            transitions = ziClz.getDeclaredField("transitions");
+            offsets = ziClz.getDeclaredField("offsets");
+            simpleTimeZoneParams = ziClz.getDeclaredField("simpleTimeZoneParams");
+            willGMTOffsetChange = ziClz.getDeclaredField("willGMTOffsetChange");
+            rawOffset.setAccessible(true);
+            checksum.setAccessible(true);
+            dstSavings.setAccessible(true);
+            transitions.setAccessible(true);
+            offsets.setAccessible(true);
+            simpleTimeZoneParams.setAccessible(true);
+            willGMTOffsetChange.setAccessible(true);
+        } catch (Exception x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    private static ZoneInfoOld toZoneInfoOld(TimeZone tz) throws Exception {
+        return new ZoneInfoOld(tz.getID(),
+                               rawOffset.getInt(tz),
+                               dstSavings.getInt(tz),
+                               checksum.getInt(tz),
+                               (long[])transitions.get(tz),
+                               (int[])offsets.get(tz),
+                               (int[])simpleTimeZoneParams.get(tz),
+                               willGMTOffsetChange.getBoolean(tz));
+    }
+
+
+}
diff --git a/jdk/test/sun/util/calendar/zi/Time.java b/jdk/test/sun/util/calendar/zi/Time.java
new file mode 100644
index 0000000..8f82e14
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Time.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2000, 2011, 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.
+ */
+
+import java.util.Locale;
+import sun.util.calendar.CalendarDate;
+import sun.util.calendar.CalendarSystem;
+import sun.util.calendar.Gregorian;
+
+/**
+ * Time class represents the "AT" field and other time related information.
+ *
+ * @since 1.4
+ */
+class Time {
+
+    static final Gregorian gcal = CalendarSystem.getGregorianCalendar();
+
+    // type is wall clock time
+    private static final int WALL = 1;
+
+    // type is standard time
+    private static final int STD = 2;
+
+    // type is UTC
+    private static final int UTC = 3;
+
+    // type of representing time
+    private int type;
+
+    /**
+     * Time from the EPOCH in milliseconds
+     */
+    private long time;
+
+    /**
+     * Current time in milliseconds
+     */
+    private static final long currentTime = System.currentTimeMillis();
+
+    Time() {
+        time = 0L;
+    }
+
+    Time(long time) {
+        this.time = time;
+    }
+
+    void setType(int type) {
+        this.type = type;
+    }
+
+    long getTime() {
+        return time;
+    }
+
+    int getType() {
+        return type;
+    }
+
+    static long getCurrentTime() {
+        return currentTime;
+    }
+
+    /**
+     * @return true if the time is represented in wall-clock time.
+     */
+    boolean isWall() {
+        return type == WALL;
+    }
+
+    /**
+     * @return true if the time is represented in standard time.
+     */
+    boolean isSTD() {
+        return type == STD;
+    }
+
+    /**
+     * @return true if the time is represented in UTC time.
+     */
+    boolean isUTC() {
+        return type == UTC;
+    }
+
+    /**
+     * Converts the type to a string that represents the type in the
+     * SimpleTimeZone time mode. (e.g., "SimpleTimeZone.WALL_TIME").
+     * @return the converted string or null if the type is undefined.
+     */
+    String getTypeForSimpleTimeZone() {
+        String  stz = "SimpleTimeZone.";
+        if (isWall()) {
+            return stz+"WALL_TIME";
+        }
+        else if (isSTD()) {
+            return stz+"STANDARD_TIME";
+        }
+        else if (isUTC()) {
+            return stz+"UTC_TIME";
+        }
+        else {
+            return null;
+        }
+    }
+
+    /**
+     * Converts the given Gregorian calendar field values to local time.
+     * Local time is represented by the amount of milliseconds from
+     * January 1, 1970 0:00 GMT.
+     * @param year the year value
+     * @param month the Month value
+     * @param day the day represented by {@link RuleDay}
+     * @param save the amount of daylight time in milliseconds
+     * @param gmtOffset the GMT offset in milliseconds
+     * @param time the time of the day represented by {@link Time}
+     * @return local time
+     */
+    static long getLocalTime(int year, Month month, RuleDay day, int save,
+                             int gmtOffset, Time time) {
+        long    t = time.getTime();
+
+        if (time.isSTD())
+            t = time.getTime() + save;
+        else if (time.isUTC())
+            t = time.getTime() + save + gmtOffset;
+
+        return getLocalTime(year, month, day, t);
+    }
+
+    /**
+     * Converts the given Gregorian calendar field values to local time.
+     * Local time is represented by the amount of milliseconds from
+     * January 1, 1970 0:00 GMT.
+     * @param year the year value
+     * @param month the Month value
+     * @param day the day value
+     * @param time the time of the day in milliseconds
+     * @return local time
+     */
+    static long getLocalTime(int year, Month month, int day, long time) {
+        CalendarDate date = gcal.newCalendarDate(null);
+        date.setDate(year, month.value(), day);
+        long millis = gcal.getTime(date);
+        return millis + time;
+    }
+
+    /**
+     * Equivalent to <code>getLocalTime(year, month, day, (long)time)</code>.
+     * @param year the year value
+     * @param month the Month value
+     * @param day the day value
+     * @param time the time of the day in milliseconds
+     * @return local time
+     */
+    static long getLocalTime(int year, Month month, int day, int time) {
+        return getLocalTime(year, month, day, (long)time);
+    }
+
+    /**
+     * Equivalent to {@link #getLocalTime(int, Month, RuleDay, int)
+     * getLocalTime(year, month, day, (int) time)}.
+     * @param year the year value
+     * @param month the Month value
+     * @param day the day represented by {@link RuleDay}
+     * @param time the time of the day represented by {@link Time}
+     * @return local time
+     */
+    static long getLocalTime(int year, Month month, RuleDay day, long time) {
+        return getLocalTime(year, month, day, (int) time);
+    }
+
+    /**
+     * Converts the given Gregorian calendar field values to local time.
+     * Local time is represented by the amount of milliseconds from
+     * January 1, 1970 0:00 GMT.
+     * @param year the year value
+     * @param month the Month value
+     * @param day the day represented by {@link RuleDay}
+     * @param time the time of the day represented by {@link Time}
+     * @return local time
+     */
+    static long getLocalTime(int year, Month month, RuleDay day, int time) {
+        CalendarDate cdate = gcal.newCalendarDate(null);
+        int monthValue = month.value();
+
+        if (day.isLast()) {     // e.g., "lastSun"
+            cdate.setDate(year, monthValue, 1);
+            cdate.setDayOfMonth(gcal.getMonthLength(cdate));
+            cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate);
+        } else if (day.isLater()) { // e.g., "Sun>=1"
+            cdate.setDate(year, monthValue, day.getDay());
+            cdate = gcal.getNthDayOfWeek(1, day.getDayOfWeekNum(), cdate);
+        } else if (day.isExact()) {
+            cdate.setDate(year, monthValue, day.getDay());
+        } else if (day.isEarlier()) {   // e.g., "Sun<=15"
+            cdate.setDate(year, monthValue, day.getDay());
+            cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate);
+        } else {
+            Main.panic("invalid day type: " + day);
+        }
+        return gcal.getTime(cdate) + time;
+    }
+
+    /**
+     * Parses the given "AT" field and constructs a Time object.
+     * @param the "AT" field string
+     * @return the Time object
+     */
+    static Time parse(String time) {
+        int sign;
+        int index = 0;
+        Time tm;
+
+        if (time.charAt(0) == '-') {
+            sign = -1;
+            index++;
+        } else {
+            sign = 1;
+        }
+        int val = 0;
+        int num = 0;
+        int countDelim = 0;
+        while (index < time.length()) {
+            char c = time.charAt(index++);
+            if (c == ':') {
+                val = val * 60 + num;
+                countDelim++;
+                num = 0;
+                continue;
+            }
+            int d = Character.digit(c, 10);
+            if (d == -1) {
+                --index;
+                break;
+            }
+            num = num * 10 + d;
+        }
+        val = val * 60 + num;
+        // convert val to second
+        for (; countDelim < 2; countDelim++) {
+            val *= 60;
+        }
+        tm = new Time((long)val * 1000 * sign);
+        if (index < time.length()) {
+            char c = time.charAt(index++);
+            if (c == 's') {
+                tm.setType(Time.STD);
+            } else if (c == 'u' || c == 'g' || c == 'z') {
+                tm.setType(Time.UTC);
+            } else if (c == 'w') {
+                tm.setType(Time.WALL);
+            } else {
+                Main.panic("unknown time mode: "+c);
+            }
+        } else {
+            tm.setType(Time.WALL);
+        }
+        return tm;
+    }
+
+    /**
+     * Converts the given milliseconds string to a "[+-]hh:mm" string.
+     * @param ms the milliseconds string
+     */
+    static String toGMTFormat(String ms) {
+        long sec = Long.parseLong(ms) / 1000;
+        char sign;
+        if (sec < 0) {
+            sign = '-';
+            sec = -sec;
+        } else {
+            sign = '+';
+        }
+        return String.format((Locale)null, "%c%02d:%02d",
+                             sign, sec/3600, (sec%3600)/60);
+    }
+
+    /**
+     * Converts the given millisecond value to a string for a
+     * SimpleTimeZone parameter.
+     * @param ms the millisecond value
+     * @return the string in a human readable form
+     */
+    static String toFormedString(int ms) {
+        StringBuilder s = new StringBuilder();
+        boolean minus = false;
+
+        if (ms < 0) {
+            s.append("-");
+            minus = true;
+            ms = -ms;
+        } else if (ms == 0) {
+            return "0";
+        }
+
+        int hour = ms / (60 * 60 * 1000);
+        ms %= (60 * 60 * 1000);
+        int minute = ms / (60 * 1000);
+
+        if (hour != 0) {
+            if (minus && minute != 0) {
+                s.append("(");
+            }
+            s.append(Integer.toString(hour) + "*ONE_HOUR");
+        }
+
+        if (minute != 0) {
+            if (hour != 0) {
+                s.append("+");
+            }
+            s.append(Integer.toString(minute) + "*ONE_MINUTE");
+            if (minus && hour != 0) {
+                s.append(")");
+            }
+        }
+
+        return s.toString();
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/Timezone.java b/jdk/test/sun/util/calendar/zi/Timezone.java
new file mode 100644
index 0000000..04518a9
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Timezone.java
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2000, 2004, 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Timezone represents all information of a single point of time to
+ * generate its time zone database.
+ *
+ * @since 1.4
+ */
+class Timezone {
+    /**
+     * zone name of this time zone
+     */
+    private String name;
+
+    /**
+     * transition time values in UTC (millisecond)
+     */
+    private List<Long> transitions;
+
+    /**
+     * All offset values in millisecond
+     * @see sun.util.calendar.ZoneInfo
+     */
+    private List<Integer> offsets;
+
+    /**
+     * Indices of GMT offset values (both raw and raw+saving)
+     * at transitions
+     */
+    private List<Integer> gmtOffsets;
+
+    /**
+     * Indices of regular or "direct" saving time values
+     * at transitions
+     */
+    private List<Integer> dstOffsets;
+
+    /**
+     * Zone records of this time zone
+     */
+    private List<ZoneRec> usedZoneRecs;
+
+    /**
+     * Rule records referred to by this time zone
+     */
+    private List<RuleRec> usedRuleRecs;
+
+    /**
+     * Type of DST rules in this time zone
+     */
+    private int dstType;
+    static final int UNDEF_DST = 0;     // DST type not set yet
+    static final int NO_DST = 1;        // never observed DST
+    static final int LAST_DST = 2;      // last rule ends in DST (all year round DST-only)
+    static final int X_DST = 3;         // used to observe DST
+    static final int DST = 4;           // observing DST regularly
+
+    /**
+     * Raw GMT offset of this time zone in the last rule
+     */
+    private int rawOffset;
+
+    /**
+     * The CRC32 value of the transitions data
+     */
+    private int crc32;
+
+    /**
+     * The last ZoneRec
+     */
+    private ZoneRec lastZoneRec;
+
+    /**
+     * The last DST rules. lastRules[0] is the DST start
+     * rule. lastRules[1] is the DST end rules.
+     */
+    private List<RuleRec> lastRules;
+
+    /**
+     * The amount of DST saving value (millisecond) in the last DST
+     * rule.
+     */
+    private int lastSaving;
+
+    /**
+     * true if the raw offset will change in the future time.
+     */
+    private boolean willRawOffsetChange = false;
+
+
+    /**
+     * Constracts a Timezone object with the given zone name.
+     * @param name the zone name
+     */
+    Timezone(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the number of transitions
+     */
+    int getNTransitions() {
+        if (transitions == null) {
+            return 0;
+        }
+        return transitions.size();
+    }
+
+    /**
+     * @return the zone name
+     */
+    String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the list of all rule records that have been referred to
+     * by this time zone.
+     * @return the rule records list
+     */
+    List<RuleRec> getRules() {
+        return usedRuleRecs;
+    }
+
+    /**
+     * Returns the list of all zone records that have been referred to
+     * by this time zone.
+     * @return the zone records list
+     */
+    List<ZoneRec> getZones() {
+        return usedZoneRecs;
+    }
+
+    /**
+     * @return the transition table (list)
+     */
+    List<Long> getTransitions() {
+        return transitions;
+    }
+
+    /**
+     * @return the offsets list
+     */
+    List<Integer> getOffsets() {
+        return offsets;
+    }
+
+    /**
+     * @return the DST saving offsets list
+     */
+    List<Integer> getDstOffsets() {
+        return dstOffsets;
+    }
+
+    /**
+     * @return the GMT offsets list
+     */
+    List<Integer> getGmtOffsets() {
+        return gmtOffsets;
+    }
+
+    /**
+     * @return the checksum (crc32) value of the trasition table
+     */
+    int getCRC32() {
+        return crc32;
+    }
+
+    /**
+     * @return true if the GMT offset of this time zone would change
+     * after the time zone database has been generated, false, otherwise.
+     */
+    boolean willGMTOffsetChange() {
+        return willRawOffsetChange;
+    }
+
+    /**
+     * @return the last known GMT offset value in milliseconds
+     */
+    int getRawOffset() {
+        return rawOffset;
+    }
+
+    /**
+     * Sets time zone's GMT offset to <code>offset</code>.
+     * @param offset the GMT offset value in milliseconds
+     */
+    void setRawOffset(int offset) {
+        rawOffset = offset;
+    }
+
+    /**
+     * Sets time zone's GMT offset value to <code>offset</code>. If
+     * <code>startTime</code> is future time, then the {@link
+     * #willRawOffsetChange} value is set to true.
+     * @param offset the GMT offset value in milliseconds
+     * @param startTime the UTC time at which the GMT offset is in effective
+     */
+    void setRawOffset(int offset, long startTime) {
+        // if this rawOffset is for the future time, let the run-time
+        // look for the current GMT offset.
+        if (startTime > Time.getCurrentTime()) {
+            willRawOffsetChange = true;
+        }
+        setRawOffset(offset);
+    }
+
+    /**
+     * Adds the specified transition information to the end of the transition table.
+     * @param time the UTC time at which this transition happens
+     * @param offset the total amount of the offset from GMT in milliseconds
+     * @param dstOffset the amount of time in milliseconds saved at this transition
+     */
+    void addTransition(long time, int offset, int dstOffset) {
+        if (transitions == null) {
+            transitions = new ArrayList<Long>();
+            offsets = new ArrayList<Integer>();
+            dstOffsets = new ArrayList<Integer>();
+        }
+        transitions.add(time);
+        offsets.add(offset);
+        dstOffsets.add(dstOffset);
+    }
+
+    /**
+     * Sets the type of historical daylight saving time
+     * observation. For example, China used to observed daylight
+     * saving time, but it no longer does. Then, X_DST is set to the
+     * China time zone.
+     * @param type the type of daylight saving time
+     */
+    void setDSTType(int type) {
+        dstType = type;
+    }
+
+    /**
+     * @return the type of historical daylight saving time
+     * observation.
+     */
+    int getDSTType() {
+        return dstType;
+    }
+
+    /**
+     * Adds the specified zone record to the zone records list.
+     * @param rec the zone record
+     */
+    void addUsedRec(ZoneRec rec) {
+        if (usedZoneRecs == null) {
+            usedZoneRecs = new ArrayList<ZoneRec>();
+        }
+        usedZoneRecs.add(rec);
+    }
+
+    /**
+     * Adds the specified rule record to the rule records list.
+     * @param rec the rule record
+     */
+    void addUsedRec(RuleRec rec) {
+        if (usedRuleRecs == null) {
+            usedRuleRecs = new ArrayList<RuleRec>();
+        }
+        // if the last used rec is the same as the given rec, avoid
+        // putting the same rule.
+        int n = usedRuleRecs.size();
+        for (int i = 0; i < n; i++) {
+            if (usedRuleRecs.get(i).equals(rec)) {
+                return;
+            }
+        }
+        usedRuleRecs.add(rec);
+    }
+
+    /**
+     * Sets the last zone record for this time zone.
+     * @param the last zone record
+     */
+    void setLastZoneRec(ZoneRec zrec) {
+        lastZoneRec = zrec;
+    }
+
+    /**
+     * @return the last zone record for this time zone.
+     */
+    ZoneRec getLastZoneRec() {
+        return lastZoneRec;
+    }
+
+    /**
+     * Sets the last rule records for this time zone. Those are used
+     * for generating SimpleTimeZone parameters.
+     * @param rules the last rule records
+     */
+    void setLastRules(List<RuleRec> rules) {
+        int n = rules.size();
+        if (n > 0) {
+            lastRules = rules;
+            RuleRec rec = rules.get(0);
+            int offset = rec.getSave();
+            if (offset > 0) {
+                setLastDSTSaving(offset);
+            } else {
+                System.err.println("\t    No DST starting rule in the last rules.");
+            }
+        }
+    }
+
+    /**
+     * @return the last rule records for this time zone.
+     */
+    List<RuleRec> getLastRules() {
+        return lastRules;
+    }
+
+    /**
+     * Sets the last daylight saving amount.
+     * @param the daylight saving amount
+     */
+    void setLastDSTSaving(int offset) {
+        lastSaving = offset;
+    }
+
+    /**
+     * @return the last daylight saving amount.
+     */
+    int getLastDSTSaving() {
+        return lastSaving;
+    }
+
+    /**
+     * Calculates the CRC32 value from the transition table and sets
+     * the value to <code>crc32</code>.
+     */
+    void checksum() {
+        if (transitions == null) {
+            crc32 = 0;
+            return;
+        }
+        Checksum sum = new Checksum();
+        for (int i = 0; i < transitions.size(); i++) {
+            int offset = offsets.get(i);
+            // adjust back to make the transition in local time
+            sum.update(transitions.get(i) + offset);
+            sum.update(offset);
+            sum.update(dstOffsets.get(i));
+        }
+        crc32 = (int)sum.getValue();
+    }
+
+    /**
+     * Removes unnecessary transitions for Java time zone support.
+     */
+    void optimize() {
+        // if there is only one offset, delete all transitions. This
+        // could happen if only time zone abbreviations changed.
+        if (gmtOffsets.size() == 1) {
+            transitions = null;
+            usedRuleRecs =  null;
+            setDSTType(NO_DST);
+            return;
+        }
+        for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
+            if (transitions.get(i) == transitions.get(i+1)) {
+                transitions.remove(i);
+                offsets.remove(i);
+                dstOffsets.remove(i);
+                i--;
+            }
+        }
+
+        for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
+            if (offsets.get(i) == offsets.get(i+1)
+                && dstOffsets.get(i) == dstOffsets.get(i+1)) {
+                transitions.remove(i+1);
+                offsets.remove(i+1);
+                dstOffsets.remove(i+1);
+                i--;
+            }
+        }
+    }
+
+    /**
+     * Stores the specified offset value from GMT in the GMT offsets
+     * table and returns its index. The offset value includes the base
+     * GMT offset and any additional daylight saving if applicable. If
+     * the same value as the specified offset is already in the table,
+     * its index is returned.
+     * @param offset the offset value in milliseconds
+     * @return the index to the offset value in the GMT offsets table.
+     */
+    int getOffsetIndex(int offset) {
+        return getOffsetIndex(offset, 0);
+    }
+
+    /**
+     * Stores the specified daylight saving value in the GMT offsets
+     * table and returns its index. If the same value as the specified
+     * offset is already in the table, its index is returned. If 0 is
+     * specified, it's not stored in the table and -1 is returned.
+     * @param offset the offset value in milliseconds
+     * @return the index to the specified offset value in the GMT
+     * offsets table, or -1 if 0 is specified.
+     */
+    int getDstOffsetIndex(int offset) {
+        if (offset == 0) {
+            return -1;
+        }
+        return getOffsetIndex(offset, 1);
+    }
+
+    private int getOffsetIndex(int offset, int index) {
+        if (gmtOffsets == null) {
+            gmtOffsets = new ArrayList<Integer>();
+        }
+        for (int i = index; i < gmtOffsets.size(); i++) {
+            if (offset == gmtOffsets.get(i)) {
+                return i;
+            }
+        }
+        if (gmtOffsets.size() < index) {
+            gmtOffsets.add(0);
+        }
+        gmtOffsets.add(offset);
+        return gmtOffsets.size() - 1;
+    }
+}
diff --git a/jdk/src/share/classes/sun/util/calendar/TzIDOldMapping.java b/jdk/test/sun/util/calendar/zi/TzIDOldMapping.java
similarity index 98%
copy from jdk/src/share/classes/sun/util/calendar/TzIDOldMapping.java
copy to jdk/test/sun/util/calendar/zi/TzIDOldMapping.java
index 4f23007..e9ea6b5 100644
--- a/jdk/src/share/classes/sun/util/calendar/TzIDOldMapping.java
+++ b/jdk/test/sun/util/calendar/zi/TzIDOldMapping.java
@@ -23,8 +23,6 @@
  * questions.
  */
 
-package sun.util.calendar;
-
 import java.util.Map;
 import java.util.HashMap;
 
diff --git a/jdk/test/sun/util/calendar/zi/Zone.java b/jdk/test/sun/util/calendar/zi/Zone.java
new file mode 100644
index 0000000..7952008
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Zone.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2000, 2004, 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Zone holds information corresponding to a "Zone" part of a time
+ * zone definition file.
+ *
+ * @since 1.4
+ */
+class Zone {
+    // zone name (e.g., "America/Los_Angeles")
+    private String name;
+
+    // zone records
+    private List<ZoneRec> list;
+
+    // target zone names for this compilation
+    private static Set<String> targetZones;
+
+    /**
+     * Constructs a Zone with the specified zone name.
+     * @param name the zone name
+     */
+    Zone(String name) {
+        this.name = name;
+        list = new ArrayList<ZoneRec>();
+    }
+
+    /**
+     * Reads time zone names to be generated, called "target zone
+     * name", from the specified text file and creats an internal hash
+     * table to keep those names. It's assumed that one text line
+     * contains a zone name or comments if it starts with
+     * '#'. Comments can't follow a zone name in a single line.
+     * @param fileName the text file name
+     */
+    static void readZoneNames(String fileName) {
+        if (fileName == null) {
+            return;
+        }
+        BufferedReader in = null;
+        try {
+            FileReader fr = new FileReader(fileName);
+            in = new BufferedReader(fr);
+        } catch (FileNotFoundException e) {
+            Main.panic("can't open file: " + fileName);
+        }
+        targetZones = new HashSet<String>();
+        String line;
+
+        try {
+            while ((line = in.readLine()) != null) {
+                line = line.trim();
+                if (line.length() == 0 || line.charAt(0) == '#') {
+                    continue;
+                }
+                if (!targetZones.add(line)) {
+                    Main.warning("duplicated target zone name: " + line);
+                }
+            }
+            in.close();
+        } catch (IOException e) {
+            Main.panic("IO error: "+e.getMessage());
+        }
+    }
+
+    /**
+     * Determines whether the specified zone is one of the target zones.
+     * If no target zones are specified, this method always returns
+     * true for any zone name.
+     * @param zoneName the zone name
+     * @return true if the specified name is a target zone.
+     */
+    static boolean isTargetZone(String zoneName) {
+        if (targetZones == null) {
+            return true;
+        }
+        return targetZones.contains(zoneName);
+    }
+
+    /**
+     * Forces to add "MET" to the target zone table. This is because
+     * there is a conflict between Java zone name "WET" and Olson zone
+     * name.
+     */
+    static void addMET() {
+        if (targetZones != null) {
+            targetZones.add("MET");
+        }
+    }
+
+    /**
+     * @return the zone name
+     */
+    String getName() {
+        return name;
+    }
+
+    /**
+     * Adds the specified zone record to the zone record list.
+     */
+    void add(ZoneRec rec) {
+        list.add(rec);
+    }
+
+    /**
+     * @param index the index at which the zone record in the list is returned.
+     * @return the zone record specified by the index.
+     */
+    ZoneRec get(int index) {
+        return list.get(index);
+    }
+
+    /**
+     * @return the size of the zone record list
+     */
+    int size() {
+        return list.size();
+    }
+
+    /**
+     * Resolves the reference to a rule in each zone record.
+     * @param zi the Zoneinfo object with which the rule reference is
+     * resolved.
+     */
+    void resolve(Zoneinfo zi) {
+        for (int i = 0; i < list.size(); i++) {
+            ZoneRec rec = list.get(i);
+            rec.resolve(zi);
+        }
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/ZoneInfoFile.java b/jdk/test/sun/util/calendar/zi/ZoneInfoFile.java
new file mode 100644
index 0000000..f0dda48
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/ZoneInfoFile.java
@@ -0,0 +1,1051 @@
+/*
+ * Copyright (c) 2000, 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.  Oracle designates this
+ * particular file as subject to the "Class-path" 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.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.ref.SoftReference;
+import java.nio.file.FileSystems;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import sun.util.calendar.*;
+
+/**
+ * <code>ZoneInfoFile</code> reads Zone information files in the
+ * &lt;java.home&gt;/lib/zi directory and provides time zone
+ * information in the form of a {@link ZoneInfo} object. Also, it
+ * reads the ZoneInfoMappings file to obtain time zone IDs information
+ * that is used by the {@link ZoneInfo} class. The directory layout
+ * and data file formats are as follows.
+ *
+ * <p><strong>Directory layout</strong><p>
+ *
+ * All zone data files and ZoneInfoMappings are put under the
+ * &lt;java.home&gt;/lib/zi directory. A path name for a given time
+ * zone ID is a concatenation of &lt;java.home&gt;/lib/zi/ and the
+ * time zone ID. (The file separator is replaced with the platform
+ * dependent value. e.g., '\' for Win32.) An example layout will look
+ * like as follows.
+ * <blockquote>
+ * <pre>
+ * &lt;java.home&gt;/lib/zi/Africa/Addis_Ababa
+ *                   /Africa/Dakar
+ *                   /America/Los_Angeles
+ *                   /Asia/Singapore
+ *                   /EET
+ *                   /Europe/Oslo
+ *                   /GMT
+ *                   /Pacific/Galapagos
+ *                       ...
+ *                   /ZoneInfoMappings
+ * </pre>
+ * </blockquote>
+ *
+ * A zone data file has specific information of each zone.
+ * <code>ZoneInfoMappings</code> has global information of zone IDs so
+ * that the information can be obtained without instantiating all time
+ * zones.
+ *
+ * <p><strong>File format</strong><p>
+ *
+ * Two binary-file formats based on a simple Tag-Length-Value format are used
+ * to describe TimeZone information. The generic format of a data file is:
+ * <blockquote>
+ * <pre>
+ *    DataFile {
+ *      u1              magic[7];
+ *      u1              version;
+ *      data_item       data[];
+ *    }
+ * </pre>
+ * </blockquote>
+ * where <code>magic</code> is a magic number identifying a file
+ * format, <code>version</code> is the format version number, and
+ * <code>data</code> is one or more <code>data_item</code>s. The
+ * <code>data_item</code> structure is:
+ * <blockquote>
+ * <pre>
+ *    data_item {
+ *      u1              tag;
+ *      u2              length;
+ *      u1              value[length];
+ *    }
+ * </pre>
+ * </blockquote>
+ * where <code>tag</code> indicates the data type of the item,
+ * <code>length</code> is a byte count of the following
+ * <code>value</code> that is the content of item data.
+ * <p>
+ * All data is stored in the big-endian order. There is no boundary
+ * alignment between date items.
+ *
+ * <p><strong>1. ZoneInfo data file</strong><p>
+ *
+ * Each ZoneInfo data file consists of the following members.
+ * <br>
+ * <blockquote>
+ * <pre>
+ *    ZoneInfoDataFile {
+ *      u1              magic[7];
+ *      u1              version;
+ *      SET OF<sup>1</sup> {
+ *        transition            transitions<sup>2</sup>;
+ *        offset_table          offsets<sup>2</sup>;
+ *        simpletimezone        stzparams<sup>2</sup>;
+ *        raw_offset            rawoffset;
+ *        dstsaving             dst;
+ *        checksum              crc32;
+ *        gmtoffsetwillchange   gmtflag<sup>2</sup>;
+ *      }
+ *   }
+ *   1: an unordered collection of zero or one occurrences of each item
+ *   2: optional item
+ * </pre>
+ * </blockquote>
+ * <code>magic</code> is a byte-string constant identifying the
+ * ZoneInfo data file.  This field must be <code>"javazi&#92;0"</code>
+ * defined as {@link #JAVAZI_LABEL}.
+ * <p>
+ * <code>version</code> is the version number of the file format. This
+ * will be used for compatibility check. This field must be
+ * <code>0x01</code> in this version.
+ * <p>
+ * <code>transition</code>, <code>offset_table</code> and
+ * <code>simpletimezone</code> have information of time transition
+ * from the past to the future.  Therefore, these structures don't
+ * exist if the zone didn't change zone names and haven't applied DST in
+ * the past, and haven't planned to apply it.  (e.g. Asia/Tokyo zone)
+ * <p>
+ * <code>raw_offset</code>, <code>dstsaving</code> and <code>checksum</code>
+ * exist in every zoneinfo file. They are used by TimeZone.class indirectly.
+ *
+ * <p><strong>1.1 <code>transition</code> structure</strong><p><a name="transition"></a>
+ * <blockquote>
+ * <pre>
+ *    transition {
+ *      u1      tag;              // 0x04 : constant
+ *      u2      length;           // byte length of whole values
+ *      s8      value[length/8];  // transitions in `long'
+ *    }
+ * </pre>
+ * </blockquote>
+ * See {@link ZoneInfo#transitions ZoneInfo.transitions} about the value.
+ *
+ * <p><strong>1.2 <code>offset_table</code> structure</strong><p>
+ * <blockquote>
+ * <pre>
+ *    offset_table {
+ *      u1      tag;              // 0x05 : constant
+ *      u2      length;           // byte length of whole values
+ *      s4      value[length/4];  // offset values in `int'
+ *    }
+ * </pre>
+ * </blockquote>
+ *
+ * <p><strong>1.3 <code>simpletimezone</code> structure</strong><p>
+ * See {@link ZoneInfo#simpleTimeZoneParams ZoneInfo.simpleTimeZoneParams}
+ * about the value.
+ * <blockquote>
+ * <pre>
+ *    simpletimezone {
+ *      u1      tag;              // 0x06 : constant
+ *      u2      length;           // byte length of whole values
+ *      s4      value[length/4];  // SimpleTimeZone parameters
+ *    }
+ * </pre>
+ * </blockquote>
+ * See {@link ZoneInfo#offsets ZoneInfo.offsets} about the value.
+ *
+ * <p><strong>1.4 <code>raw_offset</code> structure</strong><p>
+ * <blockquote>
+ * <pre>
+ *    raw_offset {
+ *      u1      tag;              // 0x01 : constant
+ *      u2      length;           // must be 4.
+ *      s4      value;            // raw GMT offset [millisecond]
+ *    }
+ * </pre>
+ * </blockquote>
+ * See {@link ZoneInfo#rawOffset ZoneInfo.rawOffset} about the value.
+ *
+ * <p><strong>1.5 <code>dstsaving</code> structure</strong><p>
+ * Value has dstSaving in seconds.
+ * <blockquote>
+ * <pre>
+ *    dstsaving {
+ *      u1      tag;              // 0x02 : constant
+ *      u2      length;           // must be 2.
+ *      s2      value;            // DST save value [second]
+ *    }
+ * </pre>
+ * </blockquote>
+ * See {@link ZoneInfo#dstSavings ZoneInfo.dstSavings} about value.
+ *
+ * <p><strong>1.6 <code>checksum</code> structure</strong><p>
+ * <blockquote>
+ * <pre>
+ *    checksum {
+ *      u1      tag;              // 0x03 : constant
+ *      u2      length;           // must be 4.
+ *      s4      value;            // CRC32 value of transitions
+ *    }
+ * </pre>
+ * </blockquote>
+ * See {@link ZoneInfo#checksum ZoneInfo.checksum}.
+ *
+ * <p><strong>1.7 <code>gmtoffsetwillchange</code> structure</strong><p>
+ * This record has a flag value for {@link ZoneInfo#rawOffsetWillChange}.
+ * If this record is not present in a zoneinfo file, 0 is assumed for
+ * the value.
+ * <blockquote>
+ * <pre>
+ *    gmtoffsetwillchange {
+ *      u1      tag;             // 0x07 : constant
+ *      u2      length;          // must be 1.
+ *      u1      value;           // 1: if the GMT raw offset will change
+ *                               // in the future, 0, otherwise.
+ *     }
+ * </pre>
+ * </blockquote>
+ *
+ *
+ * <p><strong>2. ZoneInfoMappings file</strong><p>
+ *
+ * The ZoneInfoMappings file consists of the following members.
+ * <br>
+ * <blockquote>
+ * <pre>
+ *    ZoneInfoMappings {
+ *      u1      magic[7];
+ *      u1      version;
+ *      SET OF {
+ *        versionName                   version;
+ *        zone_id_table                 zoneIDs;
+ *        raw_offset_table              rawoffsets;
+ *        raw_offset_index_table        rawoffsetindices;
+ *        alias_table                   aliases;
+ *        excluded_list                 excludedList;
+ *      }
+ *   }
+ * </pre>
+ * </blockquote>
+ *
+ * <code>magic</code> is a byte-string constant which has the file type.
+ * This field must be <code>"javazm&#92;0"</code> defined as {@link #JAVAZM_LABEL}.
+ * <p>
+ * <code>version</code> is the version number of this file
+ * format. This will be used for compatibility check. This field must
+ * be <code>0x01</code> in this version.
+ * <p>
+ * <code>versionName</code> shows which version of Olson's data has been used
+ * to generate this ZoneInfoMappings. (e.g. <code>tzdata2000g</code>) <br>
+ * This field is for trouble-shooting and isn't usually used in runtime.
+ * <p>
+ * <code>zone_id_table</code>, <code>raw_offset_index_table</code> and
+ * <code>alias_table</code> are general information of supported
+ * zones.
+ *
+ * <p><strong>2.1 <code>zone_id_table</code> structure</strong><p>
+ * The list of zone IDs included in the zi database. The list does
+ * <em>not</em> include zone IDs, if any, listed in excludedList.
+ * <br>
+ * <blockquote>
+ * <pre>
+ *    zone_id_table {
+ *      u1      tag;              // 0x40 : constant
+ *      u2      length;           // byte length of whole values
+ *      u2      zone_id_count;
+ *      zone_id value[zone_id_count];
+ *    }
+ *
+ *    zone_id {
+ *      u1      byte_length;      // byte length of id
+ *      u1      id[byte_length];  // zone name string
+ *    }
+ * </pre>
+ * </blockquote>
+ *
+ * <p><strong>2.2 <code>raw_offset_table</code> structure</strong><p>
+ * <br>
+ * <blockquote>
+ * <pre>
+ *    raw_offset_table {
+ *      u1      tag;              // 0x41 : constant
+ *      u2      length;           // byte length of whole values
+ *      s4      value[length/4];  // raw GMT offset in milliseconds
+ *   }
+ * </pre>
+ * </blockquote>
+ *
+ * <p><strong>2.3 <code>raw_offset_index_table</code> structure</strong><p>
+ * <br>
+ * <blockquote>
+ * <pre>
+ *    raw_offset_index_table {
+ *      u1      tag;              // 0x42 : constant
+ *      u2      length;           // byte length of whole values
+ *      u1      value[length];
+ *    }
+ * </pre>
+ * </blockquote>
+ *
+ * <p><strong>2.4 <code>alias_table</code> structure</strong><p>
+ * <br>
+ * <blockquote>
+ * <pre>
+ *   alias_table {
+ *      u1      tag;              // 0x43 : constant
+ *      u2      length;           // byte length of whole values
+ *      u2      nentries;         // number of id-pairs
+ *      id_pair value[nentries];
+ *   }
+ *
+ *   id_pair {
+ *      zone_id aliasname;
+ *      zone_id ID;
+ *   }
+ * </pre>
+ * </blockquote>
+ *
+ * <p><strong>2.5 <code>versionName</code> structure</strong><p>
+ * <br>
+ * <blockquote>
+ * <pre>
+ *   versionName {
+ *      u1      tag;              // 0x44 : constant
+ *      u2      length;           // byte length of whole values
+ *      u1      value[length];
+ *   }
+ * </pre>
+ * </blockquote>
+ *
+ * <p><strong>2.6 <code>excludeList</code> structure</strong><p>
+ * The list of zone IDs whose zones will change their GMT offsets
+ * (a.k.a. raw offsets) some time in the future. Those IDs must be
+ * added to the list of zone IDs for getAvailableIDs(). Also they must
+ * be examined for getAvailableIDs(int) to determine the
+ * <em>current</em> GMT offsets.
+ * <br>
+ * <blockquote>
+ * <pre>
+ *   excluded_list {
+ *      u1      tag;              // 0x45 : constant
+ *      u2      length;           // byte length of whole values
+ *      u2      nentries;         // number of zone_ids
+ *      zone_id value[nentries];  // excluded zone IDs
+ *   }
+ * </pre>
+ * </blockquote>
+ *
+ * @since 1.4
+ */
+
+public class ZoneInfoFile {
+
+    /**
+     * The magic number for the ZoneInfo data file format.
+     */
+    public static final byte[]  JAVAZI_LABEL = {
+        (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'i', (byte)'\0'
+    };
+    private static final int    JAVAZI_LABEL_LENGTH = JAVAZI_LABEL.length;
+
+    /**
+     * The ZoneInfo data file format version number. Must increase
+     * one when any incompatible change has been made.
+     */
+    public static final byte    JAVAZI_VERSION = 0x01;
+
+    /**
+     * Raw offset data item tag.
+     */
+    public static final byte    TAG_RawOffset = 1;
+
+    /**
+     * Known last Daylight Saving Time save value data item tag.
+     */
+    public static final byte    TAG_LastDSTSaving = 2;
+
+    /**
+     * Checksum data item tag.
+     */
+    public static final byte    TAG_CRC32 = 3;
+
+    /**
+     * Transition data item tag.
+     */
+    public static final byte    TAG_Transition = 4;
+
+    /**
+     * Offset table data item tag.
+     */
+    public static final byte    TAG_Offset = 5;
+
+    /**
+     * SimpleTimeZone parameters data item tag.
+     */
+    public static final byte    TAG_SimpleTimeZone = 6;
+
+    /**
+     * Raw GMT offset will change in the future.
+     */
+    public static final byte    TAG_GMTOffsetWillChange = 7;
+
+
+    /**
+     * The ZoneInfoMappings file name.
+     */
+    public static final String  JAVAZM_FILE_NAME = "ZoneInfoMappings";
+
+    /**
+     * The magic number for the ZoneInfoMappings file format.
+     */
+    public static final byte[]  JAVAZM_LABEL = {
+        (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'m', (byte)'\0'
+    };
+    private static final int    JAVAZM_LABEL_LENGTH = JAVAZM_LABEL.length;
+
+    /**
+     * The ZoneInfoMappings file format version number. Must increase
+     * one when any incompatible change has been made.
+     */
+    public static final byte    JAVAZM_VERSION = 0x01;
+
+    /**
+     * Time zone IDs data item tag.
+     */
+    public static final byte    TAG_ZoneIDs = 64;
+
+    /**
+     * Raw GMT offsets table data item tag.
+     */
+    public static final byte    TAG_RawOffsets = 65;
+
+    /**
+     * Indices to the raw GMT offset table data item tag.
+     */
+    public static final byte    TAG_RawOffsetIndices = 66;
+
+    /**
+     * Time zone aliases table data item tag.
+     */
+    public static final byte    TAG_ZoneAliases = 67;
+
+    /**
+     * Olson's public zone information version tag.
+     */
+    public static final byte    TAG_TZDataVersion = 68;
+
+    /**
+     * Excluded zones item tag. (Added in Mustang)
+     */
+    public static final byte    TAG_ExcludedZones = 69;
+
+    private static Map<String, ZoneInfoOld> zoneInfoObjects = null;
+
+    private static final ZoneInfoOld GMT = new ZoneInfoOld("GMT", 0);
+
+    static String ziDir;
+
+    /**
+     * Converts the given time zone ID to a platform dependent path
+     * name. For example, "America/Los_Angeles" is converted to
+     * "America\Los_Angeles" on Win32.
+     * @return a modified ID replacing '/' with {@link
+     * java.io.File#separatorChar File.separatorChar} if needed.
+     */
+    public static String getFileName(String ID) {
+        if (File.separatorChar == '/') {
+            return ID;
+        }
+        return ID.replace('/', File.separatorChar);
+    }
+
+    /**
+     * Gets a ZoneInfo with the given GMT offset. The object
+     * has its ID in the format of GMT{+|-}hh:mm.
+     *
+     * @param originalId the given custom id (before normalized such as "GMT+9")
+     * @param gmtOffset GMT offset <em>in milliseconds</em>
+     * @return a ZoneInfo constructed with the given GMT offset
+     */
+    public static ZoneInfoOld getCustomTimeZone(String originalId, int gmtOffset) {
+        String id = toCustomID(gmtOffset);
+
+        ZoneInfoOld zi = getFromCache(id);
+        if (zi == null) {
+            zi = new ZoneInfoOld(id, gmtOffset);
+            zi = addToCache(id, zi);
+            if (!id.equals(originalId)) {
+                zi = addToCache(originalId, zi);
+            }
+        }
+        return (ZoneInfoOld) zi.clone();
+    }
+
+    public static String toCustomID(int gmtOffset) {
+        char sign;
+        int offset = gmtOffset / 60000;
+
+        if (offset >= 0) {
+            sign = '+';
+        } else {
+            sign = '-';
+            offset = -offset;
+        }
+        int hh = offset / 60;
+        int mm = offset % 60;
+
+        char[] buf = new char[] { 'G', 'M', 'T', sign, '0', '0', ':', '0', '0' };
+        if (hh >= 10) {
+            buf[4] += hh / 10;
+        }
+        buf[5] += hh % 10;
+        if (mm != 0) {
+            buf[7] += mm / 10;
+            buf[8] += mm % 10;
+        }
+        return new String(buf);
+    }
+
+    /**
+     * @return a ZoneInfo instance created for the specified id, or
+     * null if there is no time zone data file found for the specified
+     * id.
+     */
+    public static ZoneInfoOld getZoneInfoOld(String id) {
+        //treat GMT zone as special
+        if ("GMT".equals(id))
+            return (ZoneInfoOld) GMT.clone();
+        ZoneInfoOld zi = getFromCache(id);
+        if (zi == null) {
+            Map<String, String> aliases = ZoneInfoOld.getCachedAliasTable();
+            if (aliases != null && aliases.get(id) != null) {
+                return null;
+            }
+            zi = createZoneInfoOld(id);
+            if (zi == null) {
+                return null;
+            }
+            zi = addToCache(id, zi);
+        }
+        return (ZoneInfoOld) zi.clone();
+    }
+
+    synchronized static ZoneInfoOld getFromCache(String id) {
+        if (zoneInfoObjects == null) {
+            return null;
+        }
+        return zoneInfoObjects.get(id);
+    }
+
+    synchronized static ZoneInfoOld addToCache(String id, ZoneInfoOld zi) {
+        if (zoneInfoObjects == null) {
+            zoneInfoObjects = new HashMap<>();
+        } else {
+            ZoneInfoOld zone = zoneInfoObjects.get(id);
+            if (zone != null) {
+                return zone;
+            }
+        }
+        zoneInfoObjects.put(id, zi);
+        return zi;
+    }
+
+    private static ZoneInfoOld createZoneInfoOld(String id) {
+        byte[] buf = readZoneInfoFile(getFileName(id));
+        if (buf == null) {
+            return null;
+        }
+
+        int index = 0;
+        int filesize = buf.length;
+        int rawOffset = 0;
+        int dstSavings = 0;
+        int checksum = 0;
+        boolean willGMTOffsetChange = false;
+        long[] transitions = null;
+        int[] offsets = null;
+        int[] simpleTimeZoneParams = null;
+
+        try {
+            for (index = 0; index < JAVAZI_LABEL.length; index++) {
+                if (buf[index] != JAVAZI_LABEL[index]) {
+                    System.err.println("ZoneInfoOld: wrong magic number: " + id);
+                    return null;
+                }
+            }
+            if (buf[index++] > JAVAZI_VERSION) {
+                System.err.println("ZoneInfo: incompatible version ("
+                                   + buf[index - 1] + "): " + id);
+                return null;
+            }
+
+            while (index < filesize) {
+                byte tag = buf[index++];
+                int  len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
+
+                if (filesize < index+len) {
+                    break;
+                }
+
+                switch (tag) {
+                case TAG_CRC32:
+                    {
+                        int val = buf[index++] & 0xff;
+                        val = (val << 8) + (buf[index++] & 0xff);
+                        val = (val << 8) + (buf[index++] & 0xff);
+                        val = (val << 8) + (buf[index++] & 0xff);
+                        checksum = val;
+                    }
+                    break;
+
+                case TAG_LastDSTSaving:
+                    {
+                        short val = (short)(buf[index++] & 0xff);
+                        val = (short)((val << 8) + (buf[index++] & 0xff));
+                        dstSavings = val * 1000;
+                    }
+                    break;
+
+                case TAG_RawOffset:
+                    {
+                        int val = buf[index++] & 0xff;
+                        val = (val << 8) + (buf[index++] & 0xff);
+                        val = (val << 8) + (buf[index++] & 0xff);
+                        val = (val << 8) + (buf[index++] & 0xff);
+                        rawOffset = val;
+                    }
+                    break;
+
+                case TAG_Transition:
+                    {
+                        int n = len / 8;
+                        transitions = new long[n];
+                        for (int i = 0; i < n; i ++) {
+                            long val = buf[index++] & 0xff;
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            transitions[i] = val;
+                        }
+                    }
+                    break;
+
+                case TAG_Offset:
+                    {
+                        int n = len / 4;
+                        offsets = new int[n];
+                        for (int i = 0; i < n; i ++) {
+                            int val = buf[index++] & 0xff;
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            offsets[i] = val;
+                        }
+                    }
+                    break;
+
+                case TAG_SimpleTimeZone:
+                    {
+                        if (len != 32 && len != 40) {
+                            System.err.println("ZoneInfo: wrong SimpleTimeZone parameter size");
+                            return null;
+                        }
+                        int n = len / 4;
+                        simpleTimeZoneParams = new int[n];
+                        for (int i = 0; i < n; i++) {
+                            int val = buf[index++] & 0xff;
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            simpleTimeZoneParams[i] = val;
+                        }
+                    }
+                    break;
+
+                case TAG_GMTOffsetWillChange:
+                    {
+                        if (len != 1) {
+                            System.err.println("ZoneInfo: wrong byte length for TAG_GMTOffsetWillChange");
+                        }
+                        willGMTOffsetChange = buf[index++] == 1;
+                    }
+                    break;
+
+                default:
+                    System.err.println("ZoneInfo: unknown tag < " + tag + ">. ignored.");
+                    index += len;
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("ZoneInfo: corrupted zoneinfo file: " + id);
+            return null;
+        }
+
+        if (index != filesize) {
+            System.err.println("ZoneInfo: wrong file size: " + id);
+            return null;
+        }
+
+        return new ZoneInfoOld(id, rawOffset, dstSavings, checksum,
+                            transitions, offsets, simpleTimeZoneParams,
+                            willGMTOffsetChange);
+    }
+
+    private volatile static SoftReference<List<String>> zoneIDs = null;
+
+    static List<String> getZoneIDs() {
+        List<String> ids = null;
+        SoftReference<List<String>> cache = zoneIDs;
+        if (cache != null) {
+            ids = cache.get();
+            if (ids != null) {
+                return ids;
+            }
+        }
+        byte[] buf = null;
+        buf = getZoneInfoOldMappings();
+        int index = JAVAZM_LABEL_LENGTH + 1;
+        int filesize = buf.length;
+        try {
+        loop:
+            while (index < filesize) {
+                byte tag = buf[index++];
+                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
+
+                switch (tag) {
+                case TAG_ZoneIDs:
+                    {
+                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);
+                        ids = new ArrayList<>(n);
+
+                        for (int i = 0; i < n; i++) {
+                            byte m = buf[index++];
+                            ids.add(new String(buf, index, m, "UTF-8"));
+                            index += m;
+                        }
+                    }
+                    break loop;
+
+                default:
+                    index += len;
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME);
+        }
+
+        zoneIDs = new SoftReference<>(ids);
+        return ids;
+    }
+
+    /**
+     * @return an alias table in HashMap where a key is an alias ID
+     * (e.g., "PST") and its value is a real time zone ID (e.g.,
+     * "America/Los_Angeles").
+     */
+    static Map<String, String> getZoneAliases() {
+        byte[] buf = getZoneInfoOldMappings();
+        int index = JAVAZM_LABEL_LENGTH + 1;
+        int filesize = buf.length;
+        Map<String, String> aliases = null;
+
+        try {
+        loop:
+            while (index < filesize) {
+                byte tag = buf[index++];
+                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
+
+                switch (tag) {
+                case TAG_ZoneAliases:
+                    {
+                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);
+                        aliases = new HashMap<>(n);
+                        for (int i = 0; i < n; i++) {
+                            byte m = buf[index++];
+                            String name = new String(buf, index, m, "UTF-8");
+                            index += m;
+                            m = buf[index++];
+                            String realName = new String(buf, index, m, "UTF-8");
+                            index += m;
+                            aliases.put(name, realName);
+                        }
+                    }
+                    break loop;
+
+                default:
+                    index += len;
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME);
+            return null;
+        }
+        return aliases;
+    }
+
+    private volatile static SoftReference<List<String>> excludedIDs = null;
+    private volatile static boolean hasNoExcludeList = false;
+
+    /**
+     * @return a List of zone IDs for zones that will change their GMT
+     * offsets in some future time.
+     *
+     * @since 1.6
+     */
+    static List<String> getExcludedZones() {
+        if (hasNoExcludeList) {
+            return null;
+        }
+
+        List<String> excludeList = null;
+
+        SoftReference<List<String>> cache = excludedIDs;
+        if (cache != null) {
+            excludeList = cache.get();
+            if (excludeList != null) {
+                return excludeList;
+            }
+        }
+
+        byte[] buf = getZoneInfoOldMappings();
+        int index = JAVAZM_LABEL_LENGTH + 1;
+        int filesize = buf.length;
+
+        try {
+          loop:
+            while (index < filesize) {
+                byte tag = buf[index++];
+                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
+
+                switch (tag) {
+                case TAG_ExcludedZones:
+                    {
+                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);
+                        excludeList = new ArrayList<>();
+                        for (int i = 0; i < n; i++) {
+                            byte m = buf[index++];
+                            String name = new String(buf, index, m, "UTF-8");
+                            index += m;
+                            excludeList.add(name);
+                        }
+                    }
+                    break loop;
+
+                default:
+                    index += len;
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME);
+            return null;
+        }
+
+        if (excludeList != null) {
+            excludedIDs = new SoftReference<>(excludeList);
+        } else {
+            hasNoExcludeList = true;
+        }
+        return excludeList;
+    }
+
+    private volatile static SoftReference<byte[]> rawOffsetIndices = null;
+
+    static byte[] getRawOffsetIndices() {
+        byte[] indices = null;
+
+        SoftReference<byte[]> cache = rawOffsetIndices;
+        if (cache != null) {
+            indices = cache.get();
+            if (indices != null) {
+                return indices;
+            }
+        }
+
+        byte[] buf = getZoneInfoOldMappings();
+        int index = JAVAZM_LABEL_LENGTH + 1;
+        int filesize = buf.length;
+
+        try {
+        loop:
+            while (index < filesize) {
+                byte tag = buf[index++];
+                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
+
+                switch (tag) {
+                case TAG_RawOffsetIndices:
+                    {
+                        indices = new byte[len];
+                        for (int i = 0; i < len; i++) {
+                            indices[i] = buf[index++];
+                        }
+                    }
+                    break loop;
+
+                default:
+                    index += len;
+                    break;
+                }
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME);
+        }
+
+        rawOffsetIndices = new SoftReference<>(indices);
+        return indices;
+    }
+
+    private volatile static SoftReference<int[]> rawOffsets = null;
+
+    static int[] getRawOffsets() {
+        int[] offsets = null;
+
+        SoftReference<int[]> cache = rawOffsets;
+        if (cache != null) {
+            offsets = cache.get();
+            if (offsets != null) {
+                return offsets;
+            }
+        }
+
+        byte[] buf = getZoneInfoOldMappings();
+        int index = JAVAZM_LABEL_LENGTH + 1;
+        int filesize = buf.length;
+
+        try {
+        loop:
+            while (index < filesize) {
+                byte tag = buf[index++];
+                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);
+
+                switch (tag) {
+                case TAG_RawOffsets:
+                    {
+                        int n = len/4;
+                        offsets = new int[n];
+                        for (int i = 0; i < n; i++) {
+                            int val = buf[index++] & 0xff;
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            val = (val << 8) + (buf[index++] & 0xff);
+                            offsets[i] = val;
+                        }
+                    }
+                    break loop;
+
+                default:
+                    index += len;
+                    break;
+                }
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME);
+        }
+
+        rawOffsets = new SoftReference<>(offsets);
+        return offsets;
+    }
+
+    private volatile static SoftReference<byte[]> zoneInfoMappings = null;
+
+    private static byte[] getZoneInfoOldMappings() {
+        byte[] data;
+        SoftReference<byte[]> cache = zoneInfoMappings;
+        if (cache != null) {
+            data = cache.get();
+            if (data != null) {
+                return data;
+            }
+        }
+        data = readZoneInfoFile(JAVAZM_FILE_NAME);
+        if (data == null) {
+            throw new RuntimeException("ZoneInfoOldMapping " +
+                JAVAZM_FILE_NAME + " either doesn't exist or doesn't have data");
+        }
+
+        int index;
+        for (index = 0; index < JAVAZM_LABEL.length; index++) {
+            if (data[index] != JAVAZM_LABEL[index]) {
+                System.err.println("ZoneInfoOld: wrong magic number: " + JAVAZM_FILE_NAME);
+                return null;
+            }
+        }
+        if (data[index++] > JAVAZM_VERSION) {
+            System.err.println("ZoneInfoOld: incompatible version ("
+                               + data[index - 1] + "): " + JAVAZM_FILE_NAME);
+            return null;
+        }
+
+        zoneInfoMappings = new SoftReference<>(data);
+        return data;
+    }
+
+    /**
+     * Reads the specified file under &lt;java.home&gt;/lib/zi into a buffer.
+     * @return the buffer, or null if any I/O error occurred.
+     */
+    private static byte[] readZoneInfoFile(final String fileName) {
+        if (fileName.indexOf("..") >= 0) {
+            return null;
+        }
+        byte[] buffer = null;
+        File file = new File(ziDir, fileName);
+        try {
+            int filesize = (int)file.length();
+            if (filesize > 0) {
+                FileInputStream fis = new FileInputStream(file);
+                buffer = new byte[filesize];
+                try {
+                    if (fis.read(buffer) != filesize) {
+                        throw new IOException("read error on " + fileName);
+                    }
+                } finally {
+                    fis.close();
+                }
+            }
+        } catch (Exception ex) {
+            if (!(ex instanceof FileNotFoundException) || JAVAZM_FILE_NAME.equals(fileName)) {
+                System.err.println("ZoneInfoOld: " + ex.getMessage());
+            }
+        }
+        return buffer;
+    }
+
+    private ZoneInfoFile() {
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/ZoneInfoOld.java b/jdk/test/sun/util/calendar/zi/ZoneInfoOld.java
new file mode 100644
index 0000000..4a0a31e
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/ZoneInfoOld.java
@@ -0,0 +1,1047 @@
+/*
+ * Copyright (c) 2000, 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.  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.
+ */
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.ref.SoftReference;
+import java.time.ZoneOffset;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+import sun.util.calendar.CalendarSystem;
+import sun.util.calendar.CalendarDate;
+
+/**
+ * <code>ZoneInfoOld</code> is an implementation subclass of {@link
+ * java.util.TimeZone TimeZone} that represents GMT offsets and
+ * daylight saving time transitions of a time zone.
+ * <p>
+ * The daylight saving time transitions are described in the {@link
+ * #transitions transitions} table consisting of a chronological
+ * sequence of transitions of GMT offset and/or daylight saving time
+ * changes. Since all transitions are represented in UTC, in theory,
+ * <code>ZoneInfoOld</code> can be used with any calendar systems except
+ * for the {@link #getOffset(int,int,int,int,int,int) getOffset}
+ * method that takes Gregorian calendar date fields.
+ * <p>
+ * This table covers transitions from 1900 until 2037 (as of version
+ * 1.4), Before 1900, it assumes that there was no daylight saving
+ * time and the <code>getOffset</code> methods always return the
+ * {@link #getRawOffset} value. No Local Mean Time is supported. If a
+ * specified date is beyond the transition table and this time zone is
+ * supposed to observe daylight saving time in 2037, it delegates
+ * operations to a {@link java.util.SimpleTimeZone SimpleTimeZone}
+ * object created using the daylight saving time schedule as of 2037.
+ * <p>
+ * The date items, transitions, GMT offset(s), etc. are read from a database
+ * file. See {@link ZoneInfoFile} for details.
+ * @see java.util.SimpleTimeZone
+ * @since 1.4
+ */
+
+public class ZoneInfoOld extends TimeZone {
+
+    // The constants assume no leap seconds support.
+    static final int SECOND_IN_MILLIS = 1000;
+    static final int MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
+    static final int HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
+    static final int DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
+
+    private static final int UTC_TIME = 0;
+    private static final int STANDARD_TIME = 1;
+    private static final int WALL_TIME = 2;
+
+    private static final long OFFSET_MASK = 0x0fL;
+    private static final long DST_MASK = 0xf0L;
+    private static final int DST_NSHIFT = 4;
+    // this bit field is reserved for abbreviation support
+    private static final long ABBR_MASK = 0xf00L;
+    private static final int TRANSITION_NSHIFT = 12;
+
+    // Flag for supporting JDK backward compatible IDs, such as "EST".
+    static final boolean USE_OLDMAPPING;
+    static {
+      String oldmapping = System.getProperty("sun.timezone.ids.oldmapping", "false").toLowerCase(Locale.ROOT);
+      USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
+    }
+
+    // IDs having conflicting data between Olson and JDK 1.1
+    static final String[] conflictingIDs = {
+        "EST", "MST", "HST"
+    };
+
+    private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
+
+    /**
+     * The raw GMT offset in milliseconds between this zone and GMT.
+     * Negative offsets are to the west of Greenwich.  To obtain local
+     * <em>standard</em> time, add the offset to GMT time.
+     * @serial
+     */
+    int rawOffset;
+
+    /**
+     * Difference in milliseconds from the original GMT offset in case
+     * the raw offset value has been modified by calling {@link
+     * #setRawOffset}. The initial value is 0.
+     * @serial
+     */
+    int rawOffsetDiff = 0;
+
+    /**
+     * A CRC32 value of all pairs of transition time (in milliseconds
+     * in <code>long</code>) in local time and its GMT offset (in
+     * seconds in <code>int</code>) in the chronological order. Byte
+     * values of each <code>long</code> and <code>int</code> are taken
+     * in the big endian order (i.e., MSB to LSB).
+     * @serial
+     */
+    int checksum;
+
+    /**
+     * The amount of time in milliseconds saved during daylight saving
+     * time. If <code>useDaylight</code> is false, this value is 0.
+     * @serial
+     */
+    int dstSavings;
+
+    /**
+     * This array describes transitions of GMT offsets of this time
+     * zone, including both raw offset changes and daylight saving
+     * time changes.
+     * A long integer consists of four bit fields.
+     * <ul>
+     * <li>The most significant 52-bit field represents transition
+     * time in milliseconds from Gregorian January 1 1970, 00:00:00
+     * GMT.</li>
+     * <li>The next 4-bit field is reserved and must be 0.</li>
+     * <li>The next 4-bit field is an index value to {@link #offsets
+     * offsets[]} for the amount of daylight saving at the
+     * transition. If this value is zero, it means that no daylight
+     * saving, not the index value zero.</li>
+     * <li>The least significant 4-bit field is an index value to
+     * {@link #offsets offsets[]} for <em>total</em> GMT offset at the
+     * transition.</li>
+     * </ul>
+     * If this time zone doesn't observe daylight saving time and has
+     * never changed any GMT offsets in the past, this value is null.
+     * @serial
+     */
+    long[] transitions;
+
+    /**
+     * This array holds all unique offset values in
+     * milliseconds. Index values to this array are stored in the
+     * transitions array elements.
+     * @serial
+     */
+    int[] offsets;
+
+    /**
+     * SimpleTimeZone parameter values. It has to have either 8 for
+     * {@link java.util.SimpleTimeZone#SimpleTimeZone(int, String,
+     * int, int , int , int , int , int , int , int , int) the
+     * 11-argument SimpleTimeZone constructor} or 10 for {@link
+     * java.util.SimpleTimeZone#SimpleTimeZone(int, String, int, int,
+     * int , int , int , int , int , int , int, int, int) the
+     * 13-argument SimpleTimeZone constructor} parameters.
+     * @serial
+     */
+    int[] simpleTimeZoneParams;
+
+    /**
+     * True if the raw GMT offset value would change after the time
+     * zone data has been generated; false, otherwise. The default
+     * value is false.
+     * @serial
+     */
+    boolean willGMTOffsetChange = false;
+
+    /**
+     * True if the object has been modified after its instantiation.
+     */
+    transient private boolean dirty = false;
+
+    private static final long serialVersionUID = 2653134537216586139L;
+
+    /**
+     * A constructor.
+     */
+    public ZoneInfoOld() {
+    }
+
+    /**
+     * A Constructor for CustomID.
+     */
+    public ZoneInfoOld(String ID, int rawOffset) {
+        this(ID, rawOffset, 0, 0, null, null, null, false);
+    }
+
+    /**
+     * Constructs a ZoneInfoOld instance.
+     *
+     * @param ID time zone name
+     * @param rawOffset GMT offset in milliseconds
+     * @param dstSavings daylight saving value in milliseconds or 0
+     * (zero) if this time zone doesn't observe Daylight Saving Time.
+     * @param checksum CRC32 value with all transitions table entry
+     * values
+     * @param transitions transition table
+     * @param offsets offset value table
+     * @param simpleTimeZoneParams parameter values for constructing
+     * SimpleTimeZone
+     * @param willGMTOffsetChange the value of willGMTOffsetChange
+     */
+    ZoneInfoOld(String ID,
+             int rawOffset,
+             int dstSavings,
+             int checksum,
+             long[] transitions,
+             int[] offsets,
+             int[] simpleTimeZoneParams,
+             boolean willGMTOffsetChange) {
+        setID(ID);
+        this.rawOffset = rawOffset;
+        this.dstSavings = dstSavings;
+        this.checksum = checksum;
+        this.transitions = transitions;
+        this.offsets = offsets;
+        this.simpleTimeZoneParams = simpleTimeZoneParams;
+        this.willGMTOffsetChange = willGMTOffsetChange;
+    }
+
+    /**
+     * Returns the difference in milliseconds between local time and UTC
+     * of given time, taking into account both the raw offset and the
+     * effect of daylight savings.
+     *
+     * @param date the milliseconds in UTC
+     * @return the milliseconds to add to UTC to get local wall time
+     */
+    public int getOffset(long date) {
+        return getOffsets(date, null, UTC_TIME);
+    }
+
+    public int getOffsets(long utc, int[] offsets) {
+        return getOffsets(utc, offsets, UTC_TIME);
+    }
+
+    public int getOffsetsByStandard(long standard, int[] offsets) {
+        return getOffsets(standard, offsets, STANDARD_TIME);
+    }
+
+    public int getOffsetsByWall(long wall, int[] offsets) {
+        return getOffsets(wall, offsets, WALL_TIME);
+    }
+
+    private int getOffsets(long date, int[] offsets, int type) {
+        // if dst is never observed, there is no transition.
+        if (transitions == null) {
+            int offset = getLastRawOffset();
+            if (offsets != null) {
+                offsets[0] = offset;
+                offsets[1] = 0;
+            }
+            return offset;
+        }
+
+        date -= rawOffsetDiff;
+        int index = getTransitionIndex(date, type);
+
+        // prior to the transition table, returns the raw offset.
+        // FIXME: should support LMT.
+        if (index < 0) {
+            int offset = getLastRawOffset();
+            if (offsets != null) {
+                offsets[0] = offset;
+                offsets[1] = 0;
+            }
+            return offset;
+        }
+
+        if (index < transitions.length) {
+            long val = transitions[index];
+            int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff;
+            if (offsets != null) {
+                int dst = (int)((val >>> DST_NSHIFT) & 0xfL);
+                int save = (dst == 0) ? 0 : this.offsets[dst];
+                offsets[0] = offset - save;
+                offsets[1] = save;
+            }
+            return offset;
+        }
+
+        // beyond the transitions, delegate to SimpleTimeZone if there
+        // is a rule; otherwise, return rawOffset.
+        SimpleTimeZone tz = getLastRule();
+        if (tz != null) {
+            int rawoffset = tz.getRawOffset();
+            long msec = date;
+            if (type != UTC_TIME) {
+                msec -= rawOffset;
+            }
+            int dstoffset = tz.getOffset(msec) - rawOffset;
+
+            // Check if it's in a standard-to-daylight transition.
+            if (dstoffset > 0 && tz.getOffset(msec - dstoffset) == rawoffset) {
+                dstoffset = 0;
+            }
+
+            if (offsets != null) {
+                offsets[0] = rawoffset;
+                offsets[1] = dstoffset;
+            }
+            return rawoffset + dstoffset;
+        }
+        int offset = getLastRawOffset();
+        if (offsets != null) {
+            offsets[0] = offset;
+            offsets[1] = 0;
+        }
+        return offset;
+    }
+
+    private int getTransitionIndex(long date, int type) {
+        int low = 0;
+        int high = transitions.length - 1;
+
+        while (low <= high) {
+            int mid = (low + high) / 2;
+            long val = transitions[mid];
+            long midVal = val >> TRANSITION_NSHIFT; // sign extended
+            if (type != UTC_TIME) {
+                midVal += offsets[(int)(val & OFFSET_MASK)]; // wall time
+            }
+            if (type == STANDARD_TIME) {
+                int dstIndex = (int)((val >>> DST_NSHIFT) & 0xfL);
+                if (dstIndex != 0) {
+                    midVal -= offsets[dstIndex]; // make it standard time
+                }
+            }
+
+            if (midVal < date) {
+                low = mid + 1;
+            } else if (midVal > date) {
+                high = mid - 1;
+            } else {
+                return mid;
+            }
+        }
+
+        // if beyond the transitions, returns that index.
+        if (low >= transitions.length) {
+            return low;
+        }
+        return low - 1;
+    }
+
+   /**
+     * Returns the difference in milliseconds between local time and
+     * UTC, taking into account both the raw offset and the effect of
+     * daylight savings, for the specified date and time.  This method
+     * assumes that the start and end month are distinct.  This method
+     * assumes a Gregorian calendar for calculations.
+     * <p>
+     * <em>Note: In general, clients should use
+     * {@link Calendar#ZONE_OFFSET Calendar.get(ZONE_OFFSET)} +
+     * {@link Calendar#DST_OFFSET Calendar.get(DST_OFFSET)}
+     * instead of calling this method.</em>
+     *
+     * @param era       The era of the given date. The value must be either
+     *                  GregorianCalendar.AD or GregorianCalendar.BC.
+     * @param year      The year in the given date.
+     * @param month     The month in the given date. Month is 0-based. e.g.,
+     *                  0 for January.
+     * @param day       The day-in-month of the given date.
+     * @param dayOfWeek The day-of-week of the given date.
+     * @param millis    The milliseconds in day in <em>standard</em> local time.
+     * @return The milliseconds to add to UTC to get local time.
+     */
+    public int getOffset(int era, int year, int month, int day,
+                         int dayOfWeek, int milliseconds) {
+        if (milliseconds < 0 || milliseconds >= DAY_IN_MILLIS) {
+            throw new IllegalArgumentException();
+        }
+
+        if (era == java.util.GregorianCalendar.BC) { // BC
+            year = 1 - year;
+        } else if (era != java.util.GregorianCalendar.AD) {
+            throw new IllegalArgumentException();
+        }
+
+        CalendarDate date = gcal.newCalendarDate(null);
+        date.setDate(year, month + 1, day);
+        if (gcal.validate(date) == false) {
+            throw new IllegalArgumentException();
+        }
+
+        // bug-for-bug compatible argument checking
+        if (dayOfWeek < java.util.GregorianCalendar.SUNDAY
+            || dayOfWeek > java.util.GregorianCalendar.SATURDAY) {
+            throw new IllegalArgumentException();
+        }
+
+        if (transitions == null) {
+            return getLastRawOffset();
+        }
+
+        long dateInMillis = gcal.getTime(date) + milliseconds;
+        dateInMillis -= (long) rawOffset; // make it UTC
+        return getOffsets(dateInMillis, null, UTC_TIME);
+    }
+
+    /**
+     * Sets the base time zone offset from GMT. This operation
+     * modifies all the transitions of this ZoneInfoOld object, including
+     * historical ones, if applicable.
+     *
+     * @param offsetMillis the base time zone offset to GMT.
+     * @see getRawOffset
+     */
+    public synchronized void setRawOffset(int offsetMillis) {
+        if (offsetMillis == rawOffset + rawOffsetDiff) {
+            return;
+        }
+        rawOffsetDiff = offsetMillis - rawOffset;
+        if (lastRule != null) {
+            lastRule.setRawOffset(offsetMillis);
+        }
+        dirty = true;
+    }
+
+    /**
+     * Returns the GMT offset of the current date. This GMT offset
+     * value is not modified during Daylight Saving Time.
+     *
+     * @return the GMT offset value in milliseconds to add to UTC time
+     * to get local standard time
+     */
+    public int getRawOffset() {
+        if (!willGMTOffsetChange) {
+            return rawOffset + rawOffsetDiff;
+        }
+
+        int[] offsets = new int[2];
+        getOffsets(System.currentTimeMillis(), offsets, UTC_TIME);
+        return offsets[0];
+    }
+
+    public boolean isDirty() {
+        return dirty;
+    }
+
+    int getLastRawOffset() {
+        return rawOffset + rawOffsetDiff;
+    }
+
+    /**
+     * Queries if this time zone uses Daylight Saving Time in the last known rule.
+     */
+    public boolean useDaylightTime() {
+        return (simpleTimeZoneParams != null);
+    }
+
+    @Override
+    public boolean observesDaylightTime() {
+        if (simpleTimeZoneParams != null) {
+            return true;
+        }
+        if (transitions == null) {
+            return false;
+        }
+
+        // Look up the transition table to see if it's in DST right
+        // now or if there's any standard-to-daylight transition at
+        // any future.
+        long utc = System.currentTimeMillis() - rawOffsetDiff;
+        int index = getTransitionIndex(utc, UTC_TIME);
+
+        // before transitions in the transition table
+        if (index < 0) {
+            return false;
+        }
+
+        // the time is in the table range.
+        for (int i = index; i < transitions.length; i++) {
+            if ((transitions[i] & DST_MASK) != 0) {
+                return true;
+            }
+        }
+        // No further DST is observed.
+        return false;
+    }
+
+    /**
+     * Queries if the specified date is in Daylight Saving Time.
+     */
+    public boolean inDaylightTime(Date date) {
+        if (date == null) {
+            throw new NullPointerException();
+        }
+
+        if (transitions == null) {
+            return false;
+        }
+
+        long utc = date.getTime() - rawOffsetDiff;
+        int index = getTransitionIndex(utc, UTC_TIME);
+
+        // before transitions in the transition table
+        if (index < 0) {
+            return false;
+        }
+
+        // the time is in the table range.
+        if (index < transitions.length) {
+            return (transitions[index] & DST_MASK) != 0;
+        }
+
+        // beyond the transition table
+        SimpleTimeZone tz = getLastRule();
+        if (tz != null) {
+            return tz.inDaylightTime(date);
+        }
+        return false;
+    }
+
+    /**
+     * Returns the amount of time in milliseconds that the clock is advanced
+     * during daylight saving time is in effect in its last daylight saving time rule.
+     *
+     * @return the number of milliseconds the time is advanced with respect to
+     * standard time when daylight saving time is in effect.
+     */
+    public int getDSTSavings() {
+        return dstSavings;
+    }
+
+//    /**
+//     * @return the last year in the transition table or -1 if this
+//     * time zone doesn't observe any daylight saving time.
+//     */
+//    public int getMaxTransitionYear() {
+//      if (transitions == null) {
+//          return -1;
+//      }
+//      long val = transitions[transitions.length - 1];
+//      int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff;
+//      val = (val >> TRANSITION_NSHIFT) + offset;
+//      CalendarDate lastDate = Gregorian.getCalendarDate(val);
+//      return lastDate.getYear();
+//    }
+
+    /**
+     * Returns a string representation of this time zone.
+     * @return the string
+     */
+    public String toString() {
+        return getClass().getName() +
+            "[id=\"" + getID() + "\"" +
+            ",offset=" + getLastRawOffset() +
+            ",dstSavings=" + dstSavings +
+            ",useDaylight=" + useDaylightTime() +
+            ",transitions=" + ((transitions != null) ? transitions.length : 0) +
+            ",lastRule=" + (lastRule == null ? getLastRuleInstance() : lastRule) +
+            "]";
+    }
+
+    /**
+     * Gets all available IDs supported in the Java run-time.
+     *
+     * @return an array of time zone IDs.
+     */
+    public static String[] getAvailableIDs() {
+        List<String> idList = ZoneInfoFile.getZoneIDs();
+        List<String> excluded = ZoneInfoFile.getExcludedZones();
+        if (excluded != null) {
+            // List all zones from the idList and excluded lists
+            List<String> list = new ArrayList<>(idList.size() + excluded.size());
+            list.addAll(idList);
+            list.addAll(excluded);
+            idList = list;
+        }
+        String[] ids = new String[idList.size()];
+        return idList.toArray(ids);
+    }
+
+    /**
+     * Gets all available IDs that have the same value as the
+     * specified raw GMT offset.
+     *
+     * @param rawOffset the GMT offset in milliseconds. This
+     * value should not include any daylight saving time.
+     *
+     * @return an array of time zone IDs.
+     */
+    public static String[] getAvailableIDs(int rawOffset) {
+        String[] result;
+        List<String> matched = new ArrayList<>();
+        List<String> IDs = ZoneInfoFile.getZoneIDs();
+        int[] rawOffsets = ZoneInfoFile.getRawOffsets();
+
+    loop:
+        for (int index = 0; index < rawOffsets.length; index++) {
+            if (rawOffsets[index] == rawOffset) {
+                byte[] indices = ZoneInfoFile.getRawOffsetIndices();
+                for (int i = 0; i < indices.length; i++) {
+                    if (indices[i] == index) {
+                        matched.add(IDs.get(i++));
+                        while (i < indices.length && indices[i] == index) {
+                            matched.add(IDs.get(i++));
+                        }
+                        break loop;
+                    }
+                }
+            }
+        }
+
+        // We need to add any zones from the excluded zone list that
+        // currently have the same GMT offset as the specified
+        // rawOffset. The zones returned by this method may not be
+        // correct as of return to the caller if any GMT offset
+        // transition is happening during this GMT offset checking...
+        List<String> excluded = ZoneInfoFile.getExcludedZones();
+        if (excluded != null) {
+            for (String id : excluded) {
+                TimeZone zi = getTimeZone(id);
+                if (zi != null && zi.getRawOffset() == rawOffset) {
+                    matched.add(id);
+                }
+            }
+        }
+
+        result = new String[matched.size()];
+        matched.toArray(result);
+        return result;
+    }
+
+    /**
+     * Gets the ZoneInfoOld for the given ID.
+     *
+     * @param ID the ID for a ZoneInfoOld. See TimeZone for detail.
+     *
+     * @return the specified ZoneInfoOld object, or null if there is no
+     * time zone of the ID.
+     */
+    public static TimeZone getTimeZone(String ID) {
+        String givenID = null;
+
+        /*
+         * If old JDK compatibility is specified, get the old alias
+         * name.
+         */
+        if (USE_OLDMAPPING) {
+            String compatibleID = TzIDOldMapping.MAP.get(ID);
+            if (compatibleID != null) {
+                givenID = ID;
+                ID = compatibleID;
+            }
+        }
+
+        ZoneInfoOld zi = ZoneInfoFile.getZoneInfoOld(ID);
+        if (zi == null) {
+            // if we can't create an object for the ID, try aliases.
+            try {
+                Map<String, String> map = getAliasTable();
+                String alias = ID;
+                while ((alias = map.get(alias)) != null) {
+                    zi = ZoneInfoFile.getZoneInfoOld(alias);
+                    if (zi != null) {
+                        zi.setID(ID);
+                        zi = ZoneInfoFile.addToCache(ID, zi);
+                        zi = (ZoneInfoOld) zi.clone();
+                        break;
+                    }
+                }
+            } catch (Exception e) {
+                // ignore exceptions
+            }
+        }
+
+        if (givenID != null && zi != null) {
+            zi.setID(givenID);
+        }
+        return zi;
+    }
+
+    private transient SimpleTimeZone lastRule;
+
+    /**
+     * Returns a SimpleTimeZone object representing the last GMT
+     * offset and DST schedule or null if this time zone doesn't
+     * observe DST.
+     */
+    synchronized SimpleTimeZone getLastRule() {
+        if (lastRule == null) {
+            lastRule = getLastRuleInstance();
+        }
+        return lastRule;
+    }
+
+    /**
+     * Returns a SimpleTimeZone object that represents the last
+     * known daylight saving time rules.
+     *
+     * @return a SimpleTimeZone object or null if this time zone
+     * doesn't observe DST.
+     */
+    public SimpleTimeZone getLastRuleInstance() {
+        if (simpleTimeZoneParams == null) {
+            return null;
+        }
+        if (simpleTimeZoneParams.length == 10) {
+            return new SimpleTimeZone(getLastRawOffset(), getID(),
+                                      simpleTimeZoneParams[0],
+                                      simpleTimeZoneParams[1],
+                                      simpleTimeZoneParams[2],
+                                      simpleTimeZoneParams[3],
+                                      simpleTimeZoneParams[4],
+                                      simpleTimeZoneParams[5],
+                                      simpleTimeZoneParams[6],
+                                      simpleTimeZoneParams[7],
+                                      simpleTimeZoneParams[8],
+                                      simpleTimeZoneParams[9],
+                                      dstSavings);
+        }
+        return new SimpleTimeZone(getLastRawOffset(), getID(),
+                                  simpleTimeZoneParams[0],
+                                  simpleTimeZoneParams[1],
+                                  simpleTimeZoneParams[2],
+                                  simpleTimeZoneParams[3],
+                                  simpleTimeZoneParams[4],
+                                  simpleTimeZoneParams[5],
+                                  simpleTimeZoneParams[6],
+                                  simpleTimeZoneParams[7],
+                                  dstSavings);
+    }
+
+    /**
+     * Returns a copy of this <code>ZoneInfoOld</code>.
+     */
+    public Object clone() {
+        ZoneInfoOld zi = (ZoneInfoOld) super.clone();
+        zi.lastRule = null;
+        return zi;
+    }
+
+    /**
+     * Returns a hash code value calculated from the GMT offset and
+     * transitions.
+     * @return a hash code of this time zone
+     */
+    public int hashCode() {
+        return getLastRawOffset() ^ checksum;
+    }
+
+    /**
+     * Compares the equity of two ZoneInfoOld objects.
+     *
+     * @param obj the object to be compared with
+     * @return true if given object is same as this ZoneInfoOld object,
+     * false otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof ZoneInfoOld)) {
+            return false;
+        }
+        ZoneInfoOld that = (ZoneInfoOld) obj;
+        return (getID().equals(that.getID())
+                && (getLastRawOffset() == that.getLastRawOffset())
+                && (checksum == that.checksum));
+    }
+
+    /**
+     * Returns true if this zone has the same raw GMT offset value and
+     * transition table as another zone info. If the specified
+     * TimeZone object is not a ZoneInfoOld instance, this method returns
+     * true if the specified TimeZone object has the same raw GMT
+     * offset value with no daylight saving time.
+     *
+     * @param other the ZoneInfoOld object to be compared with
+     * @return true if the given <code>TimeZone</code> has the same
+     * GMT offset and transition information; false, otherwise.
+     */
+    public boolean hasSameRules(TimeZone other) {
+        if (this == other) {
+            return true;
+        }
+        if (other == null) {
+            return false;
+        }
+        if (!(other instanceof ZoneInfoOld)) {
+            if (getRawOffset() != other.getRawOffset()) {
+                return false;
+            }
+            // if both have the same raw offset and neither observes
+            // DST, they have the same rule.
+            if ((transitions == null)
+                && (useDaylightTime() == false)
+                && (other.useDaylightTime() == false)) {
+                return true;
+            }
+            return false;
+        }
+        if (getLastRawOffset() != ((ZoneInfoOld)other).getLastRawOffset()) {
+            return false;
+        }
+        return (checksum == ((ZoneInfoOld)other).checksum);
+    }
+
+    private static SoftReference<Map<String, String>> aliasTable;
+
+    static Map<String, String> getCachedAliasTable() {
+        Map<String, String> aliases = null;
+
+        SoftReference<Map<String, String>> cache = aliasTable;
+        if (cache != null) {
+            aliases = cache.get();
+        }
+        return aliases;
+    }
+
+    /**
+     * Returns a Map from alias time zone IDs to their standard
+     * time zone IDs.
+     *
+     * @return the Map that holds the mappings from alias time zone IDs
+     *    to their standard time zone IDs, or null if
+     *    <code>ZoneInfoOldMappings</code> file is not available.
+     */
+     public synchronized static Map<String, String> getAliasTable() {
+         Map<String, String> aliases = getCachedAliasTable();
+         if (aliases == null) {
+             aliases = ZoneInfoFile.getZoneAliases();
+             if (aliases != null) {
+                 if (!USE_OLDMAPPING) {
+                     // Remove the conflicting IDs from the alias table.
+                     for (String key : conflictingIDs) {
+                         aliases.remove(key);
+                     }
+                 }
+                 aliasTable = new SoftReference<Map<String, String>>(aliases);
+             }
+         }
+         return aliases;
+     }
+
+    private void readObject(ObjectInputStream stream)
+            throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+        // We don't know how this object from 1.4.x or earlier has
+        // been mutated. So it should always be marked as `dirty'.
+        dirty = true;
+    }
+
+    //////////////////////////////////////////////////////////////
+    public boolean equalsTo(ZoneInfoOld other) {
+        return (getID().equals(other.getID())
+                && (getLastRawOffset() == other.getLastRawOffset())
+                && (dstSavings == other.dstSavings)
+                && (willGMTOffsetChange == other.willGMTOffsetChange)
+                && (checksum == other.checksum)
+                && equalsTransOffsets(other)
+                && (Arrays.equals(simpleTimeZoneParams, other.simpleTimeZoneParams) ||
+                    getLastRule().equals(other.getLastRule())));
+    }
+
+    private boolean equalsTransOffsets(ZoneInfoOld other) {
+        if (transitions == null) {
+            return (other.transitions == null &&
+                    Arrays.equals(offsets, other.offsets));
+        }
+        if (other.transitions == null ||
+            transitions.length != other.transitions.length) {
+            return false;
+        }
+        // if offsets and other.offsets have different order
+        // the last 4-bit in trans are different.
+        for (int i = 0; i < transitions.length; i++) {
+            long val = transitions[i];
+            int dst = (int)((val >>> DST_NSHIFT) & 0xfL);
+            int save = (dst == 0) ? 0 : offsets[dst] / 1000;
+            int off = offsets[(int)(val & OFFSET_MASK)]/1000;
+            long second = (val >> TRANSITION_NSHIFT)/1000;
+
+            val = other.transitions[i];
+            int dstO = (int)((val >>> DST_NSHIFT) & 0xfL);
+            int saveO = (dstO == 0) ? 0 : other.offsets[dstO] / 1000;
+            int offO = other.offsets[(int)(val & OFFSET_MASK)]/1000;
+            long secondO = (val >> TRANSITION_NSHIFT)/1000;
+            if ((dst == 0) != (dstO == 0) || save != saveO || off != offO || second != secondO)
+                return false;
+        }
+        return true;
+    }
+
+    private int transToString(long val, int off_old, int[] offsets, StringBuilder sb) {
+        int dst = (int)((val >>> DST_NSHIFT) & 0xfL);
+        int save = (dst == 0) ? 0 : offsets[dst] / 1000;
+        int off = offsets[(int)(val & OFFSET_MASK)]/1000;
+        long second = (val >> TRANSITION_NSHIFT)/1000;
+        ZoneOffset offset_old = ZoneOffset.ofTotalSeconds(off_old);
+        ZoneOffset offset = ZoneOffset.ofTotalSeconds(off);
+        sb.append("          " + LocalDateTime.ofEpochSecond(second, 0, offset_old));
+
+        sb.append("  [utc=" + second +
+                  "   raw=" + Long.toHexString(val >> TRANSITION_NSHIFT) +
+                  ", offset=" + off + "/" + offset + ", saving=" + save + "]");
+        return off;
+    }
+
+    public String diffsTo(ZoneInfoOld other) {
+
+        int rawOffset0                = other.rawOffset;
+        int checksum0                 = other.checksum;
+        int dstSavings0               = other.dstSavings;
+        long[] transitions0           = other.transitions;
+        int[] offsets0                = other.offsets;
+        int[] simpleTimeZoneParams0   = other.simpleTimeZoneParams;
+        boolean willGMTOffsetChange0  = other.willGMTOffsetChange;
+
+
+        //return getClass().getName() +
+        StringBuilder sb = new StringBuilder();
+        sb.append("******************************\n" +
+                  getID() + " : " + other.getID());
+        // ROC is excluded by ZoneInfoOld
+        if ("ROC".equals(getID())) {
+            return sb.toString();
+        }
+        if (rawOffset != rawOffset0 ||
+            dstSavings != dstSavings0 ||
+            checksum != checksum0 ||
+            willGMTOffsetChange != willGMTOffsetChange0 ||
+            (simpleTimeZoneParams != null ) != (simpleTimeZoneParams0 != null) ||
+            (transitions != null && transitions0 != null &&
+            transitions.length != transitions0.length))
+        {
+            sb.append("\n    offset=" + getLastRawOffset() +
+                  ",dstSavings=" + dstSavings +
+                  ",useDaylight=" + useDaylightTime() +
+                  ",transitions=" + ((transitions != null) ? transitions.length : 0) +
+                  ",offsets=" + ((offsets != null) ? offsets.length : 0) +
+                  ",checksum=" + checksum +
+                  ",gmtChanged=" + willGMTOffsetChange)
+              .append("\n[NG]offset=" + rawOffset0 +
+                      ",dstSavings=" + dstSavings0 +
+                      ",useDaylight=" + (simpleTimeZoneParams != null) +
+                      ",transitions=" + ((transitions0 != null) ? transitions0.length : 0) +
+                      ",offsets=" + ((offsets0 != null) ? offsets0.length : 0) +
+                      ",checksum=" + checksum0 +
+                      ",gmtChanged=" + willGMTOffsetChange0 +
+                      "");
+        }
+        // offsets
+        if (!Arrays.equals(offsets, offsets0)) {
+            sb.append("\n    offset.len=" + ((offsets != null)? offsets.length : "null") +
+                      "    " + ((offsets0 != null)? offsets0.length : "null"));
+            if (offsets != null && offsets0.length != 0) {
+                int len = Math.min(offsets.length, offsets0.length);
+                int i = 0;
+                for (i = 0; i < len; i++) {
+                    sb.append("\n        " +
+                              ZoneOffset.ofTotalSeconds(offsets[i]/1000) + "    " +
+                              ZoneOffset.ofTotalSeconds(offsets0[i]/1000));
+                }
+                for (; i < offsets0.length; i++) {
+                    sb.append("\n                  " + ZoneOffset.ofTotalSeconds(offsets0[i]/1000));
+                }
+            }
+        }
+        // trans
+        int offset = 0;
+        int offset0 = 0;
+        if (!equalsTransOffsets(other)) {
+            sb.append("\n    -------------");
+            if ((transitions == null) != (transitions0 == null)) {
+                sb.append("\n     (NG) Different trans(null) :" +
+                transitions + ", " + transitions0);
+                if (transitions != null) {
+                    for (int i = 0; i < transitions.length; i++) {
+                        sb.append("\n    (NG)");
+                        offset = transToString(transitions[i], offset, offsets, sb);
+                    }
+                }
+            } else {
+                if (transitions.length != transitions0.length) {
+                    sb.append("\n    (NG) Different trans size :" +
+                              transitions.length + ", " + transitions0.length);
+                }
+                int length = Math.min(transitions.length, transitions0.length);
+                for (int i = 0; i < length; i++) {
+                    // sb.append("\n[" + i + "]    ");
+                    // offset = transToString(transitions[i], offset, offsets, sb);
+                    long val = transitions[i];
+                    int dst = (int)((val >>> DST_NSHIFT) & 0xfL);
+                    int save = (dst == 0) ? 0 : offsets[dst] / 1000;
+                    int off = offsets[(int)(val & OFFSET_MASK)]/1000;
+                    long second = (val >> TRANSITION_NSHIFT)/1000;
+                    sb.append("\n        ");
+                    offset = transToString(transitions[i], offset, offsets, sb);
+                    if (transitions0 == null || i >= transitions0.length) {
+                        sb.append("\n    ");
+                        offset = transToString(transitions[i], offset, offsets, sb);
+                        sb.append("\n     (NG) trans0 is null or < trans.length");
+                    } else {
+                        long val0 = transitions0[i];
+                        int dst0 = (int)((val0 >>> DST_NSHIFT) & 0xfL);
+                        int save0 = (dst0 == 0) ? 0 : offsets0[dst0] / 1000;
+                        int off0 = offsets0[(int)(val0 & OFFSET_MASK)]/1000;
+                        long second0 = (val0 >> TRANSITION_NSHIFT)/1000;
+                        if (save != save0 || off != off0 || second != second0) {
+                            sb.append("\n    (NG)");
+                        } else {
+                            sb.append("\n    (OK)");
+                        }
+                        offset0 = transToString(transitions0[i], offset0, offsets0, sb);
+                        sb.append("\n            -----");
+                    }
+                }
+            }
+        }
+        SimpleTimeZone stz = getLastRuleInstance();
+        if (stz != null) {
+            SimpleTimeZone stz0 = other.getLastRule();
+            if (!stz.hasSameRules(stz0)) {
+                sb.append("\n    -------------")
+                  .append("\n    SimpleTimeZone (NG)")
+                  .append("\n       stz=" + stz)
+                  .append("\n      stz0=" + stz0);
+            }
+        }
+        sb.append("\n    -------------");
+        return sb.toString();
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/ZoneRec.java b/jdk/test/sun/util/calendar/zi/ZoneRec.java
new file mode 100644
index 0000000..e96346f
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/ZoneRec.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2000, 2004, 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * ZoneRec hold information of time zone corresponding to each text
+ * line of the "Zone" part.
+ *
+ * @since 1.4
+ */
+class ZoneRec {
+    private int gmtOffset;
+    private String ruleName;
+    private int directSave;
+    private Rule ruleRef;
+    private String format;
+    private boolean hasUntil;
+    private int untilYear;
+    private Month untilMonth;
+    private RuleDay untilDay;
+    private Time untilTime;
+    private long untilInMillis;
+    private String line;
+
+    /**
+     * @return the "UNTIL" value in milliseconds
+     */
+    Time getUntilTime() {
+        return untilTime;
+    }
+
+    /**
+     * @return the GMT offset value in milliseconds
+     */
+    int getGmtOffset() {
+        return gmtOffset;
+    }
+
+    /**
+     * @return the rule name to which this zone record refers
+     */
+    String getRuleName() {
+        return ruleName;
+    }
+
+    /**
+     * @return the amount of saving time directly defined in the
+     * "RULES/SAVE" field.
+     */
+    int getDirectSave() {
+        return directSave;
+    }
+
+    /**
+     * @return true if this zone record has a reference to a rule
+     */
+    boolean hasRuleReference() {
+        return ruleRef != null;
+    }
+
+    /**
+     * Returns the "FORMAT" field string of this zone record. This
+     * @return the "FORMAT" field
+     */
+    String getFormat() {
+        return format;
+    }
+
+    /**
+     * @return the year in the "UNTIL" field
+     */
+    int getUntilYear() {
+        return untilYear;
+    }
+
+    /**
+     * Returns the "UNTIL" field value in milliseconds from Janurary
+     * 1, 1970 0:00 GMT.
+     * @param currentSave the amount of daylight saving in
+     * milliseconds that is used to adjust wall-clock time.
+     * @return the milliseconds value of the "UNTIL" field
+     */
+    long getUntilTime(int currentSave) {
+        if (untilTime.isWall()) {
+            return untilInMillis - currentSave;
+        }
+        return untilInMillis;
+    }
+
+    /**
+     * Returns the "UNTIL" time in milliseconds without adjusting GMT
+     * offsets or daylight saving.
+     * @return local "UNTIL" time in milliseconds
+     */
+    long getLocalUntilTime() {
+        return Time.getLocalTime(untilYear,
+                                 untilMonth,
+                                 untilDay,
+                                 untilTime.getTime());
+    }
+
+    /**
+     * Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving.
+     * @return the "UNTIL" time after the adjustment
+     */
+    long getLocalUntilTime(int save, int gmtOffset) {
+        return Time.getLocalTime(untilYear,
+                                 untilMonth,
+                                 untilDay,
+                                 save,
+                                 gmtOffset,
+                                 untilTime);
+    }
+
+    /**
+     * @return the text line of this zone record
+     */
+    String getLine() {
+        return line;
+    }
+
+    /**
+     * Sets the specified text line to this zone record
+     */
+    void setLine(String line) {
+        this.line = line;
+    }
+
+    /**
+     * @return true if this zone record has the "UNTIL" field
+     */
+    boolean hasUntil() {
+        return this.hasUntil;
+    }
+
+    /**
+     * Adjusts the "UNTIL" time to GMT offset if this zone record has
+     * it.  <code>untilTime</code> is not adjusted to daylight saving
+     * in this method.
+     */
+    void adjustTime() {
+        if (!hasUntil()) {
+            return;
+        }
+        if (untilTime.isSTD() || untilTime.isWall()) {
+            // adjust to gmt offset only here.  adjust to real
+            // wall-clock time when tracking rules
+            untilInMillis -= gmtOffset;
+        }
+    }
+
+    /**
+     * @return the reference to the Rule object
+     */
+    Rule getRuleRef() {
+        return ruleRef;
+    }
+
+    /**
+     * Resolves the reference to a Rule and adjusts its "UNTIL" time
+     * to GMT offset.
+     */
+    void resolve(Zoneinfo zi) {
+        if (ruleName != null && (!"-".equals(ruleName))) {
+                ruleRef = zi.getRule(ruleName);
+        }
+        adjustTime();
+    }
+
+    /**
+     * Parses a Zone text line that is described by a StringTokenizer.
+     * @param tokens represents tokens of a Zone text line
+     * @return the zone record produced by parsing the text
+     */
+    static ZoneRec parse(StringTokenizer tokens) {
+        ZoneRec rec = new ZoneRec();
+        try {
+            rec.gmtOffset = (int) Time.parse(tokens.nextToken()).getTime();
+            String token = tokens.nextToken();
+            char c = token.charAt(0);
+            if (c >= '0' && c <= '9') {
+                rec.directSave = (int) Time.parse(token).getTime();
+            } else {
+                rec.ruleName = token;
+            }
+            rec.format = tokens.nextToken();
+            if (tokens.hasMoreTokens()) {
+                rec.hasUntil = true;
+                rec.untilYear = Integer.parseInt(tokens.nextToken());
+                if (tokens.hasMoreTokens()) {
+                    rec.untilMonth = Month.parse(tokens.nextToken());
+                } else {
+                    rec.untilMonth = Month.JANUARY;
+                }
+                if (tokens.hasMoreTokens()) {
+                    rec.untilDay = RuleDay.parse(tokens.nextToken());
+                } else {
+                    rec.untilDay = new RuleDay(1);
+                }
+                if (tokens.hasMoreTokens()) {
+                    rec.untilTime = Time.parse(tokens.nextToken());
+                } else {
+                    rec.untilTime = Time.parse("0:00");
+                }
+                rec.untilInMillis = rec.getLocalUntilTime();
+            }
+        } catch (Exception e) {
+            // TODO: error reporting
+            e.printStackTrace();
+        }
+        return rec;
+    }
+
+    private static void panic(String msg) {
+        Main.panic(msg);
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/Zoneinfo.java b/jdk/test/sun/util/calendar/zi/Zoneinfo.java
new file mode 100644
index 0000000..93242eb
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/Zoneinfo.java
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) 2000, 2011, 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * Zoneinfo provides javazic compiler front-end functionality.
+ * @since 1.4
+ */
+class Zoneinfo {
+
+    private static final int minYear = 1900;
+    private static final int maxYear = 2037;
+    private static final long minTime = Time.getLocalTime(minYear, Month.JANUARY, 1, 0);
+    private static int startYear = minYear;
+    private static int endYear = maxYear;
+
+    /**
+     * True if javazic should generate a list of SimpleTimeZone
+     * instances for the SimpleTimeZone-based time zone support.
+     */
+    static boolean isYearForTimeZoneDataSpecified = false;
+
+    /**
+     * Zone name to Zone mappings
+     */
+    private Map<String,Zone> zones;
+
+    /**
+     * Rule name to Rule mappings
+     */
+    private Map<String,Rule> rules;
+
+    /**
+     * Alias name to real name mappings
+     */
+    private Map<String,String> aliases;
+
+    /**
+     * Constracts a Zoneinfo.
+     */
+    Zoneinfo() {
+        zones = new HashMap<String,Zone>();
+        rules = new HashMap<String,Rule>();
+        aliases = new HashMap<String,String>();
+    }
+
+    /**
+     * Adds the given zone to the list of Zones.
+     * @param zone Zone to be added to the list.
+     */
+    void add(Zone zone) {
+        String name = zone.getName();
+        zones.put(name, zone);
+    }
+
+    /**
+     * Adds the given rule to the list of Rules.
+     * @param rule Rule to be added to the list.
+     */
+    void add(Rule rule) {
+        String name = rule.getName();
+        rules.put(name, rule);
+    }
+
+    /**
+     * Puts the specifid name pair to the alias table.
+     * @param name1 an alias time zone name
+     * @param name2 the real time zone of the alias name
+     */
+    void putAlias(String name1, String name2) {
+        aliases.put(name1, name2);
+    }
+
+    /**
+     * Sets the given year for SimpleTimeZone list output.
+     * This method is called when the -S option is specified.
+     * @param year the year for which SimpleTimeZone list should be generated
+     */
+    static void setYear(int year) {
+        setStartYear(year);
+        setEndYear(year);
+        isYearForTimeZoneDataSpecified = true;
+    }
+
+    /**
+     * Sets the start year.
+     * @param year the start year value
+     * @throws IllegalArgumentException if the specified year value is
+     * smaller than the minimum year or greater than the end year.
+     */
+    static void setStartYear(int year) {
+        if (year < minYear || year > endYear) {
+            throw new IllegalArgumentException("invalid start year specified: " + year);
+        }
+        startYear = year;
+    }
+
+    /**
+     * @return the start year value
+     */
+    static int getStartYear() {
+        return startYear;
+    }
+
+    /**
+     * Sets the end year.
+     * @param year the end year value
+     * @throws IllegalArgumentException if the specified year value is
+     * smaller than the start year or greater than the maximum year.
+     */
+    static void setEndYear(int year) {
+        if (year < startYear || year > maxYear) {
+            throw new IllegalArgumentException();
+        }
+        endYear = year;
+    }
+
+    /**
+     * @return the end year value
+     */
+    static int getEndYear() {
+        return endYear;
+    }
+
+    /**
+     * @return the minimum year value
+     */
+    static int getMinYear() {
+        return minYear;
+    }
+
+    /**
+     * @return the maximum year value
+     */
+    static int getMaxYear() {
+        return maxYear;
+    }
+
+    /**
+     * @return the alias table
+     */
+    Map<String,String> getAliases() {
+        return aliases;
+    }
+
+    /**
+     * @return the Zone list
+     */
+    Map<String,Zone> getZones() {
+        return zones;
+    }
+
+    /**
+     * @return a Zone specified by name.
+     * @param name a zone name
+     */
+    Zone getZone(String name) {
+        return zones.get(name);
+    }
+
+    /**
+     * @return a Rule specified by name.
+     * @param name a rule name
+     */
+    Rule getRule(String name) {
+        return rules.get(name);
+    }
+
+    private static String line;
+
+    private static int lineNum;
+
+    /**
+     * Parses the specified time zone data file and creates a Zoneinfo
+     * that has all Rules, Zones and Links (aliases) information.
+     * @param fname the time zone data file name
+     * @return a Zoneinfo object
+     */
+    static Zoneinfo parse(String fname) {
+        BufferedReader in = null;
+        try {
+            FileReader fr = new FileReader(fname);
+            in = new BufferedReader(fr);
+        } catch (FileNotFoundException e) {
+            panic("can't open file: "+fname);
+        }
+        Zoneinfo zi = new Zoneinfo();
+        boolean continued = false;
+        Zone zone = null;
+        String l;
+        lineNum = 0;
+
+        try {
+            while ((line = in.readLine()) != null) {
+                lineNum++;
+                // skip blank and comment lines
+                if (line.length() == 0 || line.charAt(0) == '#') {
+                    continue;
+                }
+
+                // trim trailing comments
+                int rindex = line.lastIndexOf('#');
+                if (rindex != -1) {
+                    // take the data part of the line
+                    l = line.substring(0, rindex);
+                } else {
+                    l = line;
+                }
+
+                StringTokenizer tokens = new StringTokenizer(l);
+                if (!tokens.hasMoreTokens()) {
+                    continue;
+                }
+                String token = tokens.nextToken();
+
+                if (continued || "Zone".equals(token)) {
+                    if (zone == null) {
+                        if (!tokens.hasMoreTokens()) {
+                            panic("syntax error: zone no more token");
+                        }
+                        token = tokens.nextToken();
+                        // if the zone name is in "GMT+hh" or "GMT-hh"
+                        // format, ignore it due to spec conflict.
+                        if (token.startsWith("GMT+") || token.startsWith("GMT-")) {
+                            continue;
+                        }
+                        zone = new Zone(token);
+                    } else {
+                        // no way to push the current token back...
+                        tokens = new StringTokenizer(l);
+                    }
+
+                    ZoneRec zrec = ZoneRec.parse(tokens);
+                    zrec.setLine(line);
+                    zone.add(zrec);
+                    if ((continued = zrec.hasUntil()) == false) {
+                        if (Zone.isTargetZone(zone.getName())) {
+                            // zone.resolve(zi);
+                            zi.add(zone);
+                        }
+                        zone = null;
+                    }
+                } else if ("Rule".equals(token)) {
+                    if (!tokens.hasMoreTokens()) {
+                        panic("syntax error: rule no more token");
+                    }
+                    token = tokens.nextToken();
+                    Rule rule = zi.getRule(token);
+                    if (rule == null) {
+                        rule = new Rule(token);
+                        zi.add(rule);
+                    }
+                    RuleRec rrec = RuleRec.parse(tokens);
+                    rrec.setLine(line);
+                    rule.add(rrec);
+                } else if ("Link".equals(token)) {
+                    // Link <newname> <oldname>
+                    try {
+                        String name1 = tokens.nextToken();
+                        String name2 = tokens.nextToken();
+
+                        // if the zone name is in "GMT+hh" or "GMT-hh"
+                        // format, ignore it due to spec conflict with
+                        // custom time zones. Also, ignore "ROC" for
+                        // PC-ness.
+                        if (name2.startsWith("GMT+") || name2.startsWith("GMT-")
+                            || "ROC".equals(name2)) {
+                            continue;
+                        }
+                        zi.putAlias(name2, name1);
+                    } catch (Exception e) {
+                        panic("syntax error: no more token for Link");
+                    }
+                }
+            }
+            in.close();
+        } catch (IOException ex) {
+            panic("IO error: " + ex.getMessage());
+        }
+
+        return zi;
+    }
+
+    /**
+     * Interprets a zone and constructs a Timezone object that
+     * contains enough information on GMT offsets and DST schedules to
+     * generate a zone info database.
+     *
+     * @param zoneName the zone name for which a Timezone object is
+     * constructed.
+     *
+     * @return a Timezone object that contains all GMT offsets and DST
+     * rules information.
+     */
+    Timezone phase2(String zoneName) {
+        Timezone tz = new Timezone(zoneName);
+        Zone zone = getZone(zoneName);
+        zone.resolve(this);
+
+        // TODO: merge phase2's for the regular and SimpleTimeZone ones.
+        if (isYearForTimeZoneDataSpecified) {
+            ZoneRec zrec = zone.get(zone.size()-1);
+            tz.setLastZoneRec(zrec);
+            tz.setRawOffset(zrec.getGmtOffset());
+            if (zrec.hasRuleReference()) {
+                /*
+                 * This part assumes that the specified year is covered by
+                 * the rules referred to by the last zone record.
+                 */
+                List<RuleRec> rrecs = zrec.getRuleRef().getRules(startYear);
+
+                if (rrecs.size() == 2) {
+                    // make sure that one is a start rule and the other is
+                    // an end rule.
+                    RuleRec r0 = rrecs.get(0);
+                    RuleRec r1 = rrecs.get(1);
+                    if (r0.getSave() == 0 && r1.getSave() > 0) {
+                        rrecs.set(0, r1);
+                        rrecs.set(1, r0);
+                    } else if (!(r0.getSave() > 0 && r1.getSave() == 0)) {
+                        rrecs = null;
+                        Main.error(zoneName + ": rules for " +  startYear + " not found.");
+                    }
+                } else {
+                    rrecs = null;
+                }
+                if (rrecs != null) {
+                    tz.setLastRules(rrecs);
+                }
+            }
+            return tz;
+        }
+
+        int gmtOffset;
+        int year = minYear;
+        int fromYear = year;
+        long fromTime = Time.getLocalTime(startYear,
+                                          Month.JANUARY,
+                                          1, 0);
+
+        // take the index 0 for the GMT offset of the last zone record
+        ZoneRec zrec = zone.get(zone.size()-1);
+        tz.getOffsetIndex(zrec.getGmtOffset());
+
+        int currentSave = 0;
+        boolean usedZone;
+        for (int zindex = 0; zindex < zone.size(); zindex++) {
+            zrec = zone.get(zindex);
+            usedZone = false;
+            gmtOffset = zrec.getGmtOffset();
+            int stdOffset = zrec.getDirectSave();
+
+            // If this is the last zone record, take the last rule info.
+            if (!zrec.hasUntil()) {
+                tz.setRawOffset(gmtOffset, fromTime);
+                if (zrec.hasRuleReference()) {
+                    tz.setLastRules(zrec.getRuleRef().getLastRules());
+                } else if (stdOffset != 0) {
+                    // in case the last rule is all year round DST-only
+                    // (Asia/Amman once announced this rule.)
+                    tz.setLastDSTSaving(stdOffset);
+                }
+            }
+            if (!zrec.hasRuleReference()) {
+                if (!zrec.hasUntil() || zrec.getUntilTime(stdOffset) >= fromTime) {
+                    tz.addTransition(fromTime,
+                                     tz.getOffsetIndex(gmtOffset+stdOffset),
+                                     tz.getDstOffsetIndex(stdOffset));
+                    usedZone = true;
+                }
+                currentSave = stdOffset;
+                // optimization in case the last rule is fixed.
+                if (!zrec.hasUntil()) {
+                    if (tz.getNTransitions() > 0) {
+                        if (stdOffset == 0) {
+                            tz.setDSTType(Timezone.X_DST);
+                        } else {
+                            tz.setDSTType(Timezone.LAST_DST);
+                        }
+                        long time = Time.getLocalTime(maxYear,
+                                                      Month.JANUARY, 1, 0);
+                        time -= zrec.getGmtOffset();
+                        tz.addTransition(time,
+                                         tz.getOffsetIndex(gmtOffset+stdOffset),
+                                         tz.getDstOffsetIndex(stdOffset));
+                        tz.addUsedRec(zrec);
+                    } else {
+                        tz.setDSTType(Timezone.NO_DST);
+                    }
+                    break;
+                }
+            } else {
+                Rule rule = zrec.getRuleRef();
+                boolean fromTimeUsed = false;
+                currentSave = 0;
+            year_loop:
+                for (year = getMinYear(); year <= endYear; year++) {
+                    if (zrec.hasUntil() && year > zrec.getUntilYear()) {
+                        break;
+                    }
+                    List<RuleRec> rules = rule.getRules(year);
+                    if (rules.size() > 0) {
+                        for (int i = 0; i < rules.size(); i++) {
+                            RuleRec rrec = rules.get(i);
+                            long transition = rrec.getTransitionTime(year,
+                                                                     gmtOffset,
+                                                                     currentSave);
+                            if (zrec.hasUntil()) {
+                                if (transition >= zrec.getUntilTime(currentSave)) {
+                                    break year_loop;
+                                }
+                            }
+
+                            if (fromTimeUsed == false) {
+                                if (fromTime <= transition) {
+                                    fromTimeUsed = true;
+
+                                    if (fromTime != minTime) {
+                                        int prevsave;
+
+                                        ZoneRec prevzrec = zone.get(zindex - 1);
+
+                                        // See if until time in the previous
+                                        // ZoneRec is the same thing as the
+                                        // local time in the next rule.
+                                        // (examples are Asia/Ashkhabad in 1991,
+                                        // Europe/Riga in 1989)
+
+                                        if (i > 0) {
+                                            prevsave = rules.get(i-1).getSave();
+                                        } else {
+                                            List<RuleRec> prevrules = rule.getRules(year-1);
+
+                                            if (prevrules.size() > 0) {
+                                                prevsave = prevrules.get(prevrules.size()-1).getSave();
+                                            } else {
+                                                prevsave = 0;
+                                            }
+                                        }
+
+                                        if (rrec.isSameTransition(prevzrec, prevsave, gmtOffset)) {
+                                            currentSave = rrec.getSave();
+                                            tz.addTransition(fromTime,
+                                                         tz.getOffsetIndex(gmtOffset+currentSave),
+                                                         tz.getDstOffsetIndex(currentSave));
+                                            tz.addUsedRec(rrec);
+                                            usedZone = true;
+                                            continue;
+                                        }
+                                        if (!prevzrec.hasRuleReference()
+                                            || rule != prevzrec.getRuleRef()
+                                            || (rule == prevzrec.getRuleRef()
+                                                && gmtOffset != prevzrec.getGmtOffset())) {
+                                            int save = (fromTime == transition) ? rrec.getSave() : currentSave;
+                                            tz.addTransition(fromTime,
+                                                         tz.getOffsetIndex(gmtOffset+save),
+                                                         tz.getDstOffsetIndex(save));
+                                            tz.addUsedRec(rrec);
+                                            usedZone = true;
+                                        }
+                                    } else {  // fromTime == minTime
+                                        int save = rrec.getSave();
+                                        tz.addTransition(minTime,
+                                                         tz.getOffsetIndex(gmtOffset),
+                                                         tz.getDstOffsetIndex(0));
+
+                                        tz.addTransition(transition,
+                                                         tz.getOffsetIndex(gmtOffset+save),
+                                                         tz.getDstOffsetIndex(save));
+
+                                        tz.addUsedRec(rrec);
+                                        usedZone = true;
+                                    }
+                                } else if (year == fromYear && i == rules.size()-1) {
+                                    int save = rrec.getSave();
+                                    tz.addTransition(fromTime,
+                                                     tz.getOffsetIndex(gmtOffset+save),
+                                                     tz.getDstOffsetIndex(save));
+                                }
+                            }
+
+                            currentSave = rrec.getSave();
+                            if (fromTime < transition) {
+                                tz.addTransition(transition,
+                                                 tz.getOffsetIndex(gmtOffset+currentSave),
+                                                 tz.getDstOffsetIndex(currentSave));
+                                tz.addUsedRec(rrec);
+                                usedZone = true;
+                            }
+                        }
+                    } else {
+                        if (year == fromYear) {
+                            tz.addTransition(fromTime,
+                                             tz.getOffsetIndex(gmtOffset+currentSave),
+                                             tz.getDstOffsetIndex(currentSave));
+                            fromTimeUsed = true;
+                        }
+                        if (year == endYear && !zrec.hasUntil()) {
+                            if (tz.getNTransitions() > 0) {
+                                // Assume that this Zone stopped DST
+                                tz.setDSTType(Timezone.X_DST);
+                                long time = Time.getLocalTime(maxYear, Month.JANUARY,
+                                                              1, 0);
+                                time -= zrec.getGmtOffset();
+                                tz.addTransition(time,
+                                                 tz.getOffsetIndex(gmtOffset),
+                                                 tz.getDstOffsetIndex(0));
+                                usedZone = true;
+                            } else {
+                                tz.setDSTType(Timezone.NO_DST);
+                            }
+                        }
+                    }
+                }
+            }
+            if (usedZone) {
+                tz.addUsedRec(zrec);
+            }
+            if (zrec.hasUntil() && zrec.getUntilTime(currentSave) > fromTime) {
+                fromTime = zrec.getUntilTime(currentSave);
+                fromYear = zrec.getUntilYear();
+                year = zrec.getUntilYear();
+            }
+        }
+
+        if (tz.getDSTType() == Timezone.UNDEF_DST) {
+            tz.setDSTType(Timezone.DST);
+        }
+        tz.optimize();
+        tz.checksum();
+        return tz;
+    }
+
+    private static void panic(String msg) {
+        Main.panic(msg);
+    }
+}
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/VERSION b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
new file mode 100644
index 0000000..85db871
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+tzdata2012i
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/africa b/jdk/test/sun/util/calendar/zi/tzdata/africa
new file mode 100644
index 0000000..7db9b3d
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/africa
@@ -0,0 +1,1186 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+#
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
+# I found in the UCLA library.
+#
+# A reliable and entertaining source about time zones is
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+#
+# Previous editions of this database used WAT, CAT, SAT, and EAT
+# for +0:00 through +3:00, respectively,
+# but Mark R V Murray reports that
+# `SAST' is the official abbreviation for +2:00 in the country of South Africa,
+# `CAT' is commonly used for +2:00 in countries north of South Africa, and
+# `WAT' is probably the best name for +1:00, as the common phrase for
+# the area that includes Nigeria is ``West Africa''.
+# He has heard of ``Western Sahara Time'' for +0:00 but can find no reference.
+#
+# To make things confusing, `WAT' seems to have been used for -1:00 long ago;
+# I'd guess that this was because people needed _some_ name for -1:00,
+# and at the time, far west Africa was the only major land area in -1:00.
+# This usage is now obsolete, as the last use of -1:00 on the African
+# mainland seems to have been 1976 in Western Sahara.
+#
+# To summarize, the following abbreviations seem to have some currency:
+#	-1:00	WAT	West Africa Time (no longer used)
+#	 0:00	GMT	Greenwich Mean Time
+#	 2:00	CAT	Central Africa Time
+#	 2:00	SAST	South Africa Standard Time
+# and Murray suggests the following abbreviation:
+#	 1:00	WAT	West Africa Time
+# I realize that this leads to `WAT' being used for both -1:00 and 1:00
+# for times before 1976, but this is the best I can think of
+# until we get more information.
+#
+# I invented the following abbreviations; corrections are welcome!
+#	 2:00	WAST	West Africa Summer Time
+#	 2:30	BEAT	British East Africa Time (no longer used)
+#	 2:45	BEAUT	British East Africa Unified Time (no longer used)
+#	 3:00	CAST	Central Africa Summer Time (no longer used)
+#	 3:00	SAST	South Africa Summer Time (no longer used)
+#	 3:00	EAT	East Africa Time
+#	 4:00	EAST	East Africa Summer Time (no longer used)
+
+# Algeria
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Algeria	1916	only	-	Jun	14	23:00s	1:00	S
+Rule	Algeria	1916	1919	-	Oct	Sun>=1	23:00s	0	-
+Rule	Algeria	1917	only	-	Mar	24	23:00s	1:00	S
+Rule	Algeria	1918	only	-	Mar	 9	23:00s	1:00	S
+Rule	Algeria	1919	only	-	Mar	 1	23:00s	1:00	S
+Rule	Algeria	1920	only	-	Feb	14	23:00s	1:00	S
+Rule	Algeria	1920	only	-	Oct	23	23:00s	0	-
+Rule	Algeria	1921	only	-	Mar	14	23:00s	1:00	S
+Rule	Algeria	1921	only	-	Jun	21	23:00s	0	-
+Rule	Algeria	1939	only	-	Sep	11	23:00s	1:00	S
+Rule	Algeria	1939	only	-	Nov	19	 1:00	0	-
+Rule	Algeria	1944	1945	-	Apr	Mon>=1	 2:00	1:00	S
+Rule	Algeria	1944	only	-	Oct	 8	 2:00	0	-
+Rule	Algeria	1945	only	-	Sep	16	 1:00	0	-
+Rule	Algeria	1971	only	-	Apr	25	23:00s	1:00	S
+Rule	Algeria	1971	only	-	Sep	26	23:00s	0	-
+Rule	Algeria	1977	only	-	May	 6	 0:00	1:00	S
+Rule	Algeria	1977	only	-	Oct	21	 0:00	0	-
+Rule	Algeria	1978	only	-	Mar	24	 1:00	1:00	S
+Rule	Algeria	1978	only	-	Sep	22	 3:00	0	-
+Rule	Algeria	1980	only	-	Apr	25	 0:00	1:00	S
+Rule	Algeria	1980	only	-	Oct	31	 2:00	0	-
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
+# more precise 0:09:21.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Algiers	0:12:12 -	LMT	1891 Mar 15 0:01
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
+			0:00	Algeria	WE%sT	1940 Feb 25 2:00
+			1:00	Algeria	CE%sT	1946 Oct  7
+			0:00	-	WET	1956 Jan 29
+			1:00	-	CET	1963 Apr 14
+			0:00	Algeria	WE%sT	1977 Oct 21
+			1:00	Algeria	CE%sT	1979 Oct 26
+			0:00	Algeria	WE%sT	1981 May
+			1:00	-	CET
+
+# Angola
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Luanda	0:52:56	-	LMT	1892
+			0:52:04	-	AOT	1911 May 26 # Angola Time
+			1:00	-	WAT
+
+# Benin
+# Whitman says they switched to 1:00 in 1946, not 1934;
+# go with Shanks & Pottenger.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Porto-Novo	0:10:28	-	LMT	1912
+			0:00	-	GMT	1934 Feb 26
+			1:00	-	WAT
+
+# Botswana
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Gaborone	1:43:40 -	LMT	1885
+			2:00	-	CAT	1943 Sep 19 2:00
+			2:00	1:00	CAST	1944 Mar 19 2:00
+			2:00	-	CAT
+
+# Burkina Faso
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Ouagadougou	-0:06:04 -	LMT	1912
+			 0:00	-	GMT
+
+# Burundi
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Bujumbura	1:57:28	-	LMT	1890
+			2:00	-	CAT
+
+# Cameroon
+# Whitman says they switched to 1:00 in 1920; go with Shanks & Pottenger.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Douala	0:38:48	-	LMT	1912
+			1:00	-	WAT
+
+# Cape Verde
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/Cape_Verde -1:34:04 -	LMT	1907			# Praia
+			-2:00	-	CVT	1942 Sep
+			-2:00	1:00	CVST	1945 Oct 15
+			-2:00	-	CVT	1975 Nov 25 2:00
+			-1:00	-	CVT
+
+# Central African Republic
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Bangui	1:14:20	-	LMT	1912
+			1:00	-	WAT
+
+# Chad
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Ndjamena	1:00:12 -	LMT	1912
+			1:00	-	WAT	1979 Oct 14
+			1:00	1:00	WAST	1980 Mar  8
+			1:00	-	WAT
+
+# Comoros
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Comoro	2:53:04 -	LMT	1911 Jul   # Moroni, Gran Comoro
+			3:00	-	EAT
+
+# Democratic Republic of Congo
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Kinshasa	1:01:12 -	LMT	1897 Nov 9
+			1:00	-	WAT
+Zone Africa/Lubumbashi	1:49:52 -	LMT	1897 Nov 9
+			2:00	-	CAT
+
+# Republic of the Congo
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Brazzaville	1:01:08 -	LMT	1912
+			1:00	-	WAT
+
+# Cote D'Ivoire
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Abidjan	-0:16:08 -	LMT	1912
+			 0:00	-	GMT
+
+# Djibouti
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Djibouti	2:52:36 -	LMT	1911 Jul
+			3:00	-	EAT
+
+###############################################################################
+
+# Egypt
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Egypt	1940	only	-	Jul	15	0:00	1:00	S
+Rule	Egypt	1940	only	-	Oct	 1	0:00	0	-
+Rule	Egypt	1941	only	-	Apr	15	0:00	1:00	S
+Rule	Egypt	1941	only	-	Sep	16	0:00	0	-
+Rule	Egypt	1942	1944	-	Apr	 1	0:00	1:00	S
+Rule	Egypt	1942	only	-	Oct	27	0:00	0	-
+Rule	Egypt	1943	1945	-	Nov	 1	0:00	0	-
+Rule	Egypt	1945	only	-	Apr	16	0:00	1:00	S
+Rule	Egypt	1957	only	-	May	10	0:00	1:00	S
+Rule	Egypt	1957	1958	-	Oct	 1	0:00	0	-
+Rule	Egypt	1958	only	-	May	 1	0:00	1:00	S
+Rule	Egypt	1959	1981	-	May	 1	1:00	1:00	S
+Rule	Egypt	1959	1965	-	Sep	30	3:00	0	-
+Rule	Egypt	1966	1994	-	Oct	 1	3:00	0	-
+Rule	Egypt	1982	only	-	Jul	25	1:00	1:00	S
+Rule	Egypt	1983	only	-	Jul	12	1:00	1:00	S
+Rule	Egypt	1984	1988	-	May	 1	1:00	1:00	S
+Rule	Egypt	1989	only	-	May	 6	1:00	1:00	S
+Rule	Egypt	1990	1994	-	May	 1	1:00	1:00	S
+# IATA (after 1990) says transitions are at 0:00.
+# Go with IATA starting in 1995, except correct 1995 entry from 09-30 to 09-29.
+
+# From Alexander Krivenyshev (2011-04-20):
+# "...Egypt's interim cabinet decided on Wednesday to cancel daylight
+# saving time after a poll posted on its website showed the majority of
+# Egyptians would approve the cancellation."
+#
+# Egypt to cancel daylight saving time
+# <a href="http://www.almasryalyoum.com/en/node/407168">
+# http://www.almasryalyoum.com/en/node/407168
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_egypt04.html">
+# http://www.worldtimezone.com/dst_news/dst_news_egypt04.html
+# </a>
+Rule	Egypt	1995	2010	-	Apr	lastFri	 0:00s	1:00	S
+Rule	Egypt	1995	2005	-	Sep	lastThu	23:00s	0	-
+# From Steffen Thorsen (2006-09-19):
+# The Egyptian Gazette, issue 41,090 (2006-09-18), page 1, reports:
+# Egypt will turn back clocks by one hour at the midnight of Thursday
+# after observing the daylight saving time since May.
+# http://news.gom.com.eg/gazette/pdf/2006/09/18/01.pdf
+Rule	Egypt	2006	only	-	Sep	21	23:00s	0	-
+# From Dirk Losch (2007-08-14):
+# I received a mail from an airline which says that the daylight
+# saving time in Egypt will end in the night of 2007-09-06 to 2007-09-07.
+# From Jesper Norgaard Welen (2007-08-15): [The following agree:]
+# http://www.nentjes.info/Bill/bill5.htm
+# http://www.timeanddate.com/worldclock/city.html?n=53
+# From Steffen Thorsen (2007-09-04): The official information...:
+# http://www.sis.gov.eg/En/EgyptOnline/Miscellaneous/000002/0207000000000000001580.htm
+Rule	Egypt	2007	only	-	Sep	Thu>=1	23:00s	0	-
+# From Abdelrahman Hassan (2007-09-06):
+# Due to the Hijri (lunar Islamic calendar) year being 11 days shorter
+# than the year of the Gregorian calendar, Ramadan shifts earlier each
+# year. This year it will be observed September 13 (September is quite
+# hot in Egypt), and the idea is to make fasting easier for workers by
+# shifting business hours one hour out of daytime heat. Consequently,
+# unless discontinued, next DST may end Thursday 28 August 2008.
+# From Paul Eggert (2007-08-17):
+# For lack of better info, assume the new rule is last Thursday in August.
+
+# From Petr Machata (2009-04-06):
+# The following appeared in Red Hat bugzilla[1] (edited):
+#
+# > $ zdump -v /usr/share/zoneinfo/Africa/Cairo | grep 2009
+# > /usr/share/zoneinfo/Africa/Cairo  Thu Apr 23 21:59:59 2009 UTC = Thu =
+# Apr 23
+# > 23:59:59 2009 EET isdst=0 gmtoff=7200
+# > /usr/share/zoneinfo/Africa/Cairo  Thu Apr 23 22:00:00 2009 UTC = Fri =
+# Apr 24
+# > 01:00:00 2009 EEST isdst=1 gmtoff=10800
+# > /usr/share/zoneinfo/Africa/Cairo  Thu Aug 27 20:59:59 2009 UTC = Thu =
+# Aug 27
+# > 23:59:59 2009 EEST isdst=1 gmtoff=10800
+# > /usr/share/zoneinfo/Africa/Cairo  Thu Aug 27 21:00:00 2009 UTC = Thu =
+# Aug 27
+# > 23:00:00 2009 EET isdst=0 gmtoff=7200
+#
+# > end date should be Thu Sep 24 2009 (Last Thursday in September at 23:59=
+# :59)
+# > http://support.microsoft.com/kb/958729/
+#
+# timeanddate[2] and another site I've found[3] also support that.
+#
+# [1] <a href="https://bugzilla.redhat.com/show_bug.cgi?id=492263">
+# https://bugzilla.redhat.com/show_bug.cgi?id=492263
+# </a>
+# [2] <a href="http://www.timeanddate.com/worldclock/clockchange.html?n=53">
+# http://www.timeanddate.com/worldclock/clockchange.html?n=53
+# </a>
+# [3] <a href="http://wwp.greenwichmeantime.com/time-zone/africa/egypt/">
+# http://wwp.greenwichmeantime.com/time-zone/africa/egypt/
+# </a>
+
+# From Arthur David Olson (2009-04-20):
+# In 2009 (and for the next several years), Ramadan ends before the fourth
+# Thursday in September; Egypt is expected to revert to the last Thursday
+# in September.
+
+# From Steffen Thorsen (2009-08-11):
+# We have been able to confirm the August change with the Egyptian Cabinet
+# Information and Decision Support Center:
+# <a href="http://www.timeanddate.com/news/time/egypt-dst-ends-2009.html">
+# http://www.timeanddate.com/news/time/egypt-dst-ends-2009.html
+# </a>
+#
+# The Middle East News Agency
+# <a href="http://www.mena.org.eg/index.aspx">
+# http://www.mena.org.eg/index.aspx
+# </a>
+# also reports "Egypt starts winter time on August 21"
+# today in article numbered "71, 11/08/2009 12:25 GMT."
+# Only the title above is available without a subscription to their service,
+# and can be found by searching for "winter" in their search engine
+# (at least today).
+
+# From Alexander Krivenyshev (2010-07-20):
+# According to News from Egypt -  Al-Masry Al-Youm Egypt's cabinet has
+# decided that Daylight Saving Time will not be used in Egypt during
+# Ramadan.
+#
+# Arabic translation:
+# "Clocks to go back during Ramadan--and then forward again"
+# <a href="http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again">
+# http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_egypt02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_egypt02.html
+# </a>
+
+Rule	Egypt	2008	only	-	Aug	lastThu	23:00s	0	-
+Rule	Egypt	2009	only	-	Aug	20	23:00s	0	-
+Rule	Egypt	2010	only	-	Aug	11	0:00	0	-
+Rule	Egypt	2010	only	-	Sep	10	0:00	1:00	S
+Rule	Egypt	2010	only	-	Sep	lastThu	23:00s	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
+			2:00	Egypt	EE%sT
+
+# Equatorial Guinea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Malabo	0:35:08 -	LMT	1912
+			0:00	-	GMT	1963 Dec 15
+			1:00	-	WAT
+
+# Eritrea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Asmara	2:35:32 -	LMT	1870
+			2:35:32	-	AMT	1890	      # Asmara Mean Time
+			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
+			3:00	-	EAT
+
+# Ethiopia
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that Ethiopia had six narrowly-spaced time zones
+# between 1870 and 1890, and that they merged to 38E50 (2:35:20) in 1890.
+# We'll guess that 38E50 is for Adis Dera.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Addis_Ababa	2:34:48 -	LMT	1870
+			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
+			3:00	-	EAT
+
+# Gabon
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Libreville	0:37:48 -	LMT	1912
+			1:00	-	WAT
+
+# Gambia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Banjul	-1:06:36 -	LMT	1912
+			-1:06:36 -	BMT	1935	# Banjul Mean Time
+			-1:00	-	WAT	1964
+			 0:00	-	GMT
+
+# Ghana
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Whitman says DST was observed from 1931 to ``the present'';
+# go with Shanks & Pottenger.
+Rule	Ghana	1936	1942	-	Sep	 1	0:00	0:20	GHST
+Rule	Ghana	1936	1942	-	Dec	31	0:00	0	GMT
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Accra	-0:00:52 -	LMT	1918
+			 0:00	Ghana	%s
+
+# Guinea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Conakry	-0:54:52 -	LMT	1912
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960
+			 0:00	-	GMT
+
+# Guinea-Bissau
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Bissau	-1:02:20 -	LMT	1911 May 26
+			-1:00	-	WAT	1975
+			 0:00	-	GMT
+
+# Kenya
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Nairobi	2:27:16	-	LMT	1928 Jul
+			3:00	-	EAT	1930
+			2:30	-	BEAT	1940
+			2:45	-	BEAUT	1960
+			3:00	-	EAT
+
+# Lesotho
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Maseru	1:50:00 -	LMT	1903 Mar
+			2:00	-	SAST	1943 Sep 19 2:00
+			2:00	1:00	SAST	1944 Mar 19 2:00
+			2:00	-	SAST
+
+# Liberia
+# From Paul Eggert (2006-03-22):
+# In 1972 Liberia was the last country to switch
+# from a UTC offset that was not a multiple of 15 or 20 minutes.
+# Howse reports that it was in honor of their president's birthday.
+# Shank & Pottenger report the date as May 1, whereas Howse reports Jan;
+# go with Shanks & Pottenger.
+# For Liberia before 1972, Shanks & Pottenger report -0:44, whereas Howse and
+# Whitman each report -0:44:30; go with the more precise figure.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Monrovia	-0:43:08 -	LMT	1882
+			-0:43:08 -	MMT	1919 Mar # Monrovia Mean Time
+			-0:44:30 -	LRT	1972 May # Liberia Time
+			 0:00	-	GMT
+
+###############################################################################
+
+# Libya
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
+Rule	Libya	1952	only	-	Jan	 1	0:00	0	-
+Rule	Libya	1953	only	-	Oct	 9	2:00	1:00	S
+Rule	Libya	1954	only	-	Jan	 1	0:00	0	-
+Rule	Libya	1955	only	-	Sep	30	0:00	1:00	S
+Rule	Libya	1956	only	-	Jan	 1	0:00	0	-
+Rule	Libya	1982	1984	-	Apr	 1	0:00	1:00	S
+Rule	Libya	1982	1985	-	Oct	 1	0:00	0	-
+Rule	Libya	1985	only	-	Apr	 6	0:00	1:00	S
+Rule	Libya	1986	only	-	Apr	 4	0:00	1:00	S
+Rule	Libya	1986	only	-	Oct	 3	0:00	0	-
+Rule	Libya	1987	1989	-	Apr	 1	0:00	1:00	S
+Rule	Libya	1987	1989	-	Oct	 1	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Tripoli	0:52:44 -	LMT	1920
+			1:00	Libya	CE%sT	1959
+			2:00	-	EET	1982
+			1:00	Libya	CE%sT	1990 May  4
+# The following entries are from Shanks & Pottenger;
+# the IATA SSIM data contain some obvious errors.
+			2:00	-	EET	1996 Sep 30
+			1:00	-	CET	1997 Apr  4
+			1:00	1:00	CEST	1997 Oct  4
+			2:00	-	EET
+
+# Madagascar
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Antananarivo 3:10:04 -	LMT	1911 Jul
+			3:00	-	EAT	1954 Feb 27 23:00s
+			3:00	1:00	EAST	1954 May 29 23:00s
+			3:00	-	EAT
+
+# Malawi
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Blantyre	2:20:00 -	LMT	1903 Mar
+			2:00	-	CAT
+
+# Mali
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Bamako	-0:32:00 -	LMT	1912
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960 Jun 20
+			 0:00	-	GMT
+
+# Mauritania
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Nouakchott	-1:03:48 -	LMT	1912
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960 Nov 28
+			 0:00	-	GMT
+
+# Mauritius
+
+# From Steffen Thorsen (2008-06-25):
+# Mauritius plans to observe DST from 2008-11-01 to 2009-03-31 on a trial
+# basis....
+# It seems that Mauritius observed daylight saving time from 1982-10-10 to
+# 1983-03-20 as well, but that was not successful....
+# http://www.timeanddate.com/news/time/mauritius-daylight-saving-time.html
+
+# From Alex Krivenyshev (2008-06-25):
+# http://economicdevelopment.gov.mu/portal/site/Mainhomepage/menuitem.a42b24128104d9845dabddd154508a0c/?content_id=0a7cee8b5d69a110VgnVCM1000000a04a8c0RCRD
+
+# From Arthur David Olson (2008-06-30):
+# The www.timeanddate.com article cited by Steffen Thorsen notes that "A
+# final decision has yet to be made on the times that daylight saving
+# would begin and end on these dates." As a place holder, use midnight.
+
+# From Paul Eggert (2008-06-30):
+# Follow Thorsen on DST in 1982/1983, instead of Shanks & Pottenger.
+
+# From Steffen Thorsen (2008-07-10):
+# According to
+# <a href="http://www.lexpress.mu/display_article.php?news_id=111216">
+# http://www.lexpress.mu/display_article.php?news_id=111216
+# </a>
+# (in French), Mauritius will start and end their DST a few days earlier
+# than previously announced (2008-11-01 to 2009-03-31).  The new start
+# date is 2008-10-26 at 02:00 and the new end date is 2009-03-27 (no time
+# given, but it is probably at either 2 or 3 wall clock time).
+#
+# A little strange though, since the article says that they moved the date
+# to align itself with Europe and USA which also change time on that date,
+# but that means they have not paid attention to what happened in
+# USA/Canada last year (DST ends first Sunday in November). I also wonder
+# why that they end on a Friday, instead of aligning with Europe which
+# changes two days later.
+
+# From Alex Krivenyshev (2008-07-11):
+# Seems that English language article "The revival of daylight saving
+# time:  Energy conservation?"-# No. 16578 (07/11/2008) was originally
+# published on Monday, June 30, 2008...
+#
+# I guess that article in French "Le gouvernement avance l'introduction
+# de l'heure d'ete" stating that DST in Mauritius starting on October 26
+# and ending on March 27, 2009 is the most recent one.
+# ...
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html
+# </a>
+
+# From Riad M. Hossen Ally (2008-08-03):
+# The Government of Mauritius weblink
+# <a href="http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD">
+# http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD
+# </a>
+# Cabinet Decision of July 18th, 2008 states as follows:
+#
+# 4. ...Cabinet has agreed to the introduction into the National Assembly
+# of the Time Bill which provides for the introduction of summer time in
+# Mauritius. The summer time period which will be of one hour ahead of
+# the standard time, will be aligned with that in Europe and the United
+# States of America. It will start at two o'clock in the morning on the
+# last Sunday of October and will end at two o'clock in the morning on
+# the last Sunday of March the following year. The summer time for the
+# year 2008 - 2009 will, therefore, be effective as from 26 October 2008
+# and end on 29 March 2009.
+
+# From Ed Maste (2008-10-07):
+# THE TIME BILL (No. XXVII of 2008) Explanatory Memorandum states the
+# beginning / ending of summer time is 2 o'clock standard time in the
+# morning of the last Sunday of October / last Sunday of March.
+# <a href="http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf">
+# http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf
+# </a>
+
+# From Steffen Thorsen (2009-06-05):
+# According to several sources, Mauritius will not continue to observe
+# DST the coming summer...
+#
+# Some sources, in French:
+# <a href="http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB">
+# http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB
+# </a>
+# <a href="http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints-">
+# http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints-
+# </a>
+#
+# Our wrap-up:
+# <a href="http://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html">
+# http://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html
+# </a>
+
+# From Arthur David Olson (2009-07-11):
+# The "mauritius-dst-will-not-repeat" wrapup includes this:
+# "The trial ended on March 29, 2009, when the clocks moved back by one hour
+# at 2am (or 02:00) local time..."
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule Mauritius	1982	only	-	Oct	10	0:00	1:00	S
+Rule Mauritius	1983	only	-	Mar	21	0:00	0	-
+Rule Mauritius	2008	only	-	Oct	lastSun	2:00	1:00	S
+Rule Mauritius	2009	only	-	Mar	lastSun	2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Mauritius	3:50:00 -	LMT	1907		# Port Louis
+			4:00 Mauritius	MU%sT	# Mauritius Time
+# Agalega Is, Rodriguez
+# no information; probably like Indian/Mauritius
+
+# Mayotte
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Mayotte	3:00:56 -	LMT	1911 Jul	# Mamoutzou
+			3:00	-	EAT
+
+# Morocco
+# See the `europe' file for Spanish Morocco (Africa/Ceuta).
+
+# From Alex Krivenyshev (2008-05-09):
+# Here is an article that Morocco plan to introduce Daylight Saving Time between
+# 1 June, 2008 and 27 September, 2008.
+#
+# "... Morocco is to save energy by adjusting its clock during summer so it will
+# be one hour ahead of GMT between 1 June and 27 September, according to
+# Communication Minister and Gov ernment Spokesman, Khalid Naciri...."
+#
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_morocco01.html">
+# http://www.worldtimezone.net/dst_news/dst_news_morocco01.html
+# </a>
+# OR
+# <a href="http://en.afrik.com/news11892.html">
+# http://en.afrik.com/news11892.html
+# </a>
+
+# From Alex Krivenyshev (2008-05-09):
+# The Morocco time change can be confirmed on Morocco web site Maghreb Arabe Presse:
+# <a href="http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view">
+# http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view
+# </a>
+#
+# Morocco shifts to daylight time on June 1st through September 27, Govt.
+# spokesman.
+
+# From Patrice Scattolin (2008-05-09):
+# According to this article:
+# <a href="http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html">
+# http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html
+# </a>
+# (and republished here:
+# <a href="http://www.actu.ma/heure-dete-comment_i127896_0.html">
+# http://www.actu.ma/heure-dete-comment_i127896_0.html
+# </a>
+# )
+# the changes occurs at midnight:
+#
+# saturday night may 31st at midnight (which in french is to be
+# intrepreted as the night between saturday and sunday)
+# sunday night the 28th  at midnight
+#
+# Seeing that the 28th is monday, I am guessing that she intends to say
+# the midnight of the 28th which is the midnight between sunday and
+# monday, which jives with other sources that say that it's inclusive
+# june1st to sept 27th.
+#
+# The decision was taken by decree *2-08-224 *but I can't find the decree
+# published on the web.
+#
+# It's also confirmed here:
+# <a href="http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm">
+# http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm
+# </a>
+# on a government portal as being  between june 1st and sept 27th (not yet
+# posted in english).
+#
+# The following google query will generate many relevant hits:
+# <a href="http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search">
+# http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search
+# </a>
+
+# From Alex Krivenyshev (2008-05-09):
+# Is Western Sahara (part which administrated by Morocco) going to follow
+# Morocco DST changes?  Any information?  What about other part of
+# Western Sahara - under administration of POLISARIO Front (also named
+# SADR Saharawi Arab Democratic Republic)?
+
+# From Arthur David Olson (2008-05-09):
+# XXX--guess that it is only Morocco for now; guess only 2008 for now.
+
+# From Steffen Thorsen (2008-08-27):
+# Morocco will change the clocks back on the midnight between August 31
+# and September 1. They originally planned to observe DST to near the end
+# of September:
+#
+# One article about it (in French):
+# <a href="http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default">
+# http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default
+# </a>
+#
+# We have some further details posted here:
+# <a href="http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html">
+# http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html
+# </a>
+
+# From Steffen Thorsen (2009-03-17):
+# Morocco will observe DST from 2009-06-01 00:00 to 2009-08-21 00:00 according
+# to many sources, such as
+# <a href="http://news.marweb.com/morocco/entertainment/morocco-daylight-saving.html">
+# http://news.marweb.com/morocco/entertainment/morocco-daylight-saving.html
+# </a>
+# <a href="http://www.medi1sat.ma/fr/depeche.aspx?idp=2312">
+# http://www.medi1sat.ma/fr/depeche.aspx?idp=2312
+# </a>
+# (French)
+#
+# Our summary:
+# <a href="http://www.timeanddate.com/news/time/morocco-starts-dst-2009.html">
+# http://www.timeanddate.com/news/time/morocco-starts-dst-2009.html
+# </a>
+
+# From Alexander Krivenyshev (2009-03-17):
+# Here is a link to official document from Royaume du Maroc Premier Ministre,
+# Ministere de la Modernisation des Secteurs Publics
+#
+# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 june 1967)
+# concerning the amendment of the legal time, the Ministry of Modernization of
+# Public Sectors announced that the official time in the Kingdom will be
+# advanced 60 minutes from Sunday 31 May 2009 at midnight.
+#
+# <a href="http://www.mmsp.gov.ma/francais/Actualites_fr/PDF_Actualites_Fr/HeureEte_FR.pdf">
+# http://www.mmsp.gov.ma/francais/Actualites_fr/PDF_Actualites_Fr/HeureEte_FR.pdf
+# </a>
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_morocco03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_morocco03.html
+# </a>
+
+# From Steffen Thorsen (2010-04-13):
+# Several news media in Morocco report that the Ministry of Modernization
+# of Public Sectors has announced that Morocco will have DST from
+# 2010-05-02 to 2010-08-08.
+#
+# Example:
+# <a href="http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html">
+# http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html
+# </a>
+# (French)
+# Our page:
+# <a href="http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html">
+# http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html
+# </a>
+
+# From Dan Abitol (2011-03-30):
+# ...Rules for Africa/Casablanca are the following (24h format)
+# The 3rd april 2011 at 00:00:00, [it] will be 3rd april 1:00:00
+# The 31th july 2011 at 00:59:59,  [it] will be 31th July 00:00:00
+# ...Official links of change in morocco
+# The change was broadcast on the FM Radio
+# I ve called ANRT (telecom regulations in Morocco) at
+# +212.537.71.84.00
+# <a href="http://www.anrt.net.ma/fr/">
+# http://www.anrt.net.ma/fr/
+# </a>
+# They said that
+# <a href="http://www.map.ma/fr/sections/accueil/l_heure_legale_au_ma/view">
+# http://www.map.ma/fr/sections/accueil/l_heure_legale_au_ma/view
+# </a>
+# is the official publication to look at.
+# They said that the decision was already taken.
+#
+# More articles in the press
+# <a href="http://www.yabiladi.com/articles/details/5058/secret-l-heure-d-ete-maroc-lev">
+# http://www.yabiladi.com/articles/details/5058/secret-l-heure-d-ete-maroc-lev
+# </a>
+# e.html
+# <a href="http://www.lematin.ma/Actualite/Express/Article.asp?id=148923">
+# http://www.lematin.ma/Actualite/Express/Article.asp?id=148923
+# </a>
+# <a href="http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT%2B1-a-partir-de-dim">
+# http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT%2B1-a-partir-de-dim
+# anche-prochain-5538.html
+# </a>
+
+# From Petr Machata (2011-03-30):
+# They have it written in English here:
+# <a href="http://www.map.ma/eng/sections/home/morocco_to_spring_fo/view">
+# http://www.map.ma/eng/sections/home/morocco_to_spring_fo/view
+# </a>
+#
+# It says there that "Morocco will resume its standard time on July 31,
+# 2011 at midnight." Now they don't say whether they mean midnight of
+# wall clock time (i.e. 11pm UTC), but that's what I would assume. It has
+# also been like that in the past.
+
+# From Alexander Krivenyshev (2012-03-09):
+# According to Infom&eacute;diaire web site from Morocco (infomediaire.ma),
+# on March 9, 2012, (in French) Heure l&eacute;gale:
+# Le Maroc adopte officiellement l'heure d'&eacute;t&eacute;
+# <a href="http://www.infomediaire.ma/news/maroc/heure-l%C3%A9gale-le-maroc-adopte-officiellement-lheure-d%C3%A9t%C3%A9">
+# http://www.infomediaire.ma/news/maroc/heure-l%C3%A9gale-le-maroc-adopte-officiellement-lheure-d%C3%A9t%C3%A9
+# </a>
+# Governing Council adopted draft decree, that Morocco DST starts on
+# the last Sunday of March (March 25, 2012) and ends on
+# last Sunday of September (September 30, 2012)
+# except the month of Ramadan.
+# or (brief)
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_morocco06.html">
+# http://www.worldtimezone.com/dst_news/dst_news_morocco06.html
+# </a>
+
+# From Arthur David Olson (2012-03-10):
+# The infomediaire.ma source indicates that the system is to be in
+# effect every year. It gives 03H00 as the "fall back" time of day;
+# it lacks a "spring forward" time of day; assume 2:00 XXX.
+# Wait on specifying the Ramadan exception for details about
+# start date, start time of day, end date, and end time of day XXX.
+
+# From Christophe Tropamer (2012-03-16):
+# Seen Morocco change again:
+# <a href="http://www.le2uminutes.com/actualite.php">
+# http://www.le2uminutes.com/actualite.php
+# </a>
+# "...&agrave; partir du dernier dimance d'avril et non fins mars,
+# comme annonc&eacute; pr&eacute;c&eacute;demment."
+
+# From Milamber Space Network (2012-07-17):
+# The official return to GMT is announced by the Moroccan government:
+# <a href="http://www.mmsp.gov.ma/fr/actualites.aspx?id=288">
+# http://www.mmsp.gov.ma/fr/actualites.aspx?id=288 [in French]
+# </a>
+#
+# Google translation, lightly edited:
+# Back to the standard time of the Kingdom (GMT)
+# Pursuant to Decree No. 2-12-126 issued on 26 Jumada (I) 1433 (April 18,
+# 2012) and in accordance with the order of Mr. President of the
+# Government No. 3-47-12 issued on 24 Sha'ban (11 July 2012), the Ministry
+# of Public Service and Administration Modernization announces the return
+# of the legal time of the Kingdom (GMT) from Friday, July 20, 2012 until
+# Monday, August 20, 2012.  So the time will be delayed by 60 minutes from
+# 3:00 am Friday, July 20, 2012 and will again be advanced by 60 minutes
+# August 20, 2012 from 2:00 am.
+
+# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+
+Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
+Rule	Morocco	1939	only	-	Nov	19	 0:00	0	-
+Rule	Morocco	1940	only	-	Feb	25	 0:00	1:00	S
+Rule	Morocco	1945	only	-	Nov	18	 0:00	0	-
+Rule	Morocco	1950	only	-	Jun	11	 0:00	1:00	S
+Rule	Morocco	1950	only	-	Oct	29	 0:00	0	-
+Rule	Morocco	1967	only	-	Jun	 3	12:00	1:00	S
+Rule	Morocco	1967	only	-	Oct	 1	 0:00	0	-
+Rule	Morocco	1974	only	-	Jun	24	 0:00	1:00	S
+Rule	Morocco	1974	only	-	Sep	 1	 0:00	0	-
+Rule	Morocco	1976	1977	-	May	 1	 0:00	1:00	S
+Rule	Morocco	1976	only	-	Aug	 1	 0:00	0	-
+Rule	Morocco	1977	only	-	Sep	28	 0:00	0	-
+Rule	Morocco	1978	only	-	Jun	 1	 0:00	1:00	S
+Rule	Morocco	1978	only	-	Aug	 4	 0:00	0	-
+Rule	Morocco	2008	only	-	Jun	 1	 0:00	1:00	S
+Rule	Morocco	2008	only	-	Sep	 1	 0:00	0	-
+Rule	Morocco	2009	only	-	Jun	 1	 0:00	1:00	S
+Rule	Morocco	2009	only	-	Aug	 21	 0:00	0	-
+Rule	Morocco	2010	only	-	May	 2	 0:00	1:00	S
+Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
+Rule	Morocco	2011	only	-	Apr	 3	 0:00	1:00	S
+Rule	Morocco	2011	only	-	Jul	 31	 0	0	-
+Rule	Morocco	2012	max	-	Apr	 lastSun 2:00	1:00	S
+Rule	Morocco	2012	max	-	Sep	 lastSun 3:00	0	-
+Rule	Morocco	2012	only	-	Jul	 20	 3:00	0	-
+Rule	Morocco	2012	only	-	Aug	 20	 2:00	1:00	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
+			 0:00	Morocco	WE%sT	1984 Mar 16
+			 1:00	-	CET	1986
+			 0:00	Morocco	WE%sT
+# Western Sahara
+Zone Africa/El_Aaiun	-0:52:48 -	LMT	1934 Jan
+			-1:00	-	WAT	1976 Apr 14
+			 0:00	-	WET
+
+# Mozambique
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Maputo	2:10:20 -	LMT	1903 Mar
+			2:00	-	CAT
+
+# Namibia
+# The 1994-04-03 transition is from Shanks & Pottenger.
+# Shanks & Pottenger report no DST after 1998-04; go with IATA.
+
+# From Petronella Sibeene (2007-03-30) in
+# <http://allafrica.com/stories/200703300178.html>:
+# While the entire country changes its time, Katima Mulilo and other
+# settlements in Caprivi unofficially will not because the sun there
+# rises and sets earlier compared to other regions.  Chief of
+# Forecasting Riaan van Zyl explained that the far eastern parts of
+# the country are close to 40 minutes earlier in sunrise than the rest
+# of the country.
+#
+# From Paul Eggert (2007-03-31):
+# Apparently the Caprivi Strip informally observes Botswana time, but
+# we have no details.  In the meantime people there can use Africa/Gaborone.
+
+# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Namibia	1994	max	-	Sep	Sun>=1	2:00	1:00	S
+Rule	Namibia	1995	max	-	Apr	Sun>=1	2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Windhoek	1:08:24 -	LMT	1892 Feb 8
+			1:30	-	SWAT	1903 Mar	# SW Africa Time
+			2:00	-	SAST	1942 Sep 20 2:00
+			2:00	1:00	SAST	1943 Mar 21 2:00
+			2:00	-	SAST	1990 Mar 21 # independence
+			2:00	-	CAT	1994 Apr  3
+			1:00	Namibia	WA%sT
+
+# Niger
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Niamey	 0:08:28 -	LMT	1912
+			-1:00	-	WAT	1934 Feb 26
+			 0:00	-	GMT	1960
+			 1:00	-	WAT
+
+# Nigeria
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Lagos	0:13:36 -	LMT	1919 Sep
+			1:00	-	WAT
+
+# Reunion
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Reunion	3:41:52 -	LMT	1911 Jun	# Saint-Denis
+			4:00	-	RET	# Reunion Time
+#
+# Scattered Islands (Iles Eparses) administered from Reunion are as follows.
+# The following information about them is taken from
+# Iles Eparses (www.outre-mer.gouv.fr/domtom/ile.htm, 1997-07-22, in French;
+# no longer available as of 1999-08-17).
+# We have no info about their time zone histories.
+#
+# Bassas da India - uninhabited
+# Europa Island - inhabited from 1905 to 1910 by two families
+# Glorioso Is - inhabited until at least 1958
+# Juan de Nova - uninhabited
+# Tromelin - inhabited until at least 1958
+
+# Rwanda
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Kigali	2:00:16 -	LMT	1935 Jun
+			2:00	-	CAT
+
+# St Helena
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/St_Helena	-0:22:48 -	LMT	1890		# Jamestown
+			-0:22:48 -	JMT	1951	# Jamestown Mean Time
+			 0:00	-	GMT
+# The other parts of the St Helena territory are similar:
+#	Tristan da Cunha: on GMT, say Whitman and the CIA
+#	Ascension: on GMT, says usno1995 and the CIA
+#	Gough (scientific station since 1955; sealers wintered previously):
+#		on GMT, says the CIA
+#	Inaccessible, Nightingale: no information, but probably GMT
+
+# Sao Tome and Principe
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Sao_Tome	 0:26:56 -	LMT	1884
+			-0:36:32 -	LMT	1912	# Lisbon Mean Time
+			 0:00	-	GMT
+
+# Senegal
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Dakar	-1:09:44 -	LMT	1912
+			-1:00	-	WAT	1941 Jun
+			 0:00	-	GMT
+
+# Seychelles
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Mahe	3:41:48 -	LMT	1906 Jun	# Victoria
+			4:00	-	SCT	# Seychelles Time
+# From Paul Eggert (2001-05-30):
+# Aldabra, Farquhar, and Desroches, originally dependencies of the
+# Seychelles, were transferred to the British Indian Ocean Territory
+# in 1965 and returned to Seychelles control in 1976.  We don't know
+# whether this affected their time zone, so omit this for now.
+# Possibly the islands were uninhabited.
+
+# Sierra Leone
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Whitman gives Mar 31 - Aug 31 for 1931 on; go with Shanks & Pottenger.
+Rule	SL	1935	1942	-	Jun	 1	0:00	0:40	SLST
+Rule	SL	1935	1942	-	Oct	 1	0:00	0	WAT
+Rule	SL	1957	1962	-	Jun	 1	0:00	1:00	SLST
+Rule	SL	1957	1962	-	Sep	 1	0:00	0	GMT
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Freetown	-0:53:00 -	LMT	1882
+			-0:53:00 -	FMT	1913 Jun # Freetown Mean Time
+			-1:00	SL	%s	1957
+			 0:00	SL	%s
+
+# Somalia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Mogadishu	3:01:28 -	LMT	1893 Nov
+			3:00	-	EAT	1931
+			2:30	-	BEAT	1957
+			3:00	-	EAT
+
+# South Africa
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	SA	1942	1943	-	Sep	Sun>=15	2:00	1:00	-
+Rule	SA	1943	1944	-	Mar	Sun>=15	2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Johannesburg 1:52:00 -	LMT	1892 Feb 8
+			1:30	-	SAST	1903 Mar
+			2:00	SA	SAST
+# Marion and Prince Edward Is
+# scientific station since 1947
+# no information
+
+# Sudan
+#
+# From <a href="http://www.sunanews.net/sn13jane.html">
+# Sudan News Agency (2000-01-13)
+# </a>, also reported by Michael De Beukelaer-Dossche via Steffen Thorsen:
+# Clocks will be moved ahead for 60 minutes all over the Sudan as of noon
+# Saturday....  This was announced Thursday by Caretaker State Minister for
+# Manpower Abdul-Rahman Nur-Eddin.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Sudan	1970	only	-	May	 1	0:00	1:00	S
+Rule	Sudan	1970	1985	-	Oct	15	0:00	0	-
+Rule	Sudan	1971	only	-	Apr	30	0:00	1:00	S
+Rule	Sudan	1972	1985	-	Apr	lastSun	0:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Khartoum	2:10:08 -	LMT	1931
+			2:00	Sudan	CA%sT	2000 Jan 15 12:00
+			3:00	-	EAT
+
+# South Sudan
+Zone	Africa/Juba	2:06:24 -	LMT	1931
+			2:00	Sudan	CA%sT	2000 Jan 15 12:00
+			3:00	-	EAT
+
+# Swaziland
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Mbabane	2:04:24 -	LMT	1903 Mar
+			2:00	-	SAST
+
+# Tanzania
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Dar_es_Salaam 2:37:08 -	LMT	1931
+			3:00	-	EAT	1948
+			2:45	-	BEAUT	1961
+			3:00	-	EAT
+
+# Togo
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Lome	0:04:52 -	LMT	1893
+			0:00	-	GMT
+
+# Tunisia
+
+# From Gwillim Law (2005-04-30):
+# My correspondent, Risto Nykanen, has alerted me to another adoption of DST,
+# this time in Tunisia.  According to Yahoo France News
+# <http://fr.news.yahoo.com/050426/5/4dumk.html>, in a story attributed to AP
+# and dated 2005-04-26, "Tunisia has decided to advance its official time by
+# one hour, starting on Sunday, May 1.  Henceforth, Tunisian time will be
+# UTC+2 instead of UTC+1.  The change will take place at 23:00 UTC next
+# Saturday."  (My translation)
+#
+# From Oscar van Vlijmen (2005-05-02):
+# LaPresse, the first national daily newspaper ...
+# <http://www.lapresse.tn/archives/archives280405/actualites/lheure.html>
+# ... DST for 2005: on: Sun May 1 0h standard time, off: Fri Sept. 30,
+# 1h standard time.
+#
+# From Atef Loukil (2006-03-28):
+# The daylight saving time will be the same each year:
+# Beginning      : the last Sunday of March at 02:00
+# Ending         : the last Sunday of October at 03:00 ...
+# http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=1188&Itemid=50
+
+# From Steffen Thorsen (2009-03-16):
+# According to several news sources, Tunisia will not observe DST this year.
+# (Arabic)
+# <a href="http://www.elbashayer.com/?page=viewn&nid=42546">
+# http://www.elbashayer.com/?page=viewn&nid=42546
+# </a>
+# <a href="http://www.babnet.net/kiwidetail-15295.asp">
+# http://www.babnet.net/kiwidetail-15295.asp
+# </a>
+#
+# We have also confirmed this with the US embassy in Tunisia.
+# We have a wrap-up about this on the following page:
+# <a href="http://www.timeanddate.com/news/time/tunisia-cancels-dst-2009.html">
+# http://www.timeanddate.com/news/time/tunisia-cancels-dst-2009.html
+# </a>
+
+# From Alexander Krivenyshev (2009-03-17):
+# Here is a link to Tunis Afrique Presse News Agency
+#
+# Standard time to be kept the whole year long (tap.info.tn):
+#
+# (in English)
+# <a href="http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=26813&Itemid=157">
+# http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=26813&Itemid=157
+# </a>
+#
+# (in Arabic)
+# <a href="http://www.tap.info.tn/ar/index.php?option=com_content&task=view&id=61240&Itemid=1">
+# http://www.tap.info.tn/ar/index.php?option=com_content&task=view&id=61240&Itemid=1
+# </a>
+
+# From Arthur David Olson (2009--3-18):
+# The Tunis Afrique Presse News Agency notice contains this: "This measure is due to the fact
+# that the fasting month of ramadan coincides with the period concerned by summer time.
+# Therefore, the standard time will be kept unchanged the whole year long."
+# So foregoing DST seems to be an exception (albeit one that may be repeated in the  future).
+
+# From Alexander Krivenyshev (2010-03-27):
+# According to some news reports Tunis confirmed not to use DST in 2010
+#
+# (translation):
+# "The Tunisian government has decided to abandon DST, which was scheduled on
+# Sunday...
+# Tunisian authorities had suspended the DST for the first time last year also
+# coincided with the month of Ramadan..."
+#
+# (in Arabic)
+# <a href="http://www.moheet.com/show_news.aspx?nid=358861&pg=1">
+# http://www.moheet.com/show_news.aspx?nid=358861&pg=1
+# <a href="http://www.almadenahnews.com/newss/news.php?c=118&id=38036">
+# http://www.almadenahnews.com/newss/news.php?c=118&id=38036
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_tunis02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_tunis02.html
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Tunisia	1939	only	-	Apr	15	23:00s	1:00	S
+Rule	Tunisia	1939	only	-	Nov	18	23:00s	0	-
+Rule	Tunisia	1940	only	-	Feb	25	23:00s	1:00	S
+Rule	Tunisia	1941	only	-	Oct	 6	 0:00	0	-
+Rule	Tunisia	1942	only	-	Mar	 9	 0:00	1:00	S
+Rule	Tunisia	1942	only	-	Nov	 2	 3:00	0	-
+Rule	Tunisia	1943	only	-	Mar	29	 2:00	1:00	S
+Rule	Tunisia	1943	only	-	Apr	17	 2:00	0	-
+Rule	Tunisia	1943	only	-	Apr	25	 2:00	1:00	S
+Rule	Tunisia	1943	only	-	Oct	 4	 2:00	0	-
+Rule	Tunisia	1944	1945	-	Apr	Mon>=1	 2:00	1:00	S
+Rule	Tunisia	1944	only	-	Oct	 8	 0:00	0	-
+Rule	Tunisia	1945	only	-	Sep	16	 0:00	0	-
+Rule	Tunisia	1977	only	-	Apr	30	 0:00s	1:00	S
+Rule	Tunisia	1977	only	-	Sep	24	 0:00s	0	-
+Rule	Tunisia	1978	only	-	May	 1	 0:00s	1:00	S
+Rule	Tunisia	1978	only	-	Oct	 1	 0:00s	0	-
+Rule	Tunisia	1988	only	-	Jun	 1	 0:00s	1:00	S
+Rule	Tunisia	1988	1990	-	Sep	lastSun	 0:00s	0	-
+Rule	Tunisia	1989	only	-	Mar	26	 0:00s	1:00	S
+Rule	Tunisia	1990	only	-	May	 1	 0:00s	1:00	S
+Rule	Tunisia	2005	only	-	May	 1	 0:00s	1:00	S
+Rule	Tunisia	2005	only	-	Sep	30	 1:00s	0	-
+Rule	Tunisia	2006	2008	-	Mar	lastSun	 2:00s	1:00	S
+Rule	Tunisia	2006	2008	-	Oct	lastSun	 2:00s	0	-
+
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
+# more precise 0:09:21.
+# Shanks & Pottenger say the 1911 switch was on Mar 9; go with Howse's Mar 11.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Tunis	0:40:44 -	LMT	1881 May 12
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
+			1:00	Tunisia	CE%sT
+
+# Uganda
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Kampala	2:09:40 -	LMT	1928 Jul
+			3:00	-	EAT	1930
+			2:30	-	BEAT	1948
+			2:45	-	BEAUT	1957
+			3:00	-	EAT
+
+# Zambia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Lusaka	1:53:08 -	LMT	1903 Mar
+			2:00	-	CAT
+
+# Zimbabwe
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Harare	2:04:12 -	LMT	1903 Mar
+			2:00	-	CAT
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/antarctica b/jdk/test/sun/util/calendar/zi/tzdata/antarctica
new file mode 100644
index 0000000..64b71d5
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/antarctica
@@ -0,0 +1,436 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# From Paul Eggert (1999-11-15):
+# To keep things manageable, we list only locations occupied year-round; see
+# <a href="http://www.comnap.aq/comnap/comnap.nsf/P/Stations/">
+# COMNAP - Stations and Bases
+# </a>
+# and
+# <a href="http://www.spri.cam.ac.uk/bob/periant.htm">
+# Summary of the Peri-Antarctic Islands (1998-07-23)
+# </a>
+# for information.
+# Unless otherwise specified, we have no time zone information.
+#
+# Except for the French entries,
+# I made up all time zone abbreviations mentioned here; corrections welcome!
+# FORMAT is `zzz' and GMTOFF is 0 for locations while uninhabited.
+
+# These rules are stolen from the `southamerica' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	ArgAQ	1964	1966	-	Mar	 1	0:00	0	-
+Rule	ArgAQ	1964	1966	-	Oct	15	0:00	1:00	S
+Rule	ArgAQ	1967	only	-	Apr	 2	0:00	0	-
+Rule	ArgAQ	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
+Rule	ArgAQ	1968	1969	-	Apr	Sun>=1	0:00	0	-
+Rule	ArgAQ	1974	only	-	Jan	23	0:00	1:00	S
+Rule	ArgAQ	1974	only	-	May	 1	0:00	0	-
+Rule	ChileAQ	1972	1986	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	1974	1987	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	ChileAQ	1987	only	-	Apr	12	3:00u	0	-
+Rule	ChileAQ	1988	1989	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	1988	only	-	Oct	Sun>=1	4:00u	1:00	S
+Rule	ChileAQ	1989	only	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	ChileAQ	1990	only	-	Mar	18	3:00u	0	-
+Rule	ChileAQ	1990	only	-	Sep	16	4:00u	1:00	S
+Rule	ChileAQ	1991	1996	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	1991	1997	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	ChileAQ	1997	only	-	Mar	30	3:00u	0	-
+Rule	ChileAQ	1998	only	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	1998	only	-	Sep	27	4:00u	1:00	S
+Rule	ChileAQ	1999	only	-	Apr	 4	3:00u	0	-
+Rule	ChileAQ	1999	2010	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	ChileAQ	2000	2007	-	Mar	Sun>=9	3:00u	0	-
+# N.B.: the end of March 29 in Chile is March 30 in Universal time,
+# which is used below in specifying the transition.
+Rule	ChileAQ	2008	only	-	Mar	30	3:00u	0	-
+Rule	ChileAQ	2009	only	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	2010	only	-	Apr	Sun>=1	3:00u	0	-
+Rule	ChileAQ	2011	only	-	May	Sun>=2	3:00u	0	-
+Rule	ChileAQ	2011	only	-	Aug	Sun>=16	4:00u	1:00	S
+Rule	ChileAQ	2012	only	-	Apr	Sun>=23	3:00u	0	-
+Rule	ChileAQ	2012	only	-	Sep	Sun>=2	4:00u	1:00	S
+Rule	ChileAQ	2013	max	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	2013	max	-	Oct	Sun>=9	4:00u	1:00	S
+
+# These rules are stolen from the `australasia' file.
+Rule	AusAQ	1917	only	-	Jan	 1	0:01	1:00	-
+Rule	AusAQ	1917	only	-	Mar	25	2:00	0	-
+Rule	AusAQ	1942	only	-	Jan	 1	2:00	1:00	-
+Rule	AusAQ	1942	only	-	Mar	29	2:00	0	-
+Rule	AusAQ	1942	only	-	Sep	27	2:00	1:00	-
+Rule	AusAQ	1943	1944	-	Mar	lastSun	2:00	0	-
+Rule	AusAQ	1943	only	-	Oct	 3	2:00	1:00	-
+Rule	ATAQ	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	ATAQ	1968	only	-	Mar	lastSun	2:00s	0	-
+Rule	ATAQ	1968	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	ATAQ	1969	1971	-	Mar	Sun>=8	2:00s	0	-
+Rule	ATAQ	1972	only	-	Feb	lastSun	2:00s	0	-
+Rule	ATAQ	1973	1981	-	Mar	Sun>=1	2:00s	0	-
+Rule	ATAQ	1982	1983	-	Mar	lastSun	2:00s	0	-
+Rule	ATAQ	1984	1986	-	Mar	Sun>=1	2:00s	0	-
+Rule	ATAQ	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
+Rule	ATAQ	1987	1990	-	Mar	Sun>=15	2:00s	0	-
+Rule	ATAQ	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
+Rule	ATAQ	1988	1990	-	Oct	lastSun	2:00s	1:00	-
+Rule	ATAQ	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	ATAQ	1991	2005	-	Mar	lastSun	2:00s	0	-
+Rule	ATAQ	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	ATAQ	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	ATAQ	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	ATAQ	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	ATAQ	2008	max	-	Apr	Sun>=1	2:00s	0	-
+
+# Argentina - year-round bases
+# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
+# Esperanza, San Martin Land, -6323-05659, since 1952-12-17
+# Jubany, Potter Peninsula, King George Island, -6414-0602320, since 1982-01
+# Marambio, Seymour I, -6414-05637, since 1969-10-29
+# Orcadas, Laurie I, -6016-04444, since 1904-02-22
+# San Martin, Debenham I, -6807-06708, since 1951-03-21
+#	(except 1960-03 / 1976-03-21)
+
+# Australia - territories
+# Heard Island, McDonald Islands (uninhabited)
+#	previously sealers and scientific personnel wintered
+#	<a href="http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html">
+#	Margaret Turner reports
+#	</a> (1999-09-30) that they're UTC+5, with no DST;
+#	presumably this is when they have visitors.
+#
+# year-round bases
+# Casey, Bailey Peninsula, -6617+11032, since 1969
+# Davis, Vestfold Hills, -6835+07759, since 1957-01-13
+#	(except 1964-11 - 1969-02)
+# Mawson, Holme Bay, -6736+06253, since 1954-02-13
+
+# From Steffen Thorsen (2009-03-11):
+# Three Australian stations in Antarctica have changed their time zone:
+# Casey moved from UTC+8 to UTC+11
+# Davis moved from UTC+7 to UTC+5
+# Mawson moved from UTC+6 to UTC+5
+# The changes occurred on 2009-10-18 at 02:00 (local times).
+#
+# Government source: (Australian Antarctic Division)
+# <a href="http://www.aad.gov.au/default.asp?casid=37079">
+# http://www.aad.gov.au/default.asp?casid=37079
+# </a>
+#
+# We have more background information here:
+# <a href="http://www.timeanddate.com/news/time/antarctica-new-times.html">
+# http://www.timeanddate.com/news/time/antarctica-new-times.html
+# </a>
+
+# From Steffen Thorsen (2010-03-10):
+# We got these changes from the Australian Antarctic Division:
+# - Macquarie Island will stay on UTC+11 for winter and therefore not
+# switch back from daylight savings time when other parts of Australia do
+# on 4 April.
+#
+# - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
+# The change to UTC+11 is being considered as a regular summer thing but
+# has not been decided yet.
+#
+# - Davis station will revert to its normal time of UTC+7 at 10 March 2010
+# 20:00 UTC.
+#
+# - Mawson station stays on UTC+5.
+#
+# In addition to the Rule changes for Casey/Davis, it means that Macquarie
+# will no longer be like Hobart and will have to have its own Zone created.
+#
+# Background:
+# <a href="http://www.timeanddate.com/news/time/antartica-time-changes-2010.html">
+# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
+# </a>
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Casey	0	-	zzz	1969
+			8:00	-	WST	2009 Oct 18 2:00
+						# Western (Aus) Standard Time
+			11:00	-	CAST	2010 Mar 5 2:00
+						# Casey Time
+			8:00	-	WST	2011 Oct 28 2:00
+			11:00	-	CAST	2012 Feb 21 17:00u
+			8:00	-	WST
+Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
+			7:00	-	DAVT	1964 Nov # Davis Time
+			0	-	zzz	1969 Feb
+			7:00	-	DAVT	2009 Oct 18 2:00
+			5:00	-	DAVT	2010 Mar 10 20:00u
+			7:00	-	DAVT	2011 Oct 28 2:00
+			5:00	-	DAVT	2012 Feb 21 20:00u
+			7:00	-	DAVT
+Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
+			6:00	-	MAWT	2009 Oct 18 2:00
+						# Mawson Time
+			5:00	-	MAWT
+Zone Antarctica/Macquarie 0	-	zzz	1911
+			10:00	-	EST	1916 Oct 1 2:00
+			10:00	1:00	EST	1917 Feb
+			10:00	AusAQ	EST	1967
+			10:00	ATAQ	EST	2010 Apr 4 3:00
+			11:00	-	MIST	# Macquarie Island Time
+# References:
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
+# Casey Weather (1998-02-26)
+# </a>
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/davis/video.html">
+# Davis Station, Antarctica (1998-02-26)
+# </a>
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/mawson/video.html">
+# Mawson Station, Antarctica (1998-02-25)
+# </a>
+
+# Brazil - year-round base
+# Comandante Ferraz, King George Island, -6205+05824, since 1983/4
+
+# Chile - year-round bases and towns
+# Escudero, South Shetland Is, -621157-0585735, since 1994
+# Presidente Eduadro Frei, King George Island, -6214-05848, since 1969-03-07
+# General Bernardo O'Higgins, Antarctic Peninsula, -6319-05704, since 1948-02
+# Capitan Arturo Prat, -6230-05941
+# Villa Las Estrellas (a town), around the Frei base, since 1984-04-09
+# These locations have always used Santiago time; use TZ='America/Santiago'.
+
+# China - year-round bases
+# Great Wall, King George Island, -6213-05858, since 1985-02-20
+# Zhongshan, Larsemann Hills, Prydz Bay, -6922+07623, since 1989-02-26
+
+# France - year-round bases
+#
+# From Antoine Leca (1997-01-20):
+# Time data are from Nicole Pailleau at the IFRTP
+# (French Institute for Polar Research and Technology).
+# She confirms that French Southern Territories and Terre Adelie bases
+# don't observe daylight saving time, even if Terre Adelie supplies came
+# from Tasmania.
+#
+# French Southern Territories with year-round inhabitants
+#
+# Martin-de-Vivies Base, Amsterdam Island, -374105+0773155, since 1950
+# Alfred-Faure Base, Crozet Islands, -462551+0515152, since 1964
+# Port-aux-Francais, Kerguelen Islands, -492110+0701303, since 1951;
+#	whaling & sealing station operated 1908/1914, 1920/1929, and 1951/1956
+#
+# St Paul Island - near Amsterdam, uninhabited
+#	fishing stations operated variously 1819/1931
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Kerguelen	0	-	zzz	1950	# Port-aux-Francais
+			5:00	-	TFT	# ISO code TF Time
+#
+# year-round base in the main continent
+# Dumont-d'Urville, Ile des Petrels, -6640+14001, since 1956-11
+#
+# Another base at Port-Martin, 50km east, began operation in 1947.
+# It was destroyed by fire on 1952-01-14.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/DumontDUrville 0 -	zzz	1947
+			10:00	-	PMT	1952 Jan 14 # Port-Martin Time
+			0	-	zzz	1956 Nov
+			10:00	-	DDUT	# Dumont-d'Urville Time
+# Reference:
+# <a href="http://en.wikipedia.org/wiki/Dumont_d'Urville_Station">
+# Dumont d'Urville Station (2005-12-05)
+# </a>
+
+# Germany - year-round base
+# Georg von Neumayer, -7039-00815
+
+# India - year-round base
+# Dakshin Gangotri, -7005+01200
+
+# Japan - year-round bases
+# Dome Fuji, -7719+03942
+# Syowa, -690022+0393524
+#
+# From Hideyuki Suzuki (1999-02-06):
+# In all Japanese stations, +0300 is used as the standard time.
+#
+# Syowa station, which is the first antarctic station of Japan,
+# was established on 1957-01-29.  Since Syowa station is still the main
+# station of Japan, it's appropriate for the principal location.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Syowa	0	-	zzz	1957 Jan 29
+			3:00	-	SYOT	# Syowa Time
+# See:
+# <a href="http://www.nipr.ac.jp/english/ara01.html">
+# NIPR Antarctic Research Activities (1999-08-17)
+# </a>
+
+# S Korea - year-round base
+# King Sejong, King George Island, -6213-05847, since 1988
+
+# New Zealand - claims
+# Balleny Islands (never inhabited)
+# Scott Island (never inhabited)
+#
+# year-round base
+# Scott, Ross Island, since 1957-01, is like Antarctica/McMurdo.
+#
+# These rules for New Zealand are stolen from the `australasia' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NZAQ	1974	only	-	Nov	 3	2:00s	1:00	D
+Rule	NZAQ	1975	1988	-	Oct	lastSun	2:00s	1:00	D
+Rule	NZAQ	1989	only	-	Oct	 8	2:00s	1:00	D
+Rule	NZAQ	1990	2006	-	Oct	Sun>=1	2:00s	1:00	D
+Rule	NZAQ	1975	only	-	Feb	23	2:00s	0	S
+Rule	NZAQ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
+Rule	NZAQ	1990	2007	-	Mar	Sun>=15	2:00s	0	S
+Rule	NZAQ	2007	max	-	Sep	lastSun	2:00s	1:00	D
+Rule	NZAQ	2008	max	-	Apr	Sun>=1	2:00s	0	S
+
+# Norway - territories
+# Bouvet (never inhabited)
+#
+# claims
+# Peter I Island (never inhabited)
+
+# Poland - year-round base
+# Arctowski, King George Island, -620945-0582745, since 1977
+
+# Russia - year-round bases
+# Bellingshausen, King George Island, -621159-0585337, since 1968-02-22
+# Mirny, Davis coast, -6633+09301, since 1956-02
+# Molodezhnaya, Alasheyev Bay, -6740+04551,
+#	year-round from 1962-02 to 1999-07-01
+# Novolazarevskaya, Queen Maud Land, -7046+01150,
+#	year-round from 1960/61 to 1992
+
+# Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
+# <a href="http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP">
+# From Craig Mundell (1994-12-15)</a>:
+# Vostok, which is one of the Russian stations, is set on the same
+# time as Moscow, Russia.
+#
+# From Lee Hotz (2001-03-08):
+# I queried the folks at Columbia who spent the summer at Vostok and this is
+# what they had to say about time there:
+# ``in the US Camp (East Camp) we have been on New Zealand (McMurdo)
+# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
+# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
+# of GMT). This is a time zone I think two hours east of Moscow. The
+# natural time zone is in between the two: 8 hours ahead of GMT.''
+#
+# From Paul Eggert (2001-05-04):
+# This seems to be hopelessly confusing, so I asked Lee Hotz about it
+# in person.  He said that some Antartic locations set their local
+# time so that noon is the warmest part of the day, and that this
+# changes during the year and does not necessarily correspond to mean
+# solar noon.  So the Vostok time might have been whatever the clocks
+# happened to be during their visit.  So we still don't really know what time
+# it is at Vostok.  But we'll guess UTC+6.
+#
+Zone Antarctica/Vostok	0	-	zzz	1957 Dec 16
+			6:00	-	VOST	# Vostok time
+
+# S Africa - year-round bases
+# Marion Island, -4653+03752
+# Sanae, -7141-00250
+
+# UK
+#
+# British Antarctic Territories (BAT) claims
+# South Orkney Islands
+#	scientific station from 1903
+#	whaling station at Signy I 1920/1926
+# South Shetland Islands
+#
+# year-round bases
+# Bird Island, South Georgia, -5400-03803, since 1983
+# Deception Island, -6259-06034, whaling station 1912/1931,
+#	scientific station 1943/1967,
+#	previously sealers and a scientific expedition wintered by accident,
+#	and a garrison was deployed briefly
+# Halley, Coates Land, -7535-02604, since 1956-01-06
+#	Halley is on a moving ice shelf and is periodically relocated
+#	so that it is never more than 10km from its nominal location.
+# Rothera, Adelaide Island, -6734-6808, since 1976-12-01
+#
+# From Paul Eggert (2002-10-22)
+# <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Rothera	0	-	zzz	1976 Dec  1
+			-3:00	-	ROTT	# Rothera time
+
+# Uruguay - year round base
+# Artigas, King George Island, -621104-0585107
+
+# USA - year-round bases
+#
+# Palmer, Anvers Island, since 1965 (moved 2 miles in 1968)
+#
+# From Ethan Dicks (1996-10-06):
+# It keeps the same time as Punta Arenas, Chile, because, just like us
+# and the South Pole, that's the other end of their supply line....
+# I verified with someone who was there that since 1980,
+# Palmer has followed Chile.  Prior to that, before the Falklands War,
+# Palmer used to be supplied from Argentina.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Palmer	0	-	zzz	1965
+			-4:00	ArgAQ	AR%sT	1969 Oct 5
+			-3:00	ArgAQ	AR%sT	1982 May
+			-4:00	ChileAQ	CL%sT
+#
+#
+# McMurdo, Ross Island, since 1955-12
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/McMurdo	0	-	zzz	1956
+			12:00	NZAQ	NZ%sT
+#
+# Amundsen-Scott, South Pole, continuously occupied since 1956-11-20
+#
+# From Paul Eggert (1996-09-03):
+# Normally it wouldn't have a separate entry, since it's like the
+# larger Antarctica/McMurdo since 1970, but it's too famous to omit.
+#
+# From Chris Carrier (1996-06-27):
+# Siple, the first commander of the South Pole station,
+# stated that he would have liked to have kept GMT at the station,
+# but that he found it more convenient to keep GMT+12
+# as supplies for the station were coming from McMurdo Sound,
+# which was on GMT+12 because New Zealand was on GMT+12 all year
+# at that time (1957).  (Source: Siple's book 90 degrees SOUTH.)
+#
+# From Susan Smith
+# http://www.cybertours.com/whs/pole10.html
+# (1995-11-13 16:24:56 +1300, no longer available):
+# We use the same time as McMurdo does.
+# And they use the same time as Christchurch, NZ does....
+# One last quirk about South Pole time.
+# All the electric clocks are usually wrong.
+# Something about the generators running at 60.1hertz or something
+# makes all of the clocks run fast.  So every couple of days,
+# we have to go around and set them back 5 minutes or so.
+# Maybe if we let them run fast all of the time, we'd get to leave here sooner!!
+#
+Link	Antarctica/McMurdo	Antarctica/South_Pole
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/asia b/jdk/test/sun/util/calendar/zi/tzdata/asia
new file mode 100644
index 0000000..9ef3ef8
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia
@@ -0,0 +1,2738 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+#
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
+# I found in the UCLA library.
+#
+# A reliable and entertaining source about time zones is
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+#
+# I invented the abbreviations marked `*' in the following table;
+# the rest are from earlier versions of this file, or from other sources.
+# Corrections are welcome!
+#	     std  dst
+#	     LMT	Local Mean Time
+#	2:00 EET  EEST	Eastern European Time
+#	2:00 IST  IDT	Israel
+#	3:00 AST  ADT	Arabia*
+#	3:30 IRST IRDT	Iran
+#	4:00 GST	Gulf*
+#	5:30 IST	India
+#	7:00 ICT	Indochina*
+#	7:00 WIT	west Indonesia
+#	8:00 CIT	central Indonesia
+#	8:00 CST	China
+#	9:00 CJT	Central Japanese Time (1896/1937)*
+#	9:00 EIT	east Indonesia
+#	9:00 JST  JDT	Japan
+#	9:00 KST  KDT	Korea
+#	9:30 CST	(Australian) Central Standard Time
+#
+# See the `europe' file for Russia and Turkey in Asia.
+
+# From Guy Harris:
+# Incorporates data for Singapore from Robert Elz' asia 1.1, as well as
+# additional information from Tom Yap, Sun Microsystems Intercontinental
+# Technical Support (including a page from the Official Airline Guide -
+# Worldwide Edition).  The names for time zones are guesses.
+
+###############################################################################
+
+# These rules are stolen from the `europe' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	EUAsia	1981	max	-	Mar	lastSun	 1:00u	1:00	S
+Rule	EUAsia	1979	1995	-	Sep	lastSun	 1:00u	0	-
+Rule	EUAsia	1996	max	-	Oct	lastSun	 1:00u	0	-
+Rule E-EurAsia	1981	max	-	Mar	lastSun	 0:00	1:00	S
+Rule E-EurAsia	1979	1995	-	Sep	lastSun	 0:00	0	-
+Rule E-EurAsia	1996	max	-	Oct	lastSun	 0:00	0	-
+Rule RussiaAsia	1981	1984	-	Apr	1	 0:00	1:00	S
+Rule RussiaAsia	1981	1983	-	Oct	1	 0:00	0	-
+Rule RussiaAsia	1984	1991	-	Sep	lastSun	 2:00s	0	-
+Rule RussiaAsia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
+Rule RussiaAsia	1992	only	-	Mar	lastSat	23:00	1:00	S
+Rule RussiaAsia	1992	only	-	Sep	lastSat	23:00	0	-
+Rule RussiaAsia	1993	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule RussiaAsia	1993	1995	-	Sep	lastSun	 2:00s	0	-
+Rule RussiaAsia	1996	max	-	Oct	lastSun	 2:00s	0	-
+
+# Afghanistan
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Kabul	4:36:48 -	LMT	1890
+			4:00	-	AFT	1945
+			4:30	-	AFT
+
+# Armenia
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger have Yerevan switching to 3:00 (with Russian DST)
+# in spring 1991, then to 4:00 with no DST in fall 1995, then
+# readopting Russian DST in 1997.  Go with Shanks & Pottenger, even
+# when they disagree with others.  Edgar Der-Danieliantz
+# reported (1996-05-04) that Yerevan probably wouldn't use DST
+# in 1996, though it did use DST in 1995.  IATA SSIM (1991/1998) reports that
+# Armenia switched from 3:00 to 4:00 in 1998 and observed DST after 1991,
+# but started switching at 3:00s in 1998.
+
+# From Arthur David Olson (2011-06-15):
+# While Russia abandoned DST in 2011, Armenia may choose to
+# follow Russia's "old" rules.
+
+# From Alexander Krivenyshev (2012-02-10):
+# According to News Armenia, on Feb 9, 2012,
+# http://newsarmenia.ru/society/20120209/42609695.html
+#
+# The Armenia National Assembly adopted final reading of Amendments to the
+# Law "On procedure of calculation time on the territory of the Republic of
+# Armenia" according to which Armenia [is] abolishing Daylight Saving Time.
+# or
+# (brief)
+# http://www.worldtimezone.com/dst_news/dst_news_armenia03.html
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Yerevan	2:58:00 -	LMT	1924 May  2
+			3:00	-	YERT	1957 Mar    # Yerevan Time
+			4:00 RussiaAsia YER%sT	1991 Mar 31 2:00s
+			3:00	1:00	YERST	1991 Sep 23 # independence
+			3:00 RussiaAsia	AM%sT	1995 Sep 24 2:00s
+			4:00	-	AMT	1997
+			4:00 RussiaAsia	AM%sT	2012 Mar 25 2:00s
+			4:00	-	AMT
+
+# Azerbaijan
+# From Rustam Aliyev of the Azerbaijan Internet Forum (2005-10-23):
+# According to the resolution of Cabinet of Ministers, 1997
+# Resolution available at: http://aif.az/docs/daylight_res.pdf
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Azer	1997	max	-	Mar	lastSun	 4:00	1:00	S
+Rule	Azer	1997	max	-	Oct	lastSun	 5:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
+			3:00	-	BAKT	1957 Mar    # Baku Time
+			4:00 RussiaAsia BAK%sT	1991 Mar 31 2:00s
+			3:00	1:00	BAKST	1991 Aug 30 # independence
+			3:00 RussiaAsia	AZ%sT	1992 Sep lastSat 23:00
+			4:00	-	AZT	1996 # Azerbaijan time
+			4:00	EUAsia	AZ%sT	1997
+			4:00	Azer	AZ%sT
+
+# Bahrain
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
+			4:00	-	GST	1972 Jun
+			3:00	-	AST
+
+# Bangladesh
+# From Alexander Krivenyshev (2009-05-13):
+# According to newspaper Asian Tribune (May 6, 2009) Bangladesh may introduce
+# Daylight Saving Time from June 16 to Sept 30
+#
+# Bangladesh to introduce daylight saving time likely from June 16
+# <a href="http://www.asiantribune.com/?q=node/17288">
+# http://www.asiantribune.com/?q=node/17288
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh02.html
+# </a>
+#
+# "... Bangladesh government has decided to switch daylight saving time from
+# June
+# 16 till September 30 in a bid to ensure maximum use of daylight to cope with
+# crippling power crisis. "
+#
+# The switch will remain in effect from June 16 to Sept 30 (2009) but if
+# implemented the next year, it will come in force from April 1, 2010
+
+# From Steffen Thorsen (2009-06-02):
+# They have finally decided now, but changed the start date to midnight between
+# the 19th and 20th, and they have not set the end date yet.
+#
+# Some sources:
+# <a href="http://in.reuters.com/article/southAsiaNews/idINIndia-40017620090601">
+# http://in.reuters.com/article/southAsiaNews/idINIndia-40017620090601
+# </a>
+# <a href="http://bdnews24.com/details.php?id=85889&cid=2">
+# http://bdnews24.com/details.php?id=85889&cid=2
+# </a>
+#
+# Our wrap-up:
+# <a href="http://www.timeanddate.com/news/time/bangladesh-daylight-saving-2009.html">
+# http://www.timeanddate.com/news/time/bangladesh-daylight-saving-2009.html
+# </a>
+
+# From A. N. M. Kamrus Saadat (2009-06-15):
+# Finally we've got the official mail regarding DST start time where DST start
+# time is mentioned as Jun 19 2009, 23:00 from BTRC (Bangladesh
+# Telecommunication Regulatory Commission).
+#
+# No DST end date has been announced yet.
+
+# From Alexander Krivenyshev (2009-09-25):
+# Bangladesh won't go back to Standard Time from October 1, 2009,
+# instead it will continue DST measure till the cabinet makes a fresh decision.
+#
+# Following report by same newspaper-"The Daily Star Friday":
+# "DST change awaits cabinet decision-Clock won't go back by 1-hr from Oct 1"
+# <a href="http://www.thedailystar.net/newDesign/news-details.php?nid=107021">
+# http://www.thedailystar.net/newDesign/news-details.php?nid=107021
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html">
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html
+# </a>
+
+# From Steffen Thorsen (2009-10-13):
+# IANS (Indo-Asian News Service) now reports:
+# Bangladesh has decided that the clock advanced by an hour to make
+# maximum use of daylight hours as an energy saving measure would
+# "continue for an indefinite period."
+#
+# One of many places where it is published:
+# <a href="http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html">
+# http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html
+# </a>
+
+# From Alexander Krivenyshev (2009-12-24):
+# According to Bangladesh newspaper "The Daily Star,"
+# Bangladesh will change its clock back to Standard Time on Dec 31, 2009.
+#
+# Clock goes back 1-hr on Dec 31 night.
+# <a href="http://www.thedailystar.net/newDesign/news-details.php?nid=119228">
+# http://www.thedailystar.net/newDesign/news-details.php?nid=119228
+# </a>
+# and
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh05.html">
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh05.html
+# </a>
+#
+# "...The government yesterday decided to put the clock back by one hour
+# on December 31 midnight and the new time will continue until March 31,
+# 2010 midnight. The decision came at a cabinet meeting at the Prime
+# Minister's Office last night..."
+
+# From Alexander Krivenyshev (2010-03-22):
+# According to Bangladesh newspaper "The Daily Star,"
+# Cabinet cancels Daylight Saving Time
+# <a href="http://www.thedailystar.net/newDesign/latest_news.php?nid=22817">
+# http://www.thedailystar.net/newDesign/latest_news.php?nid=22817
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html">
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Dhaka	2009	only	-	Jun	19	23:00	1:00	S
+Rule	Dhaka	2009	only	-	Dec	31	23:59	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dhaka	6:01:40 -	LMT	1890
+			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
+			6:30	-	BURT	1942 May 15 # Burma Time
+			5:30	-	IST	1942 Sep
+			6:30	-	BURT	1951 Sep 30
+			6:00	-	DACT	1971 Mar 26 # Dacca Time
+			6:00	-	BDT	2009
+			6:00	Dhaka	BD%sT
+
+# Bhutan
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Thimphu	5:58:36 -	LMT	1947 Aug 15 # or Thimbu
+			5:30	-	IST	1987 Oct
+			6:00	-	BTT	# Bhutan Time
+
+# British Indian Ocean Territory
+# Whitman and the 1995 CIA time zone map say 5:00, but the
+# 1997 and later maps say 6:00.  Assume the switch occurred in 1996.
+# We have no information as to when standard time was introduced;
+# assume it occurred in 1907, the same year as Mauritius (which
+# then contained the Chagos Archipelago).
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Chagos	4:49:40	-	LMT	1907
+			5:00	-	IOT	1996 # BIOT Time
+			6:00	-	IOT
+
+# Brunei
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Brunei	7:39:40 -	LMT	1926 Mar   # Bandar Seri Begawan
+			7:30	-	BNT	1933
+			8:00	-	BNT
+
+# Burma / Myanmar
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Rangoon	6:24:40 -	LMT	1880		# or Yangon
+			6:24:36	-	RMT	1920	   # Rangoon Mean Time?
+			6:30	-	BURT	1942 May   # Burma Time
+			9:00	-	JST	1945 May 3
+			6:30	-	MMT		   # Myanmar Time
+
+# Cambodia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Phnom_Penh	6:59:40 -	LMT	1906 Jun  9
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
+			7:00	-	ICT	1912 May
+			8:00	-	ICT	1931 May
+			7:00	-	ICT
+
+# China
+
+# From Guy Harris:
+# People's Republic of China.  Yes, they really have only one time zone.
+
+# From Bob Devine (1988-01-28):
+# No they don't.  See TIME mag, 1986-02-17 p.52.  Even though
+# China is across 4 physical time zones, before Feb 1, 1986 only the
+# Peking (Bejing) time zone was recognized.  Since that date, China
+# has two of 'em -- Peking's and Urumqi (named after the capital of
+# the Xinjiang Uyghur Autonomous Region).  I don't know about DST for it.
+#
+# . . .I just deleted the DST table and this editor makes it too
+# painful to suck in another copy..  So, here is what I have for
+# DST start/end dates for Peking's time zone (info from AP):
+#
+#     1986 May 4 - Sept 14
+#     1987 mid-April - ??
+
+# From U. S. Naval Observatory (1989-01-19):
+# CHINA               8 H  AHEAD OF UTC  ALL OF CHINA, INCL TAIWAN
+# CHINA               9 H  AHEAD OF UTC  APR 17 - SEP 10
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that China (except for Hong Kong and Macau)
+# has had a single time zone since 1980 May 1, observing summer DST
+# from 1986 through 1991; this contradicts Devine's
+# note about Time magazine, though apparently _something_ happened in 1986.
+# Go with Shanks & Pottenger for now.  I made up names for the other
+# pre-1980 time zones.
+
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Shang	1940	only	-	Jun	 3	0:00	1:00	D
+Rule	Shang	1940	1941	-	Oct	 1	0:00	0	S
+Rule	Shang	1941	only	-	Mar	16	0:00	1:00	D
+Rule	PRC	1986	only	-	May	 4	0:00	1:00	D
+Rule	PRC	1986	1991	-	Sep	Sun>=11	0:00	0	S
+Rule	PRC	1987	1991	-	Apr	Sun>=10	0:00	1:00	D
+
+# From Anthony Fok (2001-12-20):
+# BTW, I did some research on-line and found some info regarding these five
+# historic timezones from some Taiwan websites.  And yes, there are official
+# Chinese names for these locales (before 1949).
+#
+# From Jesper Norgaard Welen (2006-07-14):
+# I have investigated the timezones around 1970 on the
+# http://www.astro.com/atlas site [with provinces and county
+# boundaries summarized below]....  A few other exceptions were two
+# counties on the Sichuan side of the Xizang-Sichuan border,
+# counties Dege and Baiyu which lies on the Sichuan side and are
+# therefore supposed to be GMT+7, Xizang region being GMT+6, but Dege
+# county is GMT+8 according to astro.com while Baiyu county is GMT+6
+# (could be true), for the moment I am assuming that those two
+# counties are mistakes in the astro.com data.
+
+# From Paul Eggert (2008-02-11):
+# I just now checked Google News for western news sources that talk
+# about China's single time zone, and couldn't find anything before 1986
+# talking about China being in one time zone.  (That article was: Jim
+# Mann, "A clumsy embrace for another western custom: China on daylight
+# time--sort of", Los Angeles Times, 1986-05-05.  By the way, this
+# article confirms the tz database's data claiming that China began
+# observing daylight saving time in 1986.
+#
+# From Thomas S. Mullaney (2008-02-11):
+# I think you're combining two subjects that need to treated
+# separately: daylight savings (which, you're correct, wasn't
+# implemented until the 1980s) and the unified time zone centered near
+# Beijing (which was implemented in 1949). Briefly, there was also a
+# "Lhasa Time" in Tibet and "Urumqi Time" in Xinjiang. The first was
+# ceased, and the second eventually recognized (again, in the 1980s).
+#
+# From Paul Eggert (2008-06-30):
+# There seems to be a good chance China switched to a single time zone in 1949
+# rather than in 1980 as Shanks & Pottenger have it, but we don't have a
+# reliable documentary source saying so yet, so for now we still go with
+# Shanks & Pottenger.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Changbai Time ("Long-white Time", Long-white = Heilongjiang area)
+# Heilongjiang (except Mohe county), Jilin
+Zone	Asia/Harbin	8:26:44	-	LMT	1928 # or Haerbin
+			8:30	-	CHAT	1932 Mar # Changbai Time
+			8:00	-	CST	1940
+			9:00	-	CHAT	1966 May
+			8:30	-	CHAT	1980 May
+			8:00	PRC	C%sT
+# Zhongyuan Time ("Central plain Time")
+# most of China
+Zone	Asia/Shanghai	8:05:52	-	LMT	1928
+			8:00	Shang	C%sT	1949
+			8:00	PRC	C%sT
+# Long-shu Time (probably due to Long and Shu being two names of that area)
+# Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
+# most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
+# counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
+# Yangchun, Yangjiang, Yu'nan, and Yunfu.
+Zone	Asia/Chongqing	7:06:20	-	LMT	1928 # or Chungking
+			7:00	-	LONT	1980 May # Long-shu Time
+			8:00	PRC	C%sT
+# Xin-zang Time ("Xinjiang-Tibet Time")
+# The Gansu counties Aksay, Anxi, Dunhuang, Subei; west Qinghai;
+# the Guangdong counties  Xuwen, Haikang, Suixi, Lianjiang,
+# Zhanjiang, Wuchuan, Huazhou, Gaozhou, Maoming, Dianbai, and Xinyi;
+# east Tibet, including Lhasa, Chamdo, Shigaise, Jimsar, Shawan and Hutubi;
+# east Xinjiang, including Urumqi, Turpan, Karamay, Korla, Minfeng, Jinghe,
+# Wusu, Qiemo, Xinyan, Wulanwusu, Jinghe, Yumin, Tacheng, Tuoli, Emin,
+# Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami,
+# Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan.
+Zone	Asia/Urumqi	5:50:20	-	LMT	1928 # or Urumchi
+			6:00	-	URUT	1980 May # Urumqi Time
+			8:00	PRC	C%sT
+# Kunlun Time
+# West Tibet, including Pulan, Aheqi, Shufu, Shule;
+# West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke,
+# Zhaosu, Tekesi, Gongliu, Chabuchaer, Huocheng, Bole, Pishan, Suiding,
+# and Yarkand.
+
+# From Luther Ma (2009-10-17):
+# Almost all (>99.9%) ethnic Chinese (properly ethnic Han) living in
+# Xinjiang use Chinese Standard Time. Some are aware of Xinjiang time,
+# but have no need of it. All planes, trains, and schools function on
+# what is called "Beijing time." When Han make an appointment in Chinese
+# they implicitly use Beijing time.
+#
+# On the other hand, ethnic Uyghurs, who make up about half the
+# population of Xinjiang, typically use "Xinjiang time" which is two
+# hours behind Beijing time, or UTC +0600. The government of the Xinjiang
+# Uyghur Autonomous Region, (XAUR, or just Xinjiang for short) as well as
+# local governments such as the Urumqi city government use both times in
+# publications, referring to what is popularly called Xinjiang time as
+# "Urumqi time." When Uyghurs make an appointment in the Uyghur language
+# they almost invariably use Xinjiang time.
+#
+# (Their ethnic Han compatriots would typically have no clue of its
+# widespread use, however, because so extremely few of them are fluent in
+# Uyghur, comparable to the number of Anglo-Americans fluent in Navajo.)
+#
+# (...As with the rest of China there was a brief interval ending in 1990
+# or 1991 when summer time was in use.  The confusion was severe, with
+# the province not having dual times but four times in use at the same
+# time. Some areas remained on standard Xinjiang time or Beijing time and
+# others moving their clocks ahead.)
+#
+# ...an example of an official website using of Urumqi time.
+#
+# The first few lines of the Google translation of
+# <a href="http://www.fjysgl.gov.cn/show.aspx?id=2379&cid=39">
+# http://www.fjysgl.gov.cn/show.aspx?id=2379&cid=39
+# </a>
+# (retrieved 2009-10-13)
+# > Urumqi fire seven people are missing the alleged losses of at least
+# > 500 million yuan
+# >
+# > (Reporter Dong Liu) the day before 20:20 or so (Urumqi Time 18:20),
+# > Urumqi City Department of International Plaza Luther Qiantang River
+# > burst fire. As of yesterday, 18:30, Urumqi City Fire officers and men
+# > have worked continuously for 22 hours...
+
+# From Luther Ma (2009-11-19):
+# With the risk of being redundant to previous answers these are the most common
+# English "transliterations" (w/o using non-English symbols):
+#
+# 1. Wulumuqi...
+# 2. Kashi...
+# 3. Urumqi...
+# 4. Kashgar...
+# ...
+# 5. It seems that Uyghurs in Urumqi has been using Xinjiang since at least the
+# 1960's. I know of one Han, now over 50, who grew up in the surrounding
+# countryside and used Xinjiang time as a child.
+#
+# 6. Likewise for Kashgar and the rest of south Xinjiang I don't know of any
+# start date for Xinjiang time.
+#
+# Without having access to local historical records, nor the ability to legally
+# publish them, I would go with October 1, 1949, when Xinjiang became the Uyghur
+# Autonomous Region under the PRC. (Before that Uyghurs, of course, would also
+# not be using Beijing time, but some local time.)
+
+Zone	Asia/Kashgar	5:03:56	-	LMT	1928 # or Kashi or Kaxgar
+			5:30	-	KAST	1940	 # Kashgar Time
+			5:00	-	KAST	1980 May
+			8:00	PRC	C%sT
+
+
+# From Lee Yiu Chung (2009-10-24):
+# I found there are some mistakes for the...DST rule for Hong
+# Kong. [According] to the DST record from Hong Kong Observatory (actually,
+# it is not [an] observatory, but the official meteorological agency of HK,
+# and also serves as the official timing agency), there are some missing
+# and incorrect rules. Although the exact switch over time is missing, I
+# think 3:30 is correct. The official DST record for Hong Kong can be
+# obtained from
+# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
+# http://www.hko.gov.hk/gts/time/Summertime.htm
+# </a>.
+
+# From Arthur David Olson (2009-10-28):
+# Here are the dates given at
+# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
+# http://www.hko.gov.hk/gts/time/Summertime.htm
+# </a>
+# as of 2009-10-28:
+# Year        Period
+# 1941        1 Apr to 30 Sep
+# 1942        Whole year
+# 1943        Whole year
+# 1944        Whole year
+# 1945        Whole year
+# 1946        20 Apr to 1 Dec
+# 1947        13 Apr to 30 Dec
+# 1948        2 May to 31 Oct
+# 1949        3 Apr to 30 Oct
+# 1950        2 Apr to 29 Oct
+# 1951        1 Apr to 28 Oct
+# 1952        6 Apr to 25 Oct
+# 1953        5 Apr to 1 Nov
+# 1954        21 Mar to 31 Oct
+# 1955        20 Mar to 6 Nov
+# 1956        18 Mar to 4 Nov
+# 1957        24 Mar to 3 Nov
+# 1958        23 Mar to 2 Nov
+# 1959        22 Mar to 1 Nov
+# 1960        20 Mar to 6 Nov
+# 1961        19 Mar to 5 Nov
+# 1962        18 Mar to 4 Nov
+# 1963        24 Mar to 3 Nov
+# 1964        22 Mar to 1 Nov
+# 1965        18 Apr to 17 Oct
+# 1966        17 Apr to 16 Oct
+# 1967        16 Apr to 22 Oct
+# 1968        21 Apr to 20 Oct
+# 1969        20 Apr to 19 Oct
+# 1970        19 Apr to 18 Oct
+# 1971        18 Apr to 17 Oct
+# 1972        16 Apr to 22 Oct
+# 1973        22 Apr to 21 Oct
+# 1973/74     30 Dec 73 to 20 Oct 74
+# 1975        20 Apr to 19 Oct
+# 1976        18 Apr to 17 Oct
+# 1977        Nil
+# 1978        Nil
+# 1979        13 May to 21 Oct
+# 1980 to Now Nil
+# The page does not give start or end times of day.
+# The page does not give a start date for 1942.
+# The page does not givw an end date for 1945.
+# The Japanese occupation of Hong Kong began on 1941-12-25.
+# The Japanese surrender of Hong Kong was signed 1945-09-15.
+# For lack of anything better, use start of those days as the transition times.
+
+# Hong Kong (Xianggang)
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
+Rule	HK	1941	only	-	Sep	30	3:30	0	-
+Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
+Rule	HK	1946	only	-	Dec	1	3:30	0	-
+Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
+Rule	HK	1947	only	-	Dec	30	3:30	0	-
+Rule	HK	1948	only	-	May	2	3:30	1:00	S
+Rule	HK	1948	1951	-	Oct	lastSun	3:30	0	-
+Rule	HK	1952	only	-	Oct	25	3:30	0	-
+Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
+Rule	HK	1953	only	-	Nov	1	3:30	0	-
+Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
+Rule	HK	1954	only	-	Oct	31	3:30	0	-
+Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
+Rule	HK	1965	1976	-	Apr	Sun>=16	3:30	1:00	S
+Rule	HK	1965	1976	-	Oct	Sun>=16	3:30	0	-
+Rule	HK	1973	only	-	Dec	30	3:30	1:00	S
+Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
+Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
+			8:00	HK	HK%sT	1941 Dec 25
+			9:00	-	JST	1945 Sep 15
+			8:00	HK	HK%sT
+
+###############################################################################
+
+# Taiwan
+
+# Shanks & Pottenger write that Taiwan observed DST during 1945, when it
+# was still controlled by Japan.  This is hard to believe, but we don't
+# have any other information.
+
+# From smallufo (2010-04-03):
+# According to Taiwan's CWB,
+# <a href="http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm">
+# http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm
+# </a>
+# Taipei has DST in 1979 between July 1st and Sep 30.
+
+# From Arthur David Olson (2010-04-07):
+# Here's Google's translation of the table at the bottom of the "summert.htm" page:
+# Decade 	                                                    Name                      Start and end date
+# Republic of China 34 years to 40 years (AD 1945-1951 years) Summer Time               May 1 to September 30
+# 41 years of the Republic of China (AD 1952)                 Daylight Saving Time      March 1 to October 31
+# Republic of China 42 years to 43 years (AD 1953-1954 years) Daylight Saving Time      April 1 to October 31
+# In the 44 years to 45 years (AD 1955-1956 years)            Daylight Saving Time      April 1 to September 30
+# Republic of China 46 years to 48 years (AD 1957-1959)       Summer Time               April 1 to September 30
+# Republic of China 49 years to 50 years (AD 1960-1961)       Summer Time               June 1 to September 30
+# Republic of China 51 years to 62 years (AD 1962-1973 years) Stop Summer Time
+# Republic of China 63 years to 64 years (1974-1975 AD)       Daylight Saving Time      April 1 to September 30
+# Republic of China 65 years to 67 years (1976-1978 AD)       Stop Daylight Saving Time
+# Republic of China 68 years (AD 1979)                        Daylight Saving Time      July 1 to September 30
+# Republic of China since 69 years (AD 1980)                  Stop Daylight Saving Time
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Taiwan	1945	1951	-	May	1	0:00	1:00	D
+Rule	Taiwan	1945	1951	-	Oct	1	0:00	0	S
+Rule	Taiwan	1952	only	-	Mar	1	0:00	1:00	D
+Rule	Taiwan	1952	1954	-	Nov	1	0:00	0	S
+Rule	Taiwan	1953	1959	-	Apr	1	0:00	1:00	D
+Rule	Taiwan	1955	1961	-	Oct	1	0:00	0	S
+Rule	Taiwan	1960	1961	-	Jun	1	0:00	1:00	D
+Rule	Taiwan	1974	1975	-	Apr	1	0:00	1:00	D
+Rule	Taiwan	1974	1975	-	Oct	1	0:00	0	S
+Rule	Taiwan	1979	only	-	Jun	30	0:00	1:00	D
+Rule	Taiwan	1979	only	-	Sep	30	0:00	0	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Taipei	8:06:00 -	LMT	1896 # or Taibei or T'ai-pei
+			8:00	Taiwan	C%sT
+
+# Macau (Macao, Aomen)
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Macau	1961	1962	-	Mar	Sun>=16	3:30	1:00	S
+Rule	Macau	1961	1964	-	Nov	Sun>=1	3:30	0	-
+Rule	Macau	1963	only	-	Mar	Sun>=16	0:00	1:00	S
+Rule	Macau	1964	only	-	Mar	Sun>=16	3:30	1:00	S
+Rule	Macau	1965	only	-	Mar	Sun>=16	0:00	1:00	S
+Rule	Macau	1965	only	-	Oct	31	0:00	0	-
+Rule	Macau	1966	1971	-	Apr	Sun>=16	3:30	1:00	S
+Rule	Macau	1966	1971	-	Oct	Sun>=16	3:30	0	-
+Rule	Macau	1972	1974	-	Apr	Sun>=15	0:00	1:00	S
+Rule	Macau	1972	1973	-	Oct	Sun>=15	0:00	0	-
+Rule	Macau	1974	1977	-	Oct	Sun>=15	3:30	0	-
+Rule	Macau	1975	1977	-	Apr	Sun>=15	3:30	1:00	S
+Rule	Macau	1978	1980	-	Apr	Sun>=15	0:00	1:00	S
+Rule	Macau	1978	1980	-	Oct	Sun>=15	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Macau	7:34:20 -	LMT	1912
+			8:00	Macau	MO%sT	1999 Dec 20 # return to China
+			8:00	PRC	C%sT
+
+
+###############################################################################
+
+# Cyprus
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Cyprus	1975	only	-	Apr	13	0:00	1:00	S
+Rule	Cyprus	1975	only	-	Oct	12	0:00	0	-
+Rule	Cyprus	1976	only	-	May	15	0:00	1:00	S
+Rule	Cyprus	1976	only	-	Oct	11	0:00	0	-
+Rule	Cyprus	1977	1980	-	Apr	Sun>=1	0:00	1:00	S
+Rule	Cyprus	1977	only	-	Sep	25	0:00	0	-
+Rule	Cyprus	1978	only	-	Oct	2	0:00	0	-
+Rule	Cyprus	1979	1997	-	Sep	lastSun	0:00	0	-
+Rule	Cyprus	1981	1998	-	Mar	lastSun	0:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Nicosia	2:13:28 -	LMT	1921 Nov 14
+			2:00	Cyprus	EE%sT	1998 Sep
+			2:00	EUAsia	EE%sT
+# IATA SSIM (1998-09) has Cyprus using EU rules for the first time.
+
+# Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72.
+# However, for various reasons many users expect to find it under Europe.
+Link	Asia/Nicosia	Europe/Nicosia
+
+# Georgia
+# From Paul Eggert (1994-11-19):
+# Today's _Economist_ (p 60) reports that Georgia moved its clocks forward
+# an hour recently, due to a law proposed by Zurab Murvanidze,
+# an MP who went on a hunger strike for 11 days to force discussion about it!
+# We have no details, but we'll guess they didn't move the clocks back in fall.
+#
+# From Mathew Englander, quoting AP (1996-10-23 13:05-04):
+# Instead of putting back clocks at the end of October, Georgia
+# will stay on daylight savings time this winter to save energy,
+# President Eduard Shevardnadze decreed Wednesday.
+#
+# From the BBC via Joseph S. Myers (2004-06-27):
+#
+# Georgia moved closer to Western Europe on Sunday...  The former Soviet
+# republic has changed its time zone back to that of Moscow.  As a result it
+# is now just four hours ahead of Greenwich Mean Time, rather than five hours
+# ahead.  The switch was decreed by the pro-Western president of Georgia,
+# Mikhail Saakashvili, who said the change was partly prompted by the process
+# of integration into Europe.
+
+# From Teimuraz Abashidze (2005-11-07):
+# Government of Georgia ... decided to NOT CHANGE daylight savings time on
+# [Oct.] 30, as it was done before during last more than 10 years.
+# Currently, we are in fact GMT +4:00, as before 30 October it was GMT
+# +3:00.... The problem is, there is NO FORMAL LAW or governmental document
+# about it.  As far as I can find, I was told, that there is no document,
+# because we just DIDN'T ISSUE document about switching to winter time....
+# I don't know what can be done, especially knowing that some years ago our
+# DST rules where changed THREE TIMES during one month.
+
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Tbilisi	2:59:16 -	LMT	1880
+			2:59:16	-	TBMT	1924 May  2 # Tbilisi Mean Time
+			3:00	-	TBIT	1957 Mar    # Tbilisi Time
+			4:00 RussiaAsia TBI%sT	1991 Mar 31 2:00s
+			3:00	1:00	TBIST	1991 Apr  9 # independence
+			3:00 RussiaAsia GE%sT	1992 # Georgia Time
+			3:00 E-EurAsia	GE%sT	1994 Sep lastSun
+			4:00 E-EurAsia	GE%sT	1996 Oct lastSun
+			4:00	1:00	GEST	1997 Mar lastSun
+			4:00 E-EurAsia	GE%sT	2004 Jun 27
+			3:00 RussiaAsia	GE%sT	2005 Mar lastSun 2:00
+			4:00	-	GET
+
+# East Timor
+
+# See Indonesia for the 1945 transition.
+
+# From Joao Carrascalao, brother of the former governor of East Timor, in
+# <a href="http://etan.org/et99c/december/26-31/30ETMAY.htm">
+# East Timor may be late for its millennium
+# </a> (1999-12-26/31):
+# Portugal tried to change the time forward in 1974 because the sun
+# rises too early but the suggestion raised a lot of problems with the
+# Timorese and I still don't think it would work today because it
+# conflicts with their way of life.
+
+# From Paul Eggert (2000-12-04):
+# We don't have any record of the above attempt.
+# Most likely our records are incomplete, but we have no better data.
+
+# <a href="http://www.hri.org/news/world/undh/last/00-08-16.undh.html">
+# From Manoel de Almeida e Silva, Deputy Spokesman for the UN Secretary-General
+# (2000-08-16)</a>:
+# The Cabinet of the East Timor Transition Administration decided
+# today to advance East Timor's time by one hour.  The time change,
+# which will be permanent, with no seasonal adjustment, will happen at
+# midnight on Saturday, September 16.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dili	8:22:20 -	LMT	1912
+			8:00	-	TLT	1942 Feb 21 23:00 # E Timor Time
+			9:00	-	JST	1945 Sep 23
+			9:00	-	TLT	1976 May  3
+			8:00	-	CIT	2000 Sep 17 00:00
+			9:00	-	TLT
+
+# India
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Kolkata	5:53:28 -	LMT	1880	# Kolkata
+			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
+			6:30	-	BURT	1942 May 15 # Burma Time
+			5:30	-	IST	1942 Sep
+			5:30	1:00	IST	1945 Oct 15
+			5:30	-	IST
+# The following are like Asia/Kolkata:
+#	Andaman Is
+#	Lakshadweep (Laccadive, Minicoy and Amindivi Is)
+#	Nicobar Is
+
+# Indonesia
+#
+# From Gwillim Law (2001-05-28), overriding Shanks & Pottenger:
+# <http://www.sumatera-inc.com/go_to_invest/about_indonesia.asp#standtime>
+# says that Indonesia's time zones changed on 1988-01-01.  Looking at some
+# time zone maps, I think that must refer to Western Borneo (Kalimantan Barat
+# and Kalimantan Tengah) switching from UTC+8 to UTC+7.
+#
+# From Paul Eggert (2007-03-10):
+# Here is another correction to Shanks & Pottenger.
+# JohnTWB writes that Japanese forces did not surrender control in
+# Indonesia until 1945-09-01 00:00 at the earliest (in Jakarta) and
+# other formal surrender ceremonies were September 9, 11, and 13, plus
+# September 12 for the regional surrender to Mountbatten in Singapore.
+# These would be the earliest possible times for a change.
+# Regimes horaires pour le monde entier, by Henri Le Corre, (Editions
+# Traditionnelles, 1987, Paris) says that Java and Madura switched
+# from JST to UTC+07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
+# (Hollandia).  For now, assume all Indonesian locations other than Jayapura
+# switched on 1945-09-23.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Asia/Jakarta	7:07:12 -	LMT	1867 Aug 10
+# Shanks & Pottenger say the next transition was at 1924 Jan 1 0:13,
+# but this must be a typo.
+			7:07:12	-	JMT	1923 Dec 31 23:47:12 # Jakarta
+			7:20	-	JAVT	1932 Nov	 # Java Time
+			7:30	-	WIT	1942 Mar 23
+			9:00	-	JST	1945 Sep 23
+			7:30	-	WIT	1948 May
+			8:00	-	WIT	1950 May
+			7:30	-	WIT	1964
+			7:00	-	WIT
+Zone Asia/Pontianak	7:17:20	-	LMT	1908 May
+			7:17:20	-	PMT	1932 Nov    # Pontianak MT
+			7:30	-	WIT	1942 Jan 29
+			9:00	-	JST	1945 Sep 23
+			7:30	-	WIT	1948 May
+			8:00	-	WIT	1950 May
+			7:30	-	WIT	1964
+			8:00	-	CIT	1988 Jan  1
+			7:00	-	WIT
+Zone Asia/Makassar	7:57:36 -	LMT	1920
+			7:57:36	-	MMT	1932 Nov    # Macassar MT
+			8:00	-	CIT	1942 Feb  9
+			9:00	-	JST	1945 Sep 23
+			8:00	-	CIT
+Zone Asia/Jayapura	9:22:48 -	LMT	1932 Nov
+			9:00	-	EIT	1944 Sep  1
+			9:30	-	CST	1964
+			9:00	-	EIT
+
+# Iran
+
+# From Roozbeh Pournader (2003-03-15):
+# This is an English translation of what I just found (originally in Persian).
+# The Gregorian dates in brackets are mine:
+#
+#	Official Newspaper No. 13548-1370/6/25 [1991-09-16]
+#	No. 16760/T233 H				1370/6/10 [1991-09-01]
+#
+#	The Rule About Change of the Official Time of the Country
+#
+#	The Board of Ministers, in the meeting dated 1370/5/23 [1991-08-14],
+#	based on the suggestion number 2221/D dated 1370/4/22 [1991-07-13]
+#	of the Country's Organization for Official and Employment Affairs,
+#	and referring to the law for equating the working hours of workers
+#	and officers in the whole country dated 1359/4/23 [1980-07-14], and
+#	for synchronizing the official times of the country, agreed that:
+#
+#	The official time of the country will should move forward one hour
+#	at the 24[:00] hours of the first day of Farvardin and should return
+#	to its previous state at the 24[:00] hours of the 30th day of
+#	Shahrivar.
+#
+#	First Deputy to the President - Hassan Habibi
+#
+# From personal experience, that agrees with what has been followed
+# for at least the last 5 years.  Before that, for a few years, the
+# date used was the first Thursday night of Farvardin and the last
+# Thursday night of Shahrivar, but I can't give exact dates....
+# I have also changed the abbreviations to what is considered correct
+# here in Iran, IRST for regular time and IRDT for daylight saving time.
+#
+# From Roozbeh Pournader (2005-04-05):
+# The text of the Iranian law, in effect since 1925, clearly mentions
+# that the true solar year is the measure, and there is no arithmetic
+# leap year calculation involved.  There has never been any serious
+# plan to change that law....
+#
+# From Paul Eggert (2006-03-22):
+# Go with Shanks & Pottenger before Sept. 1991, and with Pournader thereafter.
+# I used Ed Reingold's cal-persia in GNU Emacs 21.2 to check Persian dates,
+# stopping after 2037 when 32-bit time_t's overflow.
+# That cal-persia used Birashk's approximation, which disagrees with the solar
+# calendar predictions for the year 2025, so I corrected those dates by hand.
+#
+# From Oscar van Vlijmen (2005-03-30), writing about future
+# discrepancies between cal-persia and the Iranian calendar:
+# For 2091 solar-longitude-after yields 2091-03-20 08:40:07.7 UT for
+# the vernal equinox and that gets so close to 12:00 some local
+# Iranian time that the definition of the correct location needs to be
+# known exactly, amongst other factors.  2157 is even closer:
+# 2157-03-20 08:37:15.5 UT.  But the Gregorian year 2025 should give
+# no interpretation problem whatsoever.  By the way, another instant
+# in the near future where there will be a discrepancy between
+# arithmetical and astronomical Iranian calendars will be in 2058:
+# vernal equinox on 2058-03-20 09:03:05.9 UT.  The Java version of
+# Reingold's/Dershowitz' calculator gives correctly the Gregorian date
+# 2058-03-21 for 1 Farvardin 1437 (astronomical).
+#
+# From Steffen Thorsen (2006-03-22):
+# Several of my users have reported that Iran will not observe DST anymore:
+# http://www.irna.ir/en/news/view/line-17/0603193812164948.htm
+#
+# From Reuters (2007-09-16), with a heads-up from Jesper Norgaard Welen:
+# ... the Guardian Council ... approved a law on Sunday to re-introduce
+# daylight saving time ...
+# http://uk.reuters.com/article/oilRpt/idUKBLA65048420070916
+#
+# From Roozbeh Pournader (2007-11-05):
+# This is quoted from Official Gazette of the Islamic Republic of
+# Iran, Volume 63, Number 18242, dated Tuesday 1386/6/24
+# [2007-10-16]. I am doing the best translation I can:...
+# The official time of the country will be moved forward for one hour
+# on the 24 hours of the first day of the month of Farvardin and will
+# be changed back to its previous state on the 24 hours of the
+# thirtieth day of Shahrivar.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Iran	1978	1980	-	Mar	21	0:00	1:00	D
+Rule	Iran	1978	only	-	Oct	21	0:00	0	S
+Rule	Iran	1979	only	-	Sep	19	0:00	0	S
+Rule	Iran	1980	only	-	Sep	23	0:00	0	S
+Rule	Iran	1991	only	-	May	 3	0:00	1:00	D
+Rule	Iran	1992	1995	-	Mar	22	0:00	1:00	D
+Rule	Iran	1991	1995	-	Sep	22	0:00	0	S
+Rule	Iran	1996	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	1996	only	-	Sep	21	0:00	0	S
+Rule	Iran	1997	1999	-	Mar	22	0:00	1:00	D
+Rule	Iran	1997	1999	-	Sep	22	0:00	0	S
+Rule	Iran	2000	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2000	only	-	Sep	21	0:00	0	S
+Rule	Iran	2001	2003	-	Mar	22	0:00	1:00	D
+Rule	Iran	2001	2003	-	Sep	22	0:00	0	S
+Rule	Iran	2004	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2004	only	-	Sep	21	0:00	0	S
+Rule	Iran	2005	only	-	Mar	22	0:00	1:00	D
+Rule	Iran	2005	only	-	Sep	22	0:00	0	S
+Rule	Iran	2008	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2008	only	-	Sep	21	0:00	0	S
+Rule	Iran	2009	2011	-	Mar	22	0:00	1:00	D
+Rule	Iran	2009	2011	-	Sep	22	0:00	0	S
+Rule	Iran	2012	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2012	only	-	Sep	21	0:00	0	S
+Rule	Iran	2013	2015	-	Mar	22	0:00	1:00	D
+Rule	Iran	2013	2015	-	Sep	22	0:00	0	S
+Rule	Iran	2016	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2016	only	-	Sep	21	0:00	0	S
+Rule	Iran	2017	2019	-	Mar	22	0:00	1:00	D
+Rule	Iran	2017	2019	-	Sep	22	0:00	0	S
+Rule	Iran	2020	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2020	only	-	Sep	21	0:00	0	S
+Rule	Iran	2021	2023	-	Mar	22	0:00	1:00	D
+Rule	Iran	2021	2023	-	Sep	22	0:00	0	S
+Rule	Iran	2024	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2024	only	-	Sep	21	0:00	0	S
+Rule	Iran	2025	2027	-	Mar	22	0:00	1:00	D
+Rule	Iran	2025	2027	-	Sep	22	0:00	0	S
+Rule	Iran	2028	2029	-	Mar	21	0:00	1:00	D
+Rule	Iran	2028	2029	-	Sep	21	0:00	0	S
+Rule	Iran	2030	2031	-	Mar	22	0:00	1:00	D
+Rule	Iran	2030	2031	-	Sep	22	0:00	0	S
+Rule	Iran	2032	2033	-	Mar	21	0:00	1:00	D
+Rule	Iran	2032	2033	-	Sep	21	0:00	0	S
+Rule	Iran	2034	2035	-	Mar	22	0:00	1:00	D
+Rule	Iran	2034	2035	-	Sep	22	0:00	0	S
+Rule	Iran	2036	2037	-	Mar	21	0:00	1:00	D
+Rule	Iran	2036	2037	-	Sep	21	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Tehran	3:25:44	-	LMT	1916
+			3:25:44	-	TMT	1946	# Tehran Mean Time
+			3:30	-	IRST	1977 Nov
+			4:00	Iran	IR%sT	1979
+			3:30	Iran	IR%sT
+
+
+# Iraq
+#
+# From Jonathan Lennox (2000-06-12):
+# An article in this week's Economist ("Inside the Saddam-free zone", p. 50 in
+# the U.S. edition) on the Iraqi Kurds contains a paragraph:
+# "The three northern provinces ... switched their clocks this spring and
+# are an hour ahead of Baghdad."
+#
+# But Rives McDow (2000-06-18) quotes a contact in Iraqi-Kurdistan as follows:
+# In the past, some Kurdish nationalists, as a protest to the Iraqi
+# Government, did not adhere to daylight saving time.  They referred
+# to daylight saving as Saddam time.  But, as of today, the time zone
+# in Iraqi-Kurdistan is on standard time with Baghdad, Iraq.
+#
+# So we'll ignore the Economist's claim.
+
+# From Steffen Thorsen (2008-03-10):
+# The cabinet in Iraq abolished DST last week, according to the following
+# news sources (in Arabic):
+# <a href="http://www.aljeeran.net/wesima_articles/news-20080305-98602.html">
+# http://www.aljeeran.net/wesima_articles/news-20080305-98602.html
+# </a>
+# <a href="http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10">
+# http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10
+# </a>
+#
+# We have published a short article in English about the change:
+# <a href="http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html">
+# http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Iraq	1982	only	-	May	1	0:00	1:00	D
+Rule	Iraq	1982	1984	-	Oct	1	0:00	0	S
+Rule	Iraq	1983	only	-	Mar	31	0:00	1:00	D
+Rule	Iraq	1984	1985	-	Apr	1	0:00	1:00	D
+Rule	Iraq	1985	1990	-	Sep	lastSun	1:00s	0	S
+Rule	Iraq	1986	1990	-	Mar	lastSun	1:00s	1:00	D
+# IATA SSIM (1991/1996) says Apr 1 12:01am UTC; guess the `:01' is a typo.
+# Shanks & Pottenger say Iraq did not observe DST 1992/1997; ignore this.
+#
+Rule	Iraq	1991	2007	-	Apr	 1	3:00s	1:00	D
+Rule	Iraq	1991	2007	-	Oct	 1	3:00s	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Baghdad	2:57:40	-	LMT	1890
+			2:57:36	-	BMT	1918	    # Baghdad Mean Time?
+			3:00	-	AST	1982 May
+			3:00	Iraq	A%sT
+
+
+###############################################################################
+
+# Israel
+
+# From Ephraim Silverberg (2001-01-11):
+#
+# I coined "IST/IDT" circa 1988.  Until then there were three
+# different abbreviations in use:
+#
+# JST  Jerusalem Standard Time [Danny Braniss, Hebrew University]
+# IZT  Israel Zonal (sic) Time [Prof. Haim Papo, Technion]
+# EEST Eastern Europe Standard Time [used by almost everyone else]
+#
+# Since timezones should be called by country and not capital cities,
+# I ruled out JST.  As Israel is in Asia Minor and not Eastern Europe,
+# EEST was equally unacceptable.  Since "zonal" was not compatible with
+# any other timezone abbreviation, I felt that 'IST' was the way to go
+# and, indeed, it has received almost universal acceptance in timezone
+# settings in Israeli computers.
+#
+# In any case, I am happy to share timezone abbreviations with India,
+# high on my favorite-country list (and not only because my wife's
+# family is from India).
+
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	1940	only	-	Jun	 1	0:00	1:00	D
+Rule	Zion	1942	1944	-	Nov	 1	0:00	0	S
+Rule	Zion	1943	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	1944	only	-	Apr	 1	0:00	1:00	D
+Rule	Zion	1945	only	-	Apr	16	0:00	1:00	D
+Rule	Zion	1945	only	-	Nov	 1	2:00	0	S
+Rule	Zion	1946	only	-	Apr	16	2:00	1:00	D
+Rule	Zion	1946	only	-	Nov	 1	0:00	0	S
+Rule	Zion	1948	only	-	May	23	0:00	2:00	DD
+Rule	Zion	1948	only	-	Sep	 1	0:00	1:00	D
+Rule	Zion	1948	1949	-	Nov	 1	2:00	0	S
+Rule	Zion	1949	only	-	May	 1	0:00	1:00	D
+Rule	Zion	1950	only	-	Apr	16	0:00	1:00	D
+Rule	Zion	1950	only	-	Sep	15	3:00	0	S
+Rule	Zion	1951	only	-	Apr	 1	0:00	1:00	D
+Rule	Zion	1951	only	-	Nov	11	3:00	0	S
+Rule	Zion	1952	only	-	Apr	20	2:00	1:00	D
+Rule	Zion	1952	only	-	Oct	19	3:00	0	S
+Rule	Zion	1953	only	-	Apr	12	2:00	1:00	D
+Rule	Zion	1953	only	-	Sep	13	3:00	0	S
+Rule	Zion	1954	only	-	Jun	13	0:00	1:00	D
+Rule	Zion	1954	only	-	Sep	12	0:00	0	S
+Rule	Zion	1955	only	-	Jun	11	2:00	1:00	D
+Rule	Zion	1955	only	-	Sep	11	0:00	0	S
+Rule	Zion	1956	only	-	Jun	 3	0:00	1:00	D
+Rule	Zion	1956	only	-	Sep	30	3:00	0	S
+Rule	Zion	1957	only	-	Apr	29	2:00	1:00	D
+Rule	Zion	1957	only	-	Sep	22	0:00	0	S
+Rule	Zion	1974	only	-	Jul	 7	0:00	1:00	D
+Rule	Zion	1974	only	-	Oct	13	0:00	0	S
+Rule	Zion	1975	only	-	Apr	20	0:00	1:00	D
+Rule	Zion	1975	only	-	Aug	31	0:00	0	S
+Rule	Zion	1985	only	-	Apr	14	0:00	1:00	D
+Rule	Zion	1985	only	-	Sep	15	0:00	0	S
+Rule	Zion	1986	only	-	May	18	0:00	1:00	D
+Rule	Zion	1986	only	-	Sep	 7	0:00	0	S
+Rule	Zion	1987	only	-	Apr	15	0:00	1:00	D
+Rule	Zion	1987	only	-	Sep	13	0:00	0	S
+Rule	Zion	1988	only	-	Apr	 9	0:00	1:00	D
+Rule	Zion	1988	only	-	Sep	 3	0:00	0	S
+
+# From Ephraim Silverberg
+# (1997-03-04, 1998-03-16, 1998-12-28, 2000-01-17, 2000-07-25, 2004-12-22,
+# and 2005-02-17):
+
+# According to the Office of the Secretary General of the Ministry of
+# Interior, there is NO set rule for Daylight-Savings/Standard time changes.
+# One thing is entrenched in law, however: that there must be at least 150
+# days of daylight savings time annually.  From 1993-1998, the change to
+# daylight savings time was on a Friday morning from midnight IST to
+# 1 a.m IDT; up until 1998, the change back to standard time was on a
+# Saturday night from midnight daylight savings time to 11 p.m. standard
+# time.  1996 is an exception to this rule where the change back to standard
+# time took place on Sunday night instead of Saturday night to avoid
+# conflicts with the Jewish New Year.  In 1999, the change to
+# daylight savings time was still on a Friday morning but from
+# 2 a.m. IST to 3 a.m. IDT; furthermore, the change back to standard time
+# was also on a Friday morning from 2 a.m. IDT to 1 a.m. IST for
+# 1999 only.  In the year 2000, the change to daylight savings time was
+# similar to 1999, but although the change back will be on a Friday, it
+# will take place from 1 a.m. IDT to midnight IST.  Starting in 2001, all
+# changes to/from will take place at 1 a.m. old time, but now there is no
+# rule as to what day of the week it will take place in as the start date
+# (except in 2003) is the night after the Passover Seder (i.e. the eve
+# of the 16th of Nisan in the lunar Hebrew calendar) and the end date
+# (except in 2002) is three nights before Yom Kippur [Day of Atonement]
+# (the eve of the 7th of Tishrei in the lunar Hebrew calendar).
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	1989	only	-	Apr	30	0:00	1:00	D
+Rule	Zion	1989	only	-	Sep	 3	0:00	0	S
+Rule	Zion	1990	only	-	Mar	25	0:00	1:00	D
+Rule	Zion	1990	only	-	Aug	26	0:00	0	S
+Rule	Zion	1991	only	-	Mar	24	0:00	1:00	D
+Rule	Zion	1991	only	-	Sep	 1	0:00	0	S
+Rule	Zion	1992	only	-	Mar	29	0:00	1:00	D
+Rule	Zion	1992	only	-	Sep	 6	0:00	0	S
+Rule	Zion	1993	only	-	Apr	 2	0:00	1:00	D
+Rule	Zion	1993	only	-	Sep	 5	0:00	0	S
+
+# The dates for 1994-1995 were obtained from Office of the Spokeswoman for the
+# Ministry of Interior, Jerusalem, Israel.  The spokeswoman can be reached by
+# calling the office directly at 972-2-6701447 or 972-2-6701448.
+
+# Rule	NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
+Rule	Zion	1994	only	-	Apr	 1	0:00	1:00	D
+Rule	Zion	1994	only	-	Aug	28	0:00	0	S
+Rule	Zion	1995	only	-	Mar	31	0:00	1:00	D
+Rule	Zion	1995	only	-	Sep	 3	0:00	0	S
+
+# The dates for 1996 were determined by the Minister of Interior of the
+# time, Haim Ramon.  The official announcement regarding 1996-1998
+# (with the dates for 1997-1998 no longer being relevant) can be viewed at:
+#
+#   ftp://ftp.cs.huji.ac.il/pub/tz/announcements/1996-1998.ramon.ps.gz
+#
+# The dates for 1997-1998 were altered by his successor, Rabbi Eli Suissa.
+#
+# The official announcements for the years 1997-1999 can be viewed at:
+#
+#   ftp://ftp.cs.huji.ac.il/pub/tz/announcements/YYYY.ps.gz
+#
+#       where YYYY is the relevant year.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	1996	only	-	Mar	15	0:00	1:00	D
+Rule	Zion	1996	only	-	Sep	16	0:00	0	S
+Rule	Zion	1997	only	-	Mar	21	0:00	1:00	D
+Rule	Zion	1997	only	-	Sep	14	0:00	0	S
+Rule	Zion	1998	only	-	Mar	20	0:00	1:00	D
+Rule	Zion	1998	only	-	Sep	 6	0:00	0	S
+Rule	Zion	1999	only	-	Apr	 2	2:00	1:00	D
+Rule	Zion	1999	only	-	Sep	 3	2:00	0	S
+
+# The Knesset Interior Committee has changed the dates for 2000 for
+# the third time in just over a year and have set new dates for the
+# years 2001-2004 as well.
+#
+# The official announcement for the start date of 2000 can be viewed at:
+#
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-start.ps.gz
+#
+# The official announcement for the end date of 2000 and the dates
+# for the years 2001-2004 can be viewed at:
+#
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-2004.ps.gz
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	2000	only	-	Apr	14	2:00	1:00	D
+Rule	Zion	2000	only	-	Oct	 6	1:00	0	S
+Rule	Zion	2001	only	-	Apr	 9	1:00	1:00	D
+Rule	Zion	2001	only	-	Sep	24	1:00	0	S
+Rule	Zion	2002	only	-	Mar	29	1:00	1:00	D
+Rule	Zion	2002	only	-	Oct	 7	1:00	0	S
+Rule	Zion	2003	only	-	Mar	28	1:00	1:00	D
+Rule	Zion	2003	only	-	Oct	 3	1:00	0	S
+Rule	Zion	2004	only	-	Apr	 7	1:00	1:00	D
+Rule	Zion	2004	only	-	Sep	22	1:00	0	S
+
+# The proposed law agreed upon by the Knesset Interior Committee on
+# 2005-02-14 is that, for 2005 and beyond, DST starts at 02:00 the
+# last Friday before April 2nd (i.e. the last Friday in March or April
+# 1st itself if it falls on a Friday) and ends at 02:00 on the Saturday
+# night _before_ the fast of Yom Kippur.
+#
+# Those who can read Hebrew can view the announcement at:
+#
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2005+beyond.ps
+
+# From Paul Eggert (2012-10-26):
+# I used Ephraim Silverberg's dst-israel.el program
+# <ftp://ftp.cs.huji.ac.il/pub/tz/software/dst-israel.el> (2005-02-20)
+# along with Ed Reingold's cal-hebrew in GNU Emacs 21.4,
+# to generate the transitions from 2005 through 2012.
+# (I replaced "lastFri" with "Fri>=26" by hand.)
+# The spring transitions all correspond to the following Rule:
+#
+# Rule	Zion	2005	2012	-	Mar	Fri>=26	2:00	1:00	D
+#
+# but older zic implementations (e.g., Solaris 8) do not support
+# "Fri>=26" to mean April 1 in years like 2005, so for now we list the
+# springtime transitions explicitly.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	2005	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	2005	only	-	Oct	 9	2:00	0	S
+Rule	Zion	2006	2010	-	Mar	Fri>=26	2:00	1:00	D
+Rule	Zion	2006	only	-	Oct	 1	2:00	0	S
+Rule	Zion	2007	only	-	Sep	16	2:00	0	S
+Rule	Zion	2008	only	-	Oct	 5	2:00	0	S
+Rule	Zion	2009	only	-	Sep	27	2:00	0	S
+Rule	Zion	2010	only	-	Sep	12	2:00	0	S
+Rule	Zion	2011	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	2011	only	-	Oct	 2	2:00	0	S
+Rule	Zion	2012	only	-	Mar	Fri>=26	2:00	1:00	D
+Rule	Zion	2012	only	-	Sep	23	2:00	0	S
+
+# From Ephraim Silverberg (2012-10-18):
+
+# Yesterday, the Interior Ministry Committee, after more than a year
+# past, approved sending the proposed June 2011 changes to the Time
+# Decree Law back to the Knesset for second and third (final) votes
+# before the upcoming elections on Jan. 22, 2013.  Hence, although the
+# changes are not yet law, they are expected to be so before February 2013.
+#
+# As of 2013, DST starts at 02:00 on the Friday before the last Sunday in March.
+# DST ends at 02:00 on the first Sunday after October 1, unless it occurs on the
+# second day of the Jewish Rosh Hashana holiday, in which case DST ends a day
+# later (i.e. at 02:00 the first Monday after October 2).
+# [Rosh Hashana holidays are factored in until 2100.]
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	2013	max	-	Mar	Fri>=23	2:00	1:00	D
+Rule	Zion	2013	2026	-	Oct	Sun>=2	2:00	0	S
+Rule	Zion	2027	only	-	Oct	Mon>=3	2:00	0	S
+Rule	Zion	2028	max	-	Oct	Sun>=2	2:00	0	S
+# The following rules are commented out for now, as they break older
+# versions of zic that support only signed 32-bit timestamps, i.e.,
+# through 2038-01-19 03:14:07 UTC.
+#Rule	Zion	2028	2053	-	Oct	Sun>=2	2:00	0	S
+#Rule	Zion	2054	only	-	Oct	Mon>=3	2:00	0	S
+#Rule	Zion	2055	2080	-	Oct	Sun>=2	2:00	0	S
+#Rule	Zion	2081	only	-	Oct	Mon>=3	2:00	0	S
+#Rule	Zion	2082	max	-	Oct	Sun>=2	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Jerusalem	2:20:56 -	LMT	1880
+			2:20:40	-	JMT	1918	# Jerusalem Mean Time?
+			2:00	Zion	I%sT
+
+
+
+###############################################################################
+
+# Japan
+
+# `9:00' and `JST' is from Guy Harris.
+
+# From Paul Eggert (1995-03-06):
+# Today's _Asahi Evening News_ (page 4) reports that Japan had
+# daylight saving between 1948 and 1951, but ``the system was discontinued
+# because the public believed it would lead to longer working hours.''
+
+# From Mayumi Negishi in the 2005-08-10 Japan Times
+# <http://www.japantimes.co.jp/cgi-bin/getarticle.pl5?nn20050810f2.htm>:
+# Occupation authorities imposed daylight-saving time on Japan on
+# [1948-05-01]....  But lack of prior debate and the execution of
+# daylight-saving time just three days after the bill was passed generated
+# deep hatred of the concept....  The Diet unceremoniously passed a bill to
+# dump the unpopular system in October 1951, less than a month after the San
+# Francisco Peace Treaty was signed.  (A government poll in 1951 showed 53%
+# of the Japanese wanted to scrap daylight-saving time, as opposed to 30% who
+# wanted to keep it.)
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that DST in Japan during those years was as follows:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Japan	1948	only	-	May	Sun>=1	2:00	1:00	D
+Rule	Japan	1948	1951	-	Sep	Sat>=8	2:00	0	S
+Rule	Japan	1949	only	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Japan	1950	1951	-	May	Sun>=1	2:00	1:00	D
+# but the only locations using it (for birth certificates, presumably, since
+# their audience is astrologers) were US military bases.  For now, assume
+# that for most purposes daylight-saving time was observed; otherwise, what
+# would have been the point of the 1951 poll?
+
+# From Hideyuki Suzuki (1998-11-09):
+# 'Tokyo' usually stands for the former location of Tokyo Astronomical
+# Observatory: E 139 44' 40".90 (9h 18m 58s.727), N 35 39' 16".0.
+# This data is from 'Rika Nenpyou (Chronological Scientific Tables) 1996'
+# edited by National Astronomical Observatory of Japan....
+# JST (Japan Standard Time) has been used since 1888-01-01 00:00 (JST).
+# The law is enacted on 1886-07-07.
+
+# From Hideyuki Suzuki (1998-11-16):
+# The ordinance No. 51 (1886) established "standard time" in Japan,
+# which stands for the time on E 135 degree.
+# In the ordinance No. 167 (1895), "standard time" was renamed to "central
+# standard time".  And the same ordinance also established "western standard
+# time", which stands for the time on E 120 degree....  But "western standard
+# time" was abolished in the ordinance No. 529 (1937).  In the ordinance No.
+# 167, there is no mention regarding for what place western standard time is
+# standard....
+#
+# I wrote "ordinance" above, but I don't know how to translate.
+# In Japanese it's "chokurei", which means ordinance from emperor.
+
+# Shanks & Pottenger claim JST in use since 1896, and that a few
+# places (e.g. Ishigaki) use +0800; go with Suzuki.  Guess that all
+# ordinances took effect on Jan 1.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Tokyo	9:18:59	-	LMT	1887 Dec 31 15:00u
+			9:00	-	JST	1896
+			9:00	-	CJT	1938
+			9:00	Japan	J%sT
+# Since 1938, all Japanese possessions have been like Asia/Tokyo.
+
+# Jordan
+#
+# From <a href="http://star.arabia.com/990701/JO9.html">
+# Jordan Week (1999-07-01) </a> via Steffen Thorsen (1999-09-09):
+# Clocks in Jordan were forwarded one hour on Wednesday at midnight,
+# in accordance with the government's decision to implement summer time
+# all year round.
+#
+# From <a href="http://star.arabia.com/990930/JO9.html">
+# Jordan Week (1999-09-30) </a> via Steffen Thorsen (1999-11-09):
+# Winter time starts today Thursday, 30 September. Clocks will be turned back
+# by one hour.  This is the latest government decision and it's final!
+# The decision was taken because of the increase in working hours in
+# government's departments from six to seven hours.
+#
+# From Paul Eggert (2005-11-22):
+# Starting 2003 transitions are from Steffen Thorsen's web site timeanddate.com.
+#
+# From Steffen Thorsen (2005-11-23):
+# For Jordan I have received multiple independent user reports every year
+# about DST end dates, as the end-rule is different every year.
+#
+# From Steffen Thorsen (2006-10-01), after a heads-up from Hilal Malawi:
+# http://www.petranews.gov.jo/nepras/2006/Sep/05/4000.htm
+# "Jordan will switch to winter time on Friday, October 27".
+#
+
+# From Phil Pizzey (2009-04-02):
+# ...I think I may have spotted an error in the timezone data for
+# Jordan.
+# The current (2009d) asia file shows Jordan going to daylight
+# saving
+# time on the last Thursday in March.
+#
+# Rule  Jordan      2000  max	-  Mar   lastThu     0:00s 1:00  S
+#
+# However timeanddate.com, which I usually find reliable, shows Jordan
+# going to daylight saving time on the last Friday in March since 2002.
+# Please see
+# <a href="http://www.timeanddate.com/worldclock/timezone.html?n=11">
+# http://www.timeanddate.com/worldclock/timezone.html?n=11
+# </a>
+
+# From Steffen Thorsen (2009-04-02):
+# This single one might be good enough, (2009-03-24, Arabic):
+# <a href="http://petra.gov.jo/Artical.aspx?Lng=2&Section=8&Artical=95279">
+# http://petra.gov.jo/Artical.aspx?Lng=2&Section=8&Artical=95279
+# </a>
+#
+# Google's translation:
+#
+# > The Council of Ministers decided in 2002 to adopt the principle of timely
+# > submission of the summer at 60 minutes as of midnight on the last Thursday
+# > of the month of March of each year.
+#
+# So - this means the midnight between Thursday and Friday since 2002.
+
+# From Arthur David Olson (2009-04-06):
+# We still have Jordan switching to DST on Thursdays in 2000 and 2001.
+
+# From Steffen Thorsen (2012-10-25):
+# Yesterday the government in Jordan announced that they will not
+# switch back to standard time this winter, so the will stay on DST
+# until about the same time next year (at least).
+# http://www.petra.gov.jo/Public_News/Nws_NewsDetails.aspx?NewsID=88950
+#
+# From Paul Eggert (2012-10-25):
+# For now, assume this is just a one-year measure.  If it becomes
+# permanent, we should move Jordan from EET to AST effective tomorrow.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Jordan	1973	only	-	Jun	6	0:00	1:00	S
+Rule	Jordan	1973	1975	-	Oct	1	0:00	0	-
+Rule	Jordan	1974	1977	-	May	1	0:00	1:00	S
+Rule	Jordan	1976	only	-	Nov	1	0:00	0	-
+Rule	Jordan	1977	only	-	Oct	1	0:00	0	-
+Rule	Jordan	1978	only	-	Apr	30	0:00	1:00	S
+Rule	Jordan	1978	only	-	Sep	30	0:00	0	-
+Rule	Jordan	1985	only	-	Apr	1	0:00	1:00	S
+Rule	Jordan	1985	only	-	Oct	1	0:00	0	-
+Rule	Jordan	1986	1988	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Jordan	1986	1990	-	Oct	Fri>=1	0:00	0	-
+Rule	Jordan	1989	only	-	May	8	0:00	1:00	S
+Rule	Jordan	1990	only	-	Apr	27	0:00	1:00	S
+Rule	Jordan	1991	only	-	Apr	17	0:00	1:00	S
+Rule	Jordan	1991	only	-	Sep	27	0:00	0	-
+Rule	Jordan	1992	only	-	Apr	10	0:00	1:00	S
+Rule	Jordan	1992	1993	-	Oct	Fri>=1	0:00	0	-
+Rule	Jordan	1993	1998	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Jordan	1994	only	-	Sep	Fri>=15	0:00	0	-
+Rule	Jordan	1995	1998	-	Sep	Fri>=15	0:00s	0	-
+Rule	Jordan	1999	only	-	Jul	 1	0:00s	1:00	S
+Rule	Jordan	1999	2002	-	Sep	lastFri	0:00s	0	-
+Rule	Jordan	2000	2001	-	Mar	lastThu	0:00s	1:00	S
+Rule	Jordan	2002	max	-	Mar	lastThu	24:00	1:00	S
+Rule	Jordan	2003	only	-	Oct	24	0:00s	0	-
+Rule	Jordan	2004	only	-	Oct	15	0:00s	0	-
+Rule	Jordan	2005	only	-	Sep	lastFri	0:00s	0	-
+Rule	Jordan	2006	2011	-	Oct	lastFri	0:00s	0	-
+Rule	Jordan	2013	max	-	Oct	lastFri	0:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Amman	2:23:44 -	LMT	1931
+			2:00	Jordan	EE%sT
+
+
+# Kazakhstan
+
+# From Paul Eggert (1996-11-22):
+# Andrew Evtichov (1996-04-13) writes that Kazakhstan
+# stayed in sync with Moscow after 1990, and that Aqtobe (formerly Aktyubinsk)
+# and Aqtau (formerly Shevchenko) are the largest cities in their zones.
+# Guess that Aqtau and Aqtobe diverged in 1995, since that's the first time
+# IATA SSIM mentions a third time zone in Kazakhstan.
+
+# From Paul Eggert (2006-03-22):
+# German Iofis, ELSI, Almaty (2001-10-09) reports that Kazakhstan uses
+# RussiaAsia rules, instead of switching at 00:00 as the IATA has it.
+# Go with Shanks & Pottenger, who have them always using RussiaAsia rules.
+# Also go with the following claims of Shanks & Pottenger:
+#
+# - Kazakhstan did not observe DST in 1991.
+# - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00.
+# - Oral switched from +5:00 to +4:00 in spring 1989.
+
+# <a href="http://www.kazsociety.org.uk/news/2005/03/30.htm">
+# From Kazakhstan Embassy's News Bulletin #11 (2005-03-21):
+# </a>
+# The Government of Kazakhstan passed a resolution March 15 abolishing
+# daylight saving time citing lack of economic benefits and health
+# complications coupled with a decrease in productivity.
+#
+# From Branislav Kojic (in Astana) via Gwillim Law (2005-06-28):
+# ... what happened was that the former Kazakhstan Eastern time zone
+# was "blended" with the Central zone.  Therefore, Kazakhstan now has
+# two time zones, and difference between them is one hour.  The zone
+# closer to UTC is the former Western zone (probably still called the
+# same), encompassing four provinces in the west: Aqtobe, Atyrau,
+# Mangghystau, and West Kazakhstan.  The other zone encompasses
+# everything else....  I guess that would make Kazakhstan time zones
+# de jure UTC+5 and UTC+6 respectively.
+
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
+Zone	Asia/Almaty	5:07:48 -	LMT	1924 May  2 # or Alma-Ata
+			5:00	-	ALMT	1930 Jun 21 # Alma-Ata Time
+			6:00 RussiaAsia ALM%sT	1991
+			6:00	-	ALMT	1992
+			6:00 RussiaAsia	ALM%sT	2005 Mar 15
+			6:00	-	ALMT
+# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.)
+Zone	Asia/Qyzylorda	4:21:52 -	LMT	1924 May  2
+			4:00	-	KIZT	1930 Jun 21 # Kizilorda Time
+			5:00	-	KIZT	1981 Apr  1
+			5:00	1:00	KIZST	1981 Oct  1
+			6:00	-	KIZT	1982 Apr  1
+			5:00 RussiaAsia	KIZ%sT	1991
+			5:00	-	KIZT	1991 Dec 16 # independence
+			5:00	-	QYZT	1992 Jan 19 2:00
+			6:00 RussiaAsia	QYZ%sT	2005 Mar 15
+			6:00	-	QYZT
+# Aqtobe (aka Aktobe, formerly Akt'ubinsk)
+Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
+			4:00	-	AKTT	1930 Jun 21 # Aktyubinsk Time
+			5:00	-	AKTT	1981 Apr  1
+			5:00	1:00	AKTST	1981 Oct  1
+			6:00	-	AKTT	1982 Apr  1
+			5:00 RussiaAsia	AKT%sT	1991
+			5:00	-	AKTT	1991 Dec 16 # independence
+			5:00 RussiaAsia	AQT%sT	2005 Mar 15 # Aqtobe Time
+			5:00	-	AQTT
+# Mangghystau
+# Aqtau was not founded until 1963, but it represents an inhabited region,
+# so include time stamps before 1963.
+Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2
+			4:00	-	FORT	1930 Jun 21 # Fort Shevchenko T
+			5:00	-	FORT	1963
+			5:00	-	SHET	1981 Oct  1 # Shevchenko Time
+			6:00	-	SHET	1982 Apr  1
+			5:00 RussiaAsia	SHE%sT	1991
+			5:00	-	SHET	1991 Dec 16 # independence
+			5:00 RussiaAsia	AQT%sT	1995 Mar lastSun 2:00 # Aqtau Time
+			4:00 RussiaAsia	AQT%sT	2005 Mar 15
+			5:00	-	AQTT
+# West Kazakhstan
+Zone	Asia/Oral	3:25:24	-	LMT	1924 May  2 # or Ural'sk
+			4:00	-	URAT	1930 Jun 21 # Ural'sk time
+			5:00	-	URAT	1981 Apr  1
+			5:00	1:00	URAST	1981 Oct  1
+			6:00	-	URAT	1982 Apr  1
+			5:00 RussiaAsia	URA%sT	1989 Mar 26 2:00
+			4:00 RussiaAsia	URA%sT	1991
+			4:00	-	URAT	1991 Dec 16 # independence
+			4:00 RussiaAsia	ORA%sT	2005 Mar 15 # Oral Time
+			5:00	-	ORAT
+
+# Kyrgyzstan (Kirgizstan)
+# Transitions through 1991 are from Shanks & Pottenger.
+
+# From Paul Eggert (2005-08-15):
+# According to an article dated today in the Kyrgyzstan Development Gateway
+# <http://eng.gateway.kg/cgi-bin/page.pl?id=1&story_name=doc9979.shtml>
+# Kyrgyzstan is canceling the daylight saving time system.  I take the article
+# to mean that they will leave their clocks at 6 hours ahead of UTC.
+# From Malik Abdugaliev (2005-09-21):
+# Our government cancels daylight saving time 6th of August 2005.
+# From 2005-08-12 our GMT-offset is +6, w/o any daylight saving.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Kyrgyz	1992	1996	-	Apr	Sun>=7	0:00s	1:00	S
+Rule	Kyrgyz	1992	1996	-	Sep	lastSun	0:00	0	-
+Rule	Kyrgyz	1997	2005	-	Mar	lastSun	2:30	1:00	S
+Rule	Kyrgyz	1997	2004	-	Oct	lastSun	2:30	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Bishkek	4:58:24 -	LMT	1924 May  2
+			5:00	-	FRUT	1930 Jun 21 # Frunze Time
+			6:00 RussiaAsia FRU%sT	1991 Mar 31 2:00s
+			5:00	1:00	FRUST	1991 Aug 31 2:00 # independence
+			5:00	Kyrgyz	KG%sT	2005 Aug 12    # Kyrgyzstan Time
+			6:00	-	KGT
+
+###############################################################################
+
+# Korea (North and South)
+
+# From Annie I. Bang (2006-07-10) in
+# <http://www.koreaherald.co.kr/SITE/data/html_dir/2006/07/10/200607100012.asp>:
+# The Ministry of Commerce, Industry and Energy has already
+# commissioned a research project [to reintroduce DST] and has said
+# the system may begin as early as 2008....  Korea ran a daylight
+# saving program from 1949-61 but stopped it during the 1950-53 Korean War.
+
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	ROK	1960	only	-	May	15	0:00	1:00	D
+Rule	ROK	1960	only	-	Sep	13	0:00	0	S
+Rule	ROK	1987	1988	-	May	Sun>=8	0:00	1:00	D
+Rule	ROK	1987	1988	-	Oct	Sun>=8	0:00	0	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Seoul	8:27:52	-	LMT	1890
+			8:30	-	KST	1904 Dec
+			9:00	-	KST	1928
+			8:30	-	KST	1932
+			9:00	-	KST	1954 Mar 21
+			8:00	ROK	K%sT	1961 Aug 10
+			8:30	-	KST	1968 Oct
+			9:00	ROK	K%sT
+Zone	Asia/Pyongyang	8:23:00 -	LMT	1890
+			8:30	-	KST	1904 Dec
+			9:00	-	KST	1928
+			8:30	-	KST	1932
+			9:00	-	KST	1954 Mar 21
+			8:00	-	KST	1961 Aug 10
+			9:00	-	KST
+
+###############################################################################
+
+# Kuwait
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# From the Arab Times (2007-03-14):
+# The Civil Service Commission (CSC) has approved a proposal forwarded
+# by MP Ahmad Baqer on implementing the daylight saving time (DST) in
+# Kuwait starting from April until the end of Sept this year, reports Al-Anba.
+# <http://www.arabtimesonline.com/arabtimes/kuwait/Viewdet.asp?ID=9950>.
+# From Paul Eggert (2007-03-29):
+# We don't know the details, or whether the approval means it'll happen,
+# so for now we assume no DST.
+Zone	Asia/Kuwait	3:11:56 -	LMT	1950
+			3:00	-	AST
+
+# Laos
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Vientiane	6:50:24 -	LMT	1906 Jun  9 # or Viangchan
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
+			7:00	-	ICT	1912 May
+			8:00	-	ICT	1931 May
+			7:00	-	ICT
+
+# Lebanon
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Lebanon	1920	only	-	Mar	28	0:00	1:00	S
+Rule	Lebanon	1920	only	-	Oct	25	0:00	0	-
+Rule	Lebanon	1921	only	-	Apr	3	0:00	1:00	S
+Rule	Lebanon	1921	only	-	Oct	3	0:00	0	-
+Rule	Lebanon	1922	only	-	Mar	26	0:00	1:00	S
+Rule	Lebanon	1922	only	-	Oct	8	0:00	0	-
+Rule	Lebanon	1923	only	-	Apr	22	0:00	1:00	S
+Rule	Lebanon	1923	only	-	Sep	16	0:00	0	-
+Rule	Lebanon	1957	1961	-	May	1	0:00	1:00	S
+Rule	Lebanon	1957	1961	-	Oct	1	0:00	0	-
+Rule	Lebanon	1972	only	-	Jun	22	0:00	1:00	S
+Rule	Lebanon	1972	1977	-	Oct	1	0:00	0	-
+Rule	Lebanon	1973	1977	-	May	1	0:00	1:00	S
+Rule	Lebanon	1978	only	-	Apr	30	0:00	1:00	S
+Rule	Lebanon	1978	only	-	Sep	30	0:00	0	-
+Rule	Lebanon	1984	1987	-	May	1	0:00	1:00	S
+Rule	Lebanon	1984	1991	-	Oct	16	0:00	0	-
+Rule	Lebanon	1988	only	-	Jun	1	0:00	1:00	S
+Rule	Lebanon	1989	only	-	May	10	0:00	1:00	S
+Rule	Lebanon	1990	1992	-	May	1	0:00	1:00	S
+Rule	Lebanon	1992	only	-	Oct	4	0:00	0	-
+Rule	Lebanon	1993	max	-	Mar	lastSun	0:00	1:00	S
+Rule	Lebanon	1993	1998	-	Sep	lastSun	0:00	0	-
+Rule	Lebanon	1999	max	-	Oct	lastSun	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Beirut	2:22:00 -	LMT	1880
+			2:00	Lebanon	EE%sT
+
+# Malaysia
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NBorneo	1935	1941	-	Sep	14	0:00	0:20	TS # one-Third Summer
+Rule	NBorneo	1935	1941	-	Dec	14	0:00	0	-
+#
+# peninsular Malaysia
+# The data here are taken from Mok Ly Yng (2003-10-30)
+# <http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html>.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Asia/Kuala_Lumpur	6:46:46 -	LMT	1901 Jan  1
+			6:55:25	-	SMT	1905 Jun  1 # Singapore M.T.
+			7:00	-	MALT	1933 Jan  1 # Malaya Time
+			7:00	0:20	MALST	1936 Jan  1
+			7:20	-	MALT	1941 Sep  1
+			7:30	-	MALT	1942 Feb 16
+			9:00	-	JST	1945 Sep 12
+			7:30	-	MALT	1982 Jan  1
+			8:00	-	MYT	# Malaysia Time
+# Sabah & Sarawak
+# From Paul Eggert (2006-03-22):
+# The data here are mostly from Shanks & Pottenger, but the 1942, 1945 and 1982
+# transition dates are from Mok Ly Yng.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Asia/Kuching	7:21:20	-	LMT	1926 Mar
+			7:30	-	BORT	1933	# Borneo Time
+			8:00	NBorneo	BOR%sT	1942 Feb 16
+			9:00	-	JST	1945 Sep 12
+			8:00	-	BORT	1982 Jan  1
+			8:00	-	MYT
+
+# Maldives
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Maldives	4:54:00 -	LMT	1880	# Male
+			4:54:00	-	MMT	1960	# Male Mean Time
+			5:00	-	MVT		# Maldives Time
+
+# Mongolia
+
+# Shanks & Pottenger say that Mongolia has three time zones, but
+# usno1995 and the CIA map Standard Time Zones of the World (2005-03)
+# both say that it has just one.
+
+# From Oscar van Vlijmen (1999-12-11):
+# <a href="http://www.mongoliatourism.gov.mn/general.htm">
+# General Information Mongolia
+# </a> (1999-09)
+# "Time: Mongolia has two time zones. Three westernmost provinces of
+# Bayan-Ulgii, Uvs, and Hovd are one hour earlier than the capital city, and
+# the rest of the country follows the Ulaanbaatar time, which is UTC/GMT plus
+# eight hours."
+
+# From Rives McDow (1999-12-13):
+# Mongolia discontinued the use of daylight savings time in 1999; 1998
+# being the last year it was implemented.  The dates of implementation I am
+# unsure of, but most probably it was similar to Russia, except for the time
+# of implementation may have been different....
+# Some maps in the past have indicated that there was an additional time
+# zone in the eastern part of Mongolia, including the provinces of Dornod,
+# Suhbaatar, and possibly Khentij.
+
+# From Paul Eggert (1999-12-15):
+# Naming and spelling is tricky in Mongolia.
+# We'll use Hovd (also spelled Chovd and Khovd) to represent the west zone;
+# the capital of the Hovd province is sometimes called Hovd, sometimes Dund-Us,
+# and sometimes Jirgalanta (with variant spellings), but the name Hovd
+# is good enough for our purposes.
+
+# From Rives McDow (2001-05-13):
+# In addition to Mongolia starting daylight savings as reported earlier
+# (adopted DST on 2001-04-27 02:00 local time, ending 2001-09-28),
+# there are three time zones.
+#
+# Provinces [at 7:00]: Bayan-ulgii, Uvs, Khovd, Zavkhan, Govi-Altai
+# Provinces [at 8:00]: Khovsgol, Bulgan, Arkhangai, Khentii, Tov,
+#	Bayankhongor, Ovorkhangai, Dundgovi, Dornogovi, Omnogovi
+# Provinces [at 9:00]: Dornod, Sukhbaatar
+#
+# [The province of Selenge is omitted from the above lists.]
+
+# From Ganbold Ts., Ulaanbaatar (2004-04-17):
+# Daylight saving occurs at 02:00 local time last Saturday of March.
+# It will change back to normal at 02:00 local time last Saturday of
+# September.... As I remember this rule was changed in 2001.
+#
+# From Paul Eggert (2004-04-17):
+# For now, assume Rives McDow's informant got confused about Friday vs
+# Saturday, and that his 2001 dates should have 1 added to them.
+
+# From Paul Eggert (2005-07-26):
+# We have wildly conflicting information about Mongolia's time zones.
+# Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says
+# there is only one time zone and that DST is observed, citing Microsoft
+# Windows XP as the source.  Risto Nykanen (2005-05-16) reports that
+# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST.
+# Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in
+# Washington, DC says there are two time zones, with DST observed.
+# He also found
+# <http://ubpost.mongolnews.mn/index.php?subaction=showcomments&id=1111634894&archive=&start_from=&ucat=1&>
+# which also says that there is DST, and which has a comment by "Toddius"
+# (2005-03-31 06:05 +0700) saying "Mongolia actually has 3.5 time zones.
+# The West (OLGII) is +7 GMT, most of the country is ULAT is +8 GMT
+# and some Eastern provinces are +9 GMT but Sukhbaatar Aimag is SUHK +8.5 GMT.
+# The SUKH timezone is new this year, it is one of the few things the
+# parliament passed during the tumultuous winter session."
+# For now, let's ignore this information, until we have more confirmation.
+
+# From Ganbold Ts. (2007-02-26):
+# Parliament of Mongolia has just changed the daylight-saving rule in February.
+# They decided not to adopt daylight-saving time....
+# http://www.mongolnews.mn/index.php?module=unuudur&sec=view&id=15742
+
+# From Deborah Goldsmith (2008-03-30):
+# We received a bug report claiming that the tz database UTC offset for
+# Asia/Choibalsan (GMT+09:00) is incorrect, and that it should be GMT
+# +08:00 instead. Different sources appear to disagree with the tz
+# database on this, e.g.:
+#
+# <a href="http://www.timeanddate.com/worldclock/city.html?n=1026">
+# http://www.timeanddate.com/worldclock/city.html?n=1026
+# </a>
+# <a href="http://www.worldtimeserver.com/current_time_in_MN.aspx">
+# http://www.worldtimeserver.com/current_time_in_MN.aspx
+# </a>
+#
+# both say GMT+08:00.
+
+# From Steffen Thorsen (2008-03-31):
+# eznis airways, which operates several domestic flights, has a flight
+# schedule here:
+# <a href="http://www.eznis.com/Container.jsp?id=112">
+# http://www.eznis.com/Container.jsp?id=112
+# </a>
+# (click the English flag for English)
+#
+# There it appears that flights between Choibalsan and Ulaanbatar arrive
+# about 1:35 - 1:50 hours later in local clock time, no matter the
+# direction, while Ulaanbaatar-Khvod takes 2 hours in the Eastern
+# direction and 3:35 back, which indicates that Ulaanbatar and Khvod are
+# in different time zones (like we know about), while Choibalsan and
+# Ulaanbatar are in the same time zone (correction needed).
+
+# From Arthur David Olson (2008-05-19):
+# Assume that Choibalsan is indeed offset by 8:00.
+# XXX--in the absence of better information, assume that transition
+# was at the start of 2008-03-31 (the day of Steffen Thorsen's report);
+# this is almost surely wrong.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Mongol	1983	1984	-	Apr	1	0:00	1:00	S
+Rule	Mongol	1983	only	-	Oct	1	0:00	0	-
+# Shanks & Pottenger and IATA SSIM say 1990s switches occurred at 00:00,
+# but McDow says the 2001 switches occurred at 02:00.  Also, IATA SSIM
+# (1996-09) says 1996-10-25.  Go with Shanks & Pottenger through 1998.
+#
+# Shanks & Pottenger say that the Sept. 1984 through Sept. 1990 switches
+# in Choibalsan (more precisely, in Dornod and Sukhbaatar) took place
+# at 02:00 standard time, not at 00:00 local time as in the rest of
+# the country.  That would be odd, and possibly is a result of their
+# correction of 02:00 (in the previous edition) not being done correctly
+# in the latest edition; so ignore it for now.
+
+Rule	Mongol	1985	1998	-	Mar	lastSun	0:00	1:00	S
+Rule	Mongol	1984	1998	-	Sep	lastSun	0:00	0	-
+# IATA SSIM (1999-09) says Mongolia no longer observes DST.
+Rule	Mongol	2001	only	-	Apr	lastSat	2:00	1:00	S
+Rule	Mongol	2001	2006	-	Sep	lastSat	2:00	0	-
+Rule	Mongol	2002	2006	-	Mar	lastSat	2:00	1:00	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Hovd, a.k.a. Chovd, Dund-Us, Dzhargalant, Khovd, Jirgalanta
+Zone	Asia/Hovd	6:06:36 -	LMT	1905 Aug
+			6:00	-	HOVT	1978	# Hovd Time
+			7:00	Mongol	HOV%sT
+# Ulaanbaatar, a.k.a. Ulan Bataar, Ulan Bator, Urga
+Zone	Asia/Ulaanbaatar 7:07:32 -	LMT	1905 Aug
+			7:00	-	ULAT	1978	# Ulaanbaatar Time
+			8:00	Mongol	ULA%sT
+# Choibalsan, a.k.a. Bajan Tuemen, Bajan Tumen, Chojbalsan,
+# Choybalsan, Sanbejse, Tchoibalsan
+Zone	Asia/Choibalsan	7:38:00 -	LMT	1905 Aug
+			7:00	-	ULAT	1978
+			8:00	-	ULAT	1983 Apr
+			9:00	Mongol	CHO%sT	2008 Mar 31 # Choibalsan Time
+			8:00	Mongol	CHO%sT
+
+# Nepal
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Kathmandu	5:41:16 -	LMT	1920
+			5:30	-	IST	1986
+			5:45	-	NPT	# Nepal Time
+
+# Oman
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Muscat	3:54:20 -	LMT	1920
+			4:00	-	GST
+
+# Pakistan
+
+# From Rives McDow (2002-03-13):
+# I have been advised that Pakistan has decided to adopt dst on a
+# TRIAL basis for one year, starting 00:01 local time on April 7, 2002
+# and ending at 00:01 local time October 6, 2002.  This is what I was
+# told, but I believe that the actual time of change may be 00:00; the
+# 00:01 was to make it clear which day it was on.
+
+# From Paul Eggert (2002-03-15):
+# Jesper Norgaard found this URL:
+# http://www.pak.gov.pk/public/news/app/app06_dec.htm
+# (dated 2001-12-06) which says that the Cabinet adopted a scheme "to
+# advance the clocks by one hour on the night between the first
+# Saturday and Sunday of April and revert to the original position on
+# 15th October each year".  This agrees with McDow's 04-07 at 00:00,
+# but disagrees about the October transition, and makes it sound like
+# it's not on a trial basis.  Also, the "between the first Saturday
+# and Sunday of April" phrase, if taken literally, means that the
+# transition takes place at 00:00 on the first Sunday on or after 04-02.
+
+# From Paul Eggert (2003-02-09):
+# DAWN <http://www.dawn.com/2002/10/06/top13.htm> reported on 2002-10-05
+# that 2002 DST ended that day at midnight.  Go with McDow for now.
+
+# From Steffen Thorsen (2003-03-14):
+# According to http://www.dawn.com/2003/03/07/top15.htm
+# there will be no DST in Pakistan this year:
+#
+# ISLAMABAD, March 6: Information and Media Development Minister Sheikh
+# Rashid Ahmed on Thursday said the cabinet had reversed a previous
+# decision to advance clocks by one hour in summer and put them back by
+# one hour in winter with the aim of saving light hours and energy.
+#
+# The minister told a news conference that the experiment had rather
+# shown 8 per cent higher consumption of electricity.
+
+# From Alex Krivenyshev (2008-05-15):
+#
+# Here is an article that Pakistan plan to introduce Daylight Saving Time
+# on June 1, 2008 for 3 months.
+#
+# "... The federal cabinet on Wednesday announced a new conservation plan to help
+# reduce load shedding by approving the closure of commercial centres at 9pm and
+# moving clocks forward by one hour for the next three months.
+# ...."
+#
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html">
+# http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html
+# </a>
+# OR
+# <a href="http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4">
+# http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4
+# </a>
+
+# From Arthur David Olson (2008-05-19):
+# XXX--midnight transitions is a guess; 2008 only is a guess.
+
+# From Alexander Krivenyshev (2008-08-28):
+# Pakistan government has decided to keep the watches one-hour advanced
+# for another 2 months--plan to return to Standard Time on October 31
+# instead of August 31.
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html
+# </a>
+# OR
+# <a href="http://dailymailnews.com/200808/28/news/dmbrn03.html">
+# http://dailymailnews.com/200808/28/news/dmbrn03.html
+# </a>
+
+# From Alexander Krivenyshev (2009-04-08):
+# Based on previous media reports that "... proposed plan to
+# advance clocks by one hour from May 1 will cause disturbance
+# to the working schedules rather than bringing discipline in
+# official working."
+# <a href="http://www.thenews.com.pk/daily_detail.asp?id=171280">
+# http://www.thenews.com.pk/daily_detail.asp?id=171280
+# </a>
+#
+# recent news that instead of May 2009 - Pakistan plan to
+# introduce DST from April 15, 2009
+#
+# FYI: Associated Press Of Pakistan
+# April 08, 2009
+# Cabinet okays proposal to advance clocks by one hour from April 15
+# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=73043&Itemid=1">
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=73043&Itemid=1
+# </a>
+#
+# or
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan05.html">
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan05.html
+# </a>
+#
+# ....
+# The Federal Cabinet on Wednesday approved the proposal to
+# advance clocks in the country by one hour from April 15 to
+# conserve energy"
+
+# From Steffen Thorsen (2009-09-17):
+# "The News International," Pakistan reports that: "The Federal
+# Government has decided to restore the previous time by moving the
+# clocks backward by one hour from October 1. A formal announcement to
+# this effect will be made after the Prime Minister grants approval in
+# this regard."
+# <a href="http://www.thenews.com.pk/updates.asp?id=87168">
+# http://www.thenews.com.pk/updates.asp?id=87168
+# </a>
+
+# From Alexander Krivenyshev (2009-09-28):
+# According to Associated Press Of Pakistan, it is confirmed that
+# Pakistan clocks across the country would be turned back by an hour from October
+# 1, 2009.
+#
+# "Clocks to go back one hour from 1 Oct"
+# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2">
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm">
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm
+# </a>
+
+# From Steffen Thorsen (2009-09-29):
+# Alexander Krivenyshev wrote:
+# > According to Associated Press Of Pakistan, it is confirmed that
+# > Pakistan clocks across the country would be turned back by an hour from October
+# > 1, 2009.
+#
+# Now they seem to have changed their mind, November 1 is the new date:
+# <a href="http://www.thenews.com.pk/top_story_detail.asp?Id=24742">
+# http://www.thenews.com.pk/top_story_detail.asp?Id=24742
+# </a>
+# "The country's clocks will be reversed by one hour on November 1.
+# Officials of Federal Ministry for Interior told this to Geo News on
+# Monday."
+#
+# And more importantly, it seems that these dates will be kept every year:
+# "It has now been decided that clocks will be wound forward by one hour
+# on April 15 and reversed by an hour on November 1 every year without
+# obtaining prior approval, the officials added."
+#
+# We have confirmed this year's end date with both with the Ministry of
+# Water and Power and the Pakistan Electric Power Company:
+# <a href="http://www.timeanddate.com/news/time/pakistan-ends-dst09.html">
+# http://www.timeanddate.com/news/time/pakistan-ends-dst09.html
+# </a>
+
+# From Christoph Goehre (2009-10-01):
+# [T]he German Consulate General in Karachi reported me today that Pakistan
+# will go back to standard time on 1st of November.
+
+# From Steffen Thorsen (2010-03-26):
+# Steffen Thorsen wrote:
+# > On Thursday (2010-03-25) it was announced that DST would start in
+# > Pakistan on 2010-04-01.
+# >
+# > Then today, the president said that they might have to revert the
+# > decision if it is not supported by the parliament. So at the time
+# > being, it seems unclear if DST will be actually observed or not - but
+# > April 1 could be a more likely date than April 15.
+# Now, it seems that the decision to not observe DST in final:
+#
+# "Govt Withdraws Plan To Advance Clocks"
+# <a href="http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041">
+# http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041
+# </a>
+#
+# "People laud PM's announcement to end DST"
+# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2">
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
+Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	0	-
+Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
+Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
+Rule Pakistan	2009	only	-	Apr	15	0:00	1:00	S
+Rule Pakistan	2009	only	-	Nov	1	0:00	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Karachi	4:28:12 -	LMT	1907
+			5:30	-	IST	1942 Sep
+			5:30	1:00	IST	1945 Oct 15
+			5:30	-	IST	1951 Sep 30
+			5:00	-	KART	1971 Mar 26 # Karachi Time
+			5:00 Pakistan	PK%sT	# Pakistan Time
+
+# Palestine
+
+# From Amos Shapir (1998-02-15):
+#
+# From 1917 until 1948-05-15, all of Palestine, including the parts now
+# known as the Gaza Strip and the West Bank, was under British rule.
+# Therefore the rules given for Israel for that period, apply there too...
+#
+# The Gaza Strip was under Egyptian rule between 1948-05-15 until 1967-06-05
+# (except a short occupation by Israel from 1956-11 till 1957-03, but no
+# time zone was affected then).  It was never formally annexed to Egypt,
+# though.
+#
+# The rest of Palestine was under Jordanian rule at that time, formally
+# annexed in 1950 as the West Bank (and the word "Trans" was dropped from
+# the country's previous name of "the Hashemite Kingdom of the
+# Trans-Jordan").  So the rules for Jordan for that time apply.  Major
+# towns in that area are Nablus (Shchem), El-Halil (Hebron), Ramallah, and
+# East Jerusalem.
+#
+# Both areas were occupied by Israel in June 1967, but not annexed (except
+# for East Jerusalem).  They were on Israel time since then; there might
+# have been a Military Governor's order about time zones, but I'm not aware
+# of any (such orders may have been issued semi-annually whenever summer
+# time was in effect, but maybe the legal aspect of time was just neglected).
+#
+# The Palestinian Authority was established in 1993, and got hold of most
+# towns in the West Bank and Gaza by 1995.  I know that in order to
+# demonstrate...independence, they have been switching to
+# summer time and back on a different schedule than Israel's, but I don't
+# know when this was started, or what algorithm is used (most likely the
+# Jordanian one).
+#
+# To summarize, the table should probably look something like that:
+#
+# Area \ when | 1918-1947 | 1948-1967 | 1967-1995 | 1996-
+# ------------+-----------+-----------+-----------+-----------
+# Israel      | Zion      | Zion      | Zion      | Zion
+# West bank   | Zion      | Jordan    | Zion      | Jordan
+# Gaza        | Zion      | Egypt     | Zion      | Jordan
+#
+# I guess more info may be available from the PA's web page (if/when they
+# have one).
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that Gaza did not observe DST until 1957, but go
+# with Shapir and assume that it observed DST from 1940 through 1947,
+# and that it used Jordanian rules starting in 1996.
+# We don't yet need a separate entry for the West Bank, since
+# the only differences between it and Gaza that we know about
+# occurred before our cutoff date of 1970.
+# However, as we get more information, we may need to add entries
+# for parts of the West Bank as they transitioned from Israel's rules
+# to Palestine's rules.  If you have more info about this, please
+# send it to tz@elsie.nci.nih.gov for incorporation into future editions.
+
+# From IINS News Service - Israel - 1998-03-23 10:38:07 Israel time,
+# forwarded by Ephraim Silverberg:
+#
+# Despite the fact that Israel changed over to daylight savings time
+# last week, the PLO Authority (PA) has decided not to turn its clocks
+# one-hour forward at this time.  As a sign of independence from Israeli rule,
+# the PA has decided to implement DST in April.
+
+# From Paul Eggert (1999-09-20):
+# Daoud Kuttab writes in
+# <a href="http://www.jpost.com/com/Archive/22.Apr.1999/Opinion/Article-2.html">
+# Holiday havoc
+# </a> (Jerusalem Post, 1999-04-22) that
+# the Palestinian National Authority changed to DST on 1999-04-15.
+# I vaguely recall that they switch back in October (sorry, forgot the source).
+# For now, let's assume that the spring switch was at 24:00,
+# and that they switch at 0:00 on the 3rd Fridays of April and October.
+
+# From Paul Eggert (2005-11-22):
+# Starting 2004 transitions are from Steffen Thorsen's web site timeanddate.com.
+
+# From Steffen Thorsen (2005-11-23):
+# A user from Gaza reported that Gaza made the change early because of
+# the Ramadan.  Next year Ramadan will be even earlier, so I think
+# there is a good chance next year's end date will be around two weeks
+# earlier--the same goes for Jordan.
+
+# From Steffen Thorsen (2006-08-17):
+# I was informed by a user in Bethlehem that in Bethlehem it started the
+# same day as Israel, and after checking with other users in the area, I
+# was informed that they started DST one day after Israel.  I was not
+# able to find any authoritative sources at the time, nor details if
+# Gaza changed as well, but presumed Gaza to follow the same rules as
+# the West Bank.
+
+# From Steffen Thorsen (2006-09-26):
+# according to the Palestine News Network (2006-09-19):
+# http://english.pnn.ps/index.php?option=com_content&task=view&id=596&Itemid=5
+# > The Council of Ministers announced that this year its winter schedule
+# > will begin early, as of midnight Thursday.  It is also time to turn
+# > back the clocks for winter.  Friday will begin an hour late this week.
+# I guess it is likely that next year's date will be moved as well,
+# because of the Ramadan.
+
+# From Jesper Norgaard Welen (2007-09-18):
+# According to Steffen Thorsen's web site the Gaza Strip and the rest of the
+# Palestinian territories left DST early on 13.th. of September at 2:00.
+
+# From Paul Eggert (2007-09-20):
+# My understanding is that Gaza and the West Bank disagree even over when
+# the weekend is (Thursday+Friday versus Friday+Saturday), so I'd be a bit
+# surprised if they agreed about DST.  But for now, assume they agree.
+# For lack of better information, predict that future changes will be
+# the 2nd Thursday of September at 02:00.
+
+# From Alexander Krivenyshev (2008-08-28):
+# Here is an article, that Mideast running on different clocks at Ramadan.
+#
+# Gaza Strip (as Egypt) ended DST at midnight Thursday (Aug 28, 2008), while
+# the West Bank will end Daylight Saving Time at midnight Sunday (Aug 31, 2008).
+#
+# <a href="http://www.guardian.co.uk/world/feedarticle/7759001">
+# http://www.guardian.co.uk/world/feedarticle/7759001
+# </a>
+# <a href="http://www.abcnews.go.com/International/wireStory?id=5676087">
+# http://www.abcnews.go.com/International/wireStory?id=5676087
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html">
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html
+# </a>
+
+# From Alexander Krivenyshev (2009-03-26):
+# According to the Palestine News Network (arabic.pnn.ps), Palestinian
+# government decided to start Daylight Time on Thursday night March
+# 26 and continue until the night of 27 September 2009.
+#
+# (in Arabic)
+# <a href="http://arabic.pnn.ps/index.php?option=com_content&task=view&id=50850">
+# http://arabic.pnn.ps/index.php?option=com_content&task=view&id=50850
+# </a>
+#
+# or
+# (English translation)
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_westbank01.html">
+# http://www.worldtimezone.com/dst_news/dst_news_westbank01.html
+# </a>
+
+# From Steffen Thorsen (2009-08-31):
+# Palestine's Council of Ministers announced that they will revert back to
+# winter time on Friday, 2009-09-04.
+#
+# One news source:
+# <a href="http://www.safa.ps/ara/?action=showdetail&seid=4158">
+# http://www.safa.ps/ara/?action=showdetail&seid=4158
+# </a>
+# (Palestinian press agency, Arabic),
+# Google translate: "Decided that the Palestinian government in Ramallah
+# headed by Salam Fayyad, the start of work in time for the winter of
+# 2009, starting on Friday approved the fourth delay Sept. clock sixty
+# minutes per hour as of Friday morning."
+#
+# We are not sure if Gaza will do the same, last year they had a different
+# end date, we will keep this page updated:
+# <a href="http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html">
+# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html
+# </a>
+
+# From Alexander Krivenyshev (2009-09-02):
+# Seems that Gaza Strip will go back to Winter Time same date as West Bank.
+#
+# According to Palestinian Ministry Of Interior, West Bank and Gaza Strip plan
+# to change time back to Standard time on September 4, 2009.
+#
+# "Winter time unite the West Bank and Gaza"
+# (from Palestinian National Authority):
+# <a href="http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
+# http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html>
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
+# </a>
+
+# From Alexander Krivenyshev (2010-03-19):
+# According to Voice of Palestine DST will last for 191 days, from March
+# 26, 2010 till "the last Sunday before the tenth day of Tishri
+# (October), each year" (October 03, 2010?)
+#
+# <a href="http://palvoice.org/forums/showthread.php?t=245697">
+# http://palvoice.org/forums/showthread.php?t=245697
+# </a>
+# (in Arabic)
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_westbank03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_westbank03.html
+# </a>
+
+# From Steffen Thorsen (2010-03-24):
+# ...Ma'an News Agency reports that Hamas cabinet has decided it will
+# start one day later, at 12:01am. Not sure if they really mean 12:01am or
+# noon though:
+#
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=271178">
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=271178
+# </a>
+# (Ma'an News Agency)
+# "At 12:01am Friday, clocks in Israel and the West Bank will change to
+# 1:01am, while Gaza clocks will change at 12:01am Saturday morning."
+
+# From Steffen Thorsen (2010-08-11):
+# According to several sources, including
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=306795">
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=306795
+# </a>
+# the clocks were set back one hour at 2010-08-11 00:00:00 local time in
+# Gaza and the West Bank.
+# Some more background info:
+# <a href="http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html">
+# http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html
+# </a>
+
+# From Steffen Thorsen (2011-08-26):
+# Gaza and the West Bank did go back to standard time in the beginning of
+# August, and will now enter daylight saving time again on 2011-08-30
+# 00:00 (so two periods of DST in 2011). The pause was because of
+# Ramadan.
+#
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=416217">
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=416217
+# </a>
+# Additional info:
+# <a href="http://www.timeanddate.com/news/time/palestine-dst-2011.html">
+# http://www.timeanddate.com/news/time/palestine-dst-2011.html
+# </a>
+
+# From Alexander Krivenyshev (2011-08-27):
+# According to the article in The Jerusalem Post:
+# "...Earlier this month, the Palestinian government in the West Bank decided to
+# move to standard time for 30 days, during Ramadan. The Palestinians in the
+# Gaza Strip accepted the change and also moved their clocks one hour back.
+# The Hamas government said on Saturday that it won't observe summertime after
+# the Muslim feast of Id al-Fitr, which begins on Tuesday..."
+# ...
+# <a href="http://www.jpost.com/MiddleEast/Article.aspx?id=235650">
+# http://www.jpost.com/MiddleEast/Article.aspx?id=235650
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip05.html">
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip05.html
+# </a>
+# The rules for Egypt are stolen from the `africa' file.
+
+# From Steffen Thorsen (2011-09-30):
+# West Bank did end Daylight Saving Time this morning/midnight (2011-09-30
+# 00:00).
+# So West Bank and Gaza now have the same time again.
+#
+# Many sources, including:
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=424808">
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=424808
+# </a>
+
+# From Steffen Thorsen (2012-03-26):
+# Palestinian news sources tell that both Gaza and West Bank will start DST
+# on Friday (Thursday midnight, 2012-03-29 24:00).
+# Some of many sources in Arabic:
+# <a href="http://www.samanews.com/index.php?act=Show&id=122638">
+# http://www.samanews.com/index.php?act=Show&id=122638
+# </a>
+#
+# <a href="http://safa.ps/details/news/74352/%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-%D8%A8%D8%A7%D9%84%D8%B6%D9%81%D8%A9-%D9%88%D8%BA%D8%B2%D8%A9-%D9%84%D9%8A%D9%84%D8%A9-%D8%A7%D9%84%D8%AC%D9%85%D8%B9%D8%A9.html">
+# http://safa.ps/details/news/74352/%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-%D8%A8%D8%A7%D9%84%D8%B6%D9%81%D8%A9-%D9%88%D8%BA%D8%B2%D8%A9-%D9%84%D9%8A%D9%84%D8%A9-%D8%A7%D9%84%D8%AC%D9%85%D8%B9%D8%A9.html
+# </a>
+#
+# Our brief summary:
+# <a href="http://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html">
+# http://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html
+# </a>
+
+# From Arthur David Olson (2012-03-27):
+# The timeanddate article for 2012 says that "the end date has not yet been
+# announced" and that "Last year, both...paused daylight saving time during...
+# Ramadan. It is not yet known [for] 2012."
+# For now, assume both switch back on the last Friday in September. XXX
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
+Rule EgyptAsia	1957	1958	-	Oct	 1	0:00	0	-
+Rule EgyptAsia	1958	only	-	May	 1	0:00	1:00	S
+Rule EgyptAsia	1959	1967	-	May	 1	1:00	1:00	S
+Rule EgyptAsia	1959	1965	-	Sep	30	3:00	0	-
+Rule EgyptAsia	1966	only	-	Oct	 1	3:00	0	-
+
+Rule Palestine	1999	2005	-	Apr	Fri>=15	0:00	1:00	S
+Rule Palestine	1999	2003	-	Oct	Fri>=15	0:00	0	-
+Rule Palestine	2004	only	-	Oct	 1	1:00	0	-
+Rule Palestine	2005	only	-	Oct	 4	2:00	0	-
+Rule Palestine	2006	2008	-	Apr	 1	0:00	1:00	S
+Rule Palestine	2006	only	-	Sep	22	0:00	0	-
+Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
+Rule Palestine	2008	only	-	Aug	lastFri	0:00	0	-
+Rule Palestine	2009	only	-	Mar	lastFri	0:00	1:00	S
+Rule Palestine	2009	only	-	Sep	Fri>=1	2:00	0	-
+Rule Palestine	2010	only	-	Mar	lastSat	0:01	1:00	S
+Rule Palestine	2010	only	-	Aug	11	0:00	0	-
+
+# From Arthur David Olson (2011-09-20):
+# 2011 transitions per http://www.timeanddate.com as of 2011-09-20.
+# From Paul Eggert (2012-10-12):
+# 2012 transitions per http://www.timeanddate.com as of 2012-10-12.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
+			2:00	Zion	EET	1948 May 15
+			2:00 EgyptAsia	EE%sT	1967 Jun  5
+			2:00	Zion	I%sT	1996
+			2:00	Jordan	EE%sT	1999
+			2:00 Palestine	EE%sT	2011 Apr  2 12:01
+			2:00	1:00	EEST	2011 Aug  1
+			2:00	-	EET	2012 Mar 30
+			2:00	1:00	EEST	2012 Sep 21 1:00
+			2:00	-	EET
+
+Zone	Asia/Hebron	2:20:23	-	LMT	1900 Oct
+			2:00	Zion	EET	1948 May 15
+			2:00 EgyptAsia	EE%sT	1967 Jun  5
+			2:00	Zion	I%sT	1996
+			2:00	Jordan	EE%sT	1999
+			2:00 Palestine	EE%sT	2008 Aug
+			2:00 	1:00	EEST	2008 Sep
+			2:00 Palestine	EE%sT	2011 Apr  1 12:01
+			2:00	1:00	EEST	2011 Aug  1
+			2:00	-	EET	2011 Aug 30
+			2:00	1:00	EEST	2011 Sep 30 3:00
+			2:00	-	EET	2012 Mar 30
+			2:00	1:00	EEST	2012 Sep 21 1:00
+			2:00	-	EET
+
+# Paracel Is
+# no information
+
+# Philippines
+# On 1844-08-16, Narciso Claveria, governor-general of the
+# Philippines, issued a proclamation announcing that 1844-12-30 was to
+# be immediately followed by 1845-01-01.  Robert H. van Gent has a
+# transcript of the decree in <http://www.phys.uu.nl/~vgent/idl/idl.htm>.
+# The rest of the data are from Shanks & Pottenger.
+
+# From Paul Eggert (2006-04-25):
+# Tomorrow's Manila Standard reports that the Philippines Department of
+# Trade and Industry is considering adopting DST this June when the
+# rainy season begins.  See
+# <http://www.manilastandardtoday.com/?page=politics02_april26_2006>.
+# For now, we'll ignore this, since it's not definite and we lack details.
+#
+# From Jesper Norgaard Welen (2006-04-26):
+# ... claims that Philippines had DST last time in 1990:
+# http://story.philippinetimes.com/p.x/ct/9/id/145be20cc6b121c0/cid/3e5bbccc730d258c/
+# [a story dated 2006-04-25 by Cris Larano of Dow Jones Newswires,
+# but no details]
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Phil	1936	only	-	Nov	1	0:00	1:00	S
+Rule	Phil	1937	only	-	Feb	1	0:00	0	-
+Rule	Phil	1954	only	-	Apr	12	0:00	1:00	S
+Rule	Phil	1954	only	-	Jul	1	0:00	0	-
+Rule	Phil	1978	only	-	Mar	22	0:00	1:00	S
+Rule	Phil	1978	only	-	Sep	21	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Manila	-15:56:00 -	LMT	1844 Dec 31
+			8:04:00 -	LMT	1899 May 11
+			8:00	Phil	PH%sT	1942 May
+			9:00	-	JST	1944 Nov
+			8:00	Phil	PH%sT
+
+# Qatar
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Qatar	3:26:08 -	LMT	1920	# Al Dawhah / Doha
+			4:00	-	GST	1972 Jun
+			3:00	-	AST
+
+# Saudi Arabia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Riyadh	3:06:52 -	LMT	1950
+			3:00	-	AST
+
+# Singapore
+# The data here are taken from Mok Ly Yng (2003-10-30)
+# <http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html>.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Singapore	6:55:25 -	LMT	1901 Jan  1
+			6:55:25	-	SMT	1905 Jun  1 # Singapore M.T.
+			7:00	-	MALT	1933 Jan  1 # Malaya Time
+			7:00	0:20	MALST	1936 Jan  1
+			7:20	-	MALT	1941 Sep  1
+			7:30	-	MALT	1942 Feb 16
+			9:00	-	JST	1945 Sep 12
+			7:30	-	MALT	1965 Aug  9 # independence
+			7:30	-	SGT	1982 Jan  1 # Singapore Time
+			8:00	-	SGT
+
+# Spratly Is
+# no information
+
+# Sri Lanka
+# From Paul Eggert (1996-09-03):
+# "Sri Lanka advances clock by an hour to avoid blackout"
+# (www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
+# no longer available as of 1999-08-17)
+# reported ``the country's standard time will be put forward by one hour at
+# midnight Friday (1830 GMT) `in the light of the present power crisis'.''
+#
+# From Dharmasiri Senanayake, Sri Lanka Media Minister (1996-10-24), as quoted
+# by Shamindra in
+# <a href="news:54rka5$m5h@mtinsc01-mgt.ops.worldnet.att.net">
+# Daily News - Hot News Section (1996-10-26)
+# </a>:
+# With effect from 12.30 a.m. on 26th October 1996
+# Sri Lanka will be six (06) hours ahead of GMT.
+
+# From Jesper Norgaard Welen (2006-04-14), quoting Sri Lanka News Online
+# <http://news.sinhalaya.com/wmview.php?ArtID=11002> (2006-04-13):
+# 0030 hrs on April 15, 2006 (midnight of April 14, 2006 +30 minutes)
+# at present, become 2400 hours of April 14, 2006 (midnight of April 14, 2006).
+
+# From Peter Apps and Ranga Sirila of Reuters (2006-04-12) in:
+# <http://today.reuters.co.uk/news/newsArticle.aspx?type=scienceNews&storyID=2006-04-12T172228Z_01_COL295762_RTRIDST_0_SCIENCE-SRILANKA-TIME-DC.XML>
+# [The Tamil Tigers] never accepted the original 1996 time change and simply
+# kept their clocks set five and a half hours ahead of Greenwich Mean
+# Time (GMT), in line with neighbor India.
+# From Paul Eggert (2006-04-18):
+# People who live in regions under Tamil control can use [TZ='Asia/Kolkata'],
+# as that zone has agreed with the Tamil areas since our cutoff date of 1970.
+
+# From K Sethu (2006-04-25):
+# I think the abbreviation LKT originated from the world of computers at
+# the time of or subsequent to the time zone changes by SL Government
+# twice in 1996 and probably SL Government or its standardization
+# agencies never declared an abbreviation as a national standard.
+#
+# I recollect before the recent change the government annoucemments
+# mentioning it as simply changing Sri Lanka Standard Time or Sri Lanka
+# Time and no mention was made about the abbreviation.
+#
+# If we look at Sri Lanka Department of Government's "Official News
+# Website of Sri Lanka" ... http://www.news.lk/ we can see that they
+# use SLT as abbreviation in time stamp at the beginning of each news
+# item....
+#
+# Within Sri Lanka I think LKT is well known among computer users and
+# adminsitrators.  In my opinion SLT may not be a good choice because the
+# nation's largest telcom / internet operator Sri Lanka Telcom is well
+# known by that abbreviation - simply as SLT (there IP domains are
+# slt.lk and sltnet.lk).
+#
+# But if indeed our government has adopted SLT as standard abbreviation
+# (that we have not known so far) then  it is better that it be used for
+# all computers.
+
+# From Paul Eggert (2006-04-25):
+# One possibility is that we wait for a bit for the dust to settle down
+# and then see what people actually say in practice.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Colombo	5:19:24 -	LMT	1880
+			5:19:32	-	MMT	1906	# Moratuwa Mean Time
+			5:30	-	IST	1942 Jan  5
+			5:30	0:30	IHST	1942 Sep
+			5:30	1:00	IST	1945 Oct 16 2:00
+			5:30	-	IST	1996 May 25 0:00
+			6:30	-	LKT	1996 Oct 26 0:30
+			6:00	-	LKT	2006 Apr 15 0:30
+			5:30	-	IST
+
+# Syria
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Syria	1920	1923	-	Apr	Sun>=15	2:00	1:00	S
+Rule	Syria	1920	1923	-	Oct	Sun>=1	2:00	0	-
+Rule	Syria	1962	only	-	Apr	29	2:00	1:00	S
+Rule	Syria	1962	only	-	Oct	1	2:00	0	-
+Rule	Syria	1963	1965	-	May	1	2:00	1:00	S
+Rule	Syria	1963	only	-	Sep	30	2:00	0	-
+Rule	Syria	1964	only	-	Oct	1	2:00	0	-
+Rule	Syria	1965	only	-	Sep	30	2:00	0	-
+Rule	Syria	1966	only	-	Apr	24	2:00	1:00	S
+Rule	Syria	1966	1976	-	Oct	1	2:00	0	-
+Rule	Syria	1967	1978	-	May	1	2:00	1:00	S
+Rule	Syria	1977	1978	-	Sep	1	2:00	0	-
+Rule	Syria	1983	1984	-	Apr	9	2:00	1:00	S
+Rule	Syria	1983	1984	-	Oct	1	2:00	0	-
+Rule	Syria	1986	only	-	Feb	16	2:00	1:00	S
+Rule	Syria	1986	only	-	Oct	9	2:00	0	-
+Rule	Syria	1987	only	-	Mar	1	2:00	1:00	S
+Rule	Syria	1987	1988	-	Oct	31	2:00	0	-
+Rule	Syria	1988	only	-	Mar	15	2:00	1:00	S
+Rule	Syria	1989	only	-	Mar	31	2:00	1:00	S
+Rule	Syria	1989	only	-	Oct	1	2:00	0	-
+Rule	Syria	1990	only	-	Apr	1	2:00	1:00	S
+Rule	Syria	1990	only	-	Sep	30	2:00	0	-
+Rule	Syria	1991	only	-	Apr	 1	0:00	1:00	S
+Rule	Syria	1991	1992	-	Oct	 1	0:00	0	-
+Rule	Syria	1992	only	-	Apr	 8	0:00	1:00	S
+Rule	Syria	1993	only	-	Mar	26	0:00	1:00	S
+Rule	Syria	1993	only	-	Sep	25	0:00	0	-
+# IATA SSIM (1998-02) says 1998-04-02;
+# (1998-09) says 1999-03-29 and 1999-09-29; (1999-02) says 1999-04-02,
+# 2000-04-02, and 2001-04-02; (1999-09) says 2000-03-31 and 2001-03-31;
+# (2006) says 2006-03-31 and 2006-09-22;
+# for now ignore all these claims and go with Shanks & Pottenger,
+# except for the 2006-09-22 claim (which seems right for Ramadan).
+Rule	Syria	1994	1996	-	Apr	 1	0:00	1:00	S
+Rule	Syria	1994	2005	-	Oct	 1	0:00	0	-
+Rule	Syria	1997	1998	-	Mar	lastMon	0:00	1:00	S
+Rule	Syria	1999	2006	-	Apr	 1	0:00	1:00	S
+# From Stephen Colebourne (2006-09-18):
+# According to IATA data, Syria will change DST on 21st September [21:00 UTC]
+# this year [only]....  This is probably related to Ramadan, like Egypt.
+Rule	Syria	2006	only	-	Sep	22	0:00	0	-
+# From Paul Eggert (2007-03-29):
+# Today the AP reported "Syria will switch to summertime at midnight Thursday."
+# http://www.iht.com/articles/ap/2007/03/29/africa/ME-GEN-Syria-Time-Change.php
+Rule	Syria	2007	only	-	Mar	lastFri	0:00	1:00	S
+# From Jesper Norgard (2007-10-27):
+# The sister center ICARDA of my work CIMMYT is confirming that Syria DST will
+# not take place 1.st November at 0:00 o'clock but 1.st November at 24:00 or
+# rather Midnight between Thursday and Friday. This does make more sence than
+# having it between Wednesday and Thursday (two workdays in Syria) since the
+# weekend in Syria is not Saturday and Sunday, but Friday and Saturday. So now
+# it is implemented at midnight of the last workday before weekend...
+#
+# From Steffen Thorsen (2007-10-27):
+# Jesper Norgaard Welen wrote:
+#
+# > "Winter local time in Syria will be observed at midnight of Thursday 1
+# > November 2007, and the clock will be put back 1 hour."
+#
+# I found confirmation on this in this gov.sy-article (Arabic):
+# http://wehda.alwehda.gov.sy/_print_veiw.asp?FileName=12521710520070926111247
+#
+# which using Google's translate tools says:
+# Council of Ministers also approved the commencement of work on
+# identifying the winter time as of Friday, 2/11/2007 where the 60th
+# minute delay at midnight Thursday 1/11/2007.
+Rule	Syria	2007	only	-	Nov	 Fri>=1	0:00	0	-
+
+# From Stephen Colebourne (2008-03-17):
+# For everyone's info, I saw an IATA time zone change for [Syria] for
+# this month (March 2008) in the last day or so...This is the data IATA
+# are now using:
+# Country     Time Standard   --- DST Start ---   --- DST End ---  DST
+# Name        Zone Variation   Time    Date        Time    Date
+# Variation
+# Syrian Arab
+# Republic    SY    +0200      2200  03APR08       2100  30SEP08   +0300
+#                              2200  02APR09       2100  30SEP09   +0300
+#                              2200  01APR10       2100  30SEP10   +0300
+
+# From Arthur David Olson (2008-03-17):
+# Here's a link to English-language coverage by the Syrian Arab News
+# Agency (SANA)...
+# <a href="http://www.sana.sy/eng/21/2008/03/11/165173.htm">
+# http://www.sana.sy/eng/21/2008/03/11/165173.htm
+# </a>...which reads (in part) "The Cabinet approved the suggestion of the
+# Ministry of Electricity to begin daylight savings time on Friday April
+# 4th, advancing clocks one hour ahead on midnight of Thursday April 3rd."
+# Since Syria is two hours east of UTC, the 2200 and 2100 transition times
+# shown above match up with midnight in Syria.
+
+# From Arthur David Olson (2008-03-18):
+# My buest guess at a Syrian rule is "the Friday nearest April 1";
+# coding that involves either using a "Mar Fri>=29" construct that old time zone
+# compilers can't handle  or having multiple Rules (a la Israel).
+# For now, use "Apr Fri>=1", and go with IATA on a uniform Sep 30 end.
+
+# From Steffen Thorsen (2008-10-07):
+# Syria has now officially decided to end DST on 2008-11-01 this year,
+# according to the following article in the Syrian Arab News Agency (SANA).
+#
+# The article is in Arabic, and seems to tell that they will go back to
+# winter time on 2008-11-01 at 00:00 local daylight time (delaying/setting
+# clocks back 60 minutes).
+#
+# <a href="http://sana.sy/ara/2/2008/10/07/195459.htm">
+# http://sana.sy/ara/2/2008/10/07/195459.htm
+# </a>
+
+# From Steffen Thorsen (2009-03-19):
+# Syria will start DST on 2009-03-27 00:00 this year according to many sources,
+# two examples:
+#
+# <a href="http://www.sana.sy/eng/21/2009/03/17/217563.htm">
+# http://www.sana.sy/eng/21/2009/03/17/217563.htm
+# </a>
+# (English, Syrian Arab News # Agency)
+# <a href="http://thawra.alwehda.gov.sy/_View_news2.asp?FileName=94459258720090318012209">
+# http://thawra.alwehda.gov.sy/_View_news2.asp?FileName=94459258720090318012209
+# </a>
+# (Arabic, gov-site)
+#
+# We have not found any sources saying anything about when DST ends this year.
+#
+# Our summary
+# <a href="http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html">
+# http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html
+# </a>
+
+# From Steffen Thorsen (2009-10-27):
+# The Syrian Arab News Network on 2009-09-29 reported that Syria will
+# revert back to winter (standard) time on midnight between Thursday
+# 2009-10-29 and Friday 2009-10-30:
+# <a href="http://www.sana.sy/ara/2/2009/09/29/247012.htm">
+# http://www.sana.sy/ara/2/2009/09/29/247012.htm (Arabic)
+# </a>
+
+# From Arthur David Olson (2009-10-28):
+# We'll see if future DST switching times turn out to be end of the last
+# Thursday of the month or the start of the last Friday of the month or
+# something else. For now, use the start of the last Friday.
+
+# From Steffen Thorsen (2010-03-17):
+# The "Syrian News Station" reported on 2010-03-16 that the Council of
+# Ministers has decided that Syria will start DST on midnight Thursday
+# 2010-04-01: (midnight between Thursday and Friday):
+# <a href="http://sns.sy/sns/?path=news/read/11421">
+# http://sns.sy/sns/?path=news/read/11421 (Arabic)
+# </a>
+
+# From Steffen Thorsen (2012-03-26):
+# Today, Syria's government announced that they will start DST early on Friday
+# (00:00). This is a bit earlier than the past two years.
+#
+# From Syrian Arab News Agency, in Arabic:
+# <a href="http://www.sana.sy/ara/2/2012/03/26/408215.htm">
+# http://www.sana.sy/ara/2/2012/03/26/408215.htm
+# </a>
+#
+# Our brief summary:
+# <a href="http://www.timeanddate.com/news/time/syria-dst-2012.html">
+# http://www.timeanddate.com/news/time/syria-dst-2012.html
+# </a>
+
+# From Arthur David Olson (2012-03-27):
+# Assume last Friday in March going forward XXX.
+
+Rule	Syria	2008	only	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Syria	2008	only	-	Nov	1	0:00	0	-
+Rule	Syria	2009	only	-	Mar	lastFri	0:00	1:00	S
+Rule	Syria	2010	2011	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Syria	2012	max	-	Mar	lastFri	0:00	1:00	S
+Rule	Syria	2009	max	-	Oct	lastFri	0:00	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
+			2:00	Syria	EE%sT
+
+# Tajikistan
+# From Shanks & Pottenger.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dushanbe	4:35:12 -	LMT	1924 May  2
+			5:00	-	DUST	1930 Jun 21 # Dushanbe Time
+			6:00 RussiaAsia DUS%sT	1991 Mar 31 2:00s
+			5:00	1:00	DUSST	1991 Sep  9 2:00s
+			5:00	-	TJT		    # Tajikistan Time
+
+# Thailand
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Bangkok	6:42:04	-	LMT	1880
+			6:42:04	-	BMT	1920 Apr # Bangkok Mean Time
+			7:00	-	ICT
+
+# Turkmenistan
+# From Shanks & Pottenger.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Ashgabat	3:53:32 -	LMT	1924 May  2 # or Ashkhabad
+			4:00	-	ASHT	1930 Jun 21 # Ashkhabad Time
+			5:00 RussiaAsia	ASH%sT	1991 Mar 31 2:00
+			4:00 RussiaAsia	ASH%sT	1991 Oct 27 # independence
+			4:00 RussiaAsia	TM%sT	1992 Jan 19 2:00
+			5:00	-	TMT
+
+# United Arab Emirates
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dubai	3:41:12 -	LMT	1920
+			4:00	-	GST
+
+# Uzbekistan
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Samarkand	4:27:12 -	LMT	1924 May  2
+			4:00	-	SAMT	1930 Jun 21 # Samarkand Time
+			5:00	-	SAMT	1981 Apr  1
+			5:00	1:00	SAMST	1981 Oct  1
+			6:00	-	TAST	1982 Apr  1 # Tashkent Time
+			5:00 RussiaAsia	SAM%sT	1991 Sep  1 # independence
+			5:00 RussiaAsia	UZ%sT	1992
+			5:00	-	UZT
+Zone	Asia/Tashkent	4:37:12 -	LMT	1924 May  2
+			5:00	-	TAST	1930 Jun 21 # Tashkent Time
+			6:00 RussiaAsia	TAS%sT	1991 Mar 31 2:00
+			5:00 RussiaAsia	TAS%sT	1991 Sep  1 # independence
+			5:00 RussiaAsia	UZ%sT	1992
+			5:00	-	UZT
+
+# Vietnam
+
+# From Arthur David Olson (2008-03-18):
+# The English-language name of Vietnam's most populous city is "Ho Chi Min City";
+# we use Ho_Chi_Minh below to avoid a name of more than 14 characters.
+
+# From Shanks & Pottenger:
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Ho_Chi_Minh	7:06:40 -	LMT	1906 Jun  9
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
+			7:00	-	ICT	1912 May
+			8:00	-	ICT	1931 May
+			7:00	-	ICT
+
+# Yemen
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Aden	3:00:48	-	LMT	1950
+			3:00	-	AST
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/australasia b/jdk/test/sun/util/calendar/zi/tzdata/australasia
new file mode 100644
index 0000000..7f83448
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/australasia
@@ -0,0 +1,1742 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# This file also includes Pacific islands.
+
+# Notes are at the end of this file
+
+###############################################################################
+
+# Australia
+
+# Please see the notes below for the controversy about "EST" versus "AEST" etc.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Aus	1917	only	-	Jan	 1	0:01	1:00	-
+Rule	Aus	1917	only	-	Mar	25	2:00	0	-
+Rule	Aus	1942	only	-	Jan	 1	2:00	1:00	-
+Rule	Aus	1942	only	-	Mar	29	2:00	0	-
+Rule	Aus	1942	only	-	Sep	27	2:00	1:00	-
+Rule	Aus	1943	1944	-	Mar	lastSun	2:00	0	-
+Rule	Aus	1943	only	-	Oct	 3	2:00	1:00	-
+# Go with Whitman and the Australian National Standards Commission, which
+# says W Australia didn't use DST in 1943/1944.  Ignore Whitman's claim that
+# 1944/1945 was just like 1943/1944.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Northern Territory
+Zone Australia/Darwin	 8:43:20 -	LMT	1895 Feb
+			 9:00	-	CST	1899 May
+			 9:30	Aus	CST
+# Western Australia
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AW	1974	only	-	Oct	lastSun	2:00s	1:00	-
+Rule	AW	1975	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AW	1983	only	-	Oct	lastSun	2:00s	1:00	-
+Rule	AW	1984	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AW	1991	only	-	Nov	17	2:00s	1:00	-
+Rule	AW	1992	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AW	2006	only	-	Dec	 3	2:00s	1:00	-
+Rule	AW	2007	2009	-	Mar	lastSun	2:00s	0	-
+Rule	AW	2007	2008	-	Oct	lastSun	2:00s	1:00	-
+Zone Australia/Perth	 7:43:24 -	LMT	1895 Dec
+			 8:00	Aus	WST	1943 Jul
+			 8:00	AW	WST
+Zone Australia/Eucla	 8:35:28 -	LMT	1895 Dec
+			 8:45	Aus	CWST	1943 Jul
+			 8:45	AW	CWST
+
+# Queensland
+#
+# From Alex Livingston (1996-11-01):
+# I have heard or read more than once that some resort islands off the coast
+# of Queensland chose to keep observing daylight-saving time even after
+# Queensland ceased to.
+#
+# From Paul Eggert (1996-11-22):
+# IATA SSIM (1993-02/1994-09) say that the Holiday Islands (Hayman, Lindeman,
+# Hamilton) observed DST for two years after the rest of Queensland stopped.
+# Hamilton is the largest, but there is also a Hamilton in Victoria,
+# so use Lindeman.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AQ	1971	only	-	Oct	lastSun	2:00s	1:00	-
+Rule	AQ	1972	only	-	Feb	lastSun	2:00s	0	-
+Rule	AQ	1989	1991	-	Oct	lastSun	2:00s	1:00	-
+Rule	AQ	1990	1992	-	Mar	Sun>=1	2:00s	0	-
+Rule	Holiday	1992	1993	-	Oct	lastSun	2:00s	1:00	-
+Rule	Holiday	1993	1994	-	Mar	Sun>=1	2:00s	0	-
+Zone Australia/Brisbane	10:12:08 -	LMT	1895
+			10:00	Aus	EST	1971
+			10:00	AQ	EST
+Zone Australia/Lindeman  9:55:56 -	LMT	1895
+			10:00	Aus	EST	1971
+			10:00	AQ	EST	1992 Jul
+			10:00	Holiday	EST
+
+# South Australia
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AS	1971	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	AS	1986	only	-	Oct	19	2:00s	1:00	-
+Rule	AS	1987	2007	-	Oct	lastSun	2:00s	1:00	-
+Rule	AS	1972	only	-	Feb	27	2:00s	0	-
+Rule	AS	1973	1985	-	Mar	Sun>=1	2:00s	0	-
+Rule	AS	1986	1990	-	Mar	Sun>=15	2:00s	0	-
+Rule	AS	1991	only	-	Mar	3	2:00s	0	-
+Rule	AS	1992	only	-	Mar	22	2:00s	0	-
+Rule	AS	1993	only	-	Mar	7	2:00s	0	-
+Rule	AS	1994	only	-	Mar	20	2:00s	0	-
+Rule	AS	1995	2005	-	Mar	lastSun	2:00s	0	-
+Rule	AS	2006	only	-	Apr	2	2:00s	0	-
+Rule	AS	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	AS	2008	max	-	Apr	Sun>=1	2:00s	0	-
+Rule	AS	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Australia/Adelaide	9:14:20 -	LMT	1895 Feb
+			9:00	-	CST	1899 May
+			9:30	Aus	CST	1971
+			9:30	AS	CST
+
+# Tasmania
+#
+# From Paul Eggert (2005-08-16):
+# <http://www.bom.gov.au/climate/averages/tables/dst_times.shtml>
+# says King Island didn't observe DST from WWII until late 1971.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AT	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	AT	1968	only	-	Mar	lastSun	2:00s	0	-
+Rule	AT	1968	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	AT	1969	1971	-	Mar	Sun>=8	2:00s	0	-
+Rule	AT	1972	only	-	Feb	lastSun	2:00s	0	-
+Rule	AT	1973	1981	-	Mar	Sun>=1	2:00s	0	-
+Rule	AT	1982	1983	-	Mar	lastSun	2:00s	0	-
+Rule	AT	1984	1986	-	Mar	Sun>=1	2:00s	0	-
+Rule	AT	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
+Rule	AT	1987	1990	-	Mar	Sun>=15	2:00s	0	-
+Rule	AT	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
+Rule	AT	1988	1990	-	Oct	lastSun	2:00s	1:00	-
+Rule	AT	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	AT	1991	2005	-	Mar	lastSun	2:00s	0	-
+Rule	AT	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AT	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	AT	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AT	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	AT	2008	max	-	Apr	Sun>=1	2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Australia/Hobart	9:49:16	-	LMT	1895 Sep
+			10:00	-	EST	1916 Oct 1 2:00
+			10:00	1:00	EST	1917 Feb
+			10:00	Aus	EST	1967
+			10:00	AT	EST
+Zone Australia/Currie	9:35:28	-	LMT	1895 Sep
+			10:00	-	EST	1916 Oct 1 2:00
+			10:00	1:00	EST	1917 Feb
+			10:00	Aus	EST	1971 Jul
+			10:00	AT	EST
+
+# Victoria
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AV	1971	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	AV	1972	only	-	Feb	lastSun	2:00s	0	-
+Rule	AV	1973	1985	-	Mar	Sun>=1	2:00s	0	-
+Rule	AV	1986	1990	-	Mar	Sun>=15	2:00s	0	-
+Rule	AV	1986	1987	-	Oct	Sun>=15	2:00s	1:00	-
+Rule	AV	1988	1999	-	Oct	lastSun	2:00s	1:00	-
+Rule	AV	1991	1994	-	Mar	Sun>=1	2:00s	0	-
+Rule	AV	1995	2005	-	Mar	lastSun	2:00s	0	-
+Rule	AV	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AV	2001	2007	-	Oct	lastSun	2:00s	1:00	-
+Rule	AV	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AV	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	AV	2008	max	-	Apr	Sun>=1	2:00s	0	-
+Rule	AV	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Australia/Melbourne 9:39:52 -	LMT	1895 Feb
+			10:00	Aus	EST	1971
+			10:00	AV	EST
+
+# New South Wales
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AN	1971	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	AN	1972	only	-	Feb	27	2:00s	0	-
+Rule	AN	1973	1981	-	Mar	Sun>=1	2:00s	0	-
+Rule	AN	1982	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AN	1983	1985	-	Mar	Sun>=1	2:00s	0	-
+Rule	AN	1986	1989	-	Mar	Sun>=15	2:00s	0	-
+Rule	AN	1986	only	-	Oct	19	2:00s	1:00	-
+Rule	AN	1987	1999	-	Oct	lastSun	2:00s	1:00	-
+Rule	AN	1990	1995	-	Mar	Sun>=1	2:00s	0	-
+Rule	AN	1996	2005	-	Mar	lastSun	2:00s	0	-
+Rule	AN	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AN	2001	2007	-	Oct	lastSun	2:00s	1:00	-
+Rule	AN	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AN	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	AN	2008	max	-	Apr	Sun>=1	2:00s	0	-
+Rule	AN	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Australia/Sydney	10:04:52 -	LMT	1895 Feb
+			10:00	Aus	EST	1971
+			10:00	AN	EST
+Zone Australia/Broken_Hill 9:25:48 -	LMT	1895 Feb
+			10:00	-	EST	1896 Aug 23
+			9:00	-	CST	1899 May
+			9:30	Aus	CST	1971
+			9:30	AN	CST	2000
+			9:30	AS	CST
+
+# Lord Howe Island
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	LH	1981	1984	-	Oct	lastSun	2:00	1:00	-
+Rule	LH	1982	1985	-	Mar	Sun>=1	2:00	0	-
+Rule	LH	1985	only	-	Oct	lastSun	2:00	0:30	-
+Rule	LH	1986	1989	-	Mar	Sun>=15	2:00	0	-
+Rule	LH	1986	only	-	Oct	19	2:00	0:30	-
+Rule	LH	1987	1999	-	Oct	lastSun	2:00	0:30	-
+Rule	LH	1990	1995	-	Mar	Sun>=1	2:00	0	-
+Rule	LH	1996	2005	-	Mar	lastSun	2:00	0	-
+Rule	LH	2000	only	-	Aug	lastSun	2:00	0:30	-
+Rule	LH	2001	2007	-	Oct	lastSun	2:00	0:30	-
+Rule	LH	2006	only	-	Apr	Sun>=1	2:00	0	-
+Rule	LH	2007	only	-	Mar	lastSun	2:00	0	-
+Rule	LH	2008	max	-	Apr	Sun>=1	2:00	0	-
+Rule	LH	2008	max	-	Oct	Sun>=1	2:00	0:30	-
+Zone Australia/Lord_Howe 10:36:20 -	LMT	1895 Feb
+			10:00	-	EST	1981 Mar
+			10:30	LH	LHST
+
+# Australian miscellany
+#
+# Ashmore Is, Cartier
+# no indigenous inhabitants; only seasonal caretakers
+# no times are set
+#
+# Coral Sea Is
+# no indigenous inhabitants; only meteorologists
+# no times are set
+#
+# Macquarie
+# permanent occupation (scientific station) since 1948;
+# sealing and penguin oil station operated 1888/1917
+# like Australia/Hobart
+
+# Christmas
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Christmas	7:02:52 -	LMT	1895 Feb
+			7:00	-	CXT	# Christmas Island Time
+
+# Cook Is
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Cook	1978	only	-	Nov	12	0:00	0:30	HS
+Rule	Cook	1979	1991	-	Mar	Sun>=1	0:00	0	-
+Rule	Cook	1979	1990	-	Oct	lastSun	0:00	0:30	HS
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Rarotonga	-10:39:04 -	LMT	1901		# Avarua
+			-10:30	-	CKT	1978 Nov 12	# Cook Is Time
+			-10:00	Cook	CK%sT
+
+# Cocos
+# These islands were ruled by the Ross family from about 1830 to 1978.
+# We don't know when standard time was introduced; for now, we guess 1900.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Cocos	6:27:40	-	LMT	1900
+			6:30	-	CCT	# Cocos Islands Time
+
+# Fiji
+# From Alexander Krivenyshev (2009-11-10):
+# According to Fiji Broadcasting Corporation,  Fiji plans to re-introduce DST
+# from November 29th 2009  to April 25th 2010.
+#
+# "Daylight savings to commence this month"
+# <a href="http://www.radiofiji.com.fj/fullstory.php?id=23719">
+# http://www.radiofiji.com.fj/fullstory.php?id=23719
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_fiji01.html">
+# http://www.worldtimezone.com/dst_news/dst_news_fiji01.html
+# </a>
+
+# From Steffen Thorsen (2009-11-10):
+# The Fiji Government has posted some more details about the approved
+# amendments:
+# <a href="http://www.fiji.gov.fj/publish/page_16198.shtml">
+# http://www.fiji.gov.fj/publish/page_16198.shtml
+# </a>
+
+# From Steffen Thorsen (2010-03-03):
+# The Cabinet in Fiji has decided to end DST about a month early, on
+# 2010-03-28 at 03:00.
+# The plan is to observe DST again, from 2010-10-24 to sometime in March
+# 2011 (last Sunday a good guess?).
+#
+# Official source:
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166">
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166
+# </a>
+#
+# A bit more background info here:
+# <a href="http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html">
+# http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html
+# </a>
+
+# From Alexander Krivenyshev (2010-10-24):
+# According to Radio Fiji and Fiji Times online, Fiji will end DST 3
+# weeks earlier than expected - on March 6, 2011, not March 27, 2011...
+# Here is confirmation from Government of the Republic of the Fiji Islands,
+# Ministry of Information (fiji.gov.fj) web site:
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=2608:daylight-savings&catid=71:press-releases&Itemid=155">
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=2608:daylight-savings&catid=71:press-releases&Itemid=155
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_fiji04.html">
+# http://www.worldtimezone.com/dst_news/dst_news_fiji04.html
+# </a>
+
+# From Steffen Thorsen (2011-10-03):
+# Now the dates have been confirmed, and at least our start date
+# assumption was correct (end date was one week wrong).
+#
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=4966:daylight-saving-starts-in-fiji&catid=71:press-releases&Itemid=155">
+# www.fiji.gov.fj/index.php?option=com_content&view=article&id=4966:daylight-saving-starts-in-fiji&catid=71:press-releases&Itemid=155
+# </a>
+# which says
+# Members of the public are reminded to change their time to one hour in
+# advance at 2am to 3am on October 23, 2011 and one hour back at 3am to
+# 2am on February 26 next year.
+
+# From Ken Rylander (2011-10-24)
+# Another change to the Fiji DST end date. In the TZ database the end date for
+# Fiji DST 2012, is currently Feb 26. This has been changed to Jan 22.
+#
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=5017:amendments-to-daylight-savings&catid=71:press-releases&Itemid=155">
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=5017:amendments-to-daylight-savings&catid=71:press-releases&Itemid=155
+# </a>
+# states:
+#
+# The end of daylight saving scheduled initially for the 26th of February 2012
+# has been brought forward to the 22nd of January 2012.
+# The commencement of daylight saving will remain unchanged and start
+# on the  23rd of October, 2011.
+
+# From the Fiji Government Online Portal (2012-08-21) via Steffen Thorsen:
+# The Minister for Labour, Industrial Relations and Employment Mr Jone Usamate
+# today confirmed that Fiji will start daylight savings at 2 am on Sunday 21st
+# October 2012 and end at 3 am on Sunday 20th January 2013.
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=6702&catid=71&Itemid=155
+#
+# From Paul Eggert (2012-08-31):
+# For now, guess a pattern of the penultimate Sundays in October and January.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Fiji	1998	1999	-	Nov	Sun>=1	2:00	1:00	S
+Rule	Fiji	1999	2000	-	Feb	lastSun	3:00	0	-
+Rule	Fiji	2009	only	-	Nov	29	2:00	1:00	S
+Rule	Fiji	2010	only	-	Mar	lastSun	3:00	0	-
+Rule	Fiji	2010	max	-	Oct	Sun>=18	2:00	1:00	S
+Rule	Fiji	2011	only	-	Mar	Sun>=1	3:00	0	-
+Rule	Fiji	2012	max	-	Jan	Sun>=18	3:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
+			12:00	Fiji	FJ%sT	# Fiji Time
+
+# French Polynesia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Gambier	 -8:59:48 -	LMT	1912 Oct	# Rikitea
+			 -9:00	-	GAMT	# Gambier Time
+Zone	Pacific/Marquesas -9:18:00 -	LMT	1912 Oct
+			 -9:30	-	MART	# Marquesas Time
+Zone	Pacific/Tahiti	 -9:58:16 -	LMT	1912 Oct	# Papeete
+			-10:00	-	TAHT	# Tahiti Time
+# Clipperton (near North America) is administered from French Polynesia;
+# it is uninhabited.
+
+# Guam
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Guam	-14:21:00 -	LMT	1844 Dec 31
+			 9:39:00 -	LMT	1901		# Agana
+			10:00	-	GST	2000 Dec 23	# Guam
+			10:00	-	ChST	# Chamorro Standard Time
+
+# Kiribati
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Tarawa	 11:32:04 -	LMT	1901		# Bairiki
+			 12:00	-	GILT		 # Gilbert Is Time
+Zone Pacific/Enderbury	-11:24:20 -	LMT	1901
+			-12:00	-	PHOT	1979 Oct # Phoenix Is Time
+			-11:00	-	PHOT	1995
+			 13:00	-	PHOT
+Zone Pacific/Kiritimati	-10:29:20 -	LMT	1901
+			-10:40	-	LINT	1979 Oct # Line Is Time
+			-10:00	-	LINT	1995
+			 14:00	-	LINT
+
+# N Mariana Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Saipan	-14:17:00 -	LMT	1844 Dec 31
+			 9:43:00 -	LMT	1901
+			 9:00	-	MPT	1969 Oct # N Mariana Is Time
+			10:00	-	MPT	2000 Dec 23
+			10:00	-	ChST	# Chamorro Standard Time
+
+# Marshall Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Majuro	11:24:48 -	LMT	1901
+			11:00	-	MHT	1969 Oct # Marshall Islands Time
+			12:00	-	MHT
+Zone Pacific/Kwajalein	11:09:20 -	LMT	1901
+			11:00	-	MHT	1969 Oct
+			-12:00	-	KWAT	1993 Aug 20	# Kwajalein Time
+			12:00	-	MHT
+
+# Micronesia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Chuuk	10:07:08 -	LMT	1901
+			10:00	-	CHUT			# Chuuk Time
+Zone Pacific/Pohnpei	10:32:52 -	LMT	1901		# Kolonia
+			11:00	-	PONT			# Pohnpei Time
+Zone Pacific/Kosrae	10:51:56 -	LMT	1901
+			11:00	-	KOST	1969 Oct	# Kosrae Time
+			12:00	-	KOST	1999
+			11:00	-	KOST
+
+# Nauru
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Nauru	11:07:40 -	LMT	1921 Jan 15	# Uaobe
+			11:30	-	NRT	1942 Mar 15	# Nauru Time
+			9:00	-	JST	1944 Aug 15
+			11:30	-	NRT	1979 May
+			12:00	-	NRT
+
+# New Caledonia
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NC	1977	1978	-	Dec	Sun>=1	0:00	1:00	S
+Rule	NC	1978	1979	-	Feb	27	0:00	0	-
+Rule	NC	1996	only	-	Dec	 1	2:00s	1:00	S
+# Shanks & Pottenger say the following was at 2:00; go with IATA.
+Rule	NC	1997	only	-	Mar	 2	2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Noumea	11:05:48 -	LMT	1912 Jan 13
+			11:00	NC	NC%sT
+
+
+###############################################################################
+
+# New Zealand
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NZ	1927	only	-	Nov	 6	2:00	1:00	S
+Rule	NZ	1928	only	-	Mar	 4	2:00	0	M
+Rule	NZ	1928	1933	-	Oct	Sun>=8	2:00	0:30	S
+Rule	NZ	1929	1933	-	Mar	Sun>=15	2:00	0	M
+Rule	NZ	1934	1940	-	Apr	lastSun	2:00	0	M
+Rule	NZ	1934	1940	-	Sep	lastSun	2:00	0:30	S
+Rule	NZ	1946	only	-	Jan	 1	0:00	0	S
+# Since 1957 Chatham has been 45 minutes ahead of NZ, but there's no
+# convenient notation for this so we must duplicate the Rule lines.
+Rule	NZ	1974	only	-	Nov	Sun>=1	2:00s	1:00	D
+Rule	Chatham	1974	only	-	Nov	Sun>=1	2:45s	1:00	D
+Rule	NZ	1975	only	-	Feb	lastSun	2:00s	0	S
+Rule	Chatham	1975	only	-	Feb	lastSun	2:45s	0	S
+Rule	NZ	1975	1988	-	Oct	lastSun	2:00s	1:00	D
+Rule	Chatham	1975	1988	-	Oct	lastSun	2:45s	1:00	D
+Rule	NZ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
+Rule	Chatham	1976	1989	-	Mar	Sun>=1	2:45s	0	S
+Rule	NZ	1989	only	-	Oct	Sun>=8	2:00s	1:00	D
+Rule	Chatham	1989	only	-	Oct	Sun>=8	2:45s	1:00	D
+Rule	NZ	1990	2006	-	Oct	Sun>=1	2:00s	1:00	D
+Rule	Chatham	1990	2006	-	Oct	Sun>=1	2:45s	1:00	D
+Rule	NZ	1990	2007	-	Mar	Sun>=15	2:00s	0	S
+Rule	Chatham	1990	2007	-	Mar	Sun>=15	2:45s	0	S
+Rule	NZ	2007	max	-	Sep	lastSun	2:00s	1:00	D
+Rule	Chatham	2007	max	-	Sep	lastSun	2:45s	1:00	D
+Rule	NZ	2008	max	-	Apr	Sun>=1	2:00s	0	S
+Rule	Chatham	2008	max	-	Apr	Sun>=1	2:45s	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Auckland	11:39:04 -	LMT	1868 Nov  2
+			11:30	NZ	NZ%sT	1946 Jan  1
+			12:00	NZ	NZ%sT
+Zone Pacific/Chatham	12:13:48 -	LMT	1957 Jan  1
+			12:45	Chatham	CHA%sT
+
+
+# Auckland Is
+# uninhabited; Maori and Moriori, colonial settlers, pastoralists, sealers,
+# and scientific personnel have wintered
+
+# Campbell I
+# minor whaling stations operated 1909/1914
+# scientific station operated 1941/1995;
+# previously whalers, sealers, pastoralists, and scientific personnel wintered
+# was probably like Pacific/Auckland
+
+###############################################################################
+
+
+# Niue
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Niue	-11:19:40 -	LMT	1901		# Alofi
+			-11:20	-	NUT	1951	# Niue Time
+			-11:30	-	NUT	1978 Oct 1
+			-11:00	-	NUT
+
+# Norfolk
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Norfolk	11:11:52 -	LMT	1901		# Kingston
+			11:12	-	NMT	1951	# Norfolk Mean Time
+			11:30	-	NFT		# Norfolk Time
+
+# Palau (Belau)
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Palau	8:57:56 -	LMT	1901		# Koror
+			9:00	-	PWT	# Palau Time
+
+# Papua New Guinea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Port_Moresby 9:48:40 -	LMT	1880
+			9:48:32	-	PMMT	1895	# Port Moresby Mean Time
+			10:00	-	PGT		# Papua New Guinea Time
+
+# Pitcairn
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Pitcairn	-8:40:20 -	LMT	1901		# Adamstown
+			-8:30	-	PNT	1998 Apr 27 00:00
+			-8:00	-	PST	# Pitcairn Standard Time
+
+# American Samoa
+Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
+			-11:22:48 -	LMT	1911
+			-11:30	-	SAMT	1950		# Samoa Time
+			-11:00	-	NST	1967 Apr	# N=Nome
+			-11:00	-	BST	1983 Nov 30	# B=Bering
+			-11:00	-	SST			# S=Samoa
+
+# Samoa
+
+# From Steffen Thorsen (2009-10-16):
+# We have been in contact with the government of Samoa again, and received
+# the following info:
+#
+# "Cabinet has now approved Daylight Saving to be effected next year
+# commencing from the last Sunday of September 2010 and conclude first
+# Sunday of April 2011."
+#
+# Background info:
+# <a href="http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html">
+# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
+# </a>
+#
+# Samoa's Daylight Saving Time Act 2009 is available here, but does not
+# contain any dates:
+# <a href="http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf">
+# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf
+# </a>
+
+# From Laupue Raymond Hughes (2010-10-07):
+# Please see
+# <a href="http://www.mcil.gov.ws">
+# http://www.mcil.gov.ws
+# </a>,
+# the Ministry of Commerce, Industry and Labour (sideframe) "Last Sunday
+# September 2010 (26/09/10) - adjust clocks forward from 12:00 midnight
+# to 01:00am and First Sunday April 2011 (03/04/11) - adjust clocks
+# backwards from 1:00am to 12:00am"
+
+# From Laupue Raymond Hughes (2011-03-07):
+# I believe this will be posted shortly on the website
+# <a href="http://www.mcil.gov.ws">
+# www.mcil.gov.ws
+# </a>
+#
+# PUBLIC NOTICE ON DAYLIGHT SAVING TIME
+#
+# Pursuant to the Daylight Saving Act 2009 and Cabinets decision,
+# businesses and the general public are hereby advised that daylight
+# saving time is on the first Saturday of April 2011 (02/04/11).
+#
+# The public is therefore advised that when the standard time strikes
+# the hour of four oclock (4.00am or 0400 Hours) on the 2nd April 2011,
+# then all instruments used to measure standard time are to be
+# adjusted/changed to three oclock (3:00am or 0300Hrs).
+#
+# Margaret Fruean ACTING CHIEF EXECUTIVE OFFICER MINISTRY OF COMMERCE,
+# INDUSTRY AND LABOUR 28th February 2011
+
+# From David Zuelke (2011-05-09):
+# Subject: Samoa to move timezone from east to west of international date line
+#
+# <a href="http://www.morningstar.co.uk/uk/markets/newsfeeditem.aspx?id=138501958347963">
+# http://www.morningstar.co.uk/uk/markets/newsfeeditem.aspx?id=138501958347963
+# </a>
+
+# From Mark Sim-Smith (2011-08-17):
+# I have been in contact with Leilani Tuala Warren from the Samoa Law
+# Reform Commission, and she has sent me a copy of the Bill that she
+# confirmed has been passed...Most of the sections are about maps rather
+# than the time zone change, but I'll paste the relevant bits below. But
+# the essence is that at midnight 29 Dec (UTC-11 I suppose), Samoa
+# changes from UTC-11 to UTC+13:
+#
+# International Date Line Bill 2011
+#
+# AN ACT to provide for the change to standard time in Samoa and to make
+# consequential amendments to the position of the International Date
+# Line, and for related purposes.
+#
+# BE IT ENACTED by the Legislative Assembly of Samoa in Parliament
+# assembled as follows:
+#
+# 1. Short title and commencement-(1) This Act may be cited as the
+# International Date Line Act 2011. (2) Except for section 5(3) this Act
+# commences at 12 o'clock midnight, on Thursday 29th December 2011. (3)
+# Section 5(3) commences on the date of assent by the Head of State.
+#
+# [snip]
+#
+# 3. Interpretation - [snip] "Samoa standard time" in this Act and any
+# other statute of Samoa which refers to 'Samoa standard time' means the
+# time 13 hours in advance of Co-ordinated Universal Time.
+#
+# 4. Samoa standard time - (1) Upon the commencement of this Act, Samoa
+# standard time shall be set at 13 hours in advance of Co-ordinated
+# Universal Time for the whole of Samoa. (2) All references to Samoa's
+# time zone and to Samoa standard time in Samoa in all legislation and
+# instruments after the commencement of this Act shall be references to
+# Samoa standard time as provided for in this Act. (3) Nothing in this
+# Act affects the provisions of the Daylight Saving Act 2009, except that
+# it defines Samoa standard time....
+
+# From Laupue Raymond Hughes (2011-09-02):
+# <a href="http://www.mcil.gov.ws/mcil_publications.html">
+# http://www.mcil.gov.ws/mcil_publications.html
+# </a>
+#
+# here is the official website publication for Samoa DST and dateline change
+#
+# DST
+# Year	End	Time	Start	Time
+# 2011	- - -	- - -	24 September	3:00am to 4:00am
+# 2012	01 April	4:00am to 3:00am	- - -	- - -
+#
+# Dateline Change skip Friday 30th Dec 2011
+# Thursday 29th December 2011	23:59:59 Hours
+# Saturday 31st December 2011	00:00:00 Hours
+#
+# Clarification by Tim Parenti (2012-01-03):
+# Although Samoa has used Daylight Saving Time in the 2010-2011 and 2011-2012
+# seasons, there is not yet any indication that this trend will continue on
+# a regular basis. For now, we have explicitly listed the transitions below.
+#
+# From Nicky (2012-09-10):
+# Daylight Saving Time commences on Sunday 30th September 2012 and
+# ends on Sunday 7th of April 2013.
+#
+# Please find link below for more information.
+# http://www.mcil.gov.ws/mcil_publications.html
+#
+# That publication also includes dates for Summer of 2013/4 as well
+# which give the impression of a pattern in selecting dates for the
+# future, so for now, we will guess this will continue.
+
+# Western Samoa
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	WS	2012	max	-	Sep	lastSun	3:00	1	D
+Rule	WS	2012	max	-	Apr	Sun>=1	4:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
+			-11:26:56 -	LMT	1911
+			-11:30	-	SAMT	1950		# Samoa Time
+			-11:00	-	WST	2010 Sep 26
+			-11:00	1:00	WSDT	2011 Apr 2 4:00
+			-11:00	-	WST	2011 Sep 24 3:00
+			-11:00	1:00	WSDT	2011 Dec 30
+			 13:00	1:00	WSDT	2012 Apr Sun>=1 4:00
+			 13:00	WS	WS%sT
+
+# Solomon Is
+# excludes Bougainville, for which see Papua New Guinea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Guadalcanal 10:39:48 -	LMT	1912 Oct	# Honiara
+			11:00	-	SBT	# Solomon Is Time
+
+# Tokelau Is
+#
+# From Gwillim Law (2011-12-29)
+# A correspondent informed me that Tokelau, like Samoa, will be skipping
+# December 31 this year ...
+#
+# From Steffen Thorsen (2012-07-25)
+# ... we double checked by calling hotels and offices based in Tokelau asking
+# about the time there, and they all told a time that agrees with UTC+13....
+# Shanks says UTC-10 from 1901 [but] ... there is a good chance the change
+# actually was to UTC-11 back then.
+#
+# From Paul Eggert (2012-07-25)
+# A Google Books snippet of Appendix to the Journals of the House of
+# Representatives of New Zealand, Session 1948,
+# <http://books.google.com/books?id=ZaVCAQAAIAAJ>, page 65, says Tokelau
+# was "11 hours slow on G.M.T."  Go with Thorsen and assume Shanks & Pottenger
+# are off by an hour starting in 1901.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Fakaofo	-11:24:56 -	LMT	1901
+			-11:00	-	TKT 2011 Dec 30	# Tokelau Time
+			13:00	-	TKT
+
+# Tonga
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Tonga	1999	only	-	Oct	 7	2:00s	1:00	S
+Rule	Tonga	2000	only	-	Mar	19	2:00s	0	-
+Rule	Tonga	2000	2001	-	Nov	Sun>=1	2:00	1:00	S
+Rule	Tonga	2001	2002	-	Jan	lastSun	2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Tongatapu	12:19:20 -	LMT	1901
+			12:20	-	TOT	1941 # Tonga Time
+			13:00	-	TOT	1999
+			13:00	Tonga	TO%sT
+
+# Tuvalu
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Funafuti	11:56:52 -	LMT	1901
+			12:00	-	TVT	# Tuvalu Time
+
+
+# US minor outlying islands
+
+# Howland, Baker
+# Howland was mined for guano by American companies 1857-1878 and British
+# 1886-1891; Baker was similar but exact dates are not known.
+# Inhabited by civilians 1935-1942; U.S. military bases 1943-1944;
+# uninhabited thereafter.
+# Howland observed Hawaii Standard Time (UTC-10:30) in 1937;
+# see page 206 of Elgen M. Long and Marie K. Long,
+# Amelia Earhart: the Mystery Solved, Simon & Schuster (2000).
+# So most likely Howland and Baker observed Hawaii Time from 1935
+# until they were abandoned after the war.
+
+# Jarvis
+# Mined for guano by American companies 1857-1879 and British 1883?-1891?.
+# Inhabited by civilians 1935-1942; IGY scientific base 1957-1958;
+# uninhabited thereafter.
+# no information; was probably like Pacific/Kiritimati
+
+# Johnston
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Johnston	-10:00	-	HST
+
+# Kingman
+# uninhabited
+
+# Midway
+#
+# From Mark Brader (2005-01-23):
+# [Fallacies and Fantasies of Air Transport History, by R.E.G. Davies,
+# published 1994 by Paladwr Press, McLean, VA, USA; ISBN 0-9626483-5-3]
+# reproduced a Pan American Airways timeables from 1936, for their weekly
+# "Orient Express" flights between San Francisco and Manila, and connecting
+# flights to Chicago and the US East Coast.  As it uses some time zone
+# designations that I've never seen before:....
+# Fri. 6:30A Lv. HONOLOLU (Pearl Harbor), H.I.   H.L.T. Ar. 5:30P Sun.
+#  "   3:00P Ar. MIDWAY ISLAND . . . . . . . . . M.L.T. Lv. 6:00A  "
+#
+Zone Pacific/Midway	-11:49:28 -	LMT	1901
+			-11:00	-	NST	1956 Jun  3
+			-11:00	1:00	NDT	1956 Sep  2
+			-11:00	-	NST	1967 Apr	# N=Nome
+			-11:00	-	BST	1983 Nov 30	# B=Bering
+			-11:00	-	SST			# S=Samoa
+
+# Palmyra
+# uninhabited since World War II; was probably like Pacific/Kiritimati
+
+# Wake
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Wake	11:06:28 -	LMT	1901
+			12:00	-	WAKT	# Wake Time
+
+
+# Vanuatu
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Vanuatu	1983	only	-	Sep	25	0:00	1:00	S
+Rule	Vanuatu	1984	1991	-	Mar	Sun>=23	0:00	0	-
+Rule	Vanuatu	1984	only	-	Oct	23	0:00	1:00	S
+Rule	Vanuatu	1985	1991	-	Sep	Sun>=23	0:00	1:00	S
+Rule	Vanuatu	1992	1993	-	Jan	Sun>=23	0:00	0	-
+Rule	Vanuatu	1992	only	-	Oct	Sun>=23	0:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Efate	11:13:16 -	LMT	1912 Jan 13		# Vila
+			11:00	Vanuatu	VU%sT	# Vanuatu Time
+
+# Wallis and Futuna
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Wallis	12:15:20 -	LMT	1901
+			12:00	-	WFT	# Wallis & Futuna Time
+
+###############################################################################
+
+# NOTES
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
+# I found in the UCLA library.
+#
+# A reliable and entertaining source about time zones is
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+#
+# I invented the abbreviations marked `*' in the following table;
+# the rest are from earlier versions of this file, or from other sources.
+# Corrections are welcome!
+#		std dst
+#		LMT	Local Mean Time
+#	  8:00	WST WST	Western Australia
+#	  8:45	CWST CWST Central Western Australia*
+#	  9:00	JST	Japan
+#	  9:30	CST CST	Central Australia
+#	 10:00	EST EST	Eastern Australia
+#	 10:00	ChST	Chamorro
+#	 10:30	LHST LHST Lord Howe*
+#	 11:30	NZMT NZST New Zealand through 1945
+#	 12:00	NZST NZDT New Zealand 1946-present
+#	 12:45	CHAST CHADT Chatham*
+#	-11:00	SST	Samoa
+#	-10:00	HST	Hawaii
+#	- 8:00	PST	Pitcairn*
+#
+# See the `northamerica' file for Hawaii.
+# See the `southamerica' file for Easter I and the Galapagos Is.
+
+###############################################################################
+
+# Australia
+
+# From Paul Eggert (2005-12-08):
+# <a href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">
+# Implementation Dates of Daylight Saving Time within Australia
+# </a> summarizes daylight saving issues in Australia.
+
+# From Arthur David Olson (2005-12-12):
+# <a href="http://www.lawlink.nsw.gov.au/lawlink/Corporate/ll_agdinfo.nsf/pages/community_relations_daylight_saving">
+# Lawlink NSW:Daylight Saving in New South Wales
+# </a> covers New South Wales in particular.
+
+# From John Mackin (1991-03-06):
+# We in Australia have _never_ referred to DST as `daylight' time.
+# It is called `summer' time.  Now by a happy coincidence, `summer'
+# and `standard' happen to start with the same letter; hence, the
+# abbreviation does _not_ change...
+# The legislation does not actually define abbreviations, at least
+# in this State, but the abbreviation is just commonly taken to be the
+# initials of the phrase, and the legislation here uniformly uses
+# the phrase `summer time' and does not use the phrase `daylight
+# time'.
+# Announcers on the Commonwealth radio network, the ABC (for Australian
+# Broadcasting Commission), use the phrases `Eastern Standard Time'
+# or `Eastern Summer Time'.  (Note, though, that as I say in the
+# current australasia file, there is really no such thing.)  Announcers
+# on its overseas service, Radio Australia, use the same phrases
+# prefixed by the word `Australian' when referring to local times;
+# time announcements on that service, naturally enough, are made in UTC.
+
+# From Arthur David Olson (1992-03-08):
+# Given the above, what's chosen for year-round use is:
+#	CST	for any place operating at a GMTOFF of 9:30
+#	WST	for any place operating at a GMTOFF of 8:00
+#	EST	for any place operating at a GMTOFF of 10:00
+
+# From Chuck Soper (2006-06-01):
+# I recently found this Australian government web page on time zones:
+# <http://www.australia.gov.au/about-australia-13time>
+# And this government web page lists time zone names and abbreviations:
+# <http://www.bom.gov.au/climate/averages/tables/daysavtm.shtml>
+
+# From Paul Eggert (2001-04-05), summarizing a long discussion about "EST"
+# versus "AEST" etc.:
+#
+# I see the following points of dispute:
+#
+# * How important are unique time zone abbreviations?
+#
+#   Here I tend to agree with the point (most recently made by Chris
+#   Newman) that unique abbreviations should not be essential for proper
+#   operation of software.  We have other instances of ambiguity
+#   (e.g. "IST" denoting both "Israel Standard Time" and "Indian
+#   Standard Time"), and they are not likely to go away any time soon.
+#   In the old days, some software mistakenly relied on unique
+#   abbreviations, but this is becoming less true with time, and I don't
+#   think it's that important to cater to such software these days.
+#
+#   On the other hand, there is another motivation for unambiguous
+#   abbreviations: it cuts down on human confusion.  This is
+#   particularly true for Australia, where "EST" can mean one thing for
+#   time T and a different thing for time T plus 1 second.
+#
+# * Does the relevant legislation indicate which abbreviations should be used?
+#
+#   Here I tend to think that things are a mess, just as they are in
+#   many other countries.  We Americans are currently disagreeing about
+#   which abbreviation to use for the newly legislated Chamorro Standard
+#   Time, for example.
+#
+#   Personally, I would prefer to use common practice; I would like to
+#   refer to legislation only for examples of common practice, or as a
+#   tiebreaker.
+#
+# * Do Australians more often use "Eastern Daylight Time" or "Eastern
+#   Summer Time"?  Do they typically prefix the time zone names with
+#   the word "Australian"?
+#
+#   My own impression is that both "Daylight Time" and "Summer Time" are
+#   common and are widely understood, but that "Summer Time" is more
+#   popular; and that the leading "A" is also common but is omitted more
+#   often than not.  I just used AltaVista advanced search and got the
+#   following count of page hits:
+#
+#     1,103 "Eastern Summer Time" AND domain:au
+#       971 "Australian Eastern Summer Time" AND domain:au
+#       613 "Eastern Daylight Time" AND domain:au
+#       127 "Australian Eastern Daylight Time" AND domain:au
+#
+#   Here "Summer" seems quite a bit more popular than "Daylight",
+#   particularly when we know the time zone is Australian and not US,
+#   say.  The "Australian" prefix seems to be popular for Eastern Summer
+#   Time, but unpopular for Eastern Daylight Time.
+#
+#   For abbreviations, tools like AltaVista are less useful because of
+#   ambiguity.  Many hits are not really time zones, unfortunately, and
+#   many hits denote US time zones and not Australian ones.  But here
+#   are the hit counts anyway:
+#
+#     161,304 "EST" and domain:au
+#      25,156 "EDT" and domain:au
+#      18,263 "AEST" and domain:au
+#      10,416 "AEDT" and domain:au
+#
+#      14,538 "CST" and domain:au
+#       5,728 "CDT" and domain:au
+#         176 "ACST" and domain:au
+#          29 "ACDT" and domain:au
+#
+#       7,539 "WST" and domain:au
+#          68 "AWST" and domain:au
+#
+#   This data suggest that Australians tend to omit the "A" prefix in
+#   practice.  The situation for "ST" versus "DT" is less clear, given
+#   the ambiguities involved.
+#
+# * How do Australians feel about the abbreviations in the tz database?
+#
+#   If you just count Australians on this list, I count 2 in favor and 3
+#   against.  One of the "against" votes (David Keegel) counseled delay,
+#   saying that both AEST/AEDT and EST/EST are widely used and
+#   understood in Australia.
+
+# From Paul Eggert (1995-12-19):
+# Shanks & Pottenger report 2:00 for all autumn changes in Australia and NZ.
+# Mark Prior writes that his newspaper
+# reports that NSW's fall 1995 change will occur at 2:00,
+# but Robert Elz says it's been 3:00 in Victoria since 1970
+# and perhaps the newspaper's `2:00' is referring to standard time.
+# For now we'll continue to assume 2:00s for changes since 1960.
+
+# From Eric Ulevik (1998-01-05):
+#
+# Here are some URLs to Australian time legislation. These URLs are stable,
+# and should probably be included in the data file. There are probably more
+# relevant entries in this database.
+#
+# NSW (including LHI and Broken Hill):
+# <a href="http://www.austlii.edu.au/au/legis/nsw/consol_act/sta1987137/index.html">
+# Standard Time Act 1987 (updated 1995-04-04)
+# </a>
+# ACT
+# <a href="http://www.austlii.edu.au/au/legis/act/consol_act/stasta1972279/index.html">
+# Standard Time and Summer Time Act 1972
+# </a>
+# SA
+# <a href="http://www.austlii.edu.au/au/legis/sa/consol_act/sta1898137/index.html">
+# Standard Time Act, 1898
+# </a>
+
+# From David Grosz (2005-06-13):
+# It was announced last week that Daylight Saving would be extended by
+# one week next year to allow for the 2006 Commonwealth Games.
+# Daylight Saving is now to end for next year only on the first Sunday
+# in April instead of the last Sunday in March.
+#
+# From Gwillim Law (2005-06-14):
+# I did some Googling and found that all of those states (and territory) plan
+# to extend DST together in 2006.
+# ACT: http://www.cmd.act.gov.au/mediareleases/fileread.cfm?file=86.txt
+# New South Wales: http://www.thecouriermail.news.com.au/common/story_page/0,5936,15538869%255E1702,00.html
+# South Australia: http://www.news.com.au/story/0,10117,15555031-1246,00.html
+# Tasmania: http://www.media.tas.gov.au/release.php?id=14772
+# Victoria: I wasn't able to find anything separate, but the other articles
+# allude to it.
+# But not Queensland
+# http://www.news.com.au/story/0,10117,15564030-1248,00.html.
+
+# Northern Territory
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# # The NORTHERN TERRITORY..  [ Courtesy N.T. Dept of the Chief Minister ]
+# #					[ Nov 1990 ]
+# #	N.T. have never utilised any DST due to sub-tropical/tropical location.
+# ...
+# Zone        Australia/North         9:30    -       CST
+
+# From Bradley White (1991-03-04):
+# A recent excerpt from an Australian newspaper...
+# the Northern Territory do[es] not have daylight saving.
+
+# Western Australia
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# #  The state of WESTERN AUSTRALIA..  [ Courtesy W.A. dept Premier+Cabinet ]
+# #						[ Nov 1990 ]
+# #	W.A. suffers from a great deal of public and political opposition to
+# #	DST in principle. A bill is brought before parliament in most years, but
+# #	usually defeated either in the upper house, or in party caucus
+# #	before reaching parliament.
+# ...
+# Zone	Australia/West		8:00	AW	%sST
+# ...
+# Rule	AW	1974	only	-	Oct	lastSun	2:00	1:00	D
+# Rule	AW	1975	only	-	Mar	Sun>=1	3:00	0	W
+# Rule	AW	1983	only	-	Oct	lastSun	2:00	1:00	D
+# Rule	AW	1984	only	-	Mar	Sun>=1	3:00	0	W
+
+# From Bradley White (1991-03-04):
+# A recent excerpt from an Australian newspaper...
+# Western Australia...do[es] not have daylight saving.
+
+# From John D. Newman via Bradley White (1991-11-02):
+# Western Australia is still on "winter time". Some DH in Sydney
+# rang me at home a few days ago at 6.00am. (He had just arrived at
+# work at 9.00am.)
+# W.A. is switching to Summer Time on Nov 17th just to confuse
+# everybody again.
+
+# From Arthur David Olson (1992-03-08):
+# The 1992 ending date used in the rules is a best guess;
+# it matches what was used in the past.
+
+# <a href="http://www.bom.gov.au/faq/faqgen.htm">
+# The Australian Bureau of Meteorology FAQ
+# </a> (1999-09-27) writes that Giles Meteorological Station uses
+# South Australian time even though it's located in Western Australia.
+
+# Queensland
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# #   The state of QUEENSLAND.. [ Courtesy Qld. Dept Premier Econ&Trade Devel ]
+# #						[ Dec 1990 ]
+# ...
+# Zone	Australia/Queensland	10:00	AQ	%sST
+# ...
+# Rule	AQ	1971	only	-	Oct	lastSun	2:00	1:00	D
+# Rule	AQ	1972	only	-	Feb	lastSun	3:00	0	E
+# Rule	AQ	1989	max	-	Oct	lastSun	2:00	1:00	D
+# Rule	AQ	1990	max	-	Mar	Sun>=1	3:00	0	E
+
+# From Bradley White (1989-12-24):
+# "Australia/Queensland" now observes daylight time (i.e. from
+# October 1989).
+
+# From Bradley White (1991-03-04):
+# A recent excerpt from an Australian newspaper...
+# ...Queensland...[has] agreed to end daylight saving
+# at 3am tomorrow (March 3)...
+
+# From John Mackin (1991-03-06):
+# I can certainly confirm for my part that Daylight Saving in NSW did in fact
+# end on Sunday, 3 March.  I don't know at what hour, though.  (It surprised
+# me.)
+
+# From Bradley White (1992-03-08):
+# ...there was recently a referendum in Queensland which resulted
+# in the experimental daylight saving system being abandoned. So, ...
+# ...
+# Rule	QLD	1989	1991	-	Oct	lastSun	2:00	1:00	D
+# Rule	QLD	1990	1992	-	Mar	Sun>=1	3:00	0	S
+# ...
+
+# From Arthur David Olson (1992-03-08):
+# The chosen rules the union of the 1971/1972 change and the 1989-1992 changes.
+
+# From Christopher Hunt (2006-11-21), after an advance warning
+# from Jesper Norgaard Welen (2006-11-01):
+# WA are trialing DST for three years.
+# <http://www.parliament.wa.gov.au/parliament/bills.nsf/9A1B183144403DA54825721200088DF1/$File/Bill175-1B.pdf>
+
+# From Rives McDow (2002-04-09):
+# The most interesting region I have found consists of three towns on the
+# southern coast....  South Australia observes daylight saving time; Western
+# Australia does not.  The two states are one and a half hours apart.  The
+# residents decided to forget about this nonsense of changing the clock so
+# much and set the local time 20 hours and 45 minutes from the
+# international date line, or right in the middle of the time of South
+# Australia and Western Australia....
+#
+# From Paul Eggert (2002-04-09):
+# This is confirmed by the section entitled
+# "What's the deal with time zones???" in
+# <http://www.earthsci.unimelb.edu.au/~awatkins/null.html>.
+#
+# From Alex Livingston (2006-12-07):
+# ... it was just on four years ago that I drove along the Eyre Highway,
+# which passes through eastern Western Australia close to the southern
+# coast of the continent.
+#
+# I paid particular attention to the time kept there. There can be no
+# dispute that UTC+08:45 was considered "the time" from the border
+# village just inside the border with South Australia to as far west
+# as just east of Caiguna. There can also be no dispute that Eucla is
+# the largest population centre in this zone....
+#
+# Now that Western Australia is observing daylight saving, the
+# question arose whether this part of the state would follow suit. I
+# just called the border village and confirmed that indeed they have,
+# meaning that they are now observing UTC+09:45.
+#
+# (2006-12-09):
+# I personally doubt that either experimentation with daylight saving
+# in WA or its introduction in SA had anything to do with the genesis
+# of this time zone.  My hunch is that it's been around since well
+# before 1975.  I remember seeing it noted on road maps decades ago.
+
+# From Paul Eggert (2006-12-15):
+# For lack of better info, assume the tradition dates back to the
+# introduction of standard time in 1895.
+
+
+# southeast Australia
+#
+# From Paul Eggert (2007-07-23):
+# Starting autumn 2008 Victoria, NSW, South Australia, Tasmania and the ACT
+# end DST the first Sunday in April and start DST the first Sunday in October.
+# http://www.theage.com.au/news/national/daylight-savings-to-span-six-months/2007/06/27/1182623966703.html
+
+
+# South Australia
+
+# From Bradley White (1991-03-04):
+# A recent excerpt from an Australian newspaper...
+# ...South Australia...[has] agreed to end daylight saving
+# at 3am tomorrow (March 3)...
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# #   The state of SOUTH AUSTRALIA....[ Courtesy of S.A. Dept of Labour ]
+# #						[ Nov 1990 ]
+# ...
+# Zone	Australia/South		9:30	AS	%sST
+# ...
+# Rule	 AS	1971	max	-	Oct	lastSun	2:00	1:00	D
+# Rule	 AS	1972	1985	-	Mar	Sun>=1	3:00	0	C
+# Rule	 AS	1986	1990	-	Mar	Sun>=15	3:00	0	C
+# Rule	 AS	1991	max	-	Mar	Sun>=1	3:00	0	C
+
+# From Bradley White (1992-03-11):
+# Recent correspondence with a friend in Adelaide
+# contained the following exchange:  "Due to the Adelaide Festival,
+# South Australia delays setting back our clocks for a few weeks."
+
+# From Robert Elz (1992-03-13):
+# I heard that apparently (or at least, it appears that)
+# South Aus will have an extra 3 weeks daylight saving every even
+# numbered year (from 1990).  That's when the Adelaide Festival
+# is on...
+
+# From Robert Elz (1992-03-16, 00:57:07 +1000):
+# DST didn't end in Adelaide today (yesterday)....
+# But whether it's "4th Sunday" or "2nd last Sunday" I have no idea whatever...
+# (it's just as likely to be "the Sunday we pick for this year"...).
+
+# From Bradley White (1994-04-11):
+# If Sun, 15 March, 1992 was at +1030 as kre asserts, but yet Sun, 20 March,
+# 1994 was at +0930 as John Connolly's customer seems to assert, then I can
+# only conclude that the actual rule is more complicated....
+
+# From John Warburton (1994-10-07):
+# The new Daylight Savings dates for South Australia ...
+# was gazetted in the Government Hansard on Sep 26 1994....
+# start on last Sunday in October and end in last sunday in March.
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# Tasmania
+
+# The rules for 1967 through 1991 were reported by George Shepherd
+# via Simon Woodhead via Robert Elz (1991-03-06):
+# #  The state of TASMANIA.. [Courtesy Tasmanian Dept of Premier + Cabinet ]
+# #					[ Nov 1990 ]
+
+# From Bill Hart via Guy Harris (1991-10-10):
+# Oh yes, the new daylight savings rules are uniquely tasmanian, we have
+# 6 weeks a year now when we are out of sync with the rest of Australia
+# (but nothing new about that).
+
+# From Alex Livingston (1999-10-04):
+# I heard on the ABC (Australian Broadcasting Corporation) radio news on the
+# (long) weekend that Tasmania, which usually goes its own way in this regard,
+# has decided to join with most of NSW, the ACT, and most of Victoria
+# (Australia) and start daylight saving on the last Sunday in August in 2000
+# instead of the first Sunday in October.
+
+# Sim Alam (2000-07-03) reported a legal citation for the 2000/2001 rules:
+# http://www.thelaw.tas.gov.au/fragview/42++1968+GS3A@EN+2000070300
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# Victoria
+
+# The rules for 1971 through 1991 were reported by George Shepherd
+# via Simon Woodhead via Robert Elz (1991-03-06):
+# #   The state of VICTORIA.. [ Courtesy of Vic. Dept of Premier + Cabinet ]
+# #						[ Nov 1990 ]
+
+# From Scott Harrington (2001-08-29):
+# On KQED's "City Arts and Lectures" program last night I heard an
+# interesting story about daylight savings time.  Dr. John Heilbron was
+# discussing his book "The Sun in the Church: Cathedrals as Solar
+# Observatories"[1], and in particular the Shrine of Remembrance[2] located
+# in Melbourne, Australia.
+#
+# Apparently the shrine's main purpose is a beam of sunlight which
+# illuminates a special spot on the floor at the 11th hour of the 11th day
+# of the 11th month (Remembrance Day) every year in memory of Australia's
+# fallen WWI soldiers.  And if you go there on Nov. 11, at 11am local time,
+# you will indeed see the sunbeam illuminate the special spot at the
+# expected time.
+#
+# However, that is only because of some special mirror contraption that had
+# to be employed, since due to daylight savings time, the true solar time of
+# the remembrance moment occurs one hour later (or earlier?).  Perhaps
+# someone with more information on this jury-rig can tell us more.
+#
+# [1] http://www.hup.harvard.edu/catalog/HEISUN.html
+# [2] http://www.shrine.org.au
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# New South Wales
+
+# From Arthur David Olson:
+# New South Wales and subjurisdictions have their own ideas of a fun time.
+# Based on law library research by John Mackin,
+# who notes:
+#	In Australia, time is not legislated federally, but rather by the
+#	individual states.  Thus, while such terms as ``Eastern Standard Time''
+#	[I mean, of course, Australian EST, not any other kind] are in common
+#	use, _they have NO REAL MEANING_, as they are not defined in the
+#	legislation.  This is very important to understand.
+#	I have researched New South Wales time only...
+
+# From Eric Ulevik (1999-05-26):
+# DST will start in NSW on the last Sunday of August, rather than the usual
+# October in 2000.  [See: Matthew Moore,
+# <a href="http://www.smh.com.au/news/9905/26/pageone/pageone4.html">
+# Two months more daylight saving
+# </a>
+# Sydney Morning Herald (1999-05-26).]
+
+# From Paul Eggert (1999-09-27):
+# See the following official NSW source:
+# <a href="http://dir.gis.nsw.gov.au/cgi-bin/genobject/document/other/daylightsaving/tigGmZ">
+# Daylight Saving in New South Wales.
+# </a>
+#
+# Narrabri Shire (NSW) council has announced it will ignore the extension of
+# daylight saving next year.  See:
+# <a href="http://abc.net.au/news/regionals/neweng/monthly/regeng-22jul1999-1.htm">
+# Narrabri Council to ignore daylight saving
+# </a> (1999-07-22).  For now, we'll wait to see if this really happens.
+#
+# Victoria will following NSW.  See:
+# <a href="http://abc.net.au/local/news/olympics/1999/07/item19990728112314_1.htm">
+# Vic to extend daylight saving
+# </a> (1999-07-28).
+#
+# However, South Australia rejected the DST request.  See:
+# <a href="http://abc.net.au/news/olympics/1999/07/item19990719151754_1.htm">
+# South Australia rejects Olympics daylight savings request
+# </a> (1999-07-19).
+#
+# Queensland also will not observe DST for the Olympics.  See:
+# <a href="http://abc.net.au/news/olympics/1999/06/item19990601114608_1.htm">
+# Qld says no to daylight savings for Olympics
+# </a> (1999-06-01), which quotes Queensland Premier Peter Beattie as saying
+# ``Look you've got to remember in my family when this came up last time
+# I voted for it, my wife voted against it and she said to me it's all very
+# well for you, you don't have to worry about getting the children out of
+# bed, getting them to school, getting them to sleep at night.
+# I've been through all this argument domestically...my wife rules.''
+#
+# Broken Hill will stick with South Australian time in 2000.  See:
+# <a href="http://abc.net.au/news/regionals/brokenh/monthly/regbrok-21jul1999-6.htm">
+# Broken Hill to be behind the times
+# </a> (1999-07-21).
+
+# IATA SSIM (1998-09) says that the spring 2000 change for Australian
+# Capital Territory, New South Wales except Lord Howe Island and Broken
+# Hill, and Victoria will be August 27, presumably due to the Sydney Olympics.
+
+# From Eric Ulevik, referring to Sydney's Sun Herald (2000-08-13), page 29:
+# The Queensland Premier Peter Beattie is encouraging northern NSW
+# towns to use Queensland time.
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# Yancowinna
+
+# From John Mackin (1989-01-04):
+# `Broken Hill' means the County of Yancowinna.
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# # YANCOWINNA..  [ Confirmation courtesy of Broken Hill Postmaster ]
+# #					[ Dec 1990 ]
+# ...
+# # Yancowinna uses Central Standard Time, despite [its] location on the
+# # New South Wales side of the S.A. border. Most business and social dealings
+# # are with CST zones, therefore CST is legislated by local government
+# # although the switch to Summer Time occurs in line with N.S.W. There have
+# # been years when this did not apply, but the historical data is not
+# # presently available.
+# Zone	Australia/Yancowinna	9:30	 AY	%sST
+# ...
+# Rule	 AY	1971	1985	-	Oct	lastSun	2:00	1:00	D
+# Rule	 AY	1972	only	-	Feb	lastSun	3:00	0	C
+# [followed by other Rules]
+
+# Lord Howe Island
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# LHI...		[ Courtesy of Pauline Van Winsen ]
+#					[ Dec 1990 ]
+# Lord Howe Island is located off the New South Wales coast, and is half an
+# hour ahead of NSW time.
+
+# From James Lonergan, Secretary, Lord Howe Island Board (2000-01-27):
+# Lord Howe Island summer time in 2000/2001 will commence on the same
+# date as the rest of NSW (i.e. 2000-08-27).  For your information the
+# Lord Howe Island Board (controlling authority for the Island) is
+# seeking the community's views on various options for summer time
+# arrangements on the Island, e.g. advance clocks by 1 full hour
+# instead of only 30 minutes.  [Dependent] on the wishes of residents
+# the Board may approach the NSW government to change the existing
+# arrangements.  The starting date for summer time on the Island will
+# however always coincide with the rest of NSW.
+
+# From James Lonergan, Secretary, Lord Howe Island Board (2000-10-25):
+# Lord Howe Island advances clocks by 30 minutes during DST in NSW and retards
+# clocks by 30 minutes when DST finishes. Since DST was most recently
+# introduced in NSW, the "changeover" time on the Island has been 02:00 as
+# shown on clocks on LHI. I guess this means that for 30 minutes at the start
+# of DST, LHI is actually 1 hour ahead of the rest of NSW.
+
+# From Paul Eggert (2006-03-22):
+# For Lord Howe dates we use Shanks & Pottenger through 1989, and
+# Lonergan thereafter.  For times we use Lonergan.
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# From Steffen Thorsen (2009-04-28):
+# According to the official press release, South Australia's extended daylight
+# saving period will continue with the same rules as used during the 2008-2009
+# summer (southern hemisphere).
+#
+# From
+# <a href="http://www.safework.sa.gov.au/uploaded_files/DaylightDatesSet.pdf">
+# http://www.safework.sa.gov.au/uploaded_files/DaylightDatesSet.pdf
+# </a>
+# The extended daylight saving period that South Australia has been trialling
+# for over the last year is now set to be ongoing.
+# Daylight saving will continue to start on the first Sunday in October each
+# year and finish on the first Sunday in April the following year.
+# Industrial Relations Minister, Paul Caica, says this provides South Australia
+# with a consistent half hour time difference with NSW, Victoria, Tasmania and
+# the ACT for all 52 weeks of the year...
+#
+# We have a wrap-up here:
+# <a href="http://www.timeanddate.com/news/time/south-australia-extends-dst.html">
+# http://www.timeanddate.com/news/time/south-australia-extends-dst.html
+# </a>
+###############################################################################
+
+# New Zealand
+
+# From Mark Davies (1990-10-03):
+# the 1989/90 year was a trial of an extended "daylight saving" period.
+# This trial was deemed successful and the extended period adopted for
+# subsequent years (with the addition of a further week at the start).
+# source -- phone call to Ministry of Internal Affairs Head Office.
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# # The Country of New Zealand   (Australia's east island -) Gee they hate that!
+# #				   or is Australia the west island of N.Z.
+# #	[ courtesy of Geoff Tribble.. Auckland N.Z. ]
+# #				[ Nov 1990 ]
+# ...
+# Rule	NZ      1974    1988	-	Oct	lastSun	2:00	1:00	D
+# Rule	NZ	1989	max	-	Oct	Sun>=1	2:00	1:00	D
+# Rule	NZ      1975    1989	-	Mar	Sun>=1	3:00	0	S
+# Rule	NZ	1990	max	-	Mar	lastSun	3:00	0	S
+# ...
+# Zone	NZ			12:00	NZ		NZ%sT	# New Zealand
+# Zone	NZ-CHAT			12:45	-		NZ-CHAT # Chatham Island
+
+# From Arthur David Olson (1992-03-08):
+# The chosen rules use the Davies October 8 values for the start of DST in 1989
+# rather than the October 1 value.
+
+# From Paul Eggert (1995-12-19);
+# Shank & Pottenger report 2:00 for all autumn changes in Australia and NZ.
+# Robert Uzgalis writes that the New Zealand Daylight
+# Savings Time Order in Council dated 1990-06-18 specifies 2:00 standard
+# time on both the first Sunday in October and the third Sunday in March.
+# As with Australia, we'll assume the tradition is 2:00s, not 2:00.
+#
+# From Paul Eggert (2006-03-22):
+# The Department of Internal Affairs (DIA) maintains a brief history,
+# as does Carol Squires; see tz-link.htm for the full references.
+# Use these sources in preference to Shanks & Pottenger.
+#
+# For Chatham, IATA SSIM (1991/1999) gives the NZ rules but with
+# transitions at 2:45 local standard time; this confirms that Chatham
+# is always exactly 45 minutes ahead of Auckland.
+
+# From Colin Sharples (2007-04-30):
+# DST will now start on the last Sunday in September, and end on the
+# first Sunday in April.  The changes take effect this year, meaning
+# that DST will begin on 2007-09-30 2008-04-06.
+# http://www.dia.govt.nz/diawebsite.nsf/wpg_URL/Services-Daylight-Saving-Daylight-saving-to-be-extended
+
+###############################################################################
+
+
+# Fiji
+
+# Howse writes (p 153) that in 1879 the British governor of Fiji
+# enacted an ordinance standardizing the islands on Antipodean Time
+# instead of the American system (which was one day behind).
+
+# From Rives McDow (1998-10-08):
+# Fiji will introduce DST effective 0200 local time, 1998-11-01
+# until 0300 local time 1999-02-28.  Each year the DST period will
+# be from the first Sunday in November until the last Sunday in February.
+
+# From Paul Eggert (2000-01-08):
+# IATA SSIM (1999-09) says DST ends 0100 local time.  Go with McDow.
+
+# From the BBC World Service (1998-10-31 11:32 UTC):
+# The Fijiian government says the main reasons for the time change is to
+# improve productivity and reduce road accidents.  But correspondents say it
+# also hopes the move will boost Fiji's ability to compete with other pacific
+# islands in the effort to attract tourists to witness the dawning of the new
+# millenium.
+
+# http://www.fiji.gov.fj/press/2000_09/2000_09_13-05.shtml (2000-09-13)
+# reports that Fiji has discontinued DST.
+
+# Johnston
+
+# Johnston data is from usno1995.
+
+
+# Kiribati
+
+# From Paul Eggert (1996-01-22):
+# Today's _Wall Street Journal_ (page 1) reports that Kiribati
+# ``declared it the same day [throughout] the country as of Jan. 1, 1995''
+# as part of the competition to be first into the 21st century.
+
+
+# Kwajalein
+
+# In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
+# I wonder what happened in Kwajalein, where there was NO Friday,
+# 1993-08-20.  Thursday night at midnight Kwajalein switched sides with
+# respect to the International Date Line, to rejoin its fellow islands,
+# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
+
+
+# N Mariana Is, Guam
+
+# Howse writes (p 153) ``The Spaniards, on the other hand, reached the
+# Philippines and the Ladrones from America,'' and implies that the Ladrones
+# (now called the Marianas) kept American date for quite some time.
+# For now, we assume the Ladrones switched at the same time as the Philippines;
+# see Asia/Manila.
+
+# US Public Law 106-564 (2000-12-23) made UTC+10 the official standard time,
+# under the name "Chamorro Standard Time".  There is no official abbreviation,
+# but Congressman Robert A. Underwood, author of the bill that became law,
+# wrote in a press release (2000-12-27) that he will seek the use of "ChST".
+
+
+# Micronesia
+
+# Alan Eugene Davis writes (1996-03-16),
+# ``I am certain, having lived there for the past decade, that "Truk"
+# (now properly known as Chuuk) ... is in the time zone GMT+10.''
+#
+# Shanks & Pottenger write that Truk switched from UTC+10 to UTC+11
+# on 1978-10-01; ignore this for now.
+
+# From Paul Eggert (1999-10-29):
+# The Federated States of Micronesia Visitors Board writes in
+# <a href="http://www.fsmgov.org/info/clocks.html">
+# The Federated States of Micronesia - Visitor Information
+# </a> (1999-01-26)
+# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
+# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
+
+
+# Midway
+
+# From Charles T O'Connor, KMTH DJ (1956),
+# quoted in the KTMH section of the Radio Heritage Collection
+# <http://radiodx.com/spdxr/KMTH.htm> (2002-12-31):
+# For the past two months we've been on what is known as Daylight
+# Saving Time.  This time has put us on air at 5am in the morning,
+# your time down there in New Zealand.  Starting September 2, 1956
+# we'll again go back to Standard Time.  This'll mean that we'll go to
+# air at 6am your time.
+#
+# From Paul Eggert (2003-03-23):
+# We don't know the date of that quote, but we'll guess they
+# started DST on June 3.  Possibly DST was observed other years
+# in Midway, but we have no record of it.
+
+
+# Pitcairn
+
+# From Rives McDow (1999-11-08):
+# A Proclamation was signed by the Governor of Pitcairn on the 27th March 1998
+# with regard to Pitcairn Standard Time.  The Proclamation is as follows.
+#
+#	The local time for general purposes in the Islands shall be
+#	Co-ordinated Universal time minus 8 hours and shall be known
+#	as Pitcairn Standard Time.
+#
+# ... I have also seen Pitcairn listed as UTC minus 9 hours in several
+# references, and can only assume that this was an error in interpretation
+# somehow in light of this proclamation.
+
+# From Rives McDow (1999-11-09):
+# The Proclamation regarding Pitcairn time came into effect on 27 April 1998
+# ... at midnight.
+
+# From Howie Phelps (1999-11-10), who talked to a Pitcairner via shortwave:
+# Betty Christian told me yesterday that their local time is the same as
+# Pacific Standard Time. They used to be 1/2 hour different from us here in
+# Sacramento but it was changed a couple of years ago.
+
+
+# Samoa
+
+# Howse writes (p 153, citing p 10 of the 1883-11-18 New York Herald)
+# that in 1879 the King of Samoa decided to change
+# ``the date in his kingdom from the Antipodean to the American system,
+# ordaining -- by a masterpiece of diplomatic flattery -- that
+# the Fourth of July should be celebrated twice in that year.''
+
+
+# Tonga
+
+# From Paul Eggert (1996-01-22):
+# Today's _Wall Street Journal_ (p 1) reports that ``Tonga has been plotting
+# to sneak ahead of [New Zealanders] by introducing daylight-saving time.''
+# Since Kiribati has moved the Date Line it's not clear what Tonga will do.
+
+# Don Mundell writes in the 1997-02-20 Tonga Chronicle
+# <a href="http://www.tongatapu.net.to/tonga/homeland/timebegins.htm">
+# How Tonga became `The Land where Time Begins'
+# </a>:
+
+# Until 1941 Tonga maintained a standard time 50 minutes ahead of NZST
+# 12 hours and 20 minutes ahead of GMT.  When New Zealand adjusted its
+# standard time in 1940s, Tonga had the choice of subtracting from its
+# local time to come on the same standard time as New Zealand or of
+# advancing its time to maintain the differential of 13 degrees
+# (approximately 50 minutes ahead of New Zealand time).
+#
+# Because His Majesty King Taufa'ahau Tupou IV, then Crown Prince
+# Tungi, preferred to ensure Tonga's title as the land where time
+# begins, the Legislative Assembly approved the latter change.
+#
+# But some of the older, more conservative members from the outer
+# islands objected. "If at midnight on Dec. 31, we move ahead 40
+# minutes, as your Royal Highness wishes, what becomes of the 40
+# minutes we have lost?"
+#
+# The Crown Prince, presented an unanswerable argument: "Remember that
+# on the World Day of Prayer, you would be the first people on Earth
+# to say your prayers in the morning."
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say the transition was on 1968-10-01; go with Mundell.
+
+# From Eric Ulevik (1999-05-03):
+# Tonga's director of tourism, who is also secretary of the National Millenium
+# Committee, has a plan to get Tonga back in front.
+# He has proposed a one-off move to tropical daylight saving for Tonga from
+# October to March, which has won approval in principle from the Tongan
+# Government.
+
+# From Steffen Thorsen (1999-09-09):
+# * Tonga will introduce DST in November
+#
+# I was given this link by John Letts:
+# <a href="http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm">
+# http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm
+# </a>
+#
+# I have not been able to find exact dates for the transition in November
+# yet. By reading this article it seems like Fiji will be 14 hours ahead
+# of UTC as well, but as far as I know Fiji will only be 13 hours ahead
+# (12 + 1 hour DST).
+
+# From Arthur David Olson (1999-09-20):
+# According to <a href="http://www.tongaonline.com/news/sept1799.html">
+# http://www.tongaonline.com/news/sept1799.html
+# </a>:
+# "Daylight Savings Time will take effect on Oct. 2 through April 15, 2000
+# and annually thereafter from the first Saturday in October through the
+# third Saturday of April.  Under the system approved by Privy Council on
+# Sept. 10, clocks must be turned ahead one hour on the opening day and
+# set back an hour on the closing date."
+# Alas, no indication of the time of day.
+
+# From Rives McDow (1999-10-06):
+# Tonga started its Daylight Saving on Saturday morning October 2nd at 0200am.
+# Daylight Saving ends on April 16 at 0300am which is Sunday morning.
+
+# From Steffen Thorsen (2000-10-31):
+# Back in March I found a notice on the website http://www.tongaonline.com
+# that Tonga changed back to standard time one month early, on March 19
+# instead of the original reported date April 16. Unfortunately, the article
+# is no longer available on the site, and I did not make a copy of the
+# text, and I have forgotten to report it here.
+# (Original URL was: http://www.tongaonline.com/news/march162000.htm )
+
+# From Rives McDow (2000-12-01):
+# Tonga is observing DST as of 2000-11-04 and will stop on 2001-01-27.
+
+# From Sione Moala-Mafi (2001-09-20) via Rives McDow:
+# At 2:00am on the first Sunday of November, the standard time in the Kingdom
+# shall be moved forward by one hour to 3:00am.  At 2:00am on the last Sunday
+# of January the standard time in the Kingdom shall be moved backward by one
+# hour to 1:00am.
+
+# From Pulu 'Anau (2002-11-05):
+# The law was for 3 years, supposedly to get renewed.  It wasn't.
+
+
+# Wake
+
+# From Vernice Anderson, Personal Secretary to Philip Jessup,
+# US Ambassador At Large (oral history interview, 1971-02-02):
+#
+# Saturday, the 14th [of October, 1950] -- ...  The time was all the
+# more confusing at that point, because we had crossed the
+# International Date Line, thus getting two Sundays.  Furthermore, we
+# discovered that Wake Island had two hours of daylight saving time
+# making calculation of time in Washington difficult if not almost
+# impossible.
+#
+# http://www.trumanlibrary.org/wake/meeting.htm
+
+# From Paul Eggert (2003-03-23):
+# We have no other report of DST in Wake Island, so omit this info for now.
+
+###############################################################################
+
+# The International Date Line
+
+# From Gwillim Law (2000-01-03):
+#
+# The International Date Line is not defined by any international standard,
+# convention, or treaty.  Mapmakers are free to draw it as they please.
+# Reputable mapmakers will simply ensure that every point of land appears on
+# the correct side of the IDL, according to the date legally observed there.
+#
+# When Kiribati adopted a uniform date in 1995, thereby moving the Phoenix and
+# Line Islands to the west side of the IDL (or, if you prefer, moving the IDL
+# to the east side of the Phoenix and Line Islands), I suppose that most
+# mapmakers redrew the IDL following the boundary of Kiribati.  Even that line
+# has a rather arbitrary nature.  The straight-line boundaries between Pacific
+# island nations that are shown on many maps are based on an international
+# convention, but are not legally binding national borders.... The date is
+# governed by the IDL; therefore, even on the high seas, there may be some
+# places as late as fourteen hours later than UTC.  And, since the IDL is not
+# an international standard, there are some places on the high seas where the
+# correct date is ambiguous.
+
+# From Wikipedia <http://en.wikipedia.org/wiki/Time_zone> (2005-08-31):
+# Before 1920, all ships kept local apparent time on the high seas by setting
+# their clocks at night or at the morning sight so that, given the ship's
+# speed and direction, it would be 12 o'clock when the Sun crossed the ship's
+# meridian (12 o'clock = local apparent noon).  During 1917, at the
+# Anglo-French Conference on Time-keeping at Sea, it was recommended that all
+# ships, both military and civilian, should adopt hourly standard time zones
+# on the high seas.  Whenever a ship was within the territorial waters of any
+# nation it would use that nation's standard time.  The captain was permitted
+# to change his ship's clocks at a time of his choice following his ship's
+# entry into another zone time--he often chose midnight.  These zones were
+# adopted by all major fleets between 1920 and 1925 but not by many
+# independent merchant ships until World War II.
+
+# From Paul Eggert, using references suggested by Oscar van Vlijmen
+# (2005-03-20):
+#
+# The American Practical Navigator (2002)
+# <http://pollux.nss.nima.mil/pubs/pubs_j_apn_sections.html?rid=187>
+# talks only about the 180-degree meridian with respect to ships in
+# international waters; it ignores the international date line.
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/backward b/jdk/test/sun/util/calendar/zi/tzdata/backward
new file mode 100644
index 0000000..4ccea7c
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/backward
@@ -0,0 +1,140 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# This file provides links between current names for time zones
+# and their old names.  Many names changed in late 1993.
+
+Link	Africa/Asmara		Africa/Asmera
+Link	Africa/Bamako		Africa/Timbuktu
+Link	America/Argentina/Catamarca	America/Argentina/ComodRivadavia
+Link	America/Adak		America/Atka
+Link	America/Argentina/Buenos_Aires	America/Buenos_Aires
+Link	America/Argentina/Catamarca	America/Catamarca
+Link	America/Atikokan	America/Coral_Harbour
+Link	America/Argentina/Cordoba	America/Cordoba
+Link	America/Tijuana		America/Ensenada
+Link	America/Indiana/Indianapolis	America/Fort_Wayne
+Link	America/Indiana/Indianapolis	America/Indianapolis
+Link	America/Argentina/Jujuy	America/Jujuy
+Link	America/Indiana/Knox	America/Knox_IN
+Link	America/Kentucky/Louisville	America/Louisville
+Link	America/Argentina/Mendoza	America/Mendoza
+Link	America/Rio_Branco	America/Porto_Acre
+Link	America/Argentina/Cordoba	America/Rosario
+Link	America/St_Thomas	America/Virgin
+Link	Asia/Ashgabat		Asia/Ashkhabad
+Link	Asia/Chongqing		Asia/Chungking
+Link	Asia/Dhaka		Asia/Dacca
+Link	Asia/Kathmandu		Asia/Katmandu
+Link	Asia/Kolkata		Asia/Calcutta
+Link	Asia/Macau		Asia/Macao
+Link	Asia/Jerusalem		Asia/Tel_Aviv
+Link	Asia/Ho_Chi_Minh	Asia/Saigon
+Link	Asia/Thimphu		Asia/Thimbu
+Link	Asia/Makassar		Asia/Ujung_Pandang
+Link	Asia/Ulaanbaatar	Asia/Ulan_Bator
+Link	Atlantic/Faroe		Atlantic/Faeroe
+Link	Europe/Oslo		Atlantic/Jan_Mayen
+Link	Australia/Sydney	Australia/ACT
+Link	Australia/Sydney	Australia/Canberra
+Link	Australia/Lord_Howe	Australia/LHI
+Link	Australia/Sydney	Australia/NSW
+Link	Australia/Darwin	Australia/North
+Link	Australia/Brisbane	Australia/Queensland
+Link	Australia/Adelaide	Australia/South
+Link	Australia/Hobart	Australia/Tasmania
+Link	Australia/Melbourne	Australia/Victoria
+Link	Australia/Perth		Australia/West
+Link	Australia/Broken_Hill	Australia/Yancowinna
+Link	America/Rio_Branco	Brazil/Acre
+Link	America/Noronha		Brazil/DeNoronha
+Link	America/Sao_Paulo	Brazil/East
+Link	America/Manaus		Brazil/West
+Link	America/Halifax		Canada/Atlantic
+Link	America/Winnipeg	Canada/Central
+Link	America/Regina		Canada/East-Saskatchewan
+Link	America/Toronto		Canada/Eastern
+Link	America/Edmonton	Canada/Mountain
+Link	America/St_Johns	Canada/Newfoundland
+Link	America/Vancouver	Canada/Pacific
+Link	America/Regina		Canada/Saskatchewan
+Link	America/Whitehorse	Canada/Yukon
+Link	America/Santiago	Chile/Continental
+Link	Pacific/Easter		Chile/EasterIsland
+Link	America/Havana		Cuba
+Link	Africa/Cairo		Egypt
+Link	Europe/Dublin		Eire
+Link	Europe/London		Europe/Belfast
+Link	Europe/Chisinau		Europe/Tiraspol
+Link	Europe/London		GB
+Link	Europe/London		GB-Eire
+Link	Etc/GMT			GMT+0
+Link	Etc/GMT			GMT-0
+Link	Etc/GMT			GMT0
+Link	Etc/GMT			Greenwich
+Link	Asia/Hong_Kong		Hongkong
+Link	Atlantic/Reykjavik	Iceland
+Link	Asia/Tehran		Iran
+Link	Asia/Jerusalem		Israel
+Link	America/Jamaica		Jamaica
+Link	Asia/Tokyo		Japan
+Link	Pacific/Kwajalein	Kwajalein
+Link	Africa/Tripoli		Libya
+Link	America/Tijuana		Mexico/BajaNorte
+Link	America/Mazatlan	Mexico/BajaSur
+Link	America/Mexico_City	Mexico/General
+Link	Pacific/Auckland	NZ
+Link	Pacific/Chatham		NZ-CHAT
+Link	America/Denver		Navajo
+Link	Asia/Shanghai		PRC
+Link	Pacific/Pago_Pago	Pacific/Samoa
+Link	Pacific/Chuuk		Pacific/Yap
+Link	Pacific/Chuuk		Pacific/Truk
+Link	Pacific/Pohnpei		Pacific/Ponape
+Link	Europe/Warsaw		Poland
+Link	Europe/Lisbon		Portugal
+Link	Asia/Taipei		ROC
+Link	Asia/Seoul		ROK
+Link	Asia/Singapore		Singapore
+Link	Europe/Istanbul		Turkey
+Link	Etc/UCT			UCT
+Link	America/Anchorage	US/Alaska
+Link	America/Adak		US/Aleutian
+Link	America/Phoenix		US/Arizona
+Link	America/Chicago		US/Central
+Link	America/Indiana/Indianapolis	US/East-Indiana
+Link	America/New_York	US/Eastern
+Link	Pacific/Honolulu	US/Hawaii
+Link	America/Indiana/Knox	US/Indiana-Starke
+Link	America/Detroit		US/Michigan
+Link	America/Denver		US/Mountain
+Link	America/Los_Angeles	US/Pacific
+Link	Pacific/Pago_Pago	US/Samoa
+Link	Etc/UTC			UTC
+Link	Etc/UTC			Universal
+Link	Europe/Moscow		W-SU
+Link	Etc/UTC			Zulu
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/etcetera b/jdk/test/sun/util/calendar/zi/tzdata/etcetera
new file mode 100644
index 0000000..609b305
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/etcetera
@@ -0,0 +1,104 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# These entries are mostly present for historical reasons, so that
+# people in areas not otherwise covered by the tz files could "zic -l"
+# to a time zone that was right for their area.  These days, the
+# tz files cover almost all the inhabited world, and the only practical
+# need now for the entries that are not on UTC are for ships at sea
+# that cannot use POSIX TZ settings.
+
+Zone	Etc/GMT		0	-	GMT
+Zone	Etc/UTC		0	-	UTC
+Zone	Etc/UCT		0	-	UCT
+
+# The following link uses older naming conventions,
+# but it belongs here, not in the file `backward',
+# as functions like gmtime load the "GMT" file to handle leap seconds properly.
+# We want this to work even on installations that omit the other older names.
+Link	Etc/GMT				GMT
+
+Link	Etc/UTC				Etc/Universal
+Link	Etc/UTC				Etc/Zulu
+
+Link	Etc/GMT				Etc/Greenwich
+Link	Etc/GMT				Etc/GMT-0
+Link	Etc/GMT				Etc/GMT+0
+Link	Etc/GMT				Etc/GMT0
+
+# We use POSIX-style signs in the Zone names and the output abbreviations,
+# even though this is the opposite of what many people expect.
+# POSIX has positive signs west of Greenwich, but many people expect
+# positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
+# the abbreviation "GMT+4" and corresponds to 4 hours behind UTC
+# (i.e. west of Greenwich) even though many people would expect it to
+# mean 4 hours ahead of UTC (i.e. east of Greenwich).
+#
+# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation allows for
+# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
+# ISO 8601 you can use TZ='<-0400>+4'.  Thus the commonly-expected
+# offset is kept within the angle bracket (and is used for display)
+# while the POSIX sign is kept outside the angle bracket (and is used
+# for calculation).
+#
+# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
+# GMT but uses the completely misleading abbreviation "GMT".
+
+# Earlier incarnations of this package were not POSIX-compliant,
+# and had lines such as
+#		Zone	GMT-12		-12	-	GMT-1200
+# We did not want things to change quietly if someone accustomed to the old
+# way does a
+#		zic -l GMT-12
+# so we moved the names into the Etc subdirectory.
+
+Zone	Etc/GMT-14	14	-	GMT-14	# 14 hours ahead of GMT
+Zone	Etc/GMT-13	13	-	GMT-13
+Zone	Etc/GMT-12	12	-	GMT-12
+Zone	Etc/GMT-11	11	-	GMT-11
+Zone	Etc/GMT-10	10	-	GMT-10
+Zone	Etc/GMT-9	9	-	GMT-9
+Zone	Etc/GMT-8	8	-	GMT-8
+Zone	Etc/GMT-7	7	-	GMT-7
+Zone	Etc/GMT-6	6	-	GMT-6
+Zone	Etc/GMT-5	5	-	GMT-5
+Zone	Etc/GMT-4	4	-	GMT-4
+Zone	Etc/GMT-3	3	-	GMT-3
+Zone	Etc/GMT-2	2	-	GMT-2
+Zone	Etc/GMT-1	1	-	GMT-1
+Zone	Etc/GMT+1	-1	-	GMT+1
+Zone	Etc/GMT+2	-2	-	GMT+2
+Zone	Etc/GMT+3	-3	-	GMT+3
+Zone	Etc/GMT+4	-4	-	GMT+4
+Zone	Etc/GMT+5	-5	-	GMT+5
+Zone	Etc/GMT+6	-6	-	GMT+6
+Zone	Etc/GMT+7	-7	-	GMT+7
+Zone	Etc/GMT+8	-8	-	GMT+8
+Zone	Etc/GMT+9	-9	-	GMT+9
+Zone	Etc/GMT+10	-10	-	GMT+10
+Zone	Etc/GMT+11	-11	-	GMT+11
+Zone	Etc/GMT+12	-12	-	GMT+12
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/europe b/jdk/test/sun/util/calendar/zi/tzdata/europe
new file mode 100644
index 0000000..9a0d0b9
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe
@@ -0,0 +1,2879 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1991, and IATA SSIM is the source for entries afterwards.
+#
+# Other sources occasionally used include:
+#
+#	Edward W. Whitman, World Time Differences,
+#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
+#	which I found in the UCLA library.
+#
+#	<a href="http://www.pettswoodvillage.co.uk/Daylight_Savings_William_Willett.pdf">
+#	William Willett, The Waste of Daylight, 19th edition
+#	</a> (1914-03)
+#
+#	Brazil's Departamento Servico da Hora (DSH),
+#	<a href="http://pcdsh01.on.br/HISTHV.htm">
+#	History of Summer Time
+#	</a> (1998-09-21, in Portuguese)
+
+#
+# I invented the abbreviations marked `*' in the following table;
+# the rest are from earlier versions of this file, or from other sources.
+# Corrections are welcome!
+#                   std dst  2dst
+#                   LMT           Local Mean Time
+#       -4:00       AST ADT       Atlantic
+#       -3:00       WGT WGST      Western Greenland*
+#       -1:00       EGT EGST      Eastern Greenland*
+#        0:00       GMT BST  BDST Greenwich, British Summer
+#        0:00       GMT IST       Greenwich, Irish Summer
+#        0:00       WET WEST WEMT Western Europe
+#        0:19:32.13 AMT NST       Amsterdam, Netherlands Summer (1835-1937)*
+#        0:20       NET NEST      Netherlands (1937-1940)*
+#        1:00       CET CEST CEMT Central Europe
+#        1:00:14    SET           Swedish (1879-1899)*
+#        2:00       EET EEST      Eastern Europe
+#        3:00       MSK MSD       Moscow
+#
+# A reliable and entertaining source about time zones, especially in Britain,
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+
+# From Peter Ilieve (1994-12-04),
+# The original six [EU members]: Belgium, France, (West) Germany, Italy,
+# Luxembourg, the Netherlands.
+# Plus, from 1 Jan 73: Denmark, Ireland, United Kingdom.
+# Plus, from 1 Jan 81: Greece.
+# Plus, from 1 Jan 86: Spain, Portugal.
+# Plus, from 1 Jan 95: Austria, Finland, Sweden. (Norway negotiated terms for
+# entry but in a referendum on 28 Nov 94 the people voted No by 52.2% to 47.8%
+# on a turnout of 88.6%. This was almost the same result as Norway's previous
+# referendum in 1972, they are the only country to have said No twice.
+# Referendums in the other three countries voted Yes.)
+# ...
+# Estonia ... uses EU dates but not at 01:00 GMT, they use midnight GMT.
+# I don't think they know yet what they will do from 1996 onwards.
+# ...
+# There shouldn't be any [current members who are not using EU rules].
+# A Directive has the force of law, member states are obliged to enact
+# national law to implement it. The only contentious issue was the
+# different end date for the UK and Ireland, and this was always allowed
+# in the Directive.
+
+
+###############################################################################
+
+# Britain (United Kingdom) and Ireland (Eire)
+
+# From Peter Ilieve (1994-07-06):
+#
+# On 17 Jan 1994 the Independent, a UK quality newspaper, had a piece about
+# historical vistas along the Thames in west London. There was a photo
+# and a sketch map showing some of the sightlines involved. One paragraph
+# of the text said:
+#
+# `An old stone obelisk marking a forgotten terrestrial meridian stands
+# beside the river at Kew. In the 18th century, before time and longitude
+# was standardised by the Royal Observatory in Greenwich, scholars observed
+# this stone and the movement of stars from Kew Observatory nearby. They
+# made their calculations and set the time for the Horse Guards and Parliament,
+# but now the stone is obscured by scrubwood and can only be seen by walking
+# along the towpath within a few yards of it.'
+#
+# I have a one inch to one mile map of London and my estimate of the stone's
+# position is 51 deg. 28' 30" N, 0 deg. 18' 45" W. The longitude should
+# be within about +-2". The Ordnance Survey grid reference is TQ172761.
+#
+# [This yields GMTOFF = -0:01:15 for London LMT in the 18th century.]
+
+# From Paul Eggert (1993-11-18):
+#
+# Howse writes that Britain was the first country to use standard time.
+# The railways cared most about the inconsistencies of local mean time,
+# and it was they who forced a uniform time on the country.
+# The original idea was credited to Dr. William Hyde Wollaston (1766-1828)
+# and was popularized by Abraham Follett Osler (1808-1903).
+# The first railway to adopt London time was the Great Western Railway
+# in November 1840; other railways followed suit, and by 1847 most
+# (though not all) railways used London time.  On 1847-09-22 the
+# Railway Clearing House, an industry standards body, recommended that GMT be
+# adopted at all stations as soon as the General Post Office permitted it.
+# The transition occurred on 12-01 for the L&NW, the Caledonian,
+# and presumably other railways; the January 1848 Bradshaw's lists many
+# railways as using GMT.  By 1855 the vast majority of public
+# clocks in Britain were set to GMT (though some, like the great clock
+# on Tom Tower at Christ Church, Oxford, were fitted with two minute hands,
+# one for local time and one for GMT).  The last major holdout was the legal
+# system, which stubbornly stuck to local time for many years, leading
+# to oddities like polls opening at 08:13 and closing at 16:13.
+# The legal system finally switched to GMT when the Statutes (Definition
+# of Time) Act took effect; it received the Royal Assent on 1880-08-02.
+#
+# In the tables below, we condense this complicated story into a single
+# transition date for London, namely 1847-12-01.  We don't know as much
+# about Dublin, so we use 1880-08-02, the legal transition time.
+
+# From Paul Eggert (2003-09-27):
+# Summer Time was first seriously proposed by William Willett (1857-1915),
+# a London builder and member of the Royal Astronomical Society
+# who circulated a pamphlet ``The Waste of Daylight'' (1907)
+# that proposed advancing clocks 20 minutes on each of four Sundays in April,
+# and retarding them by the same amount on four Sundays in September.
+# A bill was drafted in 1909 and introduced in Parliament several times,
+# but it met with ridicule and opposition, especially from farming interests.
+# Later editions of the pamphlet proposed one-hour summer time, and
+# it was eventually adopted as a wartime measure in 1916.
+# See: Summer Time Arrives Early, The Times (2000-05-18).
+# A monument to Willett was unveiled on 1927-05-21, in an open space in
+# a 45-acre wood near Chislehurst, Kent that was purchased by popular
+# subscription and open to the public.  On the south face of the monolith,
+# designed by G. W. Miller, is the...William Willett Memorial Sundial,
+# which is permanently set to Summer Time.
+
+# From Winston Churchill (1934-04-28):
+# It is one of the paradoxes of history that we should owe the boon of
+# summer time, which gives every year to the people of this country
+# between 160 and 170 hours more daylight leisure, to a war which
+# plunged Europe into darkness for four years, and shook the
+# foundations of civilization throughout the world.
+#	-- <a href="http://www.winstonchurchill.org/fh114willett.htm">
+#	"A Silent Toast to William Willett", Pictorial Weekly
+#	</a>
+
+# From Paul Eggert (1996-09-03):
+# The OED Supplement says that the English originally said ``Daylight Saving''
+# when they were debating the adoption of DST in 1908; but by 1916 this
+# term appears only in quotes taken from DST's opponents, whereas the
+# proponents (who eventually won the argument) are quoted as using ``Summer''.
+
+# From Arthur David Olson (1989-01-19):
+#
+# A source at the British Information Office in New York avers that it's
+# known as "British" Summer Time in all parts of the United Kingdom.
+
+# Date: 4 Jan 89 08:57:25 GMT (Wed)
+# From: Jonathan Leffler
+# [British Summer Time] is fixed annually by Act of Parliament.
+# If you can predict what Parliament will do, you should be in
+# politics making a fortune, not computing.
+
+# From Chris Carrier (1996-06-14):
+# I remember reading in various wartime issues of the London Times the
+# acronym BDST for British Double Summer Time.  Look for the published
+# time of sunrise and sunset in The Times, when BDST was in effect, and
+# if you find a zone reference it will say, "All times B.D.S.T."
+
+# From Joseph S. Myers (1999-09-02):
+# ... some military cables (WO 219/4100 - this is a copy from the
+# main SHAEF archives held in the US National Archives, SHAEF/5252/8/516)
+# agree that the usage is BDST (this appears in a message dated 17 Feb 1945).
+
+# From Joseph S. Myers (2000-10-03):
+# On 18th April 1941, Sir Stephen Tallents of the BBC wrote to Sir
+# Alexander Maxwell of the Home Office asking whether there was any
+# official designation; the reply of the 21st was that there wasn't
+# but he couldn't think of anything better than the "Double British
+# Summer Time" that the BBC had been using informally.
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/bbc-19410418.png
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/ho-19410421.png
+
+# From Sir Alexander Maxwell in the above-mentioned letter (1941-04-21):
+# [N]o official designation has as far as I know been adopted for the time
+# which is to be introduced in May....
+# I cannot think of anything better than "Double British Summer Time"
+# which could not be said to run counter to any official description.
+
+# From Paul Eggert (2000-10-02):
+# Howse writes (p 157) `DBST' too, but `BDST' seems to have been common
+# and follows the more usual convention of putting the location name first,
+# so we use `BDST'.
+
+# Peter Ilieve (1998-04-19) described at length
+# the history of summer time legislation in the United Kingdom.
+# Since 1998 Joseph S. Myers has been updating
+# and extending this list, which can be found in
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/
+# <a href="http://www.polyomino.org.uk/british-time/">
+# History of legal time in Britain
+# </a>
+# Rob Crowther (2012-01-04) reports that that URL no longer
+# exists, and the article can now be found at:
+# <a href="http://www.polyomino.org.uk/british-time/">
+# http://www.polyomino.org.uk/british-time/
+# </a>
+
+# From Joseph S. Myers (1998-01-06):
+#
+# The legal time in the UK outside of summer time is definitely GMT, not UTC;
+# see Lord Tanlaw's speech
+# <a href="http://www.parliament.the-stationery-office.co.uk/pa/ld199697/ldhansrd/pdvn/lds97/text/70611-20.htm#70611-20_head0">
+# (Lords Hansard 11 June 1997 columns 964 to 976)
+# </a>.
+
+# From Paul Eggert (2006-03-22):
+#
+# For lack of other data, follow Shanks & Pottenger for Eire in 1940-1948.
+#
+# Given Ilieve and Myers's data, the following claims by Shanks & Pottenger
+# are incorrect:
+#     * Wales did not switch from GMT to daylight saving time until
+#	1921 Apr 3, when they began to conform with the rest of Great Britain.
+# Actually, Wales was identical after 1880.
+#     * Eire had two transitions on 1916 Oct 1.
+# It actually just had one transition.
+#     * Northern Ireland used single daylight saving time throughout WW II.
+# Actually, it conformed to Britain.
+#     * GB-Eire changed standard time to 1 hour ahead of GMT on 1968-02-18.
+# Actually, that date saw the usual switch to summer time.
+# Standard time was not changed until 1968-10-27 (the clocks didn't change).
+#
+# Here is another incorrect claim by Shanks & Pottenger:
+#     * Jersey, Guernsey, and the Isle of Man did not switch from GMT
+#	to daylight saving time until 1921 Apr 3, when they began to
+#	conform with Great Britain.
+# S.R.&O. 1916, No. 382 and HO 45/10811/312364 (quoted above) say otherwise.
+#
+# The following claim by Shanks & Pottenger is possible though doubtful;
+# we'll ignore it for now.
+#     * Dublin's 1971-10-31 switch was at 02:00, even though London's was 03:00.
+#
+#
+# Whitman says Dublin Mean Time was -0:25:21, which is more precise than
+# Shanks & Pottenger.
+# Perhaps this was Dunsink Observatory Time, as Dunsink Observatory
+# (8 km NW of Dublin's center) seemingly was to Dublin as Greenwich was
+# to London.  For example:
+#
+#   "Timeball on the ballast office is down.  Dunsink time."
+#   -- James Joyce, Ulysses
+
+# From Joseph S. Myers (2005-01-26):
+# Irish laws are available online at www.irishstatutebook.ie.  These include
+# various relating to legal time, for example:
+#
+# ZZA13Y1923.html ZZA12Y1924.html ZZA8Y1925.html ZZSIV20PG1267.html
+#
+# ZZSI71Y1947.html ZZSI128Y1948.html ZZSI23Y1949.html ZZSI41Y1950.html
+# ZZSI27Y1951.html ZZSI73Y1952.html
+#
+# ZZSI11Y1961.html ZZSI232Y1961.html ZZSI182Y1962.html
+# ZZSI167Y1963.html ZZSI257Y1964.html ZZSI198Y1967.html
+# ZZA23Y1968.html ZZA17Y1971.html
+#
+# ZZSI67Y1981.html ZZSI212Y1982.html ZZSI45Y1986.html
+# ZZSI264Y1988.html ZZSI52Y1990.html ZZSI371Y1992.html
+# ZZSI395Y1994.html ZZSI484Y1997.html ZZSI506Y2001.html
+#
+# [These are all relative to the root, e.g., the first is
+# <http://www.irishstatutebook.ie/ZZA13Y1923.html>.]
+#
+# (These are those I found, but there could be more.  In any case these
+# should allow various updates to the comments in the europe file to cover
+# the laws applicable in Ireland.)
+#
+# (Note that the time in the Republic of Ireland since 1968 has been defined
+# in terms of standard time being GMT+1 with a period of winter time when it
+# is GMT, rather than standard time being GMT with a period of summer time
+# being GMT+1.)
+
+# From Paul Eggert (1999-03-28):
+# Clive Feather (<news:859845706.26043.0@office.demon.net>, 1997-03-31)
+# reports that Folkestone (Cheriton) Shuttle Terminal uses Concession Time
+# (CT), equivalent to French civil time.
+# Julian Hill (<news:36118128.5A14@virgin.net>, 1998-09-30) reports that
+# trains between Dollands Moor (the freight facility next door)
+# and Frethun run in CT.
+# My admittedly uninformed guess is that the terminal has two authorities,
+# the French concession operators and the British civil authorities,
+# and that the time depends on who you're talking to.
+# If, say, the British police were called to the station for some reason,
+# I would expect the official police report to use GMT/BST and not CET/CEST.
+# This is a borderline case, but for now let's stick to GMT/BST.
+
+# From an anonymous contributor (1996-06-02):
+# The law governing time in Ireland is under Statutory Instrument SI 395/94,
+# which gives force to European Union 7th Council Directive # 94/21/EC.
+# Under this directive, the Minister for Justice in Ireland makes appropriate
+# regulations. I spoke this morning with the Secretary of the Department of
+# Justice (tel +353 1 678 9711) who confirmed to me that the correct name is
+# "Irish Summer Time", abbreviated to "IST".
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Summer Time Act, 1916
+Rule	GB-Eire	1916	only	-	May	21	2:00s	1:00	BST
+Rule	GB-Eire	1916	only	-	Oct	 1	2:00s	0	GMT
+# S.R.&O. 1917, No. 358
+Rule	GB-Eire	1917	only	-	Apr	 8	2:00s	1:00	BST
+Rule	GB-Eire	1917	only	-	Sep	17	2:00s	0	GMT
+# S.R.&O. 1918, No. 274
+Rule	GB-Eire	1918	only	-	Mar	24	2:00s	1:00	BST
+Rule	GB-Eire	1918	only	-	Sep	30	2:00s	0	GMT
+# S.R.&O. 1919, No. 297
+Rule	GB-Eire	1919	only	-	Mar	30	2:00s	1:00	BST
+Rule	GB-Eire	1919	only	-	Sep	29	2:00s	0	GMT
+# S.R.&O. 1920, No. 458
+Rule	GB-Eire	1920	only	-	Mar	28	2:00s	1:00	BST
+# S.R.&O. 1920, No. 1844
+Rule	GB-Eire	1920	only	-	Oct	25	2:00s	0	GMT
+# S.R.&O. 1921, No. 363
+Rule	GB-Eire	1921	only	-	Apr	 3	2:00s	1:00	BST
+Rule	GB-Eire	1921	only	-	Oct	 3	2:00s	0	GMT
+# S.R.&O. 1922, No. 264
+Rule	GB-Eire	1922	only	-	Mar	26	2:00s	1:00	BST
+Rule	GB-Eire	1922	only	-	Oct	 8	2:00s	0	GMT
+# The Summer Time Act, 1922
+Rule	GB-Eire	1923	only	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1923	1924	-	Sep	Sun>=16	2:00s	0	GMT
+Rule	GB-Eire	1924	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1925	1926	-	Apr	Sun>=16	2:00s	1:00	BST
+# The Summer Time Act, 1925
+Rule	GB-Eire	1925	1938	-	Oct	Sun>=2	2:00s	0	GMT
+Rule	GB-Eire	1927	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1928	1929	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1930	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1931	1932	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1933	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1934	only	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1935	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1936	1937	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1938	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1939	only	-	Apr	Sun>=16	2:00s	1:00	BST
+# S.R.&O. 1939, No. 1379
+Rule	GB-Eire	1939	only	-	Nov	Sun>=16	2:00s	0	GMT
+# S.R.&O. 1940, No. 172 and No. 1883
+Rule	GB-Eire	1940	only	-	Feb	Sun>=23	2:00s	1:00	BST
+# S.R.&O. 1941, No. 476
+Rule	GB-Eire	1941	only	-	May	Sun>=2	1:00s	2:00	BDST
+Rule	GB-Eire	1941	1943	-	Aug	Sun>=9	1:00s	1:00	BST
+# S.R.&O. 1942, No. 506
+Rule	GB-Eire	1942	1944	-	Apr	Sun>=2	1:00s	2:00	BDST
+# S.R.&O. 1944, No. 932
+Rule	GB-Eire	1944	only	-	Sep	Sun>=16	1:00s	1:00	BST
+# S.R.&O. 1945, No. 312
+Rule	GB-Eire	1945	only	-	Apr	Mon>=2	1:00s	2:00	BDST
+Rule	GB-Eire	1945	only	-	Jul	Sun>=9	1:00s	1:00	BST
+# S.R.&O. 1945, No. 1208
+Rule	GB-Eire	1945	1946	-	Oct	Sun>=2	2:00s	0	GMT
+Rule	GB-Eire	1946	only	-	Apr	Sun>=9	2:00s	1:00	BST
+# The Summer Time Act, 1947
+Rule	GB-Eire	1947	only	-	Mar	16	2:00s	1:00	BST
+Rule	GB-Eire	1947	only	-	Apr	13	1:00s	2:00	BDST
+Rule	GB-Eire	1947	only	-	Aug	10	1:00s	1:00	BST
+Rule	GB-Eire	1947	only	-	Nov	 2	2:00s	0	GMT
+# Summer Time Order, 1948 (S.I. 1948/495)
+Rule	GB-Eire	1948	only	-	Mar	14	2:00s	1:00	BST
+Rule	GB-Eire	1948	only	-	Oct	31	2:00s	0	GMT
+# Summer Time Order, 1949 (S.I. 1949/373)
+Rule	GB-Eire	1949	only	-	Apr	 3	2:00s	1:00	BST
+Rule	GB-Eire	1949	only	-	Oct	30	2:00s	0	GMT
+# Summer Time Order, 1950 (S.I. 1950/518)
+# Summer Time Order, 1951 (S.I. 1951/430)
+# Summer Time Order, 1952 (S.I. 1952/451)
+Rule	GB-Eire	1950	1952	-	Apr	Sun>=14	2:00s	1:00	BST
+Rule	GB-Eire	1950	1952	-	Oct	Sun>=21	2:00s	0	GMT
+# revert to the rules of the Summer Time Act, 1925
+Rule	GB-Eire	1953	only	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1953	1960	-	Oct	Sun>=2	2:00s	0	GMT
+Rule	GB-Eire	1954	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1955	1956	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1957	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1958	1959	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1960	only	-	Apr	Sun>=9	2:00s	1:00	BST
+# Summer Time Order, 1961 (S.I. 1961/71)
+# Summer Time (1962) Order, 1961 (S.I. 1961/2465)
+# Summer Time Order, 1963 (S.I. 1963/81)
+Rule	GB-Eire	1961	1963	-	Mar	lastSun	2:00s	1:00	BST
+Rule	GB-Eire	1961	1968	-	Oct	Sun>=23	2:00s	0	GMT
+# Summer Time (1964) Order, 1963 (S.I. 1963/2101)
+# Summer Time Order, 1964 (S.I. 1964/1201)
+# Summer Time Order, 1967 (S.I. 1967/1148)
+Rule	GB-Eire	1964	1967	-	Mar	Sun>=19	2:00s	1:00	BST
+# Summer Time Order, 1968 (S.I. 1968/117)
+Rule	GB-Eire	1968	only	-	Feb	18	2:00s	1:00	BST
+# The British Standard Time Act, 1968
+#	(no summer time)
+# The Summer Time Act, 1972
+Rule	GB-Eire	1972	1980	-	Mar	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1972	1980	-	Oct	Sun>=23	2:00s	0	GMT
+# Summer Time Order, 1980 (S.I. 1980/1089)
+# Summer Time Order, 1982 (S.I. 1982/1673)
+# Summer Time Order, 1986 (S.I. 1986/223)
+# Summer Time Order, 1988 (S.I. 1988/931)
+Rule	GB-Eire	1981	1995	-	Mar	lastSun	1:00u	1:00	BST
+Rule	GB-Eire 1981	1989	-	Oct	Sun>=23	1:00u	0	GMT
+# Summer Time Order, 1989 (S.I. 1989/985)
+# Summer Time Order, 1992 (S.I. 1992/1729)
+# Summer Time Order 1994 (S.I. 1994/2798)
+Rule	GB-Eire 1990	1995	-	Oct	Sun>=22	1:00u	0	GMT
+# Summer Time Order 1997 (S.I. 1997/2982)
+# See EU for rules starting in 1996.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/London	-0:01:15 -	LMT	1847 Dec  1 0:00s
+			 0:00	GB-Eire	%s	1968 Oct 27
+			 1:00	-	BST	1971 Oct 31 2:00u
+			 0:00	GB-Eire	%s	1996
+			 0:00	EU	GMT/BST
+Link	Europe/London	Europe/Jersey
+Link	Europe/London	Europe/Guernsey
+Link	Europe/London	Europe/Isle_of_Man
+Zone	Europe/Dublin	-0:25:00 -	LMT	1880 Aug  2
+			-0:25:21 -	DMT	1916 May 21 2:00
+			-0:25:21 1:00	IST	1916 Oct  1 2:00s
+			 0:00	GB-Eire	%s	1921 Dec  6 # independence
+			 0:00	GB-Eire	GMT/IST	1940 Feb 25 2:00
+			 0:00	1:00	IST	1946 Oct  6 2:00
+			 0:00	-	GMT	1947 Mar 16 2:00
+			 0:00	1:00	IST	1947 Nov  2 2:00
+			 0:00	-	GMT	1948 Apr 18 2:00
+			 0:00	GB-Eire	GMT/IST	1968 Oct 27
+			 1:00	-	IST	1971 Oct 31 2:00u
+			 0:00	GB-Eire	GMT/IST	1996
+			 0:00	EU	GMT/IST
+
+###############################################################################
+
+# Europe
+
+# EU rules are for the European Union, previously known as the EC, EEC,
+# Common Market, etc.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	EU	1977	1980	-	Apr	Sun>=1	 1:00u	1:00	S
+Rule	EU	1977	only	-	Sep	lastSun	 1:00u	0	-
+Rule	EU	1978	only	-	Oct	 1	 1:00u	0	-
+Rule	EU	1979	1995	-	Sep	lastSun	 1:00u	0	-
+Rule	EU	1981	max	-	Mar	lastSun	 1:00u	1:00	S
+Rule	EU	1996	max	-	Oct	lastSun	 1:00u	0	-
+# The most recent directive covers the years starting in 2002.  See:
+# <a="http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=CELEX:32000L0084:EN:NOT">
+# Directive 2000/84/EC of the European Parliament and of the Council
+# of 19 January 2001 on summer-time arrangements.
+# </a>
+
+# W-Eur differs from EU only in that W-Eur uses standard time.
+Rule	W-Eur	1977	1980	-	Apr	Sun>=1	 1:00s	1:00	S
+Rule	W-Eur	1977	only	-	Sep	lastSun	 1:00s	0	-
+Rule	W-Eur	1978	only	-	Oct	 1	 1:00s	0	-
+Rule	W-Eur	1979	1995	-	Sep	lastSun	 1:00s	0	-
+Rule	W-Eur	1981	max	-	Mar	lastSun	 1:00s	1:00	S
+Rule	W-Eur	1996	max	-	Oct	lastSun	 1:00s	0	-
+
+# Older C-Eur rules are for convenience in the tables.
+# From 1977 on, C-Eur differs from EU only in that C-Eur uses standard time.
+Rule	C-Eur	1916	only	-	Apr	30	23:00	1:00	S
+Rule	C-Eur	1916	only	-	Oct	 1	 1:00	0	-
+Rule	C-Eur	1917	1918	-	Apr	Mon>=15	 2:00s	1:00	S
+Rule	C-Eur	1917	1918	-	Sep	Mon>=15	 2:00s	0	-
+Rule	C-Eur	1940	only	-	Apr	 1	 2:00s	1:00	S
+Rule	C-Eur	1942	only	-	Nov	 2	 2:00s	0	-
+Rule	C-Eur	1943	only	-	Mar	29	 2:00s	1:00	S
+Rule	C-Eur	1943	only	-	Oct	 4	 2:00s	0	-
+Rule	C-Eur	1944	1945	-	Apr	Mon>=1	 2:00s	1:00	S
+# Whitman gives 1944 Oct 7; go with Shanks & Pottenger.
+Rule	C-Eur	1944	only	-	Oct	 2	 2:00s	0	-
+# From Jesper Norgaard Welen (2008-07-13):
+#
+# I found what is probably a typo of 2:00 which should perhaps be 2:00s
+# in the C-Eur rule from tz database version 2008d (this part was
+# corrected in version 2008d). The circumstancial evidence is simply the
+# tz database itself, as seen below:
+#
+# Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15  0:01
+#    0:00 France WE%sT 1945 Sep 16  3:00
+#
+# Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
+#    0:00 France WE%sT 1945 Sep 16 3:00
+#
+# Zone Europe/Belgrade 1:22:00 - LMT 1884
+#    1:00 1:00 CEST 1945 Sep 16  2:00s
+#
+# Rule France 1945 only - Sep 16  3:00 0 -
+# Rule Belgium 1945 only - Sep 16  2:00s 0 -
+# Rule Neth 1945 only - Sep 16 2:00s 0 -
+#
+# The rule line to be changed is:
+#
+# Rule C-Eur 1945 only - Sep 16  2:00 0 -
+#
+# It seems that Paris, Monaco, Rule France, Rule Belgium all agree on
+# 2:00 standard time, e.g. 3:00 local time.  However there are no
+# countries that use C-Eur rules in September 1945, so the only items
+# affected are apparently these ficticious zones that translates acronyms
+# CET and MET:
+#
+# Zone CET  1:00 C-Eur CE%sT
+# Zone MET  1:00 C-Eur ME%sT
+#
+# It this is right then the corrected version would look like:
+#
+# Rule C-Eur 1945 only - Sep 16  2:00s 0 -
+#
+# A small step for mankind though 8-)
+Rule	C-Eur	1945	only	-	Sep	16	 2:00s	0	-
+Rule	C-Eur	1977	1980	-	Apr	Sun>=1	 2:00s	1:00	S
+Rule	C-Eur	1977	only	-	Sep	lastSun	 2:00s	0	-
+Rule	C-Eur	1978	only	-	Oct	 1	 2:00s	0	-
+Rule	C-Eur	1979	1995	-	Sep	lastSun	 2:00s	0	-
+Rule	C-Eur	1981	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule	C-Eur	1996	max	-	Oct	lastSun	 2:00s	0	-
+
+# E-Eur differs from EU only in that E-Eur switches at midnight local time.
+Rule	E-Eur	1977	1980	-	Apr	Sun>=1	 0:00	1:00	S
+Rule	E-Eur	1977	only	-	Sep	lastSun	 0:00	0	-
+Rule	E-Eur	1978	only	-	Oct	 1	 0:00	0	-
+Rule	E-Eur	1979	1995	-	Sep	lastSun	 0:00	0	-
+Rule	E-Eur	1981	max	-	Mar	lastSun	 0:00	1:00	S
+Rule	E-Eur	1996	max	-	Oct	lastSun	 0:00	0	-
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Russia	1917	only	-	Jul	 1	23:00	1:00	MST	# Moscow Summer Time
+Rule	Russia	1917	only	-	Dec	28	 0:00	0	MMT	# Moscow Mean Time
+Rule	Russia	1918	only	-	May	31	22:00	2:00	MDST	# Moscow Double Summer Time
+Rule	Russia	1918	only	-	Sep	16	 1:00	1:00	MST
+Rule	Russia	1919	only	-	May	31	23:00	2:00	MDST
+Rule	Russia	1919	only	-	Jul	 1	 2:00	1:00	S
+Rule	Russia	1919	only	-	Aug	16	 0:00	0	-
+Rule	Russia	1921	only	-	Feb	14	23:00	1:00	S
+Rule	Russia	1921	only	-	Mar	20	23:00	2:00	M # Midsummer
+Rule	Russia	1921	only	-	Sep	 1	 0:00	1:00	S
+Rule	Russia	1921	only	-	Oct	 1	 0:00	0	-
+# Act No.925 of the Council of Ministers of the USSR (1980-10-24):
+Rule	Russia	1981	1984	-	Apr	 1	 0:00	1:00	S
+Rule	Russia	1981	1983	-	Oct	 1	 0:00	0	-
+# Act No.967 of the Council of Ministers of the USSR (1984-09-13), repeated in
+# Act No.227 of the Council of Ministers of the USSR (1989-03-14):
+Rule	Russia	1984	1991	-	Sep	lastSun	 2:00s	0	-
+Rule	Russia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
+#
+Rule	Russia	1992	only	-	Mar	lastSat	 23:00	1:00	S
+Rule	Russia	1992	only	-	Sep	lastSat	 23:00	0	-
+Rule	Russia	1993	2010	-	Mar	lastSun	 2:00s	1:00	S
+Rule	Russia	1993	1995	-	Sep	lastSun	 2:00s	0	-
+Rule	Russia	1996	2010	-	Oct	lastSun	 2:00s	0	-
+
+# From Alexander Krivenyshev (2011-06-14):
+# According to Kremlin press service, Russian President Dmitry Medvedev
+# signed a federal law "On calculation of time" on June 9, 2011.
+# According to the law Russia is abolishing daylight saving time.
+#
+# Medvedev signed a law "On the Calculation of Time" (in russian):
+# <a href="http://bmockbe.ru/events/?ID=7583">
+# http://bmockbe.ru/events/?ID=7583
+# </a>
+#
+# Medvedev signed a law on the calculation of the time (in russian):
+# <a href="http://www.regnum.ru/news/polit/1413906.html">
+# http://www.regnum.ru/news/polit/1413906.html
+# </a>
+
+# From Arthur David Olson (2011-06-15):
+# Take "abolishing daylight saving time" to mean that time is now considered
+# to be standard.
+
+# These are for backward compatibility with older versions.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	WET		0:00	EU	WE%sT
+Zone	CET		1:00	C-Eur	CE%sT
+Zone	MET		1:00	C-Eur	ME%sT
+Zone	EET		2:00	EU	EE%sT
+
+# Previous editions of this database used abbreviations like MET DST
+# for Central European Summer Time, but this didn't agree with common usage.
+
+# From Markus Kuhn (1996-07-12):
+# The official German names ... are
+#
+#	Mitteleuropaeische Zeit (MEZ)         = UTC+01:00
+#	Mitteleuropaeische Sommerzeit (MESZ)  = UTC+02:00
+#
+# as defined in the German Time Act (Gesetz ueber die Zeitbestimmung (ZeitG),
+# 1978-07-25, Bundesgesetzblatt, Jahrgang 1978, Teil I, S. 1110-1111)....
+# I wrote ... to the German Federal Physical-Technical Institution
+#
+#	Physikalisch-Technische Bundesanstalt (PTB)
+#	Laboratorium 4.41 "Zeiteinheit"
+#	Postfach 3345
+#	D-38023 Braunschweig
+#	phone: +49 531 592-0
+#
+# ... I received today an answer letter from Dr. Peter Hetzel, head of the PTB
+# department for time and frequency transmission.  He explained that the
+# PTB translates MEZ and MESZ into English as
+#
+#	Central European Time (CET)         = UTC+01:00
+#	Central European Summer Time (CEST) = UTC+02:00
+
+
+# Albania
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Albania	1940	only	-	Jun	16	0:00	1:00	S
+Rule	Albania	1942	only	-	Nov	 2	3:00	0	-
+Rule	Albania	1943	only	-	Mar	29	2:00	1:00	S
+Rule	Albania	1943	only	-	Apr	10	3:00	0	-
+Rule	Albania	1974	only	-	May	 4	0:00	1:00	S
+Rule	Albania	1974	only	-	Oct	 2	0:00	0	-
+Rule	Albania	1975	only	-	May	 1	0:00	1:00	S
+Rule	Albania	1975	only	-	Oct	 2	0:00	0	-
+Rule	Albania	1976	only	-	May	 2	0:00	1:00	S
+Rule	Albania	1976	only	-	Oct	 3	0:00	0	-
+Rule	Albania	1977	only	-	May	 8	0:00	1:00	S
+Rule	Albania	1977	only	-	Oct	 2	0:00	0	-
+Rule	Albania	1978	only	-	May	 6	0:00	1:00	S
+Rule	Albania	1978	only	-	Oct	 1	0:00	0	-
+Rule	Albania	1979	only	-	May	 5	0:00	1:00	S
+Rule	Albania	1979	only	-	Sep	30	0:00	0	-
+Rule	Albania	1980	only	-	May	 3	0:00	1:00	S
+Rule	Albania	1980	only	-	Oct	 4	0:00	0	-
+Rule	Albania	1981	only	-	Apr	26	0:00	1:00	S
+Rule	Albania	1981	only	-	Sep	27	0:00	0	-
+Rule	Albania	1982	only	-	May	 2	0:00	1:00	S
+Rule	Albania	1982	only	-	Oct	 3	0:00	0	-
+Rule	Albania	1983	only	-	Apr	18	0:00	1:00	S
+Rule	Albania	1983	only	-	Oct	 1	0:00	0	-
+Rule	Albania	1984	only	-	Apr	 1	0:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Tirane	1:19:20 -	LMT	1914
+			1:00	-	CET	1940 Jun 16
+			1:00	Albania	CE%sT	1984 Jul
+			1:00	EU	CE%sT
+
+# Andorra
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Andorra	0:06:04 -	LMT	1901
+			0:00	-	WET	1946 Sep 30
+			1:00	-	CET	1985 Mar 31 2:00
+			1:00	EU	CE%sT
+
+# Austria
+
+# From Paul Eggert (2006-03-22): Shanks & Pottenger give 1918-06-16 and
+# 1945-11-18, but the Austrian Federal Office of Metrology and
+# Surveying (BEV) gives 1918-09-16 and for Vienna gives the "alleged"
+# date of 1945-04-12 with no time.  For the 1980-04-06 transition
+# Shanks & Pottenger give 02:00, the BEV 00:00.  Go with the BEV,
+# and guess 02:00 for 1945-04-12.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Austria	1920	only	-	Apr	 5	2:00s	1:00	S
+Rule	Austria	1920	only	-	Sep	13	2:00s	0	-
+Rule	Austria	1946	only	-	Apr	14	2:00s	1:00	S
+Rule	Austria	1946	1948	-	Oct	Sun>=1	2:00s	0	-
+Rule	Austria	1947	only	-	Apr	 6	2:00s	1:00	S
+Rule	Austria	1948	only	-	Apr	18	2:00s	1:00	S
+Rule	Austria	1980	only	-	Apr	 6	0:00	1:00	S
+Rule	Austria	1980	only	-	Sep	28	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Vienna	1:05:20 -	LMT	1893 Apr
+			1:00	C-Eur	CE%sT	1920
+			1:00	Austria	CE%sT	1940 Apr  1 2:00s
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
+			1:00	1:00	CEST	1945 Apr 12 2:00s
+			1:00	-	CET	1946
+			1:00	Austria	CE%sT	1981
+			1:00	EU	CE%sT
+
+# Belarus
+# From Yauhen Kharuzhy (2011-09-16):
+# By latest Belarus government act Europe/Minsk timezone was changed to
+# GMT+3 without DST (was GMT+2 with DST).
+#
+# Sources (Russian language):
+# 1.
+# <a href="http://www.belta.by/ru/all_news/society/V-Belarusi-otmenjaetsja-perexod-na-sezonnoe-vremja_i_572952.html">
+# http://www.belta.by/ru/all_news/society/V-Belarusi-otmenjaetsja-perexod-na-sezonnoe-vremja_i_572952.html
+# </a>
+# 2.
+# <a href="http://naviny.by/rubrics/society/2011/09/16/ic_articles_116_175144/">
+# http://naviny.by/rubrics/society/2011/09/16/ic_articles_116_175144/
+# </a>
+# 3.
+# <a href="http://news.tut.by/society/250578.html">
+# http://news.tut.by/society/250578.html
+# </a>
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Minsk	1:50:16 -	LMT	1880
+			1:50	-	MMT	1924 May 2 # Minsk Mean Time
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Jun 28
+			1:00	C-Eur	CE%sT	1944 Jul  3
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1991 Mar 31 2:00s
+			2:00	1:00	EEST	1991 Sep 29 2:00s
+			2:00	-	EET	1992 Mar 29 0:00s
+			2:00	1:00	EEST	1992 Sep 27 0:00s
+			2:00	Russia	EE%sT	2011 Mar 27 2:00s
+			3:00	-	FET # Further-eastern European Time
+
+# Belgium
+#
+# From Paul Eggert (1997-07-02):
+# Entries from 1918 through 1991 are taken from:
+#	Annuaire de L'Observatoire Royal de Belgique,
+#	Avenue Circulaire, 3, B-1180 BRUXELLES, CLVIIe annee, 1991
+#	(Imprimerie HAYEZ, s.p.r.l., Rue Fin, 4, 1080 BRUXELLES, MCMXC),
+#	pp 8-9.
+# LMT before 1892 was 0:17:30, according to the official journal of Belgium:
+#	Moniteur Belge, Samedi 30 Avril 1892, N.121.
+# Thanks to Pascal Delmoitie for these references.
+# The 1918 rules are listed for completeness; they apply to unoccupied Belgium.
+# Assume Brussels switched to WET in 1918 when the armistice took effect.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Belgium	1918	only	-	Mar	 9	 0:00s	1:00	S
+Rule	Belgium	1918	1919	-	Oct	Sat>=1	23:00s	0	-
+Rule	Belgium	1919	only	-	Mar	 1	23:00s	1:00	S
+Rule	Belgium	1920	only	-	Feb	14	23:00s	1:00	S
+Rule	Belgium	1920	only	-	Oct	23	23:00s	0	-
+Rule	Belgium	1921	only	-	Mar	14	23:00s	1:00	S
+Rule	Belgium	1921	only	-	Oct	25	23:00s	0	-
+Rule	Belgium	1922	only	-	Mar	25	23:00s	1:00	S
+Rule	Belgium	1922	1927	-	Oct	Sat>=1	23:00s	0	-
+Rule	Belgium	1923	only	-	Apr	21	23:00s	1:00	S
+Rule	Belgium	1924	only	-	Mar	29	23:00s	1:00	S
+Rule	Belgium	1925	only	-	Apr	 4	23:00s	1:00	S
+# DSH writes that a royal decree of 1926-02-22 specified the Sun following 3rd
+# Sat in Apr (except if it's Easter, in which case it's one Sunday earlier),
+# to Sun following 1st Sat in Oct, and that a royal decree of 1928-09-15
+# changed the transition times to 02:00 GMT.
+Rule	Belgium	1926	only	-	Apr	17	23:00s	1:00	S
+Rule	Belgium	1927	only	-	Apr	 9	23:00s	1:00	S
+Rule	Belgium	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	Belgium	1928	1938	-	Oct	Sun>=2	 2:00s	0	-
+Rule	Belgium	1929	only	-	Apr	21	 2:00s	1:00	S
+Rule	Belgium	1930	only	-	Apr	13	 2:00s	1:00	S
+Rule	Belgium	1931	only	-	Apr	19	 2:00s	1:00	S
+Rule	Belgium	1932	only	-	Apr	 3	 2:00s	1:00	S
+Rule	Belgium	1933	only	-	Mar	26	 2:00s	1:00	S
+Rule	Belgium	1934	only	-	Apr	 8	 2:00s	1:00	S
+Rule	Belgium	1935	only	-	Mar	31	 2:00s	1:00	S
+Rule	Belgium	1936	only	-	Apr	19	 2:00s	1:00	S
+Rule	Belgium	1937	only	-	Apr	 4	 2:00s	1:00	S
+Rule	Belgium	1938	only	-	Mar	27	 2:00s	1:00	S
+Rule	Belgium	1939	only	-	Apr	16	 2:00s	1:00	S
+Rule	Belgium	1939	only	-	Nov	19	 2:00s	0	-
+Rule	Belgium	1940	only	-	Feb	25	 2:00s	1:00	S
+Rule	Belgium	1944	only	-	Sep	17	 2:00s	0	-
+Rule	Belgium	1945	only	-	Apr	 2	 2:00s	1:00	S
+Rule	Belgium	1945	only	-	Sep	16	 2:00s	0	-
+Rule	Belgium	1946	only	-	May	19	 2:00s	1:00	S
+Rule	Belgium	1946	only	-	Oct	 7	 2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Brussels	0:17:30 -	LMT	1880
+			0:17:30	-	BMT	1892 May  1 12:00 # Brussels MT
+			0:00	-	WET	1914 Nov  8
+			1:00	-	CET	1916 May  1  0:00
+			1:00	C-Eur	CE%sT	1918 Nov 11 11:00u
+			0:00	Belgium	WE%sT	1940 May 20  2:00s
+			1:00	C-Eur	CE%sT	1944 Sep  3
+			1:00	Belgium	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Bosnia and Herzegovina
+# see Serbia
+
+# Bulgaria
+#
+# From Plamen Simenov via Steffen Thorsen (1999-09-09):
+# A document of Government of Bulgaria (No.94/1997) says:
+# EET --> EETDST is in 03:00 Local time in last Sunday of March ...
+# EETDST --> EET is in 04:00 Local time in last Sunday of October
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Bulg	1979	only	-	Mar	31	23:00	1:00	S
+Rule	Bulg	1979	only	-	Oct	 1	 1:00	0	-
+Rule	Bulg	1980	1982	-	Apr	Sat>=1	23:00	1:00	S
+Rule	Bulg	1980	only	-	Sep	29	 1:00	0	-
+Rule	Bulg	1981	only	-	Sep	27	 2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Sofia	1:33:16 -	LMT	1880
+			1:56:56	-	IMT	1894 Nov 30 # Istanbul MT?
+			2:00	-	EET	1942 Nov  2  3:00
+			1:00	C-Eur	CE%sT	1945
+			1:00	-	CET	1945 Apr 2 3:00
+			2:00	-	EET	1979 Mar 31 23:00
+			2:00	Bulg	EE%sT	1982 Sep 26  2:00
+			2:00	C-Eur	EE%sT	1991
+			2:00	E-Eur	EE%sT	1997
+			2:00	EU	EE%sT
+
+# Croatia
+# see Serbia
+
+# Cyprus
+# Please see the `asia' file for Asia/Nicosia.
+
+# Czech Republic
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Czech	1945	only	-	Apr	 8	2:00s	1:00	S
+Rule	Czech	1945	only	-	Nov	18	2:00s	0	-
+Rule	Czech	1946	only	-	May	 6	2:00s	1:00	S
+Rule	Czech	1946	1949	-	Oct	Sun>=1	2:00s	0	-
+Rule	Czech	1947	only	-	Apr	20	2:00s	1:00	S
+Rule	Czech	1948	only	-	Apr	18	2:00s	1:00	S
+Rule	Czech	1949	only	-	Apr	 9	2:00s	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Prague	0:57:44 -	LMT	1850
+			0:57:44	-	PMT	1891 Oct     # Prague Mean Time
+			1:00	C-Eur	CE%sT	1944 Sep 17 2:00s
+			1:00	Czech	CE%sT	1979
+			1:00	EU	CE%sT
+
+# Denmark, Faroe Islands, and Greenland
+
+# From Jesper Norgaard Welen (2005-04-26):
+# http://www.hum.aau.dk/~poe/tid/tine/DanskTid.htm says that the law
+# [introducing standard time] was in effect from 1894-01-01....
+# The page http://www.retsinfo.dk/_GETDOCI_/ACCN/A18930008330-REGL
+# confirms this, and states that the law was put forth 1893-03-29.
+#
+# The EU treaty with effect from 1973:
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/A19722110030-REGL
+#
+# This provoked a new law from 1974 to make possible summer time changes
+# in subsequenet decrees with the law
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/A19740022330-REGL
+#
+# It seems however that no decree was set forward until 1980.  I have
+# not found any decree, but in another related law, the effecting DST
+# changes are stated explicitly to be from 1980-04-06 at 02:00 to
+# 1980-09-28 at 02:00.  If this is true, this differs slightly from
+# the EU rule in that DST runs to 02:00, not 03:00.  We don't know
+# when Denmark began using the EU rule correctly, but we have only
+# confirmation of the 1980-time, so I presume it was correct in 1981:
+# The law is about the management of the extra hour, concerning
+# working hours reported and effect on obligatory-rest rules (which
+# was suspended on that night):
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/C19801120554-REGL
+
+# From Jesper Norgaard Welen (2005-06-11):
+# The Herning Folkeblad (1980-09-26) reported that the night between
+# Saturday and Sunday the clock is set back from three to two.
+
+# From Paul Eggert (2005-06-11):
+# Hence the "02:00" of the 1980 law refers to standard time, not
+# wall-clock time, and so the EU rules were in effect in 1980.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Denmark	1916	only	-	May	14	23:00	1:00	S
+Rule	Denmark	1916	only	-	Sep	30	23:00	0	-
+Rule	Denmark	1940	only	-	May	15	 0:00	1:00	S
+Rule	Denmark	1945	only	-	Apr	 2	 2:00s	1:00	S
+Rule	Denmark	1945	only	-	Aug	15	 2:00s	0	-
+Rule	Denmark	1946	only	-	May	 1	 2:00s	1:00	S
+Rule	Denmark	1946	only	-	Sep	 1	 2:00s	0	-
+Rule	Denmark	1947	only	-	May	 4	 2:00s	1:00	S
+Rule	Denmark	1947	only	-	Aug	10	 2:00s	0	-
+Rule	Denmark	1948	only	-	May	 9	 2:00s	1:00	S
+Rule	Denmark	1948	only	-	Aug	 8	 2:00s	0	-
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Copenhagen	 0:50:20 -	LMT	1890
+			 0:50:20 -	CMT	1894 Jan  1 # Copenhagen MT
+			 1:00	Denmark	CE%sT	1942 Nov  2 2:00s
+			 1:00	C-Eur	CE%sT	1945 Apr  2 2:00
+			 1:00	Denmark	CE%sT	1980
+			 1:00	EU	CE%sT
+Zone Atlantic/Faroe	-0:27:04 -	LMT	1908 Jan 11	# Torshavn
+			 0:00	-	WET	1981
+			 0:00	EU	WE%sT
+#
+# From Paul Eggert (2004-10-31):
+# During World War II, Germany maintained secret manned weather stations in
+# East Greenland and Franz Josef Land, but we don't know their time zones.
+# My source for this is Wilhelm Dege's book mentioned under Svalbard.
+#
+# From Paul Eggert (2006-03-22):
+# Greenland joined the EU as part of Denmark, obtained home rule on 1979-05-01,
+# and left the EU on 1985-02-01.  It therefore should have been using EU
+# rules at least through 1984.  Shanks & Pottenger say Scoresbysund and Godthab
+# used C-Eur rules after 1980, but IATA SSIM (1991/1996) says they use EU
+# rules since at least 1991.  Assume EU rules since 1980.
+
+# From Gwillin Law (2001-06-06), citing
+# <http://www.statkart.no/efs/efshefter/2001/efs5-2001.pdf> (2001-03-15),
+# and with translations corrected by Steffen Thorsen:
+#
+# Greenland has four local times, and the relation to UTC
+# is according to the following time line:
+#
+# The military zone near Thule	UTC-4
+# Standard Greenland time	UTC-3
+# Scoresbysund			UTC-1
+# Danmarkshavn			UTC
+#
+# In the military area near Thule and in Danmarkshavn DST will not be
+# introduced.
+
+# From Rives McDow (2001-11-01):
+#
+# I correspond regularly with the Dansk Polarcenter, and wrote them at
+# the time to clarify the situation in Thule.  Unfortunately, I have
+# not heard back from them regarding my recent letter.  [But I have
+# info from earlier correspondence.]
+#
+# According to the center, a very small local time zone around Thule
+# Air Base keeps the time according to UTC-4, implementing daylight
+# savings using North America rules, changing the time at 02:00 local time....
+#
+# The east coast of Greenland north of the community of Scoresbysund
+# uses UTC in the same way as in Iceland, year round, with no dst.
+# There are just a few stations on this coast, including the
+# Danmarkshavn ICAO weather station mentioned in your September 29th
+# email.  The other stations are two sledge patrol stations in
+# Mestersvig and Daneborg, the air force base at Station Nord, and the
+# DPC research station at Zackenberg.
+#
+# Scoresbysund and two small villages nearby keep time UTC-1 and use
+# the same daylight savings time period as in West Greenland (Godthab).
+#
+# The rest of Greenland, including Godthab (this area, although it
+# includes central Greenland, is known as west Greenland), keeps time
+# UTC-3, with daylight savings methods according to European rules.
+#
+# It is common procedure to use UTC 0 in the wilderness of East and
+# North Greenland, because it is mainly Icelandic aircraft operators
+# maintaining traffic in these areas.  However, the official status of
+# this area is that it sticks with Godthab time.  This area might be
+# considered a dual time zone in some respects because of this.
+
+# From Rives McDow (2001-11-19):
+# I heard back from someone stationed at Thule; the time change took place
+# there at 2:00 AM.
+
+# From Paul Eggert (2006-03-22):
+# From 1997 on the CIA map shows Danmarkshavn on GMT;
+# the 1995 map as like Godthab.
+# For lack of better info, assume they were like Godthab before 1996.
+# startkart.no says Thule does not observe DST, but this is clearly an error,
+# so go with Shanks & Pottenger for Thule transitions until this year.
+# For 2007 on assume Thule will stay in sync with US DST rules.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Thule	1991	1992	-	Mar	lastSun	2:00	1:00	D
+Rule	Thule	1991	1992	-	Sep	lastSun	2:00	0	S
+Rule	Thule	1993	2006	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Thule	1993	2006	-	Oct	lastSun	2:00	0	S
+Rule	Thule	2007	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	Thule	2007	max	-	Nov	Sun>=1	2:00	0	S
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Danmarkshavn -1:14:40 -	LMT	1916 Jul 28
+			-3:00	-	WGT	1980 Apr  6 2:00
+			-3:00	EU	WG%sT	1996
+			0:00	-	GMT
+Zone America/Scoresbysund -1:27:52 -	LMT	1916 Jul 28 # Ittoqqortoormiit
+			-2:00	-	CGT	1980 Apr  6 2:00
+			-2:00	C-Eur	CG%sT	1981 Mar 29
+			-1:00	EU	EG%sT
+Zone America/Godthab	-3:26:56 -	LMT	1916 Jul 28 # Nuuk
+			-3:00	-	WGT	1980 Apr  6 2:00
+			-3:00	EU	WG%sT
+Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik air base
+			-4:00	Thule	A%sT
+
+# Estonia
+# From Peter Ilieve (1994-10-15):
+# A relative in Tallinn confirms the accuracy of the data for 1989 onwards
+# [through 1994] and gives the legal authority for it,
+# a regulation of the Government of Estonia, No. 111 of 1989....
+#
+# From Peter Ilieve (1996-10-28):
+# [IATA SSIM (1992/1996) claims that the Baltic republics switch at 01:00s,
+# but a relative confirms that Estonia still switches at 02:00s, writing:]
+# ``I do not [know] exactly but there are some little different
+# (confusing) rules for International Air and Railway Transport Schedules
+# conversion in Sunday connected with end of summer time in Estonia....
+# A discussion is running about the summer time efficiency and effect on
+# human physiology.  It seems that Estonia maybe will not change to
+# summer time next spring.''
+
+# From Peter Ilieve (1998-11-04), heavily edited:
+# <a href="http://trip.rk.ee/cgi-bin/thw?${BASE}=akt&${OOHTML}=rtd&TA=1998&TO=1&AN=1390">
+# The 1998-09-22 Estonian time law
+# </a>
+# refers to the Eighth Directive and cites the association agreement between
+# the EU and Estonia, ratified by the Estonian law (RT II 1995, 22--27, 120).
+#
+# I also asked [my relative] whether they use any standard abbreviation
+# for their standard and summer times. He says no, they use "suveaeg"
+# (summer time) and "talveaeg" (winter time).
+
+# From <a href="http://www.baltictimes.com/">The Baltic Times</a> (1999-09-09)
+# via Steffen Thorsen:
+# This year will mark the last time Estonia shifts to summer time,
+# a council of the ruling coalition announced Sept. 6....
+# But what this could mean for Estonia's chances of joining the European
+# Union are still unclear.  In 1994, the EU declared summer time compulsory
+# for all member states until 2001.  Brussels has yet to decide what to do
+# after that.
+
+# From Mart Oruaas (2000-01-29):
+# Regulation no. 301 (1999-10-12) obsoletes previous regulation
+# no. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all
+# the year round.  The regulation is effective 1999-11-01.
+
+# From Toomas Soome (2002-02-21):
+# The Estonian government has changed once again timezone politics.
+# Now we are using again EU rules.
+#
+# From Urmet Jaanes (2002-03-28):
+# The legislative reference is Government decree No. 84 on 2002-02-21.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Tallinn	1:39:00	-	LMT	1880
+			1:39:00	-	TMT	1918 Feb # Tallinn Mean Time
+			1:00	C-Eur	CE%sT	1919 Jul
+			1:39:00	-	TMT	1921 May
+			2:00	-	EET	1940 Aug  6
+			3:00	-	MSK	1941 Sep 15
+			1:00	C-Eur	CE%sT	1944 Sep 22
+			3:00	Russia	MSK/MSD	1989 Mar 26 2:00s
+			2:00	1:00	EEST	1989 Sep 24 2:00s
+			2:00	C-Eur	EE%sT	1998 Sep 22
+			2:00	EU	EE%sT	1999 Nov  1
+			2:00	-	EET	2002 Feb 21
+			2:00	EU	EE%sT
+
+# Finland
+
+# From Hannu Strang (1994-09-25 06:03:37 UTC):
+# Well, here in Helsinki we're just changing from summer time to regular one,
+# and it's supposed to change at 4am...
+
+# From Janne Snabb (2010-0715):
+#
+# I noticed that the Finland data is not accurate for years 1981 and 1982.
+# During these two first trial years the DST adjustment was made one hour
+# earlier than in forthcoming years. Starting 1983 the adjustment was made
+# according to the central European standards.
+#
+# This is documented in Heikki Oja: Aikakirja 2007, published by The Almanac
+# Office of University of Helsinki, ISBN 952-10-3221-9, available online (in
+# Finnish) at
+#
+# <a href="http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf">
+# http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf
+# </a>
+#
+# Page 105 (56 in PDF version) has a handy table of all past daylight savings
+# transitions. It is easy enough to interpret without Finnish skills.
+#
+# This is also confirmed by Finnish Broadcasting Company's archive at:
+#
+# <a href="http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401">
+# http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401
+# </a>
+#
+# The news clip from 1981 says that "the time between 2 and 3 o'clock does not
+# exist tonight."
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Finland	1942	only	-	Apr	3	0:00	1:00	S
+Rule	Finland	1942	only	-	Oct	3	0:00	0	-
+Rule	Finland	1981	1982	-	Mar	lastSun	2:00	1:00	S
+Rule	Finland	1981	1982	-	Sep	lastSun	3:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Helsinki	1:39:52 -	LMT	1878 May 31
+			1:39:52	-	HMT	1921 May    # Helsinki Mean Time
+			2:00	Finland	EE%sT	1983
+			2:00	EU	EE%sT
+
+# Aaland Is
+Link	Europe/Helsinki	Europe/Mariehamn
+
+
+# France
+
+# From Ciro Discepolo (2000-12-20):
+#
+# Henri Le Corre, Regimes Horaires pour le monde entier, Editions
+# Traditionnelles - Paris 2 books, 1993
+#
+# Gabriel, Traite de l'heure dans le monde, Guy Tredaniel editeur,
+# Paris, 1991
+#
+# Francoise Gauquelin, Problemes de l'heure resolus en astrologie,
+# Guy tredaniel, Paris 1987
+
+
+#
+# Shank & Pottenger seem to use `24:00' ambiguously; resolve it with Whitman.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	France	1916	only	-	Jun	14	23:00s	1:00	S
+Rule	France	1916	1919	-	Oct	Sun>=1	23:00s	0	-
+Rule	France	1917	only	-	Mar	24	23:00s	1:00	S
+Rule	France	1918	only	-	Mar	 9	23:00s	1:00	S
+Rule	France	1919	only	-	Mar	 1	23:00s	1:00	S
+Rule	France	1920	only	-	Feb	14	23:00s	1:00	S
+Rule	France	1920	only	-	Oct	23	23:00s	0	-
+Rule	France	1921	only	-	Mar	14	23:00s	1:00	S
+Rule	France	1921	only	-	Oct	25	23:00s	0	-
+Rule	France	1922	only	-	Mar	25	23:00s	1:00	S
+# DSH writes that a law of 1923-05-24 specified 3rd Sat in Apr at 23:00 to 1st
+# Sat in Oct at 24:00; and that in 1930, because of Easter, the transitions
+# were Apr 12 and Oct 5.  Go with Shanks & Pottenger.
+Rule	France	1922	1938	-	Oct	Sat>=1	23:00s	0	-
+Rule	France	1923	only	-	May	26	23:00s	1:00	S
+Rule	France	1924	only	-	Mar	29	23:00s	1:00	S
+Rule	France	1925	only	-	Apr	 4	23:00s	1:00	S
+Rule	France	1926	only	-	Apr	17	23:00s	1:00	S
+Rule	France	1927	only	-	Apr	 9	23:00s	1:00	S
+Rule	France	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	France	1929	only	-	Apr	20	23:00s	1:00	S
+Rule	France	1930	only	-	Apr	12	23:00s	1:00	S
+Rule	France	1931	only	-	Apr	18	23:00s	1:00	S
+Rule	France	1932	only	-	Apr	 2	23:00s	1:00	S
+Rule	France	1933	only	-	Mar	25	23:00s	1:00	S
+Rule	France	1934	only	-	Apr	 7	23:00s	1:00	S
+Rule	France	1935	only	-	Mar	30	23:00s	1:00	S
+Rule	France	1936	only	-	Apr	18	23:00s	1:00	S
+Rule	France	1937	only	-	Apr	 3	23:00s	1:00	S
+Rule	France	1938	only	-	Mar	26	23:00s	1:00	S
+Rule	France	1939	only	-	Apr	15	23:00s	1:00	S
+Rule	France	1939	only	-	Nov	18	23:00s	0	-
+Rule	France	1940	only	-	Feb	25	 2:00	1:00	S
+# The French rules for 1941-1944 were not used in Paris, but Shanks & Pottenger
+# write that they were used in Monaco and in many French locations.
+# Le Corre writes that the upper limit of the free zone was Arneguy, Orthez,
+# Mont-de-Marsan, Bazas, Langon, Lamotte-Montravel, Marouil, La
+# Rochefoucault, Champagne-Mouton, La Roche-Posay, La Haye-Descartes,
+# Loches, Montrichard, Vierzon, Bourges, Moulins, Digoin,
+# Paray-le-Monial, Montceau-les-Mines, Chalons-sur-Saone, Arbois,
+# Dole, Morez, St-Claude, and Collonges (Haute-Savoie).
+Rule	France	1941	only	-	May	 5	 0:00	2:00	M # Midsummer
+# Shanks & Pottenger say this transition occurred at Oct 6 1:00,
+# but go with Denis Excoffier (1997-12-12),
+# who quotes the Ephemerides Astronomiques for 1998 from Bureau des Longitudes
+# as saying 5/10/41 22hUT.
+Rule	France	1941	only	-	Oct	 6	 0:00	1:00	S
+Rule	France	1942	only	-	Mar	 9	 0:00	2:00	M
+Rule	France	1942	only	-	Nov	 2	 3:00	1:00	S
+Rule	France	1943	only	-	Mar	29	 2:00	2:00	M
+Rule	France	1943	only	-	Oct	 4	 3:00	1:00	S
+Rule	France	1944	only	-	Apr	 3	 2:00	2:00	M
+Rule	France	1944	only	-	Oct	 8	 1:00	1:00	S
+Rule	France	1945	only	-	Apr	 2	 2:00	2:00	M
+Rule	France	1945	only	-	Sep	16	 3:00	0	-
+# Shanks & Pottenger give Mar 28 2:00 and Sep 26 3:00;
+# go with Excoffier's 28/3/76 0hUT and 25/9/76 23hUT.
+Rule	France	1976	only	-	Mar	28	 1:00	1:00	S
+Rule	France	1976	only	-	Sep	26	 1:00	0	-
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time, and Whitman 0:09:05,
+# but Howse quotes the actual French legislation as saying 0:09:21.
+# Go with Howse.  Howse writes that the time in France was officially based
+# on PMT-0:09:21 until 1978-08-09, when the time base finally switched to UTC.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Paris	0:09:21 -	LMT	1891 Mar 15  0:01
+			0:09:21	-	PMT	1911 Mar 11  0:01  # Paris MT
+# Shanks & Pottenger give 1940 Jun 14 0:00; go with Excoffier and Le Corre.
+			0:00	France	WE%sT	1940 Jun 14 23:00
+# Le Corre says Paris stuck with occupied-France time after the liberation;
+# go with Shanks & Pottenger.
+			1:00	C-Eur	CE%sT	1944 Aug 25
+			0:00	France	WE%sT	1945 Sep 16  3:00
+			1:00	France	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Germany
+
+# From Markus Kuhn (1998-09-29):
+# The German time zone web site by the Physikalisch-Technische
+# Bundesanstalt contains DST information back to 1916.
+# [See tz-link.htm for the URL.]
+
+# From Joerg Schilling (2002-10-23):
+# In 1945, Berlin was switched to Moscow Summer time (GMT+4) by
+# <a href="http://www.dhm.de/lemo/html/biografien/BersarinNikolai/">
+# General [Nikolai] Bersarin</a>.
+
+# From Paul Eggert (2003-03-08):
+# <a href="http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf">
+# http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf
+# </a>
+# says that Bersarin issued an order to use Moscow time on May 20.
+# However, Moscow did not observe daylight saving in 1945, so
+# this was equivalent to CEMT (GMT+3), not GMT+4.
+
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Germany	1946	only	-	Apr	14	2:00s	1:00	S
+Rule	Germany	1946	only	-	Oct	 7	2:00s	0	-
+Rule	Germany	1947	1949	-	Oct	Sun>=1	2:00s	0	-
+# http://www.ptb.de/de/org/4/44/441/salt.htm says the following transition
+# occurred at 3:00 MEZ, not the 2:00 MEZ given in Shanks & Pottenger.
+# Go with the PTB.
+Rule	Germany	1947	only	-	Apr	 6	3:00s	1:00	S
+Rule	Germany	1947	only	-	May	11	2:00s	2:00	M
+Rule	Germany	1947	only	-	Jun	29	3:00	1:00	S
+Rule	Germany	1948	only	-	Apr	18	2:00s	1:00	S
+Rule	Germany	1949	only	-	Apr	10	2:00s	1:00	S
+
+Rule SovietZone	1945	only	-	May	24	2:00	2:00	M # Midsummer
+Rule SovietZone	1945	only	-	Sep	24	3:00	1:00	S
+Rule SovietZone	1945	only	-	Nov	18	2:00s	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Berlin	0:53:28 -	LMT	1893 Apr
+			1:00	C-Eur	CE%sT	1945 May 24 2:00
+			1:00 SovietZone	CE%sT	1946
+			1:00	Germany	CE%sT	1980
+			1:00	EU	CE%sT
+
+# Georgia
+# Please see the "asia" file for Asia/Tbilisi.
+# Herodotus (Histories, IV.45) says Georgia north of the Phasis (now Rioni)
+# is in Europe.  Our reference location Tbilisi is in the Asian part.
+
+# Gibraltar
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Gibraltar	-0:21:24 -	LMT	1880 Aug  2 0:00s
+			0:00	GB-Eire	%s	1957 Apr 14 2:00
+			1:00	-	CET	1982
+			1:00	EU	CE%sT
+
+# Greece
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Whitman gives 1932 Jul 5 - Nov 1; go with Shanks & Pottenger.
+Rule	Greece	1932	only	-	Jul	 7	0:00	1:00	S
+Rule	Greece	1932	only	-	Sep	 1	0:00	0	-
+# Whitman gives 1941 Apr 25 - ?; go with Shanks & Pottenger.
+Rule	Greece	1941	only	-	Apr	 7	0:00	1:00	S
+# Whitman gives 1942 Feb 2 - ?; go with Shanks & Pottenger.
+Rule	Greece	1942	only	-	Nov	 2	3:00	0	-
+Rule	Greece	1943	only	-	Mar	30	0:00	1:00	S
+Rule	Greece	1943	only	-	Oct	 4	0:00	0	-
+# Whitman gives 1944 Oct 3 - Oct 31; go with Shanks & Pottenger.
+Rule	Greece	1952	only	-	Jul	 1	0:00	1:00	S
+Rule	Greece	1952	only	-	Nov	 2	0:00	0	-
+Rule	Greece	1975	only	-	Apr	12	0:00s	1:00	S
+Rule	Greece	1975	only	-	Nov	26	0:00s	0	-
+Rule	Greece	1976	only	-	Apr	11	2:00s	1:00	S
+Rule	Greece	1976	only	-	Oct	10	2:00s	0	-
+Rule	Greece	1977	1978	-	Apr	Sun>=1	2:00s	1:00	S
+Rule	Greece	1977	only	-	Sep	26	2:00s	0	-
+Rule	Greece	1978	only	-	Sep	24	4:00	0	-
+Rule	Greece	1979	only	-	Apr	 1	9:00	1:00	S
+Rule	Greece	1979	only	-	Sep	29	2:00	0	-
+Rule	Greece	1980	only	-	Apr	 1	0:00	1:00	S
+Rule	Greece	1980	only	-	Sep	28	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Athens	1:34:52 -	LMT	1895 Sep 14
+			1:34:52	-	AMT	1916 Jul 28 0:01     # Athens MT
+			2:00	Greece	EE%sT	1941 Apr 30
+			1:00	Greece	CE%sT	1944 Apr  4
+			2:00	Greece	EE%sT	1981
+			# Shanks & Pottenger say it switched to C-Eur in 1981;
+			# go with EU instead, since Greece joined it on Jan 1.
+			2:00	EU	EE%sT
+
+# Hungary
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Hungary	1918	only	-	Apr	 1	 3:00	1:00	S
+Rule	Hungary	1918	only	-	Sep	29	 3:00	0	-
+Rule	Hungary	1919	only	-	Apr	15	 3:00	1:00	S
+Rule	Hungary	1919	only	-	Sep	15	 3:00	0	-
+Rule	Hungary	1920	only	-	Apr	 5	 3:00	1:00	S
+Rule	Hungary	1920	only	-	Sep	30	 3:00	0	-
+Rule	Hungary	1945	only	-	May	 1	23:00	1:00	S
+Rule	Hungary	1945	only	-	Nov	 3	 0:00	0	-
+Rule	Hungary	1946	only	-	Mar	31	 2:00s	1:00	S
+Rule	Hungary	1946	1949	-	Oct	Sun>=1	 2:00s	0	-
+Rule	Hungary	1947	1949	-	Apr	Sun>=4	 2:00s	1:00	S
+Rule	Hungary	1950	only	-	Apr	17	 2:00s	1:00	S
+Rule	Hungary	1950	only	-	Oct	23	 2:00s	0	-
+Rule	Hungary	1954	1955	-	May	23	 0:00	1:00	S
+Rule	Hungary	1954	1955	-	Oct	 3	 0:00	0	-
+Rule	Hungary	1956	only	-	Jun	Sun>=1	 0:00	1:00	S
+Rule	Hungary	1956	only	-	Sep	lastSun	 0:00	0	-
+Rule	Hungary	1957	only	-	Jun	Sun>=1	 1:00	1:00	S
+Rule	Hungary	1957	only	-	Sep	lastSun	 3:00	0	-
+Rule	Hungary	1980	only	-	Apr	 6	 1:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Budapest	1:16:20 -	LMT	1890 Oct
+			1:00	C-Eur	CE%sT	1918
+			1:00	Hungary	CE%sT	1941 Apr  6  2:00
+			1:00	C-Eur	CE%sT	1945
+			1:00	Hungary	CE%sT	1980 Sep 28  2:00s
+			1:00	EU	CE%sT
+
+# Iceland
+#
+# From Adam David (1993-11-06):
+# The name of the timezone in Iceland for system / mail / news purposes is GMT.
+#
+# (1993-12-05):
+# This material is paraphrased from the 1988 edition of the University of
+# Iceland Almanak.
+#
+# From January 1st, 1908 the whole of Iceland was standardised at 1 hour
+# behind GMT. Previously, local mean solar time was used in different parts
+# of Iceland, the almanak had been based on Reykjavik mean solar time which
+# was 1 hour and 28 minutes behind GMT.
+#
+# "first day of winter" referred to [below] means the first day of the 26 weeks
+# of winter, according to the old icelandic calendar that dates back to the
+# time the norsemen first settled Iceland.  The first day of winter is always
+# Saturday, but is not dependent on the Julian or Gregorian calendars.
+#
+# (1993-12-10):
+# I have a reference from the Oxford Icelandic-English dictionary for the
+# beginning of winter, which ties it to the ecclesiastical calendar (and thus
+# to the julian/gregorian calendar) over the period in question.
+#	the winter begins on the Saturday next before St. Luke's day
+#	(old style), or on St. Luke's day, if a Saturday.
+# St. Luke's day ought to be traceable from ecclesiastical sources. "old style"
+# might be a reference to the Julian calendar as opposed to Gregorian, or it
+# might mean something else (???).
+#
+# From Paul Eggert (2006-03-22):
+# The Iceland Almanak, Shanks & Pottenger, and Whitman disagree on many points.
+# We go with the Almanak, except for one claim from Shanks & Pottenger, namely
+# that Reykavik was 21W57 from 1837 to 1908, local mean time before that.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Iceland	1917	1918	-	Feb	19	23:00	1:00	S
+Rule	Iceland	1917	only	-	Oct	21	 1:00	0	-
+Rule	Iceland	1918	only	-	Nov	16	 1:00	0	-
+Rule	Iceland	1939	only	-	Apr	29	23:00	1:00	S
+Rule	Iceland	1939	only	-	Nov	29	 2:00	0	-
+Rule	Iceland	1940	only	-	Feb	25	 2:00	1:00	S
+Rule	Iceland	1940	only	-	Nov	 3	 2:00	0	-
+Rule	Iceland	1941	only	-	Mar	 2	 1:00s	1:00	S
+Rule	Iceland	1941	only	-	Nov	 2	 1:00s	0	-
+Rule	Iceland	1942	only	-	Mar	 8	 1:00s	1:00	S
+Rule	Iceland	1942	only	-	Oct	25	 1:00s	0	-
+# 1943-1946 - first Sunday in March until first Sunday in winter
+Rule	Iceland	1943	1946	-	Mar	Sun>=1	 1:00s	1:00	S
+Rule	Iceland	1943	1948	-	Oct	Sun>=22	 1:00s	0	-
+# 1947-1967 - first Sunday in April until first Sunday in winter
+Rule	Iceland	1947	1967	-	Apr	Sun>=1	 1:00s	1:00	S
+# 1949 Oct transition delayed by 1 week
+Rule	Iceland	1949	only	-	Oct	30	 1:00s	0	-
+Rule	Iceland	1950	1966	-	Oct	Sun>=22	 1:00s	0	-
+Rule	Iceland	1967	only	-	Oct	29	 1:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/Reykjavik	-1:27:24 -	LMT	1837
+			-1:27:48 -	RMT	1908 # Reykjavik Mean Time?
+			-1:00	Iceland	IS%sT	1968 Apr 7 1:00s
+			 0:00	-	GMT
+
+# Italy
+#
+# From Paul Eggert (2001-03-06):
+# Sicily and Sardinia each had their own time zones from 1866 to 1893,
+# called Palermo Time (+00:53:28) and Cagliari Time (+00:36:32).
+# During World War II, German-controlled Italy used German time.
+# But these events all occurred before the 1970 cutoff,
+# so record only the time in Rome.
+#
+# From Paul Eggert (2006-03-22):
+# For Italian DST we have three sources: Shanks & Pottenger, Whitman, and
+# F. Pollastri
+# <a href="http://toi.iriti.cnr.it/uk/ienitlt.html">
+# Day-light Saving Time in Italy (2006-02-03)
+# </a>
+# (`FP' below), taken from an Italian National Electrotechnical Institute
+# publication. When the three sources disagree, guess who's right, as follows:
+#
+# year	FP	Shanks&P. (S)	Whitman (W)	Go with:
+# 1916	06-03	06-03 24:00	06-03 00:00	FP & W
+#	09-30	09-30 24:00	09-30 01:00	FP; guess 24:00s
+# 1917	04-01	03-31 24:00	03-31 00:00	FP & S
+#	09-30	09-29 24:00	09-30 01:00	FP & W
+# 1918	03-09	03-09 24:00	03-09 00:00	FP & S
+#	10-06	10-05 24:00	10-06 01:00	FP & W
+# 1919	03-01	03-01 24:00	03-01 00:00	FP & S
+#	10-04	10-04 24:00	10-04 01:00	FP; guess 24:00s
+# 1920	03-20	03-20 24:00	03-20 00:00	FP & S
+#	09-18	09-18 24:00	10-01 01:00	FP; guess 24:00s
+# 1944	04-02	04-03 02:00			S (see C-Eur)
+#	09-16	10-02 03:00			FP; guess 24:00s
+# 1945	09-14	09-16 24:00			FP; guess 24:00s
+# 1970	05-21	05-31 00:00			S
+#	09-20	09-27 00:00			S
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Italy	1916	only	-	Jun	 3	0:00s	1:00	S
+Rule	Italy	1916	only	-	Oct	 1	0:00s	0	-
+Rule	Italy	1917	only	-	Apr	 1	0:00s	1:00	S
+Rule	Italy	1917	only	-	Sep	30	0:00s	0	-
+Rule	Italy	1918	only	-	Mar	10	0:00s	1:00	S
+Rule	Italy	1918	1919	-	Oct	Sun>=1	0:00s	0	-
+Rule	Italy	1919	only	-	Mar	 2	0:00s	1:00	S
+Rule	Italy	1920	only	-	Mar	21	0:00s	1:00	S
+Rule	Italy	1920	only	-	Sep	19	0:00s	0	-
+Rule	Italy	1940	only	-	Jun	15	0:00s	1:00	S
+Rule	Italy	1944	only	-	Sep	17	0:00s	0	-
+Rule	Italy	1945	only	-	Apr	 2	2:00	1:00	S
+Rule	Italy	1945	only	-	Sep	15	0:00s	0	-
+Rule	Italy	1946	only	-	Mar	17	2:00s	1:00	S
+Rule	Italy	1946	only	-	Oct	 6	2:00s	0	-
+Rule	Italy	1947	only	-	Mar	16	0:00s	1:00	S
+Rule	Italy	1947	only	-	Oct	 5	0:00s	0	-
+Rule	Italy	1948	only	-	Feb	29	2:00s	1:00	S
+Rule	Italy	1948	only	-	Oct	 3	2:00s	0	-
+Rule	Italy	1966	1968	-	May	Sun>=22	0:00	1:00	S
+Rule	Italy	1966	1969	-	Sep	Sun>=22	0:00	0	-
+Rule	Italy	1969	only	-	Jun	 1	0:00	1:00	S
+Rule	Italy	1970	only	-	May	31	0:00	1:00	S
+Rule	Italy	1970	only	-	Sep	lastSun	0:00	0	-
+Rule	Italy	1971	1972	-	May	Sun>=22	0:00	1:00	S
+Rule	Italy	1971	only	-	Sep	lastSun	1:00	0	-
+Rule	Italy	1972	only	-	Oct	 1	0:00	0	-
+Rule	Italy	1973	only	-	Jun	 3	0:00	1:00	S
+Rule	Italy	1973	1974	-	Sep	lastSun	0:00	0	-
+Rule	Italy	1974	only	-	May	26	0:00	1:00	S
+Rule	Italy	1975	only	-	Jun	 1	0:00s	1:00	S
+Rule	Italy	1975	1977	-	Sep	lastSun	0:00s	0	-
+Rule	Italy	1976	only	-	May	30	0:00s	1:00	S
+Rule	Italy	1977	1979	-	May	Sun>=22	0:00s	1:00	S
+Rule	Italy	1978	only	-	Oct	 1	0:00s	0	-
+Rule	Italy	1979	only	-	Sep	30	0:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Rome	0:49:56 -	LMT	1866 Sep 22
+			0:49:56	-	RMT	1893 Nov  1 0:00s # Rome Mean
+			1:00	Italy	CE%sT	1942 Nov  2 2:00s
+			1:00	C-Eur	CE%sT	1944 Jul
+			1:00	Italy	CE%sT	1980
+			1:00	EU	CE%sT
+
+Link	Europe/Rome	Europe/Vatican
+Link	Europe/Rome	Europe/San_Marino
+
+# Latvia
+
+# From Liene Kanepe (1998-09-17):
+
+# I asked about this matter Scientific Secretary of the Institute of Astronomy
+# of The University of Latvia Dr. paed Mr. Ilgonis Vilks. I also searched the
+# correct data in juridical acts and I found some juridical documents about
+# changes in the counting of time in Latvia from 1981....
+#
+# Act No.35 of the Council of Ministers of Latvian SSR of 1981-01-22 ...
+# according to the Act No.925 of the Council of Ministers of USSR of 1980-10-24
+# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
+# the hands of the clock 1 hour forward on 1 April at 00:00 (GMT 31 March 21:00)
+# and 1 hour backward on the 1 October at 00:00 (GMT 30 September 20:00).
+#
+# Act No.592 of the Council of Ministers of Latvian SSR of 1984-09-24 ...
+# according to the Act No.967 of the Council of Ministers of USSR of 1984-09-13
+# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
+# the hands of the clock 1 hour forward on the last Sunday of March at 02:00
+# (GMT 23:00 on the previous day) and 1 hour backward on the last Sunday of
+# September at 03:00 (GMT 23:00 on the previous day).
+#
+# Act No.81 of the Council of Ministers of Latvian SSR of 1989-03-22 ...
+# according to the Act No.227 of the Council of Ministers of USSR of 1989-03-14
+# ...: since the last Sunday of March 1989 in Lithuanian SSR, Latvian SSR,
+# Estonian SSR and Kaliningrad region of Russian Federation all year round the
+# time of 2nd time zone (Moscow time minus one hour). On the territory of Latvia
+# transition to summer time is performed on the last Sunday of March at 02:00
+# (GMT 00:00), turning the hands of the clock 1 hour forward.  The end of
+# daylight saving time is performed on the last Sunday of September at 03:00
+# (GMT 00:00), turning the hands of the clock 1 hour backward. Exception is
+# 1989-03-26, when we must not turn the hands of the clock....
+#
+# The Regulations of the Cabinet of Ministers of the Republic of Latvia of
+# 1997-01-21 on transition to Summer time ... established the same order of
+# daylight savings time settings as in the States of the European Union.
+
+# From Andrei Ivanov (2000-03-06):
+# This year Latvia will not switch to Daylight Savings Time (as specified in
+# <a href="http://www.lv-laiks.lv/wwwraksti/2000/071072/vd4.htm">
+# The Regulations of the Cabinet of Ministers of the Rep. of Latvia of
+# 29-Feb-2000 (#79)</a>, in Latvian for subscribers only).
+
+# <a href="http://www.rferl.org/newsline/2001/01/3-CEE/cee-030101.html">
+# From RFE/RL Newsline (2001-01-03), noted after a heads-up by Rives McDow:
+# </a>
+# The Latvian government on 2 January decided that the country will
+# institute daylight-saving time this spring, LETA reported.
+# Last February the three Baltic states decided not to turn back their
+# clocks one hour in the spring....
+# Minister of Economy Aigars Kalvitis noted that Latvia had too few
+# daylight hours and thus decided to comply with a draft European
+# Commission directive that provides for instituting daylight-saving
+# time in EU countries between 2002 and 2006. The Latvian government
+# urged Lithuania and Estonia to adopt a similar time policy, but it
+# appears that they will not do so....
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Latvia	1989	1996	-	Mar	lastSun	 2:00s	1:00	S
+Rule	Latvia	1989	1996	-	Sep	lastSun	 2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Riga	1:36:24	-	LMT	1880
+			1:36:24	-	RMT	1918 Apr 15 2:00 #Riga Mean Time
+			1:36:24	1:00	LST	1918 Sep 16 3:00 #Latvian Summer
+			1:36:24	-	RMT	1919 Apr  1 2:00
+			1:36:24	1:00	LST	1919 May 22 3:00
+			1:36:24	-	RMT	1926 May 11
+			2:00	-	EET	1940 Aug  5
+			3:00	-	MSK	1941 Jul
+			1:00	C-Eur	CE%sT	1944 Oct 13
+			3:00	Russia	MSK/MSD	1989 Mar lastSun 2:00s
+			2:00	1:00	EEST	1989 Sep lastSun 2:00s
+			2:00	Latvia	EE%sT	1997 Jan 21
+			2:00	EU	EE%sT	2000 Feb 29
+			2:00	-	EET	2001 Jan  2
+			2:00	EU	EE%sT
+
+# Liechtenstein
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Vaduz	0:38:04 -	LMT	1894 Jun
+			1:00	-	CET	1981
+			1:00	EU	CE%sT
+
+# Lithuania
+
+# From Paul Eggert (1996-11-22):
+# IATA SSIM (1992/1996) says Lithuania uses W-Eur rules, but since it is
+# known to be wrong about Estonia and Latvia, assume it's wrong here too.
+
+# From Marius Gedminas (1998-08-07):
+# I would like to inform that in this year Lithuanian time zone
+# (Europe/Vilnius) was changed.
+
+# From <a href="http://www.elta.lt/">ELTA</a> No. 972 (2582) (1999-09-29),
+# via Steffen Thorsen:
+# Lithuania has shifted back to the second time zone (GMT plus two hours)
+# to be valid here starting from October 31,
+# as decided by the national government on Wednesday....
+# The Lithuanian government also announced plans to consider a
+# motion to give up shifting to summer time in spring, as it was
+# already done by Estonia.
+
+# From the <a href="http://www.tourism.lt/informa/ff.htm">
+# Fact File, Lithuanian State Department of Tourism
+# </a> (2000-03-27): Local time is GMT+2 hours ..., no daylight saving.
+
+# From a user via Klaus Marten (2003-02-07):
+# As a candidate for membership of the European Union, Lithuania will
+# observe Summer Time in 2003, changing its clocks at the times laid
+# down in EU Directive 2000/84 of 19.I.01 (i.e. at the same times as its
+# neighbour Latvia). The text of the Lithuanian government Order of
+# 7.XI.02 to this effect can be found at
+# http://www.lrvk.lt/nut/11/n1749.htm
+
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Vilnius	1:41:16	-	LMT	1880
+			1:24:00	-	WMT	1917	    # Warsaw Mean Time
+			1:35:36	-	KMT	1919 Oct 10 # Kaunas Mean Time
+			1:00	-	CET	1920 Jul 12
+			2:00	-	EET	1920 Oct  9
+			1:00	-	CET	1940 Aug  3
+			3:00	-	MSK	1941 Jun 24
+			1:00	C-Eur	CE%sT	1944 Aug
+			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
+			2:00	1:00	EEST	1991 Sep 29 2:00s
+			2:00	C-Eur	EE%sT	1998
+			2:00	-	EET	1998 Mar 29 1:00u
+			1:00	EU	CE%sT	1999 Oct 31 1:00u
+			2:00	-	EET	2003 Jan  1
+			2:00	EU	EE%sT
+
+# Luxembourg
+# Whitman disagrees with most of these dates in minor ways;
+# go with Shanks & Pottenger.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Lux	1916	only	-	May	14	23:00	1:00	S
+Rule	Lux	1916	only	-	Oct	 1	 1:00	0	-
+Rule	Lux	1917	only	-	Apr	28	23:00	1:00	S
+Rule	Lux	1917	only	-	Sep	17	 1:00	0	-
+Rule	Lux	1918	only	-	Apr	Mon>=15	 2:00s	1:00	S
+Rule	Lux	1918	only	-	Sep	Mon>=15	 2:00s	0	-
+Rule	Lux	1919	only	-	Mar	 1	23:00	1:00	S
+Rule	Lux	1919	only	-	Oct	 5	 3:00	0	-
+Rule	Lux	1920	only	-	Feb	14	23:00	1:00	S
+Rule	Lux	1920	only	-	Oct	24	 2:00	0	-
+Rule	Lux	1921	only	-	Mar	14	23:00	1:00	S
+Rule	Lux	1921	only	-	Oct	26	 2:00	0	-
+Rule	Lux	1922	only	-	Mar	25	23:00	1:00	S
+Rule	Lux	1922	only	-	Oct	Sun>=2	 1:00	0	-
+Rule	Lux	1923	only	-	Apr	21	23:00	1:00	S
+Rule	Lux	1923	only	-	Oct	Sun>=2	 2:00	0	-
+Rule	Lux	1924	only	-	Mar	29	23:00	1:00	S
+Rule	Lux	1924	1928	-	Oct	Sun>=2	 1:00	0	-
+Rule	Lux	1925	only	-	Apr	 5	23:00	1:00	S
+Rule	Lux	1926	only	-	Apr	17	23:00	1:00	S
+Rule	Lux	1927	only	-	Apr	 9	23:00	1:00	S
+Rule	Lux	1928	only	-	Apr	14	23:00	1:00	S
+Rule	Lux	1929	only	-	Apr	20	23:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Luxembourg	0:24:36 -	LMT	1904 Jun
+			1:00	Lux	CE%sT	1918 Nov 25
+			0:00	Lux	WE%sT	1929 Oct  6 2:00s
+			0:00	Belgium	WE%sT	1940 May 14 3:00
+			1:00	C-Eur	WE%sT	1944 Sep 18 3:00
+			1:00	Belgium	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Macedonia
+# see Serbia
+
+# Malta
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Malta	1973	only	-	Mar	31	0:00s	1:00	S
+Rule	Malta	1973	only	-	Sep	29	0:00s	0	-
+Rule	Malta	1974	only	-	Apr	21	0:00s	1:00	S
+Rule	Malta	1974	only	-	Sep	16	0:00s	0	-
+Rule	Malta	1975	1979	-	Apr	Sun>=15	2:00	1:00	S
+Rule	Malta	1975	1980	-	Sep	Sun>=15	2:00	0	-
+Rule	Malta	1980	only	-	Mar	31	2:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Malta	0:58:04 -	LMT	1893 Nov  2 0:00s # Valletta
+			1:00	Italy	CE%sT	1942 Nov  2 2:00s
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
+			1:00	Italy	CE%sT	1973 Mar 31
+			1:00	Malta	CE%sT	1981
+			1:00	EU	CE%sT
+
+# Moldova
+
+# From Paul Eggert (2006-03-22):
+# A previous version of this database followed Shanks & Pottenger, who write
+# that Tiraspol switched to Moscow time on 1992-01-19 at 02:00.
+# However, this is most likely an error, as Moldova declared independence
+# on 1991-08-27 (the 1992-01-19 date is that of a Russian decree).
+# In early 1992 there was large-scale interethnic violence in the area
+# and it's possible that some Russophones continued to observe Moscow time.
+# But [two people] separately reported via
+# Jesper Norgaard that as of 2001-01-24 Tiraspol was like Chisinau.
+# The Tiraspol entry has therefore been removed for now.
+#
+# From Alexander Krivenyshev (2011-10-17):
+# Pridnestrovian Moldavian Republic (PMR, also known as
+# "Pridnestrovie") has abolished seasonal clock change (no transition
+# to the Winter Time).
+#
+# News (in Russian):
+# <a href="http://www.kyivpost.ua/russia/news/pridnestrove-otkazalos-ot-perehoda-na-zimnee-vremya-30954.html">
+# http://www.kyivpost.ua/russia/news/pridnestrove-otkazalos-ot-perehoda-na-zimnee-vremya-30954.html
+# </a>
+#
+# <a href="http://www.allmoldova.com/moldova-news/1249064116.html">
+# http://www.allmoldova.com/moldova-news/1249064116.html
+# </a>
+#
+# The substance of this change (reinstatement of the Tiraspol entry)
+# is from a patch from Petr Machata (2011-10-17)
+#
+# From Tim Parenti (2011-10-19)
+# In addition, being situated at +4651+2938 would give Tiraspol
+# a pre-1880 LMT offset of 1:58:32.
+#
+# (which agrees with the earlier entry that had been removed)
+#
+# From Alexander Krivenyshev (2011-10-26)
+# NO need to divide Moldova into two timezones at this point.
+# As of today, Transnistria (Pridnestrovie)- Tiraspol reversed its own
+# decision to abolish DST this winter.
+# Following Moldova and neighboring Ukraine- Transnistria (Pridnestrovie)-
+# Tiraspol will go back to winter time on October 30, 2011.
+# News from Moldova (in russian):
+# <a href="http://ru.publika.md/link_317061.html">
+# http://ru.publika.md/link_317061.html
+# </a>
+
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Chisinau	1:55:20 -	LMT	1880
+			1:55	-	CMT	1918 Feb 15 # Chisinau MT
+			1:44:24	-	BMT	1931 Jul 24 # Bucharest MT
+			2:00	Romania	EE%sT	1940 Aug 15
+			2:00	1:00	EEST	1941 Jul 17
+			1:00	C-Eur	CE%sT	1944 Aug 24
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 May 6
+			2:00	-	EET	1991
+			2:00	Russia	EE%sT	1992
+			2:00	E-Eur	EE%sT	1997
+# See Romania commentary for the guessed 1997 transition to EU rules.
+			2:00	EU	EE%sT
+
+# Monaco
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
+# more precise 0:09:21.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Monaco	0:29:32 -	LMT	1891 Mar 15
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
+			0:00	France	WE%sT	1945 Sep 16 3:00
+			1:00	France	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Montenegro
+# see Serbia
+
+# Netherlands
+
+# Howse writes that the Netherlands' railways used GMT between 1892 and 1940,
+# but for other purposes the Netherlands used Amsterdam mean time.
+
+# However, Robert H. van Gent writes (2001-04-01):
+# Howse's statement is only correct up to 1909. From 1909-05-01 (00:00:00
+# Amsterdam mean time) onwards, the whole of the Netherlands (including
+# the Dutch railways) was required by law to observe Amsterdam mean time
+# (19 minutes 32.13 seconds ahead of GMT). This had already been the
+# common practice (except for the railways) for many decades but it was
+# not until 1909 when the Dutch government finally defined this by law.
+# On 1937-07-01 this was changed to 20 minutes (exactly) ahead of GMT and
+# was generally known as Dutch Time ("Nederlandse Tijd").
+#
+# (2001-04-08):
+# 1892-05-01 was the date when the Dutch railways were by law required to
+# observe GMT while the remainder of the Netherlands adhered to the common
+# practice of following Amsterdam mean time.
+#
+# (2001-04-09):
+# In 1835 the authorities of the province of North Holland requested the
+# municipal authorities of the towns and cities in the province to observe
+# Amsterdam mean time but I do not know in how many cases this request was
+# actually followed.
+#
+# From 1852 onwards the Dutch telegraph offices were by law required to
+# observe Amsterdam mean time. As the time signals from the observatory of
+# Leiden were also distributed by the telegraph system, I assume that most
+# places linked up with the telegraph (and railway) system automatically
+# adopted Amsterdam mean time.
+#
+# Although the early Dutch railway companies initially observed a variety
+# of times, most of them had adopted Amsterdam mean time by 1858 but it
+# was not until 1866 when they were all required by law to observe
+# Amsterdam mean time.
+
+# The data before 1945 are taken from
+# <http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm>.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Neth	1916	only	-	May	 1	0:00	1:00	NST	# Netherlands Summer Time
+Rule	Neth	1916	only	-	Oct	 1	0:00	0	AMT	# Amsterdam Mean Time
+Rule	Neth	1917	only	-	Apr	16	2:00s	1:00	NST
+Rule	Neth	1917	only	-	Sep	17	2:00s	0	AMT
+Rule	Neth	1918	1921	-	Apr	Mon>=1	2:00s	1:00	NST
+Rule	Neth	1918	1921	-	Sep	lastMon	2:00s	0	AMT
+Rule	Neth	1922	only	-	Mar	lastSun	2:00s	1:00	NST
+Rule	Neth	1922	1936	-	Oct	Sun>=2	2:00s	0	AMT
+Rule	Neth	1923	only	-	Jun	Fri>=1	2:00s	1:00	NST
+Rule	Neth	1924	only	-	Mar	lastSun	2:00s	1:00	NST
+Rule	Neth	1925	only	-	Jun	Fri>=1	2:00s	1:00	NST
+# From 1926 through 1939 DST began 05-15, except that it was delayed by a week
+# in years when 05-15 fell in the Pentecost weekend.
+Rule	Neth	1926	1931	-	May	15	2:00s	1:00	NST
+Rule	Neth	1932	only	-	May	22	2:00s	1:00	NST
+Rule	Neth	1933	1936	-	May	15	2:00s	1:00	NST
+Rule	Neth	1937	only	-	May	22	2:00s	1:00	NST
+Rule	Neth	1937	only	-	Jul	 1	0:00	1:00	S
+Rule	Neth	1937	1939	-	Oct	Sun>=2	2:00s	0	-
+Rule	Neth	1938	1939	-	May	15	2:00s	1:00	S
+Rule	Neth	1945	only	-	Apr	 2	2:00s	1:00	S
+Rule	Neth	1945	only	-	Sep	16	2:00s	0	-
+#
+# Amsterdam Mean Time was +00:19:32.13 exactly, but the .13 is omitted
+# below because the current format requires GMTOFF to be an integer.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Amsterdam	0:19:32 -	LMT	1835
+			0:19:32	Neth	%s	1937 Jul  1
+			0:20	Neth	NE%sT	1940 May 16 0:00 # Dutch Time
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00
+			1:00	Neth	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Norway
+# http://met.no/met/met_lex/q_u/sommertid.html (2004-01) agrees with Shanks &
+# Pottenger.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Norway	1916	only	-	May	22	1:00	1:00	S
+Rule	Norway	1916	only	-	Sep	30	0:00	0	-
+Rule	Norway	1945	only	-	Apr	 2	2:00s	1:00	S
+Rule	Norway	1945	only	-	Oct	 1	2:00s	0	-
+Rule	Norway	1959	1964	-	Mar	Sun>=15	2:00s	1:00	S
+Rule	Norway	1959	1965	-	Sep	Sun>=15	2:00s	0	-
+Rule	Norway	1965	only	-	Apr	25	2:00s	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Oslo	0:43:00 -	LMT	1895 Jan  1
+			1:00	Norway	CE%sT	1940 Aug 10 23:00
+			1:00	C-Eur	CE%sT	1945 Apr  2  2:00
+			1:00	Norway	CE%sT	1980
+			1:00	EU	CE%sT
+
+# Svalbard & Jan Mayen
+
+# From Steffen Thorsen (2001-05-01):
+# Although I could not find it explicitly, it seems that Jan Mayen and
+# Svalbard have been using the same time as Norway at least since the
+# time they were declared as parts of Norway.  Svalbard was declared
+# as a part of Norway by law of 1925-07-17 no 11, section 4 and Jan
+# Mayen by law of 1930-02-27 no 2, section 2. (From
+# http://www.lovdata.no/all/nl-19250717-011.html and
+# http://www.lovdata.no/all/nl-19300227-002.html).  The law/regulation
+# for normal/standard time in Norway is from 1894-06-29 no 1 (came
+# into operation on 1895-01-01) and Svalbard/Jan Mayen seem to be a
+# part of this law since 1925/1930. (From
+# http://www.lovdata.no/all/nl-18940629-001.html ) I have not been
+# able to find if Jan Mayen used a different time zone (e.g. -0100)
+# before 1930. Jan Mayen has only been "inhabitated" since 1921 by
+# Norwegian meteorologists and maybe used the same time as Norway ever
+# since 1921.  Svalbard (Arctic/Longyearbyen) has been inhabited since
+# before 1895, and therefore probably changed the local time somewhere
+# between 1895 and 1925 (inclusive).
+
+# From Paul Eggert (2001-05-01):
+#
+# Actually, Jan Mayen was never occupied by Germany during World War II,
+# so it must have diverged from Oslo time during the war, as Oslo was
+# keeping Berlin time.
+#
+# <http://home.no.net/janmayen/history.htm> says that the meteorologists
+# burned down their station in 1940 and left the island, but returned in
+# 1941 with a small Norwegian garrison and continued operations despite
+# frequent air ttacks from Germans.  In 1943 the Americans established a
+# radiolocating station on the island, called "Atlantic City".  Possibly
+# the UTC offset changed during the war, but I think it unlikely that
+# Jan Mayen used German daylight-saving rules.
+#
+# Svalbard is more complicated, as it was raided in August 1941 by an
+# Allied party that evacuated the civilian population to England (says
+# <http://www.bartleby.com/65/sv/Svalbard.html>).  The Svalbard FAQ
+# <http://www.svalbard.com/SvalbardFAQ.html> says that the Germans were
+# expelled on 1942-05-14.  However, small parties of Germans did return,
+# and according to Wilhelm Dege's book "War North of 80" (1954)
+# <http://www.ucalgary.ca/UofC/departments/UP/1-55238/1-55238-110-2.html>
+# the German armed forces at the Svalbard weather station code-named
+# Haudegen did not surrender to the Allies until September 1945.
+#
+# All these events predate our cutoff date of 1970.  Unless we can
+# come up with more definitive info about the timekeeping during the
+# war years it's probably best just do...the following for now:
+Link	Europe/Oslo	Arctic/Longyearbyen
+
+# Poland
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Poland	1918	1919	-	Sep	16	2:00s	0	-
+Rule	Poland	1919	only	-	Apr	15	2:00s	1:00	S
+Rule	Poland	1944	only	-	Apr	 3	2:00s	1:00	S
+# Whitman gives 1944 Nov 30; go with Shanks & Pottenger.
+Rule	Poland	1944	only	-	Oct	 4	2:00	0	-
+# For 1944-1948 Whitman gives the previous day; go with Shanks & Pottenger.
+Rule	Poland	1945	only	-	Apr	29	0:00	1:00	S
+Rule	Poland	1945	only	-	Nov	 1	0:00	0	-
+# For 1946 on the source is Kazimierz Borkowski,
+# Torun Center for Astronomy, Dept. of Radio Astronomy, Nicolaus Copernicus U.,
+# <http://www.astro.uni.torun.pl/~kb/Artykuly/U-PA/Czas2.htm#tth_tAb1>
+# Thanks to Przemyslaw Augustyniak (2005-05-28) for this reference.
+# He also gives these further references:
+# Mon Pol nr 13, poz 162 (1995) <http://www.abc.com.pl/serwis/mp/1995/0162.htm>
+# Druk nr 2180 (2003) <http://www.senat.gov.pl/k5/dok/sejm/053/2180.pdf>
+Rule	Poland	1946	only	-	Apr	14	0:00s	1:00	S
+Rule	Poland	1946	only	-	Oct	 7	2:00s	0	-
+Rule	Poland	1947	only	-	May	 4	2:00s	1:00	S
+Rule	Poland	1947	1949	-	Oct	Sun>=1	2:00s	0	-
+Rule	Poland	1948	only	-	Apr	18	2:00s	1:00	S
+Rule	Poland	1949	only	-	Apr	10	2:00s	1:00	S
+Rule	Poland	1957	only	-	Jun	 2	1:00s	1:00	S
+Rule	Poland	1957	1958	-	Sep	lastSun	1:00s	0	-
+Rule	Poland	1958	only	-	Mar	30	1:00s	1:00	S
+Rule	Poland	1959	only	-	May	31	1:00s	1:00	S
+Rule	Poland	1959	1961	-	Oct	Sun>=1	1:00s	0	-
+Rule	Poland	1960	only	-	Apr	 3	1:00s	1:00	S
+Rule	Poland	1961	1964	-	May	lastSun	1:00s	1:00	S
+Rule	Poland	1962	1964	-	Sep	lastSun	1:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Warsaw	1:24:00 -	LMT	1880
+			1:24:00	-	WMT	1915 Aug  5   # Warsaw Mean Time
+			1:00	C-Eur	CE%sT	1918 Sep 16 3:00
+			2:00	Poland	EE%sT	1922 Jun
+			1:00	Poland	CE%sT	1940 Jun 23 2:00
+			1:00	C-Eur	CE%sT	1944 Oct
+			1:00	Poland	CE%sT	1977
+			1:00	W-Eur	CE%sT	1988
+			1:00	EU	CE%sT
+
+# Portugal
+#
+# From Rui Pedro Salgueiro (1992-11-12):
+# Portugal has recently (September, 27) changed timezone
+# (from WET to MET or CET) to harmonize with EEC.
+#
+# Martin Bruckmann (1996-02-29) reports via Peter Ilieve
+# that Portugal is reverting to 0:00 by not moving its clocks this spring.
+# The new Prime Minister was fed up with getting up in the dark in the winter.
+#
+# From Paul Eggert (1996-11-12):
+# IATA SSIM (1991-09) reports several 1991-09 and 1992-09 transitions
+# at 02:00u, not 01:00u.  Assume that these are typos.
+# IATA SSIM (1991/1992) reports that the Azores were at -1:00.
+# IATA SSIM (1993-02) says +0:00; later issues (through 1996-09) say -1:00.
+# Guess that the Azores changed to EU rules in 1992 (since that's when Portugal
+# harmonized with the EU), and that they stayed +0:00 that winter.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# DSH writes that despite Decree 1,469 (1915), the change to the clocks was not
+# done every year, depending on what Spain did, because of railroad schedules.
+# Go with Shanks & Pottenger.
+Rule	Port	1916	only	-	Jun	17	23:00	1:00	S
+# Whitman gives 1916 Oct 31; go with Shanks & Pottenger.
+Rule	Port	1916	only	-	Nov	 1	 1:00	0	-
+Rule	Port	1917	only	-	Feb	28	23:00s	1:00	S
+Rule	Port	1917	1921	-	Oct	14	23:00s	0	-
+Rule	Port	1918	only	-	Mar	 1	23:00s	1:00	S
+Rule	Port	1919	only	-	Feb	28	23:00s	1:00	S
+Rule	Port	1920	only	-	Feb	29	23:00s	1:00	S
+Rule	Port	1921	only	-	Feb	28	23:00s	1:00	S
+Rule	Port	1924	only	-	Apr	16	23:00s	1:00	S
+Rule	Port	1924	only	-	Oct	14	23:00s	0	-
+Rule	Port	1926	only	-	Apr	17	23:00s	1:00	S
+Rule	Port	1926	1929	-	Oct	Sat>=1	23:00s	0	-
+Rule	Port	1927	only	-	Apr	 9	23:00s	1:00	S
+Rule	Port	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	Port	1929	only	-	Apr	20	23:00s	1:00	S
+Rule	Port	1931	only	-	Apr	18	23:00s	1:00	S
+# Whitman gives 1931 Oct 8; go with Shanks & Pottenger.
+Rule	Port	1931	1932	-	Oct	Sat>=1	23:00s	0	-
+Rule	Port	1932	only	-	Apr	 2	23:00s	1:00	S
+Rule	Port	1934	only	-	Apr	 7	23:00s	1:00	S
+# Whitman gives 1934 Oct 5; go with Shanks & Pottenger.
+Rule	Port	1934	1938	-	Oct	Sat>=1	23:00s	0	-
+# Shanks & Pottenger give 1935 Apr 30; go with Whitman.
+Rule	Port	1935	only	-	Mar	30	23:00s	1:00	S
+Rule	Port	1936	only	-	Apr	18	23:00s	1:00	S
+# Whitman gives 1937 Apr 2; go with Shanks & Pottenger.
+Rule	Port	1937	only	-	Apr	 3	23:00s	1:00	S
+Rule	Port	1938	only	-	Mar	26	23:00s	1:00	S
+Rule	Port	1939	only	-	Apr	15	23:00s	1:00	S
+# Whitman gives 1939 Oct 7; go with Shanks & Pottenger.
+Rule	Port	1939	only	-	Nov	18	23:00s	0	-
+Rule	Port	1940	only	-	Feb	24	23:00s	1:00	S
+# Shanks & Pottenger give 1940 Oct 7; go with Whitman.
+Rule	Port	1940	1941	-	Oct	 5	23:00s	0	-
+Rule	Port	1941	only	-	Apr	 5	23:00s	1:00	S
+Rule	Port	1942	1945	-	Mar	Sat>=8	23:00s	1:00	S
+Rule	Port	1942	only	-	Apr	25	22:00s	2:00	M # Midsummer
+Rule	Port	1942	only	-	Aug	15	22:00s	1:00	S
+Rule	Port	1942	1945	-	Oct	Sat>=24	23:00s	0	-
+Rule	Port	1943	only	-	Apr	17	22:00s	2:00	M
+Rule	Port	1943	1945	-	Aug	Sat>=25	22:00s	1:00	S
+Rule	Port	1944	1945	-	Apr	Sat>=21	22:00s	2:00	M
+Rule	Port	1946	only	-	Apr	Sat>=1	23:00s	1:00	S
+Rule	Port	1946	only	-	Oct	Sat>=1	23:00s	0	-
+Rule	Port	1947	1949	-	Apr	Sun>=1	 2:00s	1:00	S
+Rule	Port	1947	1949	-	Oct	Sun>=1	 2:00s	0	-
+# Shanks & Pottenger say DST was observed in 1950; go with Whitman.
+# Whitman gives Oct lastSun for 1952 on; go with Shanks & Pottenger.
+Rule	Port	1951	1965	-	Apr	Sun>=1	 2:00s	1:00	S
+Rule	Port	1951	1965	-	Oct	Sun>=1	 2:00s	0	-
+Rule	Port	1977	only	-	Mar	27	 0:00s	1:00	S
+Rule	Port	1977	only	-	Sep	25	 0:00s	0	-
+Rule	Port	1978	1979	-	Apr	Sun>=1	 0:00s	1:00	S
+Rule	Port	1978	only	-	Oct	 1	 0:00s	0	-
+Rule	Port	1979	1982	-	Sep	lastSun	 1:00s	0	-
+Rule	Port	1980	only	-	Mar	lastSun	 0:00s	1:00	S
+Rule	Port	1981	1982	-	Mar	lastSun	 1:00s	1:00	S
+Rule	Port	1983	only	-	Mar	lastSun	 2:00s	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Shanks & Pottenger say the transition from LMT to WET occurred 1911-05-24;
+# Willett says 1912-01-01.  Go with Willett.
+Zone	Europe/Lisbon	-0:36:32 -	LMT	1884
+			-0:36:32 -	LMT	1912 Jan  1  # Lisbon Mean Time
+			 0:00	Port	WE%sT	1966 Apr  3 2:00
+			 1:00	-	CET	1976 Sep 26 1:00
+			 0:00	Port	WE%sT	1983 Sep 25 1:00s
+			 0:00	W-Eur	WE%sT	1992 Sep 27 1:00s
+			 1:00	EU	CE%sT	1996 Mar 31 1:00u
+			 0:00	EU	WE%sT
+Zone Atlantic/Azores	-1:42:40 -	LMT	1884		# Ponta Delgada
+			-1:54:32 -	HMT	1911 May 24  # Horta Mean Time
+			-2:00	Port	AZO%sT	1966 Apr  3 2:00 # Azores Time
+			-1:00	Port	AZO%sT	1983 Sep 25 1:00s
+			-1:00	W-Eur	AZO%sT	1992 Sep 27 1:00s
+			 0:00	EU	WE%sT	1993 Mar 28 1:00u
+			-1:00	EU	AZO%sT
+Zone Atlantic/Madeira	-1:07:36 -	LMT	1884		# Funchal
+			-1:07:36 -	FMT	1911 May 24  # Funchal Mean Time
+			-1:00	Port	MAD%sT	1966 Apr  3 2:00 # Madeira Time
+			 0:00	Port	WE%sT	1983 Sep 25 1:00s
+			 0:00	EU	WE%sT
+
+# Romania
+#
+# From Paul Eggert (1999-10-07):
+# <a href="http://www.nineoclock.ro/POL/1778pol.html">
+# Nine O'clock</a> (1998-10-23) reports that the switch occurred at
+# 04:00 local time in fall 1998.  For lack of better info,
+# assume that Romania and Moldova switched to EU rules in 1997,
+# the same year as Bulgaria.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Romania	1932	only	-	May	21	 0:00s	1:00	S
+Rule	Romania	1932	1939	-	Oct	Sun>=1	 0:00s	0	-
+Rule	Romania	1933	1939	-	Apr	Sun>=2	 0:00s	1:00	S
+Rule	Romania	1979	only	-	May	27	 0:00	1:00	S
+Rule	Romania	1979	only	-	Sep	lastSun	 0:00	0	-
+Rule	Romania	1980	only	-	Apr	 5	23:00	1:00	S
+Rule	Romania	1980	only	-	Sep	lastSun	 1:00	0	-
+Rule	Romania	1991	1993	-	Mar	lastSun	 0:00s	1:00	S
+Rule	Romania	1991	1993	-	Sep	lastSun	 0:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Bucharest	1:44:24 -	LMT	1891 Oct
+			1:44:24	-	BMT	1931 Jul 24	# Bucharest MT
+			2:00	Romania	EE%sT	1981 Mar 29 2:00s
+			2:00	C-Eur	EE%sT	1991
+			2:00	Romania	EE%sT	1994
+			2:00	E-Eur	EE%sT	1997
+			2:00	EU	EE%sT
+
+# Russia
+
+# From Paul Eggert (2006-03-22):
+# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
+# Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
+# are from Andrey A. Chernov.  The rest is from Shanks & Pottenger,
+# except we follow Chernov's report that 1992 DST transitions were Sat
+# 23:00, not Sun 02:00s.
+#
+# From Stanislaw A. Kuzikowski (1994-06-29):
+# But now it is some months since Novosibirsk is 3 hours ahead of Moscow!
+# I do not know why they have decided to make this change;
+# as far as I remember it was done exactly during winter->summer switching
+# so we (Novosibirsk) simply did not switch.
+#
+# From Andrey A. Chernov (1996-10-04):
+# `MSK' and `MSD' were born and used initially on Moscow computers with
+# UNIX-like OSes by several developer groups (e.g. Demos group, Kiae group)....
+# The next step was the UUCP network, the Relcom predecessor
+# (used mainly for mail), and MSK/MSD was actively used there.
+#
+# From Chris Carrier (1996-10-30):
+# According to a friend of mine who rode the Trans-Siberian Railroad from
+# Moscow to Irkutsk in 1995, public air and rail transport in Russia ...
+# still follows Moscow time, no matter where in Russia it is located.
+#
+# For Grozny, Chechnya, we have the following story from
+# John Daniszewski, "Scavengers in the Rubble", Los Angeles Times (2001-02-07):
+# News--often false--is spread by word of mouth.  A rumor that it was
+# time to move the clocks back put this whole city out of sync with
+# the rest of Russia for two weeks--even soldiers stationed here began
+# enforcing curfew at the wrong time.
+#
+# From Gwillim Law (2001-06-05):
+# There's considerable evidence that Sakhalin Island used to be in
+# UTC+11, and has changed to UTC+10, in this decade.  I start with the
+# SSIM, which listed Yuzhno-Sakhalinsk in zone RU10 along with Magadan
+# until February 1997, and then in RU9 with Khabarovsk and Vladivostok
+# since September 1997....  Although the Kuril Islands are
+# administratively part of Sakhalin oblast', they appear to have
+# remained on UTC+11 along with Magadan.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Kaliningradskaya oblast'.
+Zone Europe/Kaliningrad	 1:22:00 -	LMT	1893 Apr
+			 1:00	C-Eur	CE%sT	1945
+			 2:00	Poland	CE%sT	1946
+			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
+			 2:00	Russia	EE%sT	2011 Mar 27 2:00s
+			 3:00	-	FET # Further-eastern European Time
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Respublika Adygeya, Arkhangel'skaya oblast',
+# Belgorodskaya oblast', Bryanskaya oblast', Vladimirskaya oblast',
+# Vologodskaya oblast', Voronezhskaya oblast',
+# Respublika Dagestan, Ivanovskaya oblast', Respublika Ingushetiya,
+# Kabarbino-Balkarskaya Respublika, Respublika Kalmykiya,
+# Kalyzhskaya oblast', Respublika Karachaevo-Cherkessiya,
+# Respublika Kareliya, Respublika Komi,
+# Kostromskaya oblast', Krasnodarskij kraj, Kurskaya oblast',
+# Leningradskaya oblast', Lipetskaya oblast', Respublika Marij El,
+# Respublika Mordoviya, Moskva, Moskovskaya oblast',
+# Murmanskaya oblast', Nenetskij avtonomnyj okrug,
+# Nizhegorodskaya oblast', Novgorodskaya oblast', Orlovskaya oblast',
+# Penzenskaya oblast', Pskovskaya oblast', Rostovskaya oblast',
+# Ryazanskaya oblast', Sankt-Peterburg,
+# Respublika Severnaya Osetiya, Smolenskaya oblast',
+# Stavropol'skij kraj, Tambovskaya oblast', Respublika Tatarstan,
+# Tverskaya oblast', Tyl'skaya oblast', Ul'yanovskaya oblast',
+# Chechenskaya Respublika, Chuvashskaya oblast',
+# Yaroslavskaya oblast'
+Zone Europe/Moscow	 2:30:20 -	LMT	1880
+			 2:30	-	MMT	1916 Jul  3 # Moscow Mean Time
+			 2:30:48 Russia	%s	1919 Jul  1 2:00
+			 3:00	Russia	MSK/MSD	1922 Oct
+			 2:00	-	EET	1930 Jun 21
+			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
+			 2:00	Russia	EE%sT	1992 Jan 19 2:00s
+			 3:00	Russia	MSK/MSD	2011 Mar 27 2:00s
+			 4:00	-	MSK
+#
+# Astrakhanskaya oblast', Kirovskaya oblast', Saratovskaya oblast',
+# Volgogradskaya oblast'.  Shanks & Pottenger say Kirov is still at +0400
+# but Wikipedia (2006-05-09) says +0300.  Perhaps it switched after the
+# others?  But we have no data.
+Zone Europe/Volgograd	 2:57:40 -	LMT	1920 Jan  3
+			 3:00	-	TSAT	1925 Apr  6 # Tsaritsyn Time
+			 3:00	-	STAT	1930 Jun 21 # Stalingrad Time
+			 4:00	-	STAT	1961 Nov 11
+			 4:00	Russia	VOL%sT	1989 Mar 26 2:00s # Volgograd T
+			 3:00	Russia	VOL%sT	1991 Mar 31 2:00s
+			 4:00	-	VOLT	1992 Mar 29 2:00s
+			 3:00	Russia	VOL%sT	2011 Mar 27 2:00s
+			 4:00	-	VOLT
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Samarskaya oblast', Udmyrtskaya respublika
+Zone Europe/Samara	 3:20:36 -	LMT	1919 Jul  1 2:00
+			 3:00	-	SAMT	1930 Jun 21
+			 4:00	-	SAMT	1935 Jan 27
+			 4:00	Russia	KUY%sT	1989 Mar 26 2:00s # Kuybyshev
+			 3:00	Russia	KUY%sT	1991 Mar 31 2:00s
+			 2:00	Russia	KUY%sT	1991 Sep 29 2:00s
+			 3:00	-	KUYT	1991 Oct 20 3:00
+			 4:00	Russia	SAM%sT	2010 Mar 28 2:00s # Samara Time
+			 3:00	Russia	SAM%sT	2011 Mar 27 2:00s
+			 4:00	-	SAMT
+
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Respublika Bashkortostan, Komi-Permyatskij avtonomnyj okrug,
+# Kurganskaya oblast', Orenburgskaya oblast', Permskaya oblast',
+# Sverdlovskaya oblast', Tyumenskaya oblast',
+# Khanty-Manskijskij avtonomnyj okrug, Chelyabinskaya oblast',
+# Yamalo-Nenetskij avtonomnyj okrug.
+Zone Asia/Yekaterinburg	 4:02:24 -	LMT	1919 Jul 15 4:00
+			 4:00	-	SVET	1930 Jun 21 # Sverdlovsk Time
+			 5:00	Russia	SVE%sT	1991 Mar 31 2:00s
+			 4:00	Russia	SVE%sT	1992 Jan 19 2:00s
+			 5:00	Russia	YEK%sT	2011 Mar 27 2:00s
+			 6:00	-	YEKT	# Yekaterinburg Time
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Respublika Altaj, Altajskij kraj, Omskaya oblast'.
+Zone Asia/Omsk		 4:53:36 -	LMT	1919 Nov 14
+			 5:00	-	OMST	1930 Jun 21 # Omsk TIme
+			 6:00	Russia	OMS%sT	1991 Mar 31 2:00s
+			 5:00	Russia	OMS%sT	1992 Jan 19 2:00s
+			 6:00	Russia	OMS%sT	2011 Mar 27 2:00s
+			 7:00	-	OMST
+#
+# From Paul Eggert (2006-08-19): I'm guessing about Tomsk here; it's
+# not clear when it switched from +7 to +6.
+# Novosibirskaya oblast', Tomskaya oblast'.
+Zone Asia/Novosibirsk	 5:31:40 -	LMT	1919 Dec 14 6:00
+			 6:00	-	NOVT	1930 Jun 21 # Novosibirsk Time
+			 7:00	Russia	NOV%sT	1991 Mar 31 2:00s
+			 6:00	Russia	NOV%sT	1992 Jan 19 2:00s
+			 7:00	Russia	NOV%sT	1993 May 23 # say Shanks & P.
+			 6:00	Russia	NOV%sT	2011 Mar 27 2:00s
+			 7:00	-	NOVT
+
+# From Alexander Krivenyshev (2009-10-13):
+# Kemerovo oblast' (Kemerovo region) in Russia will change current time zone on
+# March 28, 2010:
+# from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700
+# to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600
+#
+# This is according to Government of Russia decree # 740, on September
+# 14, 2009 "Application in the territory of the Kemerovo region the Fifth
+# time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600)
+#
+# Russian Government web site (Russian language)
+# <a href="http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archiv">
+# http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archive/2009/09/14/991633.htm
+# </a>
+# or Russian-English translation by WorldTimeZone.com with reference
+# map to local region and new Russia Time Zone map after March 28, 2010
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_russia03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_russia03.html
+# </a>
+#
+# Thus, when Russia will switch to DST on the night of March 28, 2010
+# Kemerovo region (Kemerovo oblast') will not change the clock.
+#
+# As a result, Kemerovo oblast' will be in the same time zone as
+# Novosibirsk, Omsk, Tomsk, Barnaul and Altai Republic.
+
+Zone Asia/Novokuznetsk	 5:48:48 -	NMT	1920 Jan  6
+			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
+			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
+			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
+			 7:00	Russia	KRA%sT	2010 Mar 28 2:00s
+			 6:00	Russia	NOV%sT	2011 Mar 27 2:00s
+			 7:00	-	NOVT # Novosibirsk/Novokuznetsk Time
+
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Krasnoyarskij kraj,
+# Tajmyrskij (Dolgano-Nenetskij) avtonomnyj okrug,
+# Respublika Tuva, Respublika Khakasiya, Evenkijskij avtonomnyj okrug.
+Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1920 Jan  6
+			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
+			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
+			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
+			 7:00	Russia	KRA%sT	2011 Mar 27 2:00s
+			 8:00	-	KRAT
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Respublika Buryatiya, Irkutskaya oblast',
+# Ust'-Ordynskij Buryatskij avtonomnyj okrug.
+Zone Asia/Irkutsk	 6:57:20 -	LMT	1880
+			 6:57:20 -	IMT	1920 Jan 25 # Irkutsk Mean Time
+			 7:00	-	IRKT	1930 Jun 21 # Irkutsk Time
+			 8:00	Russia	IRK%sT	1991 Mar 31 2:00s
+			 7:00	Russia	IRK%sT	1992 Jan 19 2:00s
+			 8:00	Russia	IRK%sT	2011 Mar 27 2:00s
+			 9:00	-	IRKT
+#
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
+# Aginskij Buryatskij avtonomnyj okrug, Amurskaya oblast',
+# [parts of] Respublika Sakha (Yakutiya), Chitinskaya oblast'.
+
+# From Oscar van Vlijmen (2009-11-29):
+# ...some regions of [Russia] were merged with others since 2005...
+# Some names were changed, no big deal, except for one instance: a new name.
+# YAK/YAKST: UTC+9 Zabajkal'skij kraj.
+
+# From Oscar van Vlijmen (2009-11-29):
+# The Sakha districts are: Aldanskij, Amginskij, Anabarskij,
+# Verkhnevilyujskij, Vilyujskij, Gornyj,
+# Zhiganskij, Kobyajskij, Lenskij, Megino-Kangalasskij, Mirninskij,
+# Namskij, Nyurbinskij, Olenyokskij, Olyokminskij,
+# Suntarskij, Tattinskij, Ust'-Aldanskij, Khangalasskij,
+# Churapchinskij, Eveno-Bytantajskij Natsional'nij.
+
+Zone Asia/Yakutsk	 8:38:40 -	LMT	1919 Dec 15
+			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
+			 9:00	Russia	YAK%sT	1991 Mar 31 2:00s
+			 8:00	Russia	YAK%sT	1992 Jan 19 2:00s
+			 9:00	Russia	YAK%sT	2011 Mar 27 2:00s
+			 10:00	-	YAKT
+#
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
+# Evrejskaya avtonomnaya oblast', Khabarovskij kraj, Primorskij kraj,
+# [parts of] Respublika Sakha (Yakutiya).
+
+# From Oscar van Vlijmen (2009-11-29):
+# The Sakha districts are: Bulunskij, Verkhoyanskij, Tomponskij, Ust'-Majskij,
+# Ust'-Yanskij.
+Zone Asia/Vladivostok	 8:47:44 -	LMT	1922 Nov 15
+			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
+			10:00	Russia	VLA%sT	1991 Mar 31 2:00s
+			 9:00	Russia	VLA%sST	1992 Jan 19 2:00s
+			10:00	Russia	VLA%sT	2011 Mar 27 2:00s
+			11:00	-	VLAT
+#
+# Sakhalinskaya oblast'.
+# The Zone name should be Yuzhno-Sakhalinsk, but that's too long.
+Zone Asia/Sakhalin	 9:30:48 -	LMT	1905 Aug 23
+			 9:00	-	CJT	1938
+			 9:00	-	JST	1945 Aug 25
+			11:00	Russia	SAK%sT	1991 Mar 31 2:00s # Sakhalin T.
+			10:00	Russia	SAK%sT	1992 Jan 19 2:00s
+			11:00	Russia	SAK%sT	1997 Mar lastSun 2:00s
+			10:00	Russia	SAK%sT	2011 Mar 27 2:00s
+			11:00	-	SAKT
+#
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
+# Magadanskaya oblast', Respublika Sakha (Yakutiya).
+# Probably also: Kuril Islands.
+
+# From Oscar van Vlijmen (2009-11-29):
+# The Sakha districts are: Abyjskij, Allaikhovskij, Verkhhhnekolymskij, Momskij,
+# Nizhnekolymskij, Ojmyakonskij, Srednekolymskij.
+Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
+			10:00	-	MAGT	1930 Jun 21 # Magadan Time
+			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
+			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
+			11:00	Russia	MAG%sT	2011 Mar 27 2:00s
+			12:00	-	MAGT
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Kamchatskaya oblast', Koryakskij avtonomnyj okrug.
+#
+# The Zone name should be Asia/Petropavlovsk-Kamchatski, but that's too long.
+Zone Asia/Kamchatka	10:34:36 -	LMT	1922 Nov 10
+			11:00	-	PETT	1930 Jun 21 # P-K Time
+			12:00	Russia	PET%sT	1991 Mar 31 2:00s
+			11:00	Russia	PET%sT	1992 Jan 19 2:00s
+			12:00	Russia	PET%sT	2010 Mar 28 2:00s
+			11:00	Russia	PET%sT	2011 Mar 27 2:00s
+			12:00	-	PETT
+#
+# Chukotskij avtonomnyj okrug
+Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
+			12:00	-	ANAT	1930 Jun 21 # Anadyr Time
+			13:00	Russia	ANA%sT	1982 Apr  1 0:00s
+			12:00	Russia	ANA%sT	1991 Mar 31 2:00s
+			11:00	Russia	ANA%sT	1992 Jan 19 2:00s
+			12:00	Russia	ANA%sT	2010 Mar 28 2:00s
+			11:00	Russia	ANA%sT	2011 Mar 27 2:00s
+			12:00	-	ANAT
+
+# Serbia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Belgrade	1:22:00	-	LMT	1884
+			1:00	-	CET	1941 Apr 18 23:00
+			1:00	C-Eur	CE%sT	1945
+			1:00	-	CET	1945 May 8 2:00s
+			1:00	1:00	CEST	1945 Sep 16  2:00s
+# Metod Kozelj reports that the legal date of
+# transition to EU rules was 1982-11-27, for all of Yugoslavia at the time.
+# Shanks & Pottenger don't give as much detail, so go with Kozelj.
+			1:00	-	CET	1982 Nov 27
+			1:00	EU	CE%sT
+Link Europe/Belgrade Europe/Ljubljana	# Slovenia
+Link Europe/Belgrade Europe/Podgorica	# Montenegro
+Link Europe/Belgrade Europe/Sarajevo	# Bosnia and Herzegovina
+Link Europe/Belgrade Europe/Skopje	# Macedonia
+Link Europe/Belgrade Europe/Zagreb	# Croatia
+
+# Slovakia
+Link Europe/Prague Europe/Bratislava
+
+# Slovenia
+# see Serbia
+
+# Spain
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# For 1917-1919 Whitman gives Apr Sat>=1 - Oct Sat>=1;
+# go with Shanks & Pottenger.
+Rule	Spain	1917	only	-	May	 5	23:00s	1:00	S
+Rule	Spain	1917	1919	-	Oct	 6	23:00s	0	-
+Rule	Spain	1918	only	-	Apr	15	23:00s	1:00	S
+Rule	Spain	1919	only	-	Apr	 5	23:00s	1:00	S
+# Whitman gives 1921 Feb 28 - Oct 14; go with Shanks & Pottenger.
+Rule	Spain	1924	only	-	Apr	16	23:00s	1:00	S
+# Whitman gives 1924 Oct 14; go with Shanks & Pottenger.
+Rule	Spain	1924	only	-	Oct	 4	23:00s	0	-
+Rule	Spain	1926	only	-	Apr	17	23:00s	1:00	S
+# Whitman says no DST in 1929; go with Shanks & Pottenger.
+Rule	Spain	1926	1929	-	Oct	Sat>=1	23:00s	0	-
+Rule	Spain	1927	only	-	Apr	 9	23:00s	1:00	S
+Rule	Spain	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	Spain	1929	only	-	Apr	20	23:00s	1:00	S
+# Whitman gives 1937 Jun 16, 1938 Apr 16, 1940 Apr 13;
+# go with Shanks & Pottenger.
+Rule	Spain	1937	only	-	May	22	23:00s	1:00	S
+Rule	Spain	1937	1939	-	Oct	Sat>=1	23:00s	0	-
+Rule	Spain	1938	only	-	Mar	22	23:00s	1:00	S
+Rule	Spain	1939	only	-	Apr	15	23:00s	1:00	S
+Rule	Spain	1940	only	-	Mar	16	23:00s	1:00	S
+# Whitman says no DST 1942-1945; go with Shanks & Pottenger.
+Rule	Spain	1942	only	-	May	 2	22:00s	2:00	M # Midsummer
+Rule	Spain	1942	only	-	Sep	 1	22:00s	1:00	S
+Rule	Spain	1943	1946	-	Apr	Sat>=13	22:00s	2:00	M
+Rule	Spain	1943	only	-	Oct	 3	22:00s	1:00	S
+Rule	Spain	1944	only	-	Oct	10	22:00s	1:00	S
+Rule	Spain	1945	only	-	Sep	30	 1:00	1:00	S
+Rule	Spain	1946	only	-	Sep	30	 0:00	0	-
+Rule	Spain	1949	only	-	Apr	30	23:00	1:00	S
+Rule	Spain	1949	only	-	Sep	30	 1:00	0	-
+Rule	Spain	1974	1975	-	Apr	Sat>=13	23:00	1:00	S
+Rule	Spain	1974	1975	-	Oct	Sun>=1	 1:00	0	-
+Rule	Spain	1976	only	-	Mar	27	23:00	1:00	S
+Rule	Spain	1976	1977	-	Sep	lastSun	 1:00	0	-
+Rule	Spain	1977	1978	-	Apr	 2	23:00	1:00	S
+Rule	Spain	1978	only	-	Oct	 1	 1:00	0	-
+# The following rules are copied from Morocco from 1967 through 1978.
+Rule SpainAfrica 1967	only	-	Jun	 3	12:00	1:00	S
+Rule SpainAfrica 1967	only	-	Oct	 1	 0:00	0	-
+Rule SpainAfrica 1974	only	-	Jun	24	 0:00	1:00	S
+Rule SpainAfrica 1974	only	-	Sep	 1	 0:00	0	-
+Rule SpainAfrica 1976	1977	-	May	 1	 0:00	1:00	S
+Rule SpainAfrica 1976	only	-	Aug	 1	 0:00	0	-
+Rule SpainAfrica 1977	only	-	Sep	28	 0:00	0	-
+Rule SpainAfrica 1978	only	-	Jun	 1	 0:00	1:00	S
+Rule SpainAfrica 1978	only	-	Aug	 4	 0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Madrid	-0:14:44 -	LMT	1901 Jan  1  0:00s
+			 0:00	Spain	WE%sT	1946 Sep 30
+			 1:00	Spain	CE%sT	1979
+			 1:00	EU	CE%sT
+Zone	Africa/Ceuta	-0:21:16 -	LMT	1901
+			 0:00	-	WET	1918 May  6 23:00
+			 0:00	1:00	WEST	1918 Oct  7 23:00
+			 0:00	-	WET	1924
+			 0:00	Spain	WE%sT	1929
+			 0:00 SpainAfrica WE%sT 1984 Mar 16
+			 1:00	-	CET	1986
+			 1:00	EU	CE%sT
+Zone	Atlantic/Canary	-1:01:36 -	LMT	1922 Mar # Las Palmas de Gran C.
+			-1:00	-	CANT	1946 Sep 30 1:00 # Canaries Time
+			 0:00	-	WET	1980 Apr  6 0:00s
+			 0:00	1:00	WEST	1980 Sep 28 0:00s
+			 0:00	EU	WE%sT
+# IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u.
+# Ignore this for now, as the Canaries are part of the EU.
+
+# Sweden
+
+# From Ivan Nilsson (2001-04-13), superseding Shanks & Pottenger:
+#
+# The law "Svensk forfattningssamling 1878, no 14" about standard time in 1879:
+# From the beginning of 1879 (that is 01-01 00:00) the time for all
+# places in the country is "the mean solar time for the meridian at
+# three degrees, or twelve minutes of time, to the west of the
+# meridian of the Observatory of Stockholm".  The law is dated 1878-05-31.
+#
+# The observatory at that time had the meridian 18 degrees 03' 30"
+# eastern longitude = 01:12:14 in time.  Less 12 minutes gives the
+# national standard time as 01:00:14 ahead of GMT....
+#
+# About the beginning of CET in Sweden. The lawtext ("Svensk
+# forfattningssamling 1899, no 44") states, that "from the beginning
+# of 1900... ... the same as the mean solar time for the meridian at
+# the distance of one hour of time from the meridian of the English
+# observatory at Greenwich, or at 12 minutes 14 seconds to the west
+# from the meridian of the Observatory of Stockholm". The law is dated
+# 1899-06-16.  In short: At 1900-01-01 00:00:00 the new standard time
+# in Sweden is 01:00:00 ahead of GMT.
+#
+# 1916: The lawtext ("Svensk forfattningssamling 1916, no 124") states
+# that "1916-05-15 is considered to begin one hour earlier". It is
+# pretty obvious that at 05-14 23:00 the clocks are set to 05-15 00:00....
+# Further the law says, that "1916-09-30 is considered to end one hour later".
+#
+# The laws regulating [DST] are available on the site of the Swedish
+# Parliament beginning with 1985 - the laws regulating 1980/1984 are
+# not available on the site (to my knowledge they are only available
+# in Swedish): <http://www.riksdagen.se/english/work/sfst.asp> (type
+# "sommartid" without the quotes in the field "Fritext" and then click
+# the Sok-button).
+#
+# (2001-05-13):
+#
+# I have now found a newspaper stating that at 1916-10-01 01:00
+# summertime the church-clocks etc were set back one hour to show
+# 1916-10-01 00:00 standard time.  The article also reports that some
+# people thought the switch to standard time would take place already
+# at 1916-10-01 00:00 summer time, but they had to wait for another
+# hour before the event took place.
+#
+# Source: The newspaper "Dagens Nyheter", 1916-10-01, page 7 upper left.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Stockholm	1:12:12 -	LMT	1879 Jan  1
+			1:00:14	-	SET	1900 Jan  1	# Swedish Time
+			1:00	-	CET	1916 May 14 23:00
+			1:00	1:00	CEST	1916 Oct  1 01:00
+			1:00	-	CET	1980
+			1:00	EU	CE%sT
+
+# Switzerland
+# From Howse:
+# By the end of the 18th century clocks and watches became commonplace
+# and their performance improved enormously.  Communities began to keep
+# mean time in preference to apparent time -- Geneva from 1780 ....
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# From Whitman (who writes ``Midnight?''):
+# Rule	Swiss	1940	only	-	Nov	 2	0:00	1:00	S
+# Rule	Swiss	1940	only	-	Dec	31	0:00	0	-
+# From Shanks & Pottenger:
+# Rule	Swiss	1941	1942	-	May	Sun>=1	2:00	1:00	S
+# Rule	Swiss	1941	1942	-	Oct	Sun>=1	0:00	0	-
+
+# From Alois Treindl (2008-12-17):
+# I have researched the DST usage in Switzerland during the 1940ies.
+#
+# As I wrote in an earlier message, I suspected the current tzdata values
+# to be wrong. This is now verified.
+#
+# I have found copies of the original ruling by the Swiss Federal
+# government, in 'Eidgen[o]ssische Gesetzessammlung 1941 and 1942' (Swiss
+# federal law collection)...
+#
+# DST began on Monday 5 May 1941, 1:00 am by shifting the clocks to 2:00 am
+# DST ended on Monday 6 Oct 1941, 2:00 am by shifting the clocks to 1:00 am.
+#
+# DST began on Monday, 4 May 1942 at 01:00 am
+# DST ended on Monday, 5 Oct 1942 at 02:00 am
+#
+# There was no DST in 1940, I have checked the law collection carefully.
+# It is also indicated by the fact that the 1942 entry in the law
+# collection points back to 1941 as a reference, but no reference to any
+# other years are made.
+#
+# Newspaper articles I have read in the archives on 6 May 1941 reported
+# about the introduction of DST (Sommerzeit in German) during the previous
+# night as an absolute novelty, because this was the first time that such
+# a thing had happened in Switzerland.
+#
+# I have also checked 1916, because one book source (Gabriel, Traite de
+# l'heure dans le monde) claims that Switzerland had DST in 1916. This is
+# false, no official document could be found. Probably Gabriel got misled
+# by references to Germany, which introduced DST in 1916 for the first time.
+#
+# The tzdata rules for Switzerland must be changed to:
+# Rule  Swiss   1941    1942    -       May     Mon>=1  1:00    1:00    S
+# Rule  Swiss   1941    1942    -       Oct     Mon>=1  2:00    0       -
+#
+# The 1940 rules must be deleted.
+#
+# One further detail for Switzerland, which is probably out of scope for
+# most users of tzdata:
+# The zone file
+# Zone    Europe/Zurich   0:34:08 -       LMT     1848 Sep 12
+#                          0:29:44 -       BMT     1894 Jun #Bern Mean Time
+#                          1:00    Swiss   CE%sT   1981
+#                          1:00    EU      CE%sT
+# describes all of Switzerland correctly, with the exception of
+# the Cantone Geneve (Geneva, Genf). Between 1848 and 1894 Geneve did not
+# follow Bern Mean Time but kept its own local mean time.
+# To represent this, an extra zone would be needed.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Swiss	1941	1942	-	May	Mon>=1	1:00	1:00	S
+Rule	Swiss	1941	1942	-	Oct	Mon>=1	2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Zurich	0:34:08 -	LMT	1848 Sep 12
+			0:29:44	-	BMT	1894 Jun # Bern Mean Time
+			1:00	Swiss	CE%sT	1981
+			1:00	EU	CE%sT
+
+# Turkey
+
+# From Amar Devegowda (2007-01-03):
+# The time zone rules for Istanbul, Turkey have not been changed for years now.
+# ... The latest rules are available at -
+# http://www.timeanddate.com/worldclock/timezone.html?n=107
+# From Steffen Thorsen (2007-01-03):
+# I have been able to find press records back to 1996 which all say that
+# DST started 01:00 local time and end at 02:00 local time.  I am not sure
+# what happened before that.  One example for each year from 1996 to 2001:
+# http://newspot.byegm.gov.tr/arsiv/1996/21/N4.htm
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING97/03/97X03X25.TXT
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING98/03/98X03X02.HTM
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING99/10/99X10X26.HTM#%2016
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2000/03/00X03X06.HTM#%2021
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2001/03/23x03x01.HTM#%2027
+# From Paul Eggert (2007-01-03):
+# Prefer the above source to Shanks & Pottenger for time stamps after 1990.
+
+# From Steffen Thorsen (2007-03-09):
+# Starting 2007 though, it seems that they are adopting EU's 1:00 UTC
+# start/end time, according to the following page (2007-03-07):
+# http://www.ntvmsnbc.com/news/402029.asp
+# The official document is located here - it is in Turkish...:
+# http://rega.basbakanlik.gov.tr/eskiler/2007/03/20070307-7.htm
+# I was able to locate the following seemingly official document
+# (on a non-government server though) describing dates between 2002 and 2006:
+# http://www.alomaliye.com/bkk_2002_3769.htm
+
+# From G&ouml;kdeniz Karada&#x011f; (2011-03-10):
+#
+# According to the articles linked below, Turkey will change into summer
+# time zone (GMT+3) on March 28, 2011 at 3:00 a.m. instead of March 27.
+# This change is due to a nationwide exam on 27th.
+#
+# <a href="http://www.worldbulletin.net/?aType=haber&ArticleID=70872">
+# http://www.worldbulletin.net/?aType=haber&ArticleID=70872
+# </a>
+# Turkish:
+# <a href="http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373">
+# http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Turkey	1916	only	-	May	 1	0:00	1:00	S
+Rule	Turkey	1916	only	-	Oct	 1	0:00	0	-
+Rule	Turkey	1920	only	-	Mar	28	0:00	1:00	S
+Rule	Turkey	1920	only	-	Oct	25	0:00	0	-
+Rule	Turkey	1921	only	-	Apr	 3	0:00	1:00	S
+Rule	Turkey	1921	only	-	Oct	 3	0:00	0	-
+Rule	Turkey	1922	only	-	Mar	26	0:00	1:00	S
+Rule	Turkey	1922	only	-	Oct	 8	0:00	0	-
+# Whitman gives 1923 Apr 28 - Sep 16 and no DST in 1924-1925;
+# go with Shanks & Pottenger.
+Rule	Turkey	1924	only	-	May	13	0:00	1:00	S
+Rule	Turkey	1924	1925	-	Oct	 1	0:00	0	-
+Rule	Turkey	1925	only	-	May	 1	0:00	1:00	S
+Rule	Turkey	1940	only	-	Jun	30	0:00	1:00	S
+Rule	Turkey	1940	only	-	Oct	 5	0:00	0	-
+Rule	Turkey	1940	only	-	Dec	 1	0:00	1:00	S
+Rule	Turkey	1941	only	-	Sep	21	0:00	0	-
+Rule	Turkey	1942	only	-	Apr	 1	0:00	1:00	S
+# Whitman omits the next two transition and gives 1945 Oct 1;
+# go with Shanks & Pottenger.
+Rule	Turkey	1942	only	-	Nov	 1	0:00	0	-
+Rule	Turkey	1945	only	-	Apr	 2	0:00	1:00	S
+Rule	Turkey	1945	only	-	Oct	 8	0:00	0	-
+Rule	Turkey	1946	only	-	Jun	 1	0:00	1:00	S
+Rule	Turkey	1946	only	-	Oct	 1	0:00	0	-
+Rule	Turkey	1947	1948	-	Apr	Sun>=16	0:00	1:00	S
+Rule	Turkey	1947	1950	-	Oct	Sun>=2	0:00	0	-
+Rule	Turkey	1949	only	-	Apr	10	0:00	1:00	S
+Rule	Turkey	1950	only	-	Apr	19	0:00	1:00	S
+Rule	Turkey	1951	only	-	Apr	22	0:00	1:00	S
+Rule	Turkey	1951	only	-	Oct	 8	0:00	0	-
+Rule	Turkey	1962	only	-	Jul	15	0:00	1:00	S
+Rule	Turkey	1962	only	-	Oct	 8	0:00	0	-
+Rule	Turkey	1964	only	-	May	15	0:00	1:00	S
+Rule	Turkey	1964	only	-	Oct	 1	0:00	0	-
+Rule	Turkey	1970	1972	-	May	Sun>=2	0:00	1:00	S
+Rule	Turkey	1970	1972	-	Oct	Sun>=2	0:00	0	-
+Rule	Turkey	1973	only	-	Jun	 3	1:00	1:00	S
+Rule	Turkey	1973	only	-	Nov	 4	3:00	0	-
+Rule	Turkey	1974	only	-	Mar	31	2:00	1:00	S
+Rule	Turkey	1974	only	-	Nov	 3	5:00	0	-
+Rule	Turkey	1975	only	-	Mar	30	0:00	1:00	S
+Rule	Turkey	1975	1976	-	Oct	lastSun	0:00	0	-
+Rule	Turkey	1976	only	-	Jun	 1	0:00	1:00	S
+Rule	Turkey	1977	1978	-	Apr	Sun>=1	0:00	1:00	S
+Rule	Turkey	1977	only	-	Oct	16	0:00	0	-
+Rule	Turkey	1979	1980	-	Apr	Sun>=1	3:00	1:00	S
+Rule	Turkey	1979	1982	-	Oct	Mon>=11	0:00	0	-
+Rule	Turkey	1981	1982	-	Mar	lastSun	3:00	1:00	S
+Rule	Turkey	1983	only	-	Jul	31	0:00	1:00	S
+Rule	Turkey	1983	only	-	Oct	 2	0:00	0	-
+Rule	Turkey	1985	only	-	Apr	20	0:00	1:00	S
+Rule	Turkey	1985	only	-	Sep	28	0:00	0	-
+Rule	Turkey	1986	1990	-	Mar	lastSun	2:00s	1:00	S
+Rule	Turkey	1986	1990	-	Sep	lastSun	2:00s	0	-
+Rule	Turkey	1991	2006	-	Mar	lastSun	1:00s	1:00	S
+Rule	Turkey	1991	1995	-	Sep	lastSun	1:00s	0	-
+Rule	Turkey	1996	2006	-	Oct	lastSun	1:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Istanbul	1:55:52 -	LMT	1880
+			1:56:56	-	IMT	1910 Oct # Istanbul Mean Time?
+			2:00	Turkey	EE%sT	1978 Oct 15
+			3:00	Turkey	TR%sT	1985 Apr 20 # Turkey Time
+			2:00	Turkey	EE%sT	2007
+			2:00	EU	EE%sT	2011 Mar 27 1:00u
+			2:00	-	EET	2011 Mar 28 1:00u
+			2:00	EU	EE%sT
+Link	Europe/Istanbul	Asia/Istanbul	# Istanbul is in both continents.
+
+# Ukraine
+#
+# From Igor Karpov, who works for the Ukranian Ministry of Justice,
+# via Garrett Wollman (2003-01-27):
+# BTW, I've found the official document on this matter. It's goverment
+# regulations number 509, May 13, 1996. In my poor translation it says:
+# "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday
+# of March at 3am the time is changing to 4am and each last Sunday of
+# October the time at 4am is changing to 3am"
+
+# From Alexander Krivenyshev (2011-09-20):
+# On September 20, 2011 the deputies of the Verkhovna Rada agreed to
+# abolish the transfer clock to winter time.
+#
+# Bill number 8330 of MP from the Party of Regions Oleg Nadoshi got
+# approval from 266 deputies.
+#
+# Ukraine abolishes transter back to the winter time (in Russian)
+# <a href="http://news.mail.ru/politics/6861560/">
+# http://news.mail.ru/politics/6861560/
+# </a>
+#
+# The Ukrainians will no longer change the clock (in Russian)
+# <a href="http://www.segodnya.ua/news/14290482.html">
+# http://www.segodnya.ua/news/14290482.html
+# </a>
+#
+# Deputies cancelled the winter time (in Russian)
+# <a href="http://www.pravda.com.ua/rus/news/2011/09/20/6600616/">
+# http://www.pravda.com.ua/rus/news/2011/09/20/6600616/
+# </a>
+#
+# From Philip Pizzey (2011-10-18):
+# Today my Ukrainian colleagues have informed me that the
+# Ukrainian parliament have decided that they will go to winter
+# time this year after all.
+#
+# From Udo Schwedt (2011-10-18):
+# As far as I understand, the recent change to the Ukranian time zone
+# (Europe/Kiev) to introduce permanent daylight saving time (similar
+# to Russia) was reverted today:
+#
+# <a href="http://portal.rada.gov.ua/rada/control/en/publish/article/info_left?art_id=287324&cat_id=105995">
+# http://portal.rada.gov.ua/rada/control/en/publish/article/info_left?art_id=287324&cat_id=105995
+# </a>
+#
+# Also reported by Alexander Bokovoy (2011-10-18) who also noted:
+# The law documents themselves are at
+#
+# <a href="http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484">
+# http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484
+# </a>
+
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Most of Ukraine since 1970 has been like Kiev.
+# "Kyiv" is the transliteration of the Ukrainian name, but
+# "Kiev" is more common in English.
+Zone Europe/Kiev	2:02:04 -	LMT	1880
+			2:02:04	-	KMT	1924 May  2 # Kiev Mean Time
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Sep 20
+			1:00	C-Eur	CE%sT	1943 Nov  6
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			2:00	-	EET	1992
+			2:00	E-Eur	EE%sT	1995
+			2:00	EU	EE%sT
+# Ruthenia used CET 1990/1991.
+# "Uzhhorod" is the transliteration of the Ukrainian name, but
+# "Uzhgorod" is more common in English.
+Zone Europe/Uzhgorod	1:29:12 -	LMT	1890 Oct
+			1:00	-	CET	1940
+			1:00	C-Eur	CE%sT	1944 Oct
+			1:00	1:00	CEST	1944 Oct 26
+			1:00	-	CET	1945 Jun 29
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			1:00	-	CET	1991 Mar 31 3:00
+			2:00	-	EET	1992
+			2:00	E-Eur	EE%sT	1995
+			2:00	EU	EE%sT
+# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
+# "Zaporizhia" is the transliteration of the Ukrainian name, but
+# "Zaporozh'ye" is more common in English.  Use the common English
+# spelling, except omit the apostrophe as it is not allowed in
+# portable Posix file names.
+Zone Europe/Zaporozhye	2:20:40 -	LMT	1880
+			2:20	-	CUT	1924 May  2 # Central Ukraine T
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Aug 25
+			1:00	C-Eur	CE%sT	1943 Oct 25
+			3:00	Russia	MSK/MSD	1991 Mar 31 2:00
+			2:00	E-Eur	EE%sT	1995
+			2:00	EU	EE%sT
+# Central Crimea used Moscow time 1994/1997.
+Zone Europe/Simferopol	2:16:24 -	LMT	1880
+			2:16	-	SMT	1924 May  2 # Simferopol Mean T
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Nov
+			1:00	C-Eur	CE%sT	1944 Apr 13
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			2:00	-	EET	1992
+# From Paul Eggert (2006-03-22):
+# The _Economist_ (1994-05-28, p 45) reports that central Crimea switched
+# from Kiev to Moscow time sometime after the January 1994 elections.
+# Shanks (1999) says ``date of change uncertain'', but implies that it happened
+# sometime between the 1994 DST switches.  Shanks & Pottenger simply say
+# 1994-09-25 03:00, but that can't be right.  For now, guess it
+# changed in May.
+			2:00	E-Eur	EE%sT	1994 May
+# From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev.
+			3:00	E-Eur	MSK/MSD	1996 Mar 31 3:00s
+			3:00	1:00	MSD	1996 Oct 27 3:00s
+# IATA SSIM (1997-09) says Crimea switched to EET/EEST.
+# Assume it happened in March by not changing the clocks.
+			3:00	Russia	MSK/MSD	1997
+			3:00	-	MSK	1997 Mar lastSun 1:00u
+			2:00	EU	EE%sT
+
+###############################################################################
+
+# One source shows that Bulgaria, Cyprus, Finland, and Greece observe DST from
+# the last Sunday in March to the last Sunday in September in 1986.
+# The source shows Romania changing a day later than everybody else.
+#
+# According to Bernard Sieloff's source, Poland is in the MET time zone but
+# uses the WE DST rules.  The Western USSR uses EET+1 and ME DST rules.
+# Bernard Sieloff's source claims Romania switches on the same day, but at
+# 00:00 standard time (i.e., 01:00 DST).  It also claims that Turkey
+# switches on the same day, but switches on at 01:00 standard time
+# and off at 00:00 standard time (i.e., 01:00 DST)
+
+# ...
+# Date: Wed, 28 Jan 87 16:56:27 -0100
+# From: Tom Hofmann
+# ...
+#
+# ...the European time rules are...standardized since 1981, when
+# most European coun[tr]ies started DST.  Before that year, only
+# a few countries (UK, France, Italy) had DST, each according
+# to own national rules.  In 1981, however, DST started on
+# 'Apr firstSun', and not on 'Mar lastSun' as in the following
+# years...
+# But also since 1981 there are some more national exceptions
+# than listed in 'europe': Switzerland, for example, joined DST
+# one year later, Denmark ended DST on 'Oct 1' instead of 'Sep
+# lastSun' in 1981---I don't know how they handle now.
+#
+# Finally, DST ist always from 'Apr 1' to 'Oct 1' in the
+# Soviet Union (as far as I know).
+#
+# Tom Hofmann, Scientific Computer Center, CIBA-GEIGY AG,
+# 4002 Basle, Switzerland
+# ...
+
+# ...
+# Date: Wed, 4 Feb 87 22:35:22 +0100
+# From: Dik T. Winter
+# ...
+#
+# The information from Tom Hofmann is (as far as I know) not entirely correct.
+# After a request from chongo at amdahl I tried to retrieve all information
+# about DST in Europe.  I was able to find all from about 1969.
+#
+# ...standardization on DST in Europe started in about 1977 with switches on
+# first Sunday in April and last Sunday in September...
+# In 1981 UK joined Europe insofar that
+# the starting day for both shifted to last Sunday in March.  And from 1982
+# the whole of Europe used DST, with switch dates April 1 and October 1 in
+# the Sov[i]et Union.  In 1985 the SU reverted to standard Europe[a]n switch
+# dates...
+#
+# It should also be remembered that time-zones are not constants; e.g.
+# Portugal switched in 1976 from MET (or CET) to WET with DST...
+# Note also that though there were rules for switch dates not
+# all countries abided to these dates, and many individual deviations
+# occurred, though not since 1982 I believe.  Another note: it is always
+# assumed that DST is 1 hour ahead of normal time, this need not be the
+# case; at least in the Netherlands there have been times when DST was 2 hours
+# in advance of normal time.
+#
+# ...
+# dik t. winter, cwi, amsterdam, nederland
+# ...
+
+# From Bob Devine (1988-01-28):
+# ...
+# Greece: Last Sunday in April to last Sunday in September (iffy on dates).
+# Since 1978.  Change at midnight.
+# ...
+# Monaco: has same DST as France.
+# ...
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/factory b/jdk/test/sun/util/calendar/zi/tzdata/factory
new file mode 100644
index 0000000..53ca3aa
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/factory
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# For companies who don't want to put time zone specification in
+# their installation procedures.  When users run date, they'll get the message.
+# Also useful for the "comp.sources" version.
+
+# Zone	NAME	GMTOFF	RULES	FORMAT
+Zone	Factory	0	- "Local time zone must be set--see zic manual page"
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/gmt b/jdk/test/sun/util/calendar/zi/tzdata/gmt
new file mode 100644
index 0000000..0be3179
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/gmt
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2000, 2005, 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.
+#
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	GMT		0:00	-	GMT
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/iso3166.tab b/jdk/test/sun/util/calendar/zi/tzdata/iso3166.tab
new file mode 100644
index 0000000..fee3f33
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/iso3166.tab
@@ -0,0 +1,299 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+# ISO 3166 alpha-2 country codes
+#
+# From Paul Eggert (2006-09-27):
+#
+# This file contains a table with the following columns:
+# 1.  ISO 3166-1 alpha-2 country code, current as of
+#     ISO 3166-1 Newsletter VI-1 (2007-09-21).  See:
+#     <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html">
+#     ISO 3166 Maintenance agency (ISO 3166/MA)
+#     </a>.
+# 2.  The usual English name for the country,
+#     chosen so that alphabetic sorting of subsets produces helpful lists.
+#     This is not the same as the English name in the ISO 3166 tables.
+#
+# Columns are separated by a single tab.
+# The table is sorted by country code.
+#
+# Lines beginning with `#' are comments.
+#
+# From Arthur David Olson (2011-08-17):
+# Resynchronized today with the ISO 3166 site (adding SS for South Sudan).
+#
+#country-
+#code	country name
+AD	Andorra
+AE	United Arab Emirates
+AF	Afghanistan
+AG	Antigua & Barbuda
+AI	Anguilla
+AL	Albania
+AM	Armenia
+AO	Angola
+AQ	Antarctica
+AR	Argentina
+AS	Samoa (American)
+AT	Austria
+AU	Australia
+AW	Aruba
+AX	Aaland Islands
+AZ	Azerbaijan
+BA	Bosnia & Herzegovina
+BB	Barbados
+BD	Bangladesh
+BE	Belgium
+BF	Burkina Faso
+BG	Bulgaria
+BH	Bahrain
+BI	Burundi
+BJ	Benin
+BL	St Barthelemy
+BM	Bermuda
+BN	Brunei
+BO	Bolivia
+BQ	Bonaire Sint Eustatius & Saba
+BR	Brazil
+BS	Bahamas
+BT	Bhutan
+BV	Bouvet Island
+BW	Botswana
+BY	Belarus
+BZ	Belize
+CA	Canada
+CC	Cocos (Keeling) Islands
+CD	Congo (Dem. Rep.)
+CF	Central African Rep.
+CG	Congo (Rep.)
+CH	Switzerland
+CI	Cote d'Ivoire
+CK	Cook Islands
+CL	Chile
+CM	Cameroon
+CN	China
+CO	Colombia
+CR	Costa Rica
+CU	Cuba
+CV	Cape Verde
+CW	Curacao
+CX	Christmas Island
+CY	Cyprus
+CZ	Czech Republic
+DE	Germany
+DJ	Djibouti
+DK	Denmark
+DM	Dominica
+DO	Dominican Republic
+DZ	Algeria
+EC	Ecuador
+EE	Estonia
+EG	Egypt
+EH	Western Sahara
+ER	Eritrea
+ES	Spain
+ET	Ethiopia
+FI	Finland
+FJ	Fiji
+FK	Falkland Islands
+FM	Micronesia
+FO	Faroe Islands
+FR	France
+GA	Gabon
+GB	Britain (UK)
+GD	Grenada
+GE	Georgia
+GF	French Guiana
+GG	Guernsey
+GH	Ghana
+GI	Gibraltar
+GL	Greenland
+GM	Gambia
+GN	Guinea
+GP	Guadeloupe
+GQ	Equatorial Guinea
+GR	Greece
+GS	South Georgia & the South Sandwich Islands
+GT	Guatemala
+GU	Guam
+GW	Guinea-Bissau
+GY	Guyana
+HK	Hong Kong
+HM	Heard Island & McDonald Islands
+HN	Honduras
+HR	Croatia
+HT	Haiti
+HU	Hungary
+ID	Indonesia
+IE	Ireland
+IL	Israel
+IM	Isle of Man
+IN	India
+IO	British Indian Ocean Territory
+IQ	Iraq
+IR	Iran
+IS	Iceland
+IT	Italy
+JE	Jersey
+JM	Jamaica
+JO	Jordan
+JP	Japan
+KE	Kenya
+KG	Kyrgyzstan
+KH	Cambodia
+KI	Kiribati
+KM	Comoros
+KN	St Kitts & Nevis
+KP	Korea (North)
+KR	Korea (South)
+KW	Kuwait
+KY	Cayman Islands
+KZ	Kazakhstan
+LA	Laos
+LB	Lebanon
+LC	St Lucia
+LI	Liechtenstein
+LK	Sri Lanka
+LR	Liberia
+LS	Lesotho
+LT	Lithuania
+LU	Luxembourg
+LV	Latvia
+LY	Libya
+MA	Morocco
+MC	Monaco
+MD	Moldova
+ME	Montenegro
+MF	St Martin (French part)
+MG	Madagascar
+MH	Marshall Islands
+MK	Macedonia
+ML	Mali
+MM	Myanmar (Burma)
+MN	Mongolia
+MO	Macau
+MP	Northern Mariana Islands
+MQ	Martinique
+MR	Mauritania
+MS	Montserrat
+MT	Malta
+MU	Mauritius
+MV	Maldives
+MW	Malawi
+MX	Mexico
+MY	Malaysia
+MZ	Mozambique
+NA	Namibia
+NC	New Caledonia
+NE	Niger
+NF	Norfolk Island
+NG	Nigeria
+NI	Nicaragua
+NL	Netherlands
+NO	Norway
+NP	Nepal
+NR	Nauru
+NU	Niue
+NZ	New Zealand
+OM	Oman
+PA	Panama
+PE	Peru
+PF	French Polynesia
+PG	Papua New Guinea
+PH	Philippines
+PK	Pakistan
+PL	Poland
+PM	St Pierre & Miquelon
+PN	Pitcairn
+PR	Puerto Rico
+PS	Palestine
+PT	Portugal
+PW	Palau
+PY	Paraguay
+QA	Qatar
+RE	Reunion
+RO	Romania
+RS	Serbia
+RU	Russia
+RW	Rwanda
+SA	Saudi Arabia
+SB	Solomon Islands
+SC	Seychelles
+SD	Sudan
+SE	Sweden
+SG	Singapore
+SH	St Helena
+SI	Slovenia
+SJ	Svalbard & Jan Mayen
+SK	Slovakia
+SL	Sierra Leone
+SM	San Marino
+SN	Senegal
+SO	Somalia
+SR	Suriname
+SS	South Sudan
+ST	Sao Tome & Principe
+SV	El Salvador
+SX	Sint Maarten
+SY	Syria
+SZ	Swaziland
+TC	Turks & Caicos Is
+TD	Chad
+TF	French Southern & Antarctic Lands
+TG	Togo
+TH	Thailand
+TJ	Tajikistan
+TK	Tokelau
+TL	East Timor
+TM	Turkmenistan
+TN	Tunisia
+TO	Tonga
+TR	Turkey
+TT	Trinidad & Tobago
+TV	Tuvalu
+TW	Taiwan
+TZ	Tanzania
+UA	Ukraine
+UG	Uganda
+UM	US minor outlying islands
+US	United States
+UY	Uruguay
+UZ	Uzbekistan
+VA	Vatican City
+VC	St Vincent
+VE	Venezuela
+VG	Virgin Islands (UK)
+VI	Virgin Islands (US)
+VN	Vietnam
+VU	Vanuatu
+WF	Wallis & Futuna
+WS	Samoa (western)
+YE	Yemen
+YT	Mayotte
+ZA	South Africa
+ZM	Zambia
+ZW	Zimbabwe
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/jdk11_backward b/jdk/test/sun/util/calendar/zi/tzdata/jdk11_backward
new file mode 100644
index 0000000..5404cea
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/jdk11_backward
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2000, 2006, 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.
+#
+# JDK 1.1.x compatible time zone IDs
+#
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
+Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
+Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
+Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
+Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
+Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
+Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
+Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
+Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
+Zone	SystemV/AST4	-4:00	-		AST
+Zone	SystemV/EST5	-5:00	-		EST
+Zone	SystemV/CST6	-6:00	-		CST
+Zone	SystemV/MST7	-7:00	-		MST
+Zone	SystemV/PST8	-8:00	-		PST
+Zone	SystemV/YST9	-9:00	-		YST
+Zone	SystemV/HST10	-10:00	-		HST
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/leapseconds b/jdk/test/sun/util/calendar/zi/tzdata/leapseconds
new file mode 100644
index 0000000..ab6720d
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/leapseconds
@@ -0,0 +1,123 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# Allowance for leapseconds added to each timezone file.
+
+# The International Earth Rotation Service periodically uses leap seconds
+# to keep UTC to within 0.9 s of UT1
+# (which measures the true angular orientation of the earth in space); see
+# Terry J Quinn, The BIPM and the accurate measure of time,
+# Proc IEEE 79, 7 (July 1991), 894-905.
+# There were no leap seconds before 1972, because the official mechanism
+# accounting for the discrepancy between atomic time and the earth's rotation
+# did not exist until the early 1970s.
+
+# The correction (+ or -) is made at the given time, so lines
+# will typically look like:
+#	Leap	YEAR	MON	DAY	23:59:60	+	R/S
+# or
+#	Leap	YEAR	MON	DAY	23:59:59	-	R/S
+
+# If the leapsecond is Rolling (R) the given time is local time
+# If the leapsecond is Stationary (S) the given time is UTC
+
+# Leap	YEAR	MONTH	DAY	HH:MM:SS	CORR	R/S
+Leap	1972	Jun	30	23:59:60	+	S
+Leap	1972	Dec	31	23:59:60	+	S
+Leap	1973	Dec	31	23:59:60	+	S
+Leap	1974	Dec	31	23:59:60	+	S
+Leap	1975	Dec	31	23:59:60	+	S
+Leap	1976	Dec	31	23:59:60	+	S
+Leap	1977	Dec	31	23:59:60	+	S
+Leap	1978	Dec	31	23:59:60	+	S
+Leap	1979	Dec	31	23:59:60	+	S
+Leap	1981	Jun	30	23:59:60	+	S
+Leap	1982	Jun	30	23:59:60	+	S
+Leap	1983	Jun	30	23:59:60	+	S
+Leap	1985	Jun	30	23:59:60	+	S
+Leap	1987	Dec	31	23:59:60	+	S
+Leap	1989	Dec	31	23:59:60	+	S
+Leap	1990	Dec	31	23:59:60	+	S
+Leap	1992	Jun	30	23:59:60	+	S
+Leap	1993	Jun	30	23:59:60	+	S
+Leap	1994	Jun	30	23:59:60	+	S
+Leap	1995	Dec	31	23:59:60	+	S
+Leap	1997	Jun	30	23:59:60	+	S
+Leap	1998	Dec	31	23:59:60	+	S
+Leap	2005	Dec	31	23:59:60	+	S
+Leap	2008	Dec	31	23:59:60	+	S
+Leap	2012	Jun	30	23:59:60	+	S
+
+# INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE (IERS)
+#
+# SERVICE INTERNATIONAL DE LA ROTATION TERRESTRE ET DES SYSTEMES DE REFERENCE
+#
+#
+# SERVICE DE LA ROTATION TERRESTRE
+# OBSERVATOIRE DE PARIS
+# 61, Av. de l'Observatoire 75014 PARIS (France)
+# Tel.      : 33 (0) 1 40 51 22 26
+# FAX       : 33 (0) 1 40 51 22 91
+# e-mail    : (E-Mail Removed)
+# http://hpiers.obspm.fr/eop-pc
+#
+# Paris, 5 January 2012
+#
+#
+# Bulletin C 43
+#
+# To authorities responsible
+# for the measurement and
+# distribution of time
+#
+#
+# UTC TIME STEP
+# on the 1st of July 2012
+#
+#
+# A positive leap second will be introduced at the end of June 2012.
+# The sequence of dates of the UTC second markers will be:
+#
+#                          2012 June 30,     23h 59m 59s
+#                          2012 June 30,     23h 59m 60s
+#                          2012 July  1,      0h  0m  0s
+#
+# The difference between UTC and the International Atomic Time TAI is:
+#
+# from 2009 January 1, 0h UTC, to 2012 July 1  0h UTC  : UTC-TAI = - 34s
+# from 2012 July 1,    0h UTC, until further notice    : UTC-TAI = - 35s
+#
+# Leap seconds can be introduced in UTC at the end of the months of December
+# or June, depending on the evolution of UT1-TAI. Bulletin C is mailed every
+# six months, either to announce a time step in UTC or to confirm that there
+# will be no time step at the next possible date.
+#
+#
+# Daniel GAMBIS
+# Head
+# Earth Orientation Center of IERS
+# Observatoire de Paris, France
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/northamerica b/jdk/test/sun/util/calendar/zi/tzdata/northamerica
new file mode 100644
index 0000000..c303326
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/northamerica
@@ -0,0 +1,3258 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# also includes Central America and the Caribbean
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (1999-03-22):
+# A reliable and entertaining source about time zones is
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+
+###############################################################################
+
+# United States
+
+# From Paul Eggert (1999-03-31):
+# Howse writes (pp 121-125) that time zones were invented by
+# Professor Charles Ferdinand Dowd (1825-1904),
+# Principal of Temple Grove Ladies' Seminary (Saratoga Springs, NY).
+# His pamphlet ``A System of National Time for Railroads'' (1870)
+# was the result of his proposals at the Convention of Railroad Trunk Lines
+# in New York City (1869-10).  His 1870 proposal was based on Washington, DC,
+# but in 1872-05 he moved the proposed origin to Greenwich.
+# His proposal was adopted by the railroads on 1883-11-18 at 12:00,
+# and the most of the country soon followed suit.
+
+# From Paul Eggert (2005-04-16):
+# That 1883 transition occurred at 12:00 new time, not at 12:00 old time.
+# See p 46 of David Prerau, Seize the daylight, Thunder's Mouth Press (2005).
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data in the US is
+# Thomas G. Shanks, The American Atlas (5th edition),
+# San Diego: ACS Publications, Inc. (1991).
+# Make sure you have the errata sheet; the book is somewhat useless without it.
+# It is the source for most of the pre-1991 US entries below.
+
+# From Paul Eggert (2001-03-06):
+# Daylight Saving Time was first suggested as a joke by Benjamin Franklin
+# in his whimsical essay ``An Economical Project for Diminishing the Cost
+# of Light'' published in the Journal de Paris (1784-04-26).
+# Not everyone is happy with the results:
+#
+#	I don't really care how time is reckoned so long as there is some
+#	agreement about it, but I object to being told that I am saving
+#	daylight when my reason tells me that I am doing nothing of the kind.
+#	I even object to the implication that I am wasting something
+#	valuable if I stay in bed after the sun has risen.  As an admirer
+#	of moonlight I resent the bossy insistence of those who want to
+#	reduce my time for enjoying it.  At the back of the Daylight Saving
+#	scheme I detect the bony, blue-fingered hand of Puritanism, eager
+#	to push people into bed earlier, and get them up earlier, to make
+#	them healthy, wealthy and wise in spite of themselves.
+#
+#	-- Robertson Davies, The diary of Samuel Marchbanks,
+#	   Clarke, Irwin (1947), XIX, Sunday
+#
+# For more about the first ten years of DST in the United States, see
+# Robert Garland's <a href="http://www.clpgh.org/exhibit/dst.html">
+# Ten years of daylight saving from the Pittsburgh standpoint
+# (Carnegie Library of Pittsburgh, 1927)</a>.
+#
+# Shanks says that DST was called "War Time" in the US in 1918 and 1919.
+# However, DST was imposed by the Standard Time Act of 1918, which
+# was the first nationwide legal time standard, and apparently
+# time was just called "Standard Time" or "Daylight Saving Time".
+
+# From Arthur David Olson:
+# US Daylight Saving Time ended on the last Sunday of *October* in 1974.
+# See, for example, the front page of the Saturday, 1974-10-26
+# and Sunday, 1974-10-27 editions of the Washington Post.
+
+# From Arthur David Olson:
+# Before the Uniform Time Act of 1966 took effect in 1967, observance of
+# Daylight Saving Time in the US was by local option, except during wartime.
+
+# From Arthur David Olson (2000-09-25):
+# Last night I heard part of a rebroadcast of a 1945 Arch Oboler radio drama.
+# In the introduction, Oboler spoke of "Eastern Peace Time."
+# An AltaVista search turned up
+# <a href="http://rowayton.org/rhs/hstaug45.html">:
+# "When the time is announced over the radio now, it is 'Eastern Peace
+# Time' instead of the old familiar 'Eastern War Time.'  Peace is wonderful."
+# </a> (August 1945) by way of confirmation.
+
+# From Joseph Gallant citing
+# George H. Douglas, _The Early Days of Radio Broadcasting_ (1987):
+# At 7 P.M. (Eastern War Time) [on 1945-08-14], the networks were set
+# to switch to London for Attlee's address, but the American people
+# never got to hear his speech live. According to one press account,
+# CBS' Bob Trout was first to announce the word of Japan's surrender,
+# but a few seconds later, NBC, ABC and Mutual also flashed the word
+# of surrender, all of whom interrupting the bells of Big Ben in
+# London which were to precede Mr. Attlee's speech.
+
+# From Paul Eggert (2003-02-09): It was Robert St John, not Bob Trout.  From
+# Myrna Oliver's obituary of St John on page B16 of today's Los Angeles Times:
+#
+# ... a war-weary U.S. clung to radios, awaiting word of Japan's surrender.
+# Any announcement from Asia would reach St. John's New York newsroom on a
+# wire service teletype machine, which had prescribed signals for major news.
+# Associated Press, for example, would ring five bells before spewing out
+# typed copy of an important story, and 10 bells for news "of transcendental
+# importance."
+#
+# On Aug. 14, stalling while talking steadily into the NBC networks' open
+# microphone, St. John heard five bells and waited only to hear a sixth bell,
+# before announcing confidently: "Ladies and gentlemen, World War II is over.
+# The Japanese have agreed to our surrender terms."
+#
+# He had scored a 20-second scoop on other broadcasters.
+
+# From Arthur David Olson (2005-08-22):
+# Paul has been careful to use the "US" rules only in those locations
+# that are part of the United States; this reflects the real scope of
+# U.S. government action.  So even though the "US" rules have changed
+# in the latest release, other countries won't be affected.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	US	1918	1919	-	Mar	lastSun	2:00	1:00	D
+Rule	US	1918	1919	-	Oct	lastSun	2:00	0	S
+Rule	US	1942	only	-	Feb	9	2:00	1:00	W # War
+Rule	US	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	US	1945	only	-	Sep	30	2:00	0	S
+Rule	US	1967	2006	-	Oct	lastSun	2:00	0	S
+Rule	US	1967	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	US	1974	only	-	Jan	6	2:00	1:00	D
+Rule	US	1975	only	-	Feb	23	2:00	1:00	D
+Rule	US	1976	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	US	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
+Rule	US	2007	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	US	2007	max	-	Nov	Sun>=1	2:00	0	S
+
+# From Arthur David Olson, 2005-12-19
+# We generate the files specified below to guard against old files with
+# obsolete information being left in the time zone binary directory.
+# We limit the list to names that have appeared in previous versions of
+# this time zone package.
+# We do these as separate Zones rather than as Links to avoid problems if
+# a particular place changes whether it observes DST.
+# We put these specifications here in the northamerica file both to
+# increase the chances that they'll actually get compiled and to
+# avoid the need to duplicate the US rules in another file.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	EST		 -5:00	-	EST
+Zone	MST		 -7:00	-	MST
+Zone	HST		-10:00	-	HST
+Zone	EST5EDT		 -5:00	US	E%sT
+Zone	CST6CDT		 -6:00	US	C%sT
+Zone	MST7MDT		 -7:00	US	M%sT
+Zone	PST8PDT		 -8:00	US	P%sT
+
+# From Bob Devine (1988-01-28):
+# ...Alaska (and Hawaii) had the timezone names changed in 1967.
+#    old			 new
+#    Pacific Standard Time(PST)  -same-
+#    Yukon Standard Time(YST)    -same-
+#    Central Alaska S.T. (CAT)   Alaska-Hawaii St[an]dard Time (AHST)
+#    Nome Standard Time (NT)     Bering Standard Time (BST)
+#
+# ...Alaska's timezone lines were redrawn in 1983 to give only 2 tz.
+#    The YST zone now covers nearly all of the state, AHST just part
+#    of the Aleutian islands.   No DST.
+
+# From Paul Eggert (1995-12-19):
+# The tables below use `NST', not `NT', for Nome Standard Time.
+# I invented `CAWT' for Central Alaska War Time.
+
+# From U. S. Naval Observatory (1989-01-19):
+# USA  EASTERN       5 H  BEHIND UTC    NEW YORK, WASHINGTON
+# USA  EASTERN       4 H  BEHIND UTC    APR 3 - OCT 30
+# USA  CENTRAL       6 H  BEHIND UTC    CHICAGO, HOUSTON
+# USA  CENTRAL       5 H  BEHIND UTC    APR 3 - OCT 30
+# USA  MOUNTAIN      7 H  BEHIND UTC    DENVER
+# USA  MOUNTAIN      6 H  BEHIND UTC    APR 3 - OCT 30
+# USA  PACIFIC       8 H  BEHIND UTC    L.A., SAN FRANCISCO
+# USA  PACIFIC       7 H  BEHIND UTC    APR 3 - OCT 30
+# USA  ALASKA STD    9 H  BEHIND UTC    MOST OF ALASKA     (AKST)
+# USA  ALASKA STD    8 H  BEHIND UTC    APR 3 - OCT 30 (AKDT)
+# USA  ALEUTIAN     10 H  BEHIND UTC    ISLANDS WEST OF 170W
+# USA  - " -         9 H  BEHIND UTC    APR 3 - OCT 30
+# USA  HAWAII       10 H  BEHIND UTC
+# USA  BERING       11 H  BEHIND UTC    SAMOA, MIDWAY
+
+# From Arthur David Olson (1989-01-21):
+# The above dates are for 1988.
+# Note the "AKST" and "AKDT" abbreviations, the claim that there's
+# no DST in Samoa, and the claim that there is DST in Alaska and the
+# Aleutians.
+
+# From Arthur David Olson (1988-02-13):
+# Legal standard time zone names, from United States Code (1982 Edition and
+# Supplement III), Title 15, Chapter 6, Section 260 and forward.  First, names
+# up to 1967-04-01 (when most provisions of the Uniform Time Act of 1966
+# took effect), as explained in sections 263 and 261:
+#	(none)
+#	United States standard eastern time
+#	United States standard mountain time
+#	United States standard central time
+#	United States standard Pacific time
+#	(none)
+#	United States standard Alaska time
+#	(none)
+# Next, names from 1967-04-01 until 1983-11-30 (the date for
+# public law 98-181):
+#	Atlantic standard time
+#	eastern standard time
+#	central standard time
+#	mountain standard time
+#	Pacific standard time
+#	Yukon standard time
+#	Alaska-Hawaii standard time
+#	Bering standard time
+# And after 1983-11-30:
+#	Atlantic standard time
+#	eastern standard time
+#	central standard time
+#	mountain standard time
+#	Pacific standard time
+#	Alaska standard time
+#	Hawaii-Aleutian standard time
+#	Samoa standard time
+# The law doesn't give abbreviations.
+#
+# From Paul Eggert (2000-01-08), following a heads-up from Rives McDow:
+# Public law 106-564 (2000-12-23) introduced the abbreviation
+# "Chamorro Standard Time" for time in Guam and the Northern Marianas.
+# See the file "australasia".
+
+# From Arthur David Olson, 2005-08-09
+# The following was signed into law on 2005-08-08.
+#
+# H.R. 6, Energy Policy Act of 2005, SEC. 110. DAYLIGHT SAVINGS.
+#   (a) Amendment- Section 3(a) of the Uniform Time Act of 1966 (15
+#   U.S.C. 260a(a)) is amended--
+#     (1) by striking `first Sunday of April' and inserting `second
+#     Sunday of March'; and
+#     (2) by striking `last Sunday of October' and inserting `first
+#     Sunday of November'.
+#   (b) Effective Date- Subsection (a) shall take effect 1 year after the
+#   date of enactment of this Act or March 1, 2007, whichever is later.
+#   (c) Report to Congress- Not later than 9 months after the effective
+#   date stated in subsection (b), the Secretary shall report to Congress
+#   on the impact of this section on energy consumption in the United
+#   States.
+#   (d) Right to Revert- Congress retains the right to revert the
+#   Daylight Saving Time back to the 2005 time schedules once the
+#   Department study is complete.
+
+# US eastern time, represented by New York
+
+# Connecticut, Delaware, District of Columbia, most of Florida,
+# Georgia, southeast Indiana (Dearborn and Ohio counties), eastern Kentucky
+# (except America/Kentucky/Louisville below), Maine, Maryland, Massachusetts,
+# New Hampshire, New Jersey, New York, North Carolina, Ohio,
+# Pennsylvania, Rhode Island, South Carolina, eastern Tennessee,
+# Vermont, Virginia, West Virginia
+
+# From Dave Cantor (2004-11-02):
+# Early this summer I had the occasion to visit the Mount Washington
+# Observatory weather station atop (of course!) Mount Washington [, NH]....
+# One of the staff members said that the station was on Eastern Standard Time
+# and didn't change their clocks for Daylight Saving ... so that their
+# reports will always have times which are 5 hours behind UTC.
+
+# From Paul Eggert (2005-08-26):
+# According to today's Huntsville Times
+# <http://www.al.com/news/huntsvilletimes/index.ssf?/base/news/1125047783228320.xml&coll=1>
+# a few towns on Alabama's "eastern border with Georgia, such as Phenix City
+# in Russell County, Lanett in Chambers County and some towns in Lee County,
+# set their watches and clocks on Eastern time."  It quotes H.H. "Bubba"
+# Roberts, city administrator in Phenix City. as saying "We are in the Central
+# time zone, but we do go by the Eastern time zone because so many people work
+# in Columbus."
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	NYC	1920	only	-	Mar	lastSun	2:00	1:00	D
+Rule	NYC	1920	only	-	Oct	lastSun	2:00	0	S
+Rule	NYC	1921	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	NYC	1921	1954	-	Sep	lastSun	2:00	0	S
+Rule	NYC	1955	1966	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/New_York	-4:56:02 -	LMT	1883 Nov 18 12:03:58
+			-5:00	US	E%sT	1920
+			-5:00	NYC	E%sT	1942
+			-5:00	US	E%sT	1946
+			-5:00	NYC	E%sT	1967
+			-5:00	US	E%sT
+
+# US central time, represented by Chicago
+
+# Alabama, Arkansas, Florida panhandle (Bay, Calhoun, Escambia,
+# Gulf, Holmes, Jackson, Okaloosa, Santa Rosa, Walton, and
+# Washington counties), Illinois, western Indiana
+# (Gibson, Jasper, Lake, LaPorte, Newton, Porter, Posey, Spencer,
+# Vanderburgh, and Warrick counties), Iowa, most of Kansas, western
+# Kentucky, Louisiana, Minnesota, Mississippi, Missouri, eastern
+# Nebraska, eastern North Dakota, Oklahoma, eastern South Dakota,
+# western Tennessee, most of Texas, Wisconsin
+
+# From Larry M. Smith (2006-04-26) re Wisconsin:
+# http://www.legis.state.wi.us/statutes/Stat0175.pdf ...
+# is currently enforced at the 01:00 time of change.  Because the local
+# "bar time" in the state corresponds to 02:00, a number of citations
+# are issued for the "sale of class 'B' alcohol after prohibited
+# hours" within the deviated hour of this change every year....
+#
+# From Douglas R. Bomberg (2007-03-12):
+# Wisconsin has enacted (nearly eleventh-hour) legislation to get WI
+# Statue 175 closer in synch with the US Congress' intent....
+# http://www.legis.state.wi.us/2007/data/acts/07Act3.pdf
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Chicago	1920	only	-	Jun	13	2:00	1:00	D
+Rule	Chicago	1920	1921	-	Oct	lastSun	2:00	0	S
+Rule	Chicago	1921	only	-	Mar	lastSun	2:00	1:00	D
+Rule	Chicago	1922	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	Chicago	1922	1954	-	Sep	lastSun	2:00	0	S
+Rule	Chicago	1955	1966	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Chicago	-5:50:36 -	LMT	1883 Nov 18 12:09:24
+			-6:00	US	C%sT	1920
+			-6:00	Chicago	C%sT	1936 Mar  1 2:00
+			-5:00	-	EST	1936 Nov 15 2:00
+			-6:00	Chicago	C%sT	1942
+			-6:00	US	C%sT	1946
+			-6:00	Chicago	C%sT	1967
+			-6:00	US	C%sT
+# Oliver County, ND switched from mountain to central time on 1992-10-25.
+Zone America/North_Dakota/Center -6:45:12 - LMT	1883 Nov 18 12:14:48
+			-7:00	US	M%sT	1992 Oct 25 02:00
+			-6:00	US	C%sT
+# Morton County, ND, switched from mountain to central time on
+# 2003-10-26, except for the area around Mandan which was already central time.
+# See <http://dmses.dot.gov/docimages/p63/135818.pdf>.
+# Officially this switch also included part of Sioux County, and
+# Jones, Mellette, and Todd Counties in South Dakota;
+# but in practice these other counties were already observing central time.
+# See <http://www.epa.gov/fedrgstr/EPA-IMPACT/2003/October/Day-28/i27056.htm>.
+Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
+			-7:00	US	M%sT	2003 Oct 26 02:00
+			-6:00	US	C%sT
+
+# From Josh Findley (2011-01-21):
+# ...it appears that Mercer County, North Dakota, changed from the
+# mountain time zone to the central time zone at the last transition from
+# daylight-saving to standard time (on Nov. 7, 2010):
+# <a href="http://www.gpo.gov/fdsys/pkg/FR-2010-09-29/html/2010-24376.htm">
+# http://www.gpo.gov/fdsys/pkg/FR-2010-09-29/html/2010-24376.htm
+# </a>
+# <a href="http://www.bismarcktribune.com/news/local/article_1eb1b588-c758-11df-b472-001cc4c03286.html">
+# http://www.bismarcktribune.com/news/local/article_1eb1b588-c758-11df-b472-001cc4c03286.html
+# </a>
+
+# From Andy Lipscomb (2011-01-24):
+# ...according to the Census Bureau, the largest city is Beulah (although
+# it's commonly referred to as Beulah-Hazen, with Hazen being the next
+# largest city in Mercer County).  Google Maps places Beulah's city hall
+# at 4715'51" north, 10146'40" west, which yields an offset of 6h47'07".
+
+Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53
+			-7:00	US	M%sT	2010 Nov  7 2:00
+			-6:00	US	C%sT
+
+# US mountain time, represented by Denver
+#
+# Colorado, far western Kansas, Montana, western
+# Nebraska, Nevada border (Jackpot, Owyhee, and Mountain City),
+# New Mexico, southwestern North Dakota,
+# western South Dakota, far western Texas (El Paso County, Hudspeth County,
+# and Pine Springs and Nickel Creek in Culberson County), Utah, Wyoming
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Denver	1920	1921	-	Mar	lastSun	2:00	1:00	D
+Rule	Denver	1920	only	-	Oct	lastSun	2:00	0	S
+Rule	Denver	1921	only	-	May	22	2:00	0	S
+Rule	Denver	1965	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	Denver	1965	1966	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Denver	-6:59:56 -	LMT	1883 Nov 18 12:00:04
+			-7:00	US	M%sT	1920
+			-7:00	Denver	M%sT	1942
+			-7:00	US	M%sT	1946
+			-7:00	Denver	M%sT	1967
+			-7:00	US	M%sT
+
+# US Pacific time, represented by Los Angeles
+#
+# California, northern Idaho (Benewah, Bonner, Boundary, Clearwater,
+# Idaho, Kootenai, Latah, Lewis, Nez Perce, and Shoshone counties,
+# and the northern three-quarters of Idaho county),
+# most of Nevada, most of Oregon, and Washington
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	CA	1948	only	-	Mar	14	2:00	1:00	D
+Rule	CA	1949	only	-	Jan	 1	2:00	0	S
+Rule	CA	1950	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	CA	1950	1961	-	Sep	lastSun	2:00	0	S
+Rule	CA	1962	1966	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Los_Angeles -7:52:58 -	LMT	1883 Nov 18 12:07:02
+			-8:00	US	P%sT	1946
+			-8:00	CA	P%sT	1967
+			-8:00	US	P%sT
+
+# Alaska
+# AK%sT is the modern abbreviation for -9:00 per USNO.
+#
+# From Paul Eggert (2001-05-30):
+# Howse writes that Alaska switched from the Julian to the Gregorian calendar,
+# and from east-of-GMT to west-of-GMT days, when the US bought it from Russia.
+# This was on 1867-10-18, a Friday; the previous day was 1867-10-06 Julian,
+# also a Friday.  Include only the time zone part of this transition,
+# ignoring the switch from Julian to Gregorian, since we can't represent
+# the Julian calendar.
+#
+# As far as we know, none of the exact locations mentioned below were
+# permanently inhabited in 1867 by anyone using either calendar.
+# (Yakutat was colonized by the Russians in 1799, but the settlement
+# was destroyed in 1805 by a Yakutat-kon war party.)  However, there
+# were nearby inhabitants in some cases and for our purposes perhaps
+# it's best to simply use the official transition.
+#
+
+# From Steve Ferguson (2011-01-31):
+# The author lives in Alaska and many of the references listed are only
+# available to Alaskan residents.
+#
+# <a href="http://www.alaskahistoricalsociety.org/index.cfm?section=discover%20alaska&page=Glimpses%20of%20the%20Past&viewpost=2&ContentId=98">
+# http://www.alaskahistoricalsociety.org/index.cfm?section=discover%20alaska&page=Glimpses%20of%20the%20Past&viewpost=2&ContentId=98
+# </a>
+
+# From Arthur David Olson (2011-02-01):
+# Here's database-relevant material from the 2001 "Alaska History" article:
+#
+# On September 20 [1979]...DOT...officials decreed that on April 27,
+# 1980, Juneau and other nearby communities would move to Yukon Time.
+# Sitka, Petersburg, Wrangell, and Ketchikan, however, would remain on
+# Pacific Time.
+#
+# ...on September 22, 1980, DOT Secretary Neil E. Goldschmidt rescinded the
+# Department's September 1979 decision. Juneau and other communities in
+# northern Southeast reverted to Pacific Time on October 26.
+#
+# On October 28 [1983]...the Metlakatla Indian Community Council voted
+# unanimously to keep the reservation on Pacific Time.
+#
+# According to DOT official Joanne Petrie, Indian reservations are not
+# bound to follow time zones imposed by neighboring jurisdictions.
+#
+# (The last is consistent with how the database now handles the Navajo
+# Nation.)
+
+# From Arthur David Olson (2011-02-09):
+# I just spoke by phone with a staff member at the Metlakatla Indian
+# Community office (using contact information available at
+# <a href="http://www.commerce.state.ak.us/dca/commdb/CIS.cfm?Comm_Boro_name=Metlakatla">
+# http://www.commerce.state.ak.us/dca/commdb/CIS.cfm?Comm_Boro_name=Metlakatla
+# </a>).
+# It's shortly after 1:00 here on the east coast of the United States;
+# the staffer said it was shortly after 10:00 there. When I asked whether
+# that meant they were on Pacific time, they said no--they were on their
+# own time. I asked about daylight saving; they said it wasn't used. I
+# did not inquire about practices in the past.
+
+# From Arthur David Olson (2011-08-17):
+# For lack of better information, assume that Metlakatla's
+# abandonment of use of daylight saving resulted from the 1983 vote.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Juneau	 15:02:19 -	LMT	1867 Oct 18
+			 -8:57:41 -	LMT	1900 Aug 20 12:00
+			 -8:00	-	PST	1942
+			 -8:00	US	P%sT	1946
+			 -8:00	-	PST	1969
+			 -8:00	US	P%sT	1980 Apr 27 2:00
+			 -9:00	US	Y%sT	1980 Oct 26 2:00
+			 -8:00	US	P%sT	1983 Oct 30 2:00
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Sitka	 14:58:47 -	LMT	1867 Oct 18
+			 -9:01:13 -	LMT	1900 Aug 20 12:00
+			 -8:00	-	PST	1942
+			 -8:00	US	P%sT	1946
+			 -8:00	-	PST	1969
+			 -8:00	US	P%sT	1983 Oct 30 2:00
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Metlakatla	 15:13:42 -	LMT	1867 Oct 18
+			 -8:46:18 -	LMT	1900 Aug 20 12:00
+			 -8:00	-	PST	1942
+			 -8:00	US	P%sT	1946
+			 -8:00	-	PST	1969
+			 -8:00	US	P%sT	1983 Oct 30 2:00
+			 -8:00	-	MeST
+Zone America/Yakutat	 14:41:05 -	LMT	1867 Oct 18
+			 -9:18:55 -	LMT	1900 Aug 20 12:00
+			 -9:00	-	YST	1942
+			 -9:00	US	Y%sT	1946
+			 -9:00	-	YST	1969
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Anchorage	 14:00:24 -	LMT	1867 Oct 18
+			 -9:59:36 -	LMT	1900 Aug 20 12:00
+			-10:00	-	CAT	1942
+			-10:00	US	CAT/CAWT 1945 Aug 14 23:00u
+			-10:00	US	CAT/CAPT 1946 # Peace
+			-10:00	-	CAT	1967 Apr
+			-10:00	-	AHST	1969
+			-10:00	US	AH%sT	1983 Oct 30 2:00
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Nome	 12:58:21 -	LMT	1867 Oct 18
+			-11:01:38 -	LMT	1900 Aug 20 12:00
+			-11:00	-	NST	1942
+			-11:00	US	N%sT	1946
+			-11:00	-	NST	1967 Apr
+			-11:00	-	BST	1969
+			-11:00	US	B%sT	1983 Oct 30 2:00
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Adak	 12:13:21 -	LMT	1867 Oct 18
+			-11:46:38 -	LMT	1900 Aug 20 12:00
+			-11:00	-	NST	1942
+			-11:00	US	N%sT	1946
+			-11:00	-	NST	1967 Apr
+			-11:00	-	BST	1969
+			-11:00	US	B%sT	1983 Oct 30 2:00
+			-10:00	US	AH%sT	1983 Nov 30
+			-10:00	US	HA%sT
+# The following switches don't quite make our 1970 cutoff.
+#
+# Shanks writes that part of southwest Alaska (e.g. Aniak)
+# switched from -11:00 to -10:00 on 1968-09-22 at 02:00,
+# and another part (e.g. Akiak) made the same switch five weeks later.
+#
+# From David Flater (2004-11-09):
+# In e-mail, 2004-11-02, Ray Hudson, historian/liaison to the Unalaska
+# Historic Preservation Commission, provided this information, which
+# suggests that Unalaska deviated from statutory time from early 1967
+# possibly until 1983:
+#
+#  Minutes of the Unalaska City Council Meeting, January 10, 1967:
+#  "Except for St. Paul and Akutan, Unalaska is the only important
+#  location not on Alaska Standard Time.  The following resolution was
+#  made by William Robinson and seconded by Henry Swanson:  Be it
+#  resolved that the City of Unalaska hereby goes to Alaska Standard
+#  Time as of midnight Friday, January 13, 1967 (1 A.M. Saturday,
+#  January 14, Alaska Standard Time.)  This resolution was passed with
+#  three votes for and one against."
+
+# Hawaii
+
+# From Arthur David Olson (2010-12-09):
+# "Hawaiian Time" by Robert C. Schmitt and Doak C. Cox appears on pages 207-225
+# of volume 26 of The Hawaiian Journal of History (1992). As of 2010-12-09,
+# the article is available at
+# <a href="http://evols.library.manoa.hawaii.edu/bitstream/10524/239/2/JL26215.pdf">
+# http://evols.library.manoa.hawaii.edu/bitstream/10524/239/2/JL26215.pdf
+# </a>
+# and indicates that standard time was adopted effective noon, January
+# 13, 1896 (page 218), that in "1933, the Legislature decreed daylight
+# saving for the period between the last Sunday of each April and the
+# last Sunday of each September, but less than a month later repealed the
+# act," (page 220), that year-round daylight saving time was in effect
+# from 1942-02-09 to 1945-09-30 (page 221, with no time of day given for
+# when clocks changed) and that clocks were changed by 30 minutes
+# effective the second Sunday of June, 1947 (page 219, with no time of
+# day given for when clocks changed). A footnote for the 1933 changes
+# cites Session Laws of Hawaii 1933, "Act. 90 (approved 26 Apr. 1933)
+# and Act 163 (approved 21 May 1933)."
+
+# From Arthur David Olson (2011-01-19):
+# The following is from "Laws of the Territory of Hawaii Passed by the
+# Seventeenth Legislature: Regular Session 1933," available (as of
+# 2011-01-19) at American University's Pence Law Library. Page 85: "Act
+# 90...At 2 o'clock ante meridian of the last Sunday in April of each
+# year, the standard time of this Territory shall be advanced one
+# hour...This Act shall take effect upon its approval. Approved this 26th
+# day of April, A. D. 1933. LAWRENCE M JUDD, Governor of the Territory of
+# Hawaii." Page 172:  "Act 163...Act 90 of the Session Laws of 1933 is
+# hereby repealed...This Act shall take effect upon its approval, upon
+# which date the standard time of this Territory shall be restored to
+# that existing immediately prior to the taking effect of said Act 90.
+# Approved this 21st day of May, A. D. 1933. LAWRENCE M. JUDD, Governor
+# of the Territory of Hawaii."
+#
+# Note that 1933-05-21 was a Sunday.
+# We're left to guess the time of day when Act 163 was approved; guess noon.
+
+Zone Pacific/Honolulu	-10:31:26 -	LMT	1896 Jan 13 12:00 #Schmitt&Cox
+			-10:30	-	HST	1933 Apr 30 2:00 #Laws 1933
+			-10:30	1:00	HDT	1933 May 21 12:00 #Laws 1933+12
+			-10:30	-	HST	1942 Feb 09 2:00 #Schmitt&Cox+2
+			-10:30	1:00	HDT	1945 Sep 30 2:00 #Schmitt&Cox+2
+			-10:30	-	HST	1947 Jun  8 2:00 #Schmitt&Cox+2
+			-10:00	-	HST
+
+# Now we turn to US areas that have diverged from the consensus since 1970.
+
+# Arizona mostly uses MST.
+
+# From Paul Eggert (2002-10-20):
+#
+# The information in the rest of this paragraph is derived from the
+# <a href="http://www.dlapr.lib.az.us/links/daylight.htm">
+# Daylight Saving Time web page (2002-01-23)</a> maintained by the
+# Arizona State Library, Archives and Public Records.
+# Between 1944-01-01 and 1944-04-01 the State of Arizona used standard
+# time, but by federal law railroads, airlines, bus lines, military
+# personnel, and some engaged in interstate commerce continued to
+# observe war (i.e., daylight saving) time.  The 1944-03-17 Phoenix
+# Gazette says that was the date the law changed, and that 04-01 was
+# the date the state's clocks would change.  In 1945 the State of
+# Arizona used standard time all year, again with exceptions only as
+# mandated by federal law.  Arizona observed DST in 1967, but Arizona
+# Laws 1968, ch. 183 (effective 1968-03-21) repealed DST.
+#
+# Shanks says the 1944 experiment came to an end on 1944-03-17.
+# Go with the Arizona State Library instead.
+
+Zone America/Phoenix	-7:28:18 -	LMT	1883 Nov 18 11:31:42
+			-7:00	US	M%sT	1944 Jan  1 00:01
+			-7:00	-	MST	1944 Apr  1 00:01
+			-7:00	US	M%sT	1944 Oct  1 00:01
+			-7:00	-	MST	1967
+			-7:00	US	M%sT	1968 Mar 21
+			-7:00	-	MST
+# From Arthur David Olson (1988-02-13):
+# A writer from the Inter Tribal Council of Arizona, Inc.,
+# notes in private correspondence dated 1987-12-28 that "Presently, only the
+# Navajo Nation participates in the Daylight Saving Time policy, due to its
+# large size and location in three states."  (The "only" means that other
+# tribal nations don't use DST.)
+
+Link America/Denver America/Shiprock
+
+# Southern Idaho (Ada, Adams, Bannock, Bear Lake, Bingham, Blaine,
+# Boise, Bonneville, Butte, Camas, Canyon, Caribou, Cassia, Clark,
+# Custer, Elmore, Franklin, Fremont, Gem, Gooding, Jefferson, Jerome,
+# Lemhi, Lincoln, Madison, Minidoka, Oneida, Owyhee, Payette, Power,
+# Teton, Twin Falls, Valley, Washington counties, and the southern
+# quarter of Idaho county) and eastern Oregon (most of Malheur County)
+# switched four weeks late in 1974.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Boise	-7:44:49 -	LMT	1883 Nov 18 12:15:11
+			-8:00	US	P%sT	1923 May 13 2:00
+			-7:00	US	M%sT	1974
+			-7:00	-	MST	1974 Feb  3 2:00
+			-7:00	US	M%sT
+
+# Indiana
+#
+# For a map of Indiana's time zone regions, see:
+# <a href="http://www.mccsc.edu/time.html">
+# What time is it in Indiana?
+# </a> (2006-03-01)
+#
+# From Paul Eggert (2007-08-17):
+# Since 1970, most of Indiana has been like America/Indiana/Indianapolis,
+# with the following exceptions:
+#
+# - Gibson, Jasper, Lake, LaPorte, Newton, Porter, Posey, Spencer,
+#   Vandenburgh, and Warrick counties have been like America/Chicago.
+#
+# - Dearborn and Ohio counties have been like America/New_York.
+#
+# - Clark, Floyd, and Harrison counties have been like
+#   America/Kentucky/Louisville.
+#
+# - Crawford, Daviess, Dubois, Knox, Martin, Perry, Pike, Pulaski, Starke,
+#   and Switzerland counties have their own time zone histories as noted below.
+#
+# Shanks partitioned Indiana into 345 regions, each with its own time history,
+# and wrote ``Even newspaper reports present contradictory information.''
+# Those Hoosiers!  Such a flighty and changeable people!
+# Fortunately, most of the complexity occurred before our cutoff date of 1970.
+#
+# Other than Indianapolis, the Indiana place names are so nondescript
+# that they would be ambiguous if we left them at the `America' level.
+# So we reluctantly put them all in a subdirectory `America/Indiana'.
+
+# From Paul Eggert (2005-08-16):
+# http://www.mccsc.edu/time.html says that Indiana will use DST starting 2006.
+
+# From Nathan Stratton Treadway (2006-03-30):
+# http://www.dot.gov/affairs/dot0406.htm [3705 B]
+# From Deborah Goldsmith (2006-01-18):
+# http://dmses.dot.gov/docimages/pdf95/382329_web.pdf [2.9 MB]
+# From Paul Eggert (2006-01-20):
+# It says "DOT is relocating the time zone boundary in Indiana to move Starke,
+# Pulaski, Knox, Daviess, Martin, Pike, Dubois, and Perry Counties from the
+# Eastern Time Zone to the Central Time Zone.... The effective date of
+# this rule is 2:OO a.m. EST Sunday, April 2, 2006, which is the
+# changeover date from standard time to Daylight Saving Time."
+# Strictly speaking, this means the affected counties will change their
+# clocks twice that night, but this obviously is in error.  The intent
+# is that 01:59:59 EST be followed by 02:00:00 CDT.
+
+# From Gwillim Law (2007-02-10):
+# The Associated Press has been reporting that Pulaski County, Indiana is
+# going to switch from Central to Eastern Time on March 11, 2007....
+# http://www.indystar.com/apps/pbcs.dll/article?AID=/20070207/LOCAL190108/702070524/0/LOCAL
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Indianapolis 1941	only	-	Jun	22	2:00	1:00	D
+Rule Indianapolis 1941	1954	-	Sep	lastSun	2:00	0	S
+Rule Indianapolis 1946	1954	-	Apr	lastSun	2:00	1:00	D
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
+			-6:00	US	C%sT	1920
+			-6:00 Indianapolis C%sT	1942
+			-6:00	US	C%sT	1946
+			-6:00 Indianapolis C%sT	1955 Apr 24 2:00
+			-5:00	-	EST	1957 Sep 29 2:00
+			-6:00	-	CST	1958 Apr 27 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1971
+			-5:00	-	EST	2006
+			-5:00	US	E%sT
+#
+# Eastern Crawford County, Indiana, left its clocks alone in 1974,
+# as well as from 1976 through 2005.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Marengo	1951	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Marengo	1951	only	-	Sep	lastSun	2:00	0	S
+Rule	Marengo	1954	1960	-	Apr	lastSun	2:00	1:00	D
+Rule	Marengo	1954	1960	-	Sep	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Marengo -5:45:23 -	LMT	1883 Nov 18 12:14:37
+			-6:00	US	C%sT	1951
+			-6:00	Marengo	C%sT	1961 Apr 30 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1974 Jan  6 2:00
+			-6:00	1:00	CDT	1974 Oct 27 2:00
+			-5:00	US	E%sT	1976
+			-5:00	-	EST	2006
+			-5:00	US	E%sT
+#
+# Daviess, Dubois, Knox, and Martin Counties, Indiana,
+# switched from eastern to central time in April 2006, then switched back
+# in November 2007.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Vincennes	1946	only	-	Apr	lastSun	2:00	1:00	D
+Rule Vincennes	1946	only	-	Sep	lastSun	2:00	0	S
+Rule Vincennes	1953	1954	-	Apr	lastSun	2:00	1:00	D
+Rule Vincennes	1953	1959	-	Sep	lastSun	2:00	0	S
+Rule Vincennes	1955	only	-	May	 1	0:00	1:00	D
+Rule Vincennes	1956	1963	-	Apr	lastSun	2:00	1:00	D
+Rule Vincennes	1960	only	-	Oct	lastSun	2:00	0	S
+Rule Vincennes	1961	only	-	Sep	lastSun	2:00	0	S
+Rule Vincennes	1962	1963	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Vincennes -5:50:07 - LMT	1883 Nov 18 12:09:53
+			-6:00	US	C%sT	1946
+			-6:00 Vincennes	C%sT	1964 Apr 26 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1971
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT	2007 Nov  4 2:00
+			-5:00	US	E%sT
+#
+# Perry County, Indiana, switched from eastern to central time in April 2006.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Perry	1946	only	-	Apr	lastSun	2:00	1:00	D
+Rule Perry	1946	only	-	Sep	lastSun	2:00	0	S
+Rule Perry	1953	1954	-	Apr	lastSun	2:00	1:00	D
+Rule Perry	1953	1959	-	Sep	lastSun	2:00	0	S
+Rule Perry	1955	only	-	May	 1	0:00	1:00	D
+Rule Perry	1956	1963	-	Apr	lastSun	2:00	1:00	D
+Rule Perry	1960	only	-	Oct	lastSun	2:00	0	S
+Rule Perry	1961	only	-	Sep	lastSun	2:00	0	S
+Rule Perry	1962	1963	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Tell_City -5:47:03 - LMT	1883 Nov 18 12:12:57
+			-6:00	US	C%sT	1946
+			-6:00 Perry	C%sT	1964 Apr 26 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1971
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT
+#
+# Pike County, Indiana moved from central to eastern time in 1977,
+# then switched back in 2006, then switched back again in 2007.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Pike	1955	only	-	May	 1	0:00	1:00	D
+Rule	Pike	1955	1960	-	Sep	lastSun	2:00	0	S
+Rule	Pike	1956	1964	-	Apr	lastSun	2:00	1:00	D
+Rule	Pike	1961	1964	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Petersburg -5:49:07 - LMT	1883 Nov 18 12:10:53
+			-6:00	US	C%sT	1955
+			-6:00	Pike	C%sT	1965 Apr 25 2:00
+			-5:00	-	EST	1966 Oct 30 2:00
+			-6:00	US	C%sT	1977 Oct 30 2:00
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT	2007 Nov  4 2:00
+			-5:00	US	E%sT
+#
+# Starke County, Indiana moved from central to eastern time in 1991,
+# then switched back in 2006.
+# From Arthur David Olson (1991-10-28):
+# An article on page A3 of the Sunday, 1991-10-27 Washington Post
+# notes that Starke County switched from Central time to Eastern time as of
+# 1991-10-27.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Starke	1947	1961	-	Apr	lastSun	2:00	1:00	D
+Rule	Starke	1947	1954	-	Sep	lastSun	2:00	0	S
+Rule	Starke	1955	1956	-	Oct	lastSun	2:00	0	S
+Rule	Starke	1957	1958	-	Sep	lastSun	2:00	0	S
+Rule	Starke	1959	1961	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Knox -5:46:30 -	LMT	1883 Nov 18 12:13:30
+			-6:00	US	C%sT	1947
+			-6:00	Starke	C%sT	1962 Apr 29 2:00
+			-5:00	-	EST	1963 Oct 27 2:00
+			-6:00	US	C%sT	1991 Oct 27 2:00
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT
+#
+# Pulaski County, Indiana, switched from eastern to central time in
+# April 2006 and then switched back in March 2007.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Pulaski	1946	1960	-	Apr	lastSun	2:00	1:00	D
+Rule	Pulaski	1946	1954	-	Sep	lastSun	2:00	0	S
+Rule	Pulaski	1955	1956	-	Oct	lastSun	2:00	0	S
+Rule	Pulaski	1957	1960	-	Sep	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Winamac -5:46:25 - LMT	1883 Nov 18 12:13:35
+			-6:00	US	C%sT	1946
+			-6:00	Pulaski	C%sT	1961 Apr 30 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1971
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT	2007 Mar 11 2:00
+			-5:00	US	E%sT
+#
+# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Vevay -5:40:16 -	LMT	1883 Nov 18 12:19:44
+			-6:00	US	C%sT	1954 Apr 25 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1973
+			-5:00	-	EST	2006
+			-5:00	US	E%sT
+
+# Part of Kentucky left its clocks alone in 1974.
+# This also includes Clark, Floyd, and Harrison counties in Indiana.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Louisville	1921	only	-	May	1	2:00	1:00	D
+Rule Louisville	1921	only	-	Sep	1	2:00	0	S
+Rule Louisville	1941	1961	-	Apr	lastSun	2:00	1:00	D
+Rule Louisville	1941	only	-	Sep	lastSun	2:00	0	S
+Rule Louisville	1946	only	-	Jun	2	2:00	0	S
+Rule Louisville	1950	1955	-	Sep	lastSun	2:00	0	S
+Rule Louisville	1956	1960	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Kentucky/Louisville -5:43:02 -	LMT	1883 Nov 18 12:16:58
+			-6:00	US	C%sT	1921
+			-6:00 Louisville C%sT	1942
+			-6:00	US	C%sT	1946
+			-6:00 Louisville C%sT	1961 Jul 23 2:00
+			-5:00	-	EST	1968
+			-5:00	US	E%sT	1974 Jan  6 2:00
+			-6:00	1:00	CDT	1974 Oct 27 2:00
+			-5:00	US	E%sT
+#
+# Wayne County, Kentucky
+#
+# From
+# <a href="http://www.lake-cumberland.com/life/archive/news990129time.shtml">
+# Lake Cumberland LIFE
+# </a> (1999-01-29) via WKYM-101.7:
+# Clinton County has joined Wayne County in asking the DoT to change from
+# the Central to the Eastern time zone....  The Wayne County government made
+# the same request in December.  And while Russell County officials have not
+# taken action, the majority of respondents to a poll conducted there in
+# August indicated they would like to change to "fast time" also.
+# The three Lake Cumberland counties are the farthest east of any U.S.
+# location in the Central time zone.
+#
+# From Rich Wales (2000-08-29):
+# After prolonged debate, and despite continuing deep differences of opinion,
+# Wayne County (central Kentucky) is switching from Central (-0600) to Eastern
+# (-0500) time.  They won't "fall back" this year.  See Sara Shipley,
+# The difference an hour makes, Nando Times (2000-08-29 15:33 -0400).
+#
+# From Paul Eggert (2001-07-16):
+# The final rule was published in the
+# <a href="http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=2000_register&docid=fr17au00-22">
+# Federal Register 65, 160 (2000-08-17), page 50154-50158.
+# </a>
+#
+Zone America/Kentucky/Monticello -5:39:24 - LMT	1883 Nov 18 12:20:36
+			-6:00	US	C%sT	1946
+			-6:00	-	CST	1968
+			-6:00	US	C%sT	2000 Oct 29  2:00
+			-5:00	US	E%sT
+
+
+# From Rives McDow (2000-08-30):
+# Here ... are all the changes in the US since 1985.
+# Kearny County, KS (put all of county on central;
+#	previously split between MST and CST) ... 1990-10
+# Starke County, IN (from CST to EST) ... 1991-10
+# Oliver County, ND (from MST to CST) ... 1992-10
+# West Wendover, NV (from PST TO MST) ... 1999-10
+# Wayne County, KY (from CST to EST) ... 2000-10
+#
+# From Paul Eggert (2001-07-17):
+# We don't know where the line used to be within Kearny County, KS,
+# so omit that change for now.
+# See America/Indiana/Knox for the Starke County, IN change.
+# See America/North_Dakota/Center for the Oliver County, ND change.
+# West Wendover, NV officially switched from Pacific to mountain time on
+# 1999-10-31.  See the
+# <a href="http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=1999_register&docid=fr21oc99-15">
+# Federal Register 64, 203 (1999-10-21), page 56705-56707.
+# </a>
+# However, the Federal Register says that West Wendover already operated
+# on mountain time, and the rule merely made this official;
+# hence a separate tz entry is not needed.
+
+# Michigan
+#
+# From Bob Devine (1988-01-28):
+# Michigan didn't observe DST from 1968 to 1973.
+#
+# From Paul Eggert (1999-03-31):
+# Shanks writes that Michigan started using standard time on 1885-09-18,
+# but Howse writes (pp 124-125, referring to Popular Astronomy, 1901-01)
+# that Detroit kept
+#
+#	local time until 1900 when the City Council decreed that clocks should
+#	be put back twenty-eight minutes to Central Standard Time.  Half the
+#	city obeyed, half refused.  After considerable debate, the decision
+#	was rescinded and the city reverted to Sun time.  A derisive offer to
+#	erect a sundial in front of the city hall was referred to the
+#	Committee on Sewers.  Then, in 1905, Central time was adopted
+#	by city vote.
+#
+# This story is too entertaining to be false, so go with Howse over Shanks.
+#
+# From Paul Eggert (2001-03-06):
+# Garland (1927) writes ``Cleveland and Detroit advanced their clocks
+# one hour in 1914.''  This change is not in Shanks.  We have no more
+# info, so omit this for now.
+#
+# Most of Michigan observed DST from 1973 on, but was a bit late in 1975.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Detroit	1948	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Detroit	1948	only	-	Sep	lastSun	2:00	0	S
+Rule	Detroit	1967	only	-	Jun	14	2:00	1:00	D
+Rule	Detroit	1967	only	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Detroit	-5:32:11 -	LMT	1905
+			-6:00	-	CST	1915 May 15 2:00
+			-5:00	-	EST	1942
+			-5:00	US	E%sT	1946
+			-5:00	Detroit	E%sT	1973
+			-5:00	US	E%sT	1975
+			-5:00	-	EST	1975 Apr 27 2:00
+			-5:00	US	E%sT
+#
+# Dickinson, Gogebic, Iron, and Menominee Counties, Michigan,
+# switched from EST to CST/CDT in 1973.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Menominee	1946	only	-	Apr	lastSun	2:00	1:00	D
+Rule Menominee	1946	only	-	Sep	lastSun	2:00	0	S
+Rule Menominee	1966	only	-	Apr	lastSun	2:00	1:00	D
+Rule Menominee	1966	only	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Menominee	-5:50:27 -	LMT	1885 Sep 18 12:00
+			-6:00	US	C%sT	1946
+			-6:00 Menominee	C%sT	1969 Apr 27 2:00
+			-5:00	-	EST	1973 Apr 29 2:00
+			-6:00	US	C%sT
+
+# Navassa
+# administered by the US Fish and Wildlife Service
+# claimed by US under the provisions of the 1856 Guano Islands Act
+# also claimed by Haiti
+# occupied 1857/1900 by the Navassa Phosphate Co
+# US lighthouse 1917/1996-09
+# currently uninhabited
+# see Mark Fineman, ``An Isle Rich in Guano and Discord'',
+# _Los Angeles Times_ (1998-11-10), A1, A10; it cites
+# Jimmy Skaggs, _The Great Guano Rush_ (1994).
+
+################################################################################
+
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Other sources occasionally used include:
+#
+#	Edward W. Whitman, World Time Differences,
+#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
+#	which I found in the UCLA library.
+#
+#	<a href="http://www.pettswoodvillage.co.uk/Daylight_Savings_William_Willett.pdf">
+#	William Willett, The Waste of Daylight, 19th edition
+#	</a> (1914-03)
+#
+# See the `europe' file for Greenland.
+
+# Canada
+
+# From Alain LaBont<e'> (1994-11-14):
+# I post here the time zone abbreviations standardized in Canada
+# for both English and French in the CAN/CSA-Z234.4-89 standard....
+#
+#	UTC	Standard time	Daylight savings time
+#	offset	French	English	French	English
+#	-2:30	-	-	HAT	NDT
+#	-3	-	-	HAA	ADT
+#	-3:30	HNT	NST	-	-
+#	-4	HNA	AST	HAE	EDT
+#	-5	HNE	EST	HAC	CDT
+#	-6	HNC	CST	HAR	MDT
+#	-7	HNR	MST	HAP	PDT
+#	-8	HNP	PST	HAY	YDT
+#	-9	HNY	YST	-	-
+#
+#	HN: Heure Normale	ST: Standard Time
+#	HA: Heure Avanc<e'>e	DT: Daylight saving Time
+#
+#	A: de l'Atlantique	Atlantic
+#	C: du Centre		Central
+#	E: de l'Est		Eastern
+#	M:			Mountain
+#	N:			Newfoundland
+#	P: du Pacifique		Pacific
+#	R: des Rocheuses
+#	T: de Terre-Neuve
+#	Y: du Yukon		Yukon
+#
+# From Paul Eggert (1994-11-22):
+# Alas, this sort of thing must be handled by localization software.
+
+# Unless otherwise specified, the data for Canada are all from Shanks
+# & Pottenger.
+
+# From Chris Walton (2006-04-01, 2006-04-25, 2006-06-26, 2007-01-31,
+# 2007-03-01):
+# The British Columbia government announced yesterday that it will
+# adjust daylight savings next year to align with changes in the
+# U.S. and the rest of Canada....
+# http://www2.news.gov.bc.ca/news_releases_2005-2009/2006AG0014-000330.htm
+# ...
+# Nova Scotia
+# Daylight saving time will be extended by four weeks starting in 2007....
+# http://www.gov.ns.ca/just/regulations/rg2/2006/ma1206.pdf
+#
+# [For New Brunswick] the new legislation dictates that the time change is to
+# be done at 02:00 instead of 00:01.
+# http://www.gnb.ca/0062/acts/BBA-2006/Chap-19.pdf
+# ...
+# Manitoba has traditionally changed the clock every fall at 03:00.
+# As of 2006, the transition is to take place one hour earlier at 02:00.
+# http://web2.gov.mb.ca/laws/statutes/ccsm/o030e.php
+# ...
+# [Alberta, Ontario, Quebec] will follow US rules.
+# http://www.qp.gov.ab.ca/documents/spring/CH03_06.CFM
+# http://www.e-laws.gov.on.ca/DBLaws/Source/Regs/English/2006/R06111_e.htm
+# http://www2.publicationsduquebec.gouv.qc.ca/dynamicSearch/telecharge.php?type=5&file=2006C39A.PDF
+# ...
+# P.E.I. will follow US rules....
+# http://www.assembly.pe.ca/bills/pdf_chapter/62/3/chapter-41.pdf
+# ...
+# Province of Newfoundland and Labrador....
+# http://www.hoa.gov.nl.ca/hoa/bills/Bill0634.htm
+# ...
+# Yukon
+# http://www.gov.yk.ca/legislation/regs/oic2006_127.pdf
+# ...
+# N.W.T. will follow US rules.  Whoever maintains the government web site
+# does not seem to believe in bookmarks.  To see the news release, click the
+# following link and search for "Daylight Savings Time Change".  Press the
+# "Daylight Savings Time Change" link; it will fire off a popup using
+# JavaScript.
+# http://www.exec.gov.nt.ca/currentnews/currentPR.asp?mode=archive
+# ...
+# Nunavut
+# An amendment to the Interpretation Act was registered on February 19/2007....
+# http://action.attavik.ca/home/justice-gn/attach/2007/gaz02part2.pdf
+
+# From Paul Eggert (2006-04-25):
+# H. David Matthews and Mary Vincent's map
+# <a href="http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp">
+# "It's about TIME", _Canadian Geographic_ (September-October 1998)
+# </a> contains detailed boundaries for regions observing nonstandard
+# time and daylight saving time arrangements in Canada circa 1998.
+#
+# INMS, the Institute for National Measurement Standards in Ottawa, has <a
+# href="http://inms-ienm.nrc-cnrc.gc.ca/en/time_services/daylight_saving_e.php">
+# information about standard and daylight saving time zones in Canada.
+# </a> (updated periodically).
+# Its unofficial information is often taken from Matthews and Vincent.
+
+# From Paul Eggert (2006-06-27):
+# For now, assume all of DST-observing Canada will fall into line with the
+# new US DST rules,
+
+# From Chris Walton (2011-12-01)
+# In the first of Tammy Hardwick's articles
+# <a href="http://www.ilovecreston.com/?p=articles&t=spec&ar=260">
+# http://www.ilovecreston.com/?p=articles&t=spec&ar=260
+# </a>
+# she quotes the Friday November 1/1918 edition of the Creston Review.
+# The quote includes these two statements:
+# 'Sunday the CPR went back to the old system of time...'
+# '... The daylight saving scheme was dropped all over Canada at the same time,'
+# These statements refer to a transition from daylight time to standard time
+# that occurred nationally on Sunday October 27/1918.  This transition was
+# also documented in the Saturday October 26/1918 edition of the Toronto Star.
+
+# In light of that evidence, we alter the date from the earlier believed
+# Oct 31, to Oct 27, 1918 (and Sunday is a more likely transition day
+# than Thursday) in all Canadian rulesets.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Canada	1918	only	-	Apr	14	2:00	1:00	D
+Rule	Canada	1918	only	-	Oct	27	2:00	0	S
+Rule	Canada	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Canada	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Canada	1945	only	-	Sep	30	2:00	0	S
+Rule	Canada	1974	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	Canada	1974	2006	-	Oct	lastSun	2:00	0	S
+Rule	Canada	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Canada	2007	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	Canada	2007	max	-	Nov	Sun>=1	2:00	0	S
+
+
+# Newfoundland and Labrador
+
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) write that Labrador should use NST/NDT,
+# but the only part of Labrador that follows the rules is the
+# southeast corner, including Port Hope Simpson and Mary's Harbour,
+# but excluding, say, Black Tickle.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	StJohns	1917	only	-	Apr	 8	2:00	1:00	D
+Rule	StJohns	1917	only	-	Sep	17	2:00	0	S
+# Whitman gives 1919 Apr 5 and 1920 Apr 5; go with Shanks & Pottenger.
+Rule	StJohns	1919	only	-	May	 5	23:00	1:00	D
+Rule	StJohns	1919	only	-	Aug	12	23:00	0	S
+# For 1931-1935 Whitman gives Apr same date; go with Shanks & Pottenger.
+Rule	StJohns	1920	1935	-	May	Sun>=1	23:00	1:00	D
+Rule	StJohns	1920	1935	-	Oct	lastSun	23:00	0	S
+# For 1936-1941 Whitman gives May Sun>=8 and Oct Sun>=1; go with Shanks &
+# Pottenger.
+Rule	StJohns	1936	1941	-	May	Mon>=9	0:00	1:00	D
+Rule	StJohns	1936	1941	-	Oct	Mon>=2	0:00	0	S
+# Whitman gives the following transitions:
+# 1942 03-01/12-31, 1943 05-30/09-05, 1944 07-10/09-02, 1945 01-01/10-07
+# but go with Shanks & Pottenger and assume they used Canadian rules.
+# For 1946-9 Whitman gives May 5,4,9,1 - Oct 1,5,3,2, and for 1950 he gives
+# Apr 30 - Sep 24; go with Shanks & Pottenger.
+Rule	StJohns	1946	1950	-	May	Sun>=8	2:00	1:00	D
+Rule	StJohns	1946	1950	-	Oct	Sun>=2	2:00	0	S
+Rule	StJohns	1951	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	StJohns	1951	1959	-	Sep	lastSun	2:00	0	S
+Rule	StJohns	1960	1986	-	Oct	lastSun	2:00	0	S
+# From Paul Eggert (2000-10-02):
+# INMS (2000-09-12) says that, since 1988 at least, Newfoundland switches
+# at 00:01 local time.  For now, assume it started in 1987.
+
+# From Michael Pelley (2011-09-12):
+# We received today, Monday, September 12, 2011, notification that the
+# changes to the Newfoundland Standard Time Act have been proclaimed.
+# The change in the Act stipulates that the change from Daylight Savings
+# Time to Standard Time and from Standard Time to Daylight Savings Time
+# now occurs at 2:00AM.
+# ...
+# <a href="http://www.assembly.nl.ca/legislation/sr/annualstatutes/2011/1106.chp.htm">
+# http://www.assembly.nl.ca/legislation/sr/annualstatutes/2011/1106.chp.htm
+# </a>
+# ...
+# MICHAEL PELLEY  |  Manager of Enterprise Architecture - Solution Delivery
+# Office of the Chief Information Officer
+# Executive Council
+# Government of Newfoundland & Labrador
+
+Rule	StJohns	1987	only	-	Apr	Sun>=1	0:01	1:00	D
+Rule	StJohns	1987	2006	-	Oct	lastSun	0:01	0	S
+Rule	StJohns	1988	only	-	Apr	Sun>=1	0:01	2:00	DD
+Rule	StJohns	1989	2006	-	Apr	Sun>=1	0:01	1:00	D
+Rule	StJohns	2007	2011	-	Mar	Sun>=8	0:01	1:00	D
+Rule	StJohns	2007	2010	-	Nov	Sun>=1	0:01	0	S
+#
+# St John's has an apostrophe, but Posix file names can't have apostrophes.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Johns	-3:30:52 -	LMT	1884
+			-3:30:52 StJohns N%sT	1918
+			-3:30:52 Canada	N%sT	1919
+			-3:30:52 StJohns N%sT	1935 Mar 30
+			-3:30	StJohns	N%sT	1942 May 11
+			-3:30	Canada	N%sT	1946
+			-3:30	StJohns	N%sT	2011 Nov
+			-3:30	Canada	N%sT
+
+# most of east Labrador
+
+# The name `Happy Valley-Goose Bay' is too long; use `Goose Bay'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Goose_Bay	-4:01:40 -	LMT	1884 # Happy Valley-Goose Bay
+			-3:30:52 -	NST	1918
+			-3:30:52 Canada N%sT	1919
+			-3:30:52 -	NST	1935 Mar 30
+			-3:30	-	NST	1936
+			-3:30	StJohns	N%sT	1942 May 11
+			-3:30	Canada	N%sT	1946
+			-3:30	StJohns	N%sT	1966 Mar 15 2:00
+			-4:00	StJohns	A%sT	2011 Nov
+			-4:00	Canada	A%sT
+
+
+# west Labrador, Nova Scotia, Prince Edward I
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that since 1970 most of this region has been like
+# Halifax.  Many locales did not observe peacetime DST until 1972;
+# Glace Bay, NS is the largest that we know of.
+# Shanks & Pottenger also write that Liverpool, NS was the only town
+# in Canada to observe DST in 1971 but not 1970; for now we'll assume
+# this is a typo.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Halifax	1916	only	-	Apr	 1	0:00	1:00	D
+Rule	Halifax	1916	only	-	Oct	 1	0:00	0	S
+Rule	Halifax	1920	only	-	May	 9	0:00	1:00	D
+Rule	Halifax	1920	only	-	Aug	29	0:00	0	S
+Rule	Halifax	1921	only	-	May	 6	0:00	1:00	D
+Rule	Halifax	1921	1922	-	Sep	 5	0:00	0	S
+Rule	Halifax	1922	only	-	Apr	30	0:00	1:00	D
+Rule	Halifax	1923	1925	-	May	Sun>=1	0:00	1:00	D
+Rule	Halifax	1923	only	-	Sep	 4	0:00	0	S
+Rule	Halifax	1924	only	-	Sep	15	0:00	0	S
+Rule	Halifax	1925	only	-	Sep	28	0:00	0	S
+Rule	Halifax	1926	only	-	May	16	0:00	1:00	D
+Rule	Halifax	1926	only	-	Sep	13	0:00	0	S
+Rule	Halifax	1927	only	-	May	 1	0:00	1:00	D
+Rule	Halifax	1927	only	-	Sep	26	0:00	0	S
+Rule	Halifax	1928	1931	-	May	Sun>=8	0:00	1:00	D
+Rule	Halifax	1928	only	-	Sep	 9	0:00	0	S
+Rule	Halifax	1929	only	-	Sep	 3	0:00	0	S
+Rule	Halifax	1930	only	-	Sep	15	0:00	0	S
+Rule	Halifax	1931	1932	-	Sep	Mon>=24	0:00	0	S
+Rule	Halifax	1932	only	-	May	 1	0:00	1:00	D
+Rule	Halifax	1933	only	-	Apr	30	0:00	1:00	D
+Rule	Halifax	1933	only	-	Oct	 2	0:00	0	S
+Rule	Halifax	1934	only	-	May	20	0:00	1:00	D
+Rule	Halifax	1934	only	-	Sep	16	0:00	0	S
+Rule	Halifax	1935	only	-	Jun	 2	0:00	1:00	D
+Rule	Halifax	1935	only	-	Sep	30	0:00	0	S
+Rule	Halifax	1936	only	-	Jun	 1	0:00	1:00	D
+Rule	Halifax	1936	only	-	Sep	14	0:00	0	S
+Rule	Halifax	1937	1938	-	May	Sun>=1	0:00	1:00	D
+Rule	Halifax	1937	1941	-	Sep	Mon>=24	0:00	0	S
+Rule	Halifax	1939	only	-	May	28	0:00	1:00	D
+Rule	Halifax	1940	1941	-	May	Sun>=1	0:00	1:00	D
+Rule	Halifax	1946	1949	-	Apr	lastSun	2:00	1:00	D
+Rule	Halifax	1946	1949	-	Sep	lastSun	2:00	0	S
+Rule	Halifax	1951	1954	-	Apr	lastSun	2:00	1:00	D
+Rule	Halifax	1951	1954	-	Sep	lastSun	2:00	0	S
+Rule	Halifax	1956	1959	-	Apr	lastSun	2:00	1:00	D
+Rule	Halifax	1956	1959	-	Sep	lastSun	2:00	0	S
+Rule	Halifax	1962	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	Halifax	1962	1973	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Halifax	-4:14:24 -	LMT	1902 Jun 15
+			-4:00	Halifax	A%sT	1918
+			-4:00	Canada	A%sT	1919
+			-4:00	Halifax	A%sT	1942 Feb  9 2:00s
+			-4:00	Canada	A%sT	1946
+			-4:00	Halifax	A%sT	1974
+			-4:00	Canada	A%sT
+Zone America/Glace_Bay	-3:59:48 -	LMT	1902 Jun 15
+			-4:00	Canada	A%sT	1953
+			-4:00	Halifax	A%sT	1954
+			-4:00	-	AST	1972
+			-4:00	Halifax	A%sT	1974
+			-4:00	Canada	A%sT
+
+# New Brunswick
+
+# From Paul Eggert (2007-01-31):
+# The Time Definition Act <http://www.gnb.ca/0062/PDF-acts/t-06.pdf>
+# says they changed at 00:01 through 2006, and
+# <http://www.canlii.org/nb/laws/sta/t-6/20030127/whole.html> makes it
+# clear that this was the case since at least 1993.
+# For now, assume it started in 1993.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Moncton	1933	1935	-	Jun	Sun>=8	1:00	1:00	D
+Rule	Moncton	1933	1935	-	Sep	Sun>=8	1:00	0	S
+Rule	Moncton	1936	1938	-	Jun	Sun>=1	1:00	1:00	D
+Rule	Moncton	1936	1938	-	Sep	Sun>=1	1:00	0	S
+Rule	Moncton	1939	only	-	May	27	1:00	1:00	D
+Rule	Moncton	1939	1941	-	Sep	Sat>=21	1:00	0	S
+Rule	Moncton	1940	only	-	May	19	1:00	1:00	D
+Rule	Moncton	1941	only	-	May	 4	1:00	1:00	D
+Rule	Moncton	1946	1972	-	Apr	lastSun	2:00	1:00	D
+Rule	Moncton	1946	1956	-	Sep	lastSun	2:00	0	S
+Rule	Moncton	1957	1972	-	Oct	lastSun	2:00	0	S
+Rule	Moncton	1993	2006	-	Apr	Sun>=1	0:01	1:00	D
+Rule	Moncton	1993	2006	-	Oct	lastSun	0:01	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Moncton	-4:19:08 -	LMT	1883 Dec  9
+			-5:00	-	EST	1902 Jun 15
+			-4:00	Canada	A%sT	1933
+			-4:00	Moncton	A%sT	1942
+			-4:00	Canada	A%sT	1946
+			-4:00	Moncton	A%sT	1973
+			-4:00	Canada	A%sT	1993
+			-4:00	Moncton	A%sT	2007
+			-4:00	Canada	A%sT
+
+# Quebec
+
+# From Paul Eggert (2006-07-09):
+# Shanks & Pottenger write that since 1970 most of Quebec has been
+# like Montreal.
+
+# From Paul Eggert (2006-06-27):
+# Matthews and Vincent (1998) also write that Quebec east of the -63
+# meridian is supposed to observe AST, but residents as far east as
+# Natashquan use EST/EDT, and residents east of Natashquan use AST.
+# In "Official time in Quebec" the Quebec department of justice writes in
+# http://www.justice.gouv.qc.ca/english/publications/generale/temps-regl-1-a.htm
+# that "The residents of the Municipality of the
+# Cote-Nord-du-Golfe-Saint-Laurent and the municipalities of Saint-Augustin,
+# Bonne-Esperance and Blanc-Sablon apply the Official Time Act as it is
+# written and use Atlantic standard time all year round. The same applies to
+# the residents of the Native facilities along the lower North Shore."
+# <http://www.assnat.qc.ca/eng/37legislature2/Projets-loi/Publics/06-a002.htm>
+# says this common practice was codified into law as of 2007.
+# For lack of better info, guess this practice began around 1970, contra to
+# Shanks & Pottenger who have this region observing AST/ADT.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Mont	1917	only	-	Mar	25	2:00	1:00	D
+Rule	Mont	1917	only	-	Apr	24	0:00	0	S
+Rule	Mont	1919	only	-	Mar	31	2:30	1:00	D
+Rule	Mont	1919	only	-	Oct	25	2:30	0	S
+Rule	Mont	1920	only	-	May	 2	2:30	1:00	D
+Rule	Mont	1920	1922	-	Oct	Sun>=1	2:30	0	S
+Rule	Mont	1921	only	-	May	 1	2:00	1:00	D
+Rule	Mont	1922	only	-	Apr	30	2:00	1:00	D
+Rule	Mont	1924	only	-	May	17	2:00	1:00	D
+Rule	Mont	1924	1926	-	Sep	lastSun	2:30	0	S
+Rule	Mont	1925	1926	-	May	Sun>=1	2:00	1:00	D
+# The 1927-to-1937 rules can be expressed more simply as
+# Rule	Mont	1927	1937	-	Apr	lastSat	24:00	1:00	D
+# Rule	Mont	1927	1937	-	Sep	lastSat	24:00	0	S
+# The rules below avoid use of 24:00
+# (which pre-1998 versions of zic cannot handle).
+Rule	Mont	1927	only	-	May	1	0:00	1:00	D
+Rule	Mont	1927	1932	-	Sep	lastSun	0:00	0	S
+Rule	Mont	1928	1931	-	Apr	lastSun	0:00	1:00	D
+Rule	Mont	1932	only	-	May	1	0:00	1:00	D
+Rule	Mont	1933	1940	-	Apr	lastSun	0:00	1:00	D
+Rule	Mont	1933	only	-	Oct	1	0:00	0	S
+Rule	Mont	1934	1939	-	Sep	lastSun	0:00	0	S
+Rule	Mont	1946	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	Mont	1945	1948	-	Sep	lastSun	2:00	0	S
+Rule	Mont	1949	1950	-	Oct	lastSun	2:00	0	S
+Rule	Mont	1951	1956	-	Sep	lastSun	2:00	0	S
+Rule	Mont	1957	1973	-	Oct	lastSun	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Blanc-Sablon -3:48:28 -	LMT	1884
+			-4:00	Canada	A%sT	1970
+			-4:00	-	AST
+Zone America/Montreal	-4:54:16 -	LMT	1884
+			-5:00	Mont	E%sT	1918
+			-5:00	Canada	E%sT	1919
+			-5:00	Mont	E%sT	1942 Feb  9 2:00s
+			-5:00	Canada	E%sT	1946
+			-5:00	Mont	E%sT	1974
+			-5:00	Canada	E%sT
+
+
+# Ontario
+
+# From Paul Eggert (2006-07-09):
+# Shanks & Pottenger write that since 1970 most of Ontario has been like
+# Toronto.
+# Thunder Bay skipped DST in 1973.
+# Many smaller locales did not observe peacetime DST until 1974;
+# Nipigon (EST) and Rainy River (CST) are the largest that we know of.
+# Far west Ontario is like Winnipeg; far east Quebec is like Halifax.
+
+# From Mark Brader (2003-07-26):
+# [According to the Toronto Star] Orillia, Ontario, adopted DST
+# effective Saturday, 1912-06-22, 22:00; the article mentions that
+# Port Arthur (now part of Thunder Bay, Ontario) as well as Moose Jaw
+# have already done so.  In Orillia DST was to run until Saturday,
+# 1912-08-31 (no time mentioned), but it was met with considerable
+# hostility from certain segments of the public, and was revoked after
+# only two weeks -- I copied it as Saturday, 1912-07-07, 22:00, but
+# presumably that should be -07-06.  (1912-06-19, -07-12; also letters
+# earlier in June).
+#
+# Kenora, Ontario, was to abandon DST on 1914-06-01 (-05-21).
+
+# From Paul Eggert (1997-10-17):
+# Mark Brader writes that an article in the 1997-10-14 Toronto Star
+# says that Atikokan, Ontario currently does not observe DST,
+# but will vote on 11-10 whether to use EST/EDT.
+# He also writes that the
+# <a href="http://www.gov.on.ca/MBS/english/publications/statregs/conttext.html">
+# Ontario Time Act (1990, Chapter T.9)
+# </a>
+# says that Ontario east of 90W uses EST/EDT, and west of 90W uses CST/CDT.
+# Officially Atikokan is therefore on CST/CDT, and most likely this report
+# concerns a non-official time observed as a matter of local practice.
+#
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) write that Atikokan, Pickle Lake, and
+# New Osnaburgh observe CST all year, that Big Trout Lake observes
+# CST/CDT, and that Upsala and Shebandowan observe EST/EDT, all in
+# violation of the official Ontario rules.
+#
+# From Paul Eggert (2006-07-09):
+# Chris Walton (2006-07-06) mentioned an article by Stephanie MacLellan in the
+# 2005-07-21 Chronicle-Journal, which said:
+#
+#	The clocks in Atikokan stay set on standard time year-round.
+#	This means they spend about half the time on central time and
+#	the other half on eastern time.
+#
+#	For the most part, the system works, Mayor Dennis Brown said.
+#
+#	"The majority of businesses in Atikokan deal more with Eastern
+#	Canada, but there are some that deal with Western Canada," he
+#	said.  "I don't see any changes happening here."
+#
+# Walton also writes "Supposedly Pickle Lake and Mishkeegogamang
+# [New Osnaburgh] follow the same practice."
+
+# From Garry McKinnon (2006-07-14) via Chris Walton:
+# I chatted with a member of my board who has an outstanding memory
+# and a long history in Atikokan (and in the telecom industry) and he
+# can say for certain that Atikokan has been practicing the current
+# time keeping since 1952, at least.
+
+# From Paul Eggert (2006-07-17):
+# Shanks & Pottenger say that Atikokan has agreed with Rainy River
+# ever since standard time was introduced, but the information from
+# McKinnon sounds more authoritative.  For now, assume that Atikokan
+# switched to EST immediately after WWII era daylight saving time
+# ended.  This matches the old (less-populous) America/Coral_Harbour
+# entry since our cutoff date of 1970, so we can move
+# America/Coral_Harbour to the 'backward' file.
+
+# From Mark Brader (2010-03-06):
+#
+# Currently the database has:
+#
+# # Ontario
+#
+# # From Paul Eggert (2006-07-09):
+# # Shanks & Pottenger write that since 1970 most of Ontario has been like
+# # Toronto.
+# # Thunder Bay skipped DST in 1973.
+# # Many smaller locales did not observe peacetime DST until 1974;
+# # Nipigon (EST) and Rainy River (CST) are the largest that we know of.
+#
+# In the (Toronto) Globe and Mail for Saturday, 1955-09-24, in the bottom
+# right corner of page 1, it says that Toronto will return to standard
+# time at 2 am Sunday morning (which agrees with the database), and that:
+#
+#     The one-hour setback will go into effect throughout most of Ontario,
+#     except in areas like Windsor which remains on standard time all year.
+#
+# Windsor is, of course, a lot larger than Nipigon.
+#
+# I only came across this incidentally.  I don't know if Windsor began
+# observing DST when Detroit did, or in 1974, or on some other date.
+#
+# By the way, the article continues by noting that:
+#
+#     Some cities in the United States have pushed the deadline back
+#     three weeks and will change over from daylight saving in October.
+
+# From Arthur David Olson (2010-07-17):
+#
+# "Standard Time and Time Zones in Canada" appeared in
+# The Journal of The Royal Astronomical Society of Canada,
+# volume 26, number 2 (February 1932) and, as of 2010-07-17,
+# was available at
+# <a href="http://adsabs.harvard.edu/full/1932JRASC..26...49S">
+# http://adsabs.harvard.edu/full/1932JRASC..26...49S
+# </a>
+#
+# It includes the text below (starting on page 57):
+#
+#   A list of the places in Canada using daylight saving time would
+# require yearly revision. From information kindly furnished by
+# the provincial governments and by the postmasters in many cities
+# and towns, it is found that the following places used daylight sav-
+# ing in 1930. The information for the province of Quebec is definite,
+# for the other provinces only approximate:
+#
+# 	Province	Daylight saving time used
+# Prince Edward Island	Not used.
+# Nova Scotia		In Halifax only.
+# New Brunswick		In St. John only.
+# Quebec		In the following places:
+# 			Montreal	Lachine
+# 			Quebec		Mont-Royal
+# 			Levis		Iberville
+# 			St. Lambert	Cap de la Madeleine
+# 			Verdun		Loretteville
+# 			Westmount	Richmond
+# 			Outremont	St. Jerome
+# 			Longueuil	Greenfield Park
+# 			Arvida		Waterloo
+# 			Chambly-Canton	Beaulieu
+# 			Melbourne	La Tuque
+# 			St. Theophile	Buckingham
+# Ontario		Used generally in the cities and towns along
+# 			the southerly part of the province. Not
+# 			used in the northwesterlhy part.
+# Manitoba		Not used.
+# Saskatchewan		In Regina only.
+# Alberta		Not used.
+# British Columbia	Not used.
+#
+#   With some exceptions, the use of daylight saving may be said to be limited
+# to those cities and towns lying between Quebec city and Windsor, Ont.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Toronto	1919	only	-	Mar	30	23:30	1:00	D
+Rule	Toronto	1919	only	-	Oct	26	0:00	0	S
+Rule	Toronto	1920	only	-	May	 2	2:00	1:00	D
+Rule	Toronto	1920	only	-	Sep	26	0:00	0	S
+Rule	Toronto	1921	only	-	May	15	2:00	1:00	D
+Rule	Toronto	1921	only	-	Sep	15	2:00	0	S
+Rule	Toronto	1922	1923	-	May	Sun>=8	2:00	1:00	D
+# Shanks & Pottenger say 1923-09-19; assume it's a typo and that "-16"
+# was meant.
+Rule	Toronto	1922	1926	-	Sep	Sun>=15	2:00	0	S
+Rule	Toronto	1924	1927	-	May	Sun>=1	2:00	1:00	D
+# The 1927-to-1939 rules can be expressed more simply as
+# Rule	Toronto	1927	1937	-	Sep	Sun>=25	2:00	0	S
+# Rule	Toronto	1928	1937	-	Apr	Sun>=25	2:00	1:00	D
+# Rule	Toronto	1938	1940	-	Apr	lastSun	2:00	1:00	D
+# Rule	Toronto	1938	1939	-	Sep	lastSun	2:00	0	S
+# The rules below avoid use of Sun>=25
+# (which pre-2004 versions of zic cannot handle).
+Rule	Toronto	1927	1932	-	Sep	lastSun	2:00	0	S
+Rule	Toronto	1928	1931	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1932	only	-	May	1	2:00	1:00	D
+Rule	Toronto	1933	1940	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1933	only	-	Oct	1	2:00	0	S
+Rule	Toronto	1934	1939	-	Sep	lastSun	2:00	0	S
+Rule	Toronto	1945	1946	-	Sep	lastSun	2:00	0	S
+Rule	Toronto	1946	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1947	1949	-	Apr	lastSun	0:00	1:00	D
+Rule	Toronto	1947	1948	-	Sep	lastSun	0:00	0	S
+Rule	Toronto	1949	only	-	Nov	lastSun	0:00	0	S
+Rule	Toronto	1950	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1950	only	-	Nov	lastSun	2:00	0	S
+Rule	Toronto	1951	1956	-	Sep	lastSun	2:00	0	S
+# Shanks & Pottenger say Toronto ended DST a week early in 1971,
+# namely on 1971-10-24, but Mark Brader wrote (2003-05-31) that this
+# is wrong, and that he had confirmed it by checking the 1971-10-30
+# Toronto Star, which said that DST was ending 1971-10-31 as usual.
+Rule	Toronto	1957	1973	-	Oct	lastSun	2:00	0	S
+
+# From Paul Eggert (2003-07-27):
+# Willett (1914-03) writes (p. 17) "In the Cities of Fort William, and
+# Port Arthur, Ontario, the principle of the Bill has been in
+# operation for the past three years, and in the City of Moose Jaw,
+# Saskatchewan, for one year."
+
+# From David Bryan via Tory Tronrud, Director/Curator,
+# Thunder Bay Museum (2003-11-12):
+# There is some suggestion, however, that, by-law or not, daylight
+# savings time was being practiced in Fort William and Port Arthur
+# before 1909.... [I]n 1910, the line between the Eastern and Central
+# Time Zones was permanently moved about two hundred miles west to
+# include the Thunder Bay area....  When Canada adopted daylight
+# savings time in 1916, Fort William and Port Arthur, having done so
+# already, did not change their clocks....  During the Second World
+# War,... [t]he cities agreed to implement DST during the summer
+# months for the remainder of the war years.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Toronto	-5:17:32 -	LMT	1895
+			-5:00	Canada	E%sT	1919
+			-5:00	Toronto	E%sT	1942 Feb  9 2:00s
+			-5:00	Canada	E%sT	1946
+			-5:00	Toronto	E%sT	1974
+			-5:00	Canada	E%sT
+Zone America/Thunder_Bay -5:57:00 -	LMT	1895
+			-6:00	-	CST	1910
+			-5:00	-	EST	1942
+			-5:00	Canada	E%sT	1970
+			-5:00	Mont	E%sT	1973
+			-5:00	-	EST	1974
+			-5:00	Canada	E%sT
+Zone America/Nipigon	-5:53:04 -	LMT	1895
+			-5:00	Canada	E%sT	1940 Sep 29
+			-5:00	1:00	EDT	1942 Feb  9 2:00s
+			-5:00	Canada	E%sT
+Zone America/Rainy_River -6:18:16 -	LMT	1895
+			-6:00	Canada	C%sT	1940 Sep 29
+			-6:00	1:00	CDT	1942 Feb  9 2:00s
+			-6:00	Canada	C%sT
+Zone America/Atikokan	-6:06:28 -	LMT	1895
+			-6:00	Canada	C%sT	1940 Sep 29
+			-6:00	1:00	CDT	1942 Feb  9 2:00s
+			-6:00	Canada	C%sT	1945 Sep 30 2:00
+			-5:00	-	EST
+
+
+# Manitoba
+
+# From Rob Douglas (2006-04-06):
+# the old Manitoba Time Act - as amended by Bill 2, assented to
+# March 27, 1987 ... said ...
+# "between two o'clock Central Standard Time in the morning of
+# the first Sunday of April of each year and two o'clock Central
+# Standard Time in the morning of the last Sunday of October next
+# following, one hour in advance of Central Standard Time."...
+# I believe that the English legislation [of the old time act] had =
+# been assented to (March 22, 1967)....
+# Also, as far as I can tell, there was no order-in-council varying
+# the time of Daylight Saving Time for 2005 and so the provisions of
+# the 1987 version would apply - the changeover was at 2:00 Central
+# Standard Time (i.e. not until 3:00 Central Daylight Time).
+
+# From Paul Eggert (2006-04-10):
+# Shanks & Pottenger say Manitoba switched at 02:00 (not 02:00s)
+# starting 1966.  Since 02:00s is clearly correct for 1967 on, assume
+# it was also 02:00s in 1966.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Winn	1916	only	-	Apr	23	0:00	1:00	D
+Rule	Winn	1916	only	-	Sep	17	0:00	0	S
+Rule	Winn	1918	only	-	Apr	14	2:00	1:00	D
+Rule	Winn	1918	only	-	Oct	27	2:00	0	S
+Rule	Winn	1937	only	-	May	16	2:00	1:00	D
+Rule	Winn	1937	only	-	Sep	26	2:00	0	S
+Rule	Winn	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Winn	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Winn	1945	only	-	Sep	lastSun	2:00	0	S
+Rule	Winn	1946	only	-	May	12	2:00	1:00	D
+Rule	Winn	1946	only	-	Oct	13	2:00	0	S
+Rule	Winn	1947	1949	-	Apr	lastSun	2:00	1:00	D
+Rule	Winn	1947	1949	-	Sep	lastSun	2:00	0	S
+Rule	Winn	1950	only	-	May	 1	2:00	1:00	D
+Rule	Winn	1950	only	-	Sep	30	2:00	0	S
+Rule	Winn	1951	1960	-	Apr	lastSun	2:00	1:00	D
+Rule	Winn	1951	1958	-	Sep	lastSun	2:00	0	S
+Rule	Winn	1959	only	-	Oct	lastSun	2:00	0	S
+Rule	Winn	1960	only	-	Sep	lastSun	2:00	0	S
+Rule	Winn	1963	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Winn	1963	only	-	Sep	22	2:00	0	S
+Rule	Winn	1966	1986	-	Apr	lastSun	2:00s	1:00	D
+Rule	Winn	1966	2005	-	Oct	lastSun	2:00s	0	S
+Rule	Winn	1987	2005	-	Apr	Sun>=1	2:00s	1:00	D
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Winnipeg	-6:28:36 -	LMT	1887 Jul 16
+			-6:00	Winn	C%sT	2006
+			-6:00	Canada	C%sT
+
+
+# Saskatchewan
+
+# From Mark Brader (2003-07-26):
+# The first actual adoption of DST in Canada was at the municipal
+# level.  As the [Toronto] Star put it (1912-06-07), "While people
+# elsewhere have long been talking of legislation to save daylight,
+# the city of Moose Jaw [Saskatchewan] has acted on its own hook."
+# DST in Moose Jaw began on Saturday, 1912-06-01 (no time mentioned:
+# presumably late evening, as below), and would run until "the end of
+# the summer".  The discrepancy between municipal time and railroad
+# time was noted.
+
+# From Paul Eggert (2003-07-27):
+# Willett (1914-03) notes that DST "has been in operation ... in the
+# City of Moose Jaw, Saskatchewan, for one year."
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say that since 1970 this region has mostly been as Regina.
+# Some western towns (e.g. Swift Current) switched from MST/MDT to CST in 1972.
+# Other western towns (e.g. Lloydminster) are like Edmonton.
+# Matthews and Vincent (1998) write that Denare Beach and Creighton
+# are like Winnipeg, in violation of Saskatchewan law.
+
+# From W. Jones (1992-11-06):
+# The. . .below is based on information I got from our law library, the
+# provincial archives, and the provincial Community Services department.
+# A precise history would require digging through newspaper archives, and
+# since you didn't say what you wanted, I didn't bother.
+#
+# Saskatchewan is split by a time zone meridian (105W) and over the years
+# the boundary became pretty ragged as communities near it reevaluated
+# their affiliations in one direction or the other.  In 1965 a provincial
+# referendum favoured legislating common time practices.
+#
+# On 15 April 1966 the Time Act (c. T-14, Revised Statutes of
+# Saskatchewan 1978) was proclaimed, and established that the eastern
+# part of Saskatchewan would use CST year round, that districts in
+# northwest Saskatchewan would by default follow CST but could opt to
+# follow Mountain Time rules (thus 1 hour difference in the winter and
+# zero in the summer), and that districts in southwest Saskatchewan would
+# by default follow MT but could opt to follow CST.
+#
+# It took a few years for the dust to settle (I know one story of a town
+# on one time zone having its school in another, such that a mom had to
+# serve her family lunch in two shifts), but presently it seems that only
+# a few towns on the border with Alberta (e.g. Lloydminster) follow MT
+# rules any more; all other districts appear to have used CST year round
+# since sometime in the 1960s.
+
+# From Chris Walton (2006-06-26):
+# The Saskatchewan time act which was last updated in 1996 is about 30 pages
+# long and rather painful to read.
+# http://www.qp.gov.sk.ca/documents/English/Statutes/Statutes/T14.pdf
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Regina	1918	only	-	Apr	14	2:00	1:00	D
+Rule	Regina	1918	only	-	Oct	27	2:00	0	S
+Rule	Regina	1930	1934	-	May	Sun>=1	0:00	1:00	D
+Rule	Regina	1930	1934	-	Oct	Sun>=1	0:00	0	S
+Rule	Regina	1937	1941	-	Apr	Sun>=8	0:00	1:00	D
+Rule	Regina	1937	only	-	Oct	Sun>=8	0:00	0	S
+Rule	Regina	1938	only	-	Oct	Sun>=1	0:00	0	S
+Rule	Regina	1939	1941	-	Oct	Sun>=8	0:00	0	S
+Rule	Regina	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Regina	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Regina	1945	only	-	Sep	lastSun	2:00	0	S
+Rule	Regina	1946	only	-	Apr	Sun>=8	2:00	1:00	D
+Rule	Regina	1946	only	-	Oct	Sun>=8	2:00	0	S
+Rule	Regina	1947	1957	-	Apr	lastSun	2:00	1:00	D
+Rule	Regina	1947	1957	-	Sep	lastSun	2:00	0	S
+Rule	Regina	1959	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Regina	1959	only	-	Oct	lastSun	2:00	0	S
+#
+Rule	Swift	1957	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Swift	1957	only	-	Oct	lastSun	2:00	0	S
+Rule	Swift	1959	1961	-	Apr	lastSun	2:00	1:00	D
+Rule	Swift	1959	only	-	Oct	lastSun	2:00	0	S
+Rule	Swift	1960	1961	-	Sep	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Regina	-6:58:36 -	LMT	1905 Sep
+			-7:00	Regina	M%sT	1960 Apr lastSun 2:00
+			-6:00	-	CST
+Zone America/Swift_Current -7:11:20 -	LMT	1905 Sep
+			-7:00	Canada	M%sT	1946 Apr lastSun 2:00
+			-7:00	Regina	M%sT	1950
+			-7:00	Swift	M%sT	1972 Apr lastSun 2:00
+			-6:00	-	CST
+
+
+# Alberta
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Edm	1918	1919	-	Apr	Sun>=8	2:00	1:00	D
+Rule	Edm	1918	only	-	Oct	27	2:00	0	S
+Rule	Edm	1919	only	-	May	27	2:00	0	S
+Rule	Edm	1920	1923	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1920	only	-	Oct	lastSun	2:00	0	S
+Rule	Edm	1921	1923	-	Sep	lastSun	2:00	0	S
+Rule	Edm	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Edm	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Edm	1945	only	-	Sep	lastSun	2:00	0	S
+Rule	Edm	1947	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1947	only	-	Sep	lastSun	2:00	0	S
+Rule	Edm	1967	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1967	only	-	Oct	lastSun	2:00	0	S
+Rule	Edm	1969	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1969	only	-	Oct	lastSun	2:00	0	S
+Rule	Edm	1972	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1972	2006	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Edmonton	-7:33:52 -	LMT	1906 Sep
+			-7:00	Edm	M%sT	1987
+			-7:00	Canada	M%sT
+
+
+# British Columbia
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that since 1970 most of this region has
+# been like Vancouver.
+# Dawson Creek uses MST.  Much of east BC is like Edmonton.
+# Matthews and Vincent (1998) write that Creston is like Dawson Creek.
+
+# It seems though that (re: Creston) is not entirely correct:
+
+# From Chris Walton (2011-12-01):
+# There are two areas within the Canadian province of British Columbia
+# that do not currently observe daylight saving:
+# a) The Creston Valley (includes the town of Creston and surrounding area)
+# b) The eastern half of the Peace River Regional District
+# (includes the cities of Dawson Creek and Fort St. John)
+
+# Earlier this year I stumbled across a detailed article about the time
+# keeping history of Creston; it was written by Tammy Hardwick who is the
+# manager of the Creston & District Museum. The article was written in May 2009.
+# <a href="http://www.ilovecreston.com/?p=articles&t=spec&ar=260">
+# http://www.ilovecreston.com/?p=articles&t=spec&ar=260
+# </a>
+# According to the article, Creston has not changed its clocks since June 1918.
+# i.e. Creston has been stuck on UTC-7 for 93 years.
+# Dawson Creek, on the other hand, changed its clocks as recently as April 1972.
+
+# Unfortunately the exact date for the time change in June 1918 remains
+# unknown and will be difficult to ascertain.  I e-mailed Tammy a few months
+# ago to ask if Sunday June 2 was a reasonable guess.  She said it was just
+# as plausible as any other date (in June).  She also said that after writing the
+# article she had discovered another time change in 1916; this is the subject
+# of another article which she wrote in October 2010.
+# <a href="http://www.creston.museum.bc.ca/index.php?module=comments&uop=view_comment&cm+id=56">
+# http://www.creston.museum.bc.ca/index.php?module=comments&uop=view_comment&cm+id=56
+# </a>
+
+# Here is a summary of the three clock change events in Creston's history:
+# 1. 1884 or 1885: adoption of Mountain Standard Time (GMT-7)
+# Exact date unknown
+# 2. Oct 1916: switch to Pacific Standard Time (GMT-8)
+# Exact date in October unknown;  Sunday October 1 is a reasonable guess.
+# 3. June 1918: switch to Pacific Daylight Time (GMT-7)
+# Exact date in June unknown; Sunday June 2 is a reasonable guess.
+# note#1:
+# On Oct 27/1918 when daylight saving ended in the rest of Canada,
+# Creston did not change its clocks.
+# note#2:
+# During WWII when the Federal Government legislated a mandatory clock change,
+# Creston did not oblige.
+# note#3:
+# There is no guarantee that Creston will remain on Mountain Standard Time
+# (UTC-7) forever.
+# The subject was debated at least once this year by the town Council.
+# <a href="http://www.bclocalnews.com/kootenay_rockies/crestonvalleyadvance/news/116760809.html">
+# http://www.bclocalnews.com/kootenay_rockies/crestonvalleyadvance/news/116760809.html
+# </a>
+
+# During a period WWII, summer time (Daylight saying) was mandatory in Canada.
+# In Creston, that was handled by shifting the area to PST (-8:00) then applying
+# summer time to cause the offset to be -7:00, the same as it had been before
+# the change.  It can be argued that the timezone abbreviation during this
+# period should be PDT rather than MST, but that doesn't seem important enough
+# (to anyone) to further complicate the rules.
+
+# The transition dates (and times) are guesses.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Vanc	1918	only	-	Apr	14	2:00	1:00	D
+Rule	Vanc	1918	only	-	Oct	27	2:00	0	S
+Rule	Vanc	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Vanc	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Vanc	1945	only	-	Sep	30	2:00	0	S
+Rule	Vanc	1946	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	Vanc	1946	only	-	Oct	13	2:00	0	S
+Rule	Vanc	1947	1961	-	Sep	lastSun	2:00	0	S
+Rule	Vanc	1962	2006	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Vancouver	-8:12:28 -	LMT	1884
+			-8:00	Vanc	P%sT	1987
+			-8:00	Canada	P%sT
+Zone America/Dawson_Creek -8:00:56 -	LMT	1884
+			-8:00	Canada	P%sT	1947
+			-8:00	Vanc	P%sT	1972 Aug 30 2:00
+			-7:00	-	MST
+Zone America/Creston	-7:46:04 -	LMT	1884
+			-7:00	-	MST	1916 Oct 1
+			-8:00	-	PST	1918 Jun 2
+			-7:00	-	MST
+
+# Northwest Territories, Nunavut, Yukon
+
+# From Paul Eggert (2006-03-22):
+# Dawson switched to PST in 1973.  Inuvik switched to MST in 1979.
+# Mathew Englander (1996-10-07) gives the following refs:
+#	* 1967. Paragraph 28(34)(g) of the Interpretation Act, S.C. 1967-68,
+#	c. 7 defines Yukon standard time as UTC-9.  This is still valid;
+#	see Interpretation Act, R.S.C. 1985, c. I-21, s. 35(1).
+#	* C.O. 1973/214 switched Yukon to PST on 1973-10-28 00:00.
+#	* O.I.C. 1980/02 established DST.
+#	* O.I.C. 1987/056 changed DST to Apr firstSun 2:00 to Oct lastSun 2:00.
+# Shanks & Pottenger say Yukon's 1973-10-28 switch was at 2:00; go
+# with Englander.
+# From Chris Walton (2006-06-26):
+# Here is a link to the old daylight saving portion of the interpretation
+# act which was last updated in 1987:
+# http://www.gov.yk.ca/legislation/regs/oic1987_056.pdf
+
+# From Rives McDow (1999-09-04):
+# Nunavut ... moved ... to incorporate the whole territory into one time zone.
+# <a href="http://www.nunatsiaq.com/nunavut/nvt90903_13.html">
+# Nunavut moves to single time zone Oct. 31
+# </a>
+#
+# From Antoine Leca (1999-09-06):
+# We then need to create a new timezone for the Kitikmeot region of Nunavut
+# to differentiate it from the Yellowknife region.
+
+# From Paul Eggert (1999-09-20):
+# <a href="http://www.nunavut.com/basicfacts/english/basicfacts_1territory.html">
+# Basic Facts: The New Territory
+# </a> (1999) reports that Pangnirtung operates on eastern time,
+# and that Coral Harbour does not observe DST.  We don't know when
+# Pangnirtung switched to eastern time; we'll guess 1995.
+
+# From Rives McDow (1999-11-08):
+# On October 31, when the rest of Nunavut went to Central time,
+# Pangnirtung wobbled.  Here is the result of their wobble:
+#
+# The following businesses and organizations in Pangnirtung use Central Time:
+#
+#	First Air, Power Corp, Nunavut Construction, Health Center, RCMP,
+#	Eastern Arctic National Parks, A & D Specialist
+#
+# The following businesses and organizations in Pangnirtung use Eastern Time:
+#
+#	Hamlet office, All other businesses, Both schools, Airport operator
+#
+# This has made for an interesting situation there, which warranted the news.
+# No one there that I spoke with seems concerned, or has plans to
+# change the local methods of keeping time, as it evidently does not
+# really interfere with any activities or make things difficult locally.
+# They plan to celebrate New Year's turn-over twice, one hour apart,
+# so it appears that the situation will last at least that long.
+# The Nunavut Intergovernmental Affairs hopes that they will "come to
+# their senses", but the locals evidently don't see any problem with
+# the current state of affairs.
+
+# From Michaela Rodrigue, writing in the
+# <a href="http://www.nunatsiaq.com/archives/nunavut991130/nvt91119_17.html">
+# Nunatsiaq News (1999-11-19)</a>:
+# Clyde River, Pangnirtung and Sanikiluaq now operate with two time zones,
+# central - or Nunavut time - for government offices, and eastern time
+# for municipal offices and schools....  Igloolik [was similar but then]
+# made the switch to central time on Saturday, Nov. 6.
+
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) say the following, but we lack histories
+# for these potential new Zones.
+#
+# The Canadian Forces station at Alert uses Eastern Time while the
+# handful of residents at the Eureka weather station [in the Central
+# zone] skip daylight savings.  Baffin Island, which is crossed by the
+# Central, Eastern and Atlantic Time zones only uses Eastern Time.
+# Gjoa Haven, Taloyoak and Pelly Bay all use Mountain instead of
+# Central Time and Southampton Island [in the Central zone] is not
+# required to use daylight savings.
+
+# From
+# <a href="http://www.nunatsiaq.com/archives/nunavut001130/nvt21110_02.html">
+# Nunavut now has two time zones
+# </a> (2000-11-10):
+# The Nunavut government would allow its employees in Kugluktuk and
+# Cambridge Bay to operate on central time year-round, putting them
+# one hour behind the rest of Nunavut for six months during the winter.
+# At the end of October the two communities had rebelled against
+# Nunavut's unified time zone, refusing to shift to eastern time with
+# the rest of the territory for the winter.  Cambridge Bay remained on
+# central time, while Kugluktuk, even farther west, reverted to
+# mountain time, which they had used before the advent of Nunavut's
+# unified time zone in 1999.
+#
+# From Rives McDow (2001-01-20), quoting the Nunavut government:
+# The preceding decision came into effect at midnight, Saturday Nov 4, 2000.
+
+# From Paul Eggert (2000-12-04):
+# Let's just keep track of the official times for now.
+
+# From Rives McDow (2001-03-07):
+# The premier of Nunavut has issued a ministerial statement advising
+# that effective 2001-04-01, the territory of Nunavut will revert
+# back to three time zones (mountain, central, and eastern).  Of the
+# cities in Nunavut, Coral Harbor is the only one that I know of that
+# has said it will not observe dst, staying on EST year round.  I'm
+# checking for more info, and will get back to you if I come up with
+# more.
+# [Also see <http://www.nunatsiaq.com/nunavut/nvt10309_06.html> (2001-03-09).]
+
+# From Gwillim Law (2005-05-21):
+# According to maps at
+# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SWE.jpg
+# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SSE.jpg
+# (both dated 2003), and
+# http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp
+# (from a 1998 Canadian Geographic article), the de facto and de jure time
+# for Southampton Island (at the north end of Hudson Bay) is UTC-5 all year
+# round.  Using Google, it's easy to find other websites that confirm this.
+# I wasn't able to find how far back this time regimen goes, but since it
+# predates the creation of Nunavut, it probably goes back many years....
+# The Inuktitut name of Coral Harbour is Sallit, but it's rarely used.
+#
+# From Paul Eggert (2005-07-26):
+# For lack of better information, assume that Southampton Island observed
+# daylight saving only during wartime.
+
+# From Chris Walton (2007-03-01):
+# ... the community of Resolute (located on Cornwallis Island in
+# Nunavut) moved from Central Time to Eastern Time last November.
+# Basically the community did not change its clocks at the end of
+# daylight saving....
+# http://www.nnsl.com/frames/newspapers/2006-11/nov13_06none.html
+
+# From Chris Walton (2011-03-21):
+# Back in 2007 I initiated the creation of a new "zone file" for Resolute
+# Bay. Resolute Bay is a small community located about 900km north of
+# the Arctic Circle. The zone file was required because Resolute Bay had
+# decided to use UTC-5 instead of UTC-6 for the winter of 2006-2007.
+#
+# According to new information which I received last week, Resolute Bay
+# went back to using UTC-6 in the winter of 2007-2008...
+#
+# On March 11/2007 most of Canada went onto daylight saving. On March
+# 14/2007 I phoned the Resolute Bay hamlet office to do a "time check." I
+# talked to somebody that was both knowledgeable and helpful. I was able
+# to confirm that Resolute Bay was still operating on UTC-5. It was
+# explained to me that Resolute Bay had been on the Eastern Time zone
+# (EST) in the winter, and was now back on the Central Time zone (CDT).
+# i.e. the time zone had changed twice in the last year but the clocks
+# had not moved. The residents had to know which time zone they were in
+# so they could follow the correct TV schedule...
+#
+# On Nov 02/2008 most of Canada went onto standard time. On Nov 03/2008 I
+# phoned the Resolute Bay hamlet office...[D]ue to the challenging nature
+# of the phone call, I decided to seek out an alternate source of
+# information. I found an e-mail address for somebody by the name of
+# Stephanie Adams whose job was listed as "Inns North Support Officer for
+# Arctic Co-operatives." I was under the impression that Stephanie lived
+# and worked in Resolute Bay...
+#
+# On March 14/2011 I phoned the hamlet office again. I was told that
+# Resolute Bay had been using Central Standard Time over the winter of
+# 2010-2011 and that the clocks had therefore been moved one hour ahead
+# on March 13/2011. The person I talked to was aware that Resolute Bay
+# had previously experimented with Eastern Standard Time but he could not
+# tell me when the practice had stopped.
+#
+# On March 17/2011 I searched the Web to find an e-mail address of
+# somebody that might be able to tell me exactly when Resolute Bay went
+# off Eastern Standard Time. I stumbled on the name "Aziz Kheraj." Aziz
+# used to be the mayor of Resolute Bay and he apparently owns half the
+# businesses including "South Camp Inn." This website has some info on
+# Aziz:
+# <a href="http://www.uphere.ca/node/493">
+# http://www.uphere.ca/node/493
+# </a>
+#
+# I sent Aziz an e-mail asking when Resolute Bay had stopped using
+# Eastern Standard Time.
+#
+# Aziz responded quickly with this: "hi, The time was not changed for the
+# 1 year only, the following year, the community went back to the old way
+# of "spring ahead-fall behind" currently we are zulu plus 5 hrs and in
+# the winter Zulu plus 6 hrs"
+#
+# This of course conflicted with everything I had ascertained in November 2008.
+#
+# I sent Aziz a copy of my 2008 e-mail exchange with Stephanie. Aziz
+# responded with this: "Hi, Stephanie lives in Winnipeg. I live here, You
+# may want to check with the weather office in Resolute Bay or do a
+# search on the weather through Env. Canada. web site"
+#
+# If I had realized the Stephanie did not live in Resolute Bay I would
+# never have contacted her.  I now believe that all the information I
+# obtained in November 2008 should be ignored...
+# I apologize for reporting incorrect information in 2008.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NT_YK	1918	only	-	Apr	14	2:00	1:00	D
+Rule	NT_YK	1918	only	-	Oct	27	2:00	0	S
+Rule	NT_YK	1919	only	-	May	25	2:00	1:00	D
+Rule	NT_YK	1919	only	-	Nov	 1	0:00	0	S
+Rule	NT_YK	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	NT_YK	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	NT_YK	1945	only	-	Sep	30	2:00	0	S
+Rule	NT_YK	1965	only	-	Apr	lastSun	0:00	2:00	DD
+Rule	NT_YK	1965	only	-	Oct	lastSun	2:00	0	S
+Rule	NT_YK	1980	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	NT_YK	1980	2006	-	Oct	lastSun	2:00	0	S
+Rule	NT_YK	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# aka Panniqtuuq
+Zone America/Pangnirtung 0	-	zzz	1921 # trading post est.
+			-4:00	NT_YK	A%sT	1995 Apr Sun>=1 2:00
+			-5:00	Canada	E%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	Canada	E%sT
+# formerly Frobisher Bay
+Zone America/Iqaluit	0	-	zzz	1942 Aug # Frobisher Bay est.
+			-5:00	NT_YK	E%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	Canada	E%sT
+# aka Qausuittuq
+Zone America/Resolute	0	-	zzz	1947 Aug 31 # Resolute founded
+			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
+			-5:00	-	EST	2001 Apr  1 3:00
+			-6:00	Canada	C%sT	2006 Oct 29 2:00
+			-5:00	-	EST	2007 Mar 11 3:00
+			-6:00	Canada	C%sT
+# aka Kangiqiniq
+Zone America/Rankin_Inlet 0	-	zzz	1957 # Rankin Inlet founded
+			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
+			-5:00	-	EST	2001 Apr  1 3:00
+			-6:00	Canada	C%sT
+# aka Iqaluktuuttiaq
+Zone America/Cambridge_Bay 0	-	zzz	1920 # trading post est.?
+			-7:00	NT_YK	M%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	-	EST	2000 Nov  5 0:00
+			-6:00	-	CST	2001 Apr  1 3:00
+			-7:00	Canada	M%sT
+Zone America/Yellowknife 0	-	zzz	1935 # Yellowknife founded?
+			-7:00	NT_YK	M%sT	1980
+			-7:00	Canada	M%sT
+Zone America/Inuvik	0	-	zzz	1953 # Inuvik founded
+			-8:00	NT_YK	P%sT	1979 Apr lastSun 2:00
+			-7:00	NT_YK	M%sT	1980
+			-7:00	Canada	M%sT
+Zone America/Whitehorse	-9:00:12 -	LMT	1900 Aug 20
+			-9:00	NT_YK	Y%sT	1966 Jul 1 2:00
+			-8:00	NT_YK	P%sT	1980
+			-8:00	Canada	P%sT
+Zone America/Dawson	-9:17:40 -	LMT	1900 Aug 20
+			-9:00	NT_YK	Y%sT	1973 Oct 28 0:00
+			-8:00	NT_YK	P%sT	1980
+			-8:00	Canada	P%sT
+
+
+###############################################################################
+
+# Mexico
+
+# From Paul Eggert (2001-03-05):
+# The Investigation and Analysis Service of the
+# Mexican Library of Congress (MLoC) has published a
+# <a href="http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/">
+# history of Mexican local time (in Spanish)
+# </a>.
+#
+# Here are the discrepancies between Shanks & Pottenger (S&P) and the MLoC.
+# (In all cases we go with the MLoC.)
+# S&P report that Baja was at -8:00 in 1922/1923.
+# S&P say the 1930 transition in Baja was 1930-11-16.
+# S&P report no DST during summer 1931.
+# S&P report a transition at 1932-03-30 23:00, not 1932-04-01.
+
+# From Gwillim Law (2001-02-20):
+# There are some other discrepancies between the Decrees page and the
+# tz database.  I think they can best be explained by supposing that
+# the researchers who prepared the Decrees page failed to find some of
+# the relevant documents.
+
+# From Alan Perry (1996-02-15):
+# A guy from our Mexico subsidiary finally found the Presidential Decree
+# outlining the timezone changes in Mexico.
+#
+# ------------- Begin Forwarded Message -------------
+#
+# I finally got my hands on the Official Presidential Decree that sets up the
+# rules for the DST changes. The rules are:
+#
+# 1. The country is divided in 3 timezones:
+#    - Baja California Norte (the Mexico/BajaNorte TZ)
+#    - Baja California Sur, Nayarit, Sinaloa and Sonora (the Mexico/BajaSur TZ)
+#    - The rest of the country (the Mexico/General TZ)
+#
+# 2. From the first Sunday in April at 2:00 AM to the last Sunday in October
+#    at 2:00 AM, the times in each zone are as follows:
+#    BajaNorte: GMT+7
+#    BajaSur:   GMT+6
+#    General:   GMT+5
+#
+# 3. The rest of the year, the times are as follows:
+#    BajaNorte: GMT+8
+#    BajaSur:   GMT+7
+#    General:   GMT+6
+#
+# The Decree was published in Mexico's Official Newspaper on January 4th.
+#
+# -------------- End Forwarded Message --------------
+# From Paul Eggert (1996-06-12):
+# For an English translation of the decree, see
+# <a href="http://mexico-travel.com/extra/timezone_eng.html">
+# ``Diario Oficial: Time Zone Changeover'' (1996-01-04).
+# </a>
+
+# From Rives McDow (1998-10-08):
+# The State of Quintana Roo has reverted back to central STD and DST times
+# (i.e. UTC -0600 and -0500 as of 1998-08-02).
+
+# From Rives McDow (2000-01-10):
+# Effective April 4, 1999 at 2:00 AM local time, Sonora changed to the time
+# zone 5 hours from the International Date Line, and will not observe daylight
+# savings time so as to stay on the same time zone as the southern part of
+# Arizona year round.
+
+# From Jesper Norgaard, translating
+# <http://www.reforma.com/nacional/articulo/064327/> (2001-01-17):
+# In Oaxaca, the 55.000 teachers from the Section 22 of the National
+# Syndicate of Education Workers, refuse to apply daylight saving each
+# year, so that the more than 10,000 schools work at normal hour the
+# whole year.
+
+# From Gwillim Law (2001-01-19):
+# <http://www.reforma.com/negocios_y_dinero/articulo/064481/> ... says
+# (translated):...
+# January 17, 2000 - The Energy Secretary, Ernesto Martens, announced
+# that Summer Time will be reduced from seven to five months, starting
+# this year....
+# <http://www.publico.com.mx/scripts/texto3.asp?action=pagina&pag=21&pos=p&secc=naci&date=01/17/2001>
+# [translated], says "summer time will ... take effect on the first Sunday
+# in May, and end on the last Sunday of September.
+
+# From Arthur David Olson (2001-01-25):
+# The 2001-01-24 traditional Washington Post contained the page one
+# story "Timely Issue Divides Mexicans."...
+# http://www.washingtonpost.com/wp-dyn/articles/A37383-2001Jan23.html
+# ... Mexico City Mayor Lopez Obrador "...is threatening to keep
+# Mexico City and its 20 million residents on a different time than
+# the rest of the country..." In particular, Lopez Obrador would abolish
+# observation of Daylight Saving Time.
+
+# <a href="http://www.conae.gob.mx/ahorro/decretohorver2001.html#decre">
+# Official statute published by the Energy Department
+# </a> (2001-02-01) shows Baja and Chihauhua as still using US DST rules,
+# and Sonora with no DST.  This was reported by Jesper Norgaard (2001-02-03).
+
+# From Paul Eggert (2001-03-03):
+#
+# <a href="http://www.latimes.com/news/nation/20010303/t000018766.html">
+# James F. Smith writes in today's LA Times
+# </a>
+# * Sonora will continue to observe standard time.
+# * Last week Mexico City's mayor Andres Manuel Lopez Obrador decreed that
+#   the Federal District will not adopt DST.
+# * 4 of 16 district leaders announced they'll ignore the decree.
+# * The decree does not affect federal-controlled facilities including
+#   the airport, banks, hospitals, and schools.
+#
+# For now we'll assume that the Federal District will bow to federal rules.
+
+# From Jesper Norgaard (2001-04-01):
+# I found some references to the Mexican application of daylight
+# saving, which modifies what I had already sent you, stating earlier
+# that a number of northern Mexican states would go on daylight
+# saving. The modification reverts this to only cover Baja California
+# (Norte), while all other states (except Sonora, who has no daylight
+# saving all year) will follow the original decree of president
+# Vicente Fox, starting daylight saving May 6, 2001 and ending
+# September 30, 2001.
+# References: "Diario de Monterrey" <www.diariodemonterrey.com/index.asp>
+# Palabra <http://palabra.infosel.com/010331/primera/ppri3101.pdf> (2001-03-31)
+
+# From Reuters (2001-09-04):
+# Mexico's Supreme Court on Tuesday declared that daylight savings was
+# unconstitutional in Mexico City, creating the possibility the
+# capital will be in a different time zone from the rest of the nation
+# next year....  The Supreme Court's ruling takes effect at 2:00
+# a.m. (0800 GMT) on Sept. 30, when Mexico is scheduled to revert to
+# standard time. "This is so residents of the Federal District are not
+# subject to unexpected time changes," a statement from the court said.
+
+# From Jesper Norgaard Welen (2002-03-12):
+# ... consulting my local grocery store(!) and my coworkers, they all insisted
+# that a new decision had been made to reinstate US style DST in Mexico....
+# http://www.conae.gob.mx/ahorro/horaver2001_m1_2002.html (2002-02-20)
+# confirms this.  Sonora as usual is the only state where DST is not applied.
+
+# From Steffen Thorsen (2009-12-28):
+#
+# Steffen Thorsen wrote:
+# > Mexico's House of Representatives has approved a proposal for northern
+# > Mexico's border cities to share the same daylight saving schedule as
+# > the United States.
+# Now this has passed both the Congress and the Senate, so starting from
+# 2010, some border regions will be the same:
+# <a href="http://www.signonsandiego.com/news/2009/dec/28/clocks-will-match-both-sides-border/">
+# http://www.signonsandiego.com/news/2009/dec/28/clocks-will-match-both-sides-border/
+# </a>
+# <a href="http://www.elmananarey.com/diario/noticia/nacional/noticias/empatan_horario_de_frontera_con_eu/621939">
+# http://www.elmananarey.com/diario/noticia/nacional/noticias/empatan_horario_de_frontera_con_eu/621939
+# </a>
+# (Spanish)
+#
+# Could not find the new law text, but the proposed law text changes are here:
+# <a href="http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/20091210-V.pdf">
+# http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/20091210-V.pdf
+# </a>
+# (Gaceta Parlamentaria)
+#
+# There is also a list of the votes here:
+# <a href="http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/V2-101209.html">
+# http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/V2-101209.html
+# </a>
+#
+# Our page:
+# <a href="http://www.timeanddate.com/news/time/north-mexico-dst-change.html">
+# http://www.timeanddate.com/news/time/north-mexico-dst-change.html
+# </a>
+
+# From Arthur David Olson (2010-01-20):
+# The page
+# <a href="http://dof.gob.mx/nota_detalle.php?codigo=5127480&fecha=06/01/2010">
+# http://dof.gob.mx/nota_detalle.php?codigo=5127480&fecha=06/01/2010
+# </a>
+# includes this text:
+# En los municipios fronterizos de Tijuana y Mexicali en Baja California;
+# Ju&aacute;rez y Ojinaga en Chihuahua; Acu&ntilde;a y Piedras Negras en Coahuila;
+# An&aacute;huac en Nuevo Le&oacute;n; y Nuevo Laredo, Reynosa y Matamoros en
+# Tamaulipas, la aplicaci&oacute;n de este horario estacional surtir&aacute; efecto
+# desde las dos horas del segundo domingo de marzo y concluir&aacute; a las dos
+# horas del primer domingo de noviembre.
+# En los municipios fronterizos que se encuentren ubicados en la franja
+# fronteriza norte en el territorio comprendido entre la l&iacute;nea
+# internacional y la l&iacute;nea paralela ubicada a una distancia de veinte
+# kil&oacute;metros, as&iacute; como la Ciudad de Ensenada, Baja California, hacia el
+# interior del pa&iacute;s, la aplicaci&oacute;n de este horario estacional surtir&aacute;
+# efecto desde las dos horas del segundo domingo de marzo y concluir&aacute; a
+# las dos horas del primer domingo de noviembre.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Mexico	1939	only	-	Feb	5	0:00	1:00	D
+Rule	Mexico	1939	only	-	Jun	25	0:00	0	S
+Rule	Mexico	1940	only	-	Dec	9	0:00	1:00	D
+Rule	Mexico	1941	only	-	Apr	1	0:00	0	S
+Rule	Mexico	1943	only	-	Dec	16	0:00	1:00	W # War
+Rule	Mexico	1944	only	-	May	1	0:00	0	S
+Rule	Mexico	1950	only	-	Feb	12	0:00	1:00	D
+Rule	Mexico	1950	only	-	Jul	30	0:00	0	S
+Rule	Mexico	1996	2000	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Mexico	1996	2000	-	Oct	lastSun	2:00	0	S
+Rule	Mexico	2001	only	-	May	Sun>=1	2:00	1:00	D
+Rule	Mexico	2001	only	-	Sep	lastSun	2:00	0	S
+Rule	Mexico	2002	max	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Mexico	2002	max	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Quintana Roo
+Zone America/Cancun	-5:47:04 -	LMT	1922 Jan  1  0:12:56
+			-6:00	-	CST	1981 Dec 23
+			-5:00	Mexico	E%sT	1998 Aug  2  2:00
+			-6:00	Mexico	C%sT
+# Campeche, Yucatan
+Zone America/Merida	-5:58:28 -	LMT	1922 Jan  1  0:01:32
+			-6:00	-	CST	1981 Dec 23
+			-5:00	-	EST	1982 Dec  2
+			-6:00	Mexico	C%sT
+# Coahuila, Durango, Nuevo Leon, Tamaulipas (near US border)
+Zone America/Matamoros	-6:40:00 -	LMT	1921 Dec 31 23:20:00
+			-6:00	-	CST	1988
+			-6:00	US	C%sT	1989
+			-6:00	Mexico	C%sT	2010
+			-6:00	US	C%sT
+# Coahuila, Durango, Nuevo Leon, Tamaulipas (away from US border)
+Zone America/Monterrey	-6:41:16 -	LMT	1921 Dec 31 23:18:44
+			-6:00	-	CST	1988
+			-6:00	US	C%sT	1989
+			-6:00	Mexico	C%sT
+# Central Mexico
+Zone America/Mexico_City -6:36:36 -	LMT	1922 Jan  1 0:23:24
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	Mexico	C%sT	2001 Sep 30 02:00
+			-6:00	-	CST	2002 Feb 20
+			-6:00	Mexico	C%sT
+# Chihuahua (near US border)
+Zone America/Ojinaga	-6:57:40 -	LMT	1922 Jan 1 0:02:20
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1996
+			-6:00	Mexico	C%sT	1998
+			-6:00	-	CST	1998 Apr Sun>=1 3:00
+			-7:00	Mexico	M%sT	2010
+			-7:00	US	M%sT
+# Chihuahua (away from US border)
+Zone America/Chihuahua	-7:04:20 -	LMT	1921 Dec 31 23:55:40
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1996
+			-6:00	Mexico	C%sT	1998
+			-6:00	-	CST	1998 Apr Sun>=1 3:00
+			-7:00	Mexico	M%sT
+# Sonora
+Zone America/Hermosillo	-7:23:52 -	LMT	1921 Dec 31 23:36:08
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
+			-7:00	-	MST	1949 Jan 14
+			-8:00	-	PST	1970
+			-7:00	Mexico	M%sT	1999
+			-7:00	-	MST
+
+# From Alexander Krivenyshev (2010-04-21):
+# According to news, Bah&iacute;a de Banderas (Mexican state of Nayarit)
+# changed time zone UTC-7 to new time zone UTC-6 on April 4, 2010 (to
+# share the same time zone as nearby city Puerto Vallarta, Jalisco).
+#
+# (Spanish)
+# Bah&iacute;a de Banderas homologa su horario al del centro del
+# pa&iacute;s, a partir de este domingo
+# <a href="http://www.nayarit.gob.mx/notes.asp?id=20748">
+# http://www.nayarit.gob.mx/notes.asp?id=20748
+# </a>
+#
+# Bah&iacute;a de Banderas homologa su horario con el del Centro del
+# Pa&iacute;s
+# <a href="http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50">
+# http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50"
+# </a>
+#
+# (English)
+# Puerto Vallarta and Bah&iacute;a de Banderas: One Time Zone
+# <a href="http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml">
+# http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml
+# </a>
+#
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_mexico08.html">
+# http://www.worldtimezone.com/dst_news/dst_news_mexico08.html
+# </a>
+#
+# "Mexico's Senate approved the amendments to the Mexican Schedule System that
+# will allow Bah&iacute;a de Banderas and Puerto Vallarta to share the same time
+# zone ..."
+# Baja California Sur, Nayarit, Sinaloa
+
+# From Arthur David Olson (2010-05-01):
+# Use "Bahia_Banderas" to keep the name to fourteen characters.
+
+Zone America/Mazatlan	-7:05:40 -	LMT	1921 Dec 31 23:54:20
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
+			-7:00	-	MST	1949 Jan 14
+			-8:00	-	PST	1970
+			-7:00	Mexico	M%sT
+
+Zone America/Bahia_Banderas	-7:01:00 -	LMT	1921 Dec 31 23:59:00
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
+			-7:00	-	MST	1949 Jan 14
+			-8:00	-	PST	1970
+			-7:00	Mexico	M%sT	2010 Apr 4 2:00
+			-6:00	Mexico	C%sT
+
+# Baja California (near US border)
+Zone America/Tijuana	-7:48:04 -	LMT	1922 Jan  1  0:11:56
+			-7:00	-	MST	1924
+			-8:00	-	PST	1927 Jun 10 23:00
+			-7:00	-	MST	1930 Nov 15
+			-8:00	-	PST	1931 Apr  1
+			-8:00	1:00	PDT	1931 Sep 30
+			-8:00	-	PST	1942 Apr 24
+			-8:00	1:00	PWT	1945 Aug 14 23:00u
+			-8:00	1:00	PPT	1945 Nov 12 # Peace
+			-8:00	-	PST	1948 Apr  5
+			-8:00	1:00	PDT	1949 Jan 14
+			-8:00	-	PST	1954
+			-8:00	CA	P%sT	1961
+			-8:00	-	PST	1976
+			-8:00	US	P%sT	1996
+			-8:00	Mexico	P%sT	2001
+			-8:00	US	P%sT	2002 Feb 20
+			-8:00	Mexico	P%sT	2010
+			-8:00	US	P%sT
+# Baja California (away from US border)
+Zone America/Santa_Isabel	-7:39:28 -	LMT	1922 Jan  1  0:20:32
+			-7:00	-	MST	1924
+			-8:00	-	PST	1927 Jun 10 23:00
+			-7:00	-	MST	1930 Nov 15
+			-8:00	-	PST	1931 Apr  1
+			-8:00	1:00	PDT	1931 Sep 30
+			-8:00	-	PST	1942 Apr 24
+			-8:00	1:00	PWT	1945 Aug 14 23:00u
+			-8:00	1:00	PPT	1945 Nov 12 # Peace
+			-8:00	-	PST	1948 Apr  5
+			-8:00	1:00	PDT	1949 Jan 14
+			-8:00	-	PST	1954
+			-8:00	CA	P%sT	1961
+			-8:00	-	PST	1976
+			-8:00	US	P%sT	1996
+			-8:00	Mexico	P%sT	2001
+			-8:00	US	P%sT	2002 Feb 20
+			-8:00	Mexico	P%sT
+# From Paul Eggert (2006-03-22):
+# Formerly there was an America/Ensenada zone, which differed from
+# America/Tijuana only in that it did not observe DST from 1976
+# through 1995.  This was as per Shanks (1999).  But Shanks & Pottenger say
+# Ensenada did not observe DST from 1948 through 1975.  Guy Harris reports
+# that the 1987 OAG says "Only Ensenada, Mexicale, San Felipe and
+# Tijuana observe DST," which agrees with Shanks & Pottenger but implies that
+# DST-observance was a town-by-town matter back then.  This concerns
+# data after 1970 so most likely there should be at least one Zone
+# other than America/Tijuana for Baja, but it's not clear yet what its
+# name or contents should be.
+#
+# Revillagigedo Is
+# no information
+
+###############################################################################
+
+# Anguilla
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Anguilla	-4:12:16 -	LMT	1912 Mar 2
+			-4:00	-	AST
+
+# Antigua and Barbuda
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Antigua	-4:07:12 -	LMT	1912 Mar 2
+			-5:00	-	EST	1951
+			-4:00	-	AST
+
+# Bahamas
+#
+# From Sue Williams (2006-12-07):
+# The Bahamas announced about a month ago that they plan to change their DST
+# rules to sync with the U.S. starting in 2007....
+# http://www.jonesbahamas.com/?c=45&a=10412
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Bahamas	1964	1975	-	Oct	lastSun	2:00	0	S
+Rule	Bahamas	1964	1975	-	Apr	lastSun	2:00	1:00	D
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Nassau	-5:09:24 -	LMT	1912 Mar 2
+			-5:00	Bahamas	E%sT	1976
+			-5:00	US	E%sT
+
+# Barbados
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Barb	1977	only	-	Jun	12	2:00	1:00	D
+Rule	Barb	1977	1978	-	Oct	Sun>=1	2:00	0	S
+Rule	Barb	1978	1980	-	Apr	Sun>=15	2:00	1:00	D
+Rule	Barb	1979	only	-	Sep	30	2:00	0	S
+Rule	Barb	1980	only	-	Sep	25	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Barbados	-3:58:28 -	LMT	1924		# Bridgetown
+			-3:58:28 -	BMT	1932	  # Bridgetown Mean Time
+			-4:00	Barb	A%sT
+
+# Belize
+# Whitman entirely disagrees with Shanks; go with Shanks & Pottenger.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Belize	1918	1942	-	Oct	Sun>=2	0:00	0:30	HD
+Rule	Belize	1919	1943	-	Feb	Sun>=9	0:00	0	S
+Rule	Belize	1973	only	-	Dec	 5	0:00	1:00	D
+Rule	Belize	1974	only	-	Feb	 9	0:00	0	S
+Rule	Belize	1982	only	-	Dec	18	0:00	1:00	D
+Rule	Belize	1983	only	-	Feb	12	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Belize	-5:52:48 -	LMT	1912 Apr
+			-6:00	Belize	C%sT
+
+# Bermuda
+
+# From Dan Jones, reporting in The Royal Gazette (2006-06-26):
+
+# Next year, however, clocks in the US will go forward on the second Sunday
+# in March, until the first Sunday in November.  And, after the Time Zone
+# (Seasonal Variation) Bill 2006 was passed in the House of Assembly on
+# Friday, the same thing will happen in Bermuda.
+# http://www.theroyalgazette.com/apps/pbcs.dll/article?AID=/20060529/NEWS/105290135
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/Bermuda	-4:19:04 -	LMT	1930 Jan  1 2:00    # Hamilton
+			-4:00	-	AST	1974 Apr 28 2:00
+			-4:00	Bahamas	A%sT	1976
+			-4:00	US	A%sT
+
+# Cayman Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Cayman	-5:25:32 -	LMT	1890		# Georgetown
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
+			-5:00	-	EST
+
+# Costa Rica
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	CR	1979	1980	-	Feb	lastSun	0:00	1:00	D
+Rule	CR	1979	1980	-	Jun	Sun>=1	0:00	0	S
+Rule	CR	1991	1992	-	Jan	Sat>=15	0:00	1:00	D
+# IATA SSIM (1991-09) says the following was at 1:00;
+# go with Shanks & Pottenger.
+Rule	CR	1991	only	-	Jul	 1	0:00	0	S
+Rule	CR	1992	only	-	Mar	15	0:00	0	S
+# There are too many San Joses elsewhere, so we'll use `Costa Rica'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Costa_Rica	-5:36:20 -	LMT	1890		# San Jose
+			-5:36:20 -	SJMT	1921 Jan 15 # San Jose Mean Time
+			-6:00	CR	C%sT
+# Coco
+# no information; probably like America/Costa_Rica
+
+# Cuba
+
+# From Arthur David Olson (1999-03-29):
+# The 1999-03-28 exhibition baseball game held in Havana, Cuba, between
+# the Cuban National Team and the Baltimore Orioles was carried live on
+# the Orioles Radio Network, including affiliate WTOP in Washington, DC.
+# During the game, play-by-play announcer Jim Hunter noted that
+# "We'll be losing two hours of sleep...Cuba switched to Daylight Saving
+# Time today."  (The "two hour" remark referred to losing one hour of
+# sleep on 1999-03-28--when the announcers were in Cuba as it switched
+# to DST--and one more hour on 1999-04-04--when the announcers will have
+# returned to Baltimore, which switches on that date.)
+
+# From Evert van der Veer via Steffen Thorsen (2004-10-28):
+# Cuba is not going back to standard time this year.
+# From Paul Eggert (2006-03-22):
+# http://www.granma.cu/ingles/2004/septiembre/juev30/41medid-i.html
+# says that it's due to a problem at the Antonio Guiteras
+# thermoelectric plant, and says "This October there will be no return
+# to normal hours (after daylight saving time)".
+# For now, let's assume that it's a temporary measure.
+
+# From Carlos A. Carnero Delgado (2005-11-12):
+# This year (just like in 2004-2005) there's no change in time zone
+# adjustment in Cuba.  We will stay in daylight saving time:
+# http://www.granma.cu/espanol/2005/noviembre/mier9/horario.html
+
+# From Jesper Norgaard Welen (2006-10-21):
+# An article in GRANMA INTERNACIONAL claims that Cuba will end
+# the 3 years of permanent DST next weekend, see
+# http://www.granma.cu/ingles/2006/octubre/lun16/43horario.html
+# "On Saturday night, October 28 going into Sunday, October 29, at 01:00,
+# watches should be set back one hour -- going back to 00:00 hours -- returning
+# to the normal schedule....
+
+# From Paul Eggert (2007-03-02):
+# http://www.granma.cubaweb.cu/english/news/art89.html, dated yesterday,
+# says Cuban clocks will advance at midnight on March 10.
+# For lack of better information, assume Cuba will use US rules,
+# except that it switches at midnight standard time as usual.
+#
+# From Steffen Thorsen (2007-10-25):
+# Carlos Alberto Fonseca Arauz informed me that Cuba will end DST one week
+# earlier - on the last Sunday of October, just like in 2006.
+#
+# He supplied these references:
+#
+# http://www.prensalatina.com.mx/article.asp?ID=%7B4CC32C1B-A9F7-42FB-8A07-8631AFC923AF%7D&language=ES
+# http://actualidad.terra.es/sociedad/articulo/cuba_llama_ahorrar_energia_cambio_1957044.htm
+#
+# From Alex Kryvenishev (2007-10-25):
+# Here is also article from Granma (Cuba):
+#
+# [Regira] el Horario Normal desde el [proximo] domingo 28 de octubre
+# http://www.granma.cubaweb.cu/2007/10/24/nacional/artic07.html
+#
+# http://www.worldtimezone.com/dst_news/dst_news_cuba03.html
+
+# From Arthur David Olson (2008-03-09):
+# I'm in Maryland which is now observing United States Eastern Daylight
+# Time. At 9:44 local time I used RealPlayer to listen to
+# <a href="http://media.enet.cu/radioreloj">
+# http://media.enet.cu/radioreloj
+# </a>, a Cuban information station, and heard
+# the time announced as "ocho cuarenta y cuatro" ("eight forty-four"),
+# indicating that Cuba is still on standard time.
+
+# From Steffen Thorsen (2008-03-12):
+# It seems that Cuba will start DST on Sunday, 2007-03-16...
+# It was announced yesterday, according to this source (in Spanish):
+# <a href="http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm">
+# http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm
+# </a>
+#
+# Some more background information is posted here:
+# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html">
+# http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html
+# </a>
+#
+# The article also says that Cuba has been observing DST since 1963,
+# while Shanks (and tzdata) has 1965 as the first date (except in the
+# 1940's). Many other web pages in Cuba also claim that it has been
+# observed since 1963, but with the exception of 1970 - an exception
+# which is not present in tzdata/Shanks. So there is a chance we need to
+# change some historic records as well.
+#
+# One example:
+# <a href="http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm">
+# http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm
+# </a>
+
+# From Jesper Norgaard Welen (2008-03-13):
+# The Cuban time change has just been confirmed on the most authoritative
+# web site, the Granma.  Please check out
+# <a href="http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html">
+# http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html
+# </a>
+#
+# Basically as expected after Steffen Thorsens information, the change
+# will take place midnight between Saturday and Sunday.
+
+# From Arthur David Olson (2008-03-12):
+# Assume Sun>=15 (third Sunday) going forward.
+
+# From Alexander Krivenyshev (2009-03-04)
+# According to the Radio Reloj - Cuba will start Daylight Saving Time on
+# midnight between Saturday, March 07, 2009 and Sunday, March 08, 2009-
+# not on midnight March 14 / March 15 as previously thought.
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_cuba05.html">
+# http://www.worldtimezone.com/dst_news/dst_news_cuba05.html
+# (in Spanish)
+# </a>
+
+# From Arthur David Olson (2009-03-09)
+# I listened over the Internet to
+# <a href="http://media.enet.cu/readioreloj">
+# http://media.enet.cu/readioreloj
+# </a>
+# this morning; when it was 10:05 a. m. here in Bethesda, Maryland the
+# the time was announced as "diez cinco"--the same time as here, indicating
+# that has indeed switched to DST. Assume second Sunday from 2009 forward.
+
+# From Steffen Thorsen (2011-03-08):
+# Granma announced that Cuba is going to start DST on 2011-03-20 00:00:00
+# this year. Nothing about the end date known so far (if that has
+# changed at all).
+#
+# Source:
+# <a href="http://granma.co.cu/2011/03/08/nacional/artic01.html">
+# http://granma.co.cu/2011/03/08/nacional/artic01.html
+# </a>
+#
+# Our info:
+# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-2011.html">
+# http://www.timeanddate.com/news/time/cuba-starts-dst-2011.html
+# </a>
+#
+# From Steffen Thorsen (2011-10-30)
+# Cuba will end DST two weeks later this year. Instead of going back
+# tonight, it has been delayed to 2011-11-13 at 01:00.
+#
+# One source (Spanish)
+# <a href="http://www.radioangulo.cu/noticias/cuba/17105-cuba-restablecera-el-horario-del-meridiano-de-greenwich.html">
+# http://www.radioangulo.cu/noticias/cuba/17105-cuba-restablecera-el-horario-del-meridiano-de-greenwich.html
+# </a>
+#
+# Our page:
+# <a href="http://www.timeanddate.com/news/time/cuba-time-changes-2011.html">
+# http://www.timeanddate.com/news/time/cuba-time-changes-2011.html
+# </a>
+#
+# From Steffen Thorsen (2012-03-01)
+# According to Radio Reloj, Cuba will start DST on Midnight between March
+# 31 and April 1.
+#
+# Radio Reloj has the following info (Spanish):
+# <a href="http://www.radioreloj.cu/index.php/noticias-radio-reloj/71-miscelaneas/7529-cuba-aplicara-el-horario-de-verano-desde-el-1-de-abril">
+# http://www.radioreloj.cu/index.php/noticias-radio-reloj/71-miscelaneas/7529-cuba-aplicara-el-horario-de-verano-desde-el-1-de-abril
+# </a>
+#
+# Our info on it:
+# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-2012.html">
+# http://www.timeanddate.com/news/time/cuba-starts-dst-2012.html
+# </a>
+
+# From Steffen Thorsen (2012-11-03):
+# Radio Reloj and many other sources report that Cuba is changing back
+# to standard time on 2012-11-04:
+# http://www.radioreloj.cu/index.php/noticias-radio-reloj/36-nacionales/9961-regira-horario-normal-en-cuba-desde-el-domingo-cuatro-de-noviembre
+# From Paul Eggert (2012-11-03):
+# For now, assume the future rule is first Sunday in November.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Cuba	1928	only	-	Jun	10	0:00	1:00	D
+Rule	Cuba	1928	only	-	Oct	10	0:00	0	S
+Rule	Cuba	1940	1942	-	Jun	Sun>=1	0:00	1:00	D
+Rule	Cuba	1940	1942	-	Sep	Sun>=1	0:00	0	S
+Rule	Cuba	1945	1946	-	Jun	Sun>=1	0:00	1:00	D
+Rule	Cuba	1945	1946	-	Sep	Sun>=1	0:00	0	S
+Rule	Cuba	1965	only	-	Jun	1	0:00	1:00	D
+Rule	Cuba	1965	only	-	Sep	30	0:00	0	S
+Rule	Cuba	1966	only	-	May	29	0:00	1:00	D
+Rule	Cuba	1966	only	-	Oct	2	0:00	0	S
+Rule	Cuba	1967	only	-	Apr	8	0:00	1:00	D
+Rule	Cuba	1967	1968	-	Sep	Sun>=8	0:00	0	S
+Rule	Cuba	1968	only	-	Apr	14	0:00	1:00	D
+Rule	Cuba	1969	1977	-	Apr	lastSun	0:00	1:00	D
+Rule	Cuba	1969	1971	-	Oct	lastSun	0:00	0	S
+Rule	Cuba	1972	1974	-	Oct	8	0:00	0	S
+Rule	Cuba	1975	1977	-	Oct	lastSun	0:00	0	S
+Rule	Cuba	1978	only	-	May	7	0:00	1:00	D
+Rule	Cuba	1978	1990	-	Oct	Sun>=8	0:00	0	S
+Rule	Cuba	1979	1980	-	Mar	Sun>=15	0:00	1:00	D
+Rule	Cuba	1981	1985	-	May	Sun>=5	0:00	1:00	D
+Rule	Cuba	1986	1989	-	Mar	Sun>=14	0:00	1:00	D
+Rule	Cuba	1990	1997	-	Apr	Sun>=1	0:00	1:00	D
+Rule	Cuba	1991	1995	-	Oct	Sun>=8	0:00s	0	S
+Rule	Cuba	1996	only	-	Oct	 6	0:00s	0	S
+Rule	Cuba	1997	only	-	Oct	12	0:00s	0	S
+Rule	Cuba	1998	1999	-	Mar	lastSun	0:00s	1:00	D
+Rule	Cuba	1998	2003	-	Oct	lastSun	0:00s	0	S
+Rule	Cuba	2000	2004	-	Apr	Sun>=1	0:00s	1:00	D
+Rule	Cuba	2006	2010	-	Oct	lastSun	0:00s	0	S
+Rule	Cuba	2007	only	-	Mar	Sun>=8	0:00s	1:00	D
+Rule	Cuba	2008	only	-	Mar	Sun>=15	0:00s	1:00	D
+Rule	Cuba	2009	2010	-	Mar	Sun>=8	0:00s	1:00	D
+Rule	Cuba	2011	only	-	Mar	Sun>=15	0:00s	1:00	D
+Rule	Cuba	2011	only	-	Nov	13	0:00s	0	S
+Rule	Cuba	2012	only	-	Apr	1	0:00s	1:00	D
+Rule	Cuba	2012	max	-	Nov	Sun>=1	0:00s	0	S
+Rule	Cuba	2013	max	-	Mar	Sun>=8	0:00s	1:00	D
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Havana	-5:29:28 -	LMT	1890
+			-5:29:36 -	HMT	1925 Jul 19 12:00 # Havana MT
+			-5:00	Cuba	C%sT
+
+# Dominica
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Dominica	-4:05:36 -	LMT	1911 Jul 1 0:01		# Roseau
+			-4:00	-	AST
+
+# Dominican Republic
+
+# From Steffen Thorsen (2000-10-30):
+# Enrique Morales reported to me that the Dominican Republic has changed the
+# time zone to Eastern Standard Time as of Sunday 29 at 2 am....
+# http://www.listin.com.do/antes/261000/republica/princi.html
+
+# From Paul Eggert (2000-12-04):
+# That URL (2000-10-26, in Spanish) says they planned to use US-style DST.
+
+# From Rives McDow (2000-12-01):
+# Dominican Republic changed its mind and presidential decree on Tuesday,
+# November 28, 2000, with a new decree.  On Sunday, December 3 at 1:00 AM the
+# Dominican Republic will be reverting to 8 hours from the International Date
+# Line, and will not be using DST in the foreseeable future.  The reason they
+# decided to use DST was to be in synch with Puerto Rico, who was also going
+# to implement DST.  When Puerto Rico didn't implement DST, the president
+# decided to revert.
+
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	DR	1966	only	-	Oct	30	0:00	1:00	D
+Rule	DR	1967	only	-	Feb	28	0:00	0	S
+Rule	DR	1969	1973	-	Oct	lastSun	0:00	0:30	HD
+Rule	DR	1970	only	-	Feb	21	0:00	0	S
+Rule	DR	1971	only	-	Jan	20	0:00	0	S
+Rule	DR	1972	1974	-	Jan	21	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Santo_Domingo -4:39:36 -	LMT	1890
+			-4:40	-	SDMT	1933 Apr  1 12:00 # S. Dom. MT
+			-5:00	DR	E%sT	1974 Oct 27
+			-4:00	-	AST	2000 Oct 29 02:00
+			-5:00	US	E%sT	2000 Dec  3 01:00
+			-4:00	-	AST
+
+# El Salvador
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Salv	1987	1988	-	May	Sun>=1	0:00	1:00	D
+Rule	Salv	1987	1988	-	Sep	lastSun	0:00	0	S
+# There are too many San Salvadors elsewhere, so use America/El_Salvador
+# instead of America/San_Salvador.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/El_Salvador -5:56:48 -	LMT	1921		# San Salvador
+			-6:00	Salv	C%sT
+
+# Grenada
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Grenada	-4:07:00 -	LMT	1911 Jul	# St George's
+			-4:00	-	AST
+
+# Guadeloupe
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Guadeloupe	-4:06:08 -	LMT	1911 Jun 8	# Pointe a Pitre
+			-4:00	-	AST
+# St Barthelemy
+Link America/Guadeloupe	America/St_Barthelemy
+# St Martin (French part)
+Link America/Guadeloupe	America/Marigot
+
+# Guatemala
+#
+# From Gwillim Law (2006-04-22), after a heads-up from Oscar van Vlijmen:
+# Diario Co Latino, at
+# http://www.diariocolatino.com/internacionales/detalles.asp?NewsID=8079,
+# says in an article dated 2006-04-19 that the Guatemalan government had
+# decided on that date to advance official time by 60 minutes, to lessen the
+# impact of the elevated cost of oil....  Daylight saving time will last from
+# 2006-04-29 24:00 (Guatemalan standard time) to 2006-09-30 (time unspecified).
+# From Paul Eggert (2006-06-22):
+# The Ministry of Energy and Mines, press release CP-15/2006
+# (2006-04-19), says DST ends at 24:00.  See
+# <http://www.sieca.org.gt/Sitio_publico/Energeticos/Doc/Medidas/Cambio_Horario_Nac_190406.pdf>.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Guat	1973	only	-	Nov	25	0:00	1:00	D
+Rule	Guat	1974	only	-	Feb	24	0:00	0	S
+Rule	Guat	1983	only	-	May	21	0:00	1:00	D
+Rule	Guat	1983	only	-	Sep	22	0:00	0	S
+Rule	Guat	1991	only	-	Mar	23	0:00	1:00	D
+Rule	Guat	1991	only	-	Sep	 7	0:00	0	S
+Rule	Guat	2006	only	-	Apr	30	0:00	1:00	D
+Rule	Guat	2006	only	-	Oct	 1	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Guatemala	-6:02:04 -	LMT	1918 Oct 5
+			-6:00	Guat	C%sT
+
+# Haiti
+# From Gwillim Law (2005-04-15):
+# Risto O. Nykanen wrote me that Haiti is now on DST.
+# I searched for confirmation, and I found a
+# <a href="http://www.haitianconsulate.org/time.doc"> press release
+# on the Web page of the Haitian Consulate in Chicago (2005-03-31),
+# </a>.  Translated from French, it says:
+#
+#  "The Prime Minister's Communication Office notifies the public in general
+#   and the press in particular that, following a decision of the Interior
+#   Ministry and the Territorial Collectivities [I suppose that means the
+#   provinces], Haiti will move to Eastern Daylight Time in the night from next
+#   Saturday the 2nd to Sunday the 3rd.
+#
+#  "Consequently, the Prime Minister's Communication Office wishes to inform
+#   the population that the country's clocks will be set forward one hour
+#   starting at midnight.  This provision will hold until the last Saturday in
+#   October 2005.
+#
+#  "Port-au-Prince, March 31, 2005"
+#
+# From Steffen Thorsen (2006-04-04):
+# I have been informed by users that Haiti observes DST this year like
+# last year, so the current "only" rule for 2005 might be changed to a
+# "max" rule or to last until 2006. (Who knows if they will observe DST
+# next year or if they will extend their DST like US/Canada next year).
+#
+# I have found this article about it (in French):
+# http://www.haitipressnetwork.com/news.cfm?articleID=7612
+#
+# The reason seems to be an energy crisis.
+
+# From Stephen Colebourne (2007-02-22):
+# Some IATA info: Haiti won't be having DST in 2007.
+
+# From Steffen Thorsen (2012-03-11):
+# According to several news sources, Haiti will observe DST this year,
+# apparently using the same start and end date as USA/Canada.
+# So this means they have already changed their time.
+#
+# (Sources in French):
+# <a href="http://www.alterpresse.org/spip.php?article12510">
+# http://www.alterpresse.org/spip.php?article12510
+# </a>
+# <a href="http://radiovision2000haiti.net/home/?p=13253">
+# http://radiovision2000haiti.net/home/?p=13253
+# </a>
+#
+# Our coverage:
+# <a href="http://www.timeanddate.com/news/time/haiti-dst-2012.html">
+# http://www.timeanddate.com/news/time/haiti-dst-2012.html
+# </a>
+
+# From Arthur David Olson (2012-03-11):
+# The alterpresse.org source seems to show a US-style leap from 2:00 a.m. to
+# 3:00 a.m. rather than the traditional Haitian jump at midnight.
+# Assume a US-style fall back as well XXX.
+# Do not yet assume that the change carries forward past 2012 XXX.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Haiti	1983	only	-	May	8	0:00	1:00	D
+Rule	Haiti	1984	1987	-	Apr	lastSun	0:00	1:00	D
+Rule	Haiti	1983	1987	-	Oct	lastSun	0:00	0	S
+# Shanks & Pottenger say AT is 2:00, but IATA SSIM (1991/1997) says 1:00s.
+# Go with IATA.
+Rule	Haiti	1988	1997	-	Apr	Sun>=1	1:00s	1:00	D
+Rule	Haiti	1988	1997	-	Oct	lastSun	1:00s	0	S
+Rule	Haiti	2005	2006	-	Apr	Sun>=1	0:00	1:00	D
+Rule	Haiti	2005	2006	-	Oct	lastSun	0:00	0	S
+Rule	Haiti	2012	only	-	Mar	Sun>=8	2:00	1:00	D
+Rule	Haiti	2012	only	-	Nov	Sun>=1	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Port-au-Prince -4:49:20 -	LMT	1890
+			-4:49	-	PPMT	1917 Jan 24 12:00 # P-a-P MT
+			-5:00	Haiti	E%sT
+
+# Honduras
+# Shanks & Pottenger say 1921 Jan 1; go with Whitman's more precise Apr 1.
+
+# From Paul Eggert (2006-05-05):
+# worldtimezone.com reports a 2006-05-02 Spanish-language AP article
+# saying Honduras will start using DST midnight Saturday, effective 4
+# months until September.  La Tribuna reported today
+# <http://www.latribuna.hn/99299.html> that Manuel Zelaya, the president
+# of Honduras, refused to back down on this.
+
+# From Jesper Norgaard Welen (2006-08-08):
+# It seems that Honduras has returned from DST to standard time this Monday at
+# 00:00 hours (prolonging Sunday to 25 hours duration).
+# http://www.worldtimezone.com/dst_news/dst_news_honduras04.html
+
+# From Paul Eggert (2006-08-08):
+# Also see Diario El Heraldo, The country returns to standard time (2006-08-08)
+# <http://www.elheraldo.hn/nota.php?nid=54941&sec=12>.
+# It mentions executive decree 18-2006.
+
+# From Steffen Thorsen (2006-08-17):
+# Honduras will observe DST from 2007 to 2009, exact dates are not
+# published, I have located this authoritative source:
+# http://www.presidencia.gob.hn/noticia.aspx?nId=47
+
+# From Steffen Thorsen (2007-03-30):
+# http://www.laprensahn.com/pais_nota.php?id04962=7386
+# So it seems that Honduras will not enter DST this year....
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Hond	1987	1988	-	May	Sun>=1	0:00	1:00	D
+Rule	Hond	1987	1988	-	Sep	lastSun	0:00	0	S
+Rule	Hond	2006	only	-	May	Sun>=1	0:00	1:00	D
+Rule	Hond	2006	only	-	Aug	Mon>=1	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Tegucigalpa -5:48:52 -	LMT	1921 Apr
+			-6:00	Hond	C%sT
+#
+# Great Swan I ceded by US to Honduras in 1972
+
+# Jamaica
+
+# From Bob Devine (1988-01-28):
+# Follows US rules.
+
+# From U. S. Naval Observatory (1989-01-19):
+# JAMAICA             5 H  BEHIND UTC
+
+# From Shanks & Pottenger:
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Jamaica	-5:07:12 -	LMT	1890		# Kingston
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
+			-5:00	-	EST	1974 Apr 28 2:00
+			-5:00	US	E%sT	1984
+			-5:00	-	EST
+
+# Martinique
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Martinique	-4:04:20 -      LMT	1890		# Fort-de-France
+			-4:04:20 -	FFMT	1911 May     # Fort-de-France MT
+			-4:00	-	AST	1980 Apr  6
+			-4:00	1:00	ADT	1980 Sep 28
+			-4:00	-	AST
+
+# Montserrat
+# From Paul Eggert (2006-03-22):
+# In 1995 volcanic eruptions forced evacuation of Plymouth, the capital.
+# world.gazetteer.com says Cork Hill is the most populous location now.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Montserrat	-4:08:52 -	LMT	1911 Jul 1 0:01   # Cork Hill
+			-4:00	-	AST
+
+# Nicaragua
+#
+# This uses Shanks & Pottenger for times before 2005.
+#
+# From Steffen Thorsen (2005-04-12):
+# I've got reports from 8 different people that Nicaragua just started
+# DST on Sunday 2005-04-10, in order to save energy because of
+# expensive petroleum.  The exact end date for DST is not yet
+# announced, only "September" but some sites also say "mid-September".
+# Some background information is available on the President's official site:
+# http://www.presidencia.gob.ni/Presidencia/Files_index/Secretaria/Notas%20de%20Prensa/Presidente/2005/ABRIL/Gobierno-de-nicaragua-adelanta-hora-oficial-06abril.htm
+# The Decree, no 23-2005 is available here:
+# http://www.presidencia.gob.ni/buscador_gaceta/BD/DECRETOS/2005/Decreto%2023-2005%20Se%20adelanta%20en%20una%20hora%20en%20todo%20el%20territorio%20nacional%20apartir%20de%20las%2024horas%20del%2009%20de%20Abril.pdf
+#
+# From Paul Eggert (2005-05-01):
+# The decree doesn't say anything about daylight saving, but for now let's
+# assume that it is daylight saving....
+#
+# From Gwillim Law (2005-04-21):
+# The Associated Press story on the time change, which can be found at
+# http://www.lapalmainteractivo.com/guias/content/gen/ap/America_Latina/AMC_GEN_NICARAGUA_HORA.html
+# and elsewhere, says (fifth paragraph, translated from Spanish):  "The last
+# time that a change of clocks was applied to save energy was in the year 2000
+# during the Arnoldo Aleman administration."...
+# The northamerica file says that Nicaragua has been on UTC-6 continuously
+# since December 1998.  I wasn't able to find any details of Nicaraguan time
+# changes in 2000.  Perhaps a note could be added to the northamerica file, to
+# the effect that we have indirect evidence that DST was observed in 2000.
+#
+# From Jesper Norgaard Welen (2005-11-02):
+# Nicaragua left DST the 2005-10-02 at 00:00 (local time).
+# http://www.presidencia.gob.ni/presidencia/files_index/secretaria/comunicados/2005/septiembre/26septiembre-cambio-hora.htm
+# (2005-09-26)
+#
+# From Jesper Norgaard Welen (2006-05-05):
+# http://www.elnuevodiario.com.ni/2006/05/01/nacionales/18410
+# (my informal translation)
+# By order of the president of the republic, Enrique Bolanos, Nicaragua
+# advanced by sixty minutes their official time, yesterday at 2 in the
+# morning, and will stay that way until 30.th. of september.
+#
+# From Jesper Norgaard Welen (2006-09-30):
+# http://www.presidencia.gob.ni/buscador_gaceta/BD/DECRETOS/2006/D-063-2006P-PRN-Cambio-Hora.pdf
+# My informal translation runs:
+# The natural sun time is restored in all the national territory, in that the
+# time is returned one hour at 01:00 am of October 1 of 2006.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Nic	1979	1980	-	Mar	Sun>=16	0:00	1:00	D
+Rule	Nic	1979	1980	-	Jun	Mon>=23	0:00	0	S
+Rule	Nic	2005	only	-	Apr	10	0:00	1:00	D
+Rule	Nic	2005	only	-	Oct	Sun>=1	0:00	0	S
+Rule	Nic	2006	only	-	Apr	30	2:00	1:00	D
+Rule	Nic	2006	only	-	Oct	Sun>=1	1:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Managua	-5:45:08 -	LMT	1890
+			-5:45:12 -	MMT	1934 Jun 23 # Managua Mean Time?
+			-6:00	-	CST	1973 May
+			-5:00	-	EST	1975 Feb 16
+			-6:00	Nic	C%sT	1992 Jan  1 4:00
+			-5:00	-	EST	1992 Sep 24
+			-6:00	-	CST	1993
+			-5:00	-	EST	1997
+			-6:00	Nic	C%sT
+
+# Panama
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Panama	-5:18:08 -	LMT	1890
+			-5:19:36 -	CMT	1908 Apr 22   # Colon Mean Time
+			-5:00	-	EST
+
+# Puerto Rico
+# There are too many San Juans elsewhere, so we'll use `Puerto_Rico'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Puerto_Rico -4:24:25 -	LMT	1899 Mar 28 12:00    # San Juan
+			-4:00	-	AST	1942 May  3
+			-4:00	US	A%sT	1946
+			-4:00	-	AST
+
+# St Kitts-Nevis
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Kitts	-4:10:52 -	LMT	1912 Mar 2	# Basseterre
+			-4:00	-	AST
+
+# St Lucia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Lucia	-4:04:00 -	LMT	1890		# Castries
+			-4:04:00 -	CMT	1912	    # Castries Mean Time
+			-4:00	-	AST
+
+# St Pierre and Miquelon
+# There are too many St Pierres elsewhere, so we'll use `Miquelon'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Miquelon	-3:44:40 -	LMT	1911 May 15	# St Pierre
+			-4:00	-	AST	1980 May
+			-3:00	-	PMST	1987 # Pierre & Miquelon Time
+			-3:00	Canada	PM%sT
+
+# St Vincent and the Grenadines
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Vincent	-4:04:56 -	LMT	1890		# Kingstown
+			-4:04:56 -	KMT	1912	   # Kingstown Mean Time
+			-4:00	-	AST
+
+# Turks and Caicos
+#
+# From Chris Dunn in
+# <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=415007>
+# (2007-03-15): In the Turks & Caicos Islands (America/Grand_Turk) the
+# daylight saving dates for time changes have been adjusted to match
+# the recent U.S. change of dates.
+#
+# From Brian Inglis (2007-04-28):
+# http://www.turksandcaicos.tc/calendar/index.htm [2007-04-26]
+# there is an entry for Nov 4 "Daylight Savings Time Ends 2007" and three
+# rows before that there is an out of date entry for Oct:
+# "Eastern Standard Times Begins 2007
+# Clocks are set back one hour at 2:00 a.m. local Daylight Saving Time"
+# indicating that the normal ET rules are followed.
+#
+# From Paul Eggert (2006-05-01):
+# Shanks & Pottenger say they use US DST rules, but IATA SSIM (1991/1998)
+# says they switch at midnight.  Go with Shanks & Pottenger.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	TC	1979	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	TC	1979	2006	-	Oct	lastSun	2:00	0	S
+Rule	TC	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
+Rule	TC	2007	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	TC	2007	max	-	Nov	Sun>=1	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Grand_Turk	-4:44:32 -	LMT	1890
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
+			-5:00	TC	E%sT
+
+# British Virgin Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Tortola	-4:18:28 -	LMT	1911 Jul    # Road Town
+			-4:00	-	AST
+
+# Virgin Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Thomas	-4:19:44 -	LMT	1911 Jul    # Charlotte Amalie
+			-4:00	-	AST
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/pacificnew b/jdk/test/sun/util/calendar/zi/tzdata/pacificnew
new file mode 100644
index 0000000..7738a48
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/pacificnew
@@ -0,0 +1,51 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# From Arthur David Olson (1989-04-05):
+# On 1989-04-05, the U. S. House of Representatives passed (238-154) a bill
+# establishing "Pacific Presidential Election Time"; it was not acted on
+# by the Senate or signed into law by the President.
+# You might want to change the "PE" (Presidential Election) below to
+# "Q" (Quadrennial) to maintain three-character zone abbreviations.
+# If you're really conservative, you might want to change it to "D".
+# Avoid "L" (Leap Year), which won't be true in 2100.
+
+# If Presidential Election Time is ever established, replace "XXXX" below
+# with the year the law takes effect and uncomment the "##" lines.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+## Rule	Twilite	XXXX	max	-	Apr	Sun>=1	2:00	1:00	D
+## Rule	Twilite	XXXX	max	uspres	Oct	lastSun	2:00	1:00	PE
+## Rule	Twilite	XXXX	max	uspres	Nov	Sun>=7	2:00	0	S
+## Rule	Twilite	XXXX	max	nonpres	Oct	lastSun	2:00	0	S
+
+# Zone	NAME			GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+## Zone	America/Los_Angeles-PET	-8:00	US		P%sT	XXXX
+##				-8:00	Twilite		P%sT
+
+# For now...
+Link	America/Los_Angeles	US/Pacific-New	##
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/solar87 b/jdk/test/sun/util/calendar/zi/tzdata/solar87
new file mode 100644
index 0000000..46b1d56
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/solar87
@@ -0,0 +1,413 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# So much for footnotes about Saudi Arabia.
+# Apparent noon times below are for Riyadh; your mileage will vary.
+# Times were computed using formulas in the U.S. Naval Observatory's
+# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of
+# [plus or minus two] seconds during the current year."
+#
+# Rounding to the nearest five seconds results in fewer than
+# 256 different "time types"--a limit that's faced because time types are
+# stored on disk as unsigned chars.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	sol87	1987	only	-	Jan	1	12:03:20s -0:03:20 -
+Rule	sol87	1987	only	-	Jan	2	12:03:50s -0:03:50 -
+Rule	sol87	1987	only	-	Jan	3	12:04:15s -0:04:15 -
+Rule	sol87	1987	only	-	Jan	4	12:04:45s -0:04:45 -
+Rule	sol87	1987	only	-	Jan	5	12:05:10s -0:05:10 -
+Rule	sol87	1987	only	-	Jan	6	12:05:40s -0:05:40 -
+Rule	sol87	1987	only	-	Jan	7	12:06:05s -0:06:05 -
+Rule	sol87	1987	only	-	Jan	8	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jan	9	12:06:55s -0:06:55 -
+Rule	sol87	1987	only	-	Jan	10	12:07:20s -0:07:20 -
+Rule	sol87	1987	only	-	Jan	11	12:07:45s -0:07:45 -
+Rule	sol87	1987	only	-	Jan	12	12:08:10s -0:08:10 -
+Rule	sol87	1987	only	-	Jan	13	12:08:30s -0:08:30 -
+Rule	sol87	1987	only	-	Jan	14	12:08:55s -0:08:55 -
+Rule	sol87	1987	only	-	Jan	15	12:09:15s -0:09:15 -
+Rule	sol87	1987	only	-	Jan	16	12:09:35s -0:09:35 -
+Rule	sol87	1987	only	-	Jan	17	12:09:55s -0:09:55 -
+Rule	sol87	1987	only	-	Jan	18	12:10:15s -0:10:15 -
+Rule	sol87	1987	only	-	Jan	19	12:10:35s -0:10:35 -
+Rule	sol87	1987	only	-	Jan	20	12:10:55s -0:10:55 -
+Rule	sol87	1987	only	-	Jan	21	12:11:10s -0:11:10 -
+Rule	sol87	1987	only	-	Jan	22	12:11:30s -0:11:30 -
+Rule	sol87	1987	only	-	Jan	23	12:11:45s -0:11:45 -
+Rule	sol87	1987	only	-	Jan	24	12:12:00s -0:12:00 -
+Rule	sol87	1987	only	-	Jan	25	12:12:15s -0:12:15 -
+Rule	sol87	1987	only	-	Jan	26	12:12:30s -0:12:30 -
+Rule	sol87	1987	only	-	Jan	27	12:12:40s -0:12:40 -
+Rule	sol87	1987	only	-	Jan	28	12:12:55s -0:12:55 -
+Rule	sol87	1987	only	-	Jan	29	12:13:05s -0:13:05 -
+Rule	sol87	1987	only	-	Jan	30	12:13:15s -0:13:15 -
+Rule	sol87	1987	only	-	Jan	31	12:13:25s -0:13:25 -
+Rule	sol87	1987	only	-	Feb	1	12:13:35s -0:13:35 -
+Rule	sol87	1987	only	-	Feb	2	12:13:40s -0:13:40 -
+Rule	sol87	1987	only	-	Feb	3	12:13:50s -0:13:50 -
+Rule	sol87	1987	only	-	Feb	4	12:13:55s -0:13:55 -
+Rule	sol87	1987	only	-	Feb	5	12:14:00s -0:14:00 -
+Rule	sol87	1987	only	-	Feb	6	12:14:05s -0:14:05 -
+Rule	sol87	1987	only	-	Feb	7	12:14:10s -0:14:10 -
+Rule	sol87	1987	only	-	Feb	8	12:14:10s -0:14:10 -
+Rule	sol87	1987	only	-	Feb	9	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	10	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	11	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	12	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	13	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	14	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	15	12:14:10s -0:14:10 -
+Rule	sol87	1987	only	-	Feb	16	12:14:10s -0:14:10 -
+Rule	sol87	1987	only	-	Feb	17	12:14:05s -0:14:05 -
+Rule	sol87	1987	only	-	Feb	18	12:14:00s -0:14:00 -
+Rule	sol87	1987	only	-	Feb	19	12:13:55s -0:13:55 -
+Rule	sol87	1987	only	-	Feb	20	12:13:50s -0:13:50 -
+Rule	sol87	1987	only	-	Feb	21	12:13:45s -0:13:45 -
+Rule	sol87	1987	only	-	Feb	22	12:13:35s -0:13:35 -
+Rule	sol87	1987	only	-	Feb	23	12:13:30s -0:13:30 -
+Rule	sol87	1987	only	-	Feb	24	12:13:20s -0:13:20 -
+Rule	sol87	1987	only	-	Feb	25	12:13:10s -0:13:10 -
+Rule	sol87	1987	only	-	Feb	26	12:13:00s -0:13:00 -
+Rule	sol87	1987	only	-	Feb	27	12:12:50s -0:12:50 -
+Rule	sol87	1987	only	-	Feb	28	12:12:40s -0:12:40 -
+Rule	sol87	1987	only	-	Mar	1	12:12:30s -0:12:30 -
+Rule	sol87	1987	only	-	Mar	2	12:12:20s -0:12:20 -
+Rule	sol87	1987	only	-	Mar	3	12:12:05s -0:12:05 -
+Rule	sol87	1987	only	-	Mar	4	12:11:55s -0:11:55 -
+Rule	sol87	1987	only	-	Mar	5	12:11:40s -0:11:40 -
+Rule	sol87	1987	only	-	Mar	6	12:11:25s -0:11:25 -
+Rule	sol87	1987	only	-	Mar	7	12:11:15s -0:11:15 -
+Rule	sol87	1987	only	-	Mar	8	12:11:00s -0:11:00 -
+Rule	sol87	1987	only	-	Mar	9	12:10:45s -0:10:45 -
+Rule	sol87	1987	only	-	Mar	10	12:10:30s -0:10:30 -
+Rule	sol87	1987	only	-	Mar	11	12:10:15s -0:10:15 -
+Rule	sol87	1987	only	-	Mar	12	12:09:55s -0:09:55 -
+Rule	sol87	1987	only	-	Mar	13	12:09:40s -0:09:40 -
+Rule	sol87	1987	only	-	Mar	14	12:09:25s -0:09:25 -
+Rule	sol87	1987	only	-	Mar	15	12:09:10s -0:09:10 -
+Rule	sol87	1987	only	-	Mar	16	12:08:50s -0:08:50 -
+Rule	sol87	1987	only	-	Mar	17	12:08:35s -0:08:35 -
+Rule	sol87	1987	only	-	Mar	18	12:08:15s -0:08:15 -
+Rule	sol87	1987	only	-	Mar	19	12:08:00s -0:08:00 -
+Rule	sol87	1987	only	-	Mar	20	12:07:40s -0:07:40 -
+Rule	sol87	1987	only	-	Mar	21	12:07:25s -0:07:25 -
+Rule	sol87	1987	only	-	Mar	22	12:07:05s -0:07:05 -
+Rule	sol87	1987	only	-	Mar	23	12:06:50s -0:06:50 -
+Rule	sol87	1987	only	-	Mar	24	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Mar	25	12:06:10s -0:06:10 -
+Rule	sol87	1987	only	-	Mar	26	12:05:55s -0:05:55 -
+Rule	sol87	1987	only	-	Mar	27	12:05:35s -0:05:35 -
+Rule	sol87	1987	only	-	Mar	28	12:05:15s -0:05:15 -
+Rule	sol87	1987	only	-	Mar	29	12:05:00s -0:05:00 -
+Rule	sol87	1987	only	-	Mar	30	12:04:40s -0:04:40 -
+Rule	sol87	1987	only	-	Mar	31	12:04:25s -0:04:25 -
+Rule	sol87	1987	only	-	Apr	1	12:04:05s -0:04:05 -
+Rule	sol87	1987	only	-	Apr	2	12:03:45s -0:03:45 -
+Rule	sol87	1987	only	-	Apr	3	12:03:30s -0:03:30 -
+Rule	sol87	1987	only	-	Apr	4	12:03:10s -0:03:10 -
+Rule	sol87	1987	only	-	Apr	5	12:02:55s -0:02:55 -
+Rule	sol87	1987	only	-	Apr	6	12:02:35s -0:02:35 -
+Rule	sol87	1987	only	-	Apr	7	12:02:20s -0:02:20 -
+Rule	sol87	1987	only	-	Apr	8	12:02:05s -0:02:05 -
+Rule	sol87	1987	only	-	Apr	9	12:01:45s -0:01:45 -
+Rule	sol87	1987	only	-	Apr	10	12:01:30s -0:01:30 -
+Rule	sol87	1987	only	-	Apr	11	12:01:15s -0:01:15 -
+Rule	sol87	1987	only	-	Apr	12	12:00:55s -0:00:55 -
+Rule	sol87	1987	only	-	Apr	13	12:00:40s -0:00:40 -
+Rule	sol87	1987	only	-	Apr	14	12:00:25s -0:00:25 -
+Rule	sol87	1987	only	-	Apr	15	12:00:10s -0:00:10 -
+Rule	sol87	1987	only	-	Apr	16	11:59:55s 0:00:05 -
+Rule	sol87	1987	only	-	Apr	17	11:59:45s 0:00:15 -
+Rule	sol87	1987	only	-	Apr	18	11:59:30s 0:00:30 -
+Rule	sol87	1987	only	-	Apr	19	11:59:15s 0:00:45 -
+Rule	sol87	1987	only	-	Apr	20	11:59:05s 0:00:55 -
+Rule	sol87	1987	only	-	Apr	21	11:58:50s 0:01:10 -
+Rule	sol87	1987	only	-	Apr	22	11:58:40s 0:01:20 -
+Rule	sol87	1987	only	-	Apr	23	11:58:25s 0:01:35 -
+Rule	sol87	1987	only	-	Apr	24	11:58:15s 0:01:45 -
+Rule	sol87	1987	only	-	Apr	25	11:58:05s 0:01:55 -
+Rule	sol87	1987	only	-	Apr	26	11:57:55s 0:02:05 -
+Rule	sol87	1987	only	-	Apr	27	11:57:45s 0:02:15 -
+Rule	sol87	1987	only	-	Apr	28	11:57:35s 0:02:25 -
+Rule	sol87	1987	only	-	Apr	29	11:57:25s 0:02:35 -
+Rule	sol87	1987	only	-	Apr	30	11:57:15s 0:02:45 -
+Rule	sol87	1987	only	-	May	1	11:57:10s 0:02:50 -
+Rule	sol87	1987	only	-	May	2	11:57:00s 0:03:00 -
+Rule	sol87	1987	only	-	May	3	11:56:55s 0:03:05 -
+Rule	sol87	1987	only	-	May	4	11:56:50s 0:03:10 -
+Rule	sol87	1987	only	-	May	5	11:56:45s 0:03:15 -
+Rule	sol87	1987	only	-	May	6	11:56:40s 0:03:20 -
+Rule	sol87	1987	only	-	May	7	11:56:35s 0:03:25 -
+Rule	sol87	1987	only	-	May	8	11:56:30s 0:03:30 -
+Rule	sol87	1987	only	-	May	9	11:56:25s 0:03:35 -
+Rule	sol87	1987	only	-	May	10	11:56:25s 0:03:35 -
+Rule	sol87	1987	only	-	May	11	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	12	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	13	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	14	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	15	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	16	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	17	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	18	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	19	11:56:25s 0:03:35 -
+Rule	sol87	1987	only	-	May	20	11:56:25s 0:03:35 -
+Rule	sol87	1987	only	-	May	21	11:56:30s 0:03:30 -
+Rule	sol87	1987	only	-	May	22	11:56:35s 0:03:25 -
+Rule	sol87	1987	only	-	May	23	11:56:40s 0:03:20 -
+Rule	sol87	1987	only	-	May	24	11:56:45s 0:03:15 -
+Rule	sol87	1987	only	-	May	25	11:56:50s 0:03:10 -
+Rule	sol87	1987	only	-	May	26	11:56:55s 0:03:05 -
+Rule	sol87	1987	only	-	May	27	11:57:00s 0:03:00 -
+Rule	sol87	1987	only	-	May	28	11:57:10s 0:02:50 -
+Rule	sol87	1987	only	-	May	29	11:57:15s 0:02:45 -
+Rule	sol87	1987	only	-	May	30	11:57:25s 0:02:35 -
+Rule	sol87	1987	only	-	May	31	11:57:30s 0:02:30 -
+Rule	sol87	1987	only	-	Jun	1	11:57:40s 0:02:20 -
+Rule	sol87	1987	only	-	Jun	2	11:57:50s 0:02:10 -
+Rule	sol87	1987	only	-	Jun	3	11:58:00s 0:02:00 -
+Rule	sol87	1987	only	-	Jun	4	11:58:10s 0:01:50 -
+Rule	sol87	1987	only	-	Jun	5	11:58:20s 0:01:40 -
+Rule	sol87	1987	only	-	Jun	6	11:58:30s 0:01:30 -
+Rule	sol87	1987	only	-	Jun	7	11:58:40s 0:01:20 -
+Rule	sol87	1987	only	-	Jun	8	11:58:50s 0:01:10 -
+Rule	sol87	1987	only	-	Jun	9	11:59:05s 0:00:55 -
+Rule	sol87	1987	only	-	Jun	10	11:59:15s 0:00:45 -
+Rule	sol87	1987	only	-	Jun	11	11:59:30s 0:00:30 -
+Rule	sol87	1987	only	-	Jun	12	11:59:40s 0:00:20 -
+Rule	sol87	1987	only	-	Jun	13	11:59:50s 0:00:10 -
+Rule	sol87	1987	only	-	Jun	14	12:00:05s -0:00:05 -
+Rule	sol87	1987	only	-	Jun	15	12:00:15s -0:00:15 -
+Rule	sol87	1987	only	-	Jun	16	12:00:30s -0:00:30 -
+Rule	sol87	1987	only	-	Jun	17	12:00:45s -0:00:45 -
+Rule	sol87	1987	only	-	Jun	18	12:00:55s -0:00:55 -
+Rule	sol87	1987	only	-	Jun	19	12:01:10s -0:01:10 -
+Rule	sol87	1987	only	-	Jun	20	12:01:20s -0:01:20 -
+Rule	sol87	1987	only	-	Jun	21	12:01:35s -0:01:35 -
+Rule	sol87	1987	only	-	Jun	22	12:01:50s -0:01:50 -
+Rule	sol87	1987	only	-	Jun	23	12:02:00s -0:02:00 -
+Rule	sol87	1987	only	-	Jun	24	12:02:15s -0:02:15 -
+Rule	sol87	1987	only	-	Jun	25	12:02:25s -0:02:25 -
+Rule	sol87	1987	only	-	Jun	26	12:02:40s -0:02:40 -
+Rule	sol87	1987	only	-	Jun	27	12:02:50s -0:02:50 -
+Rule	sol87	1987	only	-	Jun	28	12:03:05s -0:03:05 -
+Rule	sol87	1987	only	-	Jun	29	12:03:15s -0:03:15 -
+Rule	sol87	1987	only	-	Jun	30	12:03:30s -0:03:30 -
+Rule	sol87	1987	only	-	Jul	1	12:03:40s -0:03:40 -
+Rule	sol87	1987	only	-	Jul	2	12:03:50s -0:03:50 -
+Rule	sol87	1987	only	-	Jul	3	12:04:05s -0:04:05 -
+Rule	sol87	1987	only	-	Jul	4	12:04:15s -0:04:15 -
+Rule	sol87	1987	only	-	Jul	5	12:04:25s -0:04:25 -
+Rule	sol87	1987	only	-	Jul	6	12:04:35s -0:04:35 -
+Rule	sol87	1987	only	-	Jul	7	12:04:45s -0:04:45 -
+Rule	sol87	1987	only	-	Jul	8	12:04:55s -0:04:55 -
+Rule	sol87	1987	only	-	Jul	9	12:05:05s -0:05:05 -
+Rule	sol87	1987	only	-	Jul	10	12:05:15s -0:05:15 -
+Rule	sol87	1987	only	-	Jul	11	12:05:20s -0:05:20 -
+Rule	sol87	1987	only	-	Jul	12	12:05:30s -0:05:30 -
+Rule	sol87	1987	only	-	Jul	13	12:05:40s -0:05:40 -
+Rule	sol87	1987	only	-	Jul	14	12:05:45s -0:05:45 -
+Rule	sol87	1987	only	-	Jul	15	12:05:50s -0:05:50 -
+Rule	sol87	1987	only	-	Jul	16	12:06:00s -0:06:00 -
+Rule	sol87	1987	only	-	Jul	17	12:06:05s -0:06:05 -
+Rule	sol87	1987	only	-	Jul	18	12:06:10s -0:06:10 -
+Rule	sol87	1987	only	-	Jul	19	12:06:15s -0:06:15 -
+Rule	sol87	1987	only	-	Jul	20	12:06:15s -0:06:15 -
+Rule	sol87	1987	only	-	Jul	21	12:06:20s -0:06:20 -
+Rule	sol87	1987	only	-	Jul	22	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	23	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	24	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	25	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jul	26	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jul	27	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jul	28	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jul	29	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	30	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	31	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Aug	1	12:06:20s -0:06:20 -
+Rule	sol87	1987	only	-	Aug	2	12:06:15s -0:06:15 -
+Rule	sol87	1987	only	-	Aug	3	12:06:10s -0:06:10 -
+Rule	sol87	1987	only	-	Aug	4	12:06:05s -0:06:05 -
+Rule	sol87	1987	only	-	Aug	5	12:06:00s -0:06:00 -
+Rule	sol87	1987	only	-	Aug	6	12:05:55s -0:05:55 -
+Rule	sol87	1987	only	-	Aug	7	12:05:50s -0:05:50 -
+Rule	sol87	1987	only	-	Aug	8	12:05:40s -0:05:40 -
+Rule	sol87	1987	only	-	Aug	9	12:05:35s -0:05:35 -
+Rule	sol87	1987	only	-	Aug	10	12:05:25s -0:05:25 -
+Rule	sol87	1987	only	-	Aug	11	12:05:15s -0:05:15 -
+Rule	sol87	1987	only	-	Aug	12	12:05:05s -0:05:05 -
+Rule	sol87	1987	only	-	Aug	13	12:04:55s -0:04:55 -
+Rule	sol87	1987	only	-	Aug	14	12:04:45s -0:04:45 -
+Rule	sol87	1987	only	-	Aug	15	12:04:35s -0:04:35 -
+Rule	sol87	1987	only	-	Aug	16	12:04:25s -0:04:25 -
+Rule	sol87	1987	only	-	Aug	17	12:04:10s -0:04:10 -
+Rule	sol87	1987	only	-	Aug	18	12:04:00s -0:04:00 -
+Rule	sol87	1987	only	-	Aug	19	12:03:45s -0:03:45 -
+Rule	sol87	1987	only	-	Aug	20	12:03:30s -0:03:30 -
+Rule	sol87	1987	only	-	Aug	21	12:03:15s -0:03:15 -
+Rule	sol87	1987	only	-	Aug	22	12:03:00s -0:03:00 -
+Rule	sol87	1987	only	-	Aug	23	12:02:45s -0:02:45 -
+Rule	sol87	1987	only	-	Aug	24	12:02:30s -0:02:30 -
+Rule	sol87	1987	only	-	Aug	25	12:02:15s -0:02:15 -
+Rule	sol87	1987	only	-	Aug	26	12:02:00s -0:02:00 -
+Rule	sol87	1987	only	-	Aug	27	12:01:40s -0:01:40 -
+Rule	sol87	1987	only	-	Aug	28	12:01:25s -0:01:25 -
+Rule	sol87	1987	only	-	Aug	29	12:01:05s -0:01:05 -
+Rule	sol87	1987	only	-	Aug	30	12:00:50s -0:00:50 -
+Rule	sol87	1987	only	-	Aug	31	12:00:30s -0:00:30 -
+Rule	sol87	1987	only	-	Sep	1	12:00:10s -0:00:10 -
+Rule	sol87	1987	only	-	Sep	2	11:59:50s 0:00:10 -
+Rule	sol87	1987	only	-	Sep	3	11:59:35s 0:00:25 -
+Rule	sol87	1987	only	-	Sep	4	11:59:15s 0:00:45 -
+Rule	sol87	1987	only	-	Sep	5	11:58:55s 0:01:05 -
+Rule	sol87	1987	only	-	Sep	6	11:58:35s 0:01:25 -
+Rule	sol87	1987	only	-	Sep	7	11:58:15s 0:01:45 -
+Rule	sol87	1987	only	-	Sep	8	11:57:55s 0:02:05 -
+Rule	sol87	1987	only	-	Sep	9	11:57:30s 0:02:30 -
+Rule	sol87	1987	only	-	Sep	10	11:57:10s 0:02:50 -
+Rule	sol87	1987	only	-	Sep	11	11:56:50s 0:03:10 -
+Rule	sol87	1987	only	-	Sep	12	11:56:30s 0:03:30 -
+Rule	sol87	1987	only	-	Sep	13	11:56:10s 0:03:50 -
+Rule	sol87	1987	only	-	Sep	14	11:55:45s 0:04:15 -
+Rule	sol87	1987	only	-	Sep	15	11:55:25s 0:04:35 -
+Rule	sol87	1987	only	-	Sep	16	11:55:05s 0:04:55 -
+Rule	sol87	1987	only	-	Sep	17	11:54:45s 0:05:15 -
+Rule	sol87	1987	only	-	Sep	18	11:54:20s 0:05:40 -
+Rule	sol87	1987	only	-	Sep	19	11:54:00s 0:06:00 -
+Rule	sol87	1987	only	-	Sep	20	11:53:40s 0:06:20 -
+Rule	sol87	1987	only	-	Sep	21	11:53:15s 0:06:45 -
+Rule	sol87	1987	only	-	Sep	22	11:52:55s 0:07:05 -
+Rule	sol87	1987	only	-	Sep	23	11:52:35s 0:07:25 -
+Rule	sol87	1987	only	-	Sep	24	11:52:15s 0:07:45 -
+Rule	sol87	1987	only	-	Sep	25	11:51:55s 0:08:05 -
+Rule	sol87	1987	only	-	Sep	26	11:51:35s 0:08:25 -
+Rule	sol87	1987	only	-	Sep	27	11:51:10s 0:08:50 -
+Rule	sol87	1987	only	-	Sep	28	11:50:50s 0:09:10 -
+Rule	sol87	1987	only	-	Sep	29	11:50:30s 0:09:30 -
+Rule	sol87	1987	only	-	Sep	30	11:50:10s 0:09:50 -
+Rule	sol87	1987	only	-	Oct	1	11:49:50s 0:10:10 -
+Rule	sol87	1987	only	-	Oct	2	11:49:35s 0:10:25 -
+Rule	sol87	1987	only	-	Oct	3	11:49:15s 0:10:45 -
+Rule	sol87	1987	only	-	Oct	4	11:48:55s 0:11:05 -
+Rule	sol87	1987	only	-	Oct	5	11:48:35s 0:11:25 -
+Rule	sol87	1987	only	-	Oct	6	11:48:20s 0:11:40 -
+Rule	sol87	1987	only	-	Oct	7	11:48:00s 0:12:00 -
+Rule	sol87	1987	only	-	Oct	8	11:47:45s 0:12:15 -
+Rule	sol87	1987	only	-	Oct	9	11:47:25s 0:12:35 -
+Rule	sol87	1987	only	-	Oct	10	11:47:10s 0:12:50 -
+Rule	sol87	1987	only	-	Oct	11	11:46:55s 0:13:05 -
+Rule	sol87	1987	only	-	Oct	12	11:46:40s 0:13:20 -
+Rule	sol87	1987	only	-	Oct	13	11:46:25s 0:13:35 -
+Rule	sol87	1987	only	-	Oct	14	11:46:10s 0:13:50 -
+Rule	sol87	1987	only	-	Oct	15	11:45:55s 0:14:05 -
+Rule	sol87	1987	only	-	Oct	16	11:45:45s 0:14:15 -
+Rule	sol87	1987	only	-	Oct	17	11:45:30s 0:14:30 -
+Rule	sol87	1987	only	-	Oct	18	11:45:20s 0:14:40 -
+Rule	sol87	1987	only	-	Oct	19	11:45:05s 0:14:55 -
+Rule	sol87	1987	only	-	Oct	20	11:44:55s 0:15:05 -
+Rule	sol87	1987	only	-	Oct	21	11:44:45s 0:15:15 -
+Rule	sol87	1987	only	-	Oct	22	11:44:35s 0:15:25 -
+Rule	sol87	1987	only	-	Oct	23	11:44:25s 0:15:35 -
+Rule	sol87	1987	only	-	Oct	24	11:44:20s 0:15:40 -
+Rule	sol87	1987	only	-	Oct	25	11:44:10s 0:15:50 -
+Rule	sol87	1987	only	-	Oct	26	11:44:05s 0:15:55 -
+Rule	sol87	1987	only	-	Oct	27	11:43:55s 0:16:05 -
+Rule	sol87	1987	only	-	Oct	28	11:43:50s 0:16:10 -
+Rule	sol87	1987	only	-	Oct	29	11:43:45s 0:16:15 -
+Rule	sol87	1987	only	-	Oct	30	11:43:45s 0:16:15 -
+Rule	sol87	1987	only	-	Oct	31	11:43:40s 0:16:20 -
+Rule	sol87	1987	only	-	Nov	1	11:43:40s 0:16:20 -
+Rule	sol87	1987	only	-	Nov	2	11:43:35s 0:16:25 -
+Rule	sol87	1987	only	-	Nov	3	11:43:35s 0:16:25 -
+Rule	sol87	1987	only	-	Nov	4	11:43:35s 0:16:25 -
+Rule	sol87	1987	only	-	Nov	5	11:43:35s 0:16:25 -
+Rule	sol87	1987	only	-	Nov	6	11:43:40s 0:16:20 -
+Rule	sol87	1987	only	-	Nov	7	11:43:40s 0:16:20 -
+Rule	sol87	1987	only	-	Nov	8	11:43:45s 0:16:15 -
+Rule	sol87	1987	only	-	Nov	9	11:43:50s 0:16:10 -
+Rule	sol87	1987	only	-	Nov	10	11:43:55s 0:16:05 -
+Rule	sol87	1987	only	-	Nov	11	11:44:00s 0:16:00 -
+Rule	sol87	1987	only	-	Nov	12	11:44:05s 0:15:55 -
+Rule	sol87	1987	only	-	Nov	13	11:44:15s 0:15:45 -
+Rule	sol87	1987	only	-	Nov	14	11:44:20s 0:15:40 -
+Rule	sol87	1987	only	-	Nov	15	11:44:30s 0:15:30 -
+Rule	sol87	1987	only	-	Nov	16	11:44:40s 0:15:20 -
+Rule	sol87	1987	only	-	Nov	17	11:44:50s 0:15:10 -
+Rule	sol87	1987	only	-	Nov	18	11:45:05s 0:14:55 -
+Rule	sol87	1987	only	-	Nov	19	11:45:15s 0:14:45 -
+Rule	sol87	1987	only	-	Nov	20	11:45:30s 0:14:30 -
+Rule	sol87	1987	only	-	Nov	21	11:45:45s 0:14:15 -
+Rule	sol87	1987	only	-	Nov	22	11:46:00s 0:14:00 -
+Rule	sol87	1987	only	-	Nov	23	11:46:15s 0:13:45 -
+Rule	sol87	1987	only	-	Nov	24	11:46:30s 0:13:30 -
+Rule	sol87	1987	only	-	Nov	25	11:46:50s 0:13:10 -
+Rule	sol87	1987	only	-	Nov	26	11:47:10s 0:12:50 -
+Rule	sol87	1987	only	-	Nov	27	11:47:25s 0:12:35 -
+Rule	sol87	1987	only	-	Nov	28	11:47:45s 0:12:15 -
+Rule	sol87	1987	only	-	Nov	29	11:48:05s 0:11:55 -
+Rule	sol87	1987	only	-	Nov	30	11:48:30s 0:11:30 -
+Rule	sol87	1987	only	-	Dec	1	11:48:50s 0:11:10 -
+Rule	sol87	1987	only	-	Dec	2	11:49:10s 0:10:50 -
+Rule	sol87	1987	only	-	Dec	3	11:49:35s 0:10:25 -
+Rule	sol87	1987	only	-	Dec	4	11:50:00s 0:10:00 -
+Rule	sol87	1987	only	-	Dec	5	11:50:25s 0:09:35 -
+Rule	sol87	1987	only	-	Dec	6	11:50:50s 0:09:10 -
+Rule	sol87	1987	only	-	Dec	7	11:51:15s 0:08:45 -
+Rule	sol87	1987	only	-	Dec	8	11:51:40s 0:08:20 -
+Rule	sol87	1987	only	-	Dec	9	11:52:05s 0:07:55 -
+Rule	sol87	1987	only	-	Dec	10	11:52:30s 0:07:30 -
+Rule	sol87	1987	only	-	Dec	11	11:53:00s 0:07:00 -
+Rule	sol87	1987	only	-	Dec	12	11:53:25s 0:06:35 -
+Rule	sol87	1987	only	-	Dec	13	11:53:55s 0:06:05 -
+Rule	sol87	1987	only	-	Dec	14	11:54:25s 0:05:35 -
+Rule	sol87	1987	only	-	Dec	15	11:54:50s 0:05:10 -
+Rule	sol87	1987	only	-	Dec	16	11:55:20s 0:04:40 -
+Rule	sol87	1987	only	-	Dec	17	11:55:50s 0:04:10 -
+Rule	sol87	1987	only	-	Dec	18	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	Dec	19	11:56:50s 0:03:10 -
+Rule	sol87	1987	only	-	Dec	20	11:57:20s 0:02:40 -
+Rule	sol87	1987	only	-	Dec	21	11:57:50s 0:02:10 -
+Rule	sol87	1987	only	-	Dec	22	11:58:20s 0:01:40 -
+Rule	sol87	1987	only	-	Dec	23	11:58:50s 0:01:10 -
+Rule	sol87	1987	only	-	Dec	24	11:59:20s 0:00:40 -
+Rule	sol87	1987	only	-	Dec	25	11:59:50s 0:00:10 -
+Rule	sol87	1987	only	-	Dec	26	12:00:20s -0:00:20 -
+Rule	sol87	1987	only	-	Dec	27	12:00:45s -0:00:45 -
+Rule	sol87	1987	only	-	Dec	28	12:01:15s -0:01:15 -
+Rule	sol87	1987	only	-	Dec	29	12:01:45s -0:01:45 -
+Rule	sol87	1987	only	-	Dec	30	12:02:15s -0:02:15 -
+Rule	sol87	1987	only	-	Dec	31	12:02:45s -0:02:45 -
+
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
+# Before and after 1987, we'll operate on local mean solar time.
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	Asia/Riyadh87	3:07:04	-		zzz	1987
+			3:07:04	sol87		zzz	1988
+			3:07:04	-		zzz
+# For backward compatibility...
+Link	Asia/Riyadh87	Mideast/Riyadh87
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/solar88 b/jdk/test/sun/util/calendar/zi/tzdata/solar88
new file mode 100644
index 0000000..71b60d5
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/solar88
@@ -0,0 +1,413 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# Apparent noon times below are for Riyadh; they're a bit off for other places.
+# Times were computed using formulas in the U.S. Naval Observatory's
+# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of
+# [plus or minus two] seconds during the current year."
+#
+# Rounding to the nearest five seconds results in fewer than
+# 256 different "time types"--a limit that's faced because time types are
+# stored on disk as unsigned chars.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	sol88	1988	only	-	Jan	1	12:03:15s -0:03:15 -
+Rule	sol88	1988	only	-	Jan	2	12:03:40s -0:03:40 -
+Rule	sol88	1988	only	-	Jan	3	12:04:10s -0:04:10 -
+Rule	sol88	1988	only	-	Jan	4	12:04:40s -0:04:40 -
+Rule	sol88	1988	only	-	Jan	5	12:05:05s -0:05:05 -
+Rule	sol88	1988	only	-	Jan	6	12:05:30s -0:05:30 -
+Rule	sol88	1988	only	-	Jan	7	12:06:00s -0:06:00 -
+Rule	sol88	1988	only	-	Jan	8	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jan	9	12:06:50s -0:06:50 -
+Rule	sol88	1988	only	-	Jan	10	12:07:15s -0:07:15 -
+Rule	sol88	1988	only	-	Jan	11	12:07:40s -0:07:40 -
+Rule	sol88	1988	only	-	Jan	12	12:08:05s -0:08:05 -
+Rule	sol88	1988	only	-	Jan	13	12:08:25s -0:08:25 -
+Rule	sol88	1988	only	-	Jan	14	12:08:50s -0:08:50 -
+Rule	sol88	1988	only	-	Jan	15	12:09:10s -0:09:10 -
+Rule	sol88	1988	only	-	Jan	16	12:09:30s -0:09:30 -
+Rule	sol88	1988	only	-	Jan	17	12:09:50s -0:09:50 -
+Rule	sol88	1988	only	-	Jan	18	12:10:10s -0:10:10 -
+Rule	sol88	1988	only	-	Jan	19	12:10:30s -0:10:30 -
+Rule	sol88	1988	only	-	Jan	20	12:10:50s -0:10:50 -
+Rule	sol88	1988	only	-	Jan	21	12:11:05s -0:11:05 -
+Rule	sol88	1988	only	-	Jan	22	12:11:25s -0:11:25 -
+Rule	sol88	1988	only	-	Jan	23	12:11:40s -0:11:40 -
+Rule	sol88	1988	only	-	Jan	24	12:11:55s -0:11:55 -
+Rule	sol88	1988	only	-	Jan	25	12:12:10s -0:12:10 -
+Rule	sol88	1988	only	-	Jan	26	12:12:25s -0:12:25 -
+Rule	sol88	1988	only	-	Jan	27	12:12:40s -0:12:40 -
+Rule	sol88	1988	only	-	Jan	28	12:12:50s -0:12:50 -
+Rule	sol88	1988	only	-	Jan	29	12:13:00s -0:13:00 -
+Rule	sol88	1988	only	-	Jan	30	12:13:10s -0:13:10 -
+Rule	sol88	1988	only	-	Jan	31	12:13:20s -0:13:20 -
+Rule	sol88	1988	only	-	Feb	1	12:13:30s -0:13:30 -
+Rule	sol88	1988	only	-	Feb	2	12:13:40s -0:13:40 -
+Rule	sol88	1988	only	-	Feb	3	12:13:45s -0:13:45 -
+Rule	sol88	1988	only	-	Feb	4	12:13:55s -0:13:55 -
+Rule	sol88	1988	only	-	Feb	5	12:14:00s -0:14:00 -
+Rule	sol88	1988	only	-	Feb	6	12:14:05s -0:14:05 -
+Rule	sol88	1988	only	-	Feb	7	12:14:10s -0:14:10 -
+Rule	sol88	1988	only	-	Feb	8	12:14:10s -0:14:10 -
+Rule	sol88	1988	only	-	Feb	9	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	10	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	11	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	12	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	13	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	14	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	15	12:14:10s -0:14:10 -
+Rule	sol88	1988	only	-	Feb	16	12:14:10s -0:14:10 -
+Rule	sol88	1988	only	-	Feb	17	12:14:05s -0:14:05 -
+Rule	sol88	1988	only	-	Feb	18	12:14:00s -0:14:00 -
+Rule	sol88	1988	only	-	Feb	19	12:13:55s -0:13:55 -
+Rule	sol88	1988	only	-	Feb	20	12:13:50s -0:13:50 -
+Rule	sol88	1988	only	-	Feb	21	12:13:45s -0:13:45 -
+Rule	sol88	1988	only	-	Feb	22	12:13:40s -0:13:40 -
+Rule	sol88	1988	only	-	Feb	23	12:13:30s -0:13:30 -
+Rule	sol88	1988	only	-	Feb	24	12:13:20s -0:13:20 -
+Rule	sol88	1988	only	-	Feb	25	12:13:15s -0:13:15 -
+Rule	sol88	1988	only	-	Feb	26	12:13:05s -0:13:05 -
+Rule	sol88	1988	only	-	Feb	27	12:12:55s -0:12:55 -
+Rule	sol88	1988	only	-	Feb	28	12:12:45s -0:12:45 -
+Rule	sol88	1988	only	-	Feb	29	12:12:30s -0:12:30 -
+Rule	sol88	1988	only	-	Mar	1	12:12:20s -0:12:20 -
+Rule	sol88	1988	only	-	Mar	2	12:12:10s -0:12:10 -
+Rule	sol88	1988	only	-	Mar	3	12:11:55s -0:11:55 -
+Rule	sol88	1988	only	-	Mar	4	12:11:45s -0:11:45 -
+Rule	sol88	1988	only	-	Mar	5	12:11:30s -0:11:30 -
+Rule	sol88	1988	only	-	Mar	6	12:11:15s -0:11:15 -
+Rule	sol88	1988	only	-	Mar	7	12:11:00s -0:11:00 -
+Rule	sol88	1988	only	-	Mar	8	12:10:45s -0:10:45 -
+Rule	sol88	1988	only	-	Mar	9	12:10:30s -0:10:30 -
+Rule	sol88	1988	only	-	Mar	10	12:10:15s -0:10:15 -
+Rule	sol88	1988	only	-	Mar	11	12:10:00s -0:10:00 -
+Rule	sol88	1988	only	-	Mar	12	12:09:45s -0:09:45 -
+Rule	sol88	1988	only	-	Mar	13	12:09:30s -0:09:30 -
+Rule	sol88	1988	only	-	Mar	14	12:09:10s -0:09:10 -
+Rule	sol88	1988	only	-	Mar	15	12:08:55s -0:08:55 -
+Rule	sol88	1988	only	-	Mar	16	12:08:40s -0:08:40 -
+Rule	sol88	1988	only	-	Mar	17	12:08:20s -0:08:20 -
+Rule	sol88	1988	only	-	Mar	18	12:08:05s -0:08:05 -
+Rule	sol88	1988	only	-	Mar	19	12:07:45s -0:07:45 -
+Rule	sol88	1988	only	-	Mar	20	12:07:30s -0:07:30 -
+Rule	sol88	1988	only	-	Mar	21	12:07:10s -0:07:10 -
+Rule	sol88	1988	only	-	Mar	22	12:06:50s -0:06:50 -
+Rule	sol88	1988	only	-	Mar	23	12:06:35s -0:06:35 -
+Rule	sol88	1988	only	-	Mar	24	12:06:15s -0:06:15 -
+Rule	sol88	1988	only	-	Mar	25	12:06:00s -0:06:00 -
+Rule	sol88	1988	only	-	Mar	26	12:05:40s -0:05:40 -
+Rule	sol88	1988	only	-	Mar	27	12:05:20s -0:05:20 -
+Rule	sol88	1988	only	-	Mar	28	12:05:05s -0:05:05 -
+Rule	sol88	1988	only	-	Mar	29	12:04:45s -0:04:45 -
+Rule	sol88	1988	only	-	Mar	30	12:04:25s -0:04:25 -
+Rule	sol88	1988	only	-	Mar	31	12:04:10s -0:04:10 -
+Rule	sol88	1988	only	-	Apr	1	12:03:50s -0:03:50 -
+Rule	sol88	1988	only	-	Apr	2	12:03:35s -0:03:35 -
+Rule	sol88	1988	only	-	Apr	3	12:03:15s -0:03:15 -
+Rule	sol88	1988	only	-	Apr	4	12:03:00s -0:03:00 -
+Rule	sol88	1988	only	-	Apr	5	12:02:40s -0:02:40 -
+Rule	sol88	1988	only	-	Apr	6	12:02:25s -0:02:25 -
+Rule	sol88	1988	only	-	Apr	7	12:02:05s -0:02:05 -
+Rule	sol88	1988	only	-	Apr	8	12:01:50s -0:01:50 -
+Rule	sol88	1988	only	-	Apr	9	12:01:35s -0:01:35 -
+Rule	sol88	1988	only	-	Apr	10	12:01:15s -0:01:15 -
+Rule	sol88	1988	only	-	Apr	11	12:01:00s -0:01:00 -
+Rule	sol88	1988	only	-	Apr	12	12:00:45s -0:00:45 -
+Rule	sol88	1988	only	-	Apr	13	12:00:30s -0:00:30 -
+Rule	sol88	1988	only	-	Apr	14	12:00:15s -0:00:15 -
+Rule	sol88	1988	only	-	Apr	15	12:00:00s 0:00:00 -
+Rule	sol88	1988	only	-	Apr	16	11:59:45s 0:00:15 -
+Rule	sol88	1988	only	-	Apr	17	11:59:30s 0:00:30 -
+Rule	sol88	1988	only	-	Apr	18	11:59:20s 0:00:40 -
+Rule	sol88	1988	only	-	Apr	19	11:59:05s 0:00:55 -
+Rule	sol88	1988	only	-	Apr	20	11:58:55s 0:01:05 -
+Rule	sol88	1988	only	-	Apr	21	11:58:40s 0:01:20 -
+Rule	sol88	1988	only	-	Apr	22	11:58:30s 0:01:30 -
+Rule	sol88	1988	only	-	Apr	23	11:58:15s 0:01:45 -
+Rule	sol88	1988	only	-	Apr	24	11:58:05s 0:01:55 -
+Rule	sol88	1988	only	-	Apr	25	11:57:55s 0:02:05 -
+Rule	sol88	1988	only	-	Apr	26	11:57:45s 0:02:15 -
+Rule	sol88	1988	only	-	Apr	27	11:57:35s 0:02:25 -
+Rule	sol88	1988	only	-	Apr	28	11:57:30s 0:02:30 -
+Rule	sol88	1988	only	-	Apr	29	11:57:20s 0:02:40 -
+Rule	sol88	1988	only	-	Apr	30	11:57:10s 0:02:50 -
+Rule	sol88	1988	only	-	May	1	11:57:05s 0:02:55 -
+Rule	sol88	1988	only	-	May	2	11:56:55s 0:03:05 -
+Rule	sol88	1988	only	-	May	3	11:56:50s 0:03:10 -
+Rule	sol88	1988	only	-	May	4	11:56:45s 0:03:15 -
+Rule	sol88	1988	only	-	May	5	11:56:40s 0:03:20 -
+Rule	sol88	1988	only	-	May	6	11:56:35s 0:03:25 -
+Rule	sol88	1988	only	-	May	7	11:56:30s 0:03:30 -
+Rule	sol88	1988	only	-	May	8	11:56:25s 0:03:35 -
+Rule	sol88	1988	only	-	May	9	11:56:25s 0:03:35 -
+Rule	sol88	1988	only	-	May	10	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	11	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	12	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	13	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	14	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	15	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	16	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	17	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	18	11:56:25s 0:03:35 -
+Rule	sol88	1988	only	-	May	19	11:56:25s 0:03:35 -
+Rule	sol88	1988	only	-	May	20	11:56:30s 0:03:30 -
+Rule	sol88	1988	only	-	May	21	11:56:35s 0:03:25 -
+Rule	sol88	1988	only	-	May	22	11:56:40s 0:03:20 -
+Rule	sol88	1988	only	-	May	23	11:56:45s 0:03:15 -
+Rule	sol88	1988	only	-	May	24	11:56:50s 0:03:10 -
+Rule	sol88	1988	only	-	May	25	11:56:55s 0:03:05 -
+Rule	sol88	1988	only	-	May	26	11:57:00s 0:03:00 -
+Rule	sol88	1988	only	-	May	27	11:57:05s 0:02:55 -
+Rule	sol88	1988	only	-	May	28	11:57:15s 0:02:45 -
+Rule	sol88	1988	only	-	May	29	11:57:20s 0:02:40 -
+Rule	sol88	1988	only	-	May	30	11:57:30s 0:02:30 -
+Rule	sol88	1988	only	-	May	31	11:57:40s 0:02:20 -
+Rule	sol88	1988	only	-	Jun	1	11:57:50s 0:02:10 -
+Rule	sol88	1988	only	-	Jun	2	11:57:55s 0:02:05 -
+Rule	sol88	1988	only	-	Jun	3	11:58:05s 0:01:55 -
+Rule	sol88	1988	only	-	Jun	4	11:58:15s 0:01:45 -
+Rule	sol88	1988	only	-	Jun	5	11:58:30s 0:01:30 -
+Rule	sol88	1988	only	-	Jun	6	11:58:40s 0:01:20 -
+Rule	sol88	1988	only	-	Jun	7	11:58:50s 0:01:10 -
+Rule	sol88	1988	only	-	Jun	8	11:59:00s 0:01:00 -
+Rule	sol88	1988	only	-	Jun	9	11:59:15s 0:00:45 -
+Rule	sol88	1988	only	-	Jun	10	11:59:25s 0:00:35 -
+Rule	sol88	1988	only	-	Jun	11	11:59:35s 0:00:25 -
+Rule	sol88	1988	only	-	Jun	12	11:59:50s 0:00:10 -
+Rule	sol88	1988	only	-	Jun	13	12:00:00s 0:00:00 -
+Rule	sol88	1988	only	-	Jun	14	12:00:15s -0:00:15 -
+Rule	sol88	1988	only	-	Jun	15	12:00:25s -0:00:25 -
+Rule	sol88	1988	only	-	Jun	16	12:00:40s -0:00:40 -
+Rule	sol88	1988	only	-	Jun	17	12:00:55s -0:00:55 -
+Rule	sol88	1988	only	-	Jun	18	12:01:05s -0:01:05 -
+Rule	sol88	1988	only	-	Jun	19	12:01:20s -0:01:20 -
+Rule	sol88	1988	only	-	Jun	20	12:01:30s -0:01:30 -
+Rule	sol88	1988	only	-	Jun	21	12:01:45s -0:01:45 -
+Rule	sol88	1988	only	-	Jun	22	12:02:00s -0:02:00 -
+Rule	sol88	1988	only	-	Jun	23	12:02:10s -0:02:10 -
+Rule	sol88	1988	only	-	Jun	24	12:02:25s -0:02:25 -
+Rule	sol88	1988	only	-	Jun	25	12:02:35s -0:02:35 -
+Rule	sol88	1988	only	-	Jun	26	12:02:50s -0:02:50 -
+Rule	sol88	1988	only	-	Jun	27	12:03:00s -0:03:00 -
+Rule	sol88	1988	only	-	Jun	28	12:03:15s -0:03:15 -
+Rule	sol88	1988	only	-	Jun	29	12:03:25s -0:03:25 -
+Rule	sol88	1988	only	-	Jun	30	12:03:40s -0:03:40 -
+Rule	sol88	1988	only	-	Jul	1	12:03:50s -0:03:50 -
+Rule	sol88	1988	only	-	Jul	2	12:04:00s -0:04:00 -
+Rule	sol88	1988	only	-	Jul	3	12:04:10s -0:04:10 -
+Rule	sol88	1988	only	-	Jul	4	12:04:25s -0:04:25 -
+Rule	sol88	1988	only	-	Jul	5	12:04:35s -0:04:35 -
+Rule	sol88	1988	only	-	Jul	6	12:04:45s -0:04:45 -
+Rule	sol88	1988	only	-	Jul	7	12:04:55s -0:04:55 -
+Rule	sol88	1988	only	-	Jul	8	12:05:05s -0:05:05 -
+Rule	sol88	1988	only	-	Jul	9	12:05:10s -0:05:10 -
+Rule	sol88	1988	only	-	Jul	10	12:05:20s -0:05:20 -
+Rule	sol88	1988	only	-	Jul	11	12:05:30s -0:05:30 -
+Rule	sol88	1988	only	-	Jul	12	12:05:35s -0:05:35 -
+Rule	sol88	1988	only	-	Jul	13	12:05:45s -0:05:45 -
+Rule	sol88	1988	only	-	Jul	14	12:05:50s -0:05:50 -
+Rule	sol88	1988	only	-	Jul	15	12:05:55s -0:05:55 -
+Rule	sol88	1988	only	-	Jul	16	12:06:00s -0:06:00 -
+Rule	sol88	1988	only	-	Jul	17	12:06:05s -0:06:05 -
+Rule	sol88	1988	only	-	Jul	18	12:06:10s -0:06:10 -
+Rule	sol88	1988	only	-	Jul	19	12:06:15s -0:06:15 -
+Rule	sol88	1988	only	-	Jul	20	12:06:20s -0:06:20 -
+Rule	sol88	1988	only	-	Jul	21	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	22	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	23	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	24	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	25	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	26	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	27	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	28	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	29	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	30	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	31	12:06:20s -0:06:20 -
+Rule	sol88	1988	only	-	Aug	1	12:06:15s -0:06:15 -
+Rule	sol88	1988	only	-	Aug	2	12:06:15s -0:06:15 -
+Rule	sol88	1988	only	-	Aug	3	12:06:10s -0:06:10 -
+Rule	sol88	1988	only	-	Aug	4	12:06:05s -0:06:05 -
+Rule	sol88	1988	only	-	Aug	5	12:05:55s -0:05:55 -
+Rule	sol88	1988	only	-	Aug	6	12:05:50s -0:05:50 -
+Rule	sol88	1988	only	-	Aug	7	12:05:45s -0:05:45 -
+Rule	sol88	1988	only	-	Aug	8	12:05:35s -0:05:35 -
+Rule	sol88	1988	only	-	Aug	9	12:05:25s -0:05:25 -
+Rule	sol88	1988	only	-	Aug	10	12:05:20s -0:05:20 -
+Rule	sol88	1988	only	-	Aug	11	12:05:10s -0:05:10 -
+Rule	sol88	1988	only	-	Aug	12	12:05:00s -0:05:00 -
+Rule	sol88	1988	only	-	Aug	13	12:04:50s -0:04:50 -
+Rule	sol88	1988	only	-	Aug	14	12:04:35s -0:04:35 -
+Rule	sol88	1988	only	-	Aug	15	12:04:25s -0:04:25 -
+Rule	sol88	1988	only	-	Aug	16	12:04:15s -0:04:15 -
+Rule	sol88	1988	only	-	Aug	17	12:04:00s -0:04:00 -
+Rule	sol88	1988	only	-	Aug	18	12:03:50s -0:03:50 -
+Rule	sol88	1988	only	-	Aug	19	12:03:35s -0:03:35 -
+Rule	sol88	1988	only	-	Aug	20	12:03:20s -0:03:20 -
+Rule	sol88	1988	only	-	Aug	21	12:03:05s -0:03:05 -
+Rule	sol88	1988	only	-	Aug	22	12:02:50s -0:02:50 -
+Rule	sol88	1988	only	-	Aug	23	12:02:35s -0:02:35 -
+Rule	sol88	1988	only	-	Aug	24	12:02:20s -0:02:20 -
+Rule	sol88	1988	only	-	Aug	25	12:02:00s -0:02:00 -
+Rule	sol88	1988	only	-	Aug	26	12:01:45s -0:01:45 -
+Rule	sol88	1988	only	-	Aug	27	12:01:30s -0:01:30 -
+Rule	sol88	1988	only	-	Aug	28	12:01:10s -0:01:10 -
+Rule	sol88	1988	only	-	Aug	29	12:00:50s -0:00:50 -
+Rule	sol88	1988	only	-	Aug	30	12:00:35s -0:00:35 -
+Rule	sol88	1988	only	-	Aug	31	12:00:15s -0:00:15 -
+Rule	sol88	1988	only	-	Sep	1	11:59:55s 0:00:05 -
+Rule	sol88	1988	only	-	Sep	2	11:59:35s 0:00:25 -
+Rule	sol88	1988	only	-	Sep	3	11:59:20s 0:00:40 -
+Rule	sol88	1988	only	-	Sep	4	11:59:00s 0:01:00 -
+Rule	sol88	1988	only	-	Sep	5	11:58:40s 0:01:20 -
+Rule	sol88	1988	only	-	Sep	6	11:58:20s 0:01:40 -
+Rule	sol88	1988	only	-	Sep	7	11:58:00s 0:02:00 -
+Rule	sol88	1988	only	-	Sep	8	11:57:35s 0:02:25 -
+Rule	sol88	1988	only	-	Sep	9	11:57:15s 0:02:45 -
+Rule	sol88	1988	only	-	Sep	10	11:56:55s 0:03:05 -
+Rule	sol88	1988	only	-	Sep	11	11:56:35s 0:03:25 -
+Rule	sol88	1988	only	-	Sep	12	11:56:15s 0:03:45 -
+Rule	sol88	1988	only	-	Sep	13	11:55:50s 0:04:10 -
+Rule	sol88	1988	only	-	Sep	14	11:55:30s 0:04:30 -
+Rule	sol88	1988	only	-	Sep	15	11:55:10s 0:04:50 -
+Rule	sol88	1988	only	-	Sep	16	11:54:50s 0:05:10 -
+Rule	sol88	1988	only	-	Sep	17	11:54:25s 0:05:35 -
+Rule	sol88	1988	only	-	Sep	18	11:54:05s 0:05:55 -
+Rule	sol88	1988	only	-	Sep	19	11:53:45s 0:06:15 -
+Rule	sol88	1988	only	-	Sep	20	11:53:25s 0:06:35 -
+Rule	sol88	1988	only	-	Sep	21	11:53:00s 0:07:00 -
+Rule	sol88	1988	only	-	Sep	22	11:52:40s 0:07:20 -
+Rule	sol88	1988	only	-	Sep	23	11:52:20s 0:07:40 -
+Rule	sol88	1988	only	-	Sep	24	11:52:00s 0:08:00 -
+Rule	sol88	1988	only	-	Sep	25	11:51:40s 0:08:20 -
+Rule	sol88	1988	only	-	Sep	26	11:51:15s 0:08:45 -
+Rule	sol88	1988	only	-	Sep	27	11:50:55s 0:09:05 -
+Rule	sol88	1988	only	-	Sep	28	11:50:35s 0:09:25 -
+Rule	sol88	1988	only	-	Sep	29	11:50:15s 0:09:45 -
+Rule	sol88	1988	only	-	Sep	30	11:49:55s 0:10:05 -
+Rule	sol88	1988	only	-	Oct	1	11:49:35s 0:10:25 -
+Rule	sol88	1988	only	-	Oct	2	11:49:20s 0:10:40 -
+Rule	sol88	1988	only	-	Oct	3	11:49:00s 0:11:00 -
+Rule	sol88	1988	only	-	Oct	4	11:48:40s 0:11:20 -
+Rule	sol88	1988	only	-	Oct	5	11:48:25s 0:11:35 -
+Rule	sol88	1988	only	-	Oct	6	11:48:05s 0:11:55 -
+Rule	sol88	1988	only	-	Oct	7	11:47:50s 0:12:10 -
+Rule	sol88	1988	only	-	Oct	8	11:47:30s 0:12:30 -
+Rule	sol88	1988	only	-	Oct	9	11:47:15s 0:12:45 -
+Rule	sol88	1988	only	-	Oct	10	11:47:00s 0:13:00 -
+Rule	sol88	1988	only	-	Oct	11	11:46:45s 0:13:15 -
+Rule	sol88	1988	only	-	Oct	12	11:46:30s 0:13:30 -
+Rule	sol88	1988	only	-	Oct	13	11:46:15s 0:13:45 -
+Rule	sol88	1988	only	-	Oct	14	11:46:00s 0:14:00 -
+Rule	sol88	1988	only	-	Oct	15	11:45:45s 0:14:15 -
+Rule	sol88	1988	only	-	Oct	16	11:45:35s 0:14:25 -
+Rule	sol88	1988	only	-	Oct	17	11:45:20s 0:14:40 -
+Rule	sol88	1988	only	-	Oct	18	11:45:10s 0:14:50 -
+Rule	sol88	1988	only	-	Oct	19	11:45:00s 0:15:00 -
+Rule	sol88	1988	only	-	Oct	20	11:44:45s 0:15:15 -
+Rule	sol88	1988	only	-	Oct	21	11:44:40s 0:15:20 -
+Rule	sol88	1988	only	-	Oct	22	11:44:30s 0:15:30 -
+Rule	sol88	1988	only	-	Oct	23	11:44:20s 0:15:40 -
+Rule	sol88	1988	only	-	Oct	24	11:44:10s 0:15:50 -
+Rule	sol88	1988	only	-	Oct	25	11:44:05s 0:15:55 -
+Rule	sol88	1988	only	-	Oct	26	11:44:00s 0:16:00 -
+Rule	sol88	1988	only	-	Oct	27	11:43:55s 0:16:05 -
+Rule	sol88	1988	only	-	Oct	28	11:43:50s 0:16:10 -
+Rule	sol88	1988	only	-	Oct	29	11:43:45s 0:16:15 -
+Rule	sol88	1988	only	-	Oct	30	11:43:40s 0:16:20 -
+Rule	sol88	1988	only	-	Oct	31	11:43:40s 0:16:20 -
+Rule	sol88	1988	only	-	Nov	1	11:43:35s 0:16:25 -
+Rule	sol88	1988	only	-	Nov	2	11:43:35s 0:16:25 -
+Rule	sol88	1988	only	-	Nov	3	11:43:35s 0:16:25 -
+Rule	sol88	1988	only	-	Nov	4	11:43:35s 0:16:25 -
+Rule	sol88	1988	only	-	Nov	5	11:43:40s 0:16:20 -
+Rule	sol88	1988	only	-	Nov	6	11:43:40s 0:16:20 -
+Rule	sol88	1988	only	-	Nov	7	11:43:45s 0:16:15 -
+Rule	sol88	1988	only	-	Nov	8	11:43:45s 0:16:15 -
+Rule	sol88	1988	only	-	Nov	9	11:43:50s 0:16:10 -
+Rule	sol88	1988	only	-	Nov	10	11:44:00s 0:16:00 -
+Rule	sol88	1988	only	-	Nov	11	11:44:05s 0:15:55 -
+Rule	sol88	1988	only	-	Nov	12	11:44:10s 0:15:50 -
+Rule	sol88	1988	only	-	Nov	13	11:44:20s 0:15:40 -
+Rule	sol88	1988	only	-	Nov	14	11:44:30s 0:15:30 -
+Rule	sol88	1988	only	-	Nov	15	11:44:40s 0:15:20 -
+Rule	sol88	1988	only	-	Nov	16	11:44:50s 0:15:10 -
+Rule	sol88	1988	only	-	Nov	17	11:45:00s 0:15:00 -
+Rule	sol88	1988	only	-	Nov	18	11:45:15s 0:14:45 -
+Rule	sol88	1988	only	-	Nov	19	11:45:25s 0:14:35 -
+Rule	sol88	1988	only	-	Nov	20	11:45:40s 0:14:20 -
+Rule	sol88	1988	only	-	Nov	21	11:45:55s 0:14:05 -
+Rule	sol88	1988	only	-	Nov	22	11:46:10s 0:13:50 -
+Rule	sol88	1988	only	-	Nov	23	11:46:30s 0:13:30 -
+Rule	sol88	1988	only	-	Nov	24	11:46:45s 0:13:15 -
+Rule	sol88	1988	only	-	Nov	25	11:47:05s 0:12:55 -
+Rule	sol88	1988	only	-	Nov	26	11:47:20s 0:12:40 -
+Rule	sol88	1988	only	-	Nov	27	11:47:40s 0:12:20 -
+Rule	sol88	1988	only	-	Nov	28	11:48:00s 0:12:00 -
+Rule	sol88	1988	only	-	Nov	29	11:48:25s 0:11:35 -
+Rule	sol88	1988	only	-	Nov	30	11:48:45s 0:11:15 -
+Rule	sol88	1988	only	-	Dec	1	11:49:05s 0:10:55 -
+Rule	sol88	1988	only	-	Dec	2	11:49:30s 0:10:30 -
+Rule	sol88	1988	only	-	Dec	3	11:49:55s 0:10:05 -
+Rule	sol88	1988	only	-	Dec	4	11:50:15s 0:09:45 -
+Rule	sol88	1988	only	-	Dec	5	11:50:40s 0:09:20 -
+Rule	sol88	1988	only	-	Dec	6	11:51:05s 0:08:55 -
+Rule	sol88	1988	only	-	Dec	7	11:51:35s 0:08:25 -
+Rule	sol88	1988	only	-	Dec	8	11:52:00s 0:08:00 -
+Rule	sol88	1988	only	-	Dec	9	11:52:25s 0:07:35 -
+Rule	sol88	1988	only	-	Dec	10	11:52:55s 0:07:05 -
+Rule	sol88	1988	only	-	Dec	11	11:53:20s 0:06:40 -
+Rule	sol88	1988	only	-	Dec	12	11:53:50s 0:06:10 -
+Rule	sol88	1988	only	-	Dec	13	11:54:15s 0:05:45 -
+Rule	sol88	1988	only	-	Dec	14	11:54:45s 0:05:15 -
+Rule	sol88	1988	only	-	Dec	15	11:55:15s 0:04:45 -
+Rule	sol88	1988	only	-	Dec	16	11:55:45s 0:04:15 -
+Rule	sol88	1988	only	-	Dec	17	11:56:15s 0:03:45 -
+Rule	sol88	1988	only	-	Dec	18	11:56:40s 0:03:20 -
+Rule	sol88	1988	only	-	Dec	19	11:57:10s 0:02:50 -
+Rule	sol88	1988	only	-	Dec	20	11:57:40s 0:02:20 -
+Rule	sol88	1988	only	-	Dec	21	11:58:10s 0:01:50 -
+Rule	sol88	1988	only	-	Dec	22	11:58:40s 0:01:20 -
+Rule	sol88	1988	only	-	Dec	23	11:59:10s 0:00:50 -
+Rule	sol88	1988	only	-	Dec	24	11:59:40s 0:00:20 -
+Rule	sol88	1988	only	-	Dec	25	12:00:10s -0:00:10 -
+Rule	sol88	1988	only	-	Dec	26	12:00:40s -0:00:40 -
+Rule	sol88	1988	only	-	Dec	27	12:01:10s -0:01:10 -
+Rule	sol88	1988	only	-	Dec	28	12:01:40s -0:01:40 -
+Rule	sol88	1988	only	-	Dec	29	12:02:10s -0:02:10 -
+Rule	sol88	1988	only	-	Dec	30	12:02:35s -0:02:35 -
+Rule	sol88	1988	only	-	Dec	31	12:03:05s -0:03:05 -
+
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
+# Before and after 1988, we'll operate on local mean solar time.
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	Asia/Riyadh88	3:07:04	-		zzz	1988
+			3:07:04	sol88		zzz	1989
+			3:07:04	-		zzz
+# For backward compatibility...
+Link	Asia/Riyadh88	Mideast/Riyadh88
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/solar89 b/jdk/test/sun/util/calendar/zi/tzdata/solar89
new file mode 100644
index 0000000..ae2bea88
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/solar89
@@ -0,0 +1,418 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# Apparent noon times below are for Riyadh; they're a bit off for other places.
+# Times were computed using a formula provided by the U. S. Naval Observatory:
+#	eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l)
+#		-12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l)
+#		+ 19.3 * cos(3 * l);
+# where l is the "mean longitude of the Sun" given by
+#	l = 279.642 degrees + 0.985647 * d
+# and d is the interval in days from January 0, 0 hours Universal Time
+# (equaling the day of the year plus the fraction of a day from zero hours).
+# The accuracy of the formula is plus or minus three seconds.
+#
+# Rounding to the nearest five seconds results in fewer than
+# 256 different "time types"--a limit that's faced because time types are
+# stored on disk as unsigned chars.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	sol89	1989	only	-	Jan	1	12:03:35s -0:03:35 -
+Rule	sol89	1989	only	-	Jan	2	12:04:05s -0:04:05 -
+Rule	sol89	1989	only	-	Jan	3	12:04:30s -0:04:30 -
+Rule	sol89	1989	only	-	Jan	4	12:05:00s -0:05:00 -
+Rule	sol89	1989	only	-	Jan	5	12:05:25s -0:05:25 -
+Rule	sol89	1989	only	-	Jan	6	12:05:50s -0:05:50 -
+Rule	sol89	1989	only	-	Jan	7	12:06:15s -0:06:15 -
+Rule	sol89	1989	only	-	Jan	8	12:06:45s -0:06:45 -
+Rule	sol89	1989	only	-	Jan	9	12:07:10s -0:07:10 -
+Rule	sol89	1989	only	-	Jan	10	12:07:35s -0:07:35 -
+Rule	sol89	1989	only	-	Jan	11	12:07:55s -0:07:55 -
+Rule	sol89	1989	only	-	Jan	12	12:08:20s -0:08:20 -
+Rule	sol89	1989	only	-	Jan	13	12:08:45s -0:08:45 -
+Rule	sol89	1989	only	-	Jan	14	12:09:05s -0:09:05 -
+Rule	sol89	1989	only	-	Jan	15	12:09:25s -0:09:25 -
+Rule	sol89	1989	only	-	Jan	16	12:09:45s -0:09:45 -
+Rule	sol89	1989	only	-	Jan	17	12:10:05s -0:10:05 -
+Rule	sol89	1989	only	-	Jan	18	12:10:25s -0:10:25 -
+Rule	sol89	1989	only	-	Jan	19	12:10:45s -0:10:45 -
+Rule	sol89	1989	only	-	Jan	20	12:11:05s -0:11:05 -
+Rule	sol89	1989	only	-	Jan	21	12:11:20s -0:11:20 -
+Rule	sol89	1989	only	-	Jan	22	12:11:35s -0:11:35 -
+Rule	sol89	1989	only	-	Jan	23	12:11:55s -0:11:55 -
+Rule	sol89	1989	only	-	Jan	24	12:12:10s -0:12:10 -
+Rule	sol89	1989	only	-	Jan	25	12:12:20s -0:12:20 -
+Rule	sol89	1989	only	-	Jan	26	12:12:35s -0:12:35 -
+Rule	sol89	1989	only	-	Jan	27	12:12:50s -0:12:50 -
+Rule	sol89	1989	only	-	Jan	28	12:13:00s -0:13:00 -
+Rule	sol89	1989	only	-	Jan	29	12:13:10s -0:13:10 -
+Rule	sol89	1989	only	-	Jan	30	12:13:20s -0:13:20 -
+Rule	sol89	1989	only	-	Jan	31	12:13:30s -0:13:30 -
+Rule	sol89	1989	only	-	Feb	1	12:13:40s -0:13:40 -
+Rule	sol89	1989	only	-	Feb	2	12:13:45s -0:13:45 -
+Rule	sol89	1989	only	-	Feb	3	12:13:55s -0:13:55 -
+Rule	sol89	1989	only	-	Feb	4	12:14:00s -0:14:00 -
+Rule	sol89	1989	only	-	Feb	5	12:14:05s -0:14:05 -
+Rule	sol89	1989	only	-	Feb	6	12:14:10s -0:14:10 -
+Rule	sol89	1989	only	-	Feb	7	12:14:10s -0:14:10 -
+Rule	sol89	1989	only	-	Feb	8	12:14:15s -0:14:15 -
+Rule	sol89	1989	only	-	Feb	9	12:14:15s -0:14:15 -
+Rule	sol89	1989	only	-	Feb	10	12:14:20s -0:14:20 -
+Rule	sol89	1989	only	-	Feb	11	12:14:20s -0:14:20 -
+Rule	sol89	1989	only	-	Feb	12	12:14:20s -0:14:20 -
+Rule	sol89	1989	only	-	Feb	13	12:14:15s -0:14:15 -
+Rule	sol89	1989	only	-	Feb	14	12:14:15s -0:14:15 -
+Rule	sol89	1989	only	-	Feb	15	12:14:10s -0:14:10 -
+Rule	sol89	1989	only	-	Feb	16	12:14:10s -0:14:10 -
+Rule	sol89	1989	only	-	Feb	17	12:14:05s -0:14:05 -
+Rule	sol89	1989	only	-	Feb	18	12:14:00s -0:14:00 -
+Rule	sol89	1989	only	-	Feb	19	12:13:55s -0:13:55 -
+Rule	sol89	1989	only	-	Feb	20	12:13:50s -0:13:50 -
+Rule	sol89	1989	only	-	Feb	21	12:13:40s -0:13:40 -
+Rule	sol89	1989	only	-	Feb	22	12:13:35s -0:13:35 -
+Rule	sol89	1989	only	-	Feb	23	12:13:25s -0:13:25 -
+Rule	sol89	1989	only	-	Feb	24	12:13:15s -0:13:15 -
+Rule	sol89	1989	only	-	Feb	25	12:13:05s -0:13:05 -
+Rule	sol89	1989	only	-	Feb	26	12:12:55s -0:12:55 -
+Rule	sol89	1989	only	-	Feb	27	12:12:45s -0:12:45 -
+Rule	sol89	1989	only	-	Feb	28	12:12:35s -0:12:35 -
+Rule	sol89	1989	only	-	Mar	1	12:12:25s -0:12:25 -
+Rule	sol89	1989	only	-	Mar	2	12:12:10s -0:12:10 -
+Rule	sol89	1989	only	-	Mar	3	12:12:00s -0:12:00 -
+Rule	sol89	1989	only	-	Mar	4	12:11:45s -0:11:45 -
+Rule	sol89	1989	only	-	Mar	5	12:11:35s -0:11:35 -
+Rule	sol89	1989	only	-	Mar	6	12:11:20s -0:11:20 -
+Rule	sol89	1989	only	-	Mar	7	12:11:05s -0:11:05 -
+Rule	sol89	1989	only	-	Mar	8	12:10:50s -0:10:50 -
+Rule	sol89	1989	only	-	Mar	9	12:10:35s -0:10:35 -
+Rule	sol89	1989	only	-	Mar	10	12:10:20s -0:10:20 -
+Rule	sol89	1989	only	-	Mar	11	12:10:05s -0:10:05 -
+Rule	sol89	1989	only	-	Mar	12	12:09:50s -0:09:50 -
+Rule	sol89	1989	only	-	Mar	13	12:09:30s -0:09:30 -
+Rule	sol89	1989	only	-	Mar	14	12:09:15s -0:09:15 -
+Rule	sol89	1989	only	-	Mar	15	12:09:00s -0:09:00 -
+Rule	sol89	1989	only	-	Mar	16	12:08:40s -0:08:40 -
+Rule	sol89	1989	only	-	Mar	17	12:08:25s -0:08:25 -
+Rule	sol89	1989	only	-	Mar	18	12:08:05s -0:08:05 -
+Rule	sol89	1989	only	-	Mar	19	12:07:50s -0:07:50 -
+Rule	sol89	1989	only	-	Mar	20	12:07:30s -0:07:30 -
+Rule	sol89	1989	only	-	Mar	21	12:07:15s -0:07:15 -
+Rule	sol89	1989	only	-	Mar	22	12:06:55s -0:06:55 -
+Rule	sol89	1989	only	-	Mar	23	12:06:35s -0:06:35 -
+Rule	sol89	1989	only	-	Mar	24	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Mar	25	12:06:00s -0:06:00 -
+Rule	sol89	1989	only	-	Mar	26	12:05:40s -0:05:40 -
+Rule	sol89	1989	only	-	Mar	27	12:05:25s -0:05:25 -
+Rule	sol89	1989	only	-	Mar	28	12:05:05s -0:05:05 -
+Rule	sol89	1989	only	-	Mar	29	12:04:50s -0:04:50 -
+Rule	sol89	1989	only	-	Mar	30	12:04:30s -0:04:30 -
+Rule	sol89	1989	only	-	Mar	31	12:04:10s -0:04:10 -
+Rule	sol89	1989	only	-	Apr	1	12:03:55s -0:03:55 -
+Rule	sol89	1989	only	-	Apr	2	12:03:35s -0:03:35 -
+Rule	sol89	1989	only	-	Apr	3	12:03:20s -0:03:20 -
+Rule	sol89	1989	only	-	Apr	4	12:03:00s -0:03:00 -
+Rule	sol89	1989	only	-	Apr	5	12:02:45s -0:02:45 -
+Rule	sol89	1989	only	-	Apr	6	12:02:25s -0:02:25 -
+Rule	sol89	1989	only	-	Apr	7	12:02:10s -0:02:10 -
+Rule	sol89	1989	only	-	Apr	8	12:01:50s -0:01:50 -
+Rule	sol89	1989	only	-	Apr	9	12:01:35s -0:01:35 -
+Rule	sol89	1989	only	-	Apr	10	12:01:20s -0:01:20 -
+Rule	sol89	1989	only	-	Apr	11	12:01:05s -0:01:05 -
+Rule	sol89	1989	only	-	Apr	12	12:00:50s -0:00:50 -
+Rule	sol89	1989	only	-	Apr	13	12:00:35s -0:00:35 -
+Rule	sol89	1989	only	-	Apr	14	12:00:20s -0:00:20 -
+Rule	sol89	1989	only	-	Apr	15	12:00:05s -0:00:05 -
+Rule	sol89	1989	only	-	Apr	16	11:59:50s 0:00:10 -
+Rule	sol89	1989	only	-	Apr	17	11:59:35s 0:00:25 -
+Rule	sol89	1989	only	-	Apr	18	11:59:20s 0:00:40 -
+Rule	sol89	1989	only	-	Apr	19	11:59:10s 0:00:50 -
+Rule	sol89	1989	only	-	Apr	20	11:58:55s 0:01:05 -
+Rule	sol89	1989	only	-	Apr	21	11:58:45s 0:01:15 -
+Rule	sol89	1989	only	-	Apr	22	11:58:30s 0:01:30 -
+Rule	sol89	1989	only	-	Apr	23	11:58:20s 0:01:40 -
+Rule	sol89	1989	only	-	Apr	24	11:58:10s 0:01:50 -
+Rule	sol89	1989	only	-	Apr	25	11:58:00s 0:02:00 -
+Rule	sol89	1989	only	-	Apr	26	11:57:50s 0:02:10 -
+Rule	sol89	1989	only	-	Apr	27	11:57:40s 0:02:20 -
+Rule	sol89	1989	only	-	Apr	28	11:57:30s 0:02:30 -
+Rule	sol89	1989	only	-	Apr	29	11:57:20s 0:02:40 -
+Rule	sol89	1989	only	-	Apr	30	11:57:15s 0:02:45 -
+Rule	sol89	1989	only	-	May	1	11:57:05s 0:02:55 -
+Rule	sol89	1989	only	-	May	2	11:57:00s 0:03:00 -
+Rule	sol89	1989	only	-	May	3	11:56:50s 0:03:10 -
+Rule	sol89	1989	only	-	May	4	11:56:45s 0:03:15 -
+Rule	sol89	1989	only	-	May	5	11:56:40s 0:03:20 -
+Rule	sol89	1989	only	-	May	6	11:56:35s 0:03:25 -
+Rule	sol89	1989	only	-	May	7	11:56:30s 0:03:30 -
+Rule	sol89	1989	only	-	May	8	11:56:30s 0:03:30 -
+Rule	sol89	1989	only	-	May	9	11:56:25s 0:03:35 -
+Rule	sol89	1989	only	-	May	10	11:56:25s 0:03:35 -
+Rule	sol89	1989	only	-	May	11	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	12	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	13	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	14	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	15	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	16	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	17	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	18	11:56:25s 0:03:35 -
+Rule	sol89	1989	only	-	May	19	11:56:25s 0:03:35 -
+Rule	sol89	1989	only	-	May	20	11:56:30s 0:03:30 -
+Rule	sol89	1989	only	-	May	21	11:56:35s 0:03:25 -
+Rule	sol89	1989	only	-	May	22	11:56:35s 0:03:25 -
+Rule	sol89	1989	only	-	May	23	11:56:40s 0:03:20 -
+Rule	sol89	1989	only	-	May	24	11:56:45s 0:03:15 -
+Rule	sol89	1989	only	-	May	25	11:56:55s 0:03:05 -
+Rule	sol89	1989	only	-	May	26	11:57:00s 0:03:00 -
+Rule	sol89	1989	only	-	May	27	11:57:05s 0:02:55 -
+Rule	sol89	1989	only	-	May	28	11:57:15s 0:02:45 -
+Rule	sol89	1989	only	-	May	29	11:57:20s 0:02:40 -
+Rule	sol89	1989	only	-	May	30	11:57:30s 0:02:30 -
+Rule	sol89	1989	only	-	May	31	11:57:35s 0:02:25 -
+Rule	sol89	1989	only	-	Jun	1	11:57:45s 0:02:15 -
+Rule	sol89	1989	only	-	Jun	2	11:57:55s 0:02:05 -
+Rule	sol89	1989	only	-	Jun	3	11:58:05s 0:01:55 -
+Rule	sol89	1989	only	-	Jun	4	11:58:15s 0:01:45 -
+Rule	sol89	1989	only	-	Jun	5	11:58:25s 0:01:35 -
+Rule	sol89	1989	only	-	Jun	6	11:58:35s 0:01:25 -
+Rule	sol89	1989	only	-	Jun	7	11:58:45s 0:01:15 -
+Rule	sol89	1989	only	-	Jun	8	11:59:00s 0:01:00 -
+Rule	sol89	1989	only	-	Jun	9	11:59:10s 0:00:50 -
+Rule	sol89	1989	only	-	Jun	10	11:59:20s 0:00:40 -
+Rule	sol89	1989	only	-	Jun	11	11:59:35s 0:00:25 -
+Rule	sol89	1989	only	-	Jun	12	11:59:45s 0:00:15 -
+Rule	sol89	1989	only	-	Jun	13	12:00:00s 0:00:00 -
+Rule	sol89	1989	only	-	Jun	14	12:00:10s -0:00:10 -
+Rule	sol89	1989	only	-	Jun	15	12:00:25s -0:00:25 -
+Rule	sol89	1989	only	-	Jun	16	12:00:35s -0:00:35 -
+Rule	sol89	1989	only	-	Jun	17	12:00:50s -0:00:50 -
+Rule	sol89	1989	only	-	Jun	18	12:01:05s -0:01:05 -
+Rule	sol89	1989	only	-	Jun	19	12:01:15s -0:01:15 -
+Rule	sol89	1989	only	-	Jun	20	12:01:30s -0:01:30 -
+Rule	sol89	1989	only	-	Jun	21	12:01:40s -0:01:40 -
+Rule	sol89	1989	only	-	Jun	22	12:01:55s -0:01:55 -
+Rule	sol89	1989	only	-	Jun	23	12:02:10s -0:02:10 -
+Rule	sol89	1989	only	-	Jun	24	12:02:20s -0:02:20 -
+Rule	sol89	1989	only	-	Jun	25	12:02:35s -0:02:35 -
+Rule	sol89	1989	only	-	Jun	26	12:02:45s -0:02:45 -
+Rule	sol89	1989	only	-	Jun	27	12:03:00s -0:03:00 -
+Rule	sol89	1989	only	-	Jun	28	12:03:10s -0:03:10 -
+Rule	sol89	1989	only	-	Jun	29	12:03:25s -0:03:25 -
+Rule	sol89	1989	only	-	Jun	30	12:03:35s -0:03:35 -
+Rule	sol89	1989	only	-	Jul	1	12:03:45s -0:03:45 -
+Rule	sol89	1989	only	-	Jul	2	12:04:00s -0:04:00 -
+Rule	sol89	1989	only	-	Jul	3	12:04:10s -0:04:10 -
+Rule	sol89	1989	only	-	Jul	4	12:04:20s -0:04:20 -
+Rule	sol89	1989	only	-	Jul	5	12:04:30s -0:04:30 -
+Rule	sol89	1989	only	-	Jul	6	12:04:40s -0:04:40 -
+Rule	sol89	1989	only	-	Jul	7	12:04:50s -0:04:50 -
+Rule	sol89	1989	only	-	Jul	8	12:05:00s -0:05:00 -
+Rule	sol89	1989	only	-	Jul	9	12:05:10s -0:05:10 -
+Rule	sol89	1989	only	-	Jul	10	12:05:20s -0:05:20 -
+Rule	sol89	1989	only	-	Jul	11	12:05:25s -0:05:25 -
+Rule	sol89	1989	only	-	Jul	12	12:05:35s -0:05:35 -
+Rule	sol89	1989	only	-	Jul	13	12:05:40s -0:05:40 -
+Rule	sol89	1989	only	-	Jul	14	12:05:50s -0:05:50 -
+Rule	sol89	1989	only	-	Jul	15	12:05:55s -0:05:55 -
+Rule	sol89	1989	only	-	Jul	16	12:06:00s -0:06:00 -
+Rule	sol89	1989	only	-	Jul	17	12:06:05s -0:06:05 -
+Rule	sol89	1989	only	-	Jul	18	12:06:10s -0:06:10 -
+Rule	sol89	1989	only	-	Jul	19	12:06:15s -0:06:15 -
+Rule	sol89	1989	only	-	Jul	20	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Jul	21	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Jul	22	12:06:25s -0:06:25 -
+Rule	sol89	1989	only	-	Jul	23	12:06:25s -0:06:25 -
+Rule	sol89	1989	only	-	Jul	24	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	25	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	26	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	27	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	28	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	29	12:06:25s -0:06:25 -
+Rule	sol89	1989	only	-	Jul	30	12:06:25s -0:06:25 -
+Rule	sol89	1989	only	-	Jul	31	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Aug	1	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Aug	2	12:06:15s -0:06:15 -
+Rule	sol89	1989	only	-	Aug	3	12:06:10s -0:06:10 -
+Rule	sol89	1989	only	-	Aug	4	12:06:05s -0:06:05 -
+Rule	sol89	1989	only	-	Aug	5	12:06:00s -0:06:00 -
+Rule	sol89	1989	only	-	Aug	6	12:05:50s -0:05:50 -
+Rule	sol89	1989	only	-	Aug	7	12:05:45s -0:05:45 -
+Rule	sol89	1989	only	-	Aug	8	12:05:35s -0:05:35 -
+Rule	sol89	1989	only	-	Aug	9	12:05:30s -0:05:30 -
+Rule	sol89	1989	only	-	Aug	10	12:05:20s -0:05:20 -
+Rule	sol89	1989	only	-	Aug	11	12:05:10s -0:05:10 -
+Rule	sol89	1989	only	-	Aug	12	12:05:00s -0:05:00 -
+Rule	sol89	1989	only	-	Aug	13	12:04:50s -0:04:50 -
+Rule	sol89	1989	only	-	Aug	14	12:04:40s -0:04:40 -
+Rule	sol89	1989	only	-	Aug	15	12:04:30s -0:04:30 -
+Rule	sol89	1989	only	-	Aug	16	12:04:15s -0:04:15 -
+Rule	sol89	1989	only	-	Aug	17	12:04:05s -0:04:05 -
+Rule	sol89	1989	only	-	Aug	18	12:03:50s -0:03:50 -
+Rule	sol89	1989	only	-	Aug	19	12:03:35s -0:03:35 -
+Rule	sol89	1989	only	-	Aug	20	12:03:25s -0:03:25 -
+Rule	sol89	1989	only	-	Aug	21	12:03:10s -0:03:10 -
+Rule	sol89	1989	only	-	Aug	22	12:02:55s -0:02:55 -
+Rule	sol89	1989	only	-	Aug	23	12:02:40s -0:02:40 -
+Rule	sol89	1989	only	-	Aug	24	12:02:20s -0:02:20 -
+Rule	sol89	1989	only	-	Aug	25	12:02:05s -0:02:05 -
+Rule	sol89	1989	only	-	Aug	26	12:01:50s -0:01:50 -
+Rule	sol89	1989	only	-	Aug	27	12:01:30s -0:01:30 -
+Rule	sol89	1989	only	-	Aug	28	12:01:15s -0:01:15 -
+Rule	sol89	1989	only	-	Aug	29	12:00:55s -0:00:55 -
+Rule	sol89	1989	only	-	Aug	30	12:00:40s -0:00:40 -
+Rule	sol89	1989	only	-	Aug	31	12:00:20s -0:00:20 -
+Rule	sol89	1989	only	-	Sep	1	12:00:00s 0:00:00 -
+Rule	sol89	1989	only	-	Sep	2	11:59:45s 0:00:15 -
+Rule	sol89	1989	only	-	Sep	3	11:59:25s 0:00:35 -
+Rule	sol89	1989	only	-	Sep	4	11:59:05s 0:00:55 -
+Rule	sol89	1989	only	-	Sep	5	11:58:45s 0:01:15 -
+Rule	sol89	1989	only	-	Sep	6	11:58:25s 0:01:35 -
+Rule	sol89	1989	only	-	Sep	7	11:58:05s 0:01:55 -
+Rule	sol89	1989	only	-	Sep	8	11:57:45s 0:02:15 -
+Rule	sol89	1989	only	-	Sep	9	11:57:20s 0:02:40 -
+Rule	sol89	1989	only	-	Sep	10	11:57:00s 0:03:00 -
+Rule	sol89	1989	only	-	Sep	11	11:56:40s 0:03:20 -
+Rule	sol89	1989	only	-	Sep	12	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	Sep	13	11:56:00s 0:04:00 -
+Rule	sol89	1989	only	-	Sep	14	11:55:35s 0:04:25 -
+Rule	sol89	1989	only	-	Sep	15	11:55:15s 0:04:45 -
+Rule	sol89	1989	only	-	Sep	16	11:54:55s 0:05:05 -
+Rule	sol89	1989	only	-	Sep	17	11:54:35s 0:05:25 -
+Rule	sol89	1989	only	-	Sep	18	11:54:10s 0:05:50 -
+Rule	sol89	1989	only	-	Sep	19	11:53:50s 0:06:10 -
+Rule	sol89	1989	only	-	Sep	20	11:53:30s 0:06:30 -
+Rule	sol89	1989	only	-	Sep	21	11:53:10s 0:06:50 -
+Rule	sol89	1989	only	-	Sep	22	11:52:45s 0:07:15 -
+Rule	sol89	1989	only	-	Sep	23	11:52:25s 0:07:35 -
+Rule	sol89	1989	only	-	Sep	24	11:52:05s 0:07:55 -
+Rule	sol89	1989	only	-	Sep	25	11:51:45s 0:08:15 -
+Rule	sol89	1989	only	-	Sep	26	11:51:25s 0:08:35 -
+Rule	sol89	1989	only	-	Sep	27	11:51:05s 0:08:55 -
+Rule	sol89	1989	only	-	Sep	28	11:50:40s 0:09:20 -
+Rule	sol89	1989	only	-	Sep	29	11:50:20s 0:09:40 -
+Rule	sol89	1989	only	-	Sep	30	11:50:00s 0:10:00 -
+Rule	sol89	1989	only	-	Oct	1	11:49:45s 0:10:15 -
+Rule	sol89	1989	only	-	Oct	2	11:49:25s 0:10:35 -
+Rule	sol89	1989	only	-	Oct	3	11:49:05s 0:10:55 -
+Rule	sol89	1989	only	-	Oct	4	11:48:45s 0:11:15 -
+Rule	sol89	1989	only	-	Oct	5	11:48:30s 0:11:30 -
+Rule	sol89	1989	only	-	Oct	6	11:48:10s 0:11:50 -
+Rule	sol89	1989	only	-	Oct	7	11:47:50s 0:12:10 -
+Rule	sol89	1989	only	-	Oct	8	11:47:35s 0:12:25 -
+Rule	sol89	1989	only	-	Oct	9	11:47:20s 0:12:40 -
+Rule	sol89	1989	only	-	Oct	10	11:47:00s 0:13:00 -
+Rule	sol89	1989	only	-	Oct	11	11:46:45s 0:13:15 -
+Rule	sol89	1989	only	-	Oct	12	11:46:30s 0:13:30 -
+Rule	sol89	1989	only	-	Oct	13	11:46:15s 0:13:45 -
+Rule	sol89	1989	only	-	Oct	14	11:46:00s 0:14:00 -
+Rule	sol89	1989	only	-	Oct	15	11:45:50s 0:14:10 -
+Rule	sol89	1989	only	-	Oct	16	11:45:35s 0:14:25 -
+Rule	sol89	1989	only	-	Oct	17	11:45:20s 0:14:40 -
+Rule	sol89	1989	only	-	Oct	18	11:45:10s 0:14:50 -
+Rule	sol89	1989	only	-	Oct	19	11:45:00s 0:15:00 -
+Rule	sol89	1989	only	-	Oct	20	11:44:50s 0:15:10 -
+Rule	sol89	1989	only	-	Oct	21	11:44:40s 0:15:20 -
+Rule	sol89	1989	only	-	Oct	22	11:44:30s 0:15:30 -
+Rule	sol89	1989	only	-	Oct	23	11:44:20s 0:15:40 -
+Rule	sol89	1989	only	-	Oct	24	11:44:10s 0:15:50 -
+Rule	sol89	1989	only	-	Oct	25	11:44:05s 0:15:55 -
+Rule	sol89	1989	only	-	Oct	26	11:44:00s 0:16:00 -
+Rule	sol89	1989	only	-	Oct	27	11:43:50s 0:16:10 -
+Rule	sol89	1989	only	-	Oct	28	11:43:45s 0:16:15 -
+Rule	sol89	1989	only	-	Oct	29	11:43:40s 0:16:20 -
+Rule	sol89	1989	only	-	Oct	30	11:43:40s 0:16:20 -
+Rule	sol89	1989	only	-	Oct	31	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	1	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	2	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	3	11:43:30s 0:16:30 -
+Rule	sol89	1989	only	-	Nov	4	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	5	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	6	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	7	11:43:40s 0:16:20 -
+Rule	sol89	1989	only	-	Nov	8	11:43:45s 0:16:15 -
+Rule	sol89	1989	only	-	Nov	9	11:43:50s 0:16:10 -
+Rule	sol89	1989	only	-	Nov	10	11:43:55s 0:16:05 -
+Rule	sol89	1989	only	-	Nov	11	11:44:00s 0:16:00 -
+Rule	sol89	1989	only	-	Nov	12	11:44:05s 0:15:55 -
+Rule	sol89	1989	only	-	Nov	13	11:44:15s 0:15:45 -
+Rule	sol89	1989	only	-	Nov	14	11:44:25s 0:15:35 -
+Rule	sol89	1989	only	-	Nov	15	11:44:35s 0:15:25 -
+Rule	sol89	1989	only	-	Nov	16	11:44:45s 0:15:15 -
+Rule	sol89	1989	only	-	Nov	17	11:44:55s 0:15:05 -
+Rule	sol89	1989	only	-	Nov	18	11:45:10s 0:14:50 -
+Rule	sol89	1989	only	-	Nov	19	11:45:20s 0:14:40 -
+Rule	sol89	1989	only	-	Nov	20	11:45:35s 0:14:25 -
+Rule	sol89	1989	only	-	Nov	21	11:45:50s 0:14:10 -
+Rule	sol89	1989	only	-	Nov	22	11:46:05s 0:13:55 -
+Rule	sol89	1989	only	-	Nov	23	11:46:25s 0:13:35 -
+Rule	sol89	1989	only	-	Nov	24	11:46:40s 0:13:20 -
+Rule	sol89	1989	only	-	Nov	25	11:47:00s 0:13:00 -
+Rule	sol89	1989	only	-	Nov	26	11:47:20s 0:12:40 -
+Rule	sol89	1989	only	-	Nov	27	11:47:35s 0:12:25 -
+Rule	sol89	1989	only	-	Nov	28	11:47:55s 0:12:05 -
+Rule	sol89	1989	only	-	Nov	29	11:48:20s 0:11:40 -
+Rule	sol89	1989	only	-	Nov	30	11:48:40s 0:11:20 -
+Rule	sol89	1989	only	-	Dec	1	11:49:00s 0:11:00 -
+Rule	sol89	1989	only	-	Dec	2	11:49:25s 0:10:35 -
+Rule	sol89	1989	only	-	Dec	3	11:49:50s 0:10:10 -
+Rule	sol89	1989	only	-	Dec	4	11:50:15s 0:09:45 -
+Rule	sol89	1989	only	-	Dec	5	11:50:35s 0:09:25 -
+Rule	sol89	1989	only	-	Dec	6	11:51:00s 0:09:00 -
+Rule	sol89	1989	only	-	Dec	7	11:51:30s 0:08:30 -
+Rule	sol89	1989	only	-	Dec	8	11:51:55s 0:08:05 -
+Rule	sol89	1989	only	-	Dec	9	11:52:20s 0:07:40 -
+Rule	sol89	1989	only	-	Dec	10	11:52:50s 0:07:10 -
+Rule	sol89	1989	only	-	Dec	11	11:53:15s 0:06:45 -
+Rule	sol89	1989	only	-	Dec	12	11:53:45s 0:06:15 -
+Rule	sol89	1989	only	-	Dec	13	11:54:10s 0:05:50 -
+Rule	sol89	1989	only	-	Dec	14	11:54:40s 0:05:20 -
+Rule	sol89	1989	only	-	Dec	15	11:55:10s 0:04:50 -
+Rule	sol89	1989	only	-	Dec	16	11:55:40s 0:04:20 -
+Rule	sol89	1989	only	-	Dec	17	11:56:05s 0:03:55 -
+Rule	sol89	1989	only	-	Dec	18	11:56:35s 0:03:25 -
+Rule	sol89	1989	only	-	Dec	19	11:57:05s 0:02:55 -
+Rule	sol89	1989	only	-	Dec	20	11:57:35s 0:02:25 -
+Rule	sol89	1989	only	-	Dec	21	11:58:05s 0:01:55 -
+Rule	sol89	1989	only	-	Dec	22	11:58:35s 0:01:25 -
+Rule	sol89	1989	only	-	Dec	23	11:59:05s 0:00:55 -
+Rule	sol89	1989	only	-	Dec	24	11:59:35s 0:00:25 -
+Rule	sol89	1989	only	-	Dec	25	12:00:05s -0:00:05 -
+Rule	sol89	1989	only	-	Dec	26	12:00:35s -0:00:35 -
+Rule	sol89	1989	only	-	Dec	27	12:01:05s -0:01:05 -
+Rule	sol89	1989	only	-	Dec	28	12:01:35s -0:01:35 -
+Rule	sol89	1989	only	-	Dec	29	12:02:00s -0:02:00 -
+Rule	sol89	1989	only	-	Dec	30	12:02:30s -0:02:30 -
+Rule	sol89	1989	only	-	Dec	31	12:03:00s -0:03:00 -
+
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
+# Before and after 1989, we'll operate on local mean solar time.
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	Asia/Riyadh89	3:07:04	-		zzz	1989
+			3:07:04	sol89		zzz	1990
+			3:07:04	-		zzz
+# For backward compatibility...
+Link	Asia/Riyadh89	Mideast/Riyadh89
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/southamerica b/jdk/test/sun/util/calendar/zi/tzdata/southamerica
new file mode 100644
index 0000000..0d6797e
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/southamerica
@@ -0,0 +1,1734 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Earlier editions of these tables used the North American style (e.g. ARST and
+# ARDT for Argentine Standard and Daylight Time), but the following quote
+# suggests that it's better to use European style (e.g. ART and ARST).
+#	I suggest the use of _Summer time_ instead of the more cumbersome
+#	_daylight-saving time_.  _Summer time_ seems to be in general use
+#	in Europe and South America.
+#	-- E O Cutler, _New York Times_ (1937-02-14), quoted in
+#	H L Mencken, _The American Language: Supplement I_ (1960), p 466
+#
+# Earlier editions of these tables also used the North American style
+# for time zones in Brazil, but this was incorrect, as Brazilians say
+# "summer time".  Reinaldo Goulart, a Sao Paulo businessman active in
+# the railroad sector, writes (1999-07-06):
+#	The subject of time zones is currently a matter of discussion/debate in
+#	Brazil.  Let's say that "the Brasilia time" is considered the
+#	"official time" because Brasilia is the capital city.
+#	The other three time zones are called "Brasilia time "minus one" or
+#	"plus one" or "plus two".  As far as I know there is no such
+#	name/designation as "Eastern Time" or "Central Time".
+# So I invented the following (English-language) abbreviations for now.
+# Corrections are welcome!
+#		std	dst
+#	-2:00	FNT	FNST	Fernando de Noronha
+#	-3:00	BRT	BRST	Brasilia
+#	-4:00	AMT	AMST	Amazon
+#	-5:00	ACT	ACST	Acre
+
+###############################################################################
+
+###############################################################################
+
+# Argentina
+
+# From Bob Devine (1988-01-28):
+# Argentina: first Sunday in October to first Sunday in April since 1976.
+# Double Summer time from 1969 to 1974.  Switches at midnight.
+
+# From U. S. Naval Observatory (1988-01-199):
+# ARGENTINA           3 H BEHIND   UTC
+
+# From Hernan G. Otero (1995-06-26):
+# I am sending modifications to the Argentine time zone table...
+# AR was chosen because they are the ISO letters that represent Argentina.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Arg	1930	only	-	Dec	 1	0:00	1:00	S
+Rule	Arg	1931	only	-	Apr	 1	0:00	0	-
+Rule	Arg	1931	only	-	Oct	15	0:00	1:00	S
+Rule	Arg	1932	1940	-	Mar	 1	0:00	0	-
+Rule	Arg	1932	1939	-	Nov	 1	0:00	1:00	S
+Rule	Arg	1940	only	-	Jul	 1	0:00	1:00	S
+Rule	Arg	1941	only	-	Jun	15	0:00	0	-
+Rule	Arg	1941	only	-	Oct	15	0:00	1:00	S
+Rule	Arg	1943	only	-	Aug	 1	0:00	0	-
+Rule	Arg	1943	only	-	Oct	15	0:00	1:00	S
+Rule	Arg	1946	only	-	Mar	 1	0:00	0	-
+Rule	Arg	1946	only	-	Oct	 1	0:00	1:00	S
+Rule	Arg	1963	only	-	Oct	 1	0:00	0	-
+Rule	Arg	1963	only	-	Dec	15	0:00	1:00	S
+Rule	Arg	1964	1966	-	Mar	 1	0:00	0	-
+Rule	Arg	1964	1966	-	Oct	15	0:00	1:00	S
+Rule	Arg	1967	only	-	Apr	 2	0:00	0	-
+Rule	Arg	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
+Rule	Arg	1968	1969	-	Apr	Sun>=1	0:00	0	-
+Rule	Arg	1974	only	-	Jan	23	0:00	1:00	S
+Rule	Arg	1974	only	-	May	 1	0:00	0	-
+Rule	Arg	1988	only	-	Dec	 1	0:00	1:00	S
+#
+# From Hernan G. Otero (1995-06-26):
+# These corrections were contributed by InterSoft Argentina S.A.,
+# obtaining the data from the:
+# Talleres de Hidrografia Naval Argentina
+# (Argentine Naval Hydrography Institute)
+Rule	Arg	1989	1993	-	Mar	Sun>=1	0:00	0	-
+Rule	Arg	1989	1992	-	Oct	Sun>=15	0:00	1:00	S
+#
+# From Hernan G. Otero (1995-06-26):
+# From this moment on, the law that mandated the daylight saving
+# time corrections was derogated and no more modifications
+# to the time zones (for daylight saving) are now made.
+#
+# From Rives McDow (2000-01-10):
+# On October 3, 1999, 0:00 local, Argentina implemented daylight savings time,
+# which did not result in the switch of a time zone, as they stayed 9 hours
+# from the International Date Line.
+Rule	Arg	1999	only	-	Oct	Sun>=1	0:00	1:00	S
+# From Paul Eggert (2007-12-28):
+# DST was set to expire on March 5, not March 3, but since it was converted
+# to standard time on March 3 it's more convenient for us to pretend that
+# it ended on March 3.
+Rule	Arg	2000	only	-	Mar	3	0:00	0	-
+#
+# From Peter Gradelski via Steffen Thorsen (2000-03-01):
+# We just checked with our Sao Paulo office and they say the government of
+# Argentina decided not to become one of the countries that go on or off DST.
+# So Buenos Aires should be -3 hours from GMT at all times.
+#
+# From Fabian L. Arce Jofre (2000-04-04):
+# The law that claimed DST for Argentina was derogated by President Fernando
+# de la Rua on March 2, 2000, because it would make people spend more energy
+# in the winter time, rather than less.  The change took effect on March 3.
+#
+# From Mariano Absatz (2001-06-06):
+# one of the major newspapers here in Argentina said that the 1999
+# Timezone Law (which never was effectively applied) will (would?) be
+# in effect.... The article is at
+# http://ar.clarin.com/diario/2001-06-06/e-01701.htm
+# ... The Law itself is "Ley No 25155", sanctioned on 1999-08-25, enacted
+# 1999-09-17, and published 1999-09-21.  The official publication is at:
+# http://www.boletin.jus.gov.ar/BON/Primera/1999/09-Septiembre/21/PDF/BO21-09-99LEG.PDF
+# Regretfully, you have to subscribe (and pay) for the on-line version....
+#
+# (2001-06-12):
+# the timezone for Argentina will not change next Sunday.
+# Apparently it will do so on Sunday 24th....
+# http://ar.clarin.com/diario/2001-06-12/s-03501.htm
+#
+# (2001-06-25):
+# Last Friday (yes, the last working day before the date of the change), the
+# Senate annulled the 1999 law that introduced the changes later postponed.
+# http://www.clarin.com.ar/diario/2001-06-22/s-03601.htm
+# It remains the vote of the Deputies..., but it will be the same....
+# This kind of things had always been done this way in Argentina.
+# We are still -03:00 all year round in all of the country.
+#
+# From Steffen Thorsen (2007-12-21):
+# A user (Leonardo Chaim) reported that Argentina will adopt DST....
+# all of the country (all Zone-entries) are affected.  News reports like
+# http://www.lanacion.com.ar/opinion/nota.asp?nota_id=973037 indicate
+# that Argentina will use DST next year as well, from October to
+# March, although exact rules are not given.
+#
+# From Jesper Norgaard Welen (2007-12-26)
+# The last hurdle of Argentina DST is over, the proposal was approved in
+# the lower chamber too (Deputados) with a vote 192 for and 2 against.
+# By the way thanks to Mariano Absatz and Daniel Mario Vega for the link to
+# the original scanned proposal, where the dates and the zero hours are
+# clear and unambiguous...This is the article about final approval:
+# <a href="http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996">
+# http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996
+# </a>
+#
+# From Paul Eggert (2007-12-22):
+# For dates after mid-2008, the following rules are my guesses and
+# are quite possibly wrong, but are more likely than no DST at all.
+
+# From Alexander Krivenyshev (2008-09-05):
+# As per message from Carlos Alberto Fonseca Arauz (Nicaragua),
+# Argentina will start DST on Sunday October 19, 2008.
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_argentina03.html
+# </a>
+# OR
+# <a href="http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)">
+# http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)
+# </a>
+
+# From Rodrigo Severo (2008-10-06):
+# Here is some info available at a Gentoo bug related to TZ on Argentina's DST:
+# ...
+# ------- Comment #1 from [jmdocile]  2008-10-06 16:28 0000 -------
+# Hi, there is a problem with timezone-data-2008e and maybe with
+# timezone-data-2008f
+# Argentinian law [Number] 25.155 is no longer valid.
+# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm">
+# http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm
+# </a>
+# The new one is law [Number] 26.350
+# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm">
+# http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm
+# </a>
+# So there is no summer time in Argentina for now.
+
+# From Mariano Absatz (2008-10-20):
+# Decree 1693/2008 applies Law 26.350 for the summer 2008/2009 establishing DST in Argentina
+# From 2008-10-19 until 2009-03-15
+# <a href="http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01">
+# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01
+# </a>
+#
+# Decree 1705/2008 excepting 12 Provinces from applying DST in the summer 2008/2009:
+# Catamarca, La Rioja, Mendoza, Salta, San Juan, San Luis, La Pampa, Neuquen, Rio Negro, Chubut, Santa Cruz
+# and Tierra del Fuego
+# <a href="http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01">
+# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01
+# </a>
+#
+# Press release 235 dated Saturday October 18th, from the Government of the Province of Jujuy saying
+# it will not apply DST either (even when it was not included in Decree 1705/2008)
+# <a href="http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc">
+# http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc
+# </a>
+
+# From fullinet (2009-10-18):
+# As announced in
+# <a hef="http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356">
+# http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356
+# </a>
+# (an official .gob.ar) under title: "Sin Cambio de Hora" (english: "No hour change")
+#
+# "Por el momento, el Gobierno Nacional resolvio no modificar la hora
+# oficial, decision que estaba en estudio para su implementacion el
+# domingo 18 de octubre. Desde el Ministerio de Planificacion se anuncio
+# que la Argentina hoy, en estas condiciones meteorologicas, no necesita
+# la modificacion del huso horario, ya que 2009 nos encuentra con
+# crecimiento en la produccion y distribucion energetica."
+
+Rule	Arg	2007	only	-	Dec	30	0:00	1:00	S
+Rule	Arg	2008	2009	-	Mar	Sun>=15	0:00	0	-
+Rule	Arg	2008	only	-	Oct	Sun>=15	0:00	1:00	S
+
+# From Mariano Absatz (2004-05-21):
+# Today it was officially published that the Province of Mendoza is changing
+# its timezone this winter... starting tomorrow night....
+# http://www.gobernac.mendoza.gov.ar/boletin/pdf/20040521-27158-normas.pdf
+# From Paul Eggert (2004-05-24):
+# It's Law No. 7,210.  This change is due to a public power emergency, so for
+# now we'll assume it's for this year only.
+#
+# From Paul Eggert (2006-03-22):
+# <a href="http://www.spicasc.net/horvera.html">
+# Hora de verano para la Republica Argentina (2003-06-08)
+# </a> says that standard time in Argentina from 1894-10-31
+# to 1920-05-01 was -4:16:48.25.  Go with this more-precise value
+# over Shanks & Pottenger.
+#
+# From Mariano Absatz (2004-06-05):
+# These media articles from a major newspaper mostly cover the current state:
+# http://www.lanacion.com.ar/04/05/27/de_604825.asp
+# http://www.lanacion.com.ar/04/05/28/de_605203.asp
+#
+# The following eight (8) provinces pulled clocks back to UTC-04:00 at
+# midnight Monday May 31st. (that is, the night between 05/31 and 06/01).
+# Apparently, all nine provinces would go back to UTC-03:00 at the same
+# time in October 17th.
+#
+# Catamarca, Chubut, La Rioja, San Juan, San Luis, Santa Cruz,
+# Tierra del Fuego, Tucuman.
+#
+# From Mariano Absatz (2004-06-14):
+# ... this weekend, the Province of Tucuman decided it'd go back to UTC-03:00
+# yesterday midnight (that is, at 24:00 Saturday 12th), since the people's
+# annoyance with the change is much higher than the power savings obtained....
+#
+# From Gwillim Law (2004-06-14):
+# http://www.lanacion.com.ar/04/06/10/de_609078.asp ...
+#     "The time change in Tierra del Fuego was a conflicted decision from
+#   the start.  The government had decreed that the measure would take
+#   effect on June 1, but a normative error forced the new time to begin
+#   three days earlier, from a Saturday to a Sunday....
+# Our understanding was that the change was originally scheduled to take place
+# on June 1 at 00:00 in Chubut, Santa Cruz, Tierra del Fuego (and some other
+# provinces).  Sunday was May 30, only two days earlier.  So the article
+# contains a contradiction.  I would give more credence to the Saturday/Sunday
+# date than the "three days earlier" phrase, and conclude that Tierra del
+# Fuego set its clocks back at 2004-05-30 00:00.
+#
+# From Steffen Thorsen (2004-10-05):
+# The previous law 7210 which changed the province of Mendoza's time zone
+# back in May have been modified slightly in a new law 7277, which set the
+# new end date to 2004-09-26 (original date was 2004-10-17).
+# http://www.gobernac.mendoza.gov.ar/boletin/pdf/20040924-27244-normas.pdf
+#
+# From Mariano Absatz (2004-10-05):
+# San Juan changed from UTC-03:00 to UTC-04:00 at midnight between
+# Sunday, May 30th and Monday, May 31st.  It changed back to UTC-03:00
+# at midnight between Saturday, July 24th and Sunday, July 25th....
+# http://www.sanjuan.gov.ar/prensa/archivo/000329.html
+# http://www.sanjuan.gov.ar/prensa/archivo/000426.html
+# http://www.sanjuan.gov.ar/prensa/archivo/000441.html
+
+# From Alex Krivenyshev (2008-01-17):
+# Here are articles that Argentina Province San Luis is planning to end DST
+# as earlier as upcoming Monday January 21, 2008 or February 2008:
+#
+# Provincia argentina retrasa reloj y marca diferencia con resto del pais
+# (Argentine Province delayed clock and mark difference with the rest of the
+# country)
+# <a href="http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel">
+# http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel
+# </a>
+#
+# Es inminente que en San Luis atrasen una hora los relojes
+# (It is imminent in San Luis clocks one hour delay)
+# <a href="http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414">
+# http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414
+# </a>
+#
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_argentina02.html">
+# http://www.worldtimezone.net/dst_news/dst_news_argentina02.html
+# </a>
+
+# From Jesper Norgaard Welen (2008-01-18):
+# The page of the San Luis provincial government
+# <a href="http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812">
+# http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812
+# </a>
+# confirms what Alex Krivenyshev has earlier sent to the tz
+# emailing list about that San Luis plans to return to standard
+# time much earlier than the rest of the country. It also
+# confirms that upon request the provinces San Juan and Mendoza
+# refused to follow San Luis in this change.
+#
+# The change is supposed to take place Monday the 21.st at 0:00
+# hours. As far as I understand it if this goes ahead, we need
+# a new timezone for San Luis (although there are also documented
+# independent changes in the southamerica file of San Luis in
+# 1990 and 1991 which has not been confirmed).
+
+# From Jesper Norgaard Welen (2008-01-25):
+# Unfortunately the below page has become defunct, about the San Luis
+# time change. Perhaps because it now is part of a group of pages "Most
+# important pages of 2008."
+#
+# You can use
+# <a href="http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834">
+# http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834
+# </a>
+# instead it seems. Or use "Buscador" from the main page of the San Luis
+# government, and fill in "huso" and click OK, and you will get 3 pages
+# from which the first one is identical to the above.
+
+# From Mariano Absatz (2008-01-28):
+# I can confirm that the Province of San Luis (and so far only that
+# province) decided to go back to UTC-3 effective midnight Jan 20th 2008
+# (that is, Monday 21st at 0:00 is the time the clocks were delayed back
+# 1 hour), and they intend to keep UTC-3 as their timezone all year round
+# (that is, unless they change their mind any minute now).
+#
+# So we'll have to add yet another city to 'southamerica' (I think San
+# Luis city is the mos populated city in the Province, so it'd be
+# America/Argentina/San_Luis... of course I can't remember if San Luis's
+# history of particular changes goes along with Mendoza or San Juan :-(
+# (I only remember not being able to collect hard facts about San Luis
+# back in 2004, when these provinces changed to UTC-4 for a few days, I
+# mailed them personally and never got an answer).
+
+# From Paul Eggert (2008-06-30):
+# Unless otherwise specified, data are from Shanks & Pottenger through 1992,
+# from the IATA otherwise.  As noted below, Shanks & Pottenger say that
+# America/Cordoba split into 6 subregions during 1991/1992, one of which
+# was America/San_Luis, but we haven't verified this yet so for now we'll
+# keep America/Cordoba a single region rather than splitting it into the
+# other 5 subregions.
+
+# From Mariano Absatz (2009-03-13):
+# Yesterday (with our usual 2-day notice) the Province of San Luis
+# decided that next Sunday instead of "staying" @utc-03:00 they will go
+# to utc-04:00 until the second Saturday in October...
+#
+# The press release is at
+# <a href="http://www.sanluis.gov.ar/SL/Paginas/NoticiaDetalle.asp?TemaId=1&InfoPrensaId=3102">
+# http://www.sanluis.gov.ar/SL/Paginas/NoticiaDetalle.asp?TemaId=1&InfoPrensaId=3102
+# </a>
+# (I couldn't find the decree, but
+# <a href="http://www.sanluis.gov.ar">
+# www.sanluis.gov.ar
+# <a/>
+# is the official page for the Province Government).
+#
+# There's also a note in only one of the major national papers (La Nación) at
+# <a href="http://www.lanacion.com.ar/nota.asp?nota_id=1107912">
+# http://www.lanacion.com.ar/nota.asp?nota_id=1107912
+# </a>
+#
+# The press release says:
+#  (...) anunció que el próximo domingo a las 00:00 los puntanos deberán
+# atrasar una hora sus relojes.
+#
+# A partir de entonces, San Luis establecerá el huso horario propio de
+# la Provincia. De esta manera, durante el periodo del calendario anual
+# 2009, el cambio horario quedará comprendido entre las 00:00 del tercer
+# domingo de marzo y las 24:00 del segundo sábado de octubre.
+# Quick&dirty translation
+# (...) announced that next Sunday, at 00:00, Puntanos (the San Luis
+# inhabitants) will have to turn back one hour their clocks
+#
+# Since then, San Luis will establish its own Province timezone. Thus,
+# during 2009, this timezone change will run from 00:00 the third Sunday
+# in March until 24:00 of the second Saturday in October.
+
+# From Mariano Absatz (2009-10-16):
+# ...the Province of San Luis is a case in itself.
+#
+# The Law at
+# <a href="http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276>"
+# http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276
+# </a>
+# is ambiguous because establishes a calendar from the 2nd Sunday in
+# October at 0:00 thru the 2nd Saturday in March at 24:00 and the
+# complement of that starting on the 2nd Sunday of March at 0:00 and
+# ending on the 2nd Saturday of March at 24:00.
+#
+# This clearly breaks every time the 1st of March or October is a Sunday.
+#
+# IMHO, the "spirit of the Law" is to make the changes at 0:00 on the 2nd
+# Sunday of October and March.
+#
+# The problem is that the changes in the rest of the Provinces that did
+# change in 2007/2008, were made according to the Federal Law and Decrees
+# that did so on the 3rd Sunday of October and March.
+#
+# In fact, San Luis actually switched from UTC-4 to UTC-3 last Sunday
+# (October 11th) at 0:00.
+#
+# So I guess a new set of rules, besides "Arg", must be made and the last
+# America/Argentina/San_Luis entries should change to use these...
+#
+# I'm enclosing a patch that does what I say... regretfully, the San Luis
+# timezone must be called "WART/WARST" even when most of the time (like,
+# right now) WARST == ART... that is, since last Sunday, all the country
+# is using UTC-3, but in my patch, San Luis calls it "WARST" and the rest
+# of the country calls it "ART".
+# ...
+
+# From Alexander Krivenyshev (2010-04-09):
+# According to news reports from El Diario de la Republica Province San
+# Luis, Argentina (standard time UTC-04) will keep Daylight Saving Time
+# after April 11, 2010--will continue to have same time as rest of
+# Argentina (UTC-3) (no DST).
+#
+# Confirmaron la pr&oacute;rroga del huso horario de verano (Spanish)
+# <a href="http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9">
+# http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9
+# </a>
+# or (some English translation):
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina08.html">
+# http://www.worldtimezone.com/dst_news/dst_news_argentina08.html
+# </a>
+
+# From Mariano Absatz (2010-04-12):
+# yes...I can confirm this...and given that San Luis keeps calling
+# UTC-03:00 "summer time", we should't just let San Luis go back to "Arg"
+# rules...San Luis is still using "Western ARgentina Time" and it got
+# stuck on Summer daylight savings time even though the summer is over.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Buenos Aires (BA), Capital Federal (CF),
+Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	Arg	AR%sT
+#
+# Cordoba (CB), Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN),
+# Chaco (CC), Formosa (FM), Santiago del Estero (SE)
+#
+# Shanks & Pottenger also make the following claims, which we haven't verified:
+# - Formosa switched to -3:00 on 1991-01-07.
+# - Misiones switched to -3:00 on 1990-12-29.
+# - Chaco switched to -3:00 on 1991-01-04.
+# - Santiago del Estero switched to -4:00 on 1991-04-01,
+#   then to -3:00 on 1991-04-26.
+#
+Zone America/Argentina/Cordoba -4:16:48 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 20
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	Arg	AR%sT
+#
+# Salta (SA), La Pampa (LP), Neuquen (NQ), Rio Negro (RN)
+Zone America/Argentina/Salta -4:21:40 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 20
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+#
+# Tucuman (TM)
+Zone America/Argentina/Tucuman -4:20:52 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 20
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 Jun  1
+			-4:00	-	WART	2004 Jun 13
+			-3:00	Arg	AR%sT
+#
+# La Rioja (LR)
+Zone America/Argentina/La_Rioja -4:27:24 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  1
+			-4:00	-	WART	1991 May  7
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 Jun  1
+			-4:00	-	WART	2004 Jun 20
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+#
+# San Juan (SJ)
+Zone America/Argentina/San_Juan -4:34:04 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  1
+			-4:00	-	WART	1991 May  7
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 May 31
+			-4:00	-	WART	2004 Jul 25
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+#
+# Jujuy (JY)
+Zone America/Argentina/Jujuy -4:21:12 -	LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1990 Mar  4
+			-4:00	-	WART	1990 Oct 28
+			-4:00	1:00	WARST	1991 Mar 17
+			-4:00	-	WART	1991 Oct  6
+			-3:00	1:00	ARST	1992
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+#
+# Catamarca (CT), Chubut (CH)
+Zone America/Argentina/Catamarca -4:23:08 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 20
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 Jun  1
+			-4:00	-	WART	2004 Jun 20
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+#
+# Mendoza (MZ)
+Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1990 Mar  4
+			-4:00	-	WART	1990 Oct 15
+			-4:00	1:00	WARST	1991 Mar  1
+			-4:00	-	WART	1991 Oct 15
+			-4:00	1:00	WARST	1992 Mar  1
+			-4:00	-	WART	1992 Oct 18
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 May 23
+			-4:00	-	WART	2004 Sep 26
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+#
+# San Luis (SL)
+
+Rule	SanLuis	2008	2009	-	Mar	Sun>=8	0:00	0	-
+Rule	SanLuis	2007	2009	-	Oct	Sun>=8	0:00	1:00	S
+
+Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1990
+			-3:00	1:00	ARST	1990 Mar 14
+			-4:00	-	WART	1990 Oct 15
+			-4:00	1:00	WARST	1991 Mar  1
+			-4:00	-	WART	1991 Jun  1
+			-3:00	-	ART	1999 Oct  3
+			-4:00	1:00	WARST	2000 Mar  3
+			-3:00	-	ART	2004 May 31
+			-4:00	-	WART	2004 Jul 25
+			-3:00	Arg	AR%sT	2008 Jan 21
+			-4:00	SanLuis	WAR%sT
+#
+# Santa Cruz (SC)
+Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 Jun  1
+			-4:00	-	WART	2004 Jun 20
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+#
+# Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF)
+Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 May 30
+			-4:00	-	WART	2004 Jun 20
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+
+# Aruba
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Aruba	-4:40:24 -	LMT	1912 Feb 12	# Oranjestad
+			-4:30	-	ANT	1965 # Netherlands Antilles Time
+			-4:00	-	AST
+
+# Bolivia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/La_Paz	-4:32:36 -	LMT	1890
+			-4:32:36 -	CMT	1931 Oct 15 # Calamarca MT
+			-4:32:36 1:00	BOST	1932 Mar 21 # Bolivia ST
+			-4:00	-	BOT	# Bolivia Time
+
+# Brazil
+
+# From Paul Eggert (1993-11-18):
+# The mayor of Rio recently attempted to change the time zone rules
+# just in his city, in order to leave more summer time for the tourist trade.
+# The rule change lasted only part of the day;
+# the federal government refused to follow the city's rules, and business
+# was in a chaos, so the mayor backed down that afternoon.
+
+# From IATA SSIM (1996-02):
+# _Only_ the following states in BR1 observe DST: Rio Grande do Sul (RS),
+# Santa Catarina (SC), Parana (PR), Sao Paulo (SP), Rio de Janeiro (RJ),
+# Espirito Santo (ES), Minas Gerais (MG), Bahia (BA), Goias (GO),
+# Distrito Federal (DF), Tocantins (TO), Sergipe [SE] and Alagoas [AL].
+# [The last three states are new to this issue of the IATA SSIM.]
+
+# From Gwillim Law (1996-10-07):
+# Geography, history (Tocantins was part of Goias until 1989), and other
+# sources of time zone information lead me to believe that AL, SE, and TO were
+# always in BR1, and so the only change was whether or not they observed DST....
+# The earliest issue of the SSIM I have is 2/91.  Each issue from then until
+# 9/95 says that DST is observed only in the ten states I quoted from 9/95,
+# along with Mato Grosso (MT) and Mato Grosso do Sul (MS), which are in BR2
+# (UTC-4)....  The other two time zones given for Brazil are BR3, which is
+# UTC-5, no DST, and applies only in the state of Acre (AC); and BR4, which is
+# UTC-2, and applies to Fernando de Noronha (formerly FN, but I believe it's
+# become part of the state of Pernambuco).  The boundary between BR1 and BR2
+# has never been clearly stated.  They've simply been called East and West.
+# However, some conclusions can be drawn from another IATA manual: the Airline
+# Coding Directory, which lists close to 400 airports in Brazil.  For each
+# airport it gives a time zone which is coded to the SSIM.  From that
+# information, I'm led to conclude that the states of Amapa (AP), Ceara (CE),
+# Maranhao (MA), Paraiba (PR), Pernambuco (PE), Piaui (PI), and Rio Grande do
+# Norte (RN), and the eastern part of Para (PA) are all in BR1 without DST.
+
+# From Marcos Tadeu (1998-09-27):
+# <a href="http://pcdsh01.on.br/verao1.html">
+# Brazilian official page
+# </a>
+
+# From Jesper Norgaard (2000-11-03):
+# [For an official list of which regions in Brazil use which time zones, see:]
+# http://pcdsh01.on.br/Fusbr.htm
+# http://pcdsh01.on.br/Fusbrhv.htm
+
+# From Celso Doria via David Madeo (2002-10-09):
+# The reason for the delay this year has to do with elections in Brazil.
+#
+# Unlike in the United States, elections in Brazil are 100% computerized and
+# the results are known almost immediately.  Yesterday, it was the first
+# round of the elections when 115 million Brazilians voted for President,
+# Governor, Senators, Federal Deputies, and State Deputies.  Nobody is
+# counting (or re-counting) votes anymore and we know there will be a second
+# round for the Presidency and also for some Governors.  The 2nd round will
+# take place on October 27th.
+#
+# The reason why the DST will only begin November 3rd is that the thousands
+# of electoral machines used cannot have their time changed, and since the
+# Constitution says the elections must begin at 8:00 AM and end at 5:00 PM,
+# the Government decided to postpone DST, instead of changing the Constitution
+# (maybe, for the next elections, it will be possible to change the clock)...
+
+# From Rodrigo Severo (2004-10-04):
+# It's just the biannual change made necessary by the much hyped, supposedly
+# modern Brazilian eletronic voting machines which, apparently, can't deal
+# with a time change between the first and the second rounds of the elections.
+
+# From Steffen Thorsen (2007-09-20):
+# Brazil will start DST on 2007-10-14 00:00 and end on 2008-02-17 00:00:
+# http://www.mme.gov.br/site/news/detail.do;jsessionid=BBA06811AFCAAC28F0285210913513DA?newsId=13975
+
+# From Paul Schulze (2008-06-24):
+# ...by law number 11.662 of April 24, 2008 (published in the "Diario
+# Oficial da Uniao"...) in Brazil there are changes in the timezones,
+# effective today (00:00am at June 24, 2008) as follows:
+#
+# a) The timezone UTC+5 is e[x]tinguished, with all the Acre state and the
+# part of the Amazonas state that had this timezone now being put to the
+# timezone UTC+4
+# b) The whole Para state now is put at timezone UTC+3, instead of just
+# part of it, as was before.
+#
+# This change follows a proposal of senator Tiao Viana of Acre state, that
+# proposed it due to concerns about open television channels displaying
+# programs inappropriate to youths in the states that had the timezone
+# UTC+5 too early in the night. In the occasion, some more corrections
+# were proposed, trying to unify the timezones of any given state. This
+# change modifies timezone rules defined in decree 2.784 of 18 June,
+# 1913.
+
+# From Rodrigo Severo (2008-06-24):
+# Just correcting the URL:
+# <a href="https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=do&secao=1&pagina=1&data=25/04/2008">
+# https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=do&secao=1&pagina=1&data=25/04/2008
+# </a>
+#
+# As a result of the above Decree I believe the America/Rio_Branco
+# timezone shall be modified from UTC-5 to UTC-4 and a new timezone shall
+# be created to represent the...west side of the Para State. I
+# suggest this new timezone be called Santarem as the most
+# important/populated city in the affected area.
+#
+# This new timezone would be the same as the Rio_Branco timezone up to
+# the 2008/06/24 change which would be to UTC-3 instead of UTC-4.
+
+# From Alex Krivenyshev (2008-06-24):
+# This is a quick reference page for New and Old Brazil Time Zones map.
+# <a href="http://www.worldtimezone.com/brazil-time-new-old.php">
+# http://www.worldtimezone.com/brazil-time-new-old.php
+# </a>
+#
+# - 4 time zones replaced by 3 time zones-eliminating time zone UTC- 05
+# (state Acre and the part of the Amazonas will be UTC/GMT- 04) - western
+# part of Par state is moving to one timezone UTC- 03 (from UTC -04).
+
+# From Paul Eggert (2002-10-10):
+# The official decrees referenced below are mostly taken from
+# <a href="http://pcdsh01.on.br/DecHV.html">
+# Decretos sobre o Horario de Verao no Brasil
+# </a>.
+
+# From Steffen Thorsen (2008-08-29):
+# As announced by the government and many newspapers in Brazil late
+# yesterday, Brazil will start DST on 2008-10-19 (need to change rule) and
+# it will end on 2009-02-15 (current rule for Brazil is fine). Based on
+# past years experience with the elections, there was a good chance that
+# the start was postponed to November, but it did not happen this year.
+#
+# It has not yet been posted to http://pcdsh01.on.br/DecHV.html
+#
+# An official page about it:
+# <a href="http://www.mme.gov.br/site/news/detail.do?newsId=16722">
+# http://www.mme.gov.br/site/news/detail.do?newsId=16722
+# </a>
+# Note that this link does not always work directly, but must be accessed
+# by going to
+# <a href="http://www.mme.gov.br/first">
+# http://www.mme.gov.br/first
+# </a>
+#
+# One example link that works directly:
+# <a href="http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54">
+# http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54
+# (Portuguese)
+# </a>
+#
+# We have a written a short article about it as well:
+# <a href="http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html">
+# http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html
+# </a>
+#
+# From Alexander Krivenyshev (2011-10-04):
+# State Bahia will return to Daylight savings time this year after 8 years off.
+# The announcement was made by Governor Jaques Wagner in an interview to a
+# television station in Salvador.
+
+# In Portuguese:
+# <a href="http://g1.globo.com/bahia/noticia/2011/10/governador-jaques-wagner-confirma-horario-de-verao-na-bahia.html">
+# http://g1.globo.com/bahia/noticia/2011/10/governador-jaques-wagner-confirma-horario-de-verao-na-bahia.html
+# </a> and
+# <a href="http://noticias.terra.com.br/brasil/noticias/0,,OI5390887-EI8139,00-Bahia+volta+a+ter+horario+de+verao+apos+oito+anos.html">
+# http://noticias.terra.com.br/brasil/noticias/0,,OI5390887-EI8139,00-Bahia+volta+a+ter+horario+de+verao+apos+oito+anos.html
+# </a>
+
+# From Guilherme Bernardes Rodrigues (2011-10-07):
+# There is news in the media, however there is still no decree about it.
+# I just send a e-mail to Zulmira Brandão at
+# <a href="http://pcdsh01.on.br/">http://pcdsh01.on.br/</a> the
+# oficial agency about time in Brazil, and she confirmed that the old rule is
+# still in force.
+
+# From Guilherme Bernardes Rodrigues (2011-10-14)
+# It's official, the President signed a decree that includes Bahia in summer
+# time.
+#	 [ and in a second message (same day): ]
+# I found the decree.
+#
+# DECRETO No- 7.584, DE 13 DE OUTUBRO DE 2011
+# Link :
+# <a href="http://www.in.gov.br/visualiza/index.jsp?data=13/10/2011&jornal=1000&pagina=6&totalArquivos=6">
+# http://www.in.gov.br/visualiza/index.jsp?data=13/10/2011&jornal=1000&pagina=6&totalArquivos=6
+# </a>
+
+# From Kelley Cook (2012-10-16):
+# The governor of state of Bahia in Brazil announced on Thursday that
+# due to public pressure, he is reversing the DST policy they implemented
+# last year and will not be going to Summer Time on October 21st....
+# http://www.correio24horas.com.br/r/artigo/apos-pressoes-wagner-suspende-horario-de-verao-na-bahia
+
+# From Rodrigo Severo (2012-10-16):
+# Tocantins state will have DST.
+# http://noticias.terra.com.br/brasil/noticias/0,,OI6232536-EI306.html
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Decree <a href="http://pcdsh01.on.br/HV20466.htm">20,466</a> (1931-10-01)
+# Decree <a href="http://pcdsh01.on.br/HV21896.htm">21,896</a> (1932-01-10)
+Rule	Brazil	1931	only	-	Oct	 3	11:00	1:00	S
+Rule	Brazil	1932	1933	-	Apr	 1	 0:00	0	-
+Rule	Brazil	1932	only	-	Oct	 3	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV23195.htm">23,195</a> (1933-10-10)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV27496.htm">27,496</a> (1949-11-24)
+# Decree <a href="http://pcdsh01.on.br/HV27998.htm">27,998</a> (1950-04-13)
+Rule	Brazil	1949	1952	-	Dec	 1	 0:00	1:00	S
+Rule	Brazil	1950	only	-	Apr	16	 1:00	0	-
+Rule	Brazil	1951	1952	-	Apr	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV32308.htm">32,308</a> (1953-02-24)
+Rule	Brazil	1953	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV34724.htm">34,724</a> (1953-11-30)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV52700.htm">52,700</a> (1963-10-18)
+# established DST from 1963-10-23 00:00 to 1964-02-29 00:00
+# in SP, RJ, GB, MG, ES, due to the prolongation of the drought.
+# Decree <a href="http://pcdsh01.on.br/HV53071.htm">53,071</a> (1963-12-03)
+# extended the above decree to all of the national territory on 12-09.
+Rule	Brazil	1963	only	-	Dec	 9	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV53604.htm">53,604</a> (1964-02-25)
+# extended summer time by one day to 1964-03-01 00:00 (start of school).
+Rule	Brazil	1964	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV55639.htm">55,639</a> (1965-01-27)
+Rule	Brazil	1965	only	-	Jan	31	 0:00	1:00	S
+Rule	Brazil	1965	only	-	Mar	31	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV57303.htm">57,303</a> (1965-11-22)
+Rule	Brazil	1965	only	-	Dec	 1	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV57843.htm">57,843</a> (1966-02-18)
+Rule	Brazil	1966	1968	-	Mar	 1	 0:00	0	-
+Rule	Brazil	1966	1967	-	Nov	 1	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV63429.htm">63,429</a> (1968-10-15)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV91698.htm">91,698</a> (1985-09-27)
+Rule	Brazil	1985	only	-	Nov	 2	 0:00	1:00	S
+# Decree 92,310 (1986-01-21)
+# Decree 92,463 (1986-03-13)
+Rule	Brazil	1986	only	-	Mar	15	 0:00	0	-
+# Decree 93,316 (1986-10-01)
+Rule	Brazil	1986	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1987	only	-	Feb	14	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV94922.htm">94,922</a> (1987-09-22)
+Rule	Brazil	1987	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1988	only	-	Feb	 7	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV96676.htm">96,676</a> (1988-09-12)
+# except for the states of AC, AM, PA, RR, RO, and AP (then a territory)
+Rule	Brazil	1988	only	-	Oct	16	 0:00	1:00	S
+Rule	Brazil	1989	only	-	Jan	29	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV98077.htm">98,077</a> (1989-08-21)
+# with the same exceptions
+Rule	Brazil	1989	only	-	Oct	15	 0:00	1:00	S
+Rule	Brazil	1990	only	-	Feb	11	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV99530.htm">99,530</a> (1990-09-17)
+# adopted by RS, SC, PR, SP, RJ, ES, MG, GO, MS, DF.
+# Decree 99,629 (1990-10-19) adds BA, MT.
+Rule	Brazil	1990	only	-	Oct	21	 0:00	1:00	S
+Rule	Brazil	1991	only	-	Feb	17	 0:00	0	-
+# <a href="http://pcdsh01.on.br/HV1991.htm">Unnumbered decree</a> (1991-09-25)
+# adopted by RS, SC, PR, SP, RJ, ES, MG, BA, GO, MT, MS, DF.
+Rule	Brazil	1991	only	-	Oct	20	 0:00	1:00	S
+Rule	Brazil	1992	only	-	Feb	 9	 0:00	0	-
+# <a href="http://pcdsh01.on.br/HV1992.htm">Unnumbered decree</a> (1992-10-16)
+# adopted by same states.
+Rule	Brazil	1992	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1993	only	-	Jan	31	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV942.htm">942</a> (1993-09-28)
+# adopted by same states, plus AM.
+# Decree <a href="http://pcdsh01.on.br/HV1252.htm">1,252</a> (1994-09-22;
+# web page corrected 2004-01-07) adopted by same states, minus AM.
+# Decree <a href="http://pcdsh01.on.br/HV1636.htm">1,636</a> (1995-09-14)
+# adopted by same states, plus MT and TO.
+# Decree <a href="http://pcdsh01.on.br/HV1674.htm">1,674</a> (1995-10-13)
+# adds AL, SE.
+Rule	Brazil	1993	1995	-	Oct	Sun>=11	 0:00	1:00	S
+Rule	Brazil	1994	1995	-	Feb	Sun>=15	 0:00	0	-
+Rule	Brazil	1996	only	-	Feb	11	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV2000.htm">2,000</a> (1996-09-04)
+# adopted by same states, minus AL, SE.
+Rule	Brazil	1996	only	-	Oct	 6	 0:00	1:00	S
+Rule	Brazil	1997	only	-	Feb	16	 0:00	0	-
+# From Daniel C. Sobral (1998-02-12):
+# In 1997, the DS began on October 6. The stated reason was that
+# because international television networks ignored Brazil's policy on DS,
+# they bought the wrong times on satellite for coverage of Pope's visit.
+# This year, the ending date of DS was postponed to March 1
+# to help dealing with the shortages of electric power.
+#
+# Decree 2,317 (1997-09-04), adopted by same states.
+Rule	Brazil	1997	only	-	Oct	 6	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/figuras/HV2495.JPG">2,495</a>
+# (1998-02-10)
+Rule	Brazil	1998	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/figuras/Hv98.jpg">2,780</a> (1998-09-11)
+# adopted by the same states as before.
+Rule	Brazil	1998	only	-	Oct	11	 0:00	1:00	S
+Rule	Brazil	1999	only	-	Feb	21	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/figuras/HV3150.gif">3,150</a>
+# (1999-08-23) adopted by same states.
+# Decree <a href="http://pcdsh01.on.br/DecHV99.gif">3,188</a> (1999-09-30)
+# adds SE, AL, PB, PE, RN, CE, PI, MA and RR.
+Rule	Brazil	1999	only	-	Oct	 3	 0:00	1:00	S
+Rule	Brazil	2000	only	-	Feb	27	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/DEC3592.htm">3,592</a> (2000-09-06)
+# adopted by the same states as before.
+# Decree <a href="http://pcdsh01.on.br/Dec3630.jpg">3,630</a> (2000-10-13)
+# repeals DST in PE and RR, effective 2000-10-15 00:00.
+# Decree <a href="http://pcdsh01.on.br/Dec3632.jpg">3,632</a> (2000-10-17)
+# repeals DST in SE, AL, PB, RN, CE, PI and MA, effective 2000-10-22 00:00.
+# Decree <a href="http://pcdsh01.on.br/figuras/HV3916.gif">3,916</a>
+# (2001-09-13) reestablishes DST in AL, CE, MA, PB, PE, PI, RN, SE.
+Rule	Brazil	2000	2001	-	Oct	Sun>=8	 0:00	1:00	S
+Rule	Brazil	2001	2006	-	Feb	Sun>=15	 0:00	0	-
+# Decree 4,399 (2002-10-01) repeals DST in AL, CE, MA, PB, PE, PI, RN, SE.
+# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/2002/D4399.htm">4,399</a>
+Rule	Brazil	2002	only	-	Nov	 3	 0:00	1:00	S
+# Decree 4,844 (2003-09-24; corrected 2003-09-26) repeals DST in BA, MT, TO.
+# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/2003/D4844.htm">4,844</a>
+Rule	Brazil	2003	only	-	Oct	19	 0:00	1:00	S
+# Decree 5,223 (2004-10-01) reestablishes DST in MT.
+# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2004-2006/2004/Decreto/D5223.htm">5,223</a>
+Rule	Brazil	2004	only	-	Nov	 2	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/DecHV5539.gif">5,539</a> (2005-09-19),
+# adopted by the same states as before.
+Rule	Brazil	2005	only	-	Oct	16	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/DecHV5920.gif">5,920</a> (2006-10-03),
+# adopted by the same states as before.
+Rule	Brazil	2006	only	-	Nov	 5	 0:00	1:00	S
+Rule	Brazil	2007	only	-	Feb	25	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/DecHV6212.gif">6,212</a> (2007-09-26),
+# adopted by the same states as before.
+Rule	Brazil	2007	only	-	Oct	Sun>=8	 0:00	1:00	S
+# From Frederico A. C. Neves (2008-09-10):
+# Acording to this decree
+# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm">
+# http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm
+# </a>
+# [t]he DST period in Brazil now on will be from the 3rd Oct Sunday to the
+# 3rd Feb Sunday. There is an exception on the return date when this is
+# the Carnival Sunday then the return date will be the next Sunday...
+Rule	Brazil	2008	max	-	Oct	Sun>=15	0:00	1:00	S
+Rule	Brazil	2008	2011	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2012	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2013	2014	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2015	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2016	2022	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2023	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2024	2025	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2026	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2027	2033	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2034	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2035	2036	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2037	only	-	Feb	Sun>=22	0:00	0	-
+# From Arthur David Olson (2008-09-29):
+# The next is wrong in some years but is better than nothing.
+Rule	Brazil	2038	max	-	Feb	Sun>=15	0:00	0	-
+
+# The latest ruleset listed above says that the following states observe DST:
+# DF, ES, GO, MG, MS, MT, PR, RJ, RS, SC, SP.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Fernando de Noronha (administratively part of PE)
+Zone America/Noronha	-2:09:40 -	LMT	1914
+			-2:00	Brazil	FN%sT	1990 Sep 17
+			-2:00	-	FNT	1999 Sep 30
+			-2:00	Brazil	FN%sT	2000 Oct 15
+			-2:00	-	FNT	2001 Sep 13
+			-2:00	Brazil	FN%sT	2002 Oct  1
+			-2:00	-	FNT
+# Other Atlantic islands have no permanent settlement.
+# These include Trindade and Martin Vaz (administratively part of ES),
+# Atol das Rocas (RN), and Penedos de Sao Pedro e Sao Paulo (PE).
+# Fernando de Noronha was a separate territory from 1942-09-02 to 1989-01-01;
+# it also included the Penedos.
+#
+# Amapa (AP), east Para (PA)
+# East Para includes Belem, Maraba, Serra Norte, and Sao Felix do Xingu.
+# The division between east and west Para is the river Xingu.
+# In the north a very small part from the river Javary (now Jari I guess,
+# the border with Amapa) to the Amazon, then to the Xingu.
+Zone America/Belem	-3:13:56 -	LMT	1914
+			-3:00	Brazil	BR%sT	1988 Sep 12
+			-3:00	-	BRT
+#
+# west Para (PA)
+# West Para includes Altamira, Oribidos, Prainha, Oriximina, and Santarem.
+Zone America/Santarem	-3:38:48 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT	2008 Jun 24 00:00
+			-3:00	-	BRT
+#
+# Maranhao (MA), Piaui (PI), Ceara (CE), Rio Grande do Norte (RN),
+# Paraiba (PB)
+Zone America/Fortaleza	-2:34:00 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 22
+			-3:00	-	BRT	2001 Sep 13
+			-3:00	Brazil	BR%sT	2002 Oct  1
+			-3:00	-	BRT
+#
+# Pernambuco (PE) (except Atlantic islands)
+Zone America/Recife	-2:19:36 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 15
+			-3:00	-	BRT	2001 Sep 13
+			-3:00	Brazil	BR%sT	2002 Oct  1
+			-3:00	-	BRT
+#
+# Tocantins (TO)
+Zone America/Araguaina	-3:12:48 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1995 Sep 14
+			-3:00	Brazil	BR%sT	2003 Sep 24
+			-3:00	-	BRT	2012 Oct 21
+			-3:00	Brazil	BR%sT
+#
+# Alagoas (AL), Sergipe (SE)
+Zone America/Maceio	-2:22:52 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1995 Oct 13
+			-3:00	Brazil	BR%sT	1996 Sep  4
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 22
+			-3:00	-	BRT	2001 Sep 13
+			-3:00	Brazil	BR%sT	2002 Oct  1
+			-3:00	-	BRT
+#
+# Bahia (BA)
+# There are too many Salvadors elsewhere, so use America/Bahia instead
+# of America/Salvador.
+Zone America/Bahia	-2:34:04 -	LMT	1914
+			-3:00	Brazil	BR%sT	2003 Sep 24
+			-3:00	-	BRT	2011 Oct 16
+			-3:00	Brazil	BR%sT	2012 Oct 21
+			-3:00	-	BRT
+#
+# Goias (GO), Distrito Federal (DF), Minas Gerais (MG),
+# Espirito Santo (ES), Rio de Janeiro (RJ), Sao Paulo (SP), Parana (PR),
+# Santa Catarina (SC), Rio Grande do Sul (RS)
+Zone America/Sao_Paulo	-3:06:28 -	LMT	1914
+			-3:00	Brazil	BR%sT	1963 Oct 23 00:00
+			-3:00	1:00	BRST	1964
+			-3:00	Brazil	BR%sT
+#
+# Mato Grosso do Sul (MS)
+Zone America/Campo_Grande -3:38:28 -	LMT	1914
+			-4:00	Brazil	AM%sT
+#
+# Mato Grosso (MT)
+Zone America/Cuiaba	-3:44:20 -	LMT	1914
+			-4:00	Brazil	AM%sT	2003 Sep 24
+			-4:00	-	AMT	2004 Oct  1
+			-4:00	Brazil	AM%sT
+#
+# Rondonia (RO)
+Zone America/Porto_Velho -4:15:36 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT
+#
+# Roraima (RR)
+Zone America/Boa_Vista	-4:02:40 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT	1999 Sep 30
+			-4:00	Brazil	AM%sT	2000 Oct 15
+			-4:00	-	AMT
+#
+# east Amazonas (AM): Boca do Acre, Jutai, Manaus, Floriano Peixoto
+# The great circle line from Tabatinga to Porto Acre divides
+# east from west Amazonas.
+Zone America/Manaus	-4:00:04 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT	1993 Sep 28
+			-4:00	Brazil	AM%sT	1994 Sep 22
+			-4:00	-	AMT
+#
+# west Amazonas (AM): Atalaia do Norte, Boca do Maoco, Benjamin Constant,
+#	Eirunepe, Envira, Ipixuna
+Zone America/Eirunepe	-4:39:28 -	LMT	1914
+			-5:00	Brazil	AC%sT	1988 Sep 12
+			-5:00	-	ACT	1993 Sep 28
+			-5:00	Brazil	AC%sT	1994 Sep 22
+			-5:00	-	ACT	2008 Jun 24 00:00
+			-4:00	-	AMT
+#
+# Acre (AC)
+Zone America/Rio_Branco	-4:31:12 -	LMT	1914
+			-5:00	Brazil	AC%sT	1988 Sep 12
+			-5:00	-	ACT	2008 Jun 24 00:00
+			-4:00	-	AMT
+
+# Chile
+
+# From Eduardo Krell (1995-10-19):
+# The law says to switch to DST at midnight [24:00] on the second SATURDAY
+# of October....  The law is the same for March and October.
+# (1998-09-29):
+# Because of the drought this year, the government decided to go into
+# DST earlier (saturday 9/26 at 24:00). This is a one-time change only ...
+# (unless there's another dry season next year, I guess).
+
+# From Julio I. Pacheco Troncoso (1999-03-18):
+# Because of the same drought, the government decided to end DST later,
+# on April 3, (one-time change).
+
+# From Oscar van Vlijmen (2006-10-08):
+# http://www.horaoficial.cl/cambio.htm
+
+# From Jesper Norgaard Welen (2006-10-08):
+# I think that there are some obvious mistakes in the suggested link
+# from Oscar van Vlijmen,... for instance entry 66 says that GMT-4
+# ended 1990-09-12 while entry 67 only begins GMT-3 at 1990-09-15
+# (they should have been 1990-09-15 and 1990-09-16 respectively), but
+# anyhow it clears up some doubts too.
+
+# From Paul Eggert (2006-12-27):
+# The following data for Chile and America/Santiago are from
+# <http://www.horaoficial.cl/horaof.htm> (2006-09-20), transcribed by
+# Jesper Norgaard Welen.  The data for Pacific/Easter are from Shanks
+# & Pottenger, except with DST transitions after 1932 cloned from
+# America/Santiago.  The pre-1980 Pacific/Easter data are dubious,
+# but we have no other source.
+
+# From German Poo-Caaman~o (2008-03-03):
+# Due to drought, Chile extends Daylight Time in three weeks.  This
+# is one-time change (Saturday 3/29 at 24:00 for America/Santiago
+# and Saturday 3/29 at 22:00 for Pacific/Easter)
+# The Supreme Decree is located at
+# <a href="http://www.shoa.cl/servicios/supremo316.pdf">
+# http://www.shoa.cl/servicios/supremo316.pdf
+# </a>
+# and the instructions for 2008 are located in:
+# <a href="http://www.horaoficial.cl/cambio.htm">
+# http://www.horaoficial.cl/cambio.htm
+# </a>.
+
+# From Jose Miguel Garrido (2008-03-05):
+# ...
+# You could see the announces of the change on
+# <a href="http://www.shoa.cl/noticias/2008/04hora/hora.htm">
+# http://www.shoa.cl/noticias/2008/04hora/hora.htm
+# </a>.
+
+# From Angel Chiang (2010-03-04):
+# Subject: DST in Chile exceptionally extended to 3 April due to earthquake
+# <a href="http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098">
+# http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098
+# </a>
+# (in Spanish, last paragraph).
+#
+# This is breaking news. There should be more information available later.
+
+# From Arthur Daivd Olson (2010-03-06):
+# Angel Chiang's message confirmed by Julio Pacheco; Julio provided a patch.
+
+# From Glenn Eychaner (2011-03-02): [geychaner@mac.com]
+# It appears that the Chilean government has decided to postpone the
+# change from summer time to winter time again, by three weeks to April
+# 2nd:
+# <a href="http://www.emol.com/noticias/nacional/detalle/detallenoticias.asp?idnoticia=467651">
+# http://www.emol.com/noticias/nacional/detalle/detallenoticias.asp?idnoticia=467651
+# </a>
+#
+# This is not yet reflected in the offical "cambio de hora" site, but
+# probably will be soon:
+# <a href="http://www.horaoficial.cl/cambio.htm">
+# http://www.horaoficial.cl/cambio.htm
+# </a>
+
+# From Arthur David Olson (2011-03-02):
+# The emol.com article mentions a water shortage as the cause of the
+# postponement, which may mean that it's not a permanent change.
+
+# From Glenn Eychaner (2011-03-28):
+# The article:
+# <a href="http://diario.elmercurio.com/2011/03/28/_portada/_portada/noticias/7565897A-CA86-49E6-9E03-660B21A4883E.htm?id=3D{7565897A-CA86-49E6-9E03-660B21A4883E}">
+# http://diario.elmercurio.com/2011/03/28/_portada/_portada/noticias/7565897A-CA86-49E6-9E03-660B21A4883E.htm?id=3D{7565897A-CA86-49E6-9E03-660B21A4883E}
+# </a>
+#
+# In English:
+# Chile's clocks will go back an hour this year on the 7th of May instead
+# of this Saturday. They will go forward again the 3rd Saturday in
+# August, not in October as they have since 1968. This is a pilot plan
+# which will be reevaluated in 2012.
+
+# From Mauricio Parada (2012-02-22), translated by Glenn Eychaner (2012-02-23):
+# As stated in the website of the Chilean Energy Ministry
+# http://www.minenergia.cl/ministerio/noticias/generales/gobierno-anuncia-fechas-de-cambio-de.html
+# The Chilean Government has decided to postpone the entrance into winter time
+# (to leave DST) from March 11 2012 to April 28th 2012. The decision has not
+# been yet formalized but it will within the next days.
+# Quote from the website communication:
+#
+# 6. For the year 2012, the dates of entry into winter time will be as follows:
+# a. Saturday April 28, 2012, clocks should go back 60 minutes; that is, at
+# 23:59:59, instead of passing to 0:00, the time should be adjusted to be 23:00
+# of the same day.
+# b. Saturday, September 1, 2012, clocks should go forward 60 minutes; that is,
+# at 23:59:59, instead of passing to 0:00, the time should be adjusted to be
+# 01:00 on September 2.
+#
+# Note that...this is yet another "temporary" change that will be reevaluated
+# AGAIN in 2013.
+
+# NOTE: ChileAQ rules for Antarctic bases are stored separately in the
+# 'antarctica' file.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Chile	1927	1932	-	Sep	 1	0:00	1:00	S
+Rule	Chile	1928	1932	-	Apr	 1	0:00	0	-
+Rule	Chile	1942	only	-	Jun	 1	4:00u	0	-
+Rule	Chile	1942	only	-	Aug	 1	5:00u	1:00	S
+Rule	Chile	1946	only	-	Jul	15	4:00u	1:00	S
+Rule	Chile	1946	only	-	Sep	 1	3:00u	0:00	-
+Rule	Chile	1947	only	-	Apr	 1	4:00u	0	-
+Rule	Chile	1968	only	-	Nov	 3	4:00u	1:00	S
+Rule	Chile	1969	only	-	Mar	30	3:00u	0	-
+Rule	Chile	1969	only	-	Nov	23	4:00u	1:00	S
+Rule	Chile	1970	only	-	Mar	29	3:00u	0	-
+Rule	Chile	1971	only	-	Mar	14	3:00u	0	-
+Rule	Chile	1970	1972	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1972	1986	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1973	only	-	Sep	30	4:00u	1:00	S
+Rule	Chile	1974	1987	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1987	only	-	Apr	12	3:00u	0	-
+Rule	Chile	1988	1989	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1988	only	-	Oct	Sun>=1	4:00u	1:00	S
+Rule	Chile	1989	only	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1990	only	-	Mar	18	3:00u	0	-
+Rule	Chile	1990	only	-	Sep	16	4:00u	1:00	S
+Rule	Chile	1991	1996	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1991	1997	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1997	only	-	Mar	30	3:00u	0	-
+Rule	Chile	1998	only	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1998	only	-	Sep	27	4:00u	1:00	S
+Rule	Chile	1999	only	-	Apr	 4	3:00u	0	-
+Rule	Chile	1999	2010	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	2000	2007	-	Mar	Sun>=9	3:00u	0	-
+# N.B.: the end of March 29 in Chile is March 30 in Universal time,
+# which is used below in specifying the transition.
+Rule	Chile	2008	only	-	Mar	30	3:00u	0	-
+Rule	Chile	2009	only	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	2010	only	-	Apr	Sun>=1	3:00u	0	-
+Rule	Chile	2011	only	-	May	Sun>=2	3:00u	0	-
+Rule	Chile	2011	only	-	Aug	Sun>=16	4:00u	1:00	S
+Rule	Chile	2012	only	-	Apr	Sun>=23	3:00u	0	-
+Rule	Chile	2012	only	-	Sep	Sun>=2	4:00u	1:00	S
+Rule	Chile	2013	max	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	2013	max	-	Oct	Sun>=9	4:00u	1:00	S
+# IATA SSIM anomalies: (1992-02) says 1992-03-14;
+# (1996-09) says 1998-03-08.  Ignore these.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Santiago	-4:42:46 -	LMT	1890
+			-4:42:46 -	SMT	1910 	    # Santiago Mean Time
+			-5:00	-	CLT	1916 Jul  1 # Chile Time
+			-4:42:46 -	SMT	1918 Sep  1 # Santiago Mean Time
+			-4:00	-	CLT	1919 Jul  1 # Chile Time
+			-4:42:46 -	SMT	1927 Sep  1 # Santiago Mean Time
+			-5:00	Chile	CL%sT	1947 May 22 # Chile Time
+			-4:00	Chile	CL%sT
+Zone Pacific/Easter	-7:17:44 -	LMT	1890
+			-7:17:28 -	EMT	1932 Sep    # Easter Mean Time
+			-7:00	Chile	EAS%sT	1982 Mar 13 21:00 # Easter I Time
+			-6:00	Chile	EAS%sT
+#
+# Sala y Gomez Island is like Pacific/Easter.
+# Other Chilean locations, including Juan Fernandez Is, San Ambrosio,
+# San Felix, and Antarctic bases, are like America/Santiago.
+
+# Colombia
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	CO	1992	only	-	May	 3	0:00	1:00	S
+Rule	CO	1993	only	-	Apr	 4	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Bogota	-4:56:20 -	LMT	1884 Mar 13
+			-4:56:20 -	BMT	1914 Nov 23 # Bogota Mean Time
+			-5:00	CO	CO%sT	# Colombia Time
+# Malpelo, Providencia, San Andres
+# no information; probably like America/Bogota
+
+# Curacao
+#
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say that The Bottom and Philipsburg have been at
+# -4:00 since standard time was introduced on 1912-03-02; and that
+# Kralendijk and Rincon used Kralendijk Mean Time (-4:33:08) from
+# 1912-02-02 to 1965-01-01.  The former is dubious, since S&P also say
+# Saba Island has been like Curacao.
+# This all predates our 1970 cutoff, though.
+#
+# By July 2007 Curacao and St Maarten are planned to become
+# associated states within the Netherlands, much like Aruba;
+# Bonaire, Saba and St Eustatius would become directly part of the
+# Netherlands as Kingdom Islands.  This won't affect their time zones
+# though, as far as we know.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Curacao	-4:35:44 -	LMT	1912 Feb 12	# Willemstad
+			-4:30	-	ANT	1965 # Netherlands Antilles Time
+			-4:00	-	AST
+
+# From Arthur David Olson (2011-06-15):
+# At least for now, use links for places with new iso3166 codes.
+# The name "Lower Prince's Quarter" is both longer than fourteen charaters
+# and contains an apostrophe; use "Lower_Princes" below.
+
+Link	America/Curacao	America/Lower_Princes # Sint Maarten
+Link	America/Curacao	America/Kralendijk # Bonaire, Sint Estatius and Saba
+
+# Ecuador
+#
+# From Paul Eggert (2007-03-04):
+# Apparently Ecuador had a failed experiment with DST in 1992.
+# <http://midena.gov.ec/content/view/1261/208/> (2007-02-27) and
+# <http://www.hoy.com.ec/NoticiaNue.asp?row_id=249856> (2006-11-06) both
+# talk about "hora Sixto".  Leave this alone for now, as we have no data.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Guayaquil	-5:19:20 -	LMT	1890
+			-5:14:00 -	QMT	1931 # Quito Mean Time
+			-5:00	-	ECT	     # Ecuador Time
+Zone Pacific/Galapagos	-5:58:24 -	LMT	1931 # Puerto Baquerizo Moreno
+			-5:00	-	ECT	1986
+			-6:00	-	GALT	     # Galapagos Time
+
+# Falklands
+
+# From Paul Eggert (2006-03-22):
+# Between 1990 and 2000 inclusive, Shanks & Pottenger and the IATA agree except
+# the IATA gives 1996-09-08.  Go with Shanks & Pottenger.
+
+# From Falkland Islands Government Office, London (2001-01-22)
+# via Jesper Norgaard:
+# ... the clocks revert back to Local Mean Time at 2 am on Sunday 15
+# April 2001 and advance one hour to summer time at 2 am on Sunday 2
+# September.  It is anticipated that the clocks will revert back at 2
+# am on Sunday 21 April 2002 and advance to summer time at 2 am on
+# Sunday 1 September.
+
+# From Rives McDow (2001-02-13):
+#
+# I have communicated several times with people there, and the last
+# time I had communications that was helpful was in 1998.  Here is
+# what was said then:
+#
+# "The general rule was that Stanley used daylight saving and the Camp
+# did not. However for various reasons many people in the Camp have
+# started to use daylight saving (known locally as 'Stanley Time')
+# There is no rule as to who uses daylight saving - it is a matter of
+# personal choice and so it is impossible to draw a map showing who
+# uses it and who does not. Any list would be out of date as soon as
+# it was produced. This year daylight saving ended on April 18/19th
+# and started again on September 12/13th.  I do not know what the rule
+# is, but can find out if you like.  We do not change at the same time
+# as UK or Chile."
+#
+# I did have in my notes that the rule was "Second Saturday in Sep at
+# 0:00 until third Saturday in Apr at 0:00".  I think that this does
+# not agree in some cases with Shanks; is this true?
+#
+# Also, there is no mention in the list that some areas in the
+# Falklands do not use DST.  I have found in my communications there
+# that these areas are on the western half of East Falkland and all of
+# West Falkland.  Stanley is the only place that consistently observes
+# DST.  Again, as in other places in the world, the farmers don't like
+# it.  West Falkland is almost entirely sheep farmers.
+#
+# I know one lady there that keeps a list of which farm keeps DST and
+# which doesn't each year.  She runs a shop in Stanley, and says that
+# the list changes each year.  She uses it to communicate to her
+# customers, catching them when they are home for lunch or dinner.
+
+# From Paul Eggert (2001-03-05):
+# For now, we'll just record the time in Stanley, since we have no
+# better info.
+
+# From Steffen Thorsen (2011-04-01):
+# The Falkland Islands will not turn back clocks this winter, but stay on
+# daylight saving time.
+#
+# One source:
+# <a href="http://www.falklandnews.com/public/story.cfm?get=5914&source=3">
+# http://www.falklandnews.com/public/story.cfm?get=5914&source=3
+# </a>
+#
+# We have gotten this confirmed by a clerk of the legislative assembly:
+# Normally the clocks revert to Local Mean Time (UTC/GMT -4 hours) on the
+# third Sunday of April at 0200hrs and advance to Summer Time (UTC/GMT -3
+# hours) on the first Sunday of September at 0200hrs.
+#
+# IMPORTANT NOTE: During 2011, on a trial basis, the Falkland Islands
+# will not revert to local mean time, but clocks will remain on Summer
+# time (UTC/GMT - 3 hours) throughout the whole of 2011.  Any long term
+# change to local time following the trial period will be notified.
+#
+# From Andrew Newman (2012-02-24)
+# A letter from Justin McPhee, Chief Executive,
+# Cable & Wireless Falkland Islands (dated 2012-02-22)
+# states...
+#   The current Atlantic/Stanley entry under South America expects the
+#   clocks to go back to standard Falklands Time (FKT) on the 15th April.
+#   The database entry states that in 2011 Stanley was staying on fixed
+#   summer time on a trial basis only.  FIG need to contact IANA and/or
+#   the maintainers of the database to inform them we're adopting
+#   the same policy this year and suggest recommendations for future years.
+#
+# For now we will assume permanent summer time for the Falklands
+# until advised differently (to apply for 2012 and beyond, after the 2011
+# experiment was apparently successful.)
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Falk	1937	1938	-	Sep	lastSun	0:00	1:00	S
+Rule	Falk	1938	1942	-	Mar	Sun>=19	0:00	0	-
+Rule	Falk	1939	only	-	Oct	1	0:00	1:00	S
+Rule	Falk	1940	1942	-	Sep	lastSun	0:00	1:00	S
+Rule	Falk	1943	only	-	Jan	1	0:00	0	-
+Rule	Falk	1983	only	-	Sep	lastSun	0:00	1:00	S
+Rule	Falk	1984	1985	-	Apr	lastSun	0:00	0	-
+Rule	Falk	1984	only	-	Sep	16	0:00	1:00	S
+Rule	Falk	1985	2000	-	Sep	Sun>=9	0:00	1:00	S
+Rule	Falk	1986	2000	-	Apr	Sun>=16	0:00	0	-
+Rule	Falk	2001	2010	-	Apr	Sun>=15	2:00	0	-
+Rule	Falk	2001	2010	-	Sep	Sun>=1	2:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/Stanley	-3:51:24 -	LMT	1890
+			-3:51:24 -	SMT	1912 Mar 12  # Stanley Mean Time
+			-4:00	Falk	FK%sT	1983 May     # Falkland Is Time
+			-3:00	Falk	FK%sT	1985 Sep 15
+			-4:00	Falk	FK%sT	2010 Sep 5 02:00
+			-3:00	-	FKST
+
+# French Guiana
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Cayenne	-3:29:20 -	LMT	1911 Jul
+			-4:00	-	GFT	1967 Oct # French Guiana Time
+			-3:00	-	GFT
+
+# Guyana
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Guyana	-3:52:40 -	LMT	1915 Mar	# Georgetown
+			-3:45	-	GBGT	1966 May 26 # Br Guiana Time
+			-3:45	-	GYT	1975 Jul 31 # Guyana Time
+			-3:00	-	GYT	1991
+# IATA SSIM (1996-06) says -4:00.  Assume a 1991 switch.
+			-4:00	-	GYT
+
+# Paraguay
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say that spring transitions are from 01:00 -> 02:00,
+# and autumn transitions are from 00:00 -> 23:00.  Go with pre-1999
+# editions of Shanks, and with the IATA, who say transitions occur at 00:00.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Para	1975	1988	-	Oct	 1	0:00	1:00	S
+Rule	Para	1975	1978	-	Mar	 1	0:00	0	-
+Rule	Para	1979	1991	-	Apr	 1	0:00	0	-
+Rule	Para	1989	only	-	Oct	22	0:00	1:00	S
+Rule	Para	1990	only	-	Oct	 1	0:00	1:00	S
+Rule	Para	1991	only	-	Oct	 6	0:00	1:00	S
+Rule	Para	1992	only	-	Mar	 1	0:00	0	-
+Rule	Para	1992	only	-	Oct	 5	0:00	1:00	S
+Rule	Para	1993	only	-	Mar	31	0:00	0	-
+Rule	Para	1993	1995	-	Oct	 1	0:00	1:00	S
+Rule	Para	1994	1995	-	Feb	lastSun	0:00	0	-
+Rule	Para	1996	only	-	Mar	 1	0:00	0	-
+# IATA SSIM (2000-02) says 1999-10-10; ignore this for now.
+# From Steffen Thorsen (2000-10-02):
+# I have three independent reports that Paraguay changed to DST this Sunday
+# (10-01).
+#
+# Translated by Gwillim Law (2001-02-27) from
+# <a href="http://www.diarionoticias.com.py/011000/nacional/naciona1.htm">
+# Noticias, a daily paper in Asuncion, Paraguay (2000-10-01)
+# </a>:
+# Starting at 0:00 today, the clock will be set forward 60 minutes, in
+# fulfillment of Decree No. 7,273 of the Executive Power....  The time change
+# system has been operating for several years.  Formerly there was a separate
+# decree each year; the new law has the same effect, but permanently.  Every
+# year, the time will change on the first Sunday of October; likewise, the
+# clock will be set back on the first Sunday of March.
+#
+Rule	Para	1996	2001	-	Oct	Sun>=1	0:00	1:00	S
+# IATA SSIM (1997-09) says Mar 1; go with Shanks & Pottenger.
+Rule	Para	1997	only	-	Feb	lastSun	0:00	0	-
+# Shanks & Pottenger say 1999-02-28; IATA SSIM (1999-02) says 1999-02-27, but
+# (1999-09) reports no date; go with above sources and Gerd Knops (2001-02-27).
+Rule	Para	1998	2001	-	Mar	Sun>=1	0:00	0	-
+# From Rives McDow (2002-02-28):
+# A decree was issued in Paraguay (no. 16350) on 2002-02-26 that changed the
+# dst method to be from the first Sunday in September to the first Sunday in
+# April.
+Rule	Para	2002	2004	-	Apr	Sun>=1	0:00	0	-
+Rule	Para	2002	2003	-	Sep	Sun>=1	0:00	1:00	S
+#
+# From Jesper Norgaard Welen (2005-01-02):
+# There are several sources that claim that Paraguay made
+# a timezone rule change in autumn 2004.
+# From Steffen Thorsen (2005-01-05):
+# Decree 1,867 (2004-03-05)
+# From Carlos Raul Perasso via Jesper Norgaard Welen (2006-10-13)
+# <http://www.presidencia.gov.py/decretos/D1867.pdf>
+Rule	Para	2004	2009	-	Oct	Sun>=15	0:00	1:00	S
+Rule	Para	2005	2009	-	Mar	Sun>=8	0:00	0	-
+# From Carlos Raul Perasso (2010-02-18):
+# By decree number 3958 issued yesterday (
+# <a href="http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf">
+# http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf
+# </a>
+# )
+# Paraguay changes its DST schedule, postponing the March rule to April and
+# modifying the October date. The decree reads:
+# ...
+# Art. 1. It is hereby established that from the second Sunday of the month of
+# April of this year (2010), the official time is to be set back 60 minutes,
+# and that on the first Sunday of the month of October, it is to be set
+# forward 60 minutes, in all the territory of the Paraguayan Republic.
+# ...
+Rule	Para	2010	max	-	Oct	Sun>=1	0:00	1:00	S
+Rule	Para	2010	max	-	Apr	Sun>=8	0:00	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Asuncion	-3:50:40 -	LMT	1890
+			-3:50:40 -	AMT	1931 Oct 10 # Asuncion Mean Time
+			-4:00	-	PYT	1972 Oct # Paraguay Time
+			-3:00	-	PYT	1974 Apr
+			-4:00	Para	PY%sT
+
+# Peru
+#
+# <a href="news:xrGmb.39935$gA1.13896113@news4.srv.hcvlny.cv.net">
+# From Evelyn C. Leeper via Mark Brader (2003-10-26):</a>
+# When we were in Peru in 1985-1986, they apparently switched over
+# sometime between December 29 and January 3 while we were on the Amazon.
+#
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger don't have this transition.  Assume 1986 was like 1987.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Peru	1938	only	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1938	only	-	Apr	 1	0:00	0	-
+Rule	Peru	1938	1939	-	Sep	lastSun	0:00	1:00	S
+Rule	Peru	1939	1940	-	Mar	Sun>=24	0:00	0	-
+Rule	Peru	1986	1987	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1986	1987	-	Apr	 1	0:00	0	-
+Rule	Peru	1990	only	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1990	only	-	Apr	 1	0:00	0	-
+# IATA is ambiguous for 1993/1995; go with Shanks & Pottenger.
+Rule	Peru	1994	only	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1994	only	-	Apr	 1	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Lima	-5:08:12 -	LMT	1890
+			-5:08:36 -	LMT	1908 Jul 28 # Lima Mean Time?
+			-5:00	Peru	PE%sT	# Peru Time
+
+# South Georgia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/South_Georgia -2:26:08 -	LMT	1890		# Grytviken
+			-2:00	-	GST	# South Georgia Time
+
+# South Sandwich Is
+# uninhabited; scientific personnel have wintered
+
+# Suriname
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Paramaribo	-3:40:40 -	LMT	1911
+			-3:40:52 -	PMT	1935     # Paramaribo Mean Time
+			-3:40:36 -	PMT	1945 Oct # The capital moved?
+			-3:30	-	NEGT	1975 Nov 20 # Dutch Guiana Time
+			-3:30	-	SRT	1984 Oct # Suriname Time
+			-3:00	-	SRT
+
+# Trinidad and Tobago
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Port_of_Spain -4:06:04 -	LMT	1912 Mar 2
+			-4:00	-	AST
+
+# Uruguay
+# From Paul Eggert (1993-11-18):
+# Uruguay wins the prize for the strangest peacetime manipulation of the rules.
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Whitman gives 1923 Oct 1; go with Shanks & Pottenger.
+Rule	Uruguay	1923	only	-	Oct	 2	 0:00	0:30	HS
+Rule	Uruguay	1924	1926	-	Apr	 1	 0:00	0	-
+Rule	Uruguay	1924	1925	-	Oct	 1	 0:00	0:30	HS
+Rule	Uruguay	1933	1935	-	Oct	lastSun	 0:00	0:30	HS
+# Shanks & Pottenger give 1935 Apr 1 0:00 & 1936 Mar 30 0:00; go with Whitman.
+Rule	Uruguay	1934	1936	-	Mar	Sat>=25	23:30s	0	-
+Rule	Uruguay	1936	only	-	Nov	 1	 0:00	0:30	HS
+Rule	Uruguay	1937	1941	-	Mar	lastSun	 0:00	0	-
+# Whitman gives 1937 Oct 3; go with Shanks & Pottenger.
+Rule	Uruguay	1937	1940	-	Oct	lastSun	 0:00	0:30	HS
+# Whitman gives 1941 Oct 24 - 1942 Mar 27, 1942 Dec 14 - 1943 Apr 13,
+# and 1943 Apr 13 ``to present time''; go with Shanks & Pottenger.
+Rule	Uruguay	1941	only	-	Aug	 1	 0:00	0:30	HS
+Rule	Uruguay	1942	only	-	Jan	 1	 0:00	0	-
+Rule	Uruguay	1942	only	-	Dec	14	 0:00	1:00	S
+Rule	Uruguay	1943	only	-	Mar	14	 0:00	0	-
+Rule	Uruguay	1959	only	-	May	24	 0:00	1:00	S
+Rule	Uruguay	1959	only	-	Nov	15	 0:00	0	-
+Rule	Uruguay	1960	only	-	Jan	17	 0:00	1:00	S
+Rule	Uruguay	1960	only	-	Mar	 6	 0:00	0	-
+Rule	Uruguay	1965	1967	-	Apr	Sun>=1	 0:00	1:00	S
+Rule	Uruguay	1965	only	-	Sep	26	 0:00	0	-
+Rule	Uruguay	1966	1967	-	Oct	31	 0:00	0	-
+Rule	Uruguay	1968	1970	-	May	27	 0:00	0:30	HS
+Rule	Uruguay	1968	1970	-	Dec	 2	 0:00	0	-
+Rule	Uruguay	1972	only	-	Apr	24	 0:00	1:00	S
+Rule	Uruguay	1972	only	-	Aug	15	 0:00	0	-
+Rule	Uruguay	1974	only	-	Mar	10	 0:00	0:30	HS
+Rule	Uruguay	1974	only	-	Dec	22	 0:00	1:00	S
+Rule	Uruguay	1976	only	-	Oct	 1	 0:00	0	-
+Rule	Uruguay	1977	only	-	Dec	 4	 0:00	1:00	S
+Rule	Uruguay	1978	only	-	Apr	 1	 0:00	0	-
+Rule	Uruguay	1979	only	-	Oct	 1	 0:00	1:00	S
+Rule	Uruguay	1980	only	-	May	 1	 0:00	0	-
+Rule	Uruguay	1987	only	-	Dec	14	 0:00	1:00	S
+Rule	Uruguay	1988	only	-	Mar	14	 0:00	0	-
+Rule	Uruguay	1988	only	-	Dec	11	 0:00	1:00	S
+Rule	Uruguay	1989	only	-	Mar	12	 0:00	0	-
+Rule	Uruguay	1989	only	-	Oct	29	 0:00	1:00	S
+# Shanks & Pottenger say no DST was observed in 1990/1 and 1991/2,
+# and that 1992/3's DST was from 10-25 to 03-01.  Go with IATA.
+Rule	Uruguay	1990	1992	-	Mar	Sun>=1	 0:00	0	-
+Rule	Uruguay	1990	1991	-	Oct	Sun>=21	 0:00	1:00	S
+Rule	Uruguay	1992	only	-	Oct	18	 0:00	1:00	S
+Rule	Uruguay	1993	only	-	Feb	28	 0:00	0	-
+# From Eduardo Cota (2004-09-20):
+# The uruguayan government has decreed a change in the local time....
+# http://www.presidencia.gub.uy/decretos/2004091502.htm
+Rule	Uruguay	2004	only	-	Sep	19	 0:00	1:00	S
+# From Steffen Thorsen (2005-03-11):
+# Uruguay's DST was scheduled to end on Sunday, 2005-03-13, but in order to
+# save energy ... it was postponed two weeks....
+# http://www.presidencia.gub.uy/_Web/noticias/2005/03/2005031005.htm
+Rule	Uruguay	2005	only	-	Mar	27	 2:00	0	-
+# From Eduardo Cota (2005-09-27):
+# http://www.presidencia.gub.uy/_Web/decretos/2005/09/CM%20119_09%2009%202005_00001.PDF
+# This means that from 2005-10-09 at 02:00 local time, until 2006-03-12 at
+# 02:00 local time, official time in Uruguay will be at GMT -2.
+Rule	Uruguay	2005	only	-	Oct	 9	 2:00	1:00	S
+Rule	Uruguay	2006	only	-	Mar	12	 2:00	0	-
+# From Jesper Norgaard Welen (2006-09-06):
+# http://www.presidencia.gub.uy/_web/decretos/2006/09/CM%20210_08%2006%202006_00001.PDF
+Rule	Uruguay	2006	max	-	Oct	Sun>=1	 2:00	1:00	S
+Rule	Uruguay	2007	max	-	Mar	Sun>=8	 2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Montevideo	-3:44:44 -	LMT	1898 Jun 28
+			-3:44:44 -	MMT	1920 May  1	# Montevideo MT
+			-3:30	Uruguay	UY%sT	1942 Dec 14	# Uruguay Time
+			-3:00	Uruguay	UY%sT
+
+# Venezuela
+#
+# From John Stainforth (2007-11-28):
+# ... the change for Venezuela originally expected for 2007-12-31 has
+# been brought forward to 2007-12-09.  The official announcement was
+# published today in the "Gaceta Oficial de la Republica Bolivariana
+# de Venezuela, numero 38.819" (official document for all laws or
+# resolution publication)
+# http://www.globovision.com/news.php?nid=72208
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Caracas	-4:27:44 -	LMT	1890
+			-4:27:40 -	CMT	1912 Feb 12 # Caracas Mean Time?
+			-4:30	-	VET	1965	     # Venezuela Time
+			-4:00	-	VET	2007 Dec  9 03:00
+			-4:30	-	VET
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/systemv b/jdk/test/sun/util/calendar/zi/tzdata/systemv
new file mode 100644
index 0000000..0b0a266
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/systemv
@@ -0,0 +1,61 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+
+# Old rules, should the need arise.
+# No attempt is made to handle Newfoundland, since it cannot be expressed
+# using the System V "TZ" scheme (half-hour offset), or anything outside
+# North America (no support for non-standard DST start/end dates), nor
+# the changes in the DST rules in the US after 1976 (which occurred after
+# the old rules were written).
+#
+# If you need the old rules, uncomment ## lines.
+# Compile this *without* leap second correction for true conformance.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
+Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
+Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
+Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+## Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
+## Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
+## Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
+## Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
+## Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
+## Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
+## Zone	SystemV/AST4	-4:00	-		AST
+## Zone	SystemV/EST5	-5:00	-		EST
+## Zone	SystemV/CST6	-6:00	-		CST
+## Zone	SystemV/MST7	-7:00	-		MST
+## Zone	SystemV/PST8	-8:00	-		PST
+## Zone	SystemV/YST9	-9:00	-		YST
+## Zone	SystemV/HST10	-10:00	-		HST
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
new file mode 100644
index 0000000..ef380cd
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
@@ -0,0 +1,464 @@
+#
+# 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.
+#
+# <pre>
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+#
+# TZ zone descriptions
+#
+# From Paul Eggert (1996-08-05):
+#
+# This file contains a table with the following columns:
+# 1.  ISO 3166 2-character country code.  See the file `iso3166.tab'.
+# 2.  Latitude and longitude of the zone's principal location
+#     in ISO 6709 sign-degrees-minutes-seconds format,
+#     either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
+#     first latitude (+ is north), then longitude (+ is east).
+# 3.  Zone name used in value of TZ environment variable.
+# 4.  Comments; present if and only if the country has multiple rows.
+#
+# Columns are separated by a single tab.
+# The table is sorted first by country, then an order within the country that
+# (1) makes some geographical sense, and
+# (2) puts the most populous zones first, where that does not contradict (1).
+#
+# Lines beginning with `#' are comments.
+#
+#country-
+#code	coordinates	TZ			comments
+AD	+4230+00131	Europe/Andorra
+AE	+2518+05518	Asia/Dubai
+AF	+3431+06912	Asia/Kabul
+AG	+1703-06148	America/Antigua
+AI	+1812-06304	America/Anguilla
+AL	+4120+01950	Europe/Tirane
+AM	+4011+04430	Asia/Yerevan
+AO	-0848+01314	Africa/Luanda
+AQ	-7750+16636	Antarctica/McMurdo	McMurdo Station, Ross Island
+AQ	-9000+00000	Antarctica/South_Pole	Amundsen-Scott Station, South Pole
+AQ	-6734-06808	Antarctica/Rothera	Rothera Station, Adelaide Island
+AQ	-6448-06406	Antarctica/Palmer	Palmer Station, Anvers Island
+AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
+AQ	-6835+07758	Antarctica/Davis	Davis Station, Vestfold Hills
+AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
+AQ	-7824+10654	Antarctica/Vostok	Vostok Station, Lake Vostok
+AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
+AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
+AQ	-5430+15857	Antarctica/Macquarie	Macquarie Island Station, Macquarie Island
+AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
+AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, MN, SE, SF)
+AR	-2447-06525	America/Argentina/Salta	(SA, LP, NQ, RN)
+AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
+AR	-2649-06513	America/Argentina/Tucuman	Tucuman (TM)
+AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT), Chubut (CH)
+AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
+AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
+AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
+AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
+AR	-5138-06913	America/Argentina/Rio_Gallegos	Santa Cruz (SC)
+AR	-5448-06818	America/Argentina/Ushuaia	Tierra del Fuego (TF)
+AS	-1416-17042	Pacific/Pago_Pago
+AT	+4813+01620	Europe/Vienna
+AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
+AU	-4253+14719	Australia/Hobart	Tasmania - most locations
+AU	-3956+14352	Australia/Currie	Tasmania - King Island
+AU	-3749+14458	Australia/Melbourne	Victoria
+AU	-3352+15113	Australia/Sydney	New South Wales - most locations
+AU	-3157+14127	Australia/Broken_Hill	New South Wales - Yancowinna
+AU	-2728+15302	Australia/Brisbane	Queensland - most locations
+AU	-2016+14900	Australia/Lindeman	Queensland - Holiday Islands
+AU	-3455+13835	Australia/Adelaide	South Australia
+AU	-1228+13050	Australia/Darwin	Northern Territory
+AU	-3157+11551	Australia/Perth	Western Australia - most locations
+AU	-3143+12852	Australia/Eucla	Western Australia - Eucla area
+AW	+1230-06958	America/Aruba
+AX	+6006+01957	Europe/Mariehamn
+AZ	+4023+04951	Asia/Baku
+BA	+4352+01825	Europe/Sarajevo
+BB	+1306-05937	America/Barbados
+BD	+2343+09025	Asia/Dhaka
+BE	+5050+00420	Europe/Brussels
+BF	+1222-00131	Africa/Ouagadougou
+BG	+4241+02319	Europe/Sofia
+BH	+2623+05035	Asia/Bahrain
+BI	-0323+02922	Africa/Bujumbura
+BJ	+0629+00237	Africa/Porto-Novo
+BL	+1753-06251	America/St_Barthelemy
+BM	+3217-06446	Atlantic/Bermuda
+BN	+0456+11455	Asia/Brunei
+BO	-1630-06809	America/La_Paz
+BQ	+120903-0681636	America/Kralendijk
+BR	-0351-03225	America/Noronha	Atlantic islands
+BR	-0127-04829	America/Belem	Amapa, E Para
+BR	-0343-03830	America/Fortaleza	NE Brazil (MA, PI, CE, RN, PB)
+BR	-0803-03454	America/Recife	Pernambuco
+BR	-0712-04812	America/Araguaina	Tocantins
+BR	-0940-03543	America/Maceio	Alagoas, Sergipe
+BR	-1259-03831	America/Bahia	Bahia
+BR	-2332-04637	America/Sao_Paulo	S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS)
+BR	-2027-05437	America/Campo_Grande	Mato Grosso do Sul
+BR	-1535-05605	America/Cuiaba	Mato Grosso
+BR	-0226-05452	America/Santarem	W Para
+BR	-0846-06354	America/Porto_Velho	Rondonia
+BR	+0249-06040	America/Boa_Vista	Roraima
+BR	-0308-06001	America/Manaus	E Amazonas
+BR	-0640-06952	America/Eirunepe	W Amazonas
+BR	-0958-06748	America/Rio_Branco	Acre
+BS	+2505-07721	America/Nassau
+BT	+2728+08939	Asia/Thimphu
+BW	-2439+02555	Africa/Gaborone
+BY	+5354+02734	Europe/Minsk
+BZ	+1730-08812	America/Belize
+CA	+4734-05243	America/St_Johns	Newfoundland Time, including SE Labrador
+CA	+4439-06336	America/Halifax	Atlantic Time - Nova Scotia (most places), PEI
+CA	+4612-05957	America/Glace_Bay	Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
+CA	+4606-06447	America/Moncton	Atlantic Time - New Brunswick
+CA	+5320-06025	America/Goose_Bay	Atlantic Time - Labrador - most locations
+CA	+5125-05707	America/Blanc-Sablon	Atlantic Standard Time - Quebec - Lower North Shore
+CA	+4531-07334	America/Montreal	Eastern Time - Quebec - most locations
+CA	+4339-07923	America/Toronto	Eastern Time - Ontario - most locations
+CA	+4901-08816	America/Nipigon	Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973
+CA	+4823-08915	America/Thunder_Bay	Eastern Time - Thunder Bay, Ontario
+CA	+6344-06828	America/Iqaluit	Eastern Time - east Nunavut - most locations
+CA	+6608-06544	America/Pangnirtung	Eastern Time - Pangnirtung, Nunavut
+CA	+744144-0944945	America/Resolute	Central Standard Time - Resolute, Nunavut
+CA	+484531-0913718	America/Atikokan	Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
+CA	+624900-0920459	America/Rankin_Inlet	Central Time - central Nunavut
+CA	+4953-09709	America/Winnipeg	Central Time - Manitoba & west Ontario
+CA	+4843-09434	America/Rainy_River	Central Time - Rainy River & Fort Frances, Ontario
+CA	+5024-10439	America/Regina	Central Standard Time - Saskatchewan - most locations
+CA	+5017-10750	America/Swift_Current	Central Standard Time - Saskatchewan - midwest
+CA	+5333-11328	America/Edmonton	Mountain Time - Alberta, east British Columbia & west Saskatchewan
+CA	+690650-1050310	America/Cambridge_Bay	Mountain Time - west Nunavut
+CA	+6227-11421	America/Yellowknife	Mountain Time - central Northwest Territories
+CA	+682059-1334300	America/Inuvik	Mountain Time - west Northwest Territories
+CA	+4906-11631	America/Creston	Mountain Standard Time - Creston, British Columbia
+CA	+5946-12014	America/Dawson_Creek	Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
+CA	+4916-12307	America/Vancouver	Pacific Time - west British Columbia
+CA	+6043-13503	America/Whitehorse	Pacific Time - south Yukon
+CA	+6404-13925	America/Dawson	Pacific Time - north Yukon
+CC	-1210+09655	Indian/Cocos
+CD	-0418+01518	Africa/Kinshasa	west Dem. Rep. of Congo
+CD	-1140+02728	Africa/Lubumbashi	east Dem. Rep. of Congo
+CF	+0422+01835	Africa/Bangui
+CG	-0416+01517	Africa/Brazzaville
+CH	+4723+00832	Europe/Zurich
+CI	+0519-00402	Africa/Abidjan
+CK	-2114-15946	Pacific/Rarotonga
+CL	-3327-07040	America/Santiago	most locations
+CL	-2709-10926	Pacific/Easter	Easter Island & Sala y Gomez
+CM	+0403+00942	Africa/Douala
+CN	+3114+12128	Asia/Shanghai	east China - Beijing, Guangdong, Shanghai, etc.
+CN	+4545+12641	Asia/Harbin	Heilongjiang (except Mohe), Jilin
+CN	+2934+10635	Asia/Chongqing	central China - Sichuan, Yunnan, Guangxi, Shaanxi, Guizhou, etc.
+CN	+4348+08735	Asia/Urumqi	most of Tibet & Xinjiang
+CN	+3929+07559	Asia/Kashgar	west Tibet & Xinjiang
+CO	+0436-07405	America/Bogota
+CR	+0956-08405	America/Costa_Rica
+CU	+2308-08222	America/Havana
+CV	+1455-02331	Atlantic/Cape_Verde
+CW	+1211-06900	America/Curacao
+CX	-1025+10543	Indian/Christmas
+CY	+3510+03322	Asia/Nicosia
+CZ	+5005+01426	Europe/Prague
+DE	+5230+01322	Europe/Berlin
+DJ	+1136+04309	Africa/Djibouti
+DK	+5540+01235	Europe/Copenhagen
+DM	+1518-06124	America/Dominica
+DO	+1828-06954	America/Santo_Domingo
+DZ	+3647+00303	Africa/Algiers
+EC	-0210-07950	America/Guayaquil	mainland
+EC	-0054-08936	Pacific/Galapagos	Galapagos Islands
+EE	+5925+02445	Europe/Tallinn
+EG	+3003+03115	Africa/Cairo
+EH	+2709-01312	Africa/El_Aaiun
+ER	+1520+03853	Africa/Asmara
+ES	+4024-00341	Europe/Madrid	mainland
+ES	+3553-00519	Africa/Ceuta	Ceuta & Melilla
+ES	+2806-01524	Atlantic/Canary	Canary Islands
+ET	+0902+03842	Africa/Addis_Ababa
+FI	+6010+02458	Europe/Helsinki
+FJ	-1808+17825	Pacific/Fiji
+FK	-5142-05751	Atlantic/Stanley
+FM	+0725+15147	Pacific/Chuuk	Chuuk (Truk) and Yap
+FM	+0658+15813	Pacific/Pohnpei	Pohnpei (Ponape)
+FM	+0519+16259	Pacific/Kosrae	Kosrae
+FO	+6201-00646	Atlantic/Faroe
+FR	+4852+00220	Europe/Paris
+GA	+0023+00927	Africa/Libreville
+GB	+513030-0000731	Europe/London
+GD	+1203-06145	America/Grenada
+GE	+4143+04449	Asia/Tbilisi
+GF	+0456-05220	America/Cayenne
+GG	+4927-00232	Europe/Guernsey
+GH	+0533-00013	Africa/Accra
+GI	+3608-00521	Europe/Gibraltar
+GL	+6411-05144	America/Godthab	most locations
+GL	+7646-01840	America/Danmarkshavn	east coast, north of Scoresbysund
+GL	+7029-02158	America/Scoresbysund	Scoresbysund / Ittoqqortoormiit
+GL	+7634-06847	America/Thule	Thule / Pituffik
+GM	+1328-01639	Africa/Banjul
+GN	+0931-01343	Africa/Conakry
+GP	+1614-06132	America/Guadeloupe
+GQ	+0345+00847	Africa/Malabo
+GR	+3758+02343	Europe/Athens
+GS	-5416-03632	Atlantic/South_Georgia
+GT	+1438-09031	America/Guatemala
+GU	+1328+14445	Pacific/Guam
+GW	+1151-01535	Africa/Bissau
+GY	+0648-05810	America/Guyana
+HK	+2217+11409	Asia/Hong_Kong
+HN	+1406-08713	America/Tegucigalpa
+HR	+4548+01558	Europe/Zagreb
+HT	+1832-07220	America/Port-au-Prince
+HU	+4730+01905	Europe/Budapest
+ID	-0610+10648	Asia/Jakarta	Java & Sumatra
+ID	-0002+10920	Asia/Pontianak	west & central Borneo
+ID	-0507+11924	Asia/Makassar	east & south Borneo, Sulawesi (Celebes), Bali, Nusa Tengarra, west Timor
+ID	-0232+14042	Asia/Jayapura	west New Guinea (Irian Jaya) & Malukus (Moluccas)
+IE	+5320-00615	Europe/Dublin
+IL	+3146+03514	Asia/Jerusalem
+IM	+5409-00428	Europe/Isle_of_Man
+IN	+2232+08822	Asia/Kolkata
+IO	-0720+07225	Indian/Chagos
+IQ	+3321+04425	Asia/Baghdad
+IR	+3540+05126	Asia/Tehran
+IS	+6409-02151	Atlantic/Reykjavik
+IT	+4154+01229	Europe/Rome
+JE	+4912-00207	Europe/Jersey
+JM	+1800-07648	America/Jamaica
+JO	+3157+03556	Asia/Amman
+JP	+353916+1394441	Asia/Tokyo
+KE	-0117+03649	Africa/Nairobi
+KG	+4254+07436	Asia/Bishkek
+KH	+1133+10455	Asia/Phnom_Penh
+KI	+0125+17300	Pacific/Tarawa	Gilbert Islands
+KI	-0308-17105	Pacific/Enderbury	Phoenix Islands
+KI	+0152-15720	Pacific/Kiritimati	Line Islands
+KM	-1141+04316	Indian/Comoro
+KN	+1718-06243	America/St_Kitts
+KP	+3901+12545	Asia/Pyongyang
+KR	+3733+12658	Asia/Seoul
+KW	+2920+04759	Asia/Kuwait
+KY	+1918-08123	America/Cayman
+KZ	+4315+07657	Asia/Almaty	most locations
+KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda (Kyzylorda, Kzyl-Orda)
+KZ	+5017+05710	Asia/Aqtobe	Aqtobe (Aktobe)
+KZ	+4431+05016	Asia/Aqtau	Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau)
+KZ	+5113+05121	Asia/Oral	West Kazakhstan
+LA	+1758+10236	Asia/Vientiane
+LB	+3353+03530	Asia/Beirut
+LC	+1401-06100	America/St_Lucia
+LI	+4709+00931	Europe/Vaduz
+LK	+0656+07951	Asia/Colombo
+LR	+0618-01047	Africa/Monrovia
+LS	-2928+02730	Africa/Maseru
+LT	+5441+02519	Europe/Vilnius
+LU	+4936+00609	Europe/Luxembourg
+LV	+5657+02406	Europe/Riga
+LY	+3254+01311	Africa/Tripoli
+MA	+3339-00735	Africa/Casablanca
+MC	+4342+00723	Europe/Monaco
+MD	+4700+02850	Europe/Chisinau
+ME	+4226+01916	Europe/Podgorica
+MF	+1804-06305	America/Marigot
+MG	-1855+04731	Indian/Antananarivo
+MH	+0709+17112	Pacific/Majuro	most locations
+MH	+0905+16720	Pacific/Kwajalein	Kwajalein
+MK	+4159+02126	Europe/Skopje
+ML	+1239-00800	Africa/Bamako
+MM	+1647+09610	Asia/Rangoon
+MN	+4755+10653	Asia/Ulaanbaatar	most locations
+MN	+4801+09139	Asia/Hovd	Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
+MN	+4804+11430	Asia/Choibalsan	Dornod, Sukhbaatar
+MO	+2214+11335	Asia/Macau
+MP	+1512+14545	Pacific/Saipan
+MQ	+1436-06105	America/Martinique
+MR	+1806-01557	Africa/Nouakchott
+MS	+1643-06213	America/Montserrat
+MT	+3554+01431	Europe/Malta
+MU	-2010+05730	Indian/Mauritius
+MV	+0410+07330	Indian/Maldives
+MW	-1547+03500	Africa/Blantyre
+MX	+1924-09909	America/Mexico_City	Central Time - most locations
+MX	+2105-08646	America/Cancun	Central Time - Quintana Roo
+MX	+2058-08937	America/Merida	Central Time - Campeche, Yucatan
+MX	+2540-10019	America/Monterrey	Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border
+MX	+2550-09730	America/Matamoros	US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border
+MX	+2313-10625	America/Mazatlan	Mountain Time - S Baja, Nayarit, Sinaloa
+MX	+2838-10605	America/Chihuahua	Mexican Mountain Time - Chihuahua away from US border
+MX	+2934-10425	America/Ojinaga	US Mountain Time - Chihuahua near US border
+MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
+MX	+3232-11701	America/Tijuana	US Pacific Time - Baja California near US border
+MX	+3018-11452	America/Santa_Isabel	Mexican Pacific Time - Baja California away from US border
+MX	+2048-10515	America/Bahia_Banderas	Mexican Central Time - Bahia de Banderas
+MY	+0310+10142	Asia/Kuala_Lumpur	peninsular Malaysia
+MY	+0133+11020	Asia/Kuching	Sabah & Sarawak
+MZ	-2558+03235	Africa/Maputo
+NA	-2234+01706	Africa/Windhoek
+NC	-2216+16627	Pacific/Noumea
+NE	+1331+00207	Africa/Niamey
+NF	-2903+16758	Pacific/Norfolk
+NG	+0627+00324	Africa/Lagos
+NI	+1209-08617	America/Managua
+NL	+5222+00454	Europe/Amsterdam
+NO	+5955+01045	Europe/Oslo
+NP	+2743+08519	Asia/Kathmandu
+NR	-0031+16655	Pacific/Nauru
+NU	-1901-16955	Pacific/Niue
+NZ	-3652+17446	Pacific/Auckland	most locations
+NZ	-4357-17633	Pacific/Chatham	Chatham Islands
+OM	+2336+05835	Asia/Muscat
+PA	+0858-07932	America/Panama
+PE	-1203-07703	America/Lima
+PF	-1732-14934	Pacific/Tahiti	Society Islands
+PF	-0900-13930	Pacific/Marquesas	Marquesas Islands
+PF	-2308-13457	Pacific/Gambier	Gambier Islands
+PG	-0930+14710	Pacific/Port_Moresby
+PH	+1435+12100	Asia/Manila
+PK	+2452+06703	Asia/Karachi
+PL	+5215+02100	Europe/Warsaw
+PM	+4703-05620	America/Miquelon
+PN	-2504-13005	Pacific/Pitcairn
+PR	+182806-0660622	America/Puerto_Rico
+PS	+3130+03428	Asia/Gaza	Gaza Strip
+PS	+313200+0350542	Asia/Hebron	West Bank
+PT	+3843-00908	Europe/Lisbon	mainland
+PT	+3238-01654	Atlantic/Madeira	Madeira Islands
+PT	+3744-02540	Atlantic/Azores	Azores
+PW	+0720+13429	Pacific/Palau
+PY	-2516-05740	America/Asuncion
+QA	+2517+05132	Asia/Qatar
+RE	-2052+05528	Indian/Reunion
+RO	+4426+02606	Europe/Bucharest
+RS	+4450+02030	Europe/Belgrade
+RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
+RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
+RU	+4844+04425	Europe/Volgograd	Moscow+00 - Caspian Sea
+RU	+5312+05009	Europe/Samara	Moscow+00 - Samara, Udmurtia
+RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
+RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
+RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
+RU	+5345+08707	Asia/Novokuznetsk	Moscow+03 - Novokuznetsk
+RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
+RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
+RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
+RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
+RU	+4658+14242	Asia/Sakhalin	Moscow+07 - Sakhalin Island
+RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan
+RU	+5301+15839	Asia/Kamchatka	Moscow+08 - Kamchatka
+RU	+6445+17729	Asia/Anadyr	Moscow+08 - Bering Sea
+RW	-0157+03004	Africa/Kigali
+SA	+2438+04643	Asia/Riyadh
+SB	-0932+16012	Pacific/Guadalcanal
+SC	-0440+05528	Indian/Mahe
+SD	+1536+03232	Africa/Khartoum
+SE	+5920+01803	Europe/Stockholm
+SG	+0117+10351	Asia/Singapore
+SH	-1555-00542	Atlantic/St_Helena
+SI	+4603+01431	Europe/Ljubljana
+SJ	+7800+01600	Arctic/Longyearbyen
+SK	+4809+01707	Europe/Bratislava
+SL	+0830-01315	Africa/Freetown
+SM	+4355+01228	Europe/San_Marino
+SN	+1440-01726	Africa/Dakar
+SO	+0204+04522	Africa/Mogadishu
+SR	+0550-05510	America/Paramaribo
+SS	+0451+03136	Africa/Juba
+ST	+0020+00644	Africa/Sao_Tome
+SV	+1342-08912	America/El_Salvador
+SX	+180305-0630250	America/Lower_Princes
+SY	+3330+03618	Asia/Damascus
+SZ	-2618+03106	Africa/Mbabane
+TC	+2128-07108	America/Grand_Turk
+TD	+1207+01503	Africa/Ndjamena
+TF	-492110+0701303	Indian/Kerguelen
+TG	+0608+00113	Africa/Lome
+TH	+1345+10031	Asia/Bangkok
+TJ	+3835+06848	Asia/Dushanbe
+TK	-0922-17114	Pacific/Fakaofo
+TL	-0833+12535	Asia/Dili
+TM	+3757+05823	Asia/Ashgabat
+TN	+3648+01011	Africa/Tunis
+TO	-2110-17510	Pacific/Tongatapu
+TR	+4101+02858	Europe/Istanbul
+TT	+1039-06131	America/Port_of_Spain
+TV	-0831+17913	Pacific/Funafuti
+TW	+2503+12130	Asia/Taipei
+TZ	-0648+03917	Africa/Dar_es_Salaam
+UA	+5026+03031	Europe/Kiev	most locations
+UA	+4837+02218	Europe/Uzhgorod	Ruthenia
+UA	+4750+03510	Europe/Zaporozhye	Zaporozh'ye, E Lugansk / Zaporizhia, E Luhansk
+UA	+4457+03406	Europe/Simferopol	central Crimea
+UG	+0019+03225	Africa/Kampala
+UM	+1645-16931	Pacific/Johnston	Johnston Atoll
+UM	+2813-17722	Pacific/Midway	Midway Islands
+UM	+1917+16637	Pacific/Wake	Wake Island
+US	+404251-0740023	America/New_York	Eastern Time
+US	+421953-0830245	America/Detroit	Eastern Time - Michigan - most locations
+US	+381515-0854534	America/Kentucky/Louisville	Eastern Time - Kentucky - Louisville area
+US	+364947-0845057	America/Kentucky/Monticello	Eastern Time - Kentucky - Wayne County
+US	+394606-0860929	America/Indiana/Indianapolis	Eastern Time - Indiana - most locations
+US	+384038-0873143	America/Indiana/Vincennes	Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
+US	+410305-0863611	America/Indiana/Winamac	Eastern Time - Indiana - Pulaski County
+US	+382232-0862041	America/Indiana/Marengo	Eastern Time - Indiana - Crawford County
+US	+382931-0871643	America/Indiana/Petersburg	Eastern Time - Indiana - Pike County
+US	+384452-0850402	America/Indiana/Vevay	Eastern Time - Indiana - Switzerland County
+US	+415100-0873900	America/Chicago	Central Time
+US	+375711-0864541	America/Indiana/Tell_City	Central Time - Indiana - Perry County
+US	+411745-0863730	America/Indiana/Knox	Central Time - Indiana - Starke County
+US	+450628-0873651	America/Menominee	Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
+US	+470659-1011757	America/North_Dakota/Center	Central Time - North Dakota - Oliver County
+US	+465042-1012439	America/North_Dakota/New_Salem	Central Time - North Dakota - Morton County (except Mandan area)
+US	+471551-1014640	America/North_Dakota/Beulah	Central Time - North Dakota - Mercer County
+US	+394421-1045903	America/Denver	Mountain Time
+US	+433649-1161209	America/Boise	Mountain Time - south Idaho & east Oregon
+US	+364708-1084111	America/Shiprock	Mountain Time - Navajo
+US	+332654-1120424	America/Phoenix	Mountain Standard Time - Arizona
+US	+340308-1181434	America/Los_Angeles	Pacific Time
+US	+611305-1495401	America/Anchorage	Alaska Time
+US	+581807-1342511	America/Juneau	Alaska Time - Alaska panhandle
+US	+571035-1351807	America/Sitka	Alaska Time - southeast Alaska panhandle
+US	+593249-1394338	America/Yakutat	Alaska Time - Alaska panhandle neck
+US	+643004-1652423	America/Nome	Alaska Time - west Alaska
+US	+515248-1763929	America/Adak	Aleutian Islands
+US	+550737-1313435	America/Metlakatla	Metlakatla Time - Annette Island
+US	+211825-1575130	Pacific/Honolulu	Hawaii
+UY	-3453-05611	America/Montevideo
+UZ	+3940+06648	Asia/Samarkand	west Uzbekistan
+UZ	+4120+06918	Asia/Tashkent	east Uzbekistan
+VA	+415408+0122711	Europe/Vatican
+VC	+1309-06114	America/St_Vincent
+VE	+1030-06656	America/Caracas
+VG	+1827-06437	America/Tortola
+VI	+1821-06456	America/St_Thomas
+VN	+1045+10640	Asia/Ho_Chi_Minh
+VU	-1740+16825	Pacific/Efate
+WF	-1318-17610	Pacific/Wallis
+WS	-1350-17144	Pacific/Apia
+YE	+1245+04512	Asia/Aden
+YT	-1247+04514	Indian/Mayotte
+ZA	-2615+02800	Africa/Johannesburg
+ZM	-1525+02817	Africa/Lusaka
+ZW	-1750+03103	Africa/Harare
diff --git a/jdk/test/sun/util/calendar/zi/tzdata_jdk/gmt b/jdk/test/sun/util/calendar/zi/tzdata_jdk/gmt
new file mode 100644
index 0000000..0be3179
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata_jdk/gmt
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2000, 2005, 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.
+#
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	GMT		0:00	-	GMT
diff --git a/jdk/test/sun/util/calendar/zi/tzdata_jdk/jdk11_backward b/jdk/test/sun/util/calendar/zi/tzdata_jdk/jdk11_backward
new file mode 100644
index 0000000..4869516
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata_jdk/jdk11_backward
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2000, 2006, 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.
+#
+# JDK 1.1.x compatible time zone IDs
+#
+
+Link Australia/Darwin ACT
+Link Australia/Sydney AET
+Link America/Argentina/Buenos_Aires AGT
+Link Africa/Cairo ART
+Link America/Anchorage AST
+Link America/Sao_Paulo BET
+Link Asia/Dhaka BST
+Link Africa/Harare CAT
+Link America/St_Johns CNT
+Link America/Chicago CST
+Link Asia/Shanghai CTT
+Link Africa/Addis_Ababa EAT
+Link Europe/Paris ECT
+Link America/New_York EST
+Link Pacific/Honolulu HST
+Link America/Indianapolis IET
+Link Asia/Calcutta IST
+Link Asia/Tokyo JST
+Link Pacific/Apia MIT
+Link America/Denver MST
+Link Asia/Yerevan NET
+Link Pacific/Auckland NST
+Link Asia/Karachi PLT
+Link America/Phoenix PNT
+Link America/Puerto_Rico PRT
+Link America/Los_Angeles PST
+Link Pacific/Guadalcanal SST
+Link Asia/Saigon VST
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
+Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
+Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
+Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
+Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
+Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
+Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
+Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
+Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
+Zone	SystemV/AST4	-4:00	-		AST
+Zone	SystemV/EST5	-5:00	-		EST
+Zone	SystemV/CST6	-6:00	-		CST
+Zone	SystemV/MST7	-7:00	-		MST
+Zone	SystemV/PST8	-8:00	-		PST
+Zone	SystemV/YST9	-9:00	-		YST
+Zone	SystemV/HST10	-10:00	-		HST
diff --git a/jdk/test/sun/util/calendar/zi/tzdata_jdk/jdk11_full_backward b/jdk/test/sun/util/calendar/zi/tzdata_jdk/jdk11_full_backward
new file mode 100644
index 0000000..321180a
--- /dev/null
+++ b/jdk/test/sun/util/calendar/zi/tzdata_jdk/jdk11_full_backward
@@ -0,0 +1,93 @@
+#
+# Copyright (c) 2001, 2006, 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.
+#
+# JDK 1.1.x compatible time zone IDs
+#
+
+Link Australia/Darwin ACT
+Link Australia/Sydney AET
+Link America/Argentina/Buenos_Aires AGT
+Link Africa/Cairo ART
+Link America/Anchorage AST
+Link America/Sao_Paulo BET
+Link Asia/Dhaka BST
+Link Africa/Harare CAT
+Link America/St_Johns CNT
+Link America/Chicago CST
+Link Asia/Shanghai CTT
+Link Africa/Addis_Ababa EAT
+Link Europe/Paris ECT
+Link America/New_York EST
+Link Pacific/Honolulu HST
+Link America/Indiana/Indianapolis IET
+Link Asia/Calcutta IST
+Link Asia/Tokyo JST
+Link Pacific/Apia MIT
+Link America/Denver MST
+Link Asia/Yerevan NET
+Link Pacific/Auckland NST
+Link Asia/Karachi PLT
+Link America/Phoenix PNT
+Link America/Puerto_Rico PRT
+Link America/Los_Angeles PST
+Link Pacific/Guadalcanal SST
+Link Asia/Saigon VST
+
+# The follwong link is required to generate JDK 1.2.x and 1.3.x
+# compatible zones. In the Olson public source, MET is defined as
+# GMT+1:00 with the C-Eur rules. In JDK, MET is defined as an alias
+# of Asia/Tehran. This line must be removed if a full set of Olson
+# zones is generated. Otherwise, MET appears twice in the
+# ZoneInfoMappings.IDs table.
+Link Asia/Tehran MET
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
+Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
+Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
+Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
+Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
+Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
+Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
+Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
+Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
+Zone	SystemV/AST4	-4:00	-		AST
+Zone	SystemV/EST5	-5:00	-		EST
+Zone	SystemV/CST6	-6:00	-		CST
+Zone	SystemV/MST7	-7:00	-		MST
+Zone	SystemV/PST8	-8:00	-		PST
+Zone	SystemV/YST9	-9:00	-		YST
+Zone	SystemV/HST10	-10:00	-		HST
+
+#
+# For the UTC change in Mustang
+#
+Link GMT UTC
diff --git a/jdk/test/tools/jar/AddAndUpdateProfile.java b/jdk/test/tools/jar/AddAndUpdateProfile.java
new file mode 100644
index 0000000..e8eabd4
--- /dev/null
+++ b/jdk/test/tools/jar/AddAndUpdateProfile.java
@@ -0,0 +1,129 @@
+/*
+ * 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 8003255
+ * @compile -XDignore.symbol.file AddAndUpdateProfile.java
+ * @run main AddAndUpdateProfile
+ * @summary Basic test of jar tool "p" option to add or update the Profile
+ *    attribute in the main manifest of a JAR file
+ */
+
+import java.util.jar.*;
+import static java.util.jar.Attributes.Name.*;
+import java.nio.file.*;
+import java.io.IOException;
+
+import sun.tools.jar.Main;
+
+public class AddAndUpdateProfile {
+    static boolean doJar(String... args) {
+        System.out.print("jar");
+        for (String arg: args)
+            System.out.print(" " + arg);
+        System.out.println("");
+
+        Main jartool = new Main(System.out, System.err, "jar");
+        return jartool.run(args);
+    }
+
+    static void jar(String... args) {
+        if (!doJar(args))
+            throw new RuntimeException("jar command failed");
+    }
+
+    static void jarExpectingFail(String... args) {
+        if (doJar(args))
+            throw new RuntimeException("jar command not expected to succeed");
+    }
+
+    static void checkMainAttribute(String jarfile, Attributes.Name name,
+                                   String expectedValue)
+        throws IOException
+    {
+        try (JarFile jf = new JarFile(jarfile)) {
+            Manifest mf = jf.getManifest();
+            if (mf == null && expectedValue != null)
+                throw new RuntimeException("Manifest not found");
+            if (mf != null) {
+                String actual = mf.getMainAttributes().getValue(name);
+                if (actual != null) {
+                    if (!actual.equals(expectedValue))
+                        throw new RuntimeException("Profile attribute has unexpected value");
+                } else {
+                    if (expectedValue != null)
+                        throw new RuntimeException("Profile attribute should not be present");
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Path entry = Files.createFile(Paths.get("xfoo"));
+        String jarfile = "xFoo.jar";
+        try {
+
+            // create JAR file with Profile attribute
+            jar("cfp", jarfile, "compact1", entry.toString());
+            checkMainAttribute(jarfile, PROFILE, "compact1");
+
+            // attempt to create JAR file with Profile attribute and bad value
+            jarExpectingFail("cfp", jarfile, "garbage", entry.toString());
+            jarExpectingFail("cfp", jarfile, "Compact1", entry.toString());
+            jarExpectingFail("cfp", jarfile, "COMPACT1", entry.toString());
+
+            // update value of Profile attribute
+            jar("ufp", jarfile, "compact2");
+            checkMainAttribute(jarfile, PROFILE, "compact2");
+
+            // attempt to update value of Profile attribute to bad value
+            // (update should not change the JAR file)
+            jarExpectingFail("ufp", jarfile, "garbage");
+            checkMainAttribute(jarfile, PROFILE, "compact2");
+            jarExpectingFail("ufp", jarfile, "COMPACT1");
+            checkMainAttribute(jarfile, PROFILE, "compact2");
+
+            // create JAR file with both a Main-Class and Profile attribute
+            jar("cfep", jarfile, "Foo", "compact1", entry.toString());
+            checkMainAttribute(jarfile, MAIN_CLASS, "Foo");
+            checkMainAttribute(jarfile, PROFILE, "compact1");
+
+            // update value of Profile attribute
+            jar("ufp", jarfile, "compact2");
+            checkMainAttribute(jarfile, PROFILE, "compact2");
+
+            // create JAR file without Profile attribute
+            jar("cf", jarfile, entry.toString());
+            checkMainAttribute(jarfile, PROFILE, null);
+
+            // update value of Profile attribute
+            jar("ufp", jarfile, "compact3");
+            checkMainAttribute(jarfile, PROFILE, "compact3");
+
+        } finally {
+            Files.deleteIfExists(Paths.get(jarfile));
+            Files.delete(entry);
+        }
+    }
+
+}
diff --git a/jdk/test/tools/launcher/profiles/Basic.java b/jdk/test/tools/launcher/profiles/Basic.java
new file mode 100644
index 0000000..a794c3f
--- /dev/null
+++ b/jdk/test/tools/launcher/profiles/Basic.java
@@ -0,0 +1,231 @@
+/*
+ * 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 8003255
+ * @compile -XDignore.symbol.file Basic.java Main.java Logging.java
+ * @run main Basic
+ * @summary Test the launcher checks the Profile attribute of executable JAR
+ *     files. Also checks that libraries that specify the Profile attribute
+ *     are not loaded if the runtime does not support the required profile.
+ */
+
+import java.io.*;
+import java.util.jar.*;
+import static java.util.jar.JarFile.MANIFEST_NAME;
+import java.util.zip.*;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+
+public class Basic {
+
+    static final String MANIFEST_DIR = "META-INF/";
+
+    static final String JAVA_HOME = System.getProperty("java.home");
+    static final String OS_NAME = System.getProperty("os.name");
+    static final String OS_ARCH = System.getProperty("os.arch");
+
+    static final String JAVA_CMD =
+            OS_NAME.startsWith("Windows") ? "java.exe" : "java";
+
+    static final boolean NEED_D64 =
+            OS_NAME.equals("SunOS") &&
+            (OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64"));
+
+    /**
+     * Creates a JAR file with the given attributes and the given entries.
+     * Class files are assumed to be in ${test.classes}. Note that this this
+     * method cannot use the "jar" tool as it may not be present in the image.
+     */
+    static void createJarFile(String jarfile,
+                              String mainAttributes,
+                              String... entries)
+        throws IOException
+    {
+        // create Manifest
+        Manifest manifest = new Manifest();
+        Attributes jarAttrs = manifest.getMainAttributes();
+        jarAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+        if (mainAttributes.length() > 0) {
+            for (String attr: mainAttributes.split(",")) {
+                String[] s = attr.split("=");
+                jarAttrs.put(new Attributes.Name(s[0]), s[1]);
+            }
+        }
+
+        try (OutputStream out = Files.newOutputStream(Paths.get(jarfile));
+             ZipOutputStream zos = new JarOutputStream(out))
+        {
+            // add manifest directory and manifest file
+            ZipEntry e = new JarEntry(MANIFEST_DIR);
+            e.setTime(System.currentTimeMillis());
+            e.setSize(0);
+            e.setCrc(0);
+            zos.putNextEntry(e);
+            e = new ZipEntry(MANIFEST_NAME);
+            e.setTime(System.currentTimeMillis());
+            zos.putNextEntry(e);
+            manifest.write(zos);
+            zos.closeEntry();
+
+            // entries in JAR file
+            for (String entry: entries) {
+                e = new JarEntry(entry);
+                Path path;
+                if (entry.endsWith(".class")) {
+                    path = Paths.get(System.getProperty("test.classes"), entry);
+                } else {
+                    path = Paths.get(entry);
+                }
+                BasicFileAttributes attrs =
+                    Files.readAttributes(path, BasicFileAttributes.class);
+                e.setTime(attrs.lastModifiedTime().toMillis());
+                if (attrs.size() == 0) {
+                    e.setMethod(ZipEntry.STORED);
+                    e.setSize(0);
+                    e.setCrc(0);
+                }
+                zos.putNextEntry(e);
+                if (attrs.isRegularFile())
+                    Files.copy(path, zos);
+                zos.closeEntry();
+            }
+        }
+    }
+
+    /**
+     * Execute the given executable JAR file with the given arguments. This
+     * method blocks until the launched VM terminates. Any output or error
+     * message from the launched VM are printed to System.out. Returns the
+     * exit value.
+     */
+    static int exec(String jf, String... args) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString());
+        if (NEED_D64)
+            sb.append(" -d64");
+        sb.append(" -jar ");
+        sb.append(Paths.get(jf).toAbsolutePath());
+        for (String arg: args) {
+            sb.append(' ');
+            sb.append(arg);
+        }
+        String[] cmd = sb.toString().split(" ");
+        ProcessBuilder pb = new ProcessBuilder(cmd);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        BufferedReader reader =
+            new BufferedReader(new InputStreamReader(p.getInputStream()));
+        String line;
+        while ((line = reader.readLine()) != null) {
+            System.out.println(line);
+        }
+        try {
+            return p.waitFor();
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Should not happen");
+        }
+    }
+
+    static void checkRun(String jf, String... args) throws IOException {
+        if (exec(jf) != 0)
+            throw new RuntimeException(jf + " failed!!!");
+    }
+
+    static void checkRunFail(String jf, String... args) throws IOException {
+        if (exec(jf) == 0)
+            throw new RuntimeException(jf + " did not fail!!!");
+        System.out.println("Failed as expected");
+    }
+
+    public static void main(String[] args) throws IOException {
+        // ## replace this if there is a standard way to determine the profile
+        String profile = sun.misc.Version.profileName();
+
+        int thisProfile = 4;
+        if ("compact1".equals(profile)) thisProfile = 1;
+        if ("compact2".equals(profile)) thisProfile = 2;
+        if ("compact3".equals(profile)) thisProfile = 3;
+
+        // "library" JAR file used by the test
+        createJarFile("Logging.jar", "", "Logging.class");
+
+        // Executable JAR file without the Profile attribute
+        if (thisProfile <= 3) {
+            createJarFile("Main.jar",
+                          "Main-Class=Main,Class-Path=Logging.jar",
+                          "Main.class");
+            checkRunFail("Main.jar");
+        }
+
+        // Executable JAR file with Profile attribute, Library JAR file without
+        for (int p=1; p<=3; p++) {
+            String attrs = "Main-Class=Main,Class-Path=Logging.jar" +
+                 ",Profile=compact" + p;
+            createJarFile("Main.jar", attrs,  "Main.class");
+            if (p <= thisProfile) {
+                checkRun("Main.jar");
+            } else {
+                checkRunFail("Main.jar");
+            }
+        }
+
+        // Executable JAR file with Profile attribute that has invalid profile
+        // name, including incorrect case.
+        createJarFile("Main.jar",
+                      "Main-Class=Main,Class-Path=Logging.jar,Profile=BadName",
+                      "Main.class");
+        checkRunFail("Main.jar");
+
+        createJarFile("Main.jar",
+                      "Main-Class=Main,Class-Path=Logging.jar,Profile=Compact1",
+                      "Main.class");
+        checkRunFail("Main.jar");
+
+        // Executable JAR file and Librrary JAR file with Profile attribute
+        createJarFile("Main.jar",
+                      "Main-Class=Main,Class-Path=Logging.jar,Profile=compact1",
+                      "Main.class");
+        for (int p=1; p<=3; p++) {
+            String attrs = "Profile=compact" + p;
+            createJarFile("Logging.jar", attrs, "Logging.class");
+            if (p <= thisProfile) {
+                checkRun("Main.jar");
+            } else {
+                checkRunFail("Main.jar");
+            }
+        }
+
+        // Executable JAR file and Library JAR with Profile attribute, value
+        // of Profile not recognized
+        createJarFile("Logging.jar", "Profile=BadName", "Logging.class");
+        createJarFile("Main.jar",
+                      "Main-Class=Main,Class-Path=Logging.jar,Profile=compact1",
+                      "Main.class");
+        checkRunFail("Main.jar");
+
+        System.out.println("TEST PASSED.");
+    }
+
+}
diff --git a/jdk/test/tools/launcher/profiles/Logging.java b/jdk/test/tools/launcher/profiles/Logging.java
new file mode 100644
index 0000000..56174a9
--- /dev/null
+++ b/jdk/test/tools/launcher/profiles/Logging.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+public class Logging {
+    private Logging() { }
+
+    public static void log(String msg) {
+        System.out.println(msg);
+    }
+}
diff --git a/jdk/test/tools/launcher/profiles/Main.java b/jdk/test/tools/launcher/profiles/Main.java
new file mode 100644
index 0000000..49c09a8
--- /dev/null
+++ b/jdk/test/tools/launcher/profiles/Main.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+public class Main {
+    private Main() { }
+
+    public static void main(String[] args) {
+        Logging.log("main running");
+    }
+}
diff --git a/jdk/test/tools/launcher/profiles/VersionCheck.java b/jdk/test/tools/launcher/profiles/VersionCheck.java
new file mode 100644
index 0000000..fc3a5f7
--- /dev/null
+++ b/jdk/test/tools/launcher/profiles/VersionCheck.java
@@ -0,0 +1,169 @@
+/*
+ * 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 8003256
+ * @compile -XDignore.symbol.file VersionCheck.java
+ * @run main VersionCheck
+ * @summary Tests that "java -version" includes the name of the profile and that
+ *     it matches the name in the release file
+ */
+
+import java.nio.file.*;
+import java.io.*;
+import java.util.Properties;
+
+public class VersionCheck {
+
+    static final String JAVA_HOME = System.getProperty("java.home");
+    static final String OS_NAME = System.getProperty("os.name");
+    static final String OS_ARCH = System.getProperty("os.arch");
+
+    static final String JAVA_CMD =
+            OS_NAME.startsWith("Windows") ? "java.exe" : "java";
+
+    static final boolean NEED_D64 =
+            OS_NAME.equals("SunOS") &&
+            (OS_ARCH.equals("sparcv9") || OS_ARCH.equals("amd64"));
+
+    /**
+     * Returns {@code true} if the given class is present.
+     */
+    static boolean isPresent(String cn) {
+        try {
+            Class.forName(cn);
+            return true;
+        } catch (ClassNotFoundException ignore) {
+            return false;
+        }
+    }
+
+    /**
+     * Determines the profile by checking whether specific classes are present.
+     * Returns the empty string if this runtime does not appear to be a profile
+     * of Java SE.
+     */
+    static String probeProfile() {
+        if (isPresent("java.awt.Window"))
+            return "";
+        if (isPresent("java.lang.management.ManagementFactory"))
+            return "compact3";
+        if (isPresent("java.sql.DriverManager"))
+            return "compact2";
+        return "compact1";
+    }
+
+    /**
+     * Execs java with the given parameters. The method blocks until the
+     * process terminates. Returns a {@code ByteArrayOutputStream} with any
+     * stdout or stderr from the process.
+     */
+    static ByteArrayOutputStream execJava(String... args)
+        throws IOException
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append(Paths.get(JAVA_HOME, "bin", JAVA_CMD).toString());
+        if (NEED_D64)
+            sb.append(" -d64");
+        for (String arg: args) {
+            sb.append(' ');
+            sb.append(arg);
+        }
+        String[] cmd = sb.toString().split(" ");
+        ProcessBuilder pb = new ProcessBuilder(cmd);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+        int n;
+        do {
+            n = p.getInputStream().read(buf);
+            if (n > 0)
+               baos.write(buf, 0, n);
+        } while (n > 0);
+        try {
+            int exitCode = p.waitFor();
+            if (exitCode != 0)
+                throw new RuntimeException("Exit code: " + exitCode);
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Should not happen");
+        }
+        return baos;
+    }
+
+    public static void main(String[] args) throws IOException {
+        String reported = sun.misc.Version.profileName();
+        String probed = probeProfile();
+        if (!reported.equals(probed)) {
+            throw new RuntimeException("sun.misc.Version reports: " + reported
+               + ", but probing reports: " + probed);
+        }
+
+        String profile = probed;
+        boolean isFullJre = (profile.length() == 0);
+
+        // check that java -version includes "profile compactN"
+        String expected = "profile " + profile;
+        System.out.println("Checking java -version ...");
+        ByteArrayOutputStream baos = execJava("-version");
+        ByteArrayInputStream bain = new ByteArrayInputStream(baos.toByteArray());
+        BufferedReader reader = new BufferedReader(new InputStreamReader(bain));
+        boolean found = false;
+        String line;
+        while ((line = reader.readLine()) != null) {
+            if (line.contains(expected)) {
+                found = true;
+                break;
+            }
+        }
+        if (found && isFullJre)
+           throw new RuntimeException(expected + " found in java -version output");
+        if (!found && !isFullJre)
+            throw new RuntimeException("java -version did not include " + expected);
+
+        // check that the profile name matches the release file
+        System.out.println("Checking release file ...");
+        Properties props = new Properties();
+
+        Path home = Paths.get(JAVA_HOME);
+        if (home.getFileName().toString().equals("jre"))
+            home = home.getParent();
+        Path release = home.resolve("release");
+        try (InputStream in = Files.newInputStream(release)) {
+            props.load(in);
+        }
+        String value = props.getProperty("JAVA_PROFILE");
+        if (isFullJre) {
+            if (value != null)
+                throw new RuntimeException("JAVA_PROFILE should not be present");
+        } else {
+            if (value == null)
+                throw new RuntimeException("JAVA_PROFILE not present in release file");
+            if (!value.equals("\"" + profile + "\""))
+                throw new RuntimeException("Unexpected value of JAVA_PROFILE: " + value);
+        }
+
+        System.out.println("Test passed.");
+    }
+}
diff --git a/jdk/test/tools/pack200/NoBeans.java b/jdk/test/tools/pack200/NoBeans.java
new file mode 100644
index 0000000..c900940
--- /dev/null
+++ b/jdk/test/tools/pack200/NoBeans.java
@@ -0,0 +1,49 @@
+/*
+ * 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 8004931
+ * @compile NoBeans.java
+ * @summary A compile-only test to ensure that implementations of Packer
+ *   and Unpacker can be compiled without implementating the
+ *   addPropertyChangeListener and removePropertyChangeListener methods.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+public class NoBeans {
+
+    static class MyPacker implements Pack200.Packer {
+        public SortedMap<String,String> properties() { return null; }
+        public void pack(JarFile in, OutputStream out) { }
+        public void pack(JarInputStream in, OutputStream out) { }
+    }
+
+    static class MyUnpacker implements Pack200.Unpacker {
+        public SortedMap<String,String> properties() { return null; }
+        public void unpack(InputStream in, JarOutputStream out) { }
+        public void unpack(File in, JarOutputStream out) { }
+    }
+}
diff --git a/jdk/test/tools/pack200/Pack200Test.java b/jdk/test/tools/pack200/Pack200Test.java
index 476ece1..d897bf8 100644
--- a/jdk/test/tools/pack200/Pack200Test.java
+++ b/jdk/test/tools/pack200/Pack200Test.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -30,7 +30,7 @@
 
  /*
   * @test
-  * @bug 6521334 6712743
+  * @bug 6521334 6712743 8007902
   * @summary check for memory leaks, test general packer/unpacker functionality\
   *          using native and java unpackers
   * @compile -XDignore.symbol.file Utils.java Pack200Test.java
diff --git a/jdk/test/tools/pack200/Reflect.java b/jdk/test/tools/pack200/Reflect.java
new file mode 100644
index 0000000..27287aba
--- /dev/null
+++ b/jdk/test/tools/pack200/Reflect.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @summary Invoke getDeclaredMethods on Packer and Unpacker to ensure
+ *    that all types referenced in the method signatures is present.
+ */
+
+import java.util.jar.Pack200;
+import java.util.jar.Pack200.Packer;
+import java.util.jar.Pack200.Unpacker;
+import java.lang.reflect.Method;
+
+public class Reflect {
+    static void printMethods(Class<?> c) {
+        System.out.println(c);
+        for (Method m: c.getDeclaredMethods()) {
+            System.out.println("    " + m);
+        }
+    }
+    public static void main(String[] args) {
+        printMethods(Pack200.Packer.class);
+        printMethods(Pack200.Unpacker.class);
+        printMethods(Pack200.newPacker().getClass());
+        printMethods(Pack200.newUnpacker().getClass());
+    }
+}
diff --git a/jdk/test/tools/pack200/pack200-verifier/data/golden.jar b/jdk/test/tools/pack200/pack200-verifier/data/golden.jar
index 913fe14..511cc0f 100644
--- a/jdk/test/tools/pack200/pack200-verifier/data/golden.jar
+++ b/jdk/test/tools/pack200/pack200-verifier/data/golden.jar
Binary files differ
diff --git a/langtools/.hgtags b/langtools/.hgtags
index 788268b..599a33e 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -198,3 +198,4 @@
 56c97aff46bb577b8668874154c24115a7e8a3e8 jdk8-b74
 c2e11e2ec4a3682513e566849e5562f31ded8c65 jdk8-b75
 e81839b3233792415daaab051698edc6067f1a16 jdk8-b76
+89c66415168925dffe492356ff893ff248bb5603 jdk8-b77
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java b/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java
index bb8faf3..f927b3b 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java
@@ -56,7 +56,7 @@
     public static final int ACC_SYNTHETIC     = 0x1000; // class, inner, field, method
     public static final int ACC_ANNOTATION    = 0x2000; // class, inner
     public static final int ACC_ENUM          = 0x4000; // class, inner, field
-    public static final int ACC_MODULE        = 0x8000; // class, inner, field, method
+    public static final int ACC_MANDATED      = 0x8000; // class, inner, field, method
 
     public static enum Kind { Class, InnerClass, Field, Method};
 
@@ -81,12 +81,12 @@
     }
 
     private static final int[] classModifiers = {
-        ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
+        ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT
     };
 
     private static final int[] classFlags = {
         ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT,
-        ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
+        ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
     };
 
     public Set<String> getClassModifiers() {
@@ -100,12 +100,12 @@
 
     private static final int[] innerClassModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_ABSTRACT, ACC_MODULE
+        ACC_ABSTRACT
     };
 
     private static final int[] innerClassFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER,
-        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
+        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
     };
 
     public Set<String> getInnerClassModifiers() {
@@ -119,12 +119,12 @@
 
     private static final int[] fieldModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_VOLATILE, ACC_TRANSIENT, ACC_MODULE
+        ACC_VOLATILE, ACC_TRANSIENT
     };
 
     private static final int[] fieldFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM, ACC_MODULE
+        ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM
     };
 
     public Set<String> getFieldModifiers() {
@@ -137,13 +137,13 @@
 
     private static final int[] methodModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT, ACC_MODULE
+        ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT
     };
 
     private static final int[] methodFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
         ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT,
-        ACC_STRICT, ACC_SYNTHETIC, ACC_MODULE
+        ACC_STRICT, ACC_SYNTHETIC
     };
 
     public Set<String> getMethodModifiers() {
@@ -208,8 +208,8 @@
                 return "abstract";
             case ACC_STRICT:
                 return "strictfp";
-            case ACC_MODULE:
-                return "module";
+            case ACC_MANDATED:
+                return "mandated";
             default:
                 return null;
         }
@@ -247,8 +247,8 @@
             return "ACC_ANNOTATION";
         case ACC_ENUM:
             return "ACC_ENUM";
-        case ACC_MODULE:
-            return "ACC_MODULE";
+        case ACC_MANDATED:
+            return "ACC_MANDATED";
         default:
             return null;
         }
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
index 0f3f73e..9628b96 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java
@@ -727,12 +727,13 @@
         private void write(TypeAnnotation.Position p, ClassOutputStream out) {
             out.writeByte(p.type.targetTypeValue());
             switch (p.type) {
-            // type cast
-            case CAST:
             // instanceof
             case INSTANCEOF:
             // new expression
             case NEW:
+            // constructor/method reference receiver
+            case CONSTRUCTOR_REFERENCE:
+            case METHOD_REFERENCE:
                 out.writeShort(p.offset);
                 break;
             // local variable
@@ -779,9 +780,12 @@
             case METHOD_FORMAL_PARAMETER:
                 out.writeByte(p.parameter_index);
                 break;
+            // type cast
+            case CAST:
             // method/constructor/reference type argument
             case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
             case METHOD_INVOCATION_TYPE_ARGUMENT:
+            case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
             case METHOD_REFERENCE_TYPE_ARGUMENT:
                 out.writeShort(p.offset);
                 out.writeByte(p.type_index);
@@ -790,10 +794,6 @@
             case METHOD_RETURN:
             case FIELD:
                 break;
-            // lambda formal parameter
-            case LAMBDA_FORMAL_PARAMETER:
-                out.writeByte(p.parameter_index);
-                break;
             case UNKNOWN:
                 throw new AssertionError("ClassWriter: UNKNOWN target type should never occur!");
             default:
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
index 0b1a40d..ec842d0 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java
@@ -86,12 +86,13 @@
         position.type = type;
 
         switch (type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             position.offset = cr.readUnsignedShort();
             break;
         // local variable
@@ -142,9 +143,12 @@
         case METHOD_FORMAL_PARAMETER:
             position.parameter_index = cr.readUnsignedByte();
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             position.offset = cr.readUnsignedShort();
             position.type_index = cr.readUnsignedByte();
@@ -153,10 +157,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            position.parameter_index = cr.readUnsignedByte();
-            break;
         case UNKNOWN:
             throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
         default:
@@ -177,13 +177,14 @@
         int n = 0;
         n += 1; // TargetType tag is a byte
         switch (pos.type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
-            n += 2;
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
+            n += 2; // offset
             break;
         // local variable
         case LOCAL_VARIABLE:
@@ -192,7 +193,7 @@
             n += 2; // table_length;
             int table_length = pos.lvarOffset.length;
             n += 2 * table_length; // offset
-            n += 2 * table_length; // length;
+            n += 2 * table_length; // length
             n += 2 * table_length; // index
             break;
         // exception parameter
@@ -206,7 +207,7 @@
         // type parameter
         case CLASS_TYPE_PARAMETER:
         case METHOD_TYPE_PARAMETER:
-            n += 1; // parameter_index;
+            n += 1; // parameter_index
             break;
         // type parameter bound
         case CLASS_TYPE_PARAMETER_BOUND:
@@ -226,9 +227,12 @@
         case METHOD_FORMAL_PARAMETER:
             n += 1; // parameter_index
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             n += 2; // offset
             n += 1; // type index
@@ -237,10 +241,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            n += 1; // parameter_index
-            break;
         case UNKNOWN:
             throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
         default:
@@ -377,12 +377,13 @@
             sb.append(type);
 
             switch (type) {
-            // type cast
-            case CAST:
             // instanceof
             case INSTANCEOF:
             // new expression
             case NEW:
+            // constructor/method reference receiver
+            case CONSTRUCTOR_REFERENCE:
+            case METHOD_REFERENCE:
                 sb.append(", offset = ");
                 sb.append(offset);
                 break;
@@ -444,9 +445,12 @@
                 sb.append(", param_index = ");
                 sb.append(parameter_index);
                 break;
+            // type cast
+            case CAST:
             // method/constructor/reference type argument
             case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
             case METHOD_INVOCATION_TYPE_ARGUMENT:
+            case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
             case METHOD_REFERENCE_TYPE_ARGUMENT:
                 sb.append(", offset = ");
                 sb.append(offset);
@@ -457,12 +461,6 @@
             case METHOD_RETURN:
             case FIELD:
                 break;
-            // lambda formal parameter
-            case LAMBDA_FORMAL_PARAMETER:
-                // TODO: also needs an offset?
-                sb.append(", param_index = ");
-                sb.append(parameter_index);
-                break;
             case UNKNOWN:
                 sb.append(", position UNKNOWN!");
                 break;
@@ -564,34 +562,37 @@
         /** For annotations on an exception parameter. */
         EXCEPTION_PARAMETER(0x42, true),
 
-        /** For annotations on a typecast. */
-        CAST(0x43, true),
-
         /** For annotations on a type test. */
-        INSTANCEOF(0x44, true),
+        INSTANCEOF(0x43, true),
 
         /** For annotations on an object creation expression. */
-        NEW(0x45, true),
+        NEW(0x44, true),
+
+        /** For annotations on a constructor reference receiver. */
+        CONSTRUCTOR_REFERENCE(0x45, true),
+
+        /** For annotations on a method reference receiver. */
+        METHOD_REFERENCE(0x46, true),
+
+        /** For annotations on a typecast. */
+        CAST(0x47, true),
 
         /** For annotations on a type argument of an object creation expression. */
-        CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
+        CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
 
         /** For annotations on a type argument of a method call. */
-        METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
+        METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true),
 
-        /** For annotations on a lambda parameter type. */
-        LAMBDA_FORMAL_PARAMETER(0x48, true),
-
-        /** For annotations on a method reference. */
-        METHOD_REFERENCE(0x49, true),
+        /** For annotations on a type argument of a constructor reference. */
+        CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
 
         /** For annotations on a type argument of a method reference. */
-        METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
+        METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
 
         /** For annotations with an unknown target. */
         UNKNOWN(0xFF);
 
-        private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x50;
+        private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
 
         private final int targetTypeValue;
         private final boolean isLocal;
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
index 0a75cca..7ccee48 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -150,7 +150,20 @@
             String tableSummary, Content body) {
         if (packages.length > 0) {
             Arrays.sort(packages);
-            addAllClassesLink(body);
+            HtmlTree div = new HtmlTree(HtmlTag.DIV);
+            div.addStyle(HtmlStyle.indexHeader);
+            addAllClassesLink(div);
+            if (configuration.showProfiles) {
+                addAllProfilesLink(div);
+            }
+            body.addContent(div);
+            if (configuration.showProfiles) {
+                String profileSummary = configuration.getText("doclet.Profiles");
+                String profilesTableSummary = configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Profile_Summary"),
+                configuration.getText("doclet.profiles"));
+                addProfilesList(profileSummary, profilesTableSummary, body);
+            }
             addPackagesList(packages, text, tableSummary, body);
         }
     }
@@ -182,10 +195,29 @@
     }
 
     /**
-     * Do nothing. This will be overridden in PackageIndexFrameWriter.
+     * Do nothing. This will be overridden.
      *
-     * @param body the document tree to which the all classes link will be added
+     * @param div the document tree to which the all classes link will be added
      */
-    protected void addAllClassesLink(Content body) {
+    protected void addAllClassesLink(Content div) {
+    }
+
+    /**
+     * Do nothing. This will be overridden.
+     *
+     * @param div the document tree to which the all profiles link will be added
+     */
+    protected void addAllProfilesLink(Content div) {
+    }
+
+    /**
+     * Do nothing. This will be overridden.
+     *
+     * @param profileSummary the profile summary heading
+     * @param profilesTableSummary the profiles table summary information
+     * @param body the content tree to which the profiles list will be added
+     */
+    protected void addProfilesList(String profileSummary, String profilesTableSummary,
+            Content body) {
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractProfileIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractProfileIndexWriter.java
new file mode 100644
index 0000000..c0f7ccf
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractProfileIndexWriter.java
@@ -0,0 +1,276 @@
+/*
+ * 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.  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 com.sun.tools.doclets.formats.html;
+
+import java.io.*;
+
+import com.sun.tools.javac.sym.Profiles;
+import com.sun.tools.doclets.formats.html.markup.*;
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.DocPath;
+
+/**
+ * Abstract class to generate the profile overview files in
+ * Frame and Non-Frame format. This will be sub-classed to
+ * generate profile-overview-frame.html as well as profile-overview-summary.html.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+public abstract class AbstractProfileIndexWriter extends HtmlDocletWriter {
+
+    /**
+     * Profiles to be documented.
+     */
+    protected Profiles profiles;
+
+    /**
+     * Constructor. Also initializes the profiles variable.
+     *
+     * @param configuration  The current configuration
+     * @param filename Name of the profile index file to be generated.
+     */
+    public AbstractProfileIndexWriter(ConfigurationImpl configuration,
+                                      DocPath filename) throws IOException {
+        super(configuration, filename);
+        profiles = configuration.profiles;
+    }
+
+    /**
+     * Adds the navigation bar header to the documentation tree.
+     *
+     * @param body the document tree to which the navigation bar header will be added
+     */
+    protected abstract void addNavigationBarHeader(Content body);
+
+    /**
+     * Adds the navigation bar footer to the documentation tree.
+     *
+     * @param body the document tree to which the navigation bar footer will be added
+     */
+    protected abstract void addNavigationBarFooter(Content body);
+
+    /**
+     * Adds the overview header to the documentation tree.
+     *
+     * @param body the document tree to which the overview header will be added
+     */
+    protected abstract void addOverviewHeader(Content body);
+
+    /**
+     * Adds the profiles list to the documentation tree.
+     *
+     * @param profiles profiles object
+     * @param text caption for the table
+     * @param tableSummary summary for the table
+     * @param body the document tree to which the profiles list will be added
+     */
+    protected abstract void addProfilesList(Profiles profiles, String text,
+            String tableSummary, Content body);
+
+    /**
+     * Adds the profile packages list to the documentation tree.
+     *
+     * @param profiles profiles object
+     * @param text caption for the table
+     * @param tableSummary summary for the table
+     * @param body the document tree to which the profiles list will be added
+     * @param profileName the name for the profile being documented
+     */
+    protected abstract void addProfilePackagesList(Profiles profiles, String text,
+            String tableSummary, Content body, String profileName);
+
+    /**
+     * Generate and prints the contents in the profile index file. Call appropriate
+     * methods from the sub-class in order to generate Frame or Non
+     * Frame format.
+     *
+     * @param title the title of the window.
+     * @param includeScript boolean set true if windowtitle script is to be included
+     */
+    protected void buildProfileIndexFile(String title, boolean includeScript) throws IOException {
+        String windowOverview = configuration.getText(title);
+        Content body = getBody(includeScript, getWindowTitle(windowOverview));
+        addNavigationBarHeader(body);
+        addOverviewHeader(body);
+        addIndex(body);
+        addOverview(body);
+        addNavigationBarFooter(body);
+        printHtmlDocument(configuration.metakeywords.getOverviewMetaKeywords(title,
+                configuration.doctitle), includeScript, body);
+    }
+
+    /**
+     * Generate and prints the contents in the profile packages index file. Call appropriate
+     * methods from the sub-class in order to generate Frame or Non
+     * Frame format.
+     *
+     * @param title the title of the window.
+     * @param includeScript boolean set true if windowtitle script is to be included
+     * @param profileName the name of the profile being documented
+     */
+    protected void buildProfilePackagesIndexFile(String title,
+            boolean includeScript, String profileName) throws IOException {
+        String windowOverview = configuration.getText(title);
+        Content body = getBody(includeScript, getWindowTitle(windowOverview));
+        addNavigationBarHeader(body);
+        addOverviewHeader(body);
+        addProfilePackagesIndex(body, profileName);
+        addOverview(body);
+        addNavigationBarFooter(body);
+        printHtmlDocument(configuration.metakeywords.getOverviewMetaKeywords(title,
+                configuration.doctitle), includeScript, body);
+    }
+
+    /**
+     * Default to no overview, override to add overview.
+     *
+     * @param body the document tree to which the overview will be added
+     */
+    protected void addOverview(Content body) throws IOException {
+    }
+
+    /**
+     * Adds the frame or non-frame profile index to the documentation tree.
+     *
+     * @param body the document tree to which the index will be added
+     */
+    protected void addIndex(Content body) {
+        addIndexContents(profiles, "doclet.Profile_Summary",
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Profile_Summary"),
+                configuration.getText("doclet.profiles")), body);
+    }
+
+    /**
+     * Adds the frame or non-frame profile packages index to the documentation tree.
+     *
+     * @param body the document tree to which the index will be added
+     * @param profileName  the name of the profile being documented
+     */
+    protected void addProfilePackagesIndex(Content body, String profileName) {
+        addProfilePackagesIndexContents(profiles, "doclet.Profile_Summary",
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Profile_Summary"),
+                configuration.getText("doclet.profiles")), body, profileName);
+    }
+
+    /**
+     * Adds profile index contents. Call appropriate methods from
+     * the sub-classes. Adds it to the body HtmlTree
+     *
+     * @param profiles profiles to be documented
+     * @param text string which will be used as the heading
+     * @param tableSummary summary for the table
+     * @param body the document tree to which the index contents will be added
+     */
+    protected void addIndexContents(Profiles profiles, String text,
+            String tableSummary, Content body) {
+        if (profiles.getProfileCount() > 0) {
+            HtmlTree div = new HtmlTree(HtmlTag.DIV);
+            div.addStyle(HtmlStyle.indexHeader);
+            addAllClassesLink(div);
+            addAllPackagesLink(div);
+            body.addContent(div);
+            addProfilesList(profiles, text, tableSummary, body);
+        }
+    }
+
+    /**
+     * Adds profile packages index contents. Call appropriate methods from
+     * the sub-classes. Adds it to the body HtmlTree
+     *
+     * @param profiles profiles to be documented
+     * @param text string which will be used as the heading
+     * @param tableSummary summary for the table
+     * @param body the document tree to which the index contents will be added
+     * @param profileName the name of the profile being documented
+     */
+    protected void addProfilePackagesIndexContents(Profiles profiles, String text,
+            String tableSummary, Content body, String profileName) {
+        HtmlTree div = new HtmlTree(HtmlTag.DIV);
+        div.addStyle(HtmlStyle.indexHeader);
+        addAllClassesLink(div);
+        addAllPackagesLink(div);
+        addAllProfilesLink(div);
+        body.addContent(div);
+        addProfilePackagesList(profiles, text, tableSummary, body, profileName);
+    }
+
+    /**
+     * Adds the doctitle to the documentation tree, if it is specified on the command line.
+     *
+     * @param body the document tree to which the title will be added
+     */
+    protected void addConfigurationTitle(Content body) {
+        if (configuration.doctitle.length() > 0) {
+            Content title = new RawHtml(configuration.doctitle);
+            Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING,
+                    HtmlStyle.title, title);
+            Content div = HtmlTree.DIV(HtmlStyle.header, heading);
+            body.addContent(div);
+        }
+    }
+
+    /**
+     * Returns highlighted "Overview", in the navigation bar as this is the
+     * overview page.
+     *
+     * @return a Content object to be added to the documentation tree
+     */
+    protected Content getNavLinkContents() {
+        Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, overviewLabel);
+        return li;
+    }
+
+    /**
+     * Do nothing. This will be overridden in ProfileIndexFrameWriter.
+     *
+     * @param div the document tree to which the all classes link will be added
+     */
+    protected void addAllClassesLink(Content div) {
+    }
+
+    /**
+     * Do nothing. This will be overridden in ProfileIndexFrameWriter.
+     *
+     * @param div the document tree to which the all packages link will be added
+     */
+    protected void addAllPackagesLink(Content div) {
+    }
+
+    /**
+     * Do nothing. This will be overridden in ProfilePackageIndexFrameWriter.
+     *
+     * @param div the document tree to which the all profiles link will be added
+     */
+    protected void addAllProfilesLink(Content div) {
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
index 809f00f..36df531 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -25,10 +25,10 @@
 
 package com.sun.tools.doclets.formats.html;
 
-import java.io.IOException;
 import java.util.*;
 
 import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.doclets.formats.html.markup.*;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.builders.*;
@@ -165,6 +165,20 @@
         bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA);
         HtmlTree div = new HtmlTree(HtmlTag.DIV);
         div.addStyle(HtmlStyle.header);
+        if (configuration.showProfiles) {
+            String sep = "";
+            int profile = configuration.profiles.getProfile(getTypeNameForProfile(classDoc));
+            if (profile > 0) {
+                Content profNameContent = new StringContent();
+                for (int i = profile; i < configuration.profiles.getProfileCount(); i++) {
+                    profNameContent.addContent(sep);
+                    profNameContent.addContent(Profile.lookup(i).name);
+                    sep = ", ";
+                }
+                Content profileNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, profNameContent);
+                div.addContent(profileNameDiv);
+            }
+        }
         if (pkgname.length() > 0) {
             Content pkgNameContent = new StringContent(pkgname);
             Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, pkgNameContent);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
index 6a39ced..acf3919 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -65,7 +65,7 @@
     public FrameOutputWriter(ConfigurationImpl configuration,
                              DocPath filename) throws IOException {
         super(configuration, filename);
-    noOfPackages = configuration.packages.length;
+        noOfPackages = configuration.packages.length;
     }
 
     /**
@@ -135,7 +135,13 @@
     protected Content getFrameDetails() {
         HtmlTree frameset = HtmlTree.FRAMESET("20%,80%", null, "Documentation frame",
                 "top.loadFrames()");
-        if (noOfPackages <= 1) {
+        if (configuration.showProfiles) {
+            HtmlTree leftFrameset = HtmlTree.FRAMESET(null, "30%,70%", "Left frames",
+                "top.loadFrames()");
+            addAllProfilesFrameTag(leftFrameset);
+            addAllClassesFrameTag(leftFrameset);
+            frameset.addContent(leftFrameset);
+        } else if (noOfPackages <= 1) {
             addAllClassesFrameTag(frameset);
         } else if (noOfPackages > 1) {
             HtmlTree leftFrameset = HtmlTree.FRAMESET(null, "30%,70%", "Left frames",
@@ -150,6 +156,17 @@
     }
 
     /**
+     * Add the FRAME tag for the frame that lists all profiles.
+     *
+     * @param contentTree the content tree to which the information will be added
+     */
+    private void addAllProfilesFrameTag(Content contentTree) {
+        HtmlTree frame = HtmlTree.FRAME(DocPaths.PROFILE_OVERVIEW_FRAME.getPath(),
+                "profileListFrame", configuration.getText("doclet.All_Profiles"));
+        contentTree.addContent(frame);
+    }
+
+    /**
      * Add the FRAME tag for the frame that lists all packages.
      *
      * @param contentTree the content tree to which the information will be added
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java
index 4545382..7395503 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -28,6 +28,8 @@
 import java.util.*;
 
 import com.sun.javadoc.*;
+import com.sun.tools.javac.sym.Profiles;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.builders.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -202,6 +204,44 @@
     /**
      * {@inheritDoc}
      */
+    protected void generateProfileFiles() throws Exception {
+        if (configuration.showProfiles) {
+            ProfileIndexFrameWriter.generate(configuration);
+            Profile prevProfile = null, nextProfile;
+            for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
+                ProfilePackageIndexFrameWriter.generate(configuration, Profile.lookup(i).name);
+                PackageDoc[] packages = configuration.profilePackages.get(
+                        Profile.lookup(i).name);
+                PackageDoc prev = null, next;
+                for (int j = 0; j < packages.length; j++) {
+                    // if -nodeprecated option is set and the package is marked as
+                    // deprecated, do not generate the profilename-package-summary.html
+                    // and profilename-package-frame.html pages for that package.
+                    if (!(configuration.nodeprecated && Util.isDeprecated(packages[j]))) {
+                        ProfilePackageFrameWriter.generate(configuration, packages[j], i);
+                        next = (j + 1 < packages.length
+                                && packages[j + 1].name().length() > 0) ? packages[j + 1] : null;
+                        AbstractBuilder profilePackageSummaryBuilder =
+                                configuration.getBuilderFactory().getProfilePackageSummaryBuilder(
+                                packages[j], prev, next, Profile.lookup(i));
+                        profilePackageSummaryBuilder.build();
+                        prev = packages[j];
+                    }
+                }
+                nextProfile = (i + 1 < configuration.profiles.getProfileCount()) ?
+                        Profile.lookup(i + 1) : null;
+                AbstractBuilder profileSummaryBuilder =
+                        configuration.getBuilderFactory().getProfileSummaryBuilder(
+                        Profile.lookup(i), prevProfile, nextProfile);
+                profileSummaryBuilder.build();
+                prevProfile = Profile.lookup(i);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     protected void generatePackageFiles(ClassTree classtree) throws Exception {
         PackageDoc[] packages = configuration.packages;
         if (packages.length > 1) {
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
index ea97520..7d3c71b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
@@ -301,6 +301,107 @@
     }
 
     /**
+     * Get Profile Package link, with target frame.
+     *
+     * @param pd the packageDoc object
+     * @param target name of the target frame
+     * @param label tag for the link
+     * @param profileName the name of the profile being documented
+     * @return a content for the target profile packages link
+     */
+    public Content getTargetProfilePackageLink(PackageDoc pd, String target,
+            Content label, String profileName) {
+        return getHyperLink(pathString(pd, DocPaths.profilePackageSummary(profileName)),
+                label, "", target);
+    }
+
+    /**
+     * Get Profile link, with target frame.
+     *
+     * @param target name of the target frame
+     * @param label tag for the link
+     * @param profileName the name of the profile being documented
+     * @return a content for the target profile link
+     */
+    public Content getTargetProfileLink(String target, Content label,
+            String profileName) {
+        return getHyperLink(pathToRoot.resolve(
+                DocPaths.profileSummary(profileName)), label, "", target);
+    }
+
+    /**
+     * Get the type name for profile search.
+     *
+     * @param cd the classDoc object for which the type name conversion is needed
+     * @return a type name string for the type
+     */
+    public String getTypeNameForProfile(ClassDoc cd) {
+        StringBuilder typeName =
+                new StringBuilder((cd.containingPackage()).name().replace(".", "/"));
+        typeName.append("/")
+                .append(cd.name().replace(".", "$"));
+        return typeName.toString();
+    }
+
+    /**
+     * Check if a type belongs to a profile.
+     *
+     * @param cd the classDoc object that needs to be checked
+     * @param profileValue the profile in which the type needs to be checked
+     * @return true if the type is in the profile
+     */
+    public boolean isTypeInProfile(ClassDoc cd, int profileValue) {
+        return (configuration.profiles.getProfile(getTypeNameForProfile(cd)) <= profileValue);
+    }
+
+    public void addClassesSummary(ClassDoc[] classes, String label,
+            String tableSummary, String[] tableHeader, Content summaryContentTree,
+            int profileValue) {
+        if(classes.length > 0) {
+            Arrays.sort(classes);
+            Content caption = getTableCaption(label);
+            Content table = HtmlTree.TABLE(HtmlStyle.packageSummary, 0, 3, 0,
+                    tableSummary, caption);
+            table.addContent(getSummaryTableHeader(tableHeader, "col"));
+            Content tbody = new HtmlTree(HtmlTag.TBODY);
+            for (int i = 0; i < classes.length; i++) {
+                if (!isTypeInProfile(classes[i], profileValue)) {
+                    continue;
+                }
+                if (!Util.isCoreClass(classes[i]) ||
+                    !configuration.isGeneratedDoc(classes[i])) {
+                    continue;
+                }
+                Content classContent = new RawHtml(getLink(new LinkInfoImpl(
+                        configuration, LinkInfoImpl.CONTEXT_PACKAGE, classes[i],
+                        false)));
+                Content tdClass = HtmlTree.TD(HtmlStyle.colFirst, classContent);
+                HtmlTree tr = HtmlTree.TR(tdClass);
+                if (i%2 == 0)
+                    tr.addStyle(HtmlStyle.altColor);
+                else
+                    tr.addStyle(HtmlStyle.rowColor);
+                HtmlTree tdClassDescription = new HtmlTree(HtmlTag.TD);
+                tdClassDescription.addStyle(HtmlStyle.colLast);
+                if (Util.isDeprecated(classes[i])) {
+                    tdClassDescription.addContent(deprecatedLabel);
+                    if (classes[i].tags("deprecated").length > 0) {
+                        addSummaryDeprecatedComment(classes[i],
+                            classes[i].tags("deprecated")[0], tdClassDescription);
+                    }
+                }
+                else
+                    addSummaryComment(classes[i], tdClassDescription);
+                tr.addContent(tdClassDescription);
+                tbody.addContent(tr);
+            }
+            table.addContent(tbody);
+            Content li = HtmlTree.LI(HtmlStyle.blockList, table);
+            summaryContentTree.addContent(li);
+        }
+    }
+
+    /**
      * Generates the HTML document tree and prints it out.
      *
      * @param metakeywords Array of String keywords for META tag. Each element
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
index 6e066a8..8d580f8 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -145,13 +145,26 @@
      * Adds "All Classes" link for the top of the left-hand frame page to the
      * documentation tree.
      *
-     * @param body the Content object to which the all classes link should be added
+     * @param div the Content object to which the all classes link should be added
      */
-    protected void addAllClassesLink(Content body) {
+    protected void addAllClassesLink(Content div) {
         Content linkContent = getHyperLink(DocPaths.ALLCLASSES_FRAME,
                 allclassesLabel, "", "packageFrame");
-        Content div = HtmlTree.DIV(HtmlStyle.indexHeader, linkContent);
-        body.addContent(div);
+        Content span = HtmlTree.SPAN(linkContent);
+        div.addContent(span);
+    }
+
+    /**
+     * Adds "All Profiles" link for the top of the left-hand frame page to the
+     * documentation tree.
+     *
+     * @param div the Content object to which the all profiles link should be added
+     */
+    protected void addAllProfilesLink(Content div) {
+        Content linkContent = getHyperLink(DocPaths.PROFILE_OVERVIEW_FRAME,
+                allprofilesLabel, "", "profileListFrame");
+        Content span = HtmlTree.SPAN(linkContent);
+        div.addContent(span);
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
index c5df5f3..ee497de 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
@@ -29,6 +29,7 @@
 import java.util.*;
 
 import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.doclets.formats.html.markup.*;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -122,6 +123,21 @@
     /**
      * {@inheritDoc}
      */
+    protected void addProfilesList(String profileSummary, String profilesTableSummary,
+            Content body) {
+        Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, profilesTableSummary,
+                getTableCaption(profileSummary));
+        table.addContent(getSummaryTableHeader(profileTableHeader, "col"));
+        Content tbody = new HtmlTree(HtmlTag.TBODY);
+        addProfilesList(tbody);
+        table.addContent(tbody);
+        Content div = HtmlTree.DIV(HtmlStyle.contentContainer, table);
+        body.addContent(div);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     protected void addPackagesList(PackageDoc[] packages, String text,
             String tableSummary, Content body) {
         Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, tableSummary,
@@ -135,6 +151,31 @@
     }
 
     /**
+     * Adds list of profiles in the index table. Generate link to each profile.
+     *
+     * @param tbody the documentation tree to which the list will be added
+     */
+    protected void addProfilesList(Content tbody) {
+        for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
+            String profileName = Profile.lookup(i).name;
+            Content profileLinkContent = getTargetProfileLink("classFrame",
+                    new StringContent(profileName), profileName);
+            Content tdProfile = HtmlTree.TD(HtmlStyle.colFirst, profileLinkContent);
+            HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
+            tdSummary.addStyle(HtmlStyle.colLast);
+            tdSummary.addContent(getSpace());
+            HtmlTree tr = HtmlTree.TR(tdProfile);
+            tr.addContent(tdSummary);
+            if (i % 2 == 0) {
+                tr.addStyle(HtmlStyle.altColor);
+            } else {
+                tr.addStyle(HtmlStyle.rowColor);
+            }
+            tbody.addContent(tr);
+        }
+    }
+
+    /**
      * Adds list of packages in the index table. Generate link to each package.
      *
      * @param packages Packages to which link is to be generated
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
new file mode 100644
index 0000000..6957454
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
@@ -0,0 +1,173 @@
+/*
+ * 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.  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 com.sun.tools.doclets.formats.html;
+
+import java.io.*;
+
+import com.sun.tools.javac.sym.Profiles;
+import com.sun.tools.doclets.formats.html.markup.*;
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.*;
+import com.sun.tools.javac.jvm.Profile;
+
+/**
+ * Generate the profile index for the left-hand frame in the generated output.
+ * A click on the profile name in this frame will update the page in the top
+ * left hand frame with the listing of packages of the clicked profile.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+public class ProfileIndexFrameWriter extends AbstractProfileIndexWriter {
+
+    /**
+     * Construct the ProfileIndexFrameWriter object.
+     *
+     * @param configuration the configuration object
+     * @param filename Name of the profile index file to be generated.
+     */
+    public ProfileIndexFrameWriter(ConfigurationImpl configuration,
+                                   DocPath filename) throws IOException {
+        super(configuration, filename);
+    }
+
+    /**
+     * Generate the profile index file named "profile-overview-frame.html".
+     * @throws DocletAbortException
+     * @param configuration the configuration object
+     */
+    public static void generate(ConfigurationImpl configuration) {
+        ProfileIndexFrameWriter profilegen;
+        DocPath filename = DocPaths.PROFILE_OVERVIEW_FRAME;
+        try {
+            profilegen = new ProfileIndexFrameWriter(configuration, filename);
+            profilegen.buildProfileIndexFile("doclet.Window_Overview", false);
+            profilegen.close();
+        } catch (IOException exc) {
+            configuration.standardmessage.error(
+                        "doclet.exception_encountered",
+                        exc.toString(), filename);
+            throw new DocletAbortException();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void addProfilesList(Profiles profiles, String text,
+            String tableSummary, Content body) {
+        Content heading = HtmlTree.HEADING(HtmlConstants.PROFILE_HEADING, true,
+                profilesLabel);
+        Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
+        HtmlTree ul = new HtmlTree(HtmlTag.UL);
+        ul.addAttr(HtmlAttr.TITLE, profilesLabel.toString());
+        for (int i = 1; i < profiles.getProfileCount(); i++) {
+            ul.addContent(getProfile(i));
+        }
+        div.addContent(ul);
+        body.addContent(div);
+    }
+
+    /**
+     * Gets each profile name as a separate link.
+     *
+     * @param profile the profile being documented
+     * @return content for the profile link
+     */
+    protected Content getProfile(int profile) {
+        Content profileLinkContent;
+        Content profileLabel;
+        String profileName = (Profile.lookup(profile)).name;
+        profileLabel = new StringContent(profileName);
+        profileLinkContent = getHyperLink(DocPaths.profileFrame(profileName), profileLabel, "",
+                    "profileListFrame");
+        Content li = HtmlTree.LI(profileLinkContent);
+        return li;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void addNavigationBarHeader(Content body) {
+        Content headerContent;
+        if (configuration.packagesheader.length() > 0) {
+            headerContent = new RawHtml(replaceDocRootDir(configuration.packagesheader));
+        } else {
+            headerContent = new RawHtml(replaceDocRootDir(configuration.header));
+        }
+        Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
+                HtmlStyle.bar, headerContent);
+        body.addContent(heading);
+    }
+
+    /**
+     * Do nothing as there is no overview information in this page.
+     */
+    protected void addOverviewHeader(Content body) {
+    }
+
+    /**
+     * Adds "All Classes" link for the top of the left-hand frame page to the
+     * documentation tree.
+     *
+     * @param div the Content object to which the all classes link should be added
+     */
+    protected void addAllClassesLink(Content div) {
+        Content linkContent = getHyperLink(DocPaths.ALLCLASSES_FRAME,
+                allclassesLabel, "", "packageFrame");
+        Content span = HtmlTree.SPAN(linkContent);
+        div.addContent(span);
+    }
+
+    /**
+     * Adds "All Packages" link for the top of the left-hand frame page to the
+     * documentation tree.
+     *
+     * @param div the Content object to which the all packages link should be added
+     */
+    protected void addAllPackagesLink(Content div) {
+        Content linkContent = getHyperLink(DocPaths.OVERVIEW_FRAME,
+                allpackagesLabel, "", "profileListFrame");
+        Content span = HtmlTree.SPAN(linkContent);
+        div.addContent(span);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void addNavigationBarFooter(Content body) {
+        Content p = HtmlTree.P(getSpace());
+        body.addContent(p);
+    }
+
+    protected void addProfilePackagesList(Profiles profiles, String text,
+            String tableSummary, Content body, String profileName) {
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
new file mode 100644
index 0000000..00ff307
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
@@ -0,0 +1,186 @@
+/*
+ * 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.  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 com.sun.tools.doclets.formats.html;
+
+import java.io.*;
+import java.util.*;
+
+import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
+import com.sun.tools.doclets.formats.html.markup.*;
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.*;
+
+/**
+ * Class to generate file for each package contents of a profile in the left-hand bottom
+ * frame. This will list all the Class Kinds in the package for a profile. A click on any
+ * class-kind will update the right-hand frame with the clicked class-kind page.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+public class ProfilePackageFrameWriter extends HtmlDocletWriter {
+
+    /**
+     * The package being documented.
+     */
+    private PackageDoc packageDoc;
+
+    /**
+     * Constructor to construct ProfilePackageFrameWriter object and to generate
+     * "profilename-package-frame.html" file in the respective package directory.
+     * For example for profile compact1 and package "java.lang" this will generate file
+     * "compact1-package-frame.html" file in the "java/lang" directory. It will also
+     * create "java/lang" directory in the current or the destination directory
+     * if it doesn't exist.
+     *
+     * @param configuration the configuration of the doclet.
+     * @param packageDoc PackageDoc under consideration.
+     * @param profileName the name of the profile being documented
+     */
+    public ProfilePackageFrameWriter(ConfigurationImpl configuration,
+            PackageDoc packageDoc, String profileName)
+            throws IOException {
+        super(configuration, DocPath.forPackage(packageDoc).resolve(
+                DocPaths.profilePackageFrame(profileName)));
+        this.packageDoc = packageDoc;
+    }
+
+    /**
+     * Generate a profile package summary page for the left-hand bottom frame. Construct
+     * the ProfilePackageFrameWriter object and then uses it generate the file.
+     *
+     * @param configuration the current configuration of the doclet.
+     * @param packageDoc The package for which "profilename-package-frame.html" is to be generated.
+     * @param profileValue the value of the profile being documented
+     */
+    public static void generate(ConfigurationImpl configuration,
+            PackageDoc packageDoc, int profileValue) {
+        ProfilePackageFrameWriter profpackgen;
+        try {
+            String profileName = Profile.lookup(profileValue).name;
+            profpackgen = new ProfilePackageFrameWriter(configuration, packageDoc,
+                    profileName);
+            StringBuilder winTitle = new StringBuilder(profileName);
+            String sep = " - ";
+            winTitle.append(sep);
+            String pkgName = Util.getPackageName(packageDoc);
+            winTitle.append(pkgName);
+            Content body = profpackgen.getBody(false,
+                    profpackgen.getWindowTitle(winTitle.toString()));
+            Content profName = new StringContent(profileName);
+            Content sepContent = new StringContent(sep);
+            Content pkgNameContent = new RawHtml(pkgName);
+            Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, HtmlStyle.bar,
+                    profpackgen.getTargetProfileLink("classFrame", profName, profileName));
+            heading.addContent(sepContent);
+            heading.addContent(profpackgen.getTargetProfilePackageLink(packageDoc,
+                    "classFrame", pkgNameContent, profileName));
+            body.addContent(heading);
+            HtmlTree div = new HtmlTree(HtmlTag.DIV);
+            div.addStyle(HtmlStyle.indexContainer);
+            profpackgen.addClassListing(div, profileValue);
+            body.addContent(div);
+            profpackgen.printHtmlDocument(
+                    configuration.metakeywords.getMetaKeywords(packageDoc), false, body);
+            profpackgen.close();
+        } catch (IOException exc) {
+            configuration.standardmessage.error(
+                    "doclet.exception_encountered",
+                    exc.toString(), DocPaths.PACKAGE_FRAME.getPath());
+            throw new DocletAbortException();
+        }
+    }
+
+    /**
+     * Add class listing for all the classes in this package. Divide class
+     * listing as per the class kind and generate separate listing for
+     * Classes, Interfaces, Exceptions and Errors.
+     *
+     * @param contentTree the content tree to which the listing will be added
+     * @param profileValue the value of the profile being documented
+     */
+    protected void addClassListing(Content contentTree, int profileValue) {
+        if (packageDoc.isIncluded()) {
+            addClassKindListing(packageDoc.interfaces(),
+                getResource("doclet.Interfaces"), contentTree, profileValue);
+            addClassKindListing(packageDoc.ordinaryClasses(),
+                getResource("doclet.Classes"), contentTree, profileValue);
+            addClassKindListing(packageDoc.enums(),
+                getResource("doclet.Enums"), contentTree, profileValue);
+            addClassKindListing(packageDoc.exceptions(),
+                getResource("doclet.Exceptions"), contentTree, profileValue);
+            addClassKindListing(packageDoc.errors(),
+                getResource("doclet.Errors"), contentTree, profileValue);
+            addClassKindListing(packageDoc.annotationTypes(),
+                getResource("doclet.AnnotationTypes"), contentTree, profileValue);
+        }
+    }
+
+    /**
+     * Add specific class kind listing. Also add label to the listing.
+     *
+     * @param arr Array of specific class kinds, namely Class or Interface or Exception or Error
+     * @param labelContent content tree of the label to be added
+     * @param contentTree the content tree to which the class kind listing will be added
+     * @param profileValue the value of the profile being documented
+     */
+    protected void addClassKindListing(ClassDoc[] arr, Content labelContent,
+            Content contentTree, int profileValue) {
+        if(arr.length > 0) {
+            Arrays.sort(arr);
+            boolean printedHeader = false;
+            HtmlTree ul = new HtmlTree(HtmlTag.UL);
+            ul.addAttr(HtmlAttr.TITLE, labelContent.toString());
+            for (int i = 0; i < arr.length; i++) {
+                if (!isTypeInProfile(arr[i], profileValue)) {
+                    continue;
+                }
+                if (!Util.isCoreClass(arr[i]) || !
+                        configuration.isGeneratedDoc(arr[i])) {
+                    continue;
+                }
+                if (!printedHeader) {
+                    Content heading = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
+                            true, labelContent);
+                    contentTree.addContent(heading);
+                    printedHeader = true;
+                }
+                Content link = new RawHtml (getLink(new LinkInfoImpl(configuration,
+                        LinkInfoImpl.PACKAGE_FRAME, arr[i],
+                        (arr[i].isInterface() ? italicsText(arr[i].name()) :
+                            arr[i].name()),"classFrame")));
+                Content li = HtmlTree.LI(link);
+                ul.addContent(li);
+            }
+            contentTree.addContent(ul);
+        }
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
new file mode 100644
index 0000000..193e559
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
@@ -0,0 +1,200 @@
+/*
+ * 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.  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 com.sun.tools.doclets.formats.html;
+
+import java.io.*;
+
+import com.sun.javadoc.*;
+import com.sun.tools.javac.sym.Profiles;
+import com.sun.tools.doclets.formats.html.markup.*;
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.*;
+
+/**
+ * Generate the profile package index for the left-hand frame in the generated output.
+ * A click on the package name in this frame will update the page in the bottom
+ * left hand frame with the listing of contents of the clicked profile package.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+public class ProfilePackageIndexFrameWriter extends AbstractProfileIndexWriter {
+
+    /**
+     * Construct the ProfilePackageIndexFrameWriter object.
+     *
+     * @param configuration the configuration object
+     * @param filename Name of the package index file to be generated.
+     */
+    public ProfilePackageIndexFrameWriter(ConfigurationImpl configuration,
+                                   DocPath filename) throws IOException {
+        super(configuration, filename);
+    }
+
+    /**
+     * Generate the profile package index file.
+     * @throws DocletAbortException
+     * @param configuration the configuration object
+     * @param profileName the name of the profile being documented
+     */
+    public static void generate(ConfigurationImpl configuration, String profileName) {
+        ProfilePackageIndexFrameWriter profpackgen;
+        DocPath filename = DocPaths.profileFrame(profileName);
+        try {
+            profpackgen = new ProfilePackageIndexFrameWriter(configuration, filename);
+            profpackgen.buildProfilePackagesIndexFile("doclet.Window_Overview", false, profileName);
+            profpackgen.close();
+        } catch (IOException exc) {
+            configuration.standardmessage.error(
+                        "doclet.exception_encountered",
+                        exc.toString(), filename);
+            throw new DocletAbortException();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void addProfilePackagesList(Profiles profiles, String text,
+            String tableSummary, Content body, String profileName) {
+        Content profNameContent = new StringContent(profileName);
+        Content heading = HtmlTree.HEADING(HtmlConstants.PACKAGE_HEADING, true,
+                getTargetProfileLink("classFrame", profNameContent, profileName));
+        heading.addContent(getSpace());
+        heading.addContent(packagesLabel);
+        Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
+        HtmlTree ul = new HtmlTree(HtmlTag.UL);
+        ul.addAttr(HtmlAttr.TITLE, packagesLabel.toString());
+        PackageDoc[] packages = configuration.profilePackages.get(profileName);
+        for (int i = 0; i < packages.length; i++) {
+            if ((!(configuration.nodeprecated && Util.isDeprecated(packages[i])))) {
+                ul.addContent(getPackage(packages[i], profileName));
+            }
+        }
+        div.addContent(ul);
+        body.addContent(div);
+    }
+
+    /**
+     * Gets each package name as a separate link.
+     *
+     * @param pd PackageDoc
+     * @param profileName the name of the profile being documented
+     * @return content for the package link
+     */
+    protected Content getPackage(PackageDoc pd, String profileName) {
+        Content packageLinkContent;
+        Content pkgLabel;
+        if (pd.name().length() > 0) {
+            pkgLabel = getPackageLabel(pd.name());
+            packageLinkContent = getHyperLink(pathString(pd,
+                     DocPaths.profilePackageFrame(profileName)), pkgLabel, "",
+                    "packageFrame");
+        } else {
+            pkgLabel = new RawHtml("&lt;unnamed package&gt;");
+            packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
+                    pkgLabel, "", "packageFrame");
+        }
+        Content li = HtmlTree.LI(packageLinkContent);
+        return li;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void addNavigationBarHeader(Content body) {
+        Content headerContent;
+        if (configuration.packagesheader.length() > 0) {
+            headerContent = new RawHtml(replaceDocRootDir(configuration.packagesheader));
+        } else {
+            headerContent = new RawHtml(replaceDocRootDir(configuration.header));
+        }
+        Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
+                HtmlStyle.bar, headerContent);
+        body.addContent(heading);
+    }
+
+    /**
+     * Do nothing as there is no overview information in this page.
+     */
+    protected void addOverviewHeader(Content body) {
+    }
+
+    protected void addProfilesList(Profiles profiles, String text,
+            String tableSummary, Content body) {
+    }
+
+    /**
+     * Adds "All Classes" link for the top of the left-hand frame page to the
+     * documentation tree.
+     *
+     * @param div the Content object to which the all classes link should be added
+     */
+    protected void addAllClassesLink(Content div) {
+        Content linkContent = getHyperLink(DocPaths.ALLCLASSES_FRAME,
+                allclassesLabel, "", "packageFrame");
+        Content span = HtmlTree.SPAN(linkContent);
+        div.addContent(span);
+    }
+
+    /**
+     * Adds "All Packages" link for the top of the left-hand frame page to the
+     * documentation tree.
+     *
+     * @param div the Content object to which the all packages link should be added
+     */
+    protected void addAllPackagesLink(Content div) {
+        Content linkContent = getHyperLink(DocPaths.OVERVIEW_FRAME,
+                allpackagesLabel, "", "profileListFrame");
+        Content span = HtmlTree.SPAN(linkContent);
+        div.addContent(span);
+    }
+
+    /**
+     * Adds "All Profiles" link for the top of the left-hand frame page to the
+     * documentation tree.
+     *
+     * @param div the Content object to which the all profiles link should be added
+     */
+    protected void addAllProfilesLink(Content div) {
+        Content linkContent = getHyperLink(DocPaths.PROFILE_OVERVIEW_FRAME,
+                allprofilesLabel, "", "profileListFrame");
+        Content span = HtmlTree.SPAN(linkContent);
+        div.addContent(span);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void addNavigationBarFooter(Content body) {
+        Content p = HtmlTree.P(getSpace());
+        body.addContent(p);
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java
new file mode 100644
index 0000000..1de03f4
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java
@@ -0,0 +1,296 @@
+/*
+ * 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.  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 com.sun.tools.doclets.formats.html;
+
+import java.io.*;
+import java.util.*;
+
+import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
+import com.sun.tools.doclets.formats.html.markup.*;
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.*;
+
+/**
+ * Class to generate file for each profile package contents in the right-hand
+ * frame. This will list all the Class Kinds in the package. A click on any
+ * class-kind will update the frame with the clicked class-kind page.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+public class ProfilePackageWriterImpl extends HtmlDocletWriter
+    implements ProfilePackageSummaryWriter {
+
+    /**
+     * The prev package name in the alpha-order list.
+     */
+    protected PackageDoc prev;
+
+    /**
+     * The next package name in the alpha-order list.
+     */
+    protected PackageDoc next;
+
+    /**
+     * The profile package being documented.
+     */
+    protected PackageDoc packageDoc;
+
+    /**
+     * The name of the profile being documented.
+     */
+    protected String profileName;
+
+    /**
+     * The value of the profile being documented.
+     */
+    protected int profileValue;
+
+    /**
+     * Constructor to construct ProfilePackageWriter object and to generate
+     * "profilename-package-summary.html" file in the respective package directory.
+     * For example for profile compact1 and package "java.lang" this will generate file
+     * "compact1-package-summary.html" file in the "java/lang" directory. It will also
+     * create "java/lang" directory in the current or the destination directory
+     * if it doesn't exist.
+     *
+     * @param configuration the configuration of the doclet.
+     * @param packageDoc    PackageDoc under consideration.
+     * @param prev          Previous package in the sorted array.
+     * @param next          Next package in the sorted array.
+     * @param profile       The profile being documented.
+     */
+    public ProfilePackageWriterImpl(ConfigurationImpl configuration,
+            PackageDoc packageDoc, PackageDoc prev, PackageDoc next,
+            Profile profile) throws IOException {
+        super(configuration, DocPath.forPackage(packageDoc).resolve(
+                DocPaths.profilePackageSummary(profile.name)));
+        this.prev = prev;
+        this.next = next;
+        this.packageDoc = packageDoc;
+        this.profileName = profile.name;
+        this.profileValue = profile.value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getPackageHeader(String heading) {
+        String pkgName = packageDoc.name();
+        Content bodyTree = getBody(true, getWindowTitle(pkgName));
+        addTop(bodyTree);
+        addNavLinks(true, bodyTree);
+        HtmlTree div = new HtmlTree(HtmlTag.DIV);
+        div.addStyle(HtmlStyle.header);
+        Content profileContent = new StringContent(profileName);
+        Content profileNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, profileContent);
+        div.addContent(profileNameDiv);
+        Content annotationContent = new HtmlTree(HtmlTag.P);
+        addAnnotationInfo(packageDoc, annotationContent);
+        div.addContent(annotationContent);
+        Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
+                HtmlStyle.title, packageLabel);
+        tHeading.addContent(getSpace());
+        Content packageHead = new RawHtml(heading);
+        tHeading.addContent(packageHead);
+        div.addContent(tHeading);
+        addDeprecationInfo(div);
+        if (packageDoc.inlineTags().length > 0 && ! configuration.nocomment) {
+            HtmlTree docSummaryDiv = new HtmlTree(HtmlTag.DIV);
+            docSummaryDiv.addStyle(HtmlStyle.docSummary);
+            addSummaryComment(packageDoc, docSummaryDiv);
+            div.addContent(docSummaryDiv);
+            Content space = getSpace();
+            Content descLink = getHyperLink(DocLink.fragment("package_description"),
+                    descriptionLabel, "", "");
+            Content descPara = new HtmlTree(HtmlTag.P, seeLabel, space, descLink);
+            div.addContent(descPara);
+        }
+        bodyTree.addContent(div);
+        return bodyTree;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getContentHeader() {
+        HtmlTree div = new HtmlTree(HtmlTag.DIV);
+        div.addStyle(HtmlStyle.contentContainer);
+        return div;
+    }
+
+    /**
+     * Add the package deprecation information to the documentation tree.
+     *
+     * @param div the content tree to which the deprecation information will be added
+     */
+    public void addDeprecationInfo(Content div) {
+        Tag[] deprs = packageDoc.tags("deprecated");
+        if (Util.isDeprecated(packageDoc)) {
+            HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
+            deprDiv.addStyle(HtmlStyle.deprecatedContent);
+            Content deprPhrase = HtmlTree.SPAN(HtmlStyle.strong, deprecatedPhrase);
+            deprDiv.addContent(deprPhrase);
+            if (deprs.length > 0) {
+                Tag[] commentTags = deprs[0].inlineTags();
+                if (commentTags.length > 0) {
+                    addInlineDeprecatedComment(packageDoc, deprs[0], deprDiv);
+                }
+            }
+            div.addContent(deprDiv);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addClassesSummary(ClassDoc[] classes, String label,
+            String tableSummary, String[] tableHeader, Content packageSummaryContentTree) {
+        addClassesSummary(classes, label, tableSummary, tableHeader,
+                packageSummaryContentTree, profileValue);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getSummaryHeader() {
+        HtmlTree ul = new HtmlTree(HtmlTag.UL);
+        ul.addStyle(HtmlStyle.blockList);
+        return ul;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addPackageDescription(Content packageContentTree) {
+        if (packageDoc.inlineTags().length > 0) {
+            packageContentTree.addContent(getMarkerAnchor("package_description"));
+            Content h2Content = new StringContent(
+                    configuration.getText("doclet.Package_Description",
+                    packageDoc.name()));
+            packageContentTree.addContent(HtmlTree.HEADING(HtmlConstants.PACKAGE_HEADING,
+                    true, h2Content));
+            addInlineComment(packageDoc, packageContentTree);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addPackageTags(Content packageContentTree) {
+        addTagsInfo(packageDoc, packageContentTree);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addPackageFooter(Content contentTree) {
+        addNavLinks(false, contentTree);
+        addBottom(contentTree);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void printDocument(Content contentTree) throws IOException {
+        printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageDoc),
+                true, contentTree);
+    }
+
+    /**
+     * Get "Use" link for this package in the navigation bar.
+     *
+     * @return a content tree for the class use link
+     */
+    protected Content getNavLinkClassUse() {
+        Content useLink = getHyperLink(DocPaths.PACKAGE_USE,
+                useLabel, "", "");
+        Content li = HtmlTree.LI(useLink);
+        return li;
+    }
+
+    /**
+     * Get "PREV PACKAGE" link in the navigation bar.
+     *
+     * @return a content tree for the previous link
+     */
+    public Content getNavLinkPrevious() {
+        Content li;
+        if (prev == null) {
+            li = HtmlTree.LI(prevpackageLabel);
+        } else {
+            DocPath path = DocPath.relativePath(packageDoc, prev);
+            li = HtmlTree.LI(getHyperLink(path.resolve(DocPaths.profilePackageSummary(profileName)),
+                prevpackageLabel, "", ""));
+        }
+        return li;
+    }
+
+    /**
+     * Get "NEXT PACKAGE" link in the navigation bar.
+     *
+     * @return a content tree for the next link
+     */
+    public Content getNavLinkNext() {
+        Content li;
+        if (next == null) {
+            li = HtmlTree.LI(nextpackageLabel);
+        } else {
+            DocPath path = DocPath.relativePath(packageDoc, next);
+            li = HtmlTree.LI(getHyperLink(path.resolve(DocPaths.profilePackageSummary(profileName)),
+                nextpackageLabel, "", ""));
+        }
+        return li;
+    }
+
+    /**
+     * Get "Tree" link in the navigation bar. This will be link to the package
+     * tree file.
+     *
+     * @return a content tree for the tree link
+     */
+    protected Content getNavLinkTree() {
+        Content useLink = getHyperLink(DocPaths.PACKAGE_TREE,
+                treeLabel, "", "");
+        Content li = HtmlTree.LI(useLink);
+        return li;
+    }
+
+    /**
+     * Highlight "Package" in the navigation bar, as this is the package page.
+     *
+     * @return a content tree for the package link
+     */
+    protected Content getNavLinkPackage() {
+        Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, packageLabel);
+        return li;
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java
new file mode 100644
index 0000000..5dae2e9
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java
@@ -0,0 +1,208 @@
+/*
+ * 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.  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 com.sun.tools.doclets.formats.html;
+
+import java.io.*;
+import java.util.*;
+
+import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
+import com.sun.tools.doclets.formats.html.markup.*;
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.*;
+
+/**
+ * Class to generate file for each profile contents in the right-hand
+ * frame. This will list all the packages and Class Kinds in the profile. A click on any
+ * class-kind will update the frame with the clicked class-kind page. A click on any
+ * package will update the frame with the clicked profile package page.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+public class ProfileWriterImpl extends HtmlDocletWriter
+    implements ProfileSummaryWriter {
+
+    /**
+     * The prev profile name in the alpha-order list.
+     */
+    protected Profile prevProfile;
+
+    /**
+     * The next profile name in the alpha-order list.
+     */
+    protected Profile nextProfile;
+
+    /**
+     * The profile being documented.
+     */
+    protected Profile profile;
+
+    /**
+     * Constructor to construct ProfileWriter object and to generate
+     * "profileName-summary.html" file.
+     *
+     * @param configuration the configuration of the doclet.
+     * @param profile       Profile under consideration.
+     * @param prevProfile   Previous profile in the sorted array.
+     * @param nextProfile   Next profile in the sorted array.
+     */
+    public ProfileWriterImpl(ConfigurationImpl configuration,
+            Profile profile, Profile prevProfile, Profile nextProfile)
+            throws IOException {
+        super(configuration, DocPaths.profileSummary(profile.name));
+        this.prevProfile = prevProfile;
+        this.nextProfile = nextProfile;
+        this.profile = profile;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getProfileHeader(String heading) {
+        String profileName = profile.name;
+        Content bodyTree = getBody(true, getWindowTitle(profileName));
+        addTop(bodyTree);
+        addNavLinks(true, bodyTree);
+        HtmlTree div = new HtmlTree(HtmlTag.DIV);
+        div.addStyle(HtmlStyle.header);
+        Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
+                HtmlStyle.title, profileLabel);
+        tHeading.addContent(getSpace());
+        Content profileHead = new RawHtml(heading);
+        tHeading.addContent(profileHead);
+        div.addContent(tHeading);
+        bodyTree.addContent(div);
+        return bodyTree;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getContentHeader() {
+        HtmlTree div = new HtmlTree(HtmlTag.DIV);
+        div.addStyle(HtmlStyle.contentContainer);
+        return div;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getSummaryHeader() {
+        HtmlTree li = new HtmlTree(HtmlTag.LI);
+        li.addStyle(HtmlStyle.blockList);
+        return li;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getSummaryTree(Content summaryContentTree) {
+        HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, summaryContentTree);
+        HtmlTree div = HtmlTree.DIV(HtmlStyle.summary, ul);
+        return div;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getPackageSummaryHeader(PackageDoc pkg) {
+        Content pkgName = getTargetProfilePackageLink(pkg,
+                    "classFrame", new StringContent(pkg.name()), profile.name);
+        Content heading = HtmlTree.HEADING(HtmlTag.H3, pkgName);
+        HtmlTree li = HtmlTree.LI(HtmlStyle.blockList, heading);
+        return li;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Content getPackageSummaryTree(Content packageSummaryContentTree) {
+        HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, packageSummaryContentTree);
+        return ul;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addClassesSummary(ClassDoc[] classes, String label,
+            String tableSummary, String[] tableHeader, Content packageSummaryContentTree) {
+        addClassesSummary(classes, label, tableSummary, tableHeader,
+                packageSummaryContentTree, profile.value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addProfileFooter(Content contentTree) {
+        addNavLinks(false, contentTree);
+        addBottom(contentTree);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void printDocument(Content contentTree) throws IOException {
+        printHtmlDocument(configuration.metakeywords.getMetaKeywords(profile),
+                true, contentTree);
+    }
+
+    /**
+     * Get "PREV PROFILE" link in the navigation bar.
+     *
+     * @return a content tree for the previous link
+     */
+    public Content getNavLinkPrevious() {
+        Content li;
+        if (prevProfile == null) {
+            li = HtmlTree.LI(prevprofileLabel);
+        } else {
+            li = HtmlTree.LI(getHyperLink(pathToRoot.resolve(DocPaths.profileSummary(
+                    prevProfile.name)), prevprofileLabel, "", ""));
+        }
+        return li;
+    }
+
+    /**
+     * Get "NEXT PROFILE" link in the navigation bar.
+     *
+     * @return a content tree for the next link
+     */
+    public Content getNavLinkNext() {
+        Content li;
+        if (nextProfile == null) {
+            li = HtmlTree.LI(nextprofileLabel);
+        } else {
+            li = HtmlTree.LI(getHyperLink(pathToRoot.resolve(DocPaths.profileSummary(
+                    nextProfile.name)), nextprofileLabel, "", ""));
+        }
+        return li;
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java
index 874e1fa..7cbd329 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -28,6 +28,7 @@
 import java.io.IOException;
 
 import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
@@ -69,6 +70,24 @@
     /**
      * {@inheritDoc}
      */
+    public ProfileSummaryWriter getProfileSummaryWriter(Profile profile,
+        Profile prevProfile, Profile nextProfile) throws Exception {
+        return new ProfileWriterImpl(configuration, profile,
+            prevProfile, nextProfile);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ProfilePackageSummaryWriter getProfilePackageSummaryWriter(PackageDoc packageDoc,
+        PackageDoc prevPkg, PackageDoc nextPkg, Profile profile) throws Exception {
+        return new ProfilePackageWriterImpl(configuration, packageDoc,
+            prevPkg, nextPkg, profile);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public ClassWriter getClassWriter(ClassDoc classDoc, ClassDoc prevClass,
             ClassDoc nextClass, ClassTree classTree) throws IOException {
         return new ClassWriterImpl(configuration, classDoc,
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java
index 8b4b400..9830976 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -168,6 +168,11 @@
     public static final HtmlTag PACKAGE_HEADING = HtmlTag.H2;
 
     /**
+     * Html tag for the profile name heading.
+     */
+    public static final HtmlTag PROFILE_HEADING = HtmlTag.H2;
+
+    /**
      * Html tag for the member summary heading.
      */
     public static final HtmlTag SUMMARY_HEADING = HtmlTag.H3;
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
index 01238cf..915b37c 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -63,6 +63,11 @@
     protected boolean memberDetailsListPrinted;
 
     /**
+     * Header for table displaying profiles and description..
+     */
+    protected final String[] profileTableHeader;
+
+    /**
      * Header for tables displaying packages and description..
      */
     protected final String[] packageTableHeader;
@@ -83,6 +88,8 @@
 
     public final Content packageLabel;
 
+    public final Content profileLabel;
+
     public final Content useLabel;
 
     public final Content prevLabel;
@@ -111,6 +118,10 @@
 
     public final Content allclassesLabel;
 
+    public final Content allpackagesLabel;
+
+    public final Content allprofilesLabel;
+
     public final Content indexLabel;
 
     public final Content helpLabel;
@@ -123,8 +134,14 @@
 
     public final Content nextpackageLabel;
 
+    public final Content prevprofileLabel;
+
+    public final Content nextprofileLabel;
+
     public final Content packagesLabel;
 
+    public final Content profilesLabel;
+
     public final Content methodDetailsLabel;
 
     public final Content annotationTypeDetailsLabel;
@@ -162,6 +179,10 @@
         writer = DocFile.createFileForOutput(configuration, path).openWriter();
         this.configuration = configuration;
         this.memberDetailsListPrinted = false;
+        profileTableHeader = new String[] {
+            configuration.getText("doclet.Profile"),
+            configuration.getText("doclet.Description")
+        };
         packageTableHeader = new String[] {
             configuration.getText("doclet.Package"),
             configuration.getText("doclet.Description")
@@ -175,6 +196,7 @@
         defaultPackageLabel = new RawHtml(
                 DocletConstants.DEFAULT_PACKAGE_NAME);
         packageLabel = getResource("doclet.Package");
+        profileLabel = getResource("doclet.Profile");
         useLabel = getResource("doclet.navClassUse");
         prevLabel = getResource("doclet.Prev");
         nextLabel = getResource("doclet.Next");
@@ -189,13 +211,18 @@
         deprecatedLabel = getResource("doclet.navDeprecated");
         deprecatedPhrase = getResource("doclet.Deprecated");
         allclassesLabel = getResource("doclet.All_Classes");
+        allpackagesLabel = getResource("doclet.All_Packages");
+        allprofilesLabel = getResource("doclet.All_Profiles");
         indexLabel = getResource("doclet.Index");
         helpLabel = getResource("doclet.Help");
         seeLabel = getResource("doclet.See");
         descriptionLabel = getResource("doclet.Description");
         prevpackageLabel = getResource("doclet.Prev_Package");
         nextpackageLabel = getResource("doclet.Next_Package");
+        prevprofileLabel = getResource("doclet.Prev_Profile");
+        nextprofileLabel = getResource("doclet.Next_Profile");
         packagesLabel = getResource("doclet.Packages");
+        profilesLabel = getResource("doclet.Profiles");
         methodDetailsLabel = getResource("doclet.Method_Detail");
         annotationTypeDetailsLabel = getResource("doclet.Annotation_Type_Member_Detail");
         fieldDetailsLabel = getResource("doclet.Field_Detail");
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
index 7e6df8b..f36f7cf 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
@@ -4,7 +4,9 @@
 doclet.Window_Overview=Overview List
 doclet.Window_Overview_Summary=Overview
 doclet.Package=Package
+doclet.Profile=Profile
 doclet.All_Packages=All Packages
+doclet.All_Profiles=All Profiles
 doclet.Tree=Tree
 doclet.Class_Hierarchy=Class Hierarchy
 doclet.Window_Class_Hierarchy=Class Hierarchy
@@ -17,6 +19,8 @@
 doclet.Next_Class=Next Class
 doclet.Prev_Package=Prev Package
 doclet.Next_Package=Next Package
+doclet.Prev_Profile=Prev Profile
+doclet.Next_Profile=Next Profile
 doclet.Prev_Letter=Prev Letter
 doclet.Next_Letter=Next Letter
 doclet.Href_Class_Title=class in {0}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java
index 388c070..fd398aa 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -28,8 +28,6 @@
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.builders.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
-import java.io.File;
-import java.util.StringTokenizer;
 
 /**
  * An abstract implementation of a Doclet.
@@ -128,6 +126,7 @@
 
         PackageListWriter.generate(configuration);
         generatePackageFiles(classtree);
+        generateProfileFiles();
 
         generateOtherFiles(root, classtree);
         configuration.tagletManager.printReport();
@@ -148,6 +147,12 @@
     }
 
     /**
+     * Generate the profile documentation.
+     *
+     */
+    protected abstract void generateProfileFiles() throws Exception;
+
+    /**
      * Generate the package documentation.
      *
      * @param classtree the data structure representing the class tree.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
index 2d869df..f393c8d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
@@ -29,6 +29,8 @@
 import java.util.*;
 
 import com.sun.javadoc.*;
+import com.sun.tools.javac.sym.Profiles;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.doclets.internal.toolkit.builders.BuilderFactory;
 import com.sun.tools.doclets.internal.toolkit.taglets.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -188,6 +190,17 @@
     public String sourcepath = "";
 
     /**
+     * Argument for command line option "-Xprofilespath".
+     */
+    public String profilespath = "";
+
+    /**
+     * Generate profiles documentation if profilespath is set and valid profiles
+     * are present.
+     */
+    public boolean showProfiles = false;
+
+    /**
      * Don't generate deprecated API information at all, if -nodeprecated
      * option is used. <code>nodepracted</code> is set to true if
      * -nodeprecated option is used. Default is generate deprected API
@@ -247,6 +260,16 @@
     public abstract MessageRetriever getDocletSpecificMsg();
 
     /**
+     * A profiles object used to access profiles across various pages.
+     */
+    public Profiles profiles;
+
+    /**
+     * An map of the profiles to packages.
+     */
+    public Map<String,PackageDoc[]> profilePackages;
+
+    /**
      * An array of the packages specified on the command-line merged
      * with the array of packages that contain the classes specified on the
      * command-line.  The array is sorted.
@@ -315,7 +338,8 @@
                    option.equals("-sourcepath") ||
                    option.equals("-tag") ||
                    option.equals("-taglet") ||
-                   option.equals("-tagletpath")) {
+                   option.equals("-tagletpath") ||
+                   option.equals("-xprofilespath")) {
             return 2;
         } else if (option.equals("-group") ||
                    option.equals("-linkoffline")) {
@@ -334,6 +358,38 @@
     public abstract boolean validOptions(String options[][],
         DocErrorReporter reporter);
 
+    private void initProfiles() throws IOException {
+        profiles = Profiles.read(new File(profilespath));
+        // Generate profiles documentation only is profilespath is set and if
+        // profiles is not null and profiles count is 1 or more.
+        showProfiles = (!profilespath.isEmpty() && profiles != null &&
+                profiles.getProfileCount() > 0);
+    }
+
+    private void initProfilePackages() throws IOException {
+        profilePackages = new HashMap<String,PackageDoc[]>();
+        ArrayList<PackageDoc> results;
+        Map<String,PackageDoc> packageIndex = new HashMap<String,PackageDoc>();
+        for (int i = 0; i < packages.length; i++) {
+            PackageDoc pkg = packages[i];
+            packageIndex.put(pkg.name(), pkg);
+        }
+        for (int i = 1; i < profiles.getProfileCount(); i++) {
+            Set<String> profPkgs = profiles.getPackages(i);
+            results = new ArrayList<PackageDoc>();
+            for (String packageName : profPkgs) {
+                packageName = packageName.replace("/", ".");
+                PackageDoc profPkg = packageIndex.get(packageName);
+                if (profPkg != null) {
+                    results.add(profPkg);
+                }
+            }
+            Collections.sort(results);
+            PackageDoc[] profilePkgs = results.toArray(new PackageDoc[]{});
+            profilePackages.put(Profile.lookup(i).name, profilePkgs);
+        }
+    }
+
     private void initPackageArray() {
         Set<PackageDoc> set = new HashSet<PackageDoc>(Arrays.asList(root.specifiedPackages()));
         ClassDoc[] classes = root.specifiedClasses();
@@ -404,6 +460,8 @@
                 customTagStrs.add(os);
             } else if (opt.equals("-tagletpath")) {
                 tagletpath = os[1];
+            }  else if (opt.equals("-xprofilespath")) {
+                profilespath = os[1];
             } else if (opt.equals("-keywords")) {
                 keywords = true;
             } else if (opt.equals("-serialwarn")) {
@@ -439,6 +497,14 @@
     public void setOptions() {
         initPackageArray();
         setOptions(root.options());
+        if (!profilespath.isEmpty()) {
+            try {
+                initProfiles();
+                initProfilePackages();
+            } catch (Exception e) {
+                throw new DocletAbortException();
+            }
+        }
         setSpecificDocletOptions(root.options());
     }
 
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/ProfilePackageSummaryWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/ProfilePackageSummaryWriter.java
new file mode 100644
index 0000000..55c9762
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/ProfilePackageSummaryWriter.java
@@ -0,0 +1,116 @@
+/*
+ * 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.  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 com.sun.tools.doclets.internal.toolkit;
+
+import java.io.*;
+
+import com.sun.javadoc.*;
+
+/**
+ * The interface for writing profile package summary output.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+
+public interface ProfilePackageSummaryWriter {
+
+    /**
+     * Get the header for the summary.
+     *
+     * @param heading Package name.
+     * @return the header to be added to the content tree
+     */
+    public abstract Content getPackageHeader(String heading);
+
+    /**
+     * Get the header for the content.
+     *
+     * @return a content tree for the content header
+     */
+    public abstract Content getContentHeader();
+
+    /**
+     * Get the header for the package summary.
+     *
+     * @return a content tree with the package summary header
+     */
+    public abstract Content getSummaryHeader();
+
+    /**
+     * Adds the table of classes to the documentation tree.
+     *
+     * @param classes the array of classes to document.
+     * @param label the label for this table.
+     * @param tableSummary the summary string for the table
+     * @param tableHeader array of table headers
+     * @param summaryContentTree the content tree to which the summaries will be added
+     */
+    public abstract void addClassesSummary(ClassDoc[] classes, String label,
+            String tableSummary, String[] tableHeader, Content summaryContentTree);
+
+    /**
+     * Adds the package description from the "packages.html" file to the documentation
+     * tree.
+     *
+     * @param packageContentTree the content tree to which the package description
+     *                           will be added
+     */
+    public abstract void addPackageDescription(Content packageContentTree);
+
+    /**
+     * Adds the tag information from the "packages.html" file to the documentation
+     * tree.
+     *
+     * @param packageContentTree the content tree to which the package tags will
+     *                           be added
+     */
+    public abstract void addPackageTags(Content packageContentTree);
+
+    /**
+     * Adds the footer to the documentation tree.
+     *
+     * @param contentTree the tree to which the footer will be added
+     */
+    public abstract void addPackageFooter(Content contentTree);
+
+    /**
+     * Print the package summary document.
+     *
+     * @param contentTree the content tree that will be printed
+     */
+    public abstract void printDocument(Content contentTree) throws IOException;
+
+    /**
+     * Close the writer.
+     */
+    public abstract void close() throws IOException;
+
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/ProfileSummaryWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/ProfileSummaryWriter.java
new file mode 100644
index 0000000..d3a8682
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/ProfileSummaryWriter.java
@@ -0,0 +1,120 @@
+/*
+ * 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.  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 com.sun.tools.doclets.internal.toolkit;
+
+import java.io.*;
+
+import com.sun.javadoc.*;
+
+/**
+ * The interface for writing profile summary output.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+
+public interface ProfileSummaryWriter {
+
+    /**
+     * Get the header for the summary.
+     *
+     * @param heading profile name.
+     * @return the header to be added to the content tree
+     */
+    public abstract Content getProfileHeader(String heading);
+
+    /**
+     * Get the header for the profile content.
+     *
+     * @return a content tree for the profile content header
+     */
+    public abstract Content getContentHeader();
+
+    /**
+     * Get the header for the summary header.
+     *
+     * @return a content tree with the summary header
+     */
+    public abstract Content getSummaryHeader();
+
+    /**
+     * Get the header for the summary tree.
+     *
+     * @param summaryContentTree the content tree.
+     * @return a content tree with the summary tree
+     */
+    public abstract Content getSummaryTree(Content summaryContentTree);
+
+    /**
+     * Get the header for the package summary header.
+     *
+     * @return a content tree with the package summary header
+     */
+    public abstract Content getPackageSummaryHeader(PackageDoc pkg);
+
+    /**
+     * Get the header for the package summary tree.
+     *
+     * @return a content tree with the package summary
+     */
+    public abstract Content getPackageSummaryTree(Content packageSummaryContentTree);
+
+    /**
+     * Adds the table of classes to the documentation tree.
+     *
+     * @param classes the array of classes to document.
+     * @param label the label for this table.
+     * @param tableSummary the summary string for the table
+     * @param tableHeader array of table headers
+     * @param packageSummaryContentTree the content tree to which the summaries will be added
+     */
+    public abstract void addClassesSummary(ClassDoc[] classes, String label,
+            String tableSummary, String[] tableHeader, Content packageSummaryContentTree);
+
+    /**
+     * Adds the footer to the documentation tree.
+     *
+     * @param contentTree the tree to which the footer will be added
+     */
+    public abstract void addProfileFooter(Content contentTree);
+
+    /**
+     * Print the profile summary document.
+     *
+     * @param contentTree the content tree that will be printed
+     */
+    public abstract void printDocument(Content contentTree) throws IOException;
+
+    /**
+     * Close the writer.
+     */
+    public abstract void close() throws IOException;
+
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java
index 6c2fb5b..123a3ad 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -26,6 +26,7 @@
 package com.sun.tools.doclets.internal.toolkit;
 
 import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
 /**
@@ -65,6 +66,33 @@
     throws Exception;
 
     /**
+     * Return the writer for the profile summary.
+     *
+     * @param profile the profile being documented.
+     * @param prevProfile the previous profile that was documented.
+     * @param nextProfile the next profile being documented.
+     * @return the writer for the profile summary.  Return null if this
+     * writer is not supported by the doclet.
+     */
+    public abstract ProfileSummaryWriter getProfileSummaryWriter(Profile
+        profile, Profile prevProfile, Profile nextProfile)
+    throws Exception;
+
+    /**
+     * Return the writer for the profile package summary.
+     *
+     * @param packageDoc the profile package being documented.
+     * @param prevPkg the previous profile package that was documented.
+     * @param nextPkg the next profile package being documented.
+     * @param profile the profile being documented.
+     * @return the writer for the profile package summary.  Return null if this
+     * writer is not supported by the doclet.
+     */
+    public abstract ProfilePackageSummaryWriter getProfilePackageSummaryWriter(
+            PackageDoc packageDoc, PackageDoc prevPkg, PackageDoc nextPkg,
+            Profile profile) throws Exception;
+
+    /**
      * Return the writer for a class.
      *
      * @param classDoc the class being documented.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java
index 1936c72a..c99349d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -29,6 +29,7 @@
 import java.util.Set;
 
 import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
 
@@ -96,6 +97,36 @@
     }
 
     /**
+     * Return the builder that builds the profile summary.
+     *
+     * @param profile the profile being documented.
+     * @param prevProfile the previous profile being documented.
+     * @param nextProfile the next profile being documented.
+     * @return the builder that builds the profile summary.
+     */
+    public AbstractBuilder getProfileSummaryBuilder(Profile profile, Profile prevProfile,
+            Profile nextProfile) throws Exception {
+        return ProfileSummaryBuilder.getInstance(context, profile,
+            writerFactory.getProfileSummaryWriter(profile, prevProfile, nextProfile));
+    }
+
+    /**
+     * Return the builder that builds the profile package summary.
+     *
+     * @param pkg the profile package being documented.
+     * @param prevPkg the previous profile package being documented.
+     * @param nextPkg the next profile package being documented.
+     * @param profile the profile being documented.
+     * @return the builder that builds the profile package summary.
+     */
+    public AbstractBuilder getProfilePackageSummaryBuilder(PackageDoc pkg, PackageDoc prevPkg,
+            PackageDoc nextPkg, Profile profile) throws Exception {
+        return ProfilePackageSummaryBuilder.getInstance(context, pkg,
+            writerFactory.getProfilePackageSummaryWriter(pkg, prevPkg, nextPkg,
+                profile), profile);
+    }
+
+    /**
      * Return the builder for the class.
      *
      * @param classDoc the class being documented.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfilePackageSummaryBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfilePackageSummaryBuilder.java
new file mode 100644
index 0000000..98ae55d
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfilePackageSummaryBuilder.java
@@ -0,0 +1,374 @@
+/*
+ * 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.  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 com.sun.tools.doclets.internal.toolkit.builders;
+
+import java.io.*;
+
+import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.*;
+
+/**
+ * Builds the summary for a given profile package.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+public class ProfilePackageSummaryBuilder extends AbstractBuilder {
+    /**
+     * The root element of the profile package summary XML is {@value}.
+     */
+    public static final String ROOT = "PackageDoc";
+
+    /**
+     * The profile package being documented.
+     */
+    private final PackageDoc packageDoc;
+
+    /**
+     * The name of the profile being documented.
+     */
+    private final String profileName;
+
+    /**
+     * The value of the profile being documented.
+     */
+    private final int profileValue;
+
+    /**
+     * The doclet specific writer that will output the result.
+     */
+    private final ProfilePackageSummaryWriter profilePackageWriter;
+
+    /**
+     * The content that will be added to the profile package summary documentation tree.
+     */
+    private Content contentTree;
+
+    /**
+     * Construct a new ProfilePackageSummaryBuilder.
+     *
+     * @param context  the build context.
+     * @param pkg the profile package being documented.
+     * @param profilePackageWriter the doclet specific writer that will output the
+     *        result.
+     * @param profile the profile being documented.
+     */
+    private ProfilePackageSummaryBuilder(Context context,
+            PackageDoc pkg, ProfilePackageSummaryWriter profilePackageWriter,
+            Profile profile) {
+        super(context);
+        this.packageDoc = pkg;
+        this.profilePackageWriter = profilePackageWriter;
+        this.profileName = profile.name;
+        this.profileValue = profile.value;
+    }
+
+    /**
+     * Construct a new ProfilePackageSummaryBuilder.
+     *
+     * @param context  the build context.
+     * @param pkg the profile package being documented.
+     * @param profilePackageWriter the doclet specific writer that will output the
+     *        result.
+     * @param profile the profile being documented.
+     *
+     * @return an instance of a ProfilePackageSummaryBuilder.
+     */
+    public static ProfilePackageSummaryBuilder getInstance(Context context,
+            PackageDoc pkg, ProfilePackageSummaryWriter profilePackageWriter,
+            Profile profile) {
+        return new ProfilePackageSummaryBuilder(context, pkg, profilePackageWriter,
+                profile);
+    }
+
+    /**
+     * Build the profile package summary.
+     */
+    public void build() throws IOException {
+        if (profilePackageWriter == null) {
+            //Doclet does not support this output.
+            return;
+        }
+        build(layoutParser.parseXML(ROOT), contentTree);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getName() {
+        return ROOT;
+    }
+
+    /**
+     * Build the profile package documentation.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param contentTree the content tree to which the documentation will be added
+     */
+    public void buildPackageDoc(XMLNode node, Content contentTree) throws Exception {
+        contentTree = profilePackageWriter.getPackageHeader(
+                Util.getPackageName(packageDoc));
+        buildChildren(node, contentTree);
+        profilePackageWriter.addPackageFooter(contentTree);
+        profilePackageWriter.printDocument(contentTree);
+        profilePackageWriter.close();
+        Util.copyDocFiles(configuration, packageDoc);
+    }
+
+    /**
+     * Build the content for the profile package doc.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param contentTree the content tree to which the package contents
+     *                    will be added
+     */
+    public void buildContent(XMLNode node, Content contentTree) {
+        Content packageContentTree = profilePackageWriter.getContentHeader();
+        buildChildren(node, packageContentTree);
+        contentTree.addContent(packageContentTree);
+    }
+
+    /**
+     * Build the profile package summary.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageContentTree the package content tree to which the summaries will
+     *                           be added
+     */
+    public void buildSummary(XMLNode node, Content packageContentTree) {
+        Content summaryContentTree = profilePackageWriter.getSummaryHeader();
+        buildChildren(node, summaryContentTree);
+        packageContentTree.addContent(summaryContentTree);
+    }
+
+    /**
+     * Build the summary for the interfaces in this package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param summaryContentTree the summary tree to which the interface summary
+     *                           will be added
+     */
+    public void buildInterfaceSummary(XMLNode node, Content summaryContentTree) {
+        String interfaceTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Interface_Summary"),
+                configuration.getText("doclet.interfaces"));
+        String[] interfaceTableHeader = new String[] {
+            configuration.getText("doclet.Interface"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] interfaces =
+                packageDoc.isIncluded()
+                        ? packageDoc.interfaces()
+                        : configuration.classDocCatalog.interfaces(
+                                Util.getPackageName(packageDoc));
+        if (interfaces.length > 0) {
+            profilePackageWriter.addClassesSummary(
+                    interfaces,
+                    configuration.getText("doclet.Interface_Summary"),
+                    interfaceTableSummary, interfaceTableHeader, summaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the classes in this package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param summaryContentTree the summary tree to which the class summary will
+     *                           be added
+     */
+    public void buildClassSummary(XMLNode node, Content summaryContentTree) {
+        String classTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Class_Summary"),
+                configuration.getText("doclet.classes"));
+        String[] classTableHeader = new String[] {
+            configuration.getText("doclet.Class"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] classes =
+                packageDoc.isIncluded()
+                        ? packageDoc.ordinaryClasses()
+                        : configuration.classDocCatalog.ordinaryClasses(
+                                Util.getPackageName(packageDoc));
+        if (classes.length > 0) {
+            profilePackageWriter.addClassesSummary(
+                    classes,
+                    configuration.getText("doclet.Class_Summary"),
+                    classTableSummary, classTableHeader, summaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the enums in this package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param summaryContentTree the summary tree to which the enum summary will
+     *                           be added
+     */
+    public void buildEnumSummary(XMLNode node, Content summaryContentTree) {
+        String enumTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Enum_Summary"),
+                configuration.getText("doclet.enums"));
+        String[] enumTableHeader = new String[] {
+            configuration.getText("doclet.Enum"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] enums =
+                packageDoc.isIncluded()
+                        ? packageDoc.enums()
+                        : configuration.classDocCatalog.enums(
+                                Util.getPackageName(packageDoc));
+        if (enums.length > 0) {
+            profilePackageWriter.addClassesSummary(
+                    enums,
+                    configuration.getText("doclet.Enum_Summary"),
+                    enumTableSummary, enumTableHeader, summaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the exceptions in this package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param summaryContentTree the summary tree to which the exception summary will
+     *                           be added
+     */
+    public void buildExceptionSummary(XMLNode node, Content summaryContentTree) {
+        String exceptionTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Exception_Summary"),
+                configuration.getText("doclet.exceptions"));
+        String[] exceptionTableHeader = new String[] {
+            configuration.getText("doclet.Exception"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] exceptions =
+                packageDoc.isIncluded()
+                        ? packageDoc.exceptions()
+                        : configuration.classDocCatalog.exceptions(
+                                Util.getPackageName(packageDoc));
+        if (exceptions.length > 0) {
+            profilePackageWriter.addClassesSummary(
+                    exceptions,
+                    configuration.getText("doclet.Exception_Summary"),
+                    exceptionTableSummary, exceptionTableHeader, summaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the errors in this package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param summaryContentTree the summary tree to which the error summary will
+     *                           be added
+     */
+    public void buildErrorSummary(XMLNode node, Content summaryContentTree) {
+        String errorTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Error_Summary"),
+                configuration.getText("doclet.errors"));
+        String[] errorTableHeader = new String[] {
+            configuration.getText("doclet.Error"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] errors =
+                packageDoc.isIncluded()
+                        ? packageDoc.errors()
+                        : configuration.classDocCatalog.errors(
+                                Util.getPackageName(packageDoc));
+        if (errors.length > 0) {
+            profilePackageWriter.addClassesSummary(
+                    errors,
+                    configuration.getText("doclet.Error_Summary"),
+                    errorTableSummary, errorTableHeader, summaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the annotation type in this package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param summaryContentTree the summary tree to which the annotation type
+     *                           summary will be added
+     */
+    public void buildAnnotationTypeSummary(XMLNode node, Content summaryContentTree) {
+        String annotationtypeTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Annotation_Types_Summary"),
+                configuration.getText("doclet.annotationtypes"));
+        String[] annotationtypeTableHeader = new String[] {
+            configuration.getText("doclet.AnnotationType"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] annotationTypes =
+                packageDoc.isIncluded()
+                        ? packageDoc.annotationTypes()
+                        : configuration.classDocCatalog.annotationTypes(
+                                Util.getPackageName(packageDoc));
+        if (annotationTypes.length > 0) {
+            profilePackageWriter.addClassesSummary(
+                    annotationTypes,
+                    configuration.getText("doclet.Annotation_Types_Summary"),
+                    annotationtypeTableSummary, annotationtypeTableHeader,
+                    summaryContentTree);
+        }
+    }
+
+    /**
+     * Build the description of the summary.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageContentTree the tree to which the package description will
+     *                           be added
+     */
+    public void buildPackageDescription(XMLNode node, Content packageContentTree) {
+        if (configuration.nocomment) {
+            return;
+        }
+        profilePackageWriter.addPackageDescription(packageContentTree);
+    }
+
+    /**
+     * Build the tags of the summary.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageContentTree the tree to which the package tags will be added
+     */
+    public void buildPackageTags(XMLNode node, Content packageContentTree) {
+        if (configuration.nocomment) {
+            return;
+        }
+        profilePackageWriter.addPackageTags(packageContentTree);
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfileSummaryBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfileSummaryBuilder.java
new file mode 100644
index 0000000..57cf323
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfileSummaryBuilder.java
@@ -0,0 +1,328 @@
+/*
+ * 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.  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 com.sun.tools.doclets.internal.toolkit.builders;
+
+import java.io.*;
+
+import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.*;
+
+/**
+ * Builds the summary for a given profile.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
+ * @author Bhavesh Patel
+ */
+public class ProfileSummaryBuilder extends AbstractBuilder {
+    /**
+     * The root element of the profile summary XML is {@value}.
+     */
+    public static final String ROOT = "ProfileDoc";
+
+    /**
+     * The profile being documented.
+     */
+    private final Profile profile;
+
+    /**
+     * The doclet specific writer that will output the result.
+     */
+    private final ProfileSummaryWriter profileWriter;
+
+    /**
+     * The content that will be added to the profile summary documentation tree.
+     */
+    private Content contentTree;
+
+    /**
+     * The profile package being documented.
+     */
+    private PackageDoc pkg;
+
+    /**
+     * Construct a new ProfileSummaryBuilder.
+     *
+     * @param context  the build context.
+     * @param profile the profile being documented.
+     * @param profileWriter the doclet specific writer that will output the
+     *        result.
+     */
+    private ProfileSummaryBuilder(Context context,
+            Profile profile, ProfileSummaryWriter profileWriter) {
+        super(context);
+        this.profile = profile;
+        this.profileWriter = profileWriter;
+    }
+
+    /**
+     * Construct a new ProfileSummaryBuilder.
+     *
+     * @param context  the build context.
+     * @param profile the profile being documented.
+     * @param profileWriter the doclet specific writer that will output the
+     *        result.
+     *
+     * @return an instance of a ProfileSummaryBuilder.
+     */
+    public static ProfileSummaryBuilder getInstance(Context context,
+            Profile profile, ProfileSummaryWriter profileWriter) {
+        return new ProfileSummaryBuilder(context, profile, profileWriter);
+    }
+
+    /**
+     * Build the profile summary.
+     */
+    public void build() throws IOException {
+        if (profileWriter == null) {
+            //Doclet does not support this output.
+            return;
+        }
+        build(layoutParser.parseXML(ROOT), contentTree);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getName() {
+        return ROOT;
+    }
+
+    /**
+     * Build the profile documentation.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param contentTree the content tree to which the documentation will be added
+     */
+    public void buildProfileDoc(XMLNode node, Content contentTree) throws Exception {
+        contentTree = profileWriter.getProfileHeader(profile.name);
+        buildChildren(node, contentTree);
+        profileWriter.addProfileFooter(contentTree);
+        profileWriter.printDocument(contentTree);
+        profileWriter.close();
+        Util.copyDocFiles(configuration, DocPaths.profileSummary(profile.name));
+    }
+
+    /**
+     * Build the content for the profile doc.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param contentTree the content tree to which the profile contents
+     *                    will be added
+     */
+    public void buildContent(XMLNode node, Content contentTree) {
+        Content profileContentTree = profileWriter.getContentHeader();
+        buildChildren(node, profileContentTree);
+        contentTree.addContent(profileContentTree);
+    }
+
+    /**
+     * Build the profile summary.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param profileContentTree the profile content tree to which the summaries will
+     *                           be added
+     */
+    public void buildSummary(XMLNode node, Content profileContentTree) {
+        Content summaryContentTree = profileWriter.getSummaryHeader();
+        buildChildren(node, summaryContentTree);
+        profileContentTree.addContent(profileWriter.getSummaryTree(summaryContentTree));
+    }
+
+    /**
+     * Build the profile package summary.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param summaryContentTree the content tree to which the summaries will
+     *                           be added
+     */
+    public void buildPackageSummary(XMLNode node, Content summaryContentTree) {
+        PackageDoc[] packages = configuration.profilePackages.get(profile.name);
+        for (int i = 0; i < packages.length; i++) {
+            this.pkg = packages[i];
+            Content packageSummaryContentTree = profileWriter.getPackageSummaryHeader(this.pkg);
+            buildChildren(node, packageSummaryContentTree);
+            summaryContentTree.addContent(profileWriter.getPackageSummaryTree(
+                    packageSummaryContentTree));
+        }
+    }
+
+    /**
+     * Build the summary for the interfaces in the package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageSummaryContentTree the tree to which the interface summary
+     *                           will be added
+     */
+    public void buildInterfaceSummary(XMLNode node, Content packageSummaryContentTree) {
+        String interfaceTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Interface_Summary"),
+                configuration.getText("doclet.interfaces"));
+        String[] interfaceTableHeader = new String[] {
+            configuration.getText("doclet.Interface"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] interfaces = pkg.interfaces();
+        if (interfaces.length > 0) {
+            profileWriter.addClassesSummary(
+                    interfaces,
+                    configuration.getText("doclet.Interface_Summary"),
+                    interfaceTableSummary, interfaceTableHeader, packageSummaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the classes in the package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageSummaryContentTree the tree to which the class summary will
+     *                           be added
+     */
+    public void buildClassSummary(XMLNode node, Content packageSummaryContentTree) {
+        String classTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Class_Summary"),
+                configuration.getText("doclet.classes"));
+        String[] classTableHeader = new String[] {
+            configuration.getText("doclet.Class"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] classes = pkg.ordinaryClasses();
+        if (classes.length > 0) {
+            profileWriter.addClassesSummary(
+                    classes,
+                    configuration.getText("doclet.Class_Summary"),
+                    classTableSummary, classTableHeader, packageSummaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the enums in the package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageSummaryContentTree the tree to which the enum summary will
+     *                           be added
+     */
+    public void buildEnumSummary(XMLNode node, Content packageSummaryContentTree) {
+        String enumTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Enum_Summary"),
+                configuration.getText("doclet.enums"));
+        String[] enumTableHeader = new String[] {
+            configuration.getText("doclet.Enum"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] enums = pkg.enums();
+        if (enums.length > 0) {
+            profileWriter.addClassesSummary(
+                    enums,
+                    configuration.getText("doclet.Enum_Summary"),
+                    enumTableSummary, enumTableHeader, packageSummaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the exceptions in the package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageSummaryContentTree the tree to which the exception summary will
+     *                           be added
+     */
+    public void buildExceptionSummary(XMLNode node, Content packageSummaryContentTree) {
+        String exceptionTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Exception_Summary"),
+                configuration.getText("doclet.exceptions"));
+        String[] exceptionTableHeader = new String[] {
+            configuration.getText("doclet.Exception"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] exceptions = pkg.exceptions();
+        if (exceptions.length > 0) {
+            profileWriter.addClassesSummary(
+                    exceptions,
+                    configuration.getText("doclet.Exception_Summary"),
+                    exceptionTableSummary, exceptionTableHeader, packageSummaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the errors in the package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageSummaryContentTree the tree to which the error summary will
+     *                           be added
+     */
+    public void buildErrorSummary(XMLNode node, Content packageSummaryContentTree) {
+        String errorTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Error_Summary"),
+                configuration.getText("doclet.errors"));
+        String[] errorTableHeader = new String[] {
+            configuration.getText("doclet.Error"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] errors = pkg.errors();
+        if (errors.length > 0) {
+            profileWriter.addClassesSummary(
+                    errors,
+                    configuration.getText("doclet.Error_Summary"),
+                    errorTableSummary, errorTableHeader, packageSummaryContentTree);
+        }
+    }
+
+    /**
+     * Build the summary for the annotation type in the package.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param packageSummaryContentTree the tree to which the annotation type
+     *                           summary will be added
+     */
+    public void buildAnnotationTypeSummary(XMLNode node, Content packageSummaryContentTree) {
+        String annotationtypeTableSummary =
+                configuration.getText("doclet.Member_Table_Summary",
+                configuration.getText("doclet.Annotation_Types_Summary"),
+                configuration.getText("doclet.annotationtypes"));
+        String[] annotationtypeTableHeader = new String[] {
+            configuration.getText("doclet.AnnotationType"),
+            configuration.getText("doclet.Description")
+        };
+        ClassDoc[] annotationTypes = pkg.annotationTypes();
+        if (annotationTypes.length > 0) {
+            profileWriter.addClassesSummary(
+                    annotationTypes,
+                    configuration.getText("doclet.Annotation_Types_Summary"),
+                    annotationtypeTableSummary, annotationtypeTableHeader,
+                    packageSummaryContentTree);
+        }
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml
index ce4472e..c4e408f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml
@@ -28,6 +28,21 @@
 
 <Doclet>
 
+    <ProfileDoc>
+        <Content>
+            <Summary>
+                <PackageSummary>
+                    <InterfaceSummary/>
+                    <ClassSummary/>
+                    <EnumSummary/>
+                    <ExceptionSummary/>
+                    <ErrorSummary/>
+                    <AnnotationTypeSummary/>
+                </PackageSummary>
+            </Summary>
+        </Content>
+    </ProfileDoc>
+
     <PackageDoc>
         <Content>
             <Summary>
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
index 9322331..497c51f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
@@ -31,6 +31,7 @@
 doclet.Building_Index_For_All_Classes=Building index for all classes...
 doclet.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0.
 doclet.Packages=Packages
+doclet.Profiles=Profiles
 doclet.Other_Packages=Other Packages
 doclet.Notice_taglet_registered=Registered Taglet {0} ...
 doclet.Notice_taglet_unseen=Note: Custom tags that were not seen: {0}
@@ -61,6 +62,7 @@
 doclet.malformed_html_link_tag=<a> tag is malformed:\n"{0}"
 doclet.tag_misuse=Tag {0} cannot be used in {1} documentation.  It can only be used in the following types of documentation: {2}.
 doclet.Package_Summary=Package Summary
+doclet.Profile_Summary=Profile Summary
 doclet.Interface_Summary=Interface Summary
 doclet.Annotation_Types_Summary=Annotation Types Summary
 doclet.Enum_Summary=Enum Summary
@@ -82,6 +84,7 @@
 doclet.Classes=Classes
 doclet.Packages=Packages
 doclet.packages=packages
+doclet.profiles=profiles
 doclet.All_Classes=All Classes
 doclet.All_Superinterfaces=All Superinterfaces:
 doclet.All_Implemented_Interfaces=All Implemented Interfaces:
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css
index ce3df20..97c6741 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css
@@ -191,6 +191,9 @@
     margin:10px;
     position:relative;
 }
+.indexHeader span{
+    margin-right:15px;
+}
 .indexHeader h1 {
     font-size:1.3em;
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPaths.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPaths.java
index f1c2a13..563f9b5 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPaths.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPaths.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -87,6 +87,26 @@
     /** The name of the file for the package frame. */
     public static final DocPath PACKAGE_FRAME = DocPath.create("package-frame.html");
 
+    /** The name of the file for the profile frame. */
+     public static final DocPath profileFrame(String profileName) {
+        return DocPath.create(profileName + "-frame.html");
+    }
+
+    /** The name of the file for the profile package frame. */
+     public static final DocPath profilePackageFrame(String profileName) {
+        return DocPath.create(profileName + "-package-frame.html");
+    }
+
+    /** The name of the file for the profile package summary. */
+     public static final DocPath profilePackageSummary(String profileName) {
+        return DocPath.create(profileName + "-package-summary.html");
+    }
+
+    /** The name of the file for the profile summary. */
+     public static final DocPath profileSummary(String profileName) {
+        return DocPath.create(profileName + "-summary.html");
+    }
+
     /** The name of the file for the package list. */
     public static final DocPath PACKAGE_LIST = DocPath.create("package-list");
 
@@ -99,6 +119,9 @@
     /** The name of the file for the package usage info. */
     public static final DocPath PACKAGE_USE = DocPath.create("package-use.html");
 
+    /** The name of the file for the overview frame. */
+    public static final DocPath PROFILE_OVERVIEW_FRAME = DocPath.create("profile-overview-frame.html");
+
     /** The name of the directory in which resources are generated.
      *  Also the name of the sub-package from which resources are read.
      */
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MetaKeywords.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MetaKeywords.java
index 2f81425..18358ec 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MetaKeywords.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MetaKeywords.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -28,6 +28,7 @@
 import java.util.*;
 
 import com.sun.javadoc.*;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.doclets.internal.toolkit.*;
 
 /**
@@ -105,6 +106,20 @@
     }
 
     /**
+     * Get the profile keywords.
+     *
+     * @param profile the profile being documented
+     */
+    public String[] getMetaKeywords(Profile profile) {
+        if( configuration.keywords ) {
+            String profileName = profile.name;
+            return new String[] { profileName + " " + "profile" };
+        } else {
+            return new String[] {};
+        }
+    }
+
+    /**
      * Get the overview keywords.
      */
     public String[] getOverviewMetaKeywords(String title, String docTitle) {
diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
index 135c5b9..5969a10 100644
--- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java
@@ -245,12 +245,19 @@
         if (t == null) {
             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
         } else {
+            boolean done = false;
             for (TagStackItem tsi: tagStack) {
                 if (tsi.tag.accepts(t)) {
                     while (tagStack.peek() != tsi) tagStack.pop();
+                    done = true;
                     break;
-                } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL)
+                } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL) {
+                    done = true;
                     break;
+                }
+            }
+            if (!done && HtmlTag.BODY.accepts(t)) {
+                tagStack.clear();
             }
 
             checkStructure(tree, t);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java
index fa36e1f..db651a2 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java
@@ -154,10 +154,11 @@
                 throw new IllegalStateException();
         } else {
             initContext();
+            compilerMain.log = Log.instance(context);
             compilerMain.setOptions(Options.instance(context));
             compilerMain.filenames = new LinkedHashSet<File>();
             Collection<File> filenames = compilerMain.processArgs(CommandLine.parse(args), classNames);
-            if (!filenames.isEmpty())
+            if (filenames != null && !filenames.isEmpty())
                 throw new IllegalArgumentException("Malformed arguments " + toString(filenames, " "));
             compiler = JavaCompiler.instance(context);
             compiler.keepComments = true;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
index 0152953..08e6949 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
@@ -74,6 +74,7 @@
         if ((mask&DEPRECATED) != 0) flags.add(Flag.DEPRECATED);
         if ((mask&HASINIT) != 0) flags.add(Flag.HASINIT);
         if ((mask&ENUM) != 0) flags.add(Flag.ENUM);
+        if ((mask&MANDATED) != 0) flags.add(Flag.MANDATED);
         if ((mask&IPROXY) != 0) flags.add(Flag.IPROXY);
         if ((mask&NOOUTERTHIS) != 0) flags.add(Flag.NOOUTERTHIS);
         if ((mask&EXISTS) != 0) flags.add(Flag.EXISTS);
@@ -114,6 +115,9 @@
      *  classfile v49.0. */
     public static final int ENUM         = 1<<14;
 
+    /** Added in SE8, represents constructs implicitly declared in source. */
+    public static final int MANDATED     = 1<<15;
+
     public static final int StandardFlags = 0x0fff;
     public static final int ModifierFlags = StandardFlags & ~INTERFACE;
 
@@ -264,6 +268,11 @@
      */
     public static final long AUXILIARY = 1L<<44;
 
+    /**
+     * Flag that marks that a symbol is not available in the current profile
+     */
+    public static final long NOT_IN_PROFILE = 1L<<45;
+
     /** Modifier masks.
      */
     public static final int
@@ -342,6 +351,7 @@
         DEPRECATED("deprecated"),
         HASINIT("hasinit"),
         ENUM("enum"),
+        MANDATED("mandated"),
         IPROXY("iproxy"),
         NOOUTERTHIS("noouterthis"),
         EXISTS("exists"),
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java
index 25caf49..fffa266 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java
@@ -221,7 +221,7 @@
     public boolean allowIntersectionTypesInCast() {
         return compareTo(JDK1_8) >= 0;
     }
-    public boolean allowEarlyReturnConstraints() {
+    public boolean allowGraphInference() {
         return compareTo(JDK1_8) >= 0;
     }
     public boolean allowStructuralMostSpecific() {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
index 0bc115e..db688a5 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
@@ -217,6 +217,14 @@
         return (flags() & INTERFACE) != 0;
     }
 
+    public boolean isPrivate() {
+        return (flags_field & Flags.AccessFlags) == PRIVATE;
+    }
+
+    public boolean isEnum() {
+        return (flags() & ENUM) != 0;
+    }
+
     /** Is this symbol declared (directly or indirectly) local
      *  to a method or variable initializer?
      *  Also includes fields of inner classes which are in
@@ -479,7 +487,7 @@
     }
 
     // This method is part of the javax.lang.model API, do not use this in javac code.
-    public <A extends java.lang.annotation.Annotation> A[] getAnnotations(Class<A> annoType) {
+    public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A> annoType) {
         return JavacElements.getAnnotations(this, annoType);
     }
 
@@ -1082,6 +1090,9 @@
         /** The code of the method. */
         public Code code = null;
 
+        /** The extra (synthetic/mandated) parameters of the method. */
+        public List<VarSymbol> extraParams = List.nil();
+
         /** The parameters of the method. */
         public List<VarSymbol> params = null;
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
index 2ec60db..51eea68 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
@@ -156,6 +156,7 @@
     public final Type deprecatedType;
     public final Type suppressWarningsType;
     public final Type inheritedType;
+    public final Type profileType;
     public final Type proprietaryType;
     public final Type systemType;
     public final Type autoCloseableType;
@@ -360,6 +361,22 @@
 
     }
 
+    // Enter a synthetic class that is used to mark classes in ct.sym.
+    // This class does not have a class file.
+    private Type enterSyntheticAnnotation(String name) {
+        ClassType type = (ClassType)enterClass(name);
+        ClassSymbol sym = (ClassSymbol)type.tsym;
+        sym.completer = null;
+        sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
+        sym.erasure_field = type;
+        sym.members_field = new Scope(sym);
+        type.typarams_field = List.nil();
+        type.allparams_field = List.nil();
+        type.supertype_field = annotationType;
+        type.interfaces_field = List.nil();
+        return type;
+    }
+
     /** Constructor; enters all predefined identifiers and operators
      *  into symbol table.
      */
@@ -521,17 +538,13 @@
         // Enter a synthetic class that is used to mark internal
         // proprietary classes in ct.sym.  This class does not have a
         // class file.
-        ClassType proprietaryType = (ClassType)enterClass("sun.Proprietary+Annotation");
-        this.proprietaryType = proprietaryType;
-        ClassSymbol proprietarySymbol = (ClassSymbol)proprietaryType.tsym;
-        proprietarySymbol.completer = null;
-        proprietarySymbol.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
-        proprietarySymbol.erasure_field = proprietaryType;
-        proprietarySymbol.members_field = new Scope(proprietarySymbol);
-        proprietaryType.typarams_field = List.nil();
-        proprietaryType.allparams_field = List.nil();
-        proprietaryType.supertype_field = annotationType;
-        proprietaryType.interfaces_field = List.nil();
+        proprietaryType = enterSyntheticAnnotation("sun.Proprietary+Annotation");
+
+        // Enter a synthetic class that is used to provide profile info for
+        // classes in ct.sym.  This class does not have a class file.
+        profileType = enterSyntheticAnnotation("jdk.Profile+Annotation");
+        MethodSymbol m = new MethodSymbol(PUBLIC | ABSTRACT, names.value, intType, profileType.tsym);
+        profileType.tsym.members().enter(m);
 
         // Enter a class for arrays.
         // The class implements java.lang.Cloneable and java.io.Serializable.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java b/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java
index 59228c9..0876749 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TargetType.java
@@ -82,34 +82,37 @@
     /** For annotations on an exception parameter. */
     EXCEPTION_PARAMETER(0x42, true),
 
-    /** For annotations on a typecast. */
-    CAST(0x43, true),
-
     /** For annotations on a type test. */
-    INSTANCEOF(0x44, true),
+    INSTANCEOF(0x43, true),
 
     /** For annotations on an object creation expression. */
-    NEW(0x45, true),
+    NEW(0x44, true),
+
+    /** For annotations on a constructor reference receiver. */
+    CONSTRUCTOR_REFERENCE(0x45, true),
+
+    /** For annotations on a method reference receiver. */
+    METHOD_REFERENCE(0x46, true),
+
+    /** For annotations on a typecast. */
+    CAST(0x47, true),
 
     /** For annotations on a type argument of an object creation expression. */
-    CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
+    CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
 
     /** For annotations on a type argument of a method call. */
-    METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
+    METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true),
 
-    /** For annotations on a lambda parameter type. */
-    LAMBDA_FORMAL_PARAMETER(0x48, true),
-
-    /** For annotations on a method reference. */
-    METHOD_REFERENCE(0x49, true),
+    /** For annotations on a type argument of a constructor reference. */
+    CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
 
     /** For annotations on a type argument of a method reference. */
-    METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
+    METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
 
     /** For annotations with an unknown target. */
     UNKNOWN(0xFF);
 
-    private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x92;
+    private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
 
     private final int targetTypeValue;
     private final boolean isLocal;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
index ab8f6c7..da01174 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
@@ -1309,6 +1309,9 @@
         /** inference variable's inferred type (set from Infer.java) */
         public Type inst = null;
 
+        /** number of declared (upper) bounds */
+        public int declaredCount;
+
         /** inference variable's change listener */
         public UndetVarListener listener = null;
 
@@ -1318,13 +1321,11 @@
         }
 
         public UndetVar(TypeVar origin, Types types) {
-            this(origin, types, true);
-        }
-
-        public UndetVar(TypeVar origin, Types types, boolean includeBounds) {
             super(UNDETVAR, origin);
             bounds = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
-            bounds.put(InferenceBound.UPPER, includeBounds ? types.getBounds(origin) : List.<Type>nil());
+            List<Type> declaredBounds = types.getBounds(origin);
+            declaredCount = declaredBounds.length();
+            bounds.put(InferenceBound.UPPER, declaredBounds);
             bounds.put(InferenceBound.LOWER, List.<Type>nil());
             bounds.put(InferenceBound.EQ, List.<Type>nil());
         }
@@ -1340,38 +1341,89 @@
         }
 
         /** get all bounds of a given kind */
-        public List<Type> getBounds(InferenceBound ib) {
-            return bounds.get(ib);
+        public List<Type> getBounds(InferenceBound... ibs) {
+            ListBuffer<Type> buf = ListBuffer.lb();
+            for (InferenceBound ib : ibs) {
+                buf.appendList(bounds.get(ib));
+            }
+            return buf.toList();
+        }
+
+        /** get the list of declared (upper) bounds */
+        public List<Type> getDeclaredBounds() {
+            ListBuffer<Type> buf = ListBuffer.lb();
+            int count = 0;
+            for (Type b : getBounds(InferenceBound.UPPER)) {
+                if (count++ == declaredCount) break;
+                buf.append(b);
+            }
+            return buf.toList();
         }
 
         /** add a bound of a given kind - this might trigger listener notification */
         public void addBound(InferenceBound ib, Type bound, Types types) {
+            Type bound2 = toTypeVarMap.apply(bound);
             List<Type> prevBounds = bounds.get(ib);
             for (Type b : prevBounds) {
-                if (types.isSameType(b, bound)) {
-                    return;
-                }
+                //check for redundancy - use strict version of isSameType on tvars
+                //(as the standard version will lead to false positives w.r.t. clones ivars)
+                if (types.isSameType(b, bound2, true)) return;
             }
-            bounds.put(ib, prevBounds.prepend(bound));
+            bounds.put(ib, prevBounds.prepend(bound2));
             notifyChange(EnumSet.of(ib));
         }
+        //where
+            Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") {
+                @Override
+                public Type apply(Type t) {
+                    if (t.hasTag(UNDETVAR)) {
+                        UndetVar uv = (UndetVar)t;
+                        return uv.qtype;
+                    } else {
+                        return t.map(this);
+                    }
+                }
+            };
 
         /** replace types in all bounds - this might trigger listener notification */
         public void substBounds(List<Type> from, List<Type> to, Types types) {
-            EnumSet<InferenceBound> changed = EnumSet.noneOf(InferenceBound.class);
-            Map<InferenceBound, List<Type>> bounds2 = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
-            for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
-                InferenceBound ib = _entry.getKey();
-                List<Type> prevBounds = _entry.getValue();
-                List<Type> newBounds = types.subst(prevBounds, from, to);
-                bounds2.put(ib, newBounds);
-                if (prevBounds != newBounds) {
-                    changed.add(ib);
+            List<Type> instVars = from.diff(to);
+            //if set of instantiated ivars is empty, there's nothing to do!
+            if (instVars.isEmpty()) return;
+            final EnumSet<InferenceBound> boundsChanged = EnumSet.noneOf(InferenceBound.class);
+            UndetVarListener prevListener = listener;
+            try {
+                //setup new listener for keeping track of changed bounds
+                listener = new UndetVarListener() {
+                    public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
+                        boundsChanged.addAll(ibs);
+                    }
+                };
+                for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
+                    InferenceBound ib = _entry.getKey();
+                    List<Type> prevBounds = _entry.getValue();
+                    ListBuffer<Type> newBounds = ListBuffer.lb();
+                    ListBuffer<Type> deps = ListBuffer.lb();
+                    //step 1 - re-add bounds that are not dependent on ivars
+                    for (Type t : prevBounds) {
+                        if (!t.containsAny(instVars)) {
+                            newBounds.append(t);
+                        } else {
+                            deps.append(t);
+                        }
+                    }
+                    //step 2 - replace bounds
+                    bounds.put(ib, newBounds.toList());
+                    //step 3 - for each dependency, add new replaced bound
+                    for (Type dep : deps) {
+                        addBound(ib, types.subst(dep, from, to), types);
+                    }
                 }
-            }
-            if (!changed.isEmpty()) {
-                bounds = bounds2;
-                notifyChange(changed);
+            } finally {
+                listener = prevListener;
+                if (!boundsChanged.isEmpty()) {
+                    notifyChange(boundsChanged);
+                }
             }
         }
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
index 32a6ffd..d61a9f6 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
@@ -126,7 +126,8 @@
     // Tree position.
     public int pos = -1;
 
-    // For typecasts, type tests, new (and locals, as start_pc).
+    // For type casts, type tests, new, locals (as start_pc),
+    // and method and constructor reference type arguments.
     public boolean isValidOffset = false;
     public int offset = -1;
 
@@ -156,12 +157,13 @@
         sb.append(type);
 
         switch (type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             sb.append(", offset = ");
             sb.append(offset);
             break;
@@ -223,9 +225,12 @@
             sb.append(", param_index = ");
             sb.append(parameter_index);
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             sb.append(", offset = ");
             sb.append(offset);
@@ -236,12 +241,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            // TODO: also needs an offset?
-            sb.append(", param_index = ");
-            sb.append(parameter_index);
-            break;
         case UNKNOWN:
             sb.append(", position UNKNOWN!");
             break;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
index b438b2f..a7ce49e 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
@@ -217,6 +217,9 @@
         // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
         // need to set its position explicitly.
         // The method returns a copy of type that contains these annotations.
+        //
+        // As a side effect the method sets the type annotation position of "annotations".
+        // Note that it is assumed that all annotations share the same position.
         private static Type typeWithAnnotations(final JCTree typetree, final Type type,
                 final List<Attribute.TypeCompound> annotations, Log log) {
             // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n",
@@ -267,7 +270,9 @@
                 }
                 Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log);
                 tomodify.elemtype = arelemType;
-                for (Attribute.TypeCompound a : annotations) {
+                {
+                    // All annotations share the same position; modify the first one.
+                    Attribute.TypeCompound a = annotations.get(0);
                     TypeAnnotationPosition p = a.position;
                     p.location = p.location.prependList(depth.toList());
                 }
@@ -345,10 +350,10 @@
                 if (depth.nonEmpty()) {
                     // Only need to change the annotation positions
                     // if they are on an enclosed type.
-                    for (Attribute.TypeCompound a : annotations) {
-                        TypeAnnotationPosition p = a.position;
-                        p.location = p.location.appendList(depth.toList());
-                    }
+                    // All annotations share the same position; modify the first one.
+                    Attribute.TypeCompound a = annotations.get(0);
+                    TypeAnnotationPosition p = a.position;
+                    p.location = p.location.appendList(depth.toList());
                 }
 
                 Type ret = typeWithAnnotations(type, enclTy, annotations);
@@ -463,8 +468,7 @@
 
                 @Override
                 public Type visitType(Type t, List<TypeCompound> s) {
-                    // Error?
-                    return t;
+                    return new AnnotatedType(s, t);
                 }
             };
 
@@ -575,6 +579,10 @@
             System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
             System.out.println("    Framing tree: " + frame + " kind: " + frame.getKind());
             */
+
+            // Note that p.offset is set in
+            // com.sun.tools.javac.jvm.Gen.setTypeAnnotationPositions(int)
+
             switch (frame.getKind()) {
                 case TYPE_CAST:
                     p.type = TargetType.CAST;
@@ -659,6 +667,45 @@
                     return;
                 }
 
+                case MEMBER_REFERENCE: {
+                    JCMemberReference mrframe = (JCMemberReference) frame;
+
+                    if (mrframe.expr == tree) {
+                        switch (mrframe.mode) {
+                        case INVOKE:
+                            p.type = TargetType.METHOD_REFERENCE;
+                            break;
+                        case NEW:
+                            p.type = TargetType.CONSTRUCTOR_REFERENCE;
+                            break;
+                        default:
+                            Assert.error("Unknown method reference mode " + mrframe.mode +
+                                    " for tree " + tree + " within frame " + frame);
+                        }
+                        p.pos = frame.pos;
+                    } else if (mrframe.typeargs != null &&
+                            mrframe.typeargs.contains(tree)) {
+                        int arg = mrframe.typeargs.indexOf(tree);
+                        p.type_index = arg;
+                        switch (mrframe.mode) {
+                        case INVOKE:
+                            p.type = TargetType.METHOD_REFERENCE_TYPE_ARGUMENT;
+                            break;
+                        case NEW:
+                            p.type = TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
+                            break;
+                        default:
+                            Assert.error("Unknown method reference mode " + mrframe.mode +
+                                    " for tree " + tree + " within frame " + frame);
+                        }
+                        p.pos = frame.pos;
+                    } else {
+                        Assert.error("Could not determine type argument position of tree " + tree +
+                                " within frame " + frame);
+                    }
+                    return;
+                }
+
                 case ARRAY_TYPE: {
                     ListBuffer<TypePathEntry> index = ListBuffer.lb();
                     index = index.append(TypePathEntry.ARRAY);
@@ -766,6 +813,14 @@
                     return;
                 }
 
+                case INTERSECTION_TYPE: {
+                    JCTypeIntersection isect = (JCTypeIntersection)frame;
+                    p.type_index = isect.bounds.indexOf(tree);
+                    List<JCTree> newPath = path.tail;
+                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                    return;
+                }
+
                 case METHOD_INVOCATION: {
                     JCMethodInvocation invocation = (JCMethodInvocation)frame;
                     if (!invocation.typeargs.contains(tree)) {
@@ -911,6 +966,8 @@
         public void visitVarDef(final JCVariableDecl tree) {
             if (tree.sym == null) {
                 // Something is wrong already. Quietly ignore.
+            } else if (tree.sym.getKind() == ElementKind.PARAMETER) {
+                // Parameters are handled in visitMethodDef above.
             } else if (tree.sym.getKind() == ElementKind.FIELD) {
                 if (sigOnly) {
                     TypeAnnotationPosition pos = new TypeAnnotationPosition();
@@ -924,7 +981,6 @@
                 pos.pos = tree.pos;
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
             } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
-                // System.out.println("Found exception param: " + tree);
                 TypeAnnotationPosition pos = new TypeAnnotationPosition();
                 pos.type = TargetType.EXCEPTION_PARAMETER;
                 pos.pos = tree.pos;
@@ -934,9 +990,11 @@
                 pos.type = TargetType.RESOURCE_VARIABLE;
                 pos.pos = tree.pos;
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+            } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
+                // No type annotations can occur here.
             } else {
                 // There is nothing else in a variable declaration that needs separation.
-                // System.out.println("We found a: " + tree);
+                Assert.error("Unhandled variable kind: " + tree + " of kind: " + tree.sym.getKind());
             }
 
             push(tree);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
index f7fa666..4ade234 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
@@ -976,9 +976,12 @@
      * lists are of different length, return false.
      */
     public boolean isSameTypes(List<Type> ts, List<Type> ss) {
+        return isSameTypes(ts, ss, false);
+    }
+    public boolean isSameTypes(List<Type> ts, List<Type> ss, boolean strict) {
         while (ts.tail != null && ss.tail != null
                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
-               isSameType(ts.head, ss.head)) {
+               isSameType(ts.head, ss.head, strict)) {
             ts = ts.tail;
             ss = ss.tail;
         }
@@ -990,10 +993,15 @@
      * Is t the same type as s?
      */
     public boolean isSameType(Type t, Type s) {
-        return isSameType.visit(t, s);
+        return isSameType(t, s, false);
+    }
+    public boolean isSameType(Type t, Type s, boolean strict) {
+        return strict ?
+                isSameTypeStrict.visit(t, s) :
+                isSameTypeLoose.visit(t, s);
     }
     // where
-        private TypeRelation isSameType = new TypeRelation() {
+        abstract class SameTypeVisitor extends TypeRelation {
 
             public Boolean visitType(Type t, Type s) {
                 if (t == s)
@@ -1010,8 +1018,7 @@
                     if (s.tag == TYPEVAR) {
                         //type-substitution does not preserve type-var types
                         //check that type var symbols and bounds are indeed the same
-                        return t.tsym == s.tsym &&
-                                visit(t.getUpperBound(), s.getUpperBound());
+                        return sameTypeVars((TypeVar)t, (TypeVar)s);
                     }
                     else {
                         //special case for s == ? super X, where upper(s) = u
@@ -1026,6 +1033,8 @@
                 }
             }
 
+            abstract boolean sameTypeVars(TypeVar tv1, TypeVar tv2);
+
             @Override
             public Boolean visitWildcardType(WildcardType t, Type s) {
                 if (s.isPartial())
@@ -1060,9 +1069,11 @@
                 }
                 return t.tsym == s.tsym
                     && visit(t.getEnclosingType(), s.getEnclosingType())
-                    && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
+                    && containsTypes(t.getTypeArguments(), s.getTypeArguments());
             }
 
+            abstract protected boolean containsTypes(List<Type> ts1, List<Type> ts2);
+
             @Override
             public Boolean visitArrayType(ArrayType t, Type s) {
                 if (t == s)
@@ -1115,6 +1126,36 @@
             public Boolean visitErrorType(ErrorType t, Type s) {
                 return true;
             }
+        }
+
+        /**
+         * Standard type-equality relation - type variables are considered
+         * equals if they share the same type symbol.
+         */
+        TypeRelation isSameTypeLoose = new SameTypeVisitor() {
+            @Override
+            boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
+                return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound());
+            }
+            @Override
+            protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
+                return containsTypeEquivalent(ts1, ts2);
+            }
+        };
+
+        /**
+         * Strict type-equality relation - type variables are considered
+         * equals if they share the same object identity.
+         */
+        TypeRelation isSameTypeStrict = new SameTypeVisitor() {
+            @Override
+            boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
+                return tv1 == tv2;
+            }
+            @Override
+            protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
+                return isSameTypes(ts1, ts2, true);
+            }
         };
     // </editor-fold>
 
@@ -2027,7 +2068,15 @@
 
             @Override
             public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) {
-                return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse));
+                Type erased = erasure(t.underlyingType, recurse);
+                if (erased.getKind() == TypeKind.ANNOTATED) {
+                    // This can only happen when the underlying type is a
+                    // type variable and the upper bound of it is annotated.
+                    // The annotation on the type variable overrides the one
+                    // on the bound.
+                    erased = ((AnnotatedType)erased).underlyingType;
+                }
+                return new AnnotatedType(t.typeAnnotations, erased);
             }
         };
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
index db09cf5..994ec8d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -43,7 +43,7 @@
 import com.sun.tools.javac.comp.Check.CheckContext;
 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
 import com.sun.tools.javac.comp.Infer.InferenceContext;
-import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
+import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
@@ -244,8 +244,8 @@
                     @Override
                     public void typesInferred(InferenceContext inferenceContext) {
                         ResultInfo pendingResult =
-                                    resultInfo.dup(inferenceContext.asInstType(resultInfo.pt, types));
-                        check(tree, inferenceContext.asInstType(found, types), ownkind, pendingResult);
+                                    resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
+                        check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
                     }
                 });
                 return tree.type = resultInfo.pt;
@@ -766,6 +766,8 @@
         JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
 
         try {
+            memberEnter.typeAnnotate(initializer, env, env.info.enclVar);
+            annotate.flush();
             Type itype = attribExpr(initializer, env, type);
             if (itype.constValue() != null)
                 return coerce(itype, type).constValue();
@@ -1099,8 +1101,9 @@
             Env<AttrContext> localEnv =
                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
             localEnv.info.scope.owner =
-                new MethodSymbol(tree.flags | BLOCK, names.empty, null,
-                                 env.info.scope.owner);
+                new MethodSymbol(tree.flags | BLOCK |
+                    env.info.scope.owner.flags() & STRICTFP, names.empty, null,
+                    env.info.scope.owner);
             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
 
             // Attribute all type annotations in the block
@@ -2415,7 +2418,7 @@
                 inferenceContext.addFreeTypeListener(ts, new FreeTypeListener() {
                     @Override
                     public void typesInferred(InferenceContext inferenceContext) {
-                        checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts, types));
+                        checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts));
                     }
                 });
             } else {
@@ -2440,7 +2443,7 @@
             @Override
             public boolean compatible(Type found, Type req, Warner warn) {
                 //return type must be compatible in both current context and assignment context
-                return chk.basicHandler.compatible(found, inferenceContext().asFree(req, types), warn);
+                return chk.basicHandler.compatible(found, inferenceContext().asFree(req), warn);
             }
 
             @Override
@@ -2475,7 +2478,7 @@
         * descriptor.
         */
         private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) {
-            Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType(), types);
+            Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType());
 
             //return values have already been checked - but if lambda has no return
             //values, we must ensure that void/value compatibility is correct;
@@ -2487,13 +2490,13 @@
                         diags.fragment("missing.ret.val", returnType)));
             }
 
-            List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes(), types);
+            List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes());
             if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) {
                 checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
             }
 
             if (!speculativeAttr) {
-                List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes(), types);
+                List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes());
                 if (chk.unhandled(tree.inferredThrownTypes == null ? List.<Type>nil() : tree.inferredThrownTypes, thrownTypes).nonEmpty()) {
                     log.error(tree, "incompatible.thrown.types.in.lambda", tree.inferredThrownTypes);
                 }
@@ -2538,7 +2541,7 @@
 
             if (exprType.isErroneous()) {
                 //if the qualifier expression contains problems,
-                //give up atttribution of method reference
+                //give up attribution of method reference
                 result = that.type = exprType;
                 return;
             }
@@ -2680,7 +2683,7 @@
 
     @SuppressWarnings("fallthrough")
     void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) {
-        Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType(), types);
+        Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType());
 
         Type resType;
         switch (tree.getMode()) {
@@ -2712,7 +2715,7 @@
         }
 
         if (!speculativeAttr) {
-            List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes(), types);
+            List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes());
             if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) {
                 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes());
             }
@@ -2728,7 +2731,7 @@
         if (inferenceContext.free(descriptorType)) {
             inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() {
                 public void typesInferred(InferenceContext inferenceContext) {
-                    setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType, types), inferenceContext);
+                    setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), inferenceContext);
                 }
             });
         } else {
@@ -3396,6 +3399,7 @@
             if (sym.name != names.init) {
                 chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym);
                 chk.checkSunAPI(tree.pos(), sym);
+                chk.checkProfile(tree.pos(), sym);
             }
 
             // Test (3): if symbol is a variable, check that its type and
@@ -4151,7 +4155,9 @@
         }
 
     private Type capture(Type type) {
-        return types.capture(type);
+        //do not capture free types
+        return resultInfo.checkContext.inferenceContext().free(type) ?
+                type : types.capture(type);
     }
 
     private void validateTypeAnnotations(JCTree tree) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index 43283c8..9e9aa09 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -42,7 +42,7 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
 import com.sun.tools.javac.comp.Infer.InferenceContext;
-import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
+import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 
@@ -80,6 +80,7 @@
     private boolean enableSunApiLintControl;
     private final TreeInfo treeinfo;
     private final JavaFileManager fileManager;
+    private final Profile profile;
 
     // The set of lint options currently in effect. It is initialized
     // from the context, and then is set/reset as needed by Attr as it
@@ -110,7 +111,7 @@
         enter = Enter.instance(context);
         deferredAttr = DeferredAttr.instance(context);
         infer = Infer.instance(context);
-        this.types = Types.instance(context);
+        types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         Options options = Options.instance(context);
         lint = Lint.instance(context);
@@ -133,6 +134,8 @@
         Target target = Target.instance(context);
         syntheticNameChar = target.syntheticNameChar();
 
+        profile = Profile.instance(context);
+
         boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
         boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
         boolean verboseSunApi = lint.isEnabled(LintCategory.SUNAPI);
@@ -530,7 +533,7 @@
             inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() {
                 @Override
                 public void typesInferred(InferenceContext inferenceContext) {
-                    checkType(pos, found, inferenceContext.asInstType(req, types), checkContext);
+                    checkType(pos, found, inferenceContext.asInstType(req), checkContext);
                 }
             });
         }
@@ -1023,7 +1026,7 @@
         };
 
     /** Check that given modifiers are legal for given symbol and
-     *  return modifiers together with any implicit modififiers for that symbol.
+     *  return modifiers together with any implicit modifiers for that symbol.
      *  Warning: we can't use flags() here since this method
      *  is called during class enter, when flags() would cause a premature
      *  completion.
@@ -1069,7 +1072,7 @@
             }
             // Imply STRICTFP if owner has STRICTFP set.
             if (((flags|implicit) & Flags.ABSTRACT) == 0)
-              implicit |= sym.owner.flags_field & STRICTFP;
+                implicit |= sym.owner.flags_field & STRICTFP;
             break;
         case TYP:
             if (sym.isLocal()) {
@@ -3033,6 +3036,12 @@
         }
     }
 
+    void checkProfile(final DiagnosticPosition pos, final Symbol s) {
+        if (profile != Profile.DEFAULT && (s.flags() & NOT_IN_PROFILE) != 0) {
+            log.error(pos, "not.in.profile", s, profile);
+        }
+    }
+
 /* *************************************************************************
  * Check for recursive annotation elements.
  **************************************************************************/
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
index 6464002..dd9cc3ed 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
@@ -234,7 +234,7 @@
                     dt.speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase);
                     return speculativeTree.type;
                 case CHECK:
-                    Assert.check(dt.mode == AttrMode.SPECULATIVE);
+                    Assert.check(dt.mode != null);
                     return attr.attribTree(dt.tree, dt.env, resultInfo);
             }
             Assert.error();
@@ -242,6 +242,13 @@
         }
     };
 
+    DeferredTypeCompleter dummyCompleter = new DeferredTypeCompleter() {
+        public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
+            Assert.check(deferredAttrContext.mode == AttrMode.CHECK);
+            return dt.tree.type = Type.noType;
+        }
+    };
+
     /**
      * The 'mode' in which the deferred type is to be type-checked
      */
@@ -332,13 +339,22 @@
         /** inference context */
         final InferenceContext inferenceContext;
 
+        /** parent deferred context */
+        final DeferredAttrContext parent;
+
+        /** Warner object to report warnings */
+        final Warner warn;
+
         /** list of deferred attribution nodes to be processed */
         ArrayList<DeferredAttrNode> deferredAttrNodes = new ArrayList<DeferredAttrNode>();
 
-        DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase, InferenceContext inferenceContext) {
+        DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase,
+                InferenceContext inferenceContext, DeferredAttrContext parent, Warner warn) {
             this.mode = mode;
             this.msym = msym;
             this.phase = phase;
+            this.parent = parent;
+            this.warn = warn;
             this.inferenceContext = inferenceContext;
         }
 
@@ -363,7 +379,7 @@
                 //scan a defensive copy of the node list - this is because a deferred
                 //attribution round can add new nodes to the list
                 for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) {
-                    if (!deferredAttrNode.process()) {
+                    if (!deferredAttrNode.process(this)) {
                         stuckVars.addAll(deferredAttrNode.stuckVars);
                     } else {
                         deferredAttrNodes.remove(deferredAttrNode);
@@ -373,123 +389,133 @@
                 if (!progress) {
                     //remove all variables that have already been instantiated
                     //from the list of stuck variables
-                    inferenceContext.solveAny(inferenceContext.freeVarsIn(List.from(stuckVars)), types, infer);
-                    inferenceContext.notifyChange(types);
+                    inferenceContext.solveAny(List.from(stuckVars), warn);
+                    inferenceContext.notifyChange();
                 }
             }
         }
+    }
+
+    /**
+     * Class representing a deferred attribution node. It keeps track of
+     * a deferred type, along with the expected target type information.
+     */
+    class DeferredAttrNode implements Infer.FreeTypeListener {
+
+        /** underlying deferred type */
+        DeferredType dt;
+
+        /** underlying target type information */
+        ResultInfo resultInfo;
+
+        /** list of uninferred inference variables causing this node to be stuck */
+        List<Type> stuckVars;
+
+        DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
+            this.dt = dt;
+            this.resultInfo = resultInfo;
+            this.stuckVars = stuckVars;
+            if (!stuckVars.isEmpty()) {
+                resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
+            }
+        }
+
+        @Override
+        public void typesInferred(InferenceContext inferenceContext) {
+            stuckVars = List.nil();
+            resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
+        }
+
+        /**
+         * Process a deferred attribution node.
+         * Invariant: a stuck node cannot be processed.
+         */
+        @SuppressWarnings("fallthrough")
+        boolean process(DeferredAttrContext deferredAttrContext) {
+            switch (deferredAttrContext.mode) {
+                case SPECULATIVE:
+                    dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
+                    return true;
+                case CHECK:
+                    if (stuckVars.nonEmpty()) {
+                        //stuck expression - see if we can propagate
+                        if (deferredAttrContext.parent != emptyDeferredAttrContext &&
+                                Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars, List.from(stuckVars))) {
+                            deferredAttrContext.parent.deferredAttrNodes.add(this);
+                            dt.check(resultInfo, List.<Type>nil(), dummyCompleter);
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    } else {
+                        dt.check(resultInfo, stuckVars, basicCompleter);
+                        return true;
+                    }
+                default:
+                    throw new AssertionError("Bad mode");
+            }
+        }
 
         /**
-         * Class representing a deferred attribution node. It keeps track of
-         * a deferred type, along with the expected target type information.
+         * Structural checker for stuck expressions
          */
-        class DeferredAttrNode implements Infer.InferenceContext.FreeTypeListener {
+        class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter {
 
-            /** underlying deferred type */
-            DeferredType dt;
-
-            /** underlying target type information */
             ResultInfo resultInfo;
+            InferenceContext inferenceContext;
 
-            /** list of uninferred inference variables causing this node to be stuck */
-            List<Type> stuckVars;
-
-            DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
-                this.dt = dt;
+            public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
                 this.resultInfo = resultInfo;
-                this.stuckVars = stuckVars;
-                if (!stuckVars.isEmpty()) {
-                    resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
+                this.inferenceContext = deferredAttrContext.inferenceContext;
+                dt.tree.accept(this);
+                dt.speculativeCache.put(deferredAttrContext.msym, stuckTree, deferredAttrContext.phase);
+                return Type.noType;
+            }
+
+            @Override
+            public void visitLambda(JCLambda tree) {
+                Check.CheckContext checkContext = resultInfo.checkContext;
+                Type pt = resultInfo.pt;
+                if (inferenceContext.inferencevars.contains(pt)) {
+                    //ok
+                    return;
+                } else {
+                    //must be a functional descriptor
+                    try {
+                        Type desc = types.findDescriptorType(pt);
+                        if (desc.getParameterTypes().length() != tree.params.length()) {
+                            checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
+                        }
+                    } catch (Types.FunctionDescriptorLookupError ex) {
+                        checkContext.report(null, ex.getDiagnostic());
+                    }
                 }
             }
 
             @Override
-            public void typesInferred(InferenceContext inferenceContext) {
-                stuckVars = List.nil();
-                resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt, types));
+            public void visitNewClass(JCNewClass tree) {
+                //do nothing
             }
 
-            /**
-             * Process a deferred attribution node.
-             * Invariant: a stuck node cannot be processed.
-             */
-            @SuppressWarnings("fallthrough")
-            boolean process() {
-                switch (mode) {
-                    case SPECULATIVE:
-                        dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
-                        return true;
-                    case CHECK:
-                        if (stuckVars.nonEmpty()) {
-                            return false;
-                        } else {
-                            dt.check(resultInfo, stuckVars, basicCompleter);
-                            return true;
-                        }
-                    default:
-                        throw new AssertionError("Bad mode");
-                }
+            @Override
+            public void visitApply(JCMethodInvocation tree) {
+                //do nothing
             }
 
-            /**
-             * Structural checker for stuck expressions
-             */
-            class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter {
-
-                ResultInfo resultInfo;
-
-                public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
-                    this.resultInfo = resultInfo;
-                    dt.tree.accept(this);
-                    dt.speculativeCache.put(msym, stuckTree, phase);
-                    return Type.noType;
-                }
-
-                @Override
-                public void visitLambda(JCLambda tree) {
-                    Check.CheckContext checkContext = resultInfo.checkContext;
-                    Type pt = resultInfo.pt;
-                    if (inferenceContext.inferencevars.contains(pt)) {
-                        //ok
-                        return;
-                    } else {
-                        //must be a functional descriptor
-                        try {
-                            Type desc = types.findDescriptorType(pt);
-                            if (desc.getParameterTypes().length() != tree.params.length()) {
-                                checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
-                            }
-                        } catch (Types.FunctionDescriptorLookupError ex) {
-                            checkContext.report(null, ex.getDiagnostic());
-                        }
-                    }
-                }
-
-                @Override
-                public void visitNewClass(JCNewClass tree) {
-                    //do nothing
-                }
-
-                @Override
-                public void visitApply(JCMethodInvocation tree) {
-                    //do nothing
-                }
-
-                @Override
-                public void visitReference(JCMemberReference tree) {
-                    Check.CheckContext checkContext = resultInfo.checkContext;
-                    Type pt = resultInfo.pt;
-                    if (inferenceContext.inferencevars.contains(pt)) {
-                        //ok
-                        return;
-                    } else {
-                        try {
-                            //TODO: we should speculative determine if there's a match
-                            //based on arity - if yes, method is applicable.
-                            types.findDescriptorType(pt);
-                        } catch (Types.FunctionDescriptorLookupError ex) {
-                            checkContext.report(null, ex.getDiagnostic());
-                        }
+            @Override
+            public void visitReference(JCMemberReference tree) {
+                Check.CheckContext checkContext = resultInfo.checkContext;
+                Type pt = resultInfo.pt;
+                if (inferenceContext.inferencevars.contains(pt)) {
+                    //ok
+                    return;
+                } else {
+                    try {
+                        //TODO: we should speculative determine if there's a match
+                        //based on arity - if yes, method is applicable.
+                        types.findDescriptorType(pt);
+                    } catch (Types.FunctionDescriptorLookupError ex) {
+                        checkContext.report(null, ex.getDiagnostic());
                     }
                 }
             }
@@ -498,7 +524,7 @@
 
     /** an empty deferred attribution context - all methods throw exceptions */
     final DeferredAttrContext emptyDeferredAttrContext =
-            new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null) {
+            new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null, null, null) {
                 @Override
                 void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
                     Assert.error("Empty deferred context!");
@@ -521,7 +547,8 @@
 
         protected DeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
             super(String.format("deferredTypeMap[%s]", mode));
-            this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase, infer.emptyContext);
+            this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase,
+                    infer.emptyContext, emptyDeferredAttrContext, types.noWarnings);
         }
 
         protected boolean validState(DeferredType dt) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java
index c6e1894..216cf3c 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,22 +25,30 @@
 
 package com.sun.tools.javac.comp;
 
-import com.sun.tools.javac.code.*;
-import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
-import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
-import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
-import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCTypeCast;
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
+import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph;
+import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node;
+import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
+import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
 
 import static com.sun.tools.javac.code.TypeTag.*;
 
@@ -55,19 +63,15 @@
     protected static final Context.Key<Infer> inferKey =
         new Context.Key<Infer>();
 
-    /** A value for prototypes that admit any type, including polymorphic ones. */
-    public static final Type anyPoly = new Type(NONE, null);
-
+    Resolve rs;
+    Check chk;
     Symtab syms;
     Types types;
-    Check chk;
-    Resolve rs;
-    DeferredAttr deferredAttr;
-    Log log;
     JCDiagnostic.Factory diags;
+    Log log;
 
-    /** Should we inject return-type constraints earlier? */
-    boolean allowEarlyReturnConstraints;
+    /** should the graph solver be used? */
+    boolean allowGraphInference;
 
     public static Infer instance(Context context) {
         Infer instance = context.get(inferKey);
@@ -78,17 +82,22 @@
 
     protected Infer(Context context) {
         context.put(inferKey, this);
+
+        rs = Resolve.instance(context);
+        chk = Check.instance(context);
         syms = Symtab.instance(context);
         types = Types.instance(context);
-        rs = Resolve.instance(context);
-        deferredAttr = DeferredAttr.instance(context);
-        log = Log.instance(context);
-        chk = Check.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
+        log = Log.instance(context);
         inferenceException = new InferenceException(diags);
-        allowEarlyReturnConstraints = Source.instance(context).allowEarlyReturnConstraints();
+        Options options = Options.instance(context);
+        allowGraphInference = Source.instance(context).allowGraphInference()
+                && options.isUnset("useLegacyInference");
     }
 
+    /** A value for prototypes that admit any type, including polymorphic ones. */
+    public static final Type anyPoly = new Type(NONE, null);
+
    /**
     * This exception class is design to store a list of diagnostics corresponding
     * to inference errors that can arise during a method applicability check.
@@ -118,140 +127,12 @@
         }
     }
 
-    final InferenceException inferenceException;
+    protected final InferenceException inferenceException;
 
-/***************************************************************************
- * Mini/Maximization of UndetVars
- ***************************************************************************/
-
-    /** Instantiate undetermined type variable to its minimal upper bound.
-     *  Throw a NoInstanceException if this not possible.
-     */
-   void maximizeInst(UndetVar that, Warner warn) throws InferenceException {
-        List<Type> hibounds = Type.filter(that.getBounds(InferenceBound.UPPER), boundFilter);
-        if (that.getBounds(InferenceBound.EQ).isEmpty()) {
-            if (hibounds.isEmpty())
-                that.inst = syms.objectType;
-            else if (hibounds.tail.isEmpty())
-                that.inst = hibounds.head;
-            else
-                that.inst = types.glb(hibounds);
-        } else {
-            that.inst = that.getBounds(InferenceBound.EQ).head;
-        }
-        if (that.inst == null ||
-            that.inst.isErroneous())
-            throw inferenceException
-                .setMessage("no.unique.maximal.instance.exists",
-                            that.qtype, hibounds);
-    }
-
-    private Filter<Type> boundFilter = new Filter<Type>() {
-        @Override
-        public boolean accepts(Type t) {
-            return !t.isErroneous() && !t.hasTag(BOT);
-        }
-    };
-
-    /** Instantiate undetermined type variable to the lub of all its lower bounds.
-     *  Throw a NoInstanceException if this not possible.
-     */
-    void minimizeInst(UndetVar that, Warner warn) throws InferenceException {
-        List<Type> lobounds = Type.filter(that.getBounds(InferenceBound.LOWER), boundFilter);
-        if (that.getBounds(InferenceBound.EQ).isEmpty()) {
-            if (lobounds.isEmpty()) {
-                //do nothing - the inference variable is under-constrained
-                return;
-            } else if (lobounds.tail.isEmpty())
-                that.inst = lobounds.head.isPrimitive() ? syms.errType : lobounds.head;
-            else {
-                that.inst = types.lub(lobounds);
-            }
-            if (that.inst == null || that.inst.hasTag(ERROR))
-                    throw inferenceException
-                        .setMessage("no.unique.minimal.instance.exists",
-                                    that.qtype, lobounds);
-        } else {
-            that.inst = that.getBounds(InferenceBound.EQ).head;
-        }
-    }
-
-/***************************************************************************
- * Exported Methods
- ***************************************************************************/
-
+    // <editor-fold defaultstate="collapsed" desc="Inference routines">
     /**
-     * Instantiate uninferred inference variables (JLS 15.12.2.8). First
-     * if the method return type is non-void, we derive constraints from the
-     * expected type - then we use declared bound well-formedness to derive additional
-     * constraints. If no instantiation exists, or if several incomparable
-     * best instantiations exist throw a NoInstanceException.
-     */
-    public void instantiateUninferred(DiagnosticPosition pos,
-            InferenceContext inferenceContext,
-            MethodType mtype,
-            Attr.ResultInfo resultInfo,
-            Warner warn) throws InferenceException {
-        while (true) {
-            boolean stuck = true;
-            for (Type t : inferenceContext.undetvars) {
-                UndetVar uv = (UndetVar)t;
-                if (uv.inst == null && (uv.getBounds(InferenceBound.EQ).nonEmpty() ||
-                        !inferenceContext.free(uv.getBounds(InferenceBound.UPPER)))) {
-                    maximizeInst((UndetVar)t, warn);
-                    stuck = false;
-                }
-            }
-            if (inferenceContext.restvars().isEmpty()) {
-                //all variables have been instantiated - exit
-                break;
-            } else if (stuck) {
-                //some variables could not be instantiated because of cycles in
-                //upper bounds - provide a (possibly recursive) default instantiation
-                instantiateAsUninferredVars(inferenceContext);
-                break;
-            } else {
-                //some variables have been instantiated - replace newly instantiated
-                //variables in remaining upper bounds and continue
-                for (Type t : inferenceContext.undetvars) {
-                    UndetVar uv = (UndetVar)t;
-                    uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types);
-                }
-            }
-        }
-    }
-
-    /**
-     * Infer cyclic inference variables as described in 15.12.2.8.
-     */
-    private void instantiateAsUninferredVars(InferenceContext inferenceContext) {
-        ListBuffer<Type> todo = ListBuffer.lb();
-        //step 1 - create fresh tvars
-        for (Type t : inferenceContext.undetvars) {
-            UndetVar uv = (UndetVar)t;
-            if (uv.inst == null) {
-                TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
-                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null);
-                todo.append(uv);
-                uv.inst = fresh_tvar.type;
-            }
-        }
-        //step 2 - replace fresh tvars in their bounds
-        List<Type> formals = inferenceContext.inferenceVars();
-        for (Type t : todo) {
-            UndetVar uv = (UndetVar)t;
-            TypeVar ct = (TypeVar)uv.inst;
-            ct.bound = types.glb(inferenceContext.asInstTypes(types.getBounds(ct), types));
-            if (ct.bound.isErroneous()) {
-                //report inference error if glb fails
-                reportBoundError(uv, BoundErrorKind.BAD_UPPER);
-            }
-            formals = formals.tail;
-        }
-    }
-
-    /** Instantiate a generic method type by finding instantiations for all its
-     * inference variables so that it can be applied to a given argument type list.
+     * Main inference entry point - instantiate a generic method type
+     * using given argument types and (possibly) an expected target-type.
      */
     public Type instantiateMethod(Env<AttrContext> env,
                                   List<Type> tvars,
@@ -265,259 +146,146 @@
                                   Resolve.MethodCheck methodCheck,
                                   Warner warn) throws InferenceException {
         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
-        final InferenceContext inferenceContext = new InferenceContext(tvars, this, true);
+        final InferenceContext inferenceContext = new InferenceContext(tvars);
         inferenceException.clear();
-
-        DeferredAttr.DeferredAttrContext deferredAttrContext =
-                resolveContext.deferredAttrContext(msym, inferenceContext);
-
         try {
-            methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn);
+            DeferredAttr.DeferredAttrContext deferredAttrContext =
+                    resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
 
-            if (resultInfo != null && allowEarlyReturnConstraints &&
+            methodCheck.argumentsAcceptable(env, deferredAttrContext,
+                    argtypes, mt.getParameterTypes(), warn);
+
+            if (allowGraphInference &&
+                    resultInfo != null &&
                     !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
-                generateReturnConstraints(mt, inferenceContext, resultInfo);
+                //inject return constraints earlier
+                checkWithinBounds(inferenceContext, warn); //propagation
+                generateReturnConstraints(resultInfo, mt, inferenceContext);
+                //propagate outwards if needed
+                if (resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
+                    //propagate inference context outwards and exit
+                    inferenceContext.dupTo(resultInfo.checkContext.inferenceContext());
+                    deferredAttrContext.complete();
+                    return mt;
+                }
             }
 
             deferredAttrContext.complete();
 
             // minimize as yet undetermined type variables
-            for (Type t : inferenceContext.undetvars) {
-                minimizeInst((UndetVar)t, warn);
+            if (allowGraphInference) {
+                inferenceContext.solve(warn);
+            } else {
+                inferenceContext.solveLegacy(true, warn, LegacyInferenceSteps.EQ_LOWER.steps); //minimizeInst
             }
 
-            checkWithinBounds(inferenceContext, warn);
+            mt = (MethodType)inferenceContext.asInstType(mt);
 
-            mt = (MethodType)inferenceContext.asInstType(mt, types);
+            if (!allowGraphInference &&
+                    inferenceContext.restvars().nonEmpty() &&
+                    resultInfo != null &&
+                    !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+                generateReturnConstraints(resultInfo, mt, inferenceContext);
+                inferenceContext.solveLegacy(false, warn, LegacyInferenceSteps.EQ_UPPER.steps); //maximizeInst
+                mt = (MethodType)inferenceContext.asInstType(mt);
+            }
 
-            List<Type> restvars = inferenceContext.restvars();
-
-            if (!restvars.isEmpty()) {
-                if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
-                    if (!allowEarlyReturnConstraints) {
-                        generateReturnConstraints(mt, inferenceContext, resultInfo);
-                    }
-                    instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn);
-                    checkWithinBounds(inferenceContext, warn);
-                    mt = (MethodType)inferenceContext.asInstType(mt, types);
-                    if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) {
-                        log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt);
-                    }
-                }
+            if (resultInfo != null && rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) {
+                log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt);
             }
 
             // return instantiated version of method type
             return mt;
         } finally {
-            inferenceContext.notifyChange(types);
-        }
-    }
-    //where
-        void generateReturnConstraints(Type mt, InferenceContext inferenceContext, Attr.ResultInfo resultInfo) {
-            if (resultInfo != null) {
-                Type to = resultInfo.pt;
-                if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
-                    to = mt.getReturnType().isPrimitiveOrVoid() ?
-                            mt.getReturnType() : syms.objectType;
-                }
-                Type qtype1 = inferenceContext.asFree(mt.getReturnType(), types);
-                Warner retWarn = new Warner();
-                if (!resultInfo.checkContext.compatible(qtype1, qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to, retWarn) ||
-                        //unchecked conversion is not allowed
-                        retWarn.hasLint(Lint.LintCategory.UNCHECKED)) {
-                    throw inferenceException
-                            .setMessage("infer.no.conforming.instance.exists",
-                            inferenceContext.restvars(), mt.getReturnType(), to);
-                }
-            }
-        }
-
-    /** check that type parameters are within their bounds.
-     */
-    void checkWithinBounds(InferenceContext inferenceContext,
-                           Warner warn) throws InferenceException {
-        //step 1 - check compatibility of instantiated type w.r.t. initial bounds
-        for (Type t : inferenceContext.undetvars) {
-            UndetVar uv = (UndetVar)t;
-            uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types);
-            checkCompatibleUpperBounds(uv, inferenceContext.inferenceVars());
-            if (!inferenceContext.restvars().contains(uv.qtype)) {
-                Type inst = inferenceContext.asInstType(t, types);
-                for (Type u : uv.getBounds(InferenceBound.UPPER)) {
-                    if (!types.isSubtypeUnchecked(inst, inferenceContext.asFree(u, types), warn)) {
-                        reportBoundError(uv, BoundErrorKind.UPPER);
-                    }
-                }
-                for (Type l : uv.getBounds(InferenceBound.LOWER)) {
-                    Assert.check(!inferenceContext.free(l));
-                    if (!types.isSubtypeUnchecked(l, inst, warn)) {
-                        reportBoundError(uv, BoundErrorKind.LOWER);
-                    }
-                }
-                for (Type e : uv.getBounds(InferenceBound.EQ)) {
-                    Assert.check(!inferenceContext.free(e));
-                    if (!types.isSameType(inst, e)) {
-                        reportBoundError(uv, BoundErrorKind.EQ);
-                    }
-                }
-            }
-        }
-
-        //step 2 - check that eq bounds are consistent w.r.t. eq/lower bounds
-        for (Type t : inferenceContext.undetvars) {
-            UndetVar uv = (UndetVar)t;
-            //check eq bounds consistency
-            Type eq = null;
-            for (Type e : uv.getBounds(InferenceBound.EQ)) {
-                Assert.check(!inferenceContext.free(e));
-                if (eq != null && !types.isSameType(e, eq)) {
-                    reportBoundError(uv, BoundErrorKind.EQ);
-                }
-                eq = e;
-                for (Type l : uv.getBounds(InferenceBound.LOWER)) {
-                    Assert.check(!inferenceContext.free(l));
-                    if (!types.isSubtypeUnchecked(l, e, warn)) {
-                        reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
-                    }
-                }
-                for (Type u : uv.getBounds(InferenceBound.UPPER)) {
-                    if (inferenceContext.free(u)) continue;
-                    if (!types.isSubtypeUnchecked(e, u, warn)) {
-                        reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
-                    }
-                }
+            if (resultInfo != null || !allowGraphInference) {
+                inferenceContext.notifyChange();
+            } else {
+                inferenceContext.notifyChange(inferenceContext.boundedVars());
             }
         }
     }
 
-    void checkCompatibleUpperBounds(UndetVar uv, List<Type> tvars) {
-        // VGJ: sort of inlined maximizeInst() below.  Adding
-        // bounds can cause lobounds that are above hibounds.
-        ListBuffer<Type> hiboundsNoVars = ListBuffer.lb();
-        for (Type t : Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter)) {
-            if (!t.containsAny(tvars)) {
-                hiboundsNoVars.append(t);
-            }
-        }
-        List<Type> hibounds = hiboundsNoVars.toList();
-        Type hb = null;
-        if (hibounds.isEmpty())
-            hb = syms.objectType;
-        else if (hibounds.tail.isEmpty())
-            hb = hibounds.head;
-        else
-            hb = types.glb(hibounds);
-        if (hb == null || hb.isErroneous())
-            reportBoundError(uv, BoundErrorKind.BAD_UPPER);
-    }
-
-    enum BoundErrorKind {
-        BAD_UPPER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("incompatible.upper.bounds", uv.qtype,
-                        uv.getBounds(InferenceBound.UPPER));
-            }
-        },
-        BAD_EQ_UPPER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("incompatible.eq.upper.bounds", uv.qtype,
-                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.UPPER));
-            }
-        },
-        BAD_EQ_LOWER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype,
-                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER));
-            }
-        },
-        UPPER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst,
-                        uv.getBounds(InferenceBound.UPPER));
-            }
-        },
-        LOWER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst,
-                        uv.getBounds(InferenceBound.LOWER));
-            }
-        },
-        EQ() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst,
-                        uv.getBounds(InferenceBound.EQ));
-            }
-        };
-
-        abstract InapplicableMethodException setMessage(InferenceException ex, UndetVar uv);
-    }
-    //where
-    void reportBoundError(UndetVar uv, BoundErrorKind bk) {
-        throw bk.setMessage(inferenceException, uv);
-    }
-
-    // <editor-fold desc="functional interface instantiation">
     /**
-     * This method is used to infer a suitable target functional interface in case
-     * the original parameterized interface contains wildcards. An inference process
-     * is applied so that wildcard bounds, as well as explicit lambda/method ref parameters
-     * (where applicable) are used to constraint the solution.
+     * Generate constraints from the generic method's return type. If the method
+     * call occurs in a context where a type T is expected, use the expected
+     * type to derive more constraints on the generic method inference variables.
      */
-    public Type instantiateFunctionalInterface(DiagnosticPosition pos, Type funcInterface,
-            List<Type> paramTypes, Check.CheckContext checkContext) {
-        if (types.capture(funcInterface) == funcInterface) {
-            //if capture doesn't change the type then return the target unchanged
-            //(this means the target contains no wildcards!)
-            return funcInterface;
-        } else {
-            Type formalInterface = funcInterface.tsym.type;
-            InferenceContext funcInterfaceContext =
-                    new InferenceContext(funcInterface.tsym.type.getTypeArguments(), this, false);
-            Assert.check(paramTypes != null);
-            //get constraints from explicit params (this is done by
-            //checking that explicit param types are equal to the ones
-            //in the functional interface descriptors)
-            List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes();
-            if (descParameterTypes.size() != paramTypes.size()) {
-                checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda"));
-                return types.createErrorType(funcInterface);
-            }
-            for (Type p : descParameterTypes) {
-                if (!types.isSameType(funcInterfaceContext.asFree(p, types), paramTypes.head)) {
-                    checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
-                    return types.createErrorType(funcInterface);
-                }
-                paramTypes = paramTypes.tail;
-            }
-            List<Type> actualTypeargs = funcInterface.getTypeArguments();
-            for (Type t : funcInterfaceContext.undetvars) {
-                UndetVar uv = (UndetVar)t;
-                minimizeInst(uv, types.noWarnings);
-                if (uv.inst == null &&
-                        Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) {
-                    maximizeInst(uv, types.noWarnings);
-                }
-                if (uv.inst == null) {
-                    uv.inst = actualTypeargs.head;
-                }
-                actualTypeargs = actualTypeargs.tail;
-            }
-            Type owntype = funcInterfaceContext.asInstType(formalInterface, types);
-            if (!chk.checkValidGenericType(owntype)) {
-                //if the inferred functional interface type is not well-formed,
-                //or if it's not a subtype of the original target, issue an error
-                checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
-            }
-            return owntype;
+    void generateReturnConstraints(Attr.ResultInfo resultInfo,
+            MethodType mt, InferenceContext inferenceContext) {
+        Type qtype1 = inferenceContext.asFree(mt.getReturnType());
+        Type to = returnConstraintTarget(qtype1, resultInfo.pt);
+        Assert.check(allowGraphInference || !resultInfo.checkContext.inferenceContext().free(to),
+                "legacy inference engine cannot handle constraints on both sides of a subtyping assertion");
+        //we need to skip capture?
+        Warner retWarn = new Warner();
+        if (!resultInfo.checkContext.compatible(qtype1, resultInfo.checkContext.inferenceContext().asFree(to), retWarn) ||
+                //unchecked conversion is not allowed
+                retWarn.hasLint(Lint.LintCategory.UNCHECKED)) {
+            throw inferenceException
+                    .setMessage("infer.no.conforming.instance.exists",
+                    inferenceContext.restvars(), mt.getReturnType(), to);
         }
     }
-    // </editor-fold>
+    //where
+        private Type returnConstraintTarget(Type from, Type to) {
+            if (from.hasTag(VOID)) {
+                return syms.voidType;
+            } else if (to.hasTag(NONE)) {
+                return from.isPrimitive() ? from : syms.objectType;
+            } else if (from.hasTag(UNDETVAR) && to.isPrimitive()) {
+                if (!allowGraphInference) {
+                    //if legacy, just return boxed type
+                    return types.boxedClass(to).type;
+                }
+                //if graph inference we need to skip conflicting boxed bounds...
+                UndetVar uv = (UndetVar)from;
+                for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
+                    Type boundAsPrimitive = types.unboxedType(t);
+                    if (boundAsPrimitive == null) continue;
+                    if (types.isConvertible(boundAsPrimitive, to)) {
+                        //effectively skip return-type constraint generation (compatibility)
+                        return syms.objectType;
+                    }
+                }
+                return types.boxedClass(to).type;
+            } else {
+                return to;
+            }
+        }
+
+    /**
+      * Infer cyclic inference variables as described in 15.12.2.8.
+      */
+    private void instantiateAsUninferredVars(List<Type> vars, InferenceContext inferenceContext) {
+        ListBuffer<Type> todo = ListBuffer.lb();
+        //step 1 - create fresh tvars
+        for (Type t : vars) {
+            UndetVar uv = (UndetVar)inferenceContext.asFree(t);
+            List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER);
+            if (Type.containsAny(upperBounds, vars)) {
+                TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
+                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null);
+                todo.append(uv);
+                uv.inst = fresh_tvar.type;
+            } else if (upperBounds.nonEmpty()) {
+                uv.inst = types.glb(upperBounds);
+            } else {
+                uv.inst = syms.objectType;
+            }
+        }
+        //step 2 - replace fresh tvars in their bounds
+        List<Type> formals = vars;
+        for (Type t : todo) {
+            UndetVar uv = (UndetVar)t;
+            TypeVar ct = (TypeVar)uv.inst;
+            ct.bound = types.glb(inferenceContext.asInstTypes(types.getBounds(ct)));
+            if (ct.bound.isErroneous()) {
+                //report inference error if glb fails
+                reportBoundError(uv, BoundErrorKind.BAD_UPPER);
+            }
+            formals = formals.tail;
+        }
+    }
 
     /**
      * Compute a synthetic method type corresponding to the requested polymorphic
@@ -571,7 +339,7 @@
         class ImplicitArgType extends DeferredAttr.DeferredTypeMap {
 
             public ImplicitArgType(Symbol msym, Resolve.MethodResolutionPhase phase) {
-                deferredAttr.super(AttrMode.SPECULATIVE, msym, phase);
+                rs.deferredAttr.super(AttrMode.SPECULATIVE, msym, phase);
             }
 
             public Type apply(Type t) {
@@ -585,23 +353,927 @@
         }
 
     /**
-     * Mapping that turns inference variables into undet vars
-     * (used by inference context)
+      * This method is used to infer a suitable target SAM in case the original
+      * SAM type contains one or more wildcards. An inference process is applied
+      * so that wildcard bounds, as well as explicit lambda/method ref parameters
+      * (where applicable) are used to constraint the solution.
+      */
+    public Type instantiateFunctionalInterface(DiagnosticPosition pos, Type funcInterface,
+            List<Type> paramTypes, Check.CheckContext checkContext) {
+        if (types.capture(funcInterface) == funcInterface) {
+            //if capture doesn't change the type then return the target unchanged
+            //(this means the target contains no wildcards!)
+            return funcInterface;
+        } else {
+            Type formalInterface = funcInterface.tsym.type;
+            InferenceContext funcInterfaceContext =
+                    new InferenceContext(funcInterface.tsym.type.getTypeArguments());
+
+            Assert.check(paramTypes != null);
+            //get constraints from explicit params (this is done by
+            //checking that explicit param types are equal to the ones
+            //in the functional interface descriptors)
+            List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes();
+            if (descParameterTypes.size() != paramTypes.size()) {
+                checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda"));
+                return types.createErrorType(funcInterface);
+            }
+            for (Type p : descParameterTypes) {
+                if (!types.isSameType(funcInterfaceContext.asFree(p), paramTypes.head)) {
+                    checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
+                    return types.createErrorType(funcInterface);
+                }
+                paramTypes = paramTypes.tail;
+            }
+
+            try {
+                funcInterfaceContext.solve(funcInterfaceContext.boundedVars(), types.noWarnings);
+            } catch (InferenceException ex) {
+                checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
+            }
+
+            List<Type> actualTypeargs = funcInterface.getTypeArguments();
+            for (Type t : funcInterfaceContext.undetvars) {
+                UndetVar uv = (UndetVar)t;
+                if (uv.inst == null) {
+                    uv.inst = actualTypeargs.head;
+                }
+                actualTypeargs = actualTypeargs.tail;
+            }
+
+            Type owntype = funcInterfaceContext.asInstType(formalInterface);
+            if (!chk.checkValidGenericType(owntype)) {
+                //if the inferred functional interface type is not well-formed,
+                //or if it's not a subtype of the original target, issue an error
+                checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
+            }
+            return owntype;
+        }
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Bound checking">
+    /**
+     * Check bounds and perform incorporation
      */
-    class FromTypeVarFun extends Mapping {
+    void checkWithinBounds(InferenceContext inferenceContext,
+                             Warner warn) throws InferenceException {
+        MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars);
+        try {
+            while (true) {
+                mlistener.reset();
+                if (!allowGraphInference) {
+                    //in legacy mode we lack of transitivity, so bound check
+                    //cannot be run in parallel with other incoprporation rounds
+                    for (Type t : inferenceContext.undetvars) {
+                        UndetVar uv = (UndetVar)t;
+                        IncorporationStep.CHECK_BOUNDS.apply(uv, inferenceContext, warn);
+                    }
+                }
+                for (Type t : inferenceContext.undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    //bound incorporation
+                    EnumSet<IncorporationStep> incorporationSteps = allowGraphInference ?
+                            incorporationStepsGraph : incorporationStepsLegacy;
+                    for (IncorporationStep is : incorporationSteps) {
+                        is.apply(uv, inferenceContext, warn);
+                    }
+                }
+                if (!mlistener.changed || !allowGraphInference) break;
+            }
+        }
+        finally {
+            mlistener.detach();
+        }
+    }
+    //where
+        /**
+         * This listener keeps track of changes on a group of inference variable
+         * bounds. Note: the listener must be detached (calling corresponding
+         * method) to make sure that the underlying inference variable is
+         * left in a clean state.
+         */
+        class MultiUndetVarListener implements UndetVar.UndetVarListener {
 
-        boolean includeBounds;
+            int rounds;
+            boolean changed;
+            List<Type> undetvars;
 
-        FromTypeVarFun(boolean includeBounds) {
-            super("fromTypeVarFunWithBounds");
-            this.includeBounds = includeBounds;
+            public MultiUndetVarListener(List<Type> undetvars) {
+                this.undetvars = undetvars;
+                for (Type t : undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    uv.listener = this;
+                }
+            }
+
+            public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
+                //avoid non-termination
+                if (rounds < MAX_INCORPORATION_STEPS) {
+                    changed = true;
+                }
+            }
+
+            void reset() {
+                rounds++;
+                changed = false;
+            }
+
+            void detach() {
+                for (Type t : undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    uv.listener = null;
+                }
+            }
+        };
+
+        /** max number of incorporation rounds */
+        static final int MAX_INCORPORATION_STEPS = 100;
+
+    /**
+     * This enumeration defines an entry point for doing inference variable
+     * bound incorporation - it can be used to inject custom incorporation
+     * logic into the basic bound checking routine
+     */
+    enum IncorporationStep {
+        /**
+         * Performs basic bound checking - i.e. is the instantiated type for a given
+         * inference variable compatible with its bounds?
+         */
+        CHECK_BOUNDS() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), infer.types);
+                infer.checkCompatibleUpperBounds(uv, inferenceContext);
+                if (uv.inst != null) {
+                    Type inst = uv.inst;
+                    for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                        if (!infer.types.isSubtypeUnchecked(inst, inferenceContext.asFree(u), warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.UPPER);
+                        }
+                    }
+                    for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                        if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), inst, warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.LOWER);
+                        }
+                    }
+                    for (Type e : uv.getBounds(InferenceBound.EQ)) {
+                        if (!infer.types.isSameType(inst, inferenceContext.asFree(e))) {
+                            infer.reportBoundError(uv, BoundErrorKind.EQ);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Check consistency of equality constraints. This is a slightly more aggressive
+         * inference routine that is designed as to maximize compatibility with JDK 7.
+         * Note: this is not used in graph mode.
+         */
+        EQ_CHECK_LEGACY() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                Type eq = null;
+                for (Type e : uv.getBounds(InferenceBound.EQ)) {
+                    Assert.check(!inferenceContext.free(e));
+                    if (eq != null && !infer.types.isSameType(e, eq)) {
+                        infer.reportBoundError(uv, BoundErrorKind.EQ);
+                    }
+                    eq = e;
+                    for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                        Assert.check(!inferenceContext.free(l));
+                        if (!infer.types.isSubtypeUnchecked(l, e, warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
+                        }
+                    }
+                    for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                        if (inferenceContext.free(u)) continue;
+                        if (!infer.types.isSubtypeUnchecked(e, u, warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Check consistency of equality constraints.
+         */
+        EQ_CHECK() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type e : uv.getBounds(InferenceBound.EQ)) {
+                    if (e.containsAny(inferenceContext.inferenceVars())) continue;
+                    for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                        if (!infer.types.isSubtypeUnchecked(e, inferenceContext.asFree(u), warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
+                        }
+                    }
+                    for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                        if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), e, warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha <: T} and {@code alpha :> S}
+         * perform {@code S <: T} (which could lead to new bounds).
+         */
+        CROSS_UPPER_LOWER() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
+                    for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
+                        if (!inferenceContext.inferenceVars().contains(b1) &&
+                                !inferenceContext.inferenceVars().contains(b2) &&
+                                infer.types.asSuper(b2, b1.tsym) != null) {
+                            infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha <: T} and {@code alpha == S}
+         * perform {@code S <: T} (which could lead to new bounds).
+         */
+        CROSS_UPPER_EQ() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
+                    for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
+                        if (!inferenceContext.inferenceVars().contains(b1) &&
+                                !inferenceContext.inferenceVars().contains(b2) &&
+                                infer.types.asSuper(b2, b1.tsym) != null) {
+                            infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha :> S} and {@code alpha == T}
+         * perform {@code S <: T} (which could lead to new bounds).
+         */
+        CROSS_EQ_LOWER() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
+                    for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
+                        if (!inferenceContext.inferenceVars().contains(b1) &&
+                                !inferenceContext.inferenceVars().contains(b2) &&
+                                infer.types.asSuper(b2, b1.tsym) != null) {
+                            infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha <: beta} propagate lower bounds
+         * from alpha to beta; also propagate upper bounds from beta to alpha.
+         */
+        PROP_UPPER() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b : uv.getBounds(InferenceBound.UPPER)) {
+                    if (inferenceContext.inferenceVars().contains(b)) {
+                        UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
+                        //alpha <: beta
+                        //1. copy alpha's lower to beta's
+                        for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                            uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
+                        }
+                        //2. copy beta's upper to alpha's
+                        for (Type u : uv2.getBounds(InferenceBound.UPPER)) {
+                            uv.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha :> beta} propagate lower bounds
+         * from beta to alpha; also propagate upper bounds from alpha to beta.
+         */
+        PROP_LOWER() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b : uv.getBounds(InferenceBound.LOWER)) {
+                    if (inferenceContext.inferenceVars().contains(b)) {
+                        UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
+                        //alpha :> beta
+                        //1. copy alpha's upper to beta's
+                        for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                            uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
+                        }
+                        //2. copy beta's lower to alpha's
+                        for (Type l : uv2.getBounds(InferenceBound.LOWER)) {
+                            uv.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha == beta} propagate lower/upper
+         * bounds from alpha to beta and back.
+         */
+        PROP_EQ() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b : uv.getBounds(InferenceBound.EQ)) {
+                    if (inferenceContext.inferenceVars().contains(b)) {
+                        UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
+                        //alpha == beta
+                        //1. copy all alpha's bounds to beta's
+                        for (InferenceBound ib : InferenceBound.values()) {
+                            for (Type b2 : uv.getBounds(ib)) {
+                                if (b2 != uv2) {
+                                    uv2.addBound(ib, inferenceContext.asInstType(b2), infer.types);
+                                }
+                            }
+                        }
+                        //2. copy all beta's bounds to alpha's
+                        for (InferenceBound ib : InferenceBound.values()) {
+                            for (Type b2 : uv2.getBounds(ib)) {
+                                if (b2 != uv) {
+                                    uv.addBound(ib, inferenceContext.asInstType(b2), infer.types);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        };
+
+        abstract void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn);
+    }
+
+    /** incorporation steps to be executed when running in legacy mode */
+    EnumSet<IncorporationStep> incorporationStepsLegacy = EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY);
+
+    /** incorporation steps to be executed when running in graph mode */
+    EnumSet<IncorporationStep> incorporationStepsGraph =
+            EnumSet.complementOf(EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY));
+
+    /**
+     * Make sure that the upper bounds we got so far lead to a solvable inference
+     * variable by making sure that a glb exists.
+     */
+    void checkCompatibleUpperBounds(UndetVar uv, InferenceContext inferenceContext) {
+        List<Type> hibounds =
+                Type.filter(uv.getBounds(InferenceBound.UPPER), new BoundFilter(inferenceContext));
+        Type hb = null;
+        if (hibounds.isEmpty())
+            hb = syms.objectType;
+        else if (hibounds.tail.isEmpty())
+            hb = hibounds.head;
+        else
+            hb = types.glb(hibounds);
+        if (hb == null || hb.isErroneous())
+            reportBoundError(uv, BoundErrorKind.BAD_UPPER);
+    }
+    //where
+        protected static class BoundFilter implements Filter<Type> {
+
+            InferenceContext inferenceContext;
+
+            public BoundFilter(InferenceContext inferenceContext) {
+                this.inferenceContext = inferenceContext;
+            }
+
+            @Override
+            public boolean accepts(Type t) {
+                return !t.isErroneous() && !inferenceContext.free(t) &&
+                        !t.hasTag(BOT);
+            }
+        };
+
+    /**
+     * This enumeration defines all possible bound-checking related errors.
+     */
+    enum BoundErrorKind {
+        /**
+         * The (uninstantiated) inference variable has incompatible upper bounds.
+         */
+        BAD_UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.upper.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.UPPER));
+            }
+        },
+        /**
+         * An equality constraint is not compatible with an upper bound.
+         */
+        BAD_EQ_UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.eq.upper.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.UPPER));
+            }
+        },
+        /**
+         * An equality constraint is not compatible with a lower bound.
+         */
+        BAD_EQ_LOWER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER));
+            }
+        },
+        /**
+         * Instantiated inference variable is not compatible with an upper bound.
+         */
+        UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.UPPER));
+            }
+        },
+        /**
+         * Instantiated inference variable is not compatible with a lower bound.
+         */
+        LOWER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.LOWER));
+            }
+        },
+        /**
+         * Instantiated inference variable is not compatible with an equality constraint.
+         */
+        EQ() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.EQ));
+            }
+        };
+
+        abstract InapplicableMethodException setMessage(InferenceException ex, UndetVar uv);
+    }
+
+    /**
+     * Report a bound-checking error of given kind
+     */
+    void reportBoundError(UndetVar uv, BoundErrorKind bk) {
+        throw bk.setMessage(inferenceException, uv);
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Inference engine">
+    /**
+     * Graph inference strategy - act as an input to the inference solver; a strategy is
+     * composed of two ingredients: (i) find a node to solve in the inference graph,
+     * and (ii) tell th engine when we are done fixing inference variables
+     */
+    interface GraphStrategy {
+        /**
+         * Pick the next node (leaf) to solve in the graph
+         */
+        Node pickNode(InferenceGraph g);
+        /**
+         * Is this the last step?
+         */
+        boolean done();
+    }
+
+    /**
+     * Simple solver strategy class that locates all leaves inside a graph
+     * and picks the first leaf as the next node to solve
+     */
+    abstract class LeafSolver implements GraphStrategy {
+        public Node pickNode(InferenceGraph g) {
+                        Assert.check(!g.nodes.isEmpty(), "No nodes to solve!");
+            return g.nodes.get(0);
+        }
+    }
+
+    /**
+     * This solver uses an heuristic to pick the best leaf - the heuristic
+     * tries to select the node that has maximal probability to contain one
+     * or more inference variables in a given list
+     */
+    abstract class BestLeafSolver extends LeafSolver {
+
+        List<Type> varsToSolve;
+
+        BestLeafSolver(List<Type> varsToSolve) {
+            this.varsToSolve = varsToSolve;
         }
 
-        public Type apply(Type t) {
-            if (t.hasTag(TYPEVAR)) return new UndetVar((TypeVar)t, types, includeBounds);
-            else return t.map(this);
+        /**
+         * Computes the cost associated with a given node; the cost is computed
+         * as the total number of type-variables that should be eagerly instantiated
+         * in order to get to some of the variables in {@code varsToSolve} from
+         * a given node
+         */
+        void computeCostIfNeeded(Node n, Map<Node, Integer> costMap) {
+            if (costMap.containsKey(n)) {
+                return;
+            } else if (!Collections.disjoint(n.data, varsToSolve)) {
+                costMap.put(n, n.data.size());
+            } else {
+                int subcost = Integer.MAX_VALUE;
+                costMap.put(n, subcost); //avoid loops
+                for (Node n2 : n.getDependencies()) {
+                    computeCostIfNeeded(n2, costMap);
+                    subcost = Math.min(costMap.get(n2), subcost);
+                }
+                //update cost map to reflect real cost
+                costMap.put(n, subcost == Integer.MAX_VALUE ?
+                        Integer.MAX_VALUE :
+                        n.data.size() + subcost);
+            }
         }
-    };
+
+        /**
+         * Pick the leaf that minimize cost
+         */
+        @Override
+        public Node pickNode(final InferenceGraph g) {
+            final Map<Node, Integer> costMap = new HashMap<Node, Integer>();
+            ArrayList<Node> leaves = new ArrayList<Node>();
+            for (Node n : g.nodes) {
+                computeCostIfNeeded(n, costMap);
+                if (n.isLeaf(n)) {
+                    leaves.add(n);
+                }
+            }
+            Assert.check(!leaves.isEmpty(), "No nodes to solve!");
+            Collections.sort(leaves, new java.util.Comparator<Node>() {
+                public int compare(Node n1, Node n2) {
+                    return costMap.get(n1) - costMap.get(n2);
+                }
+            });
+            return leaves.get(0);
+        }
+    }
+
+    /**
+     * The inference process can be thought of as a sequence of steps. Each step
+     * instantiates an inference variable using a subset of the inference variable
+     * bounds, if certain condition are met. Decisions such as the sequence in which
+     * steps are applied, or which steps are to be applied are left to the inference engine.
+     */
+    enum InferenceStep {
+
+        /**
+         * Instantiate an inference variables using one of its (ground) equality
+         * constraints
+         */
+        EQ(InferenceBound.EQ) {
+            @Override
+            Type solve(UndetVar uv, InferenceContext inferenceContext) {
+                return filterBounds(uv, inferenceContext).head;
+            }
+        },
+        /**
+         * Instantiate an inference variables using its (ground) lower bounds. Such
+         * bounds are merged together using lub().
+         */
+        LOWER(InferenceBound.LOWER) {
+            @Override
+            Type solve(UndetVar uv, InferenceContext inferenceContext) {
+                Infer infer = inferenceContext.infer();
+                List<Type> lobounds = filterBounds(uv, inferenceContext);
+                Type owntype = infer.types.lub(lobounds);
+                if (owntype.hasTag(ERROR)) {
+                    throw infer.inferenceException
+                        .setMessage("no.unique.minimal.instance.exists",
+                                    uv.qtype, lobounds);
+                } else {
+                    return owntype;
+                }
+            }
+        },
+        /**
+         * Instantiate an inference variables using its (ground) upper bounds. Such
+         * bounds are merged together using glb().
+         */
+        UPPER(InferenceBound.UPPER) {
+            @Override
+            Type solve(UndetVar uv, InferenceContext inferenceContext) {
+                Infer infer = inferenceContext.infer();
+                List<Type> hibounds = filterBounds(uv, inferenceContext);
+                Type owntype = infer.types.glb(hibounds);
+                if (owntype.isErroneous()) {
+                    throw infer.inferenceException
+                        .setMessage("no.unique.maximal.instance.exists",
+                                    uv.qtype, hibounds);
+                } else {
+                    return owntype;
+                }
+            }
+        },
+        /**
+         * Like the former; the only difference is that this step can only be applied
+         * if all upper bounds are ground.
+         */
+        UPPER_LEGACY(InferenceBound.UPPER) {
+            @Override
+            public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
+                return !inferenceContext.free(t.getBounds(ib));
+            }
+
+            @Override
+            Type solve(UndetVar uv, InferenceContext inferenceContext) {
+                return UPPER.solve(uv, inferenceContext);
+            }
+        };
+
+        final InferenceBound ib;
+
+        InferenceStep(InferenceBound ib) {
+            this.ib = ib;
+        }
+
+        /**
+         * Find an instantiated type for a given inference variable within
+         * a given inference context
+         */
+        abstract Type solve(UndetVar uv, InferenceContext inferenceContext);
+
+        /**
+         * Can the inference variable be instantiated using this step?
+         */
+        public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
+            return filterBounds(t, inferenceContext).nonEmpty();
+        }
+
+        /**
+         * Return the subset of ground bounds in a given bound set (i.e. eq/lower/upper)
+         */
+        List<Type> filterBounds(UndetVar uv, InferenceContext inferenceContext) {
+            return Type.filter(uv.getBounds(ib), new BoundFilter(inferenceContext));
+        }
+    }
+
+    /**
+     * This enumeration defines the sequence of steps to be applied when the
+     * solver works in legacy mode. The steps in this enumeration reflect
+     * the behavior of old inference routine (see JLS SE 7 15.12.2.7/15.12.2.8).
+     */
+    enum LegacyInferenceSteps {
+
+        EQ_LOWER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER)),
+        EQ_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.UPPER_LEGACY));
+
+        final EnumSet<InferenceStep> steps;
+
+        LegacyInferenceSteps(EnumSet<InferenceStep> steps) {
+            this.steps = steps;
+        }
+    }
+
+    /**
+     * This enumeration defines the sequence of steps to be applied when the
+     * graph solver is used. This order is defined so as to maximize compatibility
+     * w.r.t. old inference routine (see JLS SE 7 15.12.2.7/15.12.2.8).
+     */
+    enum GraphInferenceSteps {
+
+        EQ(EnumSet.of(InferenceStep.EQ)),
+        EQ_LOWER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER)),
+        EQ_LOWER_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER, InferenceStep.UPPER));
+
+        final EnumSet<InferenceStep> steps;
+
+        GraphInferenceSteps(EnumSet<InferenceStep> steps) {
+            this.steps = steps;
+        }
+    }
+
+    /**
+     * This is the graph inference solver - the solver organizes all inference variables in
+     * a given inference context by bound dependencies - in the general case, such dependencies
+     * would lead to a cyclic directed graph (hence the name); the dependency info is used to build
+     * an acyclic graph, where all cyclic variables are bundled together. An inference
+     * step corresponds to solving a node in the acyclic graph - this is done by
+     * relying on a given strategy (see GraphStrategy).
+     */
+    class GraphSolver {
+
+        InferenceContext inferenceContext;
+        Warner warn;
+
+        GraphSolver(InferenceContext inferenceContext, Warner warn) {
+            this.inferenceContext = inferenceContext;
+            this.warn = warn;
+        }
+
+        /**
+         * Solve variables in a given inference context. The amount of variables
+         * to be solved, and the way in which the underlying acyclic graph is explored
+         * depends on the selected solver strategy.
+         */
+        void solve(GraphStrategy sstrategy) {
+            checkWithinBounds(inferenceContext, warn); //initial propagation of bounds
+            InferenceGraph inferenceGraph = new InferenceGraph();
+            while (!sstrategy.done()) {
+                InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
+                List<Type> varsToSolve = List.from(nodeToSolve.data);
+                inferenceContext.save();
+                try {
+                    //repeat until all variables are solved
+                    outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) {
+                        //for each inference phase
+                        for (GraphInferenceSteps step : GraphInferenceSteps.values()) {
+                            if (inferenceContext.solveBasic(varsToSolve, step.steps)) {
+                                checkWithinBounds(inferenceContext, warn);
+                                continue outer;
+                            }
+                        }
+                        //no progress
+                        throw inferenceException;
+                    }
+                }
+                catch (InferenceException ex) {
+                    inferenceContext.rollback();
+                    instantiateAsUninferredVars(varsToSolve, inferenceContext);
+                    checkWithinBounds(inferenceContext, warn);
+                }
+                inferenceGraph.deleteNode(nodeToSolve);
+            }
+        }
+
+        /**
+         * The dependencies between the inference variables that need to be solved
+         * form a (possibly cyclic) graph. This class reduces the original dependency graph
+         * to an acyclic version, where cyclic nodes are folded into a single 'super node'.
+         */
+        class InferenceGraph {
+
+            /**
+             * This class represents a node in the graph. Each node corresponds
+             * to an inference variable and has edges (dependencies) on other
+             * nodes. The node defines an entry point that can be used to receive
+             * updates on the structure of the graph this node belongs to (used to
+             * keep dependencies in sync).
+             */
+            class Node extends GraphUtils.TarjanNode<ListBuffer<Type>> {
+
+                Set<Node> deps;
+
+                Node(Type ivar) {
+                    super(ListBuffer.of(ivar));
+                    this.deps = new HashSet<Node>();
+                }
+
+                @Override
+                public Iterable<? extends Node> getDependencies() {
+                    return deps;
+                }
+
+                @Override
+                public String printDependency(GraphUtils.Node<ListBuffer<Type>> to) {
+                    StringBuilder buf = new StringBuilder();
+                    String sep = "";
+                    for (Type from : data) {
+                        UndetVar uv = (UndetVar)inferenceContext.asFree(from);
+                        for (Type bound : uv.getBounds(InferenceBound.values())) {
+                            if (bound.containsAny(List.from(to.data))) {
+                                buf.append(sep);
+                                buf.append(bound);
+                                sep = ",";
+                            }
+                        }
+                    }
+                    return buf.toString();
+                }
+
+                boolean isLeaf(Node n) {
+                    //no deps, or only one self dep
+                    return (n.deps.isEmpty() ||
+                            n.deps.size() == 1 && n.deps.contains(n));
+                }
+
+                void mergeWith(List<? extends Node> nodes) {
+                    for (Node n : nodes) {
+                        Assert.check(n.data.length() == 1, "Attempt to merge a compound node!");
+                        data.appendList(n.data);
+                        deps.addAll(n.deps);
+                    }
+                    //update deps
+                    Set<Node> deps2 = new HashSet<Node>();
+                    for (Node d : deps) {
+                        if (data.contains(d.data.first())) {
+                            deps2.add(this);
+                        } else {
+                            deps2.add(d);
+                        }
+                    }
+                    deps = deps2;
+                }
+
+                void graphChanged(Node from, Node to) {
+                    if (deps.contains(from)) {
+                        deps.remove(from);
+                        if (to != null) {
+                            deps.add(to);
+                        }
+                    }
+                }
+            }
+
+            /** the nodes in the inference graph */
+            ArrayList<Node> nodes;
+
+            InferenceGraph() {
+                initNodes();
+            }
+
+            /**
+             * Delete a node from the graph. This update the underlying structure
+             * of the graph (including dependencies) via listeners updates.
+             */
+            public void deleteNode(Node n) {
+                Assert.check(nodes.contains(n));
+                nodes.remove(n);
+                notifyUpdate(n, null);
+            }
+
+            /**
+             * Notify all nodes of a change in the graph. If the target node is
+             * {@code null} the source node is assumed to be removed.
+             */
+            void notifyUpdate(Node from, Node to) {
+                for (Node n : nodes) {
+                    n.graphChanged(from, to);
+                }
+            }
+
+            /**
+             * Create the graph nodes. First a simple node is created for every inference
+             * variables to be solved. Then Tarjan is used to found all connected components
+             * in the graph. For each component containing more than one node, a super node is
+                 * created, effectively replacing the original cyclic nodes.
+             */
+            void initNodes() {
+                ArrayList<Node> nodes = new ArrayList<Node>();
+                for (Type t : inferenceContext.restvars()) {
+                    nodes.add(new Node(t));
+                }
+                for (Node n_i : nodes) {
+                    Type i = n_i.data.first();
+                    for (Node n_j : nodes) {
+                        Type j = n_j.data.first();
+                        UndetVar uv_i = (UndetVar)inferenceContext.asFree(i);
+                        if (Type.containsAny(uv_i.getBounds(InferenceBound.values()), List.of(j))) {
+                            //update i's deps
+                            n_i.deps.add(n_j);
+                            //update j's deps - only if i's bounds contain _exactly_ j
+                            if (uv_i.getBounds(InferenceBound.values()).contains(j)) {
+                                n_j.deps.add(n_i);
+                            }
+                        }
+                    }
+                }
+                this.nodes = new ArrayList<Node>();
+                for (List<? extends Node> conSubGraph : GraphUtils.tarjan(nodes)) {
+                    if (conSubGraph.length() > 1) {
+                        Node root = conSubGraph.head;
+                        root.mergeWith(conSubGraph.tail);
+                        for (Node n : conSubGraph) {
+                            notifyUpdate(n, root);
+                        }
+                    }
+                    this.nodes.add(conSubGraph.head);
+                }
+            }
+
+            /**
+             * Debugging: dot representation of this graph
+             */
+            String toDot() {
+                StringBuilder buf = new StringBuilder();
+                for (Type t : inferenceContext.undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    buf.append(String.format("var %s - upper bounds = %s, lower bounds = %s, eq bounds = %s\\n",
+                            uv.qtype, uv.getBounds(InferenceBound.UPPER), uv.getBounds(InferenceBound.LOWER),
+                            uv.getBounds(InferenceBound.EQ)));
+                }
+                return GraphUtils.toDot(nodes, "inferenceGraph" + hashCode(), buf.toString());
+            }
+        }
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Inference context">
+    /**
+     * Functional interface for defining inference callbacks. Certain actions
+     * (i.e. subtyping checks) might need to be redone after all inference variables
+     * have been fixed.
+     */
+    interface FreeTypeListener {
+        void typesInferred(InferenceContext inferenceContext);
+    }
 
     /**
      * An inference context keeps track of the set of variables that are free
@@ -611,16 +1283,7 @@
      * it can be used as an entry point for performing upper/lower bound inference
      * (see InferenceKind).
      */
-    static class InferenceContext {
-
-        /**
-        * Single-method-interface for defining inference callbacks. Certain actions
-        * (i.e. subtyping checks) might need to be redone after all inference variables
-        * have been fixed.
-        */
-        interface FreeTypeListener {
-            void typesInferred(InferenceContext inferenceContext);
-        }
+     class InferenceContext {
 
         /** list of inference vars as undet vars */
         List<Type> undetvars;
@@ -628,15 +1291,26 @@
         /** list of inference vars in this context */
         List<Type> inferencevars;
 
+        /** backed up inference variables */
+        List<Type> saved_undet;
+
         java.util.Map<FreeTypeListener, List<Type>> freeTypeListeners =
                 new java.util.HashMap<FreeTypeListener, List<Type>>();
 
         List<FreeTypeListener> freetypeListeners = List.nil();
 
-        public InferenceContext(List<Type> inferencevars, Infer infer, boolean includeBounds) {
-            this.undetvars = Type.map(inferencevars, infer.new FromTypeVarFun(includeBounds));
+        public InferenceContext(List<Type> inferencevars) {
+            this.undetvars = Type.map(inferencevars, fromTypeVarFun);
             this.inferencevars = inferencevars;
         }
+        //where
+            Mapping fromTypeVarFun = new Mapping("fromTypeVarFunWithBounds") {
+                // mapping that turns inference variables into undet vars
+                public Type apply(Type t) {
+                    if (t.hasTag(TYPEVAR)) return new UndetVar((TypeVar)t, types);
+                    else return t.map(this);
+                }
+            };
 
         /**
          * returns the list of free variables (as type-variables) in this
@@ -648,19 +1322,51 @@
 
         /**
          * returns the list of uninstantiated variables (as type-variables) in this
-         * inference context (usually called after instantiate())
+         * inference context
          */
         List<Type> restvars() {
-            List<Type> undetvars = this.undetvars;
-            ListBuffer<Type> restvars = ListBuffer.lb();
-            for (Type t : instTypes()) {
-                UndetVar uv = (UndetVar)undetvars.head;
-                if (uv.qtype == t) {
-                    restvars.append(t);
+            return filterVars(new Filter<UndetVar>() {
+                public boolean accepts(UndetVar uv) {
+                    return uv.inst == null;
                 }
-                undetvars = undetvars.tail;
+            });
+        }
+
+        /**
+         * returns the list of instantiated variables (as type-variables) in this
+         * inference context
+         */
+        List<Type> instvars() {
+            return filterVars(new Filter<UndetVar>() {
+                public boolean accepts(UndetVar uv) {
+                    return uv.inst != null;
+                }
+            });
+        }
+
+        /**
+         * Get list of bounded inference variables (where bound is other than
+         * declared bounds).
+         */
+        final List<Type> boundedVars() {
+            return filterVars(new Filter<UndetVar>() {
+                public boolean accepts(UndetVar uv) {
+                    return uv.getBounds(InferenceBound.UPPER)
+                            .diff(uv.getDeclaredBounds())
+                            .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty();
+                }
+            });
+        }
+
+        private List<Type> filterVars(Filter<UndetVar> fu) {
+            ListBuffer<Type> res = ListBuffer.lb();
+            for (Type t : undetvars) {
+                UndetVar uv = (UndetVar)t;
+                if (fu.accepts(uv)) {
+                    res.append(uv.qtype);
+                }
             }
-            return restvars.toList();
+            return res.toList();
         }
 
         /**
@@ -709,14 +1415,14 @@
          * undet vars (used ahead of subtyping/compatibility checks to allow propagation
          * of inference constraints).
          */
-        final Type asFree(Type t, Types types) {
+        final Type asFree(Type t) {
             return types.subst(t, inferencevars, undetvars);
         }
 
-        final List<Type> asFree(List<Type> ts, Types types) {
+        final List<Type> asFree(List<Type> ts) {
             ListBuffer<Type> buf = ListBuffer.lb();
             for (Type t : ts) {
-                buf.append(asFree(t, types));
+                buf.append(asFree(t));
             }
             return buf.toList();
         }
@@ -735,14 +1441,14 @@
          * instantiated types - if one or more free variable has not been
          * fully instantiated, it will still be available in the resulting type.
          */
-        Type asInstType(Type t, Types types) {
+        Type asInstType(Type t) {
             return types.subst(t, inferencevars, instTypes());
         }
 
-        List<Type> asInstTypes(List<Type> ts, Types types) {
+        List<Type> asInstTypes(List<Type> ts) {
             ListBuffer<Type> buf = ListBuffer.lb();
             for (Type t : ts) {
-                buf.append(asInstType(t, types));
+                buf.append(asInstType(t));
             }
             return buf.toList();
         }
@@ -758,11 +1464,15 @@
          * Mark the inference context as complete and trigger evaluation
          * of all deferred checks.
          */
-        void notifyChange(Types types) {
+        void notifyChange() {
+            notifyChange(inferencevars.diff(restvars()));
+        }
+
+        void notifyChange(List<Type> inferredVars) {
             InferenceException thrownEx = null;
             for (Map.Entry<FreeTypeListener, List<Type>> entry :
                     new HashMap<FreeTypeListener, List<Type>>(freeTypeListeners).entrySet()) {
-                if (!Type.containsAny(entry.getValue(), restvars())) {
+                if (!Type.containsAny(entry.getValue(), inferencevars.diff(inferredVars))) {
                     try {
                         entry.getKey().typesInferred(this);
                         freeTypeListeners.remove(entry.getKey());
@@ -780,22 +1490,156 @@
             }
         }
 
-        void solveAny(List<Type> varsToSolve, Types types, Infer infer) {
-            boolean progress = false;
-            for (Type t : varsToSolve) {
-                UndetVar uv = (UndetVar)asFree(t, types);
-                if (uv.inst == null) {
-                    infer.minimizeInst(uv, types.noWarnings);
-                    if (uv.inst != null) {
-                        progress = true;
+        /**
+         * Save the state of this inference context
+         */
+        void save() {
+            ListBuffer<Type> buf = ListBuffer.lb();
+            for (Type t : undetvars) {
+                UndetVar uv = (UndetVar)t;
+                UndetVar uv2 = new UndetVar((TypeVar)uv.qtype, types);
+                for (InferenceBound ib : InferenceBound.values()) {
+                    for (Type b : uv.getBounds(ib)) {
+                        uv2.addBound(ib, b, types);
+                    }
+                }
+                uv2.inst = uv.inst;
+                buf.add(uv2);
+            }
+            saved_undet = buf.toList();
+        }
+
+        /**
+         * Restore the state of this inference context to the previous known checkpoint
+         */
+        void rollback() {
+            Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
+            undetvars = saved_undet;
+            saved_undet = null;
+        }
+
+        /**
+         * Copy variable in this inference context to the given context
+         */
+        void dupTo(final InferenceContext that) {
+            that.inferencevars = that.inferencevars.appendList(inferencevars);
+            that.undetvars = that.undetvars.appendList(undetvars);
+            //set up listeners to notify original inference contexts as
+            //propagated vars are inferred in new context
+            for (Type t : inferencevars) {
+                that.freeTypeListeners.put(new FreeTypeListener() {
+                    public void typesInferred(InferenceContext inferenceContext) {
+                        InferenceContext.this.notifyChange();
+                    }
+                }, List.of(t));
+            }
+        }
+
+        /**
+         * Solve with given graph strategy.
+         */
+        private void solve(GraphStrategy ss, Warner warn) {
+            GraphSolver s = new GraphSolver(this, warn);
+            s.solve(ss);
+        }
+
+        /**
+         * Solve all variables in this context.
+         */
+        public void solve(Warner warn) {
+            solve(new LeafSolver() {
+                public boolean done() {
+                    return restvars().isEmpty();
+                }
+            }, warn);
+        }
+
+        /**
+         * Solve all variables in the given list.
+         */
+        public void solve(final List<Type> vars, Warner warn) {
+            solve(new BestLeafSolver(vars) {
+                public boolean done() {
+                    return !free(asInstTypes(vars));
+                }
+            }, warn);
+        }
+
+        /**
+         * Solve at least one variable in given list.
+         */
+        public void solveAny(List<Type> varsToSolve, Warner warn) {
+            checkWithinBounds(this, warn); //propagate bounds
+            List<Type> boundedVars = boundedVars().intersect(restvars()).intersect(varsToSolve);
+            if (boundedVars.isEmpty()) {
+                throw inferenceException.setMessage("cyclic.inference",
+                                freeVarsIn(varsToSolve));
+            }
+            solve(new BestLeafSolver(boundedVars) {
+                public boolean done() {
+                    return instvars().intersect(varsToSolve).nonEmpty();
+                }
+            }, warn);
+        }
+
+        /**
+         * Apply a set of inference steps
+         */
+        private boolean solveBasic(EnumSet<InferenceStep> steps) {
+            return solveBasic(inferencevars, steps);
+        }
+
+        private boolean solveBasic(List<Type> varsToSolve, EnumSet<InferenceStep> steps) {
+            boolean changed = false;
+            for (Type t : varsToSolve.intersect(restvars())) {
+                UndetVar uv = (UndetVar)asFree(t);
+                for (InferenceStep step : steps) {
+                    if (step.accepts(uv, this)) {
+                        uv.inst = step.solve(uv, this);
+                        changed = true;
+                        break;
                     }
                 }
             }
-            if (!progress) {
-                throw infer.inferenceException.setMessage("cyclic.inference", varsToSolve);
+            return changed;
+        }
+
+        /**
+         * Instantiate inference variables in legacy mode (JLS 15.12.2.7, 15.12.2.8).
+         * During overload resolution, instantiation is done by doing a partial
+         * inference process using eq/lower bound instantiation. During check,
+         * we also instantiate any remaining vars by repeatedly using eq/upper
+         * instantiation, until all variables are solved.
+         */
+        public void solveLegacy(boolean partial, Warner warn, EnumSet<InferenceStep> steps) {
+            while (true) {
+                boolean stuck = !solveBasic(steps);
+                if (restvars().isEmpty() || partial) {
+                    //all variables have been instantiated - exit
+                    break;
+                } else if (stuck) {
+                    //some variables could not be instantiated because of cycles in
+                    //upper bounds - provide a (possibly recursive) default instantiation
+                    instantiateAsUninferredVars(restvars(), this);
+                    break;
+                } else {
+                    //some variables have been instantiated - replace newly instantiated
+                    //variables in remaining upper bounds and continue
+                    for (Type t : undetvars) {
+                        UndetVar uv = (UndetVar)t;
+                        uv.substBounds(inferenceVars(), instTypes(), types);
+                    }
+                }
             }
+            checkWithinBounds(this, warn);
+        }
+
+        private Infer infer() {
+            //back-door to infer
+            return Infer.this;
         }
     }
 
-    final InferenceContext emptyContext = new InferenceContext(List.<Type>nil(), this, false);
+    final InferenceContext emptyContext = new InferenceContext(List.<Type>nil());
+    // </editor-fold>
 }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index fb5202d..937dd40 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -1445,24 +1445,51 @@
         return result;
     }
 
-    /** Definition for this$n field.
-     *  @param pos        The source code position of the definition.
-     *  @param owner      The class in which the definition goes.
-     */
-    JCVariableDecl outerThisDef(int pos, Symbol owner) {
-        long flags = FINAL | SYNTHETIC;
+    private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) {
         if (owner.kind == TYP &&
             target.usePrivateSyntheticFields())
             flags |= PRIVATE;
         Type target = types.erasure(owner.enclClass().type.getEnclosingType());
-        VarSymbol outerThis = new VarSymbol(
-            flags, outerThisName(target, owner), target, owner);
+        VarSymbol outerThis =
+            new VarSymbol(flags, outerThisName(target, owner), target, owner);
         outerThisStack = outerThisStack.prepend(outerThis);
-        JCVariableDecl vd = make.at(pos).VarDef(outerThis, null);
+        return outerThis;
+    }
+
+    private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) {
+        JCVariableDecl vd = make.at(pos).VarDef(sym, null);
         vd.vartype = access(vd.vartype);
         return vd;
     }
 
+    /** Definition for this$n field.
+     *  @param pos        The source code position of the definition.
+     *  @param owner      The method in which the definition goes.
+     */
+    JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
+        ClassSymbol c = owner.enclClass();
+        boolean isMandated =
+            // Anonymous constructors
+            (owner.isConstructor() && owner.isAnonymous()) ||
+            // Constructors of non-private inner member classes
+            (owner.isConstructor() && c.isInner() &&
+             !c.isPrivate() && !c.isStatic());
+        long flags =
+            FINAL | (isMandated ? MANDATED : SYNTHETIC);
+        VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
+        owner.extraParams = owner.extraParams.prepend(outerThis);
+        return makeOuterThisVarDecl(pos, outerThis);
+    }
+
+    /** Definition for this$n field.
+     *  @param pos        The source code position of the definition.
+     *  @param owner      The class in which the definition goes.
+     */
+    JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
+        VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
+        return makeOuterThisVarDecl(pos, outerThis);
+    }
+
     /** Return a list of trees that load the free variables in given list,
      *  in reverse order.
      *  @param pos          The source code position to be used for the trees.
@@ -2568,7 +2595,6 @@
                                        "enum" + target.syntheticNameChar() + "name"),
                       syms.stringType, tree.sym);
             nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC;
-
             JCVariableDecl ordParam = make.
                 Param(names.fromString(target.syntheticNameChar() +
                                        "enum" + target.syntheticNameChar() +
@@ -2579,6 +2605,8 @@
             tree.params = tree.params.prepend(ordParam).prepend(nameParam);
 
             MethodSymbol m = tree.sym;
+            m.extraParams = m.extraParams.prepend(ordParam.sym);
+            m.extraParams = m.extraParams.prepend(nameParam.sym);
             Type olderasure = m.erasure(types);
             m.erasure_field = new MethodType(
                 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
@@ -3066,55 +3094,38 @@
     }
 
     public void visitAssignop(final JCAssignOp tree) {
-        if (!tree.lhs.type.isPrimitive() &&
-            tree.operator.type.getReturnType().isPrimitive()) {
-            // boxing required; need to rewrite as x = (unbox typeof x)(x op y);
-            // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
-            // (but without recomputing x)
-            JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
-                    public JCTree build(final JCTree lhs) {
-                        JCTree.Tag newTag = tree.getTag().noAssignOp();
-                        // Erasure (TransTypes) can change the type of
-                        // tree.lhs.  However, we can still get the
-                        // unerased type of tree.lhs as it is stored
-                        // in tree.type in Attr.
-                        Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
-                                                                      newTag,
-                                                                      attrEnv,
-                                                                      tree.type,
-                                                                      tree.rhs.type);
-                        JCExpression expr = (JCExpression)lhs;
-                        if (expr.type != tree.type)
-                            expr = make.TypeCast(tree.type, expr);
-                        JCBinary opResult = make.Binary(newTag, expr, tree.rhs);
-                        opResult.operator = newOperator;
-                        opResult.type = newOperator.type.getReturnType();
-                        JCTypeCast newRhs = make.TypeCast(types.unboxedType(tree.type),
-                                                          opResult);
-                        return make.Assign((JCExpression)lhs, newRhs).setType(tree.type);
-                    }
-                });
-            result = translate(newTree);
-            return;
-        }
-        tree.lhs = translate(tree.lhs, tree);
-        tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head);
+        final boolean boxingReq = !tree.lhs.type.isPrimitive() &&
+            tree.operator.type.getReturnType().isPrimitive();
 
-        // If translated left hand side is an Apply, we are
-        // seeing an access method invocation. In this case, append
-        // right hand side as last argument of the access method.
-        if (tree.lhs.hasTag(APPLY)) {
-            JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
-            // if operation is a += on strings,
-            // make sure to convert argument to string
-            JCExpression rhs = (((OperatorSymbol)tree.operator).opcode == string_add)
-              ? makeString(tree.rhs)
-              : tree.rhs;
-            app.args = List.of(rhs).prependList(app.args);
-            result = app;
-        } else {
-            result = tree;
-        }
+        // boxing required; need to rewrite as x = (unbox typeof x)(x op y);
+        // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
+        // (but without recomputing x)
+        JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
+                public JCTree build(final JCTree lhs) {
+                    JCTree.Tag newTag = tree.getTag().noAssignOp();
+                    // Erasure (TransTypes) can change the type of
+                    // tree.lhs.  However, we can still get the
+                    // unerased type of tree.lhs as it is stored
+                    // in tree.type in Attr.
+                    Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
+                                                                  newTag,
+                                                                  attrEnv,
+                                                                  tree.type,
+                                                                  tree.rhs.type);
+                    JCExpression expr = (JCExpression)lhs;
+                    if (expr.type != tree.type)
+                        expr = make.TypeCast(tree.type, expr);
+                    JCBinary opResult = make.Binary(newTag, expr, tree.rhs);
+                    opResult.operator = newOperator;
+                    opResult.type = newOperator.type.getReturnType();
+                    JCExpression newRhs = boxingReq ?
+                            make.TypeCast(types.unboxedType(tree.type),
+                                                      opResult) :
+                            opResult;
+                    return make.Assign((JCExpression)lhs, newRhs).setType(tree.type);
+                }
+            });
+        result = translate(newTree);
     }
 
     /** Lower a tree of the form e++ or e-- where e is an object type */
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
index 407a49f..907f068 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
@@ -465,7 +465,8 @@
                       names.valueOf,
                       make.Type(tree.sym.type),
                       List.<JCTypeParameter>nil(),
-                      List.of(make.VarDef(make.Modifiers(Flags.PARAMETER),
+                      List.of(make.VarDef(make.Modifiers(Flags.PARAMETER |
+                                                         Flags.MANDATED),
                                             names.fromString("name"),
                                             make.Type(syms.stringType), null)),
                       List.<JCExpression>nil(), // thrown
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index 08cc94f..f1afa36 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -35,7 +35,7 @@
 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
 import com.sun.tools.javac.comp.Infer.InferenceContext;
-import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
+import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
@@ -564,7 +564,7 @@
                                     methodCheck,
                                     warn);
 
-        methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext),
+        methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
                                 argtypes, mt.getParameterTypes(), warn);
         return mt;
     }
@@ -741,7 +741,7 @@
                 inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
                     @Override
                     public void typesInferred(InferenceContext inferenceContext) {
-                        varargsAccessible(env, inferenceContext.asInstType(t, types), inferenceContext);
+                        varargsAccessible(env, inferenceContext.asInstType(t), inferenceContext);
                     }
                 });
             } else {
@@ -785,8 +785,8 @@
 
         public boolean compatible(Type found, Type req, Warner warn) {
             return strict ?
-                    types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req, types), warn) :
-                    types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req, types), warn);
+                    types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req), warn) :
+                    types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req), warn);
         }
 
         public void report(DiagnosticPosition pos, JCDiagnostic details) {
@@ -3589,8 +3589,8 @@
             candidates = candidates.append(c);
         }
 
-        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext) {
-            return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext);
+        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
+            return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext, pendingResult != null ? pendingResult.checkContext.deferredAttrContext() : deferredAttr.emptyDeferredAttrContext, warn);
         }
 
         /**
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
index 4061471..9b19cc3 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
@@ -134,6 +134,11 @@
      **/
     public boolean preferSource;
 
+    /**
+     * The currently selected profile.
+     */
+    public final Profile profile;
+
     /** The log to use for verbose output
      */
     final Log log;
@@ -284,16 +289,20 @@
         annotate = Annotate.instance(context);
         verbose        = options.isSet(VERBOSE);
         checkClassFile = options.isSet("-checkclassfile");
+
         Source source = Source.instance(context);
         allowGenerics    = source.allowGenerics();
         allowVarargs     = source.allowVarargs();
         allowAnnotations = source.allowAnnotations();
         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
         allowDefaultMethods = source.allowDefaultMethods();
+
         saveParameterNames = options.isSet("save-parameter-names");
         cacheCompletionFailure = options.isUnset("dev");
         preferSource = "source".equals(options.get("-Xprefer"));
 
+        profile = Profile.instance(context);
+
         completionFailureName =
             options.isSet("failcomplete")
             ? names.fromString(options.get("failcomplete"))
@@ -1370,7 +1379,18 @@
                 CompoundAnnotationProxy proxy = readCompoundAnnotation();
                 if (proxy.type.tsym == syms.proprietaryType.tsym)
                     sym.flags_field |= PROPRIETARY;
-                else
+                else if (proxy.type.tsym == syms.profileType.tsym) {
+                    if (profile != Profile.DEFAULT) {
+                        for (Pair<Name,Attribute> v: proxy.values) {
+                            if (v.fst == names.value && v.snd instanceof Attribute.Constant) {
+                                Attribute.Constant c = (Attribute.Constant) v.snd;
+                                if (c.type == syms.intType && ((Integer) c.value) > profile.value) {
+                                    sym.flags_field |= NOT_IN_PROFILE;
+                                }
+                            }
+                        }
+                    }
+                } else
                     proxies.append(proxy);
             }
             annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
@@ -1470,12 +1490,13 @@
         position.type = type;
 
         switch (type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             position.offset = nextChar();
             break;
         // local variable
@@ -1524,9 +1545,12 @@
         case METHOD_FORMAL_PARAMETER:
             position.parameter_index = nextByte();
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             position.offset = nextChar();
             position.type_index = nextByte();
@@ -1535,10 +1559,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            position.parameter_index = nextByte();
-            break;
         case UNKNOWN:
             throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
         default:
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
index 8c1e320..acb8748 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
@@ -728,14 +728,24 @@
      * Write method parameter names attribute.
      */
     int writeMethodParametersAttr(MethodSymbol m) {
-        if (m.params != null && 0 != m.params.length()) {
-            int attrIndex = writeAttr(names.MethodParameters);
-            databuf.appendByte(m.params.length());
+        MethodType ty = m.externalType(types).asMethodType();
+        final int allparams = ty.argtypes.size();
+        if (m.params != null && allparams != 0) {
+            final int attrIndex = writeAttr(names.MethodParameters);
+            databuf.appendByte(allparams);
+            // Write extra parameters first
+            for (VarSymbol s : m.extraParams) {
+                final int flags =
+                    ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) |
+                    ((int) m.flags() & SYNTHETIC);
+                databuf.appendChar(pool.put(s.name));
+                databuf.appendInt(flags);
+            }
+            // Now write the real parameters
             for (VarSymbol s : m.params) {
-                // TODO: expand to cover synthesized, once we figure out
-                // how to represent that.
-                final int flags = (int) s.flags() & (FINAL | SYNTHETIC);
-                // output parameter info
+                final int flags =
+                    ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) |
+                    ((int) m.flags() & SYNTHETIC);
                 databuf.appendChar(pool.put(s.name));
                 databuf.appendInt(flags);
             }
@@ -992,12 +1002,13 @@
     void writePosition(TypeAnnotationPosition p) {
         databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte
         switch (p.type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             databuf.appendChar(p.offset);
             break;
         // local variable
@@ -1042,9 +1053,12 @@
         case METHOD_FORMAL_PARAMETER:
             databuf.appendByte(p.parameter_index);
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             databuf.appendChar(p.offset);
             databuf.appendByte(p.type_index);
@@ -1053,10 +1067,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            databuf.appendByte(p.parameter_index);
-            break;
         case UNKNOWN:
             throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!");
         default:
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
index b450fdc..56bcb59 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
@@ -513,7 +513,8 @@
         // that contains them as its body.
         if (clinitCode.length() != 0) {
             MethodSymbol clinit = new MethodSymbol(
-                STATIC, names.clinit,
+                STATIC | (c.flags() & STRICTFP),
+                names.clinit,
                 new MethodType(
                     List.<Type>nil(), syms.voidType,
                     List.<Type>nil(), syms.methodClass),
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Profile.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Profile.java
new file mode 100644
index 0000000..59ba84e
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Profile.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2002, 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.  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 com.sun.tools.javac.jvm;
+
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Options;
+import java.util.EnumSet;
+import java.util.Set;
+
+import static com.sun.tools.javac.main.Option.PROFILE;
+
+/** The target profile.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public enum Profile {
+    COMPACT1("compact1", 1, Target.JDK1_8),
+    COMPACT2("compact2", 2, Target.JDK1_8),
+    COMPACT3("compact3", 3, Target.JDK1_8),
+
+    DEFAULT {
+        @Override
+        public boolean isValid(Target t) {
+            return true;
+        }
+    };
+
+    private static final Context.Key<Profile> profileKey =
+        new Context.Key<Profile>();
+
+    public static Profile instance(Context context) {
+        Profile instance = context.get(profileKey);
+        if (instance == null) {
+            Options options = Options.instance(context);
+            String profileString = options.get(PROFILE);
+            if (profileString != null) instance = lookup(profileString);
+            if (instance == null) instance = DEFAULT;
+            context.put(profileKey, instance);
+        }
+        return instance;
+    }
+
+    public final String name;
+    public final int value;
+    final Set<Target> targets;
+
+    Profile() {
+        name = null;
+        value = Integer.MAX_VALUE;
+        targets = null;
+    }
+
+    Profile(String name, int value, Target t, Target... targets) {
+        this.name = name;
+        this.value = value;
+        this.targets = EnumSet.of(t, targets);
+    }
+
+    public static Profile lookup(String name) {
+        // the set of values is small enough to do linear search
+        for (Profile p: values()) {
+            if (name.equals(p.name))
+                return p;
+        }
+        return null;
+    }
+
+    public static Profile lookup(int value) {
+        // the set of values is small enough to do linear search
+        for (Profile p: values()) {
+            if (value == p.value)
+                return p;
+        }
+        return null;
+    }
+
+    public boolean isValid(Target t) {
+        return targets.contains(t);
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java
index 8323a05..3c22d21 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java
@@ -31,7 +31,7 @@
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.util.*;
 
-import static com.sun.tools.javac.main.Option.*;
+import static com.sun.tools.javac.main.Option.TARGET;
 
 /** The classfile version target.
  *
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
index 80bf5d2..a45d12d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
@@ -49,6 +49,7 @@
 import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.file.CacheFSInfo;
 import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.processing.AnnotationProcessingError;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
@@ -76,7 +77,7 @@
 
     /** The log to use for diagnostic output.
      */
-    Log log;
+    public Log log;
 
     /**
      * If true, certain errors will cause an exception, such as command line
@@ -165,6 +166,7 @@
         this.ownName = name;
         this.out = out;
     }
+
     /** A table of all options that's passed to the JavaCompiler constructor.  */
     private Options options = null;
 
@@ -307,6 +309,15 @@
             }
         }
 
+        String profileString = options.get(PROFILE);
+        if (profileString != null) {
+            Profile profile = Profile.lookup(profileString);
+            if (!profile.isValid(target)) {
+                warning("warn.profile.target.conflict", profileString, target.name);
+                return null;
+            }
+        }
+
         // handle this here so it works even if no other options given
         String showClass = options.get("showClass");
         if (showClass != null) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
index abfd7e1..b6bfa33 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
@@ -40,6 +40,7 @@
 import com.sun.tools.javac.code.Lint;
 import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.util.Log;
@@ -218,6 +219,18 @@
         }
     },
 
+    PROFILE("-profile", "opt.arg.profile", "opt.profile", STANDARD, BASIC) {
+        @Override
+        public boolean process(OptionHelper helper, String option, String operand) {
+            Profile profile = Profile.lookup(operand);
+            if (profile == null) {
+                helper.error("err.invalid.profile", operand);
+                return true;
+            }
+            return super.process(helper, option, operand);
+        }
+    },
+
     VERSION("-version", "opt.version", STANDARD, INFO) {
         @Override
         public boolean process(OptionHelper helper, String option) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java
index 5861e70..23416a0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java
@@ -760,6 +760,16 @@
         return names.fromString(cs.toString());
     }
 
+    @Override
+    public boolean isFunctionalInterface(TypeElement element) {
+        if (element.getKind() != ElementKind.INTERFACE)
+            return false;
+        else {
+            TypeSymbol tsym = cast(TypeSymbol.class, element);
+            return types.isFunctionalInterface(tsym);
+        }
+    }
+
     /**
      * Returns the tree node and compilation unit corresponding to this
      * element, or null if they can't be found.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
index 52e8e08..87441e8 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -1164,7 +1164,7 @@
             } else return illegal();
             break;
         case MONKEYS_AT:
-            // Only annotated cast types are valid
+            // Only annotated cast types and method references are valid
             List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
             if (typeAnnos.isEmpty()) {
                 // else there would be no '@'
@@ -1175,17 +1175,27 @@
 
             if ((mode & TYPE) == 0) {
                 // Type annotations on class literals no longer legal
-                if (!expr.hasTag(Tag.SELECT)) {
+                switch (expr.getTag()) {
+                case REFERENCE: {
+                    JCMemberReference mref = (JCMemberReference) expr;
+                    mref.expr = toP(F.at(pos).AnnotatedType(typeAnnos, mref.expr));
+                    t = mref;
+                    break;
+                }
+                case SELECT: {
+                    JCFieldAccess sel = (JCFieldAccess) expr;
+
+                    if (sel.name != names._class) {
+                        return illegal();
+                    } else {
+                        log.error(token.pos, "no.annotations.on.dot.class");
+                        return expr;
+                    }
+                }
+                default:
                     return illegal(typeAnnos.head.pos);
                 }
-                JCFieldAccess sel = (JCFieldAccess)expr;
 
-                if (sel.name != names._class) {
-                    return illegal();
-                } else {
-                    log.error(token.pos, "no.annotations.on.dot.class");
-                    return expr;
-                }
             } else {
                 // Type annotations targeting a cast
                 t = insertAnnotationsToMostInner(expr, typeAnnos, false);
@@ -1457,18 +1467,40 @@
     /**
      * If we see an identifier followed by a '&lt;' it could be an unbound
      * method reference or a binary expression. To disambiguate, look for a
-     * matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
+     * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
      */
     @SuppressWarnings("fallthrough")
     boolean isUnboundMemberRef() {
         int pos = 0, depth = 0;
-        for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
+        outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
             switch (t.kind) {
                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
                 case DOUBLE: case BOOLEAN: case CHAR:
+                case MONKEYS_AT:
                     break;
+
+                case LPAREN:
+                    // skip annotation values
+                    int nesting = 0;
+                    for (; ; pos++) {
+                        TokenKind tk2 = S.token(pos).kind;
+                        switch (tk2) {
+                            case EOF:
+                                return false;
+                            case LPAREN:
+                                nesting++;
+                                break;
+                            case RPAREN:
+                                nesting--;
+                                if (nesting == 0) {
+                                    continue outer;
+                                }
+                                break;
+                        }
+                    }
+
                 case LT:
                     depth++; break;
                 case GTGTGT:
@@ -1494,7 +1526,7 @@
     /**
      * If we see an identifier followed by a '&lt;' it could be an unbound
      * method reference or a binary expression. To disambiguate, look for a
-     * matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
+     * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
      */
     @SuppressWarnings("fallthrough")
     ParensResult analyzeParens() {
@@ -3022,7 +3054,7 @@
         boolean checkForImports = true;
         boolean firstTypeDecl = true;
         while (token.kind != EOF) {
-            if (token.pos <= endPosTable.errorEndPos) {
+            if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
                 // error recovery
                 skip(checkForImports, false, false, false);
                 if (token.kind == EOF)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
index 5161bed..926c401 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -485,6 +485,10 @@
 compiler.err.illegal.forward.ref=\
     illegal forward reference
 
+# 0: symbol, 1: string
+compiler.err.not.in.profile=\
+    {0} is not available in profile ''{1}''
+
 # 0: symbol
 compiler.warn.forward.ref=\
     reference to variable ''{0}'' before it has been initialized
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
index 9263c30..490a927 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
@@ -69,6 +69,8 @@
     Pass <flag> directly to the runtime system
 javac.opt.encoding=\
     Specify character encoding used by source files
+javac.opt.profile=\
+    Check that API used is available in the specified profile
 javac.opt.target=\
     Generate class files for specific VM version
 javac.opt.source=\
@@ -97,6 +99,8 @@
     <directory>
 javac.opt.arg.encoding=\
     <encoding>
+javac.opt.arg.profile=\
+    <profile>
 javac.opt.arg.release=\
     <release>
 javac.opt.arg.number=\
@@ -175,6 +179,8 @@
      key in annotation processor option ''{0}'' is not a dot-separated sequence of identifiers
 javac.err.invalid.flag=\
     invalid flag: {0}
+javac.err.invalid.profile=\
+    invalid profile: {0}
 javac.err.invalid.target=\
     invalid target release: {0}
 javac.err.no.source.files=\
@@ -191,6 +197,8 @@
     source release {0} requires target release {1}
 javac.warn.target.default.source.conflict=\
     target release {0} conflicts with default source release {1}
+javac.warn.profile.target.conflict=\
+    profile {0} is not valid for target release {1}
 javac.err.dir.not.found=\
     directory not found: {0}
 javac.err.file.not.found=\
diff --git a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
index 10c0de7..98ed8fa 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
@@ -34,11 +34,11 @@
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Types;
-import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.jvm.ClassWriter;
 import com.sun.tools.javac.jvm.Pool;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Names;
 import com.sun.tools.javac.util.Pair;
 
 import java.io.File;
@@ -47,6 +47,7 @@
 import java.util.EnumSet;
 import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.ResourceBundle;
 import java.util.Set;
 
@@ -85,7 +86,10 @@
  *
  * @author Peter von der Ah\u00e9
  */
-@SupportedOptions({"com.sun.tools.javac.sym.Jar","com.sun.tools.javac.sym.Dest"})
+@SupportedOptions({
+    "com.sun.tools.javac.sym.Jar",
+    "com.sun.tools.javac.sym.Dest",
+    "com.sun.tools.javac.sym.Profiles"})
 @SupportedAnnotationTypes("*")
 public class CreateSymbols extends AbstractProcessor {
 
@@ -106,6 +110,7 @@
             processingEnv.getMessager()
                 .printMessage(Diagnostic.Kind.ERROR, e.getLocalizedMessage());
         } catch (Throwable t) {
+            t.printStackTrace();
             Throwable cause = t.getCause();
             if (cause == null)
                 cause = t;
@@ -121,12 +126,17 @@
         Set<String> documented = new HashSet<String>();
         Set<PackageSymbol> packages =
             ((JavacProcessingEnvironment)processingEnv).getSpecifiedPackages();
-        String jarName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Jar");
+        Map<String,String> pOptions = processingEnv.getOptions();
+        String jarName = pOptions.get("com.sun.tools.javac.sym.Jar");
         if (jarName == null)
             throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Jar=LOCATION_OF_JAR");
-        String destName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Dest");
+        String destName = pOptions.get("com.sun.tools.javac.sym.Dest");
         if (destName == null)
             throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Dest=LOCATION_OF_JAR");
+        String profileSpec=pOptions.get("com.sun.tools.javac.sym.Profiles");
+        if (profileSpec == null)
+            throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Profiles=PROFILES_SPEC");
+        Profiles profiles = Profiles.read(new File(profileSpec));
 
         for (PackageSymbol psym : packages) {
             String name = psym.getQualifiedName().toString();
@@ -166,12 +176,19 @@
             tool.getTask(null, fm, null, options, null, null);
         com.sun.tools.javac.main.JavaCompiler compiler =
             com.sun.tools.javac.main.JavaCompiler.instance(task.getContext());
-        ClassReader reader = ClassReader.instance(task.getContext());
         ClassWriter writer = ClassWriter.instance(task.getContext());
         Symtab syms = Symtab.instance(task.getContext());
-        Attribute.Compound proprietary =
+        Names names = Names.instance(task.getContext());
+        Attribute.Compound proprietaryAnno =
             new Attribute.Compound(syms.proprietaryType,
                                    List.<Pair<Symbol.MethodSymbol,Attribute>>nil());
+        Attribute.Compound[] profileAnnos = new Attribute.Compound[profiles.getProfileCount() + 1];
+        Symbol.MethodSymbol profileValue = (MethodSymbol) syms.profileType.tsym.members().lookup(names.value).sym;
+        for (int i = 1; i < profileAnnos.length; i++) {
+            profileAnnos[i] = new Attribute.Compound(syms.profileType,
+                    List.<Pair<Symbol.MethodSymbol, Attribute>>of(
+                    new Pair<Symbol.MethodSymbol, Attribute>(profileValue, new Attribute.Constant(syms.intType, i))));
+        }
 
         Type.moreInfo = true;
         Types types = Types.instance(task.getContext());
@@ -208,8 +225,11 @@
             }
             ClassSymbol cs = (ClassSymbol) sym;
             if (addLegacyAnnotation) {
-                cs.annotations.prepend(List.of(proprietary));
+                cs.annotations.prepend(List.of(proprietaryAnno));
             }
+            int p = profiles.getProfile(cs.fullname.toString().replace(".", "/"));
+            if (0 < p && p < profileAnnos.length)
+                cs.annotations.prepend(List.of(profileAnnos[p]));
             writeClass(pool, cs, writer);
         }
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java b/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java
new file mode 100644
index 0000000..53c709b
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2006, 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.  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 com.sun.tools.javac.sym;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import com.sun.tools.javac.util.Assert;
+
+/**
+ * Provide details about profile contents.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk.  This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public abstract class Profiles {
+    // for debugging
+    public static void main(String[] args) throws IOException {
+        Profiles p = Profiles.read(new File(args[0]));
+        if (args.length >= 2) {
+            Map<Integer,Set<String>> lists = new TreeMap<Integer,Set<String>>();
+            for (int i = 1; i <= 4; i++)
+                lists.put(i, new TreeSet<String>());
+
+            File rt_jar_lst = new File(args[1]);
+            for (String line: Files.readAllLines(rt_jar_lst.toPath(), Charset.defaultCharset())) {
+                if (line.endsWith(".class")) {
+                    String type = line.substring(0, line.length() - 6);
+                    int profile = p.getProfile(type);
+                    for (int i = profile; i <= 4; i++)
+                        lists.get(i).add(type);
+                }
+            }
+
+            for (int i = 1; i <= 4; i++) {
+                BufferedWriter out = new BufferedWriter(new FileWriter(i + ".txt"));
+                try {
+                    for (String type: lists.get(i)) {
+                        out.write(type);
+                        out.newLine();
+                    }
+                } finally {
+                    out.close();
+                }
+            }
+        }
+    }
+
+    public static Profiles read(File file) throws IOException {
+        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
+        try {
+            Properties p = new Properties();
+            p.load(in);
+            if (p.containsKey("java/lang/Object"))
+                return new SimpleProfiles(p);
+            else
+                return new MakefileProfiles(p);
+        } finally {
+            in.close();
+        }
+    }
+
+    public abstract int getProfileCount();
+
+    public abstract int getProfile(String typeName);
+
+    public abstract Set<String> getPackages(int profile);
+
+    private static class MakefileProfiles extends Profiles {
+        static class Package {
+            final Package parent;
+            final String name;
+
+            Map<String, Package> subpackages = new TreeMap<String, Package>();
+
+            int profile;
+            Map<String, Integer> includedTypes = new TreeMap<String,Integer>();
+            Map<String, Integer> excludedTypes = new TreeMap<String,Integer>();
+
+            Package(Package parent, String name) {
+                this.parent = parent;
+                this.name = name;
+            }
+
+            int getProfile() {
+                return (parent == null) ? profile : Math.max(parent.getProfile(), profile);
+            }
+
+            int getProfile(String simpleTypeName) {
+                Integer i;
+                if ((i = includedTypes.get(simpleTypeName)) != null)
+                    return i;
+                if ((i = includedTypes.get("*")) != null)
+                    return i;
+                if ((i = excludedTypes.get(simpleTypeName)) != null)
+                    return i + 1;
+                if ((i = excludedTypes.get("*")) != null)
+                    return i + 1;
+                return getProfile();
+            }
+
+            String getName() {
+                return (parent == null) ? name : (parent.getName() + "/" + name);
+            }
+
+            void getPackages(int profile, Set<String> results) {
+                int prf = getProfile();
+                if (prf != 0 && profile >= prf)
+                    results.add(getName());
+                for (Package pkg: subpackages.values())
+                    pkg.getPackages(profile, results);
+            }
+        }
+
+        final static Map<String, Package> packages = new TreeMap<String, Package>();
+        int maxProfile;
+
+        MakefileProfiles(Properties p) {
+            int profile = 1;
+            while (true) {
+                String inclPackages = p.getProperty("PROFILE_" + profile + "_RTJAR_INCLUDE_PACKAGES");
+                if (inclPackages == null)
+                    break;
+                for (String pkg: inclPackages.substring(1).trim().split("\\s+")) {
+                    if (pkg.endsWith("/"))
+                        pkg = pkg.substring(0, pkg.length() - 1);
+                    includePackage(profile, pkg);
+                }
+                String inclTypes =  p.getProperty("PROFILE_" + profile + "_RTJAR_INCLUDE_TYPES");
+                if (inclTypes != null) {
+                    for (String type: inclTypes.replace("$$", "$").split("\\s+")) {
+                        if (type.endsWith(".class"))
+                            includeType(profile, type.substring(0, type.length() - 6));
+                    }
+                }
+                String exclTypes =  p.getProperty("PROFILE_" + profile + "_RTJAR_EXCLUDE_TYPES");
+                if (exclTypes != null) {
+                    for (String type: exclTypes.replace("$$", "$").split("\\s+")) {
+                        if (type.endsWith(".class"))
+                            excludeType(profile, type.substring(0, type.length() - 6));
+                    }
+                }
+                maxProfile = profile;
+                profile++;
+            }
+        }
+
+        @Override
+        public int getProfileCount() {
+            return maxProfile;
+        }
+
+        @Override
+        public int getProfile(String typeName) {
+            int sep = typeName.lastIndexOf("/");
+            String packageName = typeName.substring(0, sep);
+            String simpleName = typeName.substring(sep + 1);
+
+            Package p = getPackage(packageName);
+            return p.getProfile(simpleName);
+        }
+
+        @Override
+        public Set<String> getPackages(int profile) {
+            Set<String> results = new TreeSet<String>();
+            for (Package p: packages.values())
+                p.getPackages(profile, results);
+            return results;
+        }
+
+        private void includePackage(int profile, String packageName) {
+//            System.err.println("include package " + packageName);
+            Package p = getPackage(packageName);
+            Assert.check(p.profile == 0);
+            p.profile = profile;
+        }
+
+        private void includeType(int profile, String typeName) {
+//            System.err.println("include type " + typeName);
+            int sep = typeName.lastIndexOf("/");
+            String packageName = typeName.substring(0, sep);
+            String simpleName = typeName.substring(sep + 1);
+
+            Package p = getPackage(packageName);
+            Assert.check(!p.includedTypes.containsKey(simpleName));
+            p.includedTypes.put(simpleName, profile);
+        }
+
+        private void excludeType(int profile, String typeName) {
+//            System.err.println("exclude type " + typeName);
+            int sep = typeName.lastIndexOf("/");
+            String packageName = typeName.substring(0, sep);
+            String simpleName = typeName.substring(sep + 1);
+
+            Package p = getPackage(packageName);
+            Assert.check(!p.excludedTypes.containsKey(simpleName));
+            p.excludedTypes.put(simpleName, profile);
+        }
+
+        private Package getPackage(String packageName) {
+            int sep = packageName.lastIndexOf("/");
+            Package parent;
+            Map<String, Package> parentSubpackages;
+            String simpleName;
+            if (sep == -1) {
+                parent = null;
+                parentSubpackages = packages;
+                simpleName = packageName;
+            } else {
+                parent = getPackage(packageName.substring(0, sep));
+                parentSubpackages = parent.subpackages;
+                simpleName = packageName.substring(sep + 1);
+            }
+
+            Package p = parentSubpackages.get(simpleName);
+            if (p == null) {
+                parentSubpackages.put(simpleName, p = new Package(parent, simpleName));
+            }
+            return p;
+        }
+    }
+
+    private static class SimpleProfiles extends Profiles {
+        private final Map<String, Integer> map;
+        private final int profileCount;
+
+        SimpleProfiles(Properties p) {
+            int max = 0;
+            map = new HashMap<String, Integer>();
+            for (Map.Entry<Object,Object> e: p.entrySet()) {
+                String typeName = (String) e.getKey();
+                int profile = Integer.valueOf((String) e.getValue());
+                map.put(typeName, profile);
+                max = Math.max(max, profile);
+            }
+            profileCount = max;
+        }
+
+        @Override
+        public int getProfileCount() {
+            return profileCount;
+        }
+
+        @Override
+        public int getProfile(String typeName) {
+            return map.get(typeName);
+        }
+
+        @Override
+        public Set<String> getPackages(int profile) {
+            Set<String> results = new TreeSet<String>();
+            for (Map.Entry<String,Integer> e: map.entrySet()) {
+                String tn = e.getKey();
+                int prf = e.getValue();
+                int sep = tn.lastIndexOf("/");
+                if (sep > 0 && profile >= prf)
+                    results.add(tn);
+            }
+            return results;
+        }
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
index 36e3a10..3991aae 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
@@ -235,6 +235,7 @@
         switch(tree.getTag()) {
             case TYPEAPPLY: return ((JCTypeApply)tree).getTypeArguments().isEmpty();
             case NEWCLASS: return isDiamond(((JCNewClass)tree).clazz);
+            case ANNOTATED_TYPE: return isDiamond(((JCAnnotatedType)tree).underlyingType);
             default: return false;
         }
     }
@@ -335,6 +336,8 @@
             case TYPEAPPLY:
             case TYPEARRAY:
                 return true;
+            case ANNOTATED_TYPE:
+                return isStaticSelector(((JCAnnotatedType)base).underlyingType, names);
             default:
                 return false;
         }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java
index a75d92c..cc21e6d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java
@@ -45,6 +45,7 @@
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Type.CapturedType;
 import com.sun.tools.javac.file.BaseFileObject;
+import com.sun.tools.javac.jvm.Profile;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.Pretty;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
@@ -197,6 +198,9 @@
         else if (arg instanceof JavaFileObject) {
             return ((JavaFileObject)arg).getName();
         }
+        else if (arg instanceof Profile) {
+            return ((Profile)arg).name;
+        }
         else if (arg instanceof Formattable) {
             return ((Formattable)arg).toString(l, messages);
         }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java
new file mode 100644
index 0000000..c15f1ec
--- /dev/null
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1999, 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.  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 com.sun.tools.javac.util;
+
+/** <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class GraphUtils {
+
+    /**
+     * This class is a basic abstract class for representing a node.
+     * A node is associated with a given data.
+     */
+    public static abstract class Node<D> {
+        public final D data;
+
+        public Node(D data) {
+            this.data = data;
+        }
+
+        public abstract Iterable<? extends Node<D>> getDependencies();
+
+        public abstract String printDependency(Node<D> to);
+
+        @Override
+        public String toString() {
+            return data.toString();
+        }
+    }
+
+    /**
+     * This class specialized Node, by adding elements that are required in order
+     * to perform Tarjan computation of strongly connected components.
+     */
+    public static abstract class TarjanNode<D> extends Node<D> implements Comparable<TarjanNode<D>> {
+        int index = -1;
+        int lowlink;
+        boolean active;
+
+        public TarjanNode(D data) {
+            super(data);
+        }
+
+        public abstract Iterable<? extends TarjanNode<D>> getDependencies();
+
+        public int compareTo(TarjanNode<D> o) {
+            return (index < o.index) ? -1 : (index == o.index) ? 0 : 1;
+        }
+    }
+
+    /**
+     * Tarjan's algorithm to determine strongly connected components of a
+     * directed graph in linear time. Works on TarjanNode.
+     */
+    public static <D, N extends TarjanNode<D>> List<? extends List<? extends N>> tarjan(Iterable<? extends N> nodes) {
+        ListBuffer<List<N>> cycles = ListBuffer.lb();
+        ListBuffer<N> stack = ListBuffer.lb();
+        int index = 0;
+        for (N node: nodes) {
+            if (node.index == -1) {
+                index += tarjan(node, index, stack, cycles);
+            }
+        }
+        return cycles.toList();
+    }
+
+    private static <D, N extends TarjanNode<D>> int tarjan(N v, int index, ListBuffer<N> stack, ListBuffer<List<N>> cycles) {
+        v.index = index;
+        v.lowlink = index;
+        index++;
+        stack.prepend(v);
+        v.active = true;
+        for (TarjanNode<D> nd: v.getDependencies()) {
+            @SuppressWarnings("unchecked")
+            N n = (N)nd;
+            if (n.index == -1) {
+                tarjan(n, index, stack, cycles);
+                v.lowlink = Math.min(v.lowlink, n.lowlink);
+            } else if (stack.contains(n)) {
+                v.lowlink = Math.min(v.lowlink, n.index);
+            }
+        }
+        if (v.lowlink == v.index) {
+            N n;
+            ListBuffer<N> cycle = ListBuffer.lb();
+            do {
+                n = stack.remove();
+                n.active = false;
+                cycle.add(n);
+            } while (n != v);
+            cycles.add(cycle.toList());
+        }
+        return index;
+    }
+
+    /**
+     * Debugging: dot representation of a set of connected nodes. The resulting
+     * dot representation will use {@code Node.toString} to display node labels
+     * and {@code Node.printDependency} to display edge labels. The resulting
+     * representation is also customizable with a graph name and a header.
+     */
+    public static <D> String toDot(Iterable<? extends TarjanNode<D>> nodes, String name, String header) {
+        StringBuilder buf = new StringBuilder();
+        buf.append(String.format("digraph %s {\n", name));
+        buf.append(String.format("label = \"%s\";\n", header));
+        //dump nodes
+        for (TarjanNode<D> n : nodes) {
+            buf.append(String.format("%s [label = \"%s\"];\n", n.hashCode(), n.toString()));
+        }
+        //dump arcs
+        for (TarjanNode<D> from : nodes) {
+            for (TarjanNode<D> to : from.getDependencies()) {
+                buf.append(String.format("%s -> %s [label = \" %s \"];\n",
+                        from.hashCode(), to.hashCode(), from.printDependency(to)));
+            }
+        }
+        buf.append("}\n");
+        return buf.toString();
+    }
+}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/List.java b/langtools/src/share/classes/com/sun/tools/javac/util/List.java
index 76704ef..30b00fa 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java
@@ -96,6 +96,26 @@
         return res.reverse();
     }
 
+    public List<A> intersect(List<A> that) {
+        ListBuffer<A> buf = ListBuffer.lb();
+        for (A el : this) {
+            if (that.contains(el)) {
+                buf.append(el);
+            }
+        }
+        return buf.toList();
+    }
+
+    public List<A> diff(List<A> that) {
+        ListBuffer<A> buf = ListBuffer.lb();
+        for (A el : this) {
+            if (!that.contains(el)) {
+                buf.append(el);
+            }
+        }
+        return buf.toList();
+    }
+
     /** Construct a list consisting of given element.
      */
     public static <A> List<A> of(A x1) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java
index 7c5849d..932801c 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java
@@ -24,6 +24,7 @@
  */
 package com.sun.tools.javac.util;
 
+import java.util.EnumMap;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
@@ -96,7 +97,7 @@
         this.diags = JCDiagnostic.Factory.instance(context);
         this.types = Types.instance(context);
         this.messages = JavacMessages.instance(context);
-        whereClauses = new LinkedHashMap<WhereClauseKind, Map<Type, JCDiagnostic>>();
+        whereClauses = new EnumMap<WhereClauseKind, Map<Type, JCDiagnostic>>(WhereClauseKind.class);
         configuration = new RichConfiguration(Options.instance(context), formatter);
         for (WhereClauseKind kind : WhereClauseKind.values())
             whereClauses.put(kind, new LinkedHashMap<Type, JCDiagnostic>());
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java
index 0cac65c..11a2b7f 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java
@@ -801,7 +801,9 @@
             doclintOpts.add(opt == null ? DocLint.XMSGS_OPTION : DocLint.XMSGS_CUSTOM_PREFIX + opt);
         }
 
-        if (doclintOpts.size() == 1
+        if (doclintOpts.isEmpty()) {
+            doclintOpts.add(DocLint.XMSGS_OPTION);
+        } else if (doclintOpts.size() == 1
                 && doclintOpts.get(0).equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) {
             return;
         }
diff --git a/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java b/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java
index 6f894e7..99aa17a 100644
--- a/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java
@@ -91,12 +91,13 @@
         print(pos.type);
 
         switch (pos.type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             if (showOffsets) {
                 print(", offset=");
                 print(pos.offset);
@@ -162,9 +163,12 @@
             print(", param_index=");
             print(pos.parameter_index);
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             if (showOffsets) {
                 print(", offset=");
@@ -177,11 +181,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            print(", param_index=");
-            print(pos.parameter_index);
-            break;
         case UNKNOWN:
             throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!");
         default:
diff --git a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java
index d25477b..94aeb01 100644
--- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java
@@ -400,12 +400,14 @@
         println(header);
         for (MethodParameters_attribute.Entry entry :
                  attr.method_parameter_table) {
+            String namestr =
+                entry.name_index != 0 ?
+                constantWriter.stringValue(entry.name_index) : "<no name>";
             String flagstr =
-                (0 != (entry.flags & ACC_FINAL) ? " final" : "") +
-                (0 != (entry.flags & ACC_SYNTHETIC) ? " synthetic" : "");
-            println(String.format(format,
-                                  constantWriter.stringValue(entry.name_index),
-                                  flagstr));
+                (0 != (entry.flags & ACC_FINAL) ? "final " : "") +
+                (0 != (entry.flags & ACC_MANDATED) ? "mandated " : "") +
+                (0 != (entry.flags & ACC_SYNTHETIC) ? "synthetic" : "");
+            println(String.format(format, namestr, flagstr));
         }
         indent(-1);
         return null;
diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
index 7f367d1..d640059 100644
--- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
+++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -362,7 +362,8 @@
         }
 
         try {
-            handleOptions(options, false);
+            if (options != null)
+                handleOptions(options, false);
         } catch (BadArgs e) {
             throw new IllegalArgumentException(e.getMessage());
         }
diff --git a/langtools/src/share/classes/javax/lang/model/element/Element.java b/langtools/src/share/classes/javax/lang/model/element/Element.java
index a95cbe0..ab2bcb5 100644
--- a/langtools/src/share/classes/javax/lang/model/element/Element.java
+++ b/langtools/src/share/classes/javax/lang/model/element/Element.java
@@ -149,12 +149,15 @@
     <A extends Annotation> A getAnnotation(Class<A> annotationType);
 
     /**
-     * Returns an array of all of this element's annotation for the
-     * specified type if such annotations are present, else an empty
-     * array.  The annotation may be either inherited or directly
-     * present on this element. This method will look through a container
-     * annotation (if present) if the supplied annotation type is
-     * repeatable.
+     * Returns annotations that are <em>present</em> on this element.
+     *
+     * If there are no annotations <em>present</em> on this element, the return
+     * value is an array of length 0.
+     *
+     * The difference between this method and {@link #getAnnotation(Class)}
+     * is that this method detects if its argument is a <em>repeatable
+     * annotation type</em> (JLS 9.6), and if so, attempts to find one or more
+     * annotations of that type by "looking through" a container annotation.
      *
      * <p> The annotations returned by this method could contain an element
      * whose value is of type {@code Class}.
@@ -189,14 +192,14 @@
      *
      * @see #getAnnotationMirrors()
      * @see #getAnnotation(java.lang.Class)
-     * @see java.lang.reflect.AnnotatedElement#getAnnotations
+     * @see java.lang.reflect.AnnotatedElement#getAnnotationsByType
      * @see EnumConstantNotPresentException
      * @see AnnotationTypeMismatchException
      * @see IncompleteAnnotationException
      * @see MirroredTypeException
      * @see MirroredTypesException
      */
-    <A extends Annotation> A[] getAnnotations(Class<A> annotationType);
+    <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType);
 
     /**
      * Returns the modifiers of this element, excluding annotations.
diff --git a/langtools/src/share/classes/javax/lang/model/element/TypeElement.java b/langtools/src/share/classes/javax/lang/model/element/TypeElement.java
index a86db82..d25c2e3 100644
--- a/langtools/src/share/classes/javax/lang/model/element/TypeElement.java
+++ b/langtools/src/share/classes/javax/lang/model/element/TypeElement.java
@@ -111,7 +111,6 @@
      */
     Name getQualifiedName();
 
-
     /**
      * Returns the simple name of this type element.
      *
@@ -152,7 +151,6 @@
      */
     List<? extends TypeParameterElement> getTypeParameters();
 
-
     /**
      * Returns the package of a top-level type and returns the
      * immediately lexically enclosing element for a {@linkplain
diff --git a/langtools/src/share/classes/javax/lang/model/util/Elements.java b/langtools/src/share/classes/javax/lang/model/util/Elements.java
index 2167f5a..5778bd0 100644
--- a/langtools/src/share/classes/javax/lang/model/util/Elements.java
+++ b/langtools/src/share/classes/javax/lang/model/util/Elements.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -249,4 +249,14 @@
      * @param cs the character sequence to return as a name
      */
     Name getName(CharSequence cs);
+
+    /**
+     * Returns {@code true} if the type element is a functional interface, {@code false} otherwise.
+     *
+     * @param type the type element being examined
+     * @return {@code true} if the element is a functional interface, {@code false} otherwise
+     * @jls 9.8 Functional Interfaces
+     * @since 1.8
+     */
+    boolean isFunctionalInterface(TypeElement type);
 }
diff --git a/langtools/test/com/sun/javadoc/T6735320/T6735320.java b/langtools/test/com/sun/javadoc/T6735320/T6735320.java
index 9646557..19b1df4 100644
--- a/langtools/test/com/sun/javadoc/T6735320/T6735320.java
+++ b/langtools/test/com/sun/javadoc/T6735320/T6735320.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -47,8 +47,8 @@
 
     public static void main(String... args) {
         T6735320 tester = new T6735320();
-        if (tester.runJavadoc(ARGS) != 0) {
-            throw new AssertionError("non-zero return code from javadoc");
+        if (tester.runJavadoc(ARGS) == 0) {
+            throw new AssertionError("zero return code from javadoc");
         }
         if (tester.getErrorOutput().contains("StringIndexOutOfBoundsException")) {
             throw new AssertionError("javadoc threw StringIndexOutOfBoundsException");
diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
new file mode 100644
index 0000000..93978fb
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
@@ -0,0 +1,186 @@
+/*
+ * 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      8006124
+ * @summary  Test javadoc support for profiles.
+ * @author   Bhavesh Patel
+ * @library  ../lib/
+ * @build    JavadocTester TestProfiles
+ * @run main TestProfiles
+ */
+public class TestProfiles extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "8006124";
+    private static final String PROFILE_BUG_ID = BUG_ID + "-1";
+    private static final String PACKAGE_BUG_ID = BUG_ID + "-2";
+    //Javadoc arguments.
+    private static final String[] ARGS1 = new String[]{
+        "-d", PROFILE_BUG_ID, "-sourcepath", SRC_DIR, "-Xprofilespath", SRC_DIR + FS
+        + "profile-rtjar-includes.txt", "pkg1", "pkg2", "pkg3", "pkg4", "pkg5"
+    };
+    private static final String[] ARGS2 = new String[]{
+        "-d", PACKAGE_BUG_ID, "-sourcepath", SRC_DIR, "pkg1", "pkg2", "pkg3", "pkg4", "pkg5"
+    };
+    //Input for string tests for profiles.
+    private static final String[][] PROFILES_TEST = {
+        // Tests for profile-overview-frame.html listing all profiles.
+        {PROFILE_BUG_ID + FS + "profile-overview-frame.html",
+            "<span><a href=\"overview-frame.html\" "
+            + "target=\"profileListFrame\">All Packages</a></span>"
+        },
+        {PROFILE_BUG_ID + FS + "profile-overview-frame.html",
+            "<li><a href=\"compact1-frame.html\" target=\"profileListFrame\">"
+            + "compact1</a></li>"
+        },
+        // Tests for profileName-frame.html listing all packages in a profile.
+        {PROFILE_BUG_ID + FS + "compact2-frame.html",
+            "<span><a href=\"overview-frame.html\" target=\"profileListFrame\">"
+            + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
+            + "target=\"profileListFrame\">All Profiles</a></span>"
+        },
+        {PROFILE_BUG_ID + FS + "compact2-frame.html",
+            "<li><a href=\"pkg4/compact2-package-frame.html\" "
+            + "target=\"packageFrame\">pkg4</a></li>"
+        },
+        // Test for profileName-package-frame.html listing all types in a
+        // package of a profile.
+        {PROFILE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html",
+            "<a href=\"../compact2-summary.html\" target=\"classFrame\">"
+            + "compact2</a> - <a href=\"../pkg2/compact2-package-summary.html\" "
+            + "target=\"classFrame\">pkg2</a>"
+        },
+        // Tests for profileName-summary.html listing the summary for a profile.
+        {PROFILE_BUG_ID + FS + "compact2-summary.html",
+            "<li><a href=\"compact1-summary.html\">Prev Profile</a></li>" + NL
+            + "<li><a href=\"compact3-summary.html\">Next Profile</a></li>"
+        },
+        {PROFILE_BUG_ID + FS + "compact2-summary.html",
+            "<h1 title=\"Profile\" class=\"title\">Profile&nbsp;compact2</h1>"
+        },
+        {PROFILE_BUG_ID + FS + "compact2-summary.html",
+            "<h3><a href=\"pkg2/compact2-package-summary.html\" "
+            + "target=\"classFrame\">pkg2</a></h3>"
+        },
+        // Tests for profileName-package-summary.html listing the summary for a
+        // package in a profile.
+        {PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html",
+            "<li><a href=\"../pkg4/compact3-package-summary.html\">Prev Package"
+            + "</a></li>"
+        },
+        {PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html",
+            "<div class=\"subTitle\">compact3</div>"
+        },
+        //Test for "overview-frame.html" showing the "All Profiles" link.
+        {PROFILE_BUG_ID + FS + "overview-frame.html",
+            "<span><a href=\"profile-overview-frame.html\" "
+            + "target=\"profileListFrame\">All Profiles</a></span>"
+        },
+        //Test for "className.html" showing the profile information for the type.
+        {PROFILE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html",
+            "<div class=\"subTitle\">compact1, compact2, compact3</div>"
+        }
+    };
+    private static final String[][] PROFILES_NEGATED_TEST = {
+        {PROFILE_BUG_ID + FS + "pkg3" + FS + "Class2Pkg3.html",
+            "<div class=\"subTitle\">compact1"
+        },
+        {PROFILE_BUG_ID + FS + "pkg3" + FS + "Interface1Pkg3.html",
+            "<div class=\"subTitle\">compact1"
+        },
+        {PROFILE_BUG_ID + FS + "pkg4" + FS + "compact2-package-frame.html",
+            "<li><a href=\"Anno1Pkg4.html\" title=\"annotation in pkg4\" "
+            + "target=\"classFrame\">Anno1Pkg4</a></li>"
+        }
+    };
+    private static final String[][] PACKAGES_TEST = {
+        {PACKAGE_BUG_ID + FS + "overview-frame.html",
+            "<h2 title=\"Packages\">Packages</h2>"
+        },
+        {PACKAGE_BUG_ID + FS + "pkg4" + FS + "package-frame.html",
+            "<h1 class=\"bar\"><a href=\"../pkg4/package-summary.html\" "
+            + "target=\"classFrame\">pkg4</a></h1>"
+        },
+        {PACKAGE_BUG_ID + FS + "pkg4" + FS + "package-summary.html",
+            "<div class=\"header\">" + NL + "<h1 title=\"Package\" "
+            + "class=\"title\">Package&nbsp;pkg4</h1>" + NL + "</div>"
+        }
+    };
+    private static final String[][] PACKAGES_NEGATED_TEST = {
+        {PACKAGE_BUG_ID + FS + "profile-overview-frame.html",
+            "<span><a href=\"overview-frame.html\" "
+            + "target=\"profileListFrame\">All Packages</a></span>"
+        },
+        {PACKAGE_BUG_ID + FS + "compact2-frame.html",
+            "<span><a href=\"overview-frame.html\" target=\"profileListFrame\">"
+            + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
+            + "target=\"profileListFrame\">All Profiles</a></span>"
+        },
+        {PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html",
+            "<a href=\"../compact2-summary.html\" target=\"classFrame\">"
+            + "compact2</a> - <a href=\"../pkg2/compact2-package-summary.html\" "
+            + "target=\"classFrame\">pkg2</a>"
+        },
+        {PACKAGE_BUG_ID + FS + "compact2-summary.html",
+            "<h1 title=\"Profile\" class=\"title\">Profile&nbsp;compact2</h1>"
+        },
+        {PACKAGE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html",
+            "<div class=\"subTitle\">compact3</div>"
+        },
+        {PACKAGE_BUG_ID + FS + "overview-frame.html",
+            "<span><a href=\"profile-overview-frame.html\" "
+            + "target=\"profileListFrame\">All Profiles</a></span>"
+        },
+        {PACKAGE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html",
+            "<div class=\"subTitle\">compact1, compact2, compact3</div>"
+        }
+    };
+
+    /**
+     * The entry point of the test.
+     *
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestProfiles tester = new TestProfiles();
+        run(tester, ARGS1, PROFILES_TEST, PROFILES_NEGATED_TEST);
+        run(tester, ARGS2, PACKAGES_TEST, PACKAGES_NEGATED_TEST);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class1Pkg1.java b/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class1Pkg1.java
new file mode 100644
index 0000000..dc5c50d
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class1Pkg1.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+/**
+ * A test class.
+ *
+ * @author Bhavesh Patel
+ */
+public class Class1Pkg1 {
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class2Pkg1.java b/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class2Pkg1.java
new file mode 100644
index 0000000..33ecb01
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class2Pkg1.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+/**
+ * A test class.
+ *
+ * @author Bhavesh Patel
+ */
+public class Class2Pkg1 {
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class3Pkg1.java b/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class3Pkg1.java
new file mode 100644
index 0000000..162cbfb
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg1/Class3Pkg1.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+/**
+ * A test class.
+ *
+ * @author Bhavesh Patel
+ */
+public class Class3Pkg1 {
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg1/Interface1Pkg1.java b/langtools/test/com/sun/javadoc/testProfiles/pkg1/Interface1Pkg1.java
new file mode 100644
index 0000000..e2a4337
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg1/Interface1Pkg1.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+/**
+ * A sample interface.
+ *
+ * @author Bhavesh Patel
+ */
+public interface Interface1Pkg1 {
+
+    /**
+     * A test method.
+     *
+     * @param a blah.
+     * @param b blah.
+     */
+    void method1(int a, int b);
+
+    /**
+     * Another test method.
+     *
+     * @param c blah.
+     */
+    void method2(int c);
+
+}
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Anno1Pkg2.java
similarity index 65%
copy from jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java
copy to langtools/test/com/sun/javadoc/testProfiles/pkg2/Anno1Pkg2.java
index 1124d12..9ef89fc 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Anno1Pkg2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,17 +23,18 @@
  * questions.
  */
 
-package sun.lwawt.macosx;
+package pkg2;
 
-// This exists strictly to work around the fact that java.awt.Conditional isn't a public class.
-// It uses java reflection to get the EventDispatchThread class and call a MacOSX only
-// method on it.
-//
-// NOTE: This uses reflection in its implementation, so it is not for performance critical code.
-//
-// See java.awt.EventDispatchThread and apple.awt.CPrintJob for more.
-//
-public abstract class EventDispatchAccess {
-    public native void pumpEventsAndWait();
-    public abstract boolean evaluate();
+import java.lang.annotation.*;
+
+/**
+ * Test Annotation class.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface Anno1Pkg2 {
+    /**
+     * Comment.
+     */
+    String[] value();
 }
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Anno2Pkg2.java
similarity index 65%
rename from jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java
rename to langtools/test/com/sun/javadoc/testProfiles/pkg2/Anno2Pkg2.java
index 1124d12..204fbc4 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Anno2Pkg2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,17 +23,13 @@
  * questions.
  */
 
-package sun.lwawt.macosx;
+package pkg2;
 
-// This exists strictly to work around the fact that java.awt.Conditional isn't a public class.
-// It uses java reflection to get the EventDispatchThread class and call a MacOSX only
-// method on it.
-//
-// NOTE: This uses reflection in its implementation, so it is not for performance critical code.
-//
-// See java.awt.EventDispatchThread and apple.awt.CPrintJob for more.
-//
-public abstract class EventDispatchAccess {
-    public native void pumpEventsAndWait();
-    public abstract boolean evaluate();
+import java.lang.annotation.*;
+
+/*
+ * A sample interface.
+ */
+public @interface Anno2Pkg2 {
+    boolean value() default true;
 }
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java
new file mode 100644
index 0000000..afa13d8
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg2;
+
+/**
+ * Another test class.
+ *
+ * @author Bhavesh Patel
+ */
+public class Class1Pkg2 {
+
+    /**
+     * A sample enum.
+     */
+    public static enum ModalExclusionType {
+        /**
+         * Test comment.
+         */
+        NO_EXCLUDE,
+        /**
+         * Another comment.
+         */
+        APPLICATION_EXCLUDE
+    };
+
+    /**
+     * A string constant.
+     */
+    public static final String CONSTANT1 = "C2";
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg3/Class1Pkg3.java b/langtools/test/com/sun/javadoc/testProfiles/pkg3/Class1Pkg3.java
new file mode 100644
index 0000000..ec340af
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg3/Class1Pkg3.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg3;
+
+/**
+ * A test class.
+ *
+ * @author Bhavesh Patel
+ */
+public class Class1Pkg3 {
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg3/Class2Pkg3.java b/langtools/test/com/sun/javadoc/testProfiles/pkg3/Class2Pkg3.java
new file mode 100644
index 0000000..45272d0
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg3/Class2Pkg3.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg3;
+
+/**
+ * A test class.
+ *
+ * @author Bhavesh Patel
+ */
+public class Class2Pkg3 {
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg3/Interface1Pkg3.java b/langtools/test/com/sun/javadoc/testProfiles/pkg3/Interface1Pkg3.java
new file mode 100644
index 0000000..09db1af
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg3/Interface1Pkg3.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg3;
+
+/**
+ * A sample interface.
+ *
+ * @author Bhavesh Patel
+ */
+public interface Interface1Pkg3 {
+
+    /**
+     * A test method.
+     *
+     * @param a blah.
+     * @param b blah.
+     */
+    void method1(int a, int b);
+
+    /**
+     * Another test method.
+     *
+     * @param c blah.
+     */
+    void method2(int c);
+
+}
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java b/langtools/test/com/sun/javadoc/testProfiles/pkg4/Anno1Pkg4.java
similarity index 65%
copy from jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java
copy to langtools/test/com/sun/javadoc/testProfiles/pkg4/Anno1Pkg4.java
index 1124d12..f9816d3 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/EventDispatchAccess.java
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg4/Anno1Pkg4.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,17 +23,18 @@
  * questions.
  */
 
-package sun.lwawt.macosx;
+package pkg4;
 
-// This exists strictly to work around the fact that java.awt.Conditional isn't a public class.
-// It uses java reflection to get the EventDispatchThread class and call a MacOSX only
-// method on it.
-//
-// NOTE: This uses reflection in its implementation, so it is not for performance critical code.
-//
-// See java.awt.EventDispatchThread and apple.awt.CPrintJob for more.
-//
-public abstract class EventDispatchAccess {
-    public native void pumpEventsAndWait();
-    public abstract boolean evaluate();
+import java.lang.annotation.*;
+
+/**
+ * Test Annotation class.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface Anno1Pkg4 {
+    /**
+     * Comment.
+     */
+    String[] value();
 }
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg4/Class1Pkg4.java b/langtools/test/com/sun/javadoc/testProfiles/pkg4/Class1Pkg4.java
new file mode 100644
index 0000000..7c9966b
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg4/Class1Pkg4.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg4;
+
+/**
+ * Another test class.
+ *
+ * @author Bhavesh Patel
+ */
+public class Class1Pkg4 {
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg5/Class1Pkg5.java b/langtools/test/com/sun/javadoc/testProfiles/pkg5/Class1Pkg5.java
new file mode 100644
index 0000000..606d838
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg5/Class1Pkg5.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg5;
+
+/**
+ * A test class.
+ *
+ * @author Bhavesh Patel
+ */
+public class Class1Pkg5 {
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/pkg5/Interface1Pkg5.java b/langtools/test/com/sun/javadoc/testProfiles/pkg5/Interface1Pkg5.java
new file mode 100644
index 0000000..4660a30
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg5/Interface1Pkg5.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg5;
+
+/**
+ * A sample interface.
+ *
+ * @author Bhavesh Patel
+ */
+public interface Interface1Pkg5 {
+
+    /**
+     * A test method.
+     *
+     * @param a blah.
+     * @param b blah.
+     */
+    void method1(int a, int b);
+}
diff --git a/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt
new file mode 100644
index 0000000..9460b3f
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt
@@ -0,0 +1,42 @@
+PROFILE_1_RTJAR_INCLUDE_PACKAGES := \
+    pkg2 
+
+PROFILE_1_RTJAR_INCLUDE_TYPES := \
+    pkg3/Class1Pkg3.class
+
+PROFILE_1_RTJAR_EXCLUDE_TYPES := 
+
+PROFILE_1_INCLUDE_METAINF_SERVICES := 
+
+
+PROFILE_2_RTJAR_INCLUDE_PACKAGES := \
+    pkg4 
+
+PROFILE_2_RTJAR_INCLUDE_TYPES := 
+
+PROFILE_2_RTJAR_EXCLUDE_TYPES := \
+    pkg4/Anno1Pkg4.class 
+
+PROFILE_2_INCLUDE_METAINF_SERVICES := 
+
+
+PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
+    pkg5 
+
+PROFILE_3_RTJAR_INCLUDE_TYPES := 
+
+PROFILE_3_RTJAR_EXCLUDE_TYPES := 
+
+PROFILE_3_INCLUDE_METAINF_SERVICES := 
+
+
+PROFILE_4_RTJAR_INCLUDE_PACKAGES := \
+    pkg1 
+
+PROFILE_4_RTJAR_INCLUDE_TYPES := 
+
+PROFILE_4_RTJAR_EXCLUDE_TYPES := 
+
+PROFILE_4_INCLUDE_METAINF_SERVICES :=  
+
+
diff --git a/langtools/test/tools/doclint/ParaTagTest.java b/langtools/test/tools/doclint/ParaTagTest.java
new file mode 100644
index 0000000..eb7a0a5
--- /dev/null
+++ b/langtools/test/tools/doclint/ParaTagTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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 8007566
+ * @summary DocLint too aggressive with not allowed here: <p>
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs ParaTagTest.java
+ */
+
+/**
+ * First line.
+ * <p> Para c1.</p>
+ * <p> Para c2.
+ * <p> Para c3.</p>
+ */
+public class ParaTagTest {
+    /**
+     * m1 <code>code </code>.
+     * <p> Para m1.
+     * <p> Para m2.
+     */
+    public void m() {}
+
+    /**
+     * m2.
+     * <p> Para z1.
+     * <p> Para z2.
+     * <pre>
+     *    Preformat 1.
+     * </pre>
+     */
+    public void z() {}
+}
diff --git a/langtools/test/tools/javac/6758789/T6758789b.out b/langtools/test/tools/javac/6758789/T6758789b.out
index 45a828d..5393f9a 100644
--- a/langtools/test/tools/javac/6758789/T6758789b.out
+++ b/langtools/test/tools/javac/6758789/T6758789b.out
@@ -1,4 +1,4 @@
-T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
+T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<java.lang.Object>
 T6758789b.java:16:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo<X>, T6758789a.Foo, kindname.class, T6758789a
 - compiler.err.warnings.and.werror
 1 error
diff --git a/langtools/test/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java b/langtools/test/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java
new file mode 100644
index 0000000..0651132
--- /dev/null
+++ b/langtools/test/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.  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.
+ */
+
+/*
+ * @test
+ * @bug 7166455
+ * @summary javac doesn't set ACC_STRICT bit on <clinit> for strictfp class
+ * @run main CheckACC_STRICTFlagOnclinitTest
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.File;
+import java.io.IOException;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.Method;
+
+import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
+
+public strictfp class CheckACC_STRICTFlagOnclinitTest {
+    private static final String AssertionErrorMessage =
+        "All methods should have the ACC_STRICT access flag " +
+        "please check output";
+    private static final String offendingMethodErrorMessage =
+        "Method %s of class %s doesn't have the ACC_STRICT access flag";
+
+    static {
+        class Foo {
+            class Bar {
+                void m11() {}
+            }
+            void m1() {}
+        }
+    }
+    void m2() {
+        class Any {
+            void m21() {}
+        }
+    }
+
+    private List<String> errors = new ArrayList<>();
+
+    public static void main(String[] args)
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        new CheckACC_STRICTFlagOnclinitTest().run();
+    }
+
+    private void run()
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        String testClasses = System.getProperty("test.classes");
+        check(testClasses,
+              "CheckACC_STRICTFlagOnclinitTest.class",
+              "CheckACC_STRICTFlagOnclinitTest$1Foo.class",
+              "CheckACC_STRICTFlagOnclinitTest$1Foo$Bar.class",
+              "CheckACC_STRICTFlagOnclinitTest$1Any.class");
+        if (errors.size() > 0) {
+            for (String error: errors) {
+                System.err.println(error);
+            }
+            throw new AssertionError(AssertionErrorMessage);
+        }
+    }
+
+    void check(String dir, String... fileNames)
+        throws
+            IOException,
+            ConstantPoolException,
+            Descriptor.InvalidDescriptor {
+        for (String fileName : fileNames) {
+            ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName));
+
+            for (Method method : classFileToCheck.methods) {
+                if ((method.access_flags.flags & ACC_STRICT) == 0) {
+                    errors.add(String.format(offendingMethodErrorMessage,
+                            method.getName(classFileToCheck.constant_pool),
+                            classFileToCheck.getName()));
+                }
+            }
+        }
+    }
+
+}
diff --git a/langtools/test/tools/javac/7167125/DiffResultAfterSameOperationInnerClasses.java b/langtools/test/tools/javac/7167125/DiffResultAfterSameOperationInnerClasses.java
new file mode 100644
index 0000000..c7c3368
--- /dev/null
+++ b/langtools/test/tools/javac/7167125/DiffResultAfterSameOperationInnerClasses.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2002, 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 7167125
+ * @summary Two variables after the same operation in a inner class return
+ * different results
+ * @run main DiffResultAfterSameOperationInnerClasses
+ */
+
+public class DiffResultAfterSameOperationInnerClasses {
+    public int i = 1;
+    private int j = 1;
+    public String s1 = "Hi, ";
+    private String s2 = "Hi, ";
+
+    public static void main(String[] args) {
+        InnerClass inner =
+                new DiffResultAfterSameOperationInnerClasses().new InnerClass();
+        if (!inner.test()) {
+            throw new AssertionError("Different results after same calculation");
+        }
+    }
+
+    class InnerClass {
+        public boolean test() {
+            i += i += 1;
+            j += j += 1;
+
+            s1 += s1 += "dude";
+            s2 += s2 += "dude";
+
+            System.out.println("s1 = " + s1);
+            System.out.println("s2 = " + s2);
+
+            return (i == j && i == 3 &&
+                    s1.equals(s2) && s1.endsWith("Hi, Hi, dude"));
+        }
+    }
+}
diff --git a/langtools/test/tools/javac/8005931/CheckACC_STRICTFlagOnPkgAccessClassTest.java b/langtools/test/tools/javac/8005931/CheckACC_STRICTFlagOnPkgAccessClassTest.java
new file mode 100644
index 0000000..e879a3c
--- /dev/null
+++ b/langtools/test/tools/javac/8005931/CheckACC_STRICTFlagOnPkgAccessClassTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.  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.
+ */
+
+/*
+ * @test
+ * @bug 8005931
+ * @summary javac doesn't set ACC_STRICT for classes with package access
+ * @run main CheckACC_STRICTFlagOnPkgAccessClassTest
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.Method;
+
+import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
+
+public class CheckACC_STRICTFlagOnPkgAccessClassTest {
+
+    private static final String AssertionErrorMessage =
+        "All methods should have the ACC_STRICT access flag " +
+        "please check output";
+    private static final String CompilationErrorMessage =
+        "Error thrown when compiling the following source:\n";
+    private static final String offendingMethodErrorMessage =
+        "Method %s of class %s doesn't have the ACC_STRICT access flag";
+
+    JavaSource source = new JavaSource();
+
+    private List<String> errors = new ArrayList<>();
+
+    public static void main(String[] args)
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        new CheckACC_STRICTFlagOnPkgAccessClassTest().run(comp);
+    }
+
+    private void run(JavaCompiler comp)
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        compile(comp);
+        check();
+        if (errors.size() > 0) {
+            for (String error: errors) {
+                System.err.println(error);
+            }
+            throw new AssertionError(AssertionErrorMessage);
+        }
+    }
+
+    private void compile(JavaCompiler comp) {
+        JavacTask ct = (JavacTask)comp.getTask(null, null, null, null, null,
+                Arrays.asList(source));
+        try {
+            if (!ct.call()) {
+                throw new AssertionError(CompilationErrorMessage +
+                        source.getCharContent(true));
+            }
+        } catch (Throwable ex) {
+            throw new AssertionError(CompilationErrorMessage +
+                    source.getCharContent(true));
+        }
+    }
+
+    void check()
+        throws
+            IOException,
+            ConstantPoolException,
+            Descriptor.InvalidDescriptor {
+        ClassFile classFileToCheck = ClassFile.read(new File("Test.class"));
+
+        for (Method method : classFileToCheck.methods) {
+            if ((method.access_flags.flags & ACC_STRICT) == 0) {
+                errors.add(String.format(offendingMethodErrorMessage,
+                        method.getName(classFileToCheck.constant_pool),
+                        classFileToCheck.getName()));
+            }
+        }
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        String source = "strictfp class Test {" +
+                "    Test(){}" +
+                "    void m(){}" +
+                "}";
+
+        public JavaSource() {
+            super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+}
diff --git a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out
index 196e739..24bce3d 100644
--- a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out
+++ b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out
@@ -1,4 +1,4 @@
-T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
+T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.incompatible.eq.upper.bounds: T, compiler.misc.type.captureof: 1, ?, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
 T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
 T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?))}
 3 errors
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java
index 8a01095..28fe91d 100644
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java
@@ -40,14 +40,17 @@
         IMPORTINHERITED("import java.lang.annotation.Inherited;\n"),
         IMPORTRETENTION("import java.lang.annotation.Retention;\n" +
                         "\nimport java.lang.annotation.RetentionPolicy;\n"),
+        IMPORTSTMTS("import java.lang.annotation.*;\n"),
         REPEATABLE("\n@Repeatable(FooContainer.class)\n"),
         CONTAINER("@interface FooContainer {\n" +"  Foo[] value();\n}\n"),
         BASE("@interface Foo {}\n"),
+        BASEANNO("@Foo"),
         REPEATABLEANNO("\n@Foo() @Foo()"),
         DEPRECATED("\n@Deprecated"),
         DOCUMENTED("\n@Documented"),
         INHERITED("\n@Inherited"),
-        RETENTION("@Retention(RetentionPolicy.#VAL)\n");
+        RETENTION("@Retention(RetentionPolicy.#VAL)\n"),
+        TARGET("\n@Target(#VAL)\n");
 
         private String val;
 
@@ -69,6 +72,7 @@
     public static final String template =
             "/*PACKAGE*/\n" +
             "//pkg test;\n\n" +
+            "/*ANNODATA*/\n" + // import statements, declaration of Foo/FooContainer
             "/*TYPE*/ //class\n" +
             "class #ClassName {\n" +
             "  /*FIELD*/ //instance var\n" +
@@ -97,7 +101,11 @@
             "interface TestInterface {}\n\n" +
             "/*TYPE*/\n" +
             "/*ANNOTATION_TYPE*/\n" +
-            "@interface TestAnnotationType{}\n";
+            "@interface TestAnnotationType{}\n" +
+            "class TestPkg {}\n" +
+            "class TestTypeAnno </*TYPE_PARAMETER*/ T extends Object> {\n" +
+            "  String /*TYPE_USE*/[] arr;\n" +
+            "}";
 
     // Create and compile FileObject using values for className and contents
     public static boolean compileCode(String className, String contents,
@@ -150,3 +158,4 @@
         }
     }
 }
+
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java
new file mode 100644
index 0000000..d6d9795
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java
@@ -0,0 +1,469 @@
+/*
+ * 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      7195131
+ * @author   sogoel
+ * @summary  Combo test for all possible combinations for Target values
+ * @build    Helper
+ * @compile  TargetAnnoCombo.java TestCaseGenerator.java
+ * @run main TargetAnnoCombo
+ */
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+/*
+ * TargetAnnoCombo gets a list of test case numbers using TestCaseGenerator.
+ * For each of the test case number, @Target sets for base and container annotations
+ * are determined, source files are generated, compiled, and the result is verified
+ * based on if the @Target set for base and container is a positive or negative combination.
+ *
+ * @Target sets for base and container annotations are determined using a bit mapping of
+ * 10 ElementType enum constants defined in JDK8.
+ *
+ * Bit      Target value
+ *  0  "ElementType.ANNOTATION_TYPE"
+ *  1  "ElementType.CONSTRUCTOR"
+ *  2  "ElementType.FIELD"
+ *  3  "ElementType.LOCAL_VARIABLE"
+ *  4  "ElementType.METHOD"
+ *  5  "ElementType.TYPE"
+ *  6  "ElementType.PARAMETER"
+ *  7  "ElementType.PACKAGE"
+ *  8  "ElementType.TYPE_USE"
+ *  9  "ElementType.TYPE_PARAMETER"
+ *
+ * Group 1:
+ * 20 bits mapping, representing a test case number, is used for all target set
+ * combinations ( 0 to 1048575 ) including empty @Target sets => @Target({}).
+ * From this 20 bits, 10 bits are for base followed by 10 bits for container
+ * where each bit maps to an ElementType enum constant defined in JDK8.
+ *
+ * Examples:
+ * Test case number: 4, binary: 100 => container=100, base=[], container=["ElementType.FIELD"]
+ * Test case number: 1003575, binary: 11110101000000110111 => base=1111010100, container=0000110111;
+ *                   base=["ElementType.PARAMETER", "ElementType.TYPE_USE", "ElementType.METHOD", "ElementType.FIELD", "ElementType.PACKAGE", "ElementType.TYPE_PARAMETER"],
+ *                   container=["ElementType.TYPE", "ElementType.METHOD", "ElementType.ANNOTATION_TYPE", "ElementType.CONSTRUCTOR", "ElementType.FIELD"]
+ *
+ * In the following groups, no @Target set is represented by null.
+ * Group 2:
+ * @Target is not defined on base.
+ * Target sets for container are determined using the 10-bit binary number
+ * resulting in 1024 test cases, mapping them to test case numbers from
+ * 1048576 to (1048576 + 1023) => 1048576 to 1049599.
+ *
+ * Example:
+ * Test case number: 1048587 => 1048587 - 1048576 = test case 11 in Group 2, binary: 1011 =>
+ *                   base = null,
+ *                   container = ["ElementType.ANNOTATION_TYPE","ElementType.CONSTRUCTOR","ElementType.LOCAL_VARIABLE"]
+ *
+ * Group 3:
+ * @Target is not defined on container
+ * Target sets for base are determined using the 10-bit binary number
+ * resulting in 1024 test cases, mapping them to test case numbers from
+ * 1049600 to (1049600 + 1023) => 1049600 to 1050623.
+ *
+ * Example:
+ * Test case number: 1049708 => 1049708 - 1049600 = test case 108 in Group 3, binary: 1101100 =>
+ *                   base = ["ElementType.FIELD", "ElementType.LOCAL_VARIABLE", "ElementType.TYPE", "ElementType.PARAMETER"],
+ *                   container = null
+ *
+ * For the above group, test case number: 1049855 gives compiler error, JDK-8006547 filed
+ *
+ * Group 4:
+ * @Target not defined for both base and container annotations.
+ *
+ * This is the last test and corresponds to test case number 1050624. base=null, container=null
+ *
+ * Examples to run this test:
+ * 1. Run a specific test case number:
+ *    ${JTREG} -DTestCaseNum=10782 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ * 2. Run specific number of tests:
+ *    ${JTREG} -DNumberOfTests=4 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ * 3. Run specific number of tests with a seed:
+ *    ${JTREG} -DNumberOfTests=4 -DTestSeed=-972894659 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ * 4. Run tests in default mode (number of tests = 1000):
+ *    ${JTREG} -DTestMode=DEFAULT -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ * 5. Run all tests (FULL mode):
+ *    ${JTREG} -DTestMode=FULL -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ *
+ */
+
+public class TargetAnnoCombo {
+    int errors = 0;
+    static final String TESTPKG = "testpkg";
+    /*
+     *  Set it to true to get more debug information including base and
+     *  container target sets for a given test case number
+     */
+    static final boolean DEBUG = false;
+
+    // JDK 5/6/7/8 Targets
+    static final String[] targetVals = {"ElementType.ANNOTATION_TYPE",
+      "ElementType.CONSTRUCTOR", "ElementType.FIELD",
+      "ElementType.LOCAL_VARIABLE", "ElementType.METHOD",
+      "ElementType.TYPE", "ElementType.PARAMETER",
+      "ElementType.PACKAGE", "ElementType.TYPE_USE",
+      "ElementType.TYPE_PARAMETER"};
+
+    // TYPE_USE and TYPE_PARAMETER (added in JDK8) are not part of default Target set
+    static final int DEFAULT_TARGET_CNT = 8;
+
+    public static void main(String args[]) throws Exception {
+
+        /* maxTestNum = (base and container combinations of targetVals elems [0 - 1048575 combos])
+         *              + (combinations where base or container has no Target [1024 combos])
+         *              + (no -1 even though 1st test is number 0 as last test is where both
+         *                 base and container have no target)
+         */
+
+        int maxTestNum = (int)Math.pow(2, 2*targetVals.length) + 2*(int)Math.pow(2, targetVals.length);
+        TestCaseGenerator tcg = new TestCaseGenerator(maxTestNum);
+        TargetAnnoCombo tac = new TargetAnnoCombo();
+
+        int testCtr = 0;
+        int testCase = -1;
+        while ( (testCase=tcg.getNextTestCase()) != -1 ) {
+            tac.executeTestCase(testCase, maxTestNum);
+            testCtr++;
+        }
+
+        System.out.println("Total tests run: " + testCtr);
+        if (tac.errors > 0)
+            throw new Exception(tac.errors + " errors found");
+    }
+
+    /*
+     * For given testCase, determine the base and container annotation Target sets,
+     * get if testCase should compile, get test source file(s), get compilation result and verify.
+     *
+     */
+    private void executeTestCase(int testCase, int maxTestNum) {
+
+        // Determine base and container annotation Target sets for the testCase
+        Set<String> baseAnnoTarget = null;
+        Set<String> conAnnoTarget = null;
+
+        //Number of base and container combinations [0 - 1048575 combos]
+        int baseContCombos = (int)Math.pow(2, 2*targetVals.length);
+        //Number of either base or container combinations when one of them has no @Target [1024 combos]
+        int targetValsCombos = (int)Math.pow(2, targetVals.length);
+
+        if (testCase >= baseContCombos) {
+            //Base annotation do not have @Target
+            if (testCase < baseContCombos + targetValsCombos) {
+                baseAnnoTarget = null;
+                conAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos));
+            } else if (testCase < baseContCombos + 2*targetValsCombos) {
+                //Container annotation do not have @Target
+                baseAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos - targetValsCombos));
+                conAnnoTarget = null;
+            } else {
+                //Both Base and Container annotation do not have @Target
+                baseAnnoTarget = null;
+                conAnnoTarget = null;
+            }
+        } else {
+            //TestCase number is represented as 10-bits for base followed by container bits
+            String bin = Integer.toBinaryString(testCase);
+            String base="", cont=bin;
+            if (bin.length() > targetVals.length){
+                base = bin.substring(0, bin.length() - targetVals.length);
+                cont = bin.substring(bin.length() - targetVals.length,bin.length());
+            }
+            baseAnnoTarget = getSetFromBitVec(base);
+            conAnnoTarget = getSetFromBitVec(cont);
+        }
+
+        debugPrint("Test case number = " + testCase + " => binary = " + Integer.toBinaryString(testCase));
+        debugPrint(" => baseAnnoTarget = " + baseAnnoTarget);
+        debugPrint(" => containerAnnoTarget = " + conAnnoTarget);
+
+        // Determine if a testCase should compile or not
+        String className = "TC" + testCase;
+        boolean shouldCompile = isValidSubSet(baseAnnoTarget, conAnnoTarget);
+
+        // Get test source file(s)
+        Iterable<? extends JavaFileObject> files = getFileList(className, baseAnnoTarget,
+                conAnnoTarget, shouldCompile);
+
+        // Get result of compiling test src file(s)
+        boolean result = getCompileResult(className, shouldCompile, files);
+
+        // List test src code if test fails
+        if(!result) {
+            System.out.println("FAIL: Test " + testCase);
+            try {
+                for (JavaFileObject f: files) {
+                    System.out.println("File: " + f.getName() + "\n" + f.getCharContent(true));
+                }
+            } catch (IOException ioe) {
+                System.out.println("Exception: " + ioe);
+            }
+        } else {
+            debugPrint("PASS: Test " + testCase);
+        }
+    }
+
+    // Get a Set<String> based on bits that are set to 1
+    public Set<String> getSetFromBitVec(String bitVec) {
+        Set<String> ret = new HashSet<>();
+        char[] bit = bitVec.toCharArray();
+        for (int i=bit.length-1, j=0; i>=0; i--, j++){
+            if (bit[i] == '1') {
+                ret.add(targetVals[j]);
+            }
+        }
+        return ret;
+    }
+
+    // Compile the test source file(s) and return test result
+    private boolean getCompileResult(String className, boolean shouldCompile,
+            Iterable<? extends JavaFileObject> files) {
+
+        DiagnosticCollector<JavaFileObject> diagnostics =
+                new DiagnosticCollector<JavaFileObject>();
+        Helper.compileCode(diagnostics, files);
+
+        // Test case pass or fail
+        boolean ok = false;
+
+        String errMesg = "";
+        int numDiags = diagnostics.getDiagnostics().size();
+
+        if (numDiags == 0) {
+            if (shouldCompile) {
+                debugPrint("Test passed, compiled as expected.");
+                ok = true;
+            } else {
+                errMesg = "Test failed, compiled unexpectedly.";
+                ok = false;
+            }
+        } else {
+            if (shouldCompile) {
+                // did not compile
+                errMesg = "Test failed, did not compile.";
+                ok = false;
+            } else {
+                // Error in compilation as expected
+                String expectedErrKey = "compiler.err.invalid.repeatable." +
+                        "annotation.incompatible.target";
+                for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
+                    if((d.getKind() == Diagnostic.Kind.ERROR) &&
+                        d.getCode().contains(expectedErrKey)) {
+                        // Error message as expected
+                        debugPrint("Error message as expected.");
+                        ok = true;
+                        break;
+                    } else {
+                        // error message is incorrect
+                        ok = false;
+                    }
+                }
+                if (!ok) {
+                    errMesg = "Incorrect error received when compiling " +
+                        className + ", expected: " + expectedErrKey;
+                }
+            }
+        }
+
+        if(!ok) {
+            error(errMesg);
+            for (Diagnostic<?> d : diagnostics.getDiagnostics())
+                System.out.println(" Diags: " + d);
+        }
+        return ok;
+    }
+
+    private void debugPrint(String string) {
+        if(DEBUG)
+            System.out.println(string);
+    }
+
+    // Create src code and corresponding JavaFileObjects
+    private Iterable<? extends JavaFileObject> getFileList(String className,
+            Set<String> baseAnnoTarget, Set<String> conAnnoTarget,
+            boolean shouldCompile) {
+
+        String srcContent = "";
+        String pkgInfoContent = "";
+        String template = Helper.template;
+        String baseTarget = "", conTarget = "";
+
+        String target = Helper.ContentVars.TARGET.getVal();
+        if(baseAnnoTarget != null) {
+            baseTarget = target.replace("#VAL", baseAnnoTarget.toString())
+                                  .replace("[", "{").replace("]", "}");
+        }
+        if(conAnnoTarget != null) {
+            conTarget = target.replace("#VAL", conAnnoTarget.toString())
+                                 .replace("[", "{").replace("]", "}");
+        }
+
+        String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() +
+                          conTarget +
+                          Helper.ContentVars.CONTAINER.getVal() +
+                          baseTarget +
+                          Helper.ContentVars.REPEATABLE.getVal() +
+                          Helper.ContentVars.BASE.getVal();
+
+        JavaFileObject pkgInfoFile = null;
+
+        /*
+         *  If shouldCompile = true and no @Target is specified for container annotation,
+         *  then all 8 ElementType enum constants are applicable as targets for
+         *  container annotation.
+         */
+        if(shouldCompile && conAnnoTarget == null) {
+            //conAnnoTarget = new HashSet<String>(Arrays.asList(targetVals));
+            conAnnoTarget = getDefaultTargetSet();
+        }
+
+        if(shouldCompile) {
+            boolean isPkgCasePresent = new ArrayList<String>(conAnnoTarget).contains("ElementType.PACKAGE");
+            String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() + " " + Helper.ContentVars.BASEANNO.getVal();
+            for(String s: conAnnoTarget) {
+                s = s.replace("ElementType.","");
+                String replaceStr = "/*"+s+"*/";
+                if(s.equalsIgnoreCase("PACKAGE")) {
+                    //Create packageInfo file
+                    String pkgInfoName = TESTPKG + "." + "package-info";
+                    pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData;
+                    pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent);
+                } else {
+                    template = template.replace(replaceStr, repeatableAnno);
+                    //srcContent = template.replace("#ClassName",className);
+                    if(!isPkgCasePresent) {
+                        srcContent = template.replace("/*ANNODATA*/", annoData).replace("#ClassName",className);
+                    } else {
+                        replaceStr = "/*PACKAGE*/";
+                        srcContent = template.replace(replaceStr, "package " + TESTPKG + ";")
+                                     .replace("#ClassName", className);
+                    }
+                }
+            }
+        } else {
+            // For invalid cases, compilation should fail at declaration site
+            template = "class #ClassName {}";
+            srcContent = annoData + template.replace("#ClassName",className);
+        }
+        JavaFileObject srcFile = Helper.getFile(className, srcContent);
+        Iterable<? extends JavaFileObject> files = null;
+        if(pkgInfoFile != null)
+            files = Arrays.asList(pkgInfoFile,srcFile);
+        else
+            files = Arrays.asList(srcFile);
+        return files;
+    }
+
+    private Set<String> getDefaultTargetSet() {
+        Set<String> defaultSet = new HashSet<>();
+        int ctr = 0;
+        for(String s : targetVals) {
+            if(ctr++ < DEFAULT_TARGET_CNT) {
+                defaultSet.add(s);
+            }
+        }
+        return defaultSet;
+    }
+
+    private boolean isValidSubSet(Set<String> baseAnnoTarget, Set<String> conAnnoTarget) {
+        /*
+         *  RULE 1: conAnnoTarget should be a subset of baseAnnoTarget
+         *  RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere
+         *         - Empty sets for both is valid
+         *         - Empty baseTarget set is invalid with non-empty conTarget set
+         *         - Non-empty baseTarget set is valid with empty conTarget set
+         *  RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets
+         *         - No @Target for both is valid
+         *         - No @Target for baseTarget set with @Target conTarget set is valid
+         *         - @Target for baseTarget set with no @Target for conTarget is invalid
+         */
+
+
+        /* If baseAnno has no @Target, Foo can be either applied to @Target specified for container annotation
+         * else will be applicable for all default targets if no @Target is present for container annotation.
+         * In both cases, the set will be a valid set with no @Target for base annotation
+         */
+        if(baseAnnoTarget == null) {
+            if(conAnnoTarget == null) return true;
+            return !(conAnnoTarget.contains("ElementType.TYPE_USE") || conAnnoTarget.contains("ElementType.TYPE_PARAMETER"));
+        }
+
+        Set<String> tempBaseSet = new HashSet<>(baseAnnoTarget);
+        // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default
+        if(baseAnnoTarget.contains("ElementType.TYPE")) {
+            tempBaseSet.add("ElementType.ANNOTATION_TYPE");
+        }
+
+        /*
+         * If containerAnno has no @Target, only valid case if baseAnnoTarget has all targets defined
+         * else invalid set
+         */
+        if(conAnnoTarget == null) {
+            return (tempBaseSet.containsAll(getDefaultTargetSet()));
+        }
+
+        // At this point, neither conAnnoTarget or baseAnnoTarget are null
+        if(conAnnoTarget.size() == 0) return true;
+
+        // At this point, conAnnoTarget is non-empty
+        if (baseAnnoTarget.size() == 0) return false;
+
+        // At this point, neither conAnnoTarget or baseAnnoTarget are empty
+        return tempBaseSet.containsAll(conAnnoTarget);
+    }
+
+    void error(String msg) {
+        System.out.println("ERROR: " + msg);
+        errors++;
+    }
+
+    // Lists the start and end range for the given set of target vals
+    void showGroups() {
+        //Group 1: All target set combinations ( 0 to 1048575 ) including empty @Target sets => @Target({})
+        int grpEnd1 = (int)Math.pow(2, 2*targetVals.length) - 1;
+        System.out.println("[Group 1]: 0 - " + grpEnd1);
+
+        //Group 2: @Target not defined for base annotation ( 1048576 - 1049599 ).
+        System.out.print("[Group 2]: " + (grpEnd1 + 1) + " - ");
+        int grpEnd2 = grpEnd1 + 1 + (int)Math.pow(2, targetVals.length) - 1;
+        System.out.println(grpEnd2);
+
+        //Group 3: @Target not defined for container annotation ( 1049600 - 1050623 ).
+        System.out.print("[Group 3]: " + (grpEnd2 + 1) + " - ");
+        int grpEnd3 = grpEnd2 + 1 + (int)Math.pow(2, targetVals.length) - 1;
+        System.out.println(grpEnd3);
+
+        //Group 4: @Target not defined for both base and container annotations ( 1050624 ).
+        System.out.println("[Group 4]: " + (grpEnd3 + 1));
+    }
+}
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/TestCaseGenerator.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/TestCaseGenerator.java
new file mode 100644
index 0000000..fe2eaf2
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/TestCaseGenerator.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+
+/* System properties:
+ * NumberOfTests, TestMode, and TestCaseNum are mutually exclusive
+ * TestSeed will be used only with NumberOfTests or TestMode, otherwise it will be ignored
+ * -DNumberOfTests=[0 to 2^20+2^11+1]
+ * -DTestMode=[FULL|DEFAULT]
+ * -DTestSeed=[seedNumber]
+ * -DTestCaseNum=[0 to 2^20+2^11+1]
+ */
+public class TestCaseGenerator {
+    // Total number of tests to be run
+    int numberOfTests = -1;
+    //Single test case
+    int testCaseNum = -1;
+    //Seed used to generate test cases
+    int testSeed;
+
+    int maxTestNum;
+    Random randNum;
+
+    // used in getNextTestCase
+    int curTestNum;
+    int testCompletedCount;
+    HashSet<Integer> uniqueTestSet;
+
+    static final int DEFAULT_TEST_COUNT = 250;
+
+    /*
+     *  Get parameter values from command line to set numberOfTests, testCaseNum,
+     *  and testSeed
+     */
+    public TestCaseGenerator(int maxTestNum) {
+        this.maxTestNum = maxTestNum;
+
+        // Set values for variables based on input from command line
+
+        // TestMode system property
+        String testModeVal = System.getProperty("TestMode");
+        if(testModeVal != null && !testModeVal.isEmpty()) {
+            switch (testModeVal.toUpperCase()) {
+            case "FULL":
+                numberOfTests = maxTestNum;
+                break;
+            case "DEFAULT":
+                numberOfTests = DEFAULT_TEST_COUNT;
+                break;
+            default:
+                System.out.println("Invalid property value " + testModeVal +
+                        " for numberOfTests. Possible range: 0 to " +
+                        maxTestNum + ". Ignoring property");
+                numberOfTests = -1;
+            }
+        }
+
+        // NumberOfTests system property
+        String numTestsStr = System.getProperty("NumberOfTests");
+        if(numTestsStr != null && !numTestsStr.isEmpty()) {
+            int numTests = -1;
+            try {
+                numTests = Integer.parseInt(numTestsStr);
+                if (numTests < 0 || numTests > maxTestNum) {
+                    throw new NumberFormatException();
+                }
+            } catch(NumberFormatException nfe) {
+                System.out.println("Invalid NumberOfTests property value " +
+                        numTestsStr + ". Possible range: 0 to " + maxTestNum +
+                        "Reset to default: " + DEFAULT_TEST_COUNT);
+                numTests = DEFAULT_TEST_COUNT;
+            }
+
+            if (numberOfTests != -1 && numTests != -1) {
+                System.out.println("TestMode and NumberOfTests cannot be set together. Ignoring TestMode.");
+            }
+            numberOfTests = numTests;
+        }
+
+        // TestSeed system property
+        String seedVal = System.getProperty("TestSeed");
+        if(seedVal != null && !seedVal.isEmpty()) {
+            try {
+                testSeed = Integer.parseInt(seedVal);
+            } catch(NumberFormatException nfe) {
+                Random srand = new Random();
+                testSeed = srand.nextInt();
+            }
+        } else {
+            Random srand = new Random();
+            testSeed = srand.nextInt();
+        }
+
+        // TestCaseNum system property
+        String testNumStr = System.getProperty("TestCaseNum");
+        if(testNumStr != null && !testNumStr.isEmpty()) {
+            try {
+                testCaseNum = Integer.parseInt(testNumStr);
+                if (testCaseNum < 0 || testCaseNum > maxTestNum) {
+                    throw new NumberFormatException();
+                }
+            } catch(NumberFormatException nfe) {
+                System.out.println("Invalid TestCaseNumber property value " +
+                        testNumStr + ". Possible value in range: 0 to " +
+                        maxTestNum + ". Defaulting to last test case.");
+                testCaseNum = maxTestNum;
+            }
+
+            if ( numberOfTests != -1) {
+                System.out.println("TestMode or NumberOfTests cannot be set along with TestCaseNum. Ignoring TestCaseNumber.");
+                testCaseNum = -1;
+            }
+        }
+
+        if (numberOfTests == -1 && testCaseNum == -1) {
+            numberOfTests = DEFAULT_TEST_COUNT;
+            System.out.println("Setting TestMode to default, will run " + numberOfTests + "tests.");
+        }
+
+        /*
+         *  By this point in code, we will have:
+         *  - testSeed: as per TestSeed or a Random one
+         *  - numberOfTests to run or -1 to denote not set
+         *  - testCaseNum to run or -1 to denote not set
+         */
+
+        /*
+         * If numberOfTests = maxTestNum, all tests are to be run,
+         * so no randNum will be required
+         */
+        if (numberOfTests != -1 && numberOfTests < maxTestNum) {
+            System.out.println("Seed = " + testSeed);
+            randNum = new Random(testSeed);
+            uniqueTestSet = new HashSet<>();
+        }
+
+        testCompletedCount = 0;
+        // to be used to keep sequential count when running all tests
+        curTestNum = 0;
+    }
+
+    /*
+     * returns next test case number to run
+     * returns -1 when there are no more tests to run
+     */
+    public int getNextTestCase() {
+        if (testCaseNum != -1) {
+            int nextTC = testCaseNum;
+            testCaseNum = -1;
+            return nextTC;
+        }
+        if (++testCompletedCount <= numberOfTests) {
+            if (numberOfTests == maxTestNum) {
+                //all the tests need to be run, so just return
+                //next test case sequentially
+                return curTestNum++;
+            } else {
+                int nextTC = -1;
+                // Ensuring unique test are run
+                while(!uniqueTestSet.add(nextTC = randNum.nextInt(maxTestNum))) {
+                }
+                return nextTC;
+            }
+        }
+        return -1;
+    }
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java
new file mode 100644
index 0000000..337ac8b
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008077
+ * @summary Type annotations in a lazy constant need to be attributed
+ *   in the correct order.
+ * @author Werner Dietl
+ * @compile LazyConstantValue.java
+ */
+
+import java.lang.annotation.*;
+
+class ClassA {
+    Object o = ClassB.lcv;
+}
+
+class ClassB {
+    static final String[] lcv = new @TA String[0];
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA {}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariable.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariable.java
new file mode 100644
index 0000000..2c83bfe
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariable.java
@@ -0,0 +1,43 @@
+/*
+ * 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 8008077
+ * @summary Type annotations on a type variable, where the bound of
+ *   the type variable is also annotated, need to be processed correctly.
+ * @author Werner Dietl
+ * @compile TypeVariable.java
+ */
+
+import java.lang.annotation.*;
+
+class TypeVariable {
+    <TV extends  @TA Object> TV cast(TV p) {
+        return (@TA TV) p;
+    }
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA {}
+
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java
index 38a0395..3650d11 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java
@@ -21,6 +21,8 @@
  * questions.
  */
 
+import java.lang.annotation.*;
+
 /*
  * @test
  * @bug 6843077 8006775
@@ -29,7 +31,8 @@
  * @compile/fail VoidGenericMethod.java
  */
 class VoidGenericMethod {
-  public <T> @A void method() { }
+  public @A <T> void method() { }
 }
 
+@Target(ElementType.TYPE_USE)
 @interface A { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java
new file mode 100644
index 0000000..2a99420
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008077
+ * @summary new type annotation location: lambda expressions
+ * @compile Lambda.java
+ * @author Werner Dietl
+ */
+
+import java.lang.annotation.*;
+
+public class Lambda {
+
+    interface LambdaInt {
+        <S, T> void generic(S p1, T p2);
+    }
+
+    static class LambdaImpl implements LambdaInt {
+        <S, T> LambdaImpl(S p1, T p2) {}
+        public <S, T> void generic(S p1, T p2) {}
+    }
+
+    LambdaInt getMethodRefTA(LambdaImpl r) {
+        return r::<@TA Object, @TB Object>generic;
+    }
+
+    LambdaInt getConstructorRefTA() {
+        return LambdaImpl::<@TA Object, @TB Object>new;
+    }
+
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TB { }
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java
new file mode 100644
index 0000000..ddeeb94
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java
@@ -0,0 +1,262 @@
+/*
+ * 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 8008077
+ * @summary Test population of reference info for lambda expressions
+ * @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
+ * @run main Driver Lambda
+ * @author Werner Dietl
+ */
+
+import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
+
+public class Lambda {
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String returnMethodRef1() {
+        return
+                "class Lambda {" +
+                "  public String getName() { return \"Lambda!\"; }" +
+                "}" +
+
+                "class Test {" +
+                "  java.util.function.Function<Lambda, String> lambda() {" +
+                "    return @TA @TB Lambda::getName;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TC", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TD", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 }),
+        @TADescription(annotation = "TE", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 })
+    })
+    public String returnMethodRef2() {
+        return
+                "class Lambda<S, T> {" +
+                "  public String getName() { return \"Lambda!\"; }" +
+                "}" +
+
+                "class Test {" +
+                "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
+                "    return @TA Lambda<@TB @TC Integer, @TD @TE Float>::getName;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "CTA", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "CTB", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "CTC", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 })
+    })
+    public String returnMethodRef3() {
+        return
+                "class Lambda<S, T> {" +
+                "  public String getName() { return \"Lambda!\"; }" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTA {" +
+                "  String value();" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTB {" +
+                "  int age();" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTC {" +
+                "  String name();" +
+                "}" +
+
+                "class Test {" +
+                "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
+                "    return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::getName;" +
+                "  }" +
+                "}";
+    }
+
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String returnConstructorRef1() {
+        return
+                "class Lambda {" +
+                "  Lambda() { }" +
+                "}" +
+
+                "class Test {" +
+                "  Runnable lambda() {" +
+                "    return @TA @TB Lambda::new;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TC", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TD", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 }),
+        @TADescription(annotation = "TE", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 })
+    })
+    public String returnConstructorRef2() {
+        return
+                "class Lambda<S, T> {" +
+                "  Lambda() { }" +
+                "}" +
+
+                "class Test {" +
+                "  Runnable lambda() {" +
+                "    return @TA Lambda<@TB @TC Integer, @TD @TE Float>::new;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "CTA", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "CTB", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "CTC", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 })
+    })
+    public String returnConstructorRef3() {
+        return
+                "class Lambda<S, T> {" +
+                "  Lambda() { }" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTA {" +
+                "  String value();" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTB {" +
+                "  int age();" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTC {" +
+                "  String name();" +
+                "}" +
+
+                "class Test {" +
+                "  Runnable lambda() {" +
+                "    return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::new;" +
+                "  }" +
+                "}";
+    }
+
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 0),
+        @TADescription(annotation = "TB", type = METHOD_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 1)
+    })
+    public String returnMethodRefTA1() {
+        return
+                "interface Lambda {" +
+                "  <S, T> void generic(S p1, T p2);" +
+                "}" +
+
+                "class LambdaImpl implements Lambda {" +
+                "  public <S, T> void generic(S p1, T p2) {}" +
+                "}" +
+
+                "class Test {" +
+                "  Lambda lambda(LambdaImpl r) {" +
+                "    return r::<@TA Object, @TB Object>generic;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 0),
+        @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 1)
+    })
+    public String returnConstructorRefTA2() {
+        return
+                "interface Lambda {" +
+                "  <S, T> void generic(S p1, T p2);" +
+                "}" +
+
+                "class LambdaImpl implements Lambda {" +
+                "  <S, T> LambdaImpl(S p1, T p2) {}" +
+                "  public <S, T> void generic(S p1, T p2) {}" +
+                "}" +
+
+                "class Test {" +
+                "  Lambda lambda() {" +
+                "    return LambdaImpl::<@TA Object, @TB Object>new;" +
+                "  }" +
+                "}";
+    }
+
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java
index c23636c..eb23838 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java
@@ -93,6 +93,28 @@
     }
 
     @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1),
+        @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1)
+    })
+    public String methodParamAsArray2() {
+        return "void test(Object b, @TA @TB String [] a) { }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1),
+        @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1),
+        @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1)
+    })
+    public String methodParamAsArray3() {
+        return "void test(Object b, @TA @TB @TC String [] a) { }";
+    }
+
+    @TADescriptions({
         @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1),
         @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
                 genericLocation = { 0, 0 }, paramIndex = 1),
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java
index 84e5e01..a50a964 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java
@@ -31,118 +31,170 @@
  */
 public class TypeCasts {
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String returnObject() {
         return "Object returnObject() { return (@TA String)null; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TC", type = CAST,
-                genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String returnObjectArray() {
         return "Object returnObjectArray() { return (@TC String @TA [] @TB [])null; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String returnObjectGeneric() {
         return "Object returnObjectGeneric() { return (@TA List<@TB String>)null; }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String returnPrim() {
         return "Object returnPrim() { return (@TA int)0; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String returnPrimArray() {
         return "Object returnPrimArray() { return (@TB int @TA [])null; }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String initObject() {
         return "void initObject() { Object a =  (@TA String)null; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String initObjectArray() {
         return "void initObjectArray() { Object a = (@TB String @TA [])null; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String initObjectGeneric() {
         return "void initObjectGeneric() { Object a = (@TA List<@TB String>)null; }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String initPrim() {
         return "void initPrim() { Object a =  (@TA int)0; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String initPrimArray() {
         return "void initPrimArray() { Object a = (@TB int @TA [])null; }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String eqtestObject() {
         return "void eqtestObject() { if (null == (@TA String)null); }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String eqtestObjectArray() {
         return "void eqtestObjectArray() { if (null == (@TB String @TA [])null); }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String eqtestObjectGeneric() {
         return "void eqtestObjectGeneric() { if (null == (@TA List<@TB String >)null); }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     // compiler optimizes away compile time constants casts
     public String eqtestPrim() {
         return "void eqtestPrim(int a) { if (0 == (@TA int)a); }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String eqtestPrimArray() {
         return "void eqtestPrimArray() { if (null == (@TB int @TA [])null); }";
     }
 
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 0),
+        @TADescription(annotation = "TB", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1),
+        @TADescription(annotation = "TC", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1,
+                genericLocation = {3, 0})
+    })
+    public String intersection1() {
+        return "void intersection() { Object o = (@TA String & @TB Comparable<@TC String>) null; }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 0),
+        @TADescription(annotation = "TB", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1),
+        @TADescription(annotation = "TC", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1,
+                genericLocation = {3, 0}),
+        @TADescription(annotation = "TD", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 2),
+    })
+    public String intersection2() {
+        return "void intersection() { Object o = (@TA String & @TB Comparable<@TC String> & @TD CharSequence) null; }";
+    }
 }
diff --git a/langtools/test/tools/javac/api/8007344/Test.java b/langtools/test/tools/javac/api/8007344/Test.java
index 871faa7..23f63b7 100644
--- a/langtools/test/tools/javac/api/8007344/Test.java
+++ b/langtools/test/tools/javac/api/8007344/Test.java
@@ -41,6 +41,7 @@
 import javax.lang.model.element.TypeElement;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
 
 import com.sun.source.doctree.DocCommentTree;
 import com.sun.source.tree.*;
@@ -83,6 +84,7 @@
         File thisFile = new File(testSrc, getClass().getName() + ".java");
         JavacTool javac = JavacTool.create();
         StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
+        fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
         Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjects(thisFile);
         testAnnoProcessor(javac, fm, fos, out, EXPECT_DOC_COMMENTS);
         testTaskListener(javac, fm, fos, out, EXPECT_DOC_COMMENTS);
diff --git a/langtools/test/tools/javac/api/T6306137.java b/langtools/test/tools/javac/api/T6306137.java
index 8ccf577..b291114 100644
--- a/langtools/test/tools/javac/api/T6306137.java
+++ b/langtools/test/tools/javac/api/T6306137.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -25,6 +25,8 @@
  * @test
  * @bug     6306137
  * @summary JSR 199: encoding option doesn't affect standard file manager
+ * @compile -encoding utf-8 T6306137.java
+ * @run main T6306137
  * @author  Peter von der Ahé
  */
 
diff --git a/langtools/test/tools/javac/diags/examples/CantApplyDiamond1.java b/langtools/test/tools/javac/diags/examples/CantApplyDiamond1.java
index e06b59e..18ca0a6 100644
--- a/langtools/test/tools/javac/diags/examples/CantApplyDiamond1.java
+++ b/langtools/test/tools/javac/diags/examples/CantApplyDiamond1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 // key: compiler.err.prob.found.req
 // key: compiler.misc.cant.apply.diamond.1
-// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
+// key: compiler.misc.incompatible.eq.upper.bounds
 // key: compiler.misc.diamond
 
 class CantApplyDiamond1<X> {
diff --git a/langtools/test/tools/javac/diags/examples/InferredDoNotConformToEq.java b/langtools/test/tools/javac/diags/examples/InferredDoNotConformToEq.java
index 8038334..c5beec0 100644
--- a/langtools/test/tools/javac/diags/examples/InferredDoNotConformToEq.java
+++ b/langtools/test/tools/javac/diags/examples/InferredDoNotConformToEq.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 
 // key: compiler.err.cant.apply.symbol
 // key: compiler.misc.inferred.do.not.conform.to.eq.bounds
+// options: -source 7 -Xlint:-options
 
 import java.util.*;
 
diff --git a/langtools/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java b/langtools/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java
index 639510d..ca45b46 100644
--- a/langtools/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java
+++ b/langtools/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 
 // key: compiler.err.cant.apply.symbol
 // key: compiler.misc.inferred.do.not.conform.to.upper.bounds
+// options: -source 7 -Xlint:-options
 
 import java.util.*;
 
diff --git a/langtools/test/tools/javac/diags/examples/NotInProfile.java b/langtools/test/tools/javac/diags/examples/NotInProfile.java
new file mode 100644
index 0000000..7165651
--- /dev/null
+++ b/langtools/test/tools/javac/diags/examples/NotInProfile.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.err.not.in.profile
+// options: -profile compact1
+
+class NotInProfile {
+    Class<?> c = java.awt.Frame.class;
+}
diff --git a/langtools/test/tools/javac/diags/examples/WhereFreshTvar.java b/langtools/test/tools/javac/diags/examples/WhereFreshTvar.java
index 271ada3..92a8157 100644
--- a/langtools/test/tools/javac/diags/examples/WhereFreshTvar.java
+++ b/langtools/test/tools/javac/diags/examples/WhereFreshTvar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 // key: compiler.misc.where.fresh.typevar
 // key: compiler.misc.where.description.typevar
 // key: compiler.err.prob.found.req
-// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
+// key: compiler.misc.inconvertible.types
 // options: -XDdiags=where,simpleNames
 // run: simple
 
@@ -33,5 +33,5 @@
 class WhereFreshTvar {
     <T extends List<T>> T m() {}
 
-    { List<String> ls = m(); }
+    { Object o = (List<String>)m(); }
 }
diff --git a/langtools/test/tools/javac/generics/7015430/T7015430.out b/langtools/test/tools/javac/generics/7015430/T7015430.out
index 269d484..109bfe7 100644
--- a/langtools/test/tools/javac/generics/7015430/T7015430.out
+++ b/langtools/test/tools/javac/generics/7015430/T7015430.out
@@ -1,14 +1,14 @@
-T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
 T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
 T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
 T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:41:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
 T7015430.java:68:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
diff --git a/langtools/test/tools/javac/generics/7151802/T7151802.out b/langtools/test/tools/javac/generics/7151802/T7151802.out
index e2ff30b..94f8282 100644
--- a/langtools/test/tools/javac/generics/7151802/T7151802.out
+++ b/langtools/test/tools/javac/generics/7151802/T7151802.out
@@ -1,5 +1,5 @@
 T7151802.java:14:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get1, Z, T7151802.Foo, kindname.class, T7151802
-T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<Z>
+T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.Object>
 T7151802.java:22:30: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get3, T7151802.Foo<Z>, T7151802.Foo, kindname.class, T7151802
 T7151802.java:30:36: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get5, compiler.misc.no.args, compiler.misc.no.args, kindname.class, T7151802
 T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.String>
diff --git a/langtools/test/tools/javac/generics/diamond/neg/Neg06.out b/langtools/test/tools/javac/generics/diamond/neg/Neg06.out
index ca49a15..bf439f7 100644
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg06.out
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg06.out
@@ -1,2 +1,2 @@
-Neg06.java:16:37: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))
+Neg06.java:16:37: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
 1 error
diff --git a/langtools/test/tools/javac/generics/inference/6278587/T6278587Neg.java b/langtools/test/tools/javac/generics/inference/6278587/T6278587Neg.java
index c3d6f47..54ff0ad 100644
--- a/langtools/test/tools/javac/generics/inference/6278587/T6278587Neg.java
+++ b/langtools/test/tools/javac/generics/inference/6278587/T6278587Neg.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -23,10 +23,11 @@
 
 /*
  * @test
- * @bug     6278587
+ * @bug     6278587 8007464
  * @summary Inference broken for subtypes of subtypes of F-bounded types
  * @author  Peter von der Ah\u00e9
- * @compile/fail T6278587Neg.java
+ * @compile/fail -source 7 T6278587Neg.java
+ * @compile T6278587Neg.java
  */
 
 public abstract class T6278587Neg {
diff --git a/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out
index a3ec358..b1137d0 100644
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out
@@ -1,2 +1,2 @@
-T6638712d.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.String, java.lang.Integer)
+T6638712d.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.incompatible.eq.lower.bounds: U, java.lang.String, java.lang.Integer)
 1 error
diff --git a/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out
index e61aced..18adee2 100644
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out
@@ -1,2 +1,2 @@
-T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Boolean,java.lang.Object)
+T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Boolean,java.lang.Object)
 1 error
diff --git a/langtools/test/tools/javac/generics/inference/7154127/T7154127.java b/langtools/test/tools/javac/generics/inference/7154127/T7154127.java
index a37c76c..ea92c86 100644
--- a/langtools/test/tools/javac/generics/inference/7154127/T7154127.java
+++ b/langtools/test/tools/javac/generics/inference/7154127/T7154127.java
@@ -1,8 +1,9 @@
 /**
  * @test /nodynamiccopyright/
- * @bug 7154127
+ * @bug 7154127 8007464
  * @summary Inference cleanup: remove bound check analysis from visitors in Types.java
- * @compile/fail/ref=T7154127.out -XDrawDiagnostics T7154127.java
+ * @compile/fail/ref=T7154127.out -Xlint:-options -source 7 -XDrawDiagnostics T7154127.java
+ * @compile T7154127.java
  */
 class T7154127 {
 
diff --git a/langtools/test/tools/javac/generics/inference/7154127/T7154127.out b/langtools/test/tools/javac/generics/inference/7154127/T7154127.out
index 3586aba..e3d7798 100644
--- a/langtools/test/tools/javac/generics/inference/7154127/T7154127.out
+++ b/langtools/test/tools/javac/generics/inference/7154127/T7154127.out
@@ -1,2 +1,2 @@
-T7154127.java:19:49: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: Y, T7154127.D,T7154127.B<U>)
+T7154127.java:20:49: compiler.err.prob.found.req: (compiler.misc.incompatible.upper.bounds: Y, T7154127.B<U>,T7154127.D)
 1 error
diff --git a/langtools/test/tools/javac/generics/inference/7177306/T7177306a.out b/langtools/test/tools/javac/generics/inference/7177306/T7177306a.out
index 178a1d5..c455d24 100644
--- a/langtools/test/tools/javac/generics/inference/7177306/T7177306a.out
+++ b/langtools/test/tools/javac/generics/inference/7177306/T7177306a.out
@@ -1,4 +1,4 @@
-T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<E>
+T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<java.lang.Object>
 T7177306a.java:13:33: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, java.util.List<E>, java.util.List, kindname.class, T7177306a
 T7177306a.java:13:33: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7177306a, T7177306a<java.lang.Object>
 - compiler.err.warnings.and.werror
diff --git a/langtools/test/tools/javac/generics/inference/7177306/T7177306e.java b/langtools/test/tools/javac/generics/inference/7177306/T7177306e.java
index 4c8c7f2..4786e7b 100644
--- a/langtools/test/tools/javac/generics/inference/7177306/T7177306e.java
+++ b/langtools/test/tools/javac/generics/inference/7177306/T7177306e.java
@@ -1,8 +1,9 @@
 /**
  * @test /nodynamiccopyright/
- * @bug 7177306
+ * @bug 7177306 8007464
  * @summary Regression: unchecked method call does not erase return type
- * @compile/fail/ref=T7177306e.out -XDrawDiagnostics T7177306e.java
+ * @compile/fail/ref=T7177306e.out -source 7 -Xlint:-options -XDrawDiagnostics T7177306e.java
+ * @compile/fail T7177306e.java
  */
 
 import java.util.List;
diff --git a/langtools/test/tools/javac/generics/inference/7177306/T7177306e.out b/langtools/test/tools/javac/generics/inference/7177306/T7177306e.out
index 63e4cb6..323b786 100644
--- a/langtools/test/tools/javac/generics/inference/7177306/T7177306e.out
+++ b/langtools/test/tools/javac/generics/inference/7177306/T7177306e.out
@@ -1,2 +1,2 @@
-T7177306e.java:15:9: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.util.List<?>, java.util.List<compiler.misc.type.captureof: 1, ?>)
+T7177306e.java:16:9: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.util.List<?>, java.util.List<compiler.misc.type.captureof: 1, ?>)
 1 error
diff --git a/langtools/test/tools/javac/generics/odersky/BadTest4.java b/langtools/test/tools/javac/generics/odersky/BadTest4.java
index 20bdd10..d0ed639 100644
--- a/langtools/test/tools/javac/generics/odersky/BadTest4.java
+++ b/langtools/test/tools/javac/generics/odersky/BadTest4.java
@@ -23,11 +23,12 @@
 
 /*
  * @test
- * @ bug
+ * @bug 8007464
  * @summary Negative regression test from odersky
  * @author odersky
  *
- * @compile/fail  BadTest4.java
+ * @compile/fail -source 7 BadTest4.java
+ * @compile BadTest4.java
  */
 
 class BadTest4 {
diff --git a/langtools/test/tools/javac/lambda/TargetType14.out b/langtools/test/tools/javac/lambda/TargetType14.out
index 9de9a63..fc03187 100644
--- a/langtools/test/tools/javac/lambda/TargetType14.out
+++ b/langtools/test/tools/javac/lambda/TargetType14.out
@@ -1,2 +1,2 @@
-TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String)
+TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.lower.bounds: X, java.lang.Integer, java.lang.String)
 1 error
diff --git a/langtools/test/tools/javac/lambda/TargetType20.java b/langtools/test/tools/javac/lambda/TargetType20.java
index 06577a6..0678b01 100644
--- a/langtools/test/tools/javac/lambda/TargetType20.java
+++ b/langtools/test/tools/javac/lambda/TargetType20.java
@@ -1,10 +1,33 @@
 /*
- * @test /nodynamiccopyright/
+ * 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 8003280
  * @summary Add lambda tests
  *  complex case of lambda return type that depends on generic method
  *          inference variable
- * @compile/fail/ref=TargetType20.out -XDrawDiagnostics TargetType20.java
+ * @compile -XDrawDiagnostics TargetType20.java
  */
 import java.util.*;
 
diff --git a/langtools/test/tools/javac/lambda/TargetType20.out b/langtools/test/tools/javac/lambda/TargetType20.out
deleted file mode 100644
index 7bbbefe..0000000
--- a/langtools/test/tools/javac/lambda/TargetType20.out
+++ /dev/null
@@ -1,2 +0,0 @@
-TargetType20.java:19:10: compiler.err.cant.apply.symbol: kindname.method, call, TargetType20.SAM2<Z>,TargetType20.SAM2<Z>, @428,@459, kindname.class, TargetType20.Test, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
-1 error
diff --git a/langtools/test/tools/javac/lambda/TargetType28.out b/langtools/test/tools/javac/lambda/TargetType28.out
index 6b63723..8a9ab1f 100644
--- a/langtools/test/tools/javac/lambda/TargetType28.out
+++ b/langtools/test/tools/javac/lambda/TargetType28.out
@@ -1,3 +1,2 @@
-TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.String)
-TargetType28.java:21:33: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.Integer)
-2 errors
+TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String,X, java.lang.Object,java.lang.Number)
+1 error
diff --git a/langtools/test/tools/javac/lambda/TargetType50.java b/langtools/test/tools/javac/lambda/TargetType50.java
index ab9d3a4..d2942b9 100644
--- a/langtools/test/tools/javac/lambda/TargetType50.java
+++ b/langtools/test/tools/javac/lambda/TargetType50.java
@@ -1,9 +1,32 @@
 /*
- * @test /nodynamiccopyright/
+ * 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 8003280
  * @summary Add lambda tests
  *  bad stuck check for method reference leads to javac crash
- * @compile/fail/ref=TargetType50.out -XDrawDiagnostics TargetType50.java
+ * @compile TargetType50.java
  */
 import java.util.*;
 
@@ -17,7 +40,7 @@
         static <Z> Sink<Z> make() { return null; }
     }
 
-    <Y, S extends Sink<Y>> List<Y> m(Factory<S> factory) {  }
+    <Y, S extends Sink<Y>> List<Y> m(Factory<S> factory) { return null; }
 
     void test() {
         List<?> l1 = m(Sink::new);
diff --git a/langtools/test/tools/javac/lambda/TargetType50.out b/langtools/test/tools/javac/lambda/TargetType50.out
deleted file mode 100644
index 02736d4..0000000
--- a/langtools/test/tools/javac/lambda/TargetType50.out
+++ /dev/null
@@ -1,3 +0,0 @@
-TargetType50.java:25:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>)
-TargetType50.java:26:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>)
-2 errors
diff --git a/langtools/test/tools/javac/lambda/TargetType51.java b/langtools/test/tools/javac/lambda/TargetType51.java
index a26a9af..7e7a129 100644
--- a/langtools/test/tools/javac/lambda/TargetType51.java
+++ b/langtools/test/tools/javac/lambda/TargetType51.java
@@ -23,7 +23,9 @@
 
 /*
  * @test
- * @summary smoke test for combinator-like stuck analysis
+ * @bug 8005244
+ * @summary Implement overload resolution as per latest spec EDR
+ *          smoke test for combinator-like stuck analysis
  * @author  Maurizio Cimadamore
  * @compile TargetType51.java
  */
diff --git a/langtools/test/tools/javac/lambda/TargetType52.java b/langtools/test/tools/javac/lambda/TargetType52.java
index 752ff40..f06c3e9 100644
--- a/langtools/test/tools/javac/lambda/TargetType52.java
+++ b/langtools/test/tools/javac/lambda/TargetType52.java
@@ -1,6 +1,8 @@
 /*
  * @test /nodynamiccopyright/
- * @summary uncatched sam conversion failure exception lead to javac crash
+ * @bug 8005244
+ * @summary Implement overload resolution as per latest spec EDR
+ *          uncatched sam conversion failure exception lead to javac crash
  * @compile/fail/ref=TargetType52.out -XDrawDiagnostics TargetType52.java
  */
 class TargetType52 {
diff --git a/langtools/test/tools/javac/lambda/TargetType52.out b/langtools/test/tools/javac/lambda/TargetType52.out
index 962bbb7..ccfb466 100644
--- a/langtools/test/tools/javac/lambda/TargetType52.out
+++ b/langtools/test/tools/javac/lambda/TargetType52.out
@@ -1,2 +1,2 @@
-TargetType52.java:15:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType52.FI<? extends java.lang.CharSequence,? extends java.util.ArrayList<? extends java.lang.CharSequence>>, @444, kindname.class, TargetType52, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: TargetType52.FI<java.lang.CharSequence,java.util.ArrayList<? extends java.lang.CharSequence>>))
+TargetType52.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType52.FI<? extends java.lang.CharSequence,? extends java.util.ArrayList<? extends java.lang.CharSequence>>, @525, kindname.class, TargetType52, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: TargetType52.FI<java.lang.CharSequence,java.util.ArrayList<? extends java.lang.CharSequence>>))
 1 error
diff --git a/langtools/test/tools/javac/lambda/TargetType53.java b/langtools/test/tools/javac/lambda/TargetType53.java
new file mode 100644
index 0000000..26c9887
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType53.java
@@ -0,0 +1,47 @@
+/*
+ * 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 8007464
+ * @summary Add graph inference support
+ *          smoke test for graph inference
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType53.java
+ */
+import java.util.*;
+import java.util.stream.*;
+import java.util.function.*;
+
+class TargetType53 {
+
+    <P> List<List<P>> perm(List<P> l) { return null; }
+
+    void g(List<List<UnaryOperator<IntStream>>> l) { }
+
+    void test() {
+        List<List<UnaryOperator<IntStream>>> l =
+            perm(Arrays.asList(s -> s.sorted()));
+        g(perm(Arrays.asList(s -> s.sorted())));
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/TargetType54.java b/langtools/test/tools/javac/lambda/TargetType54.java
new file mode 100644
index 0000000..0d73270
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType54.java
@@ -0,0 +1,45 @@
+/*
+ * 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 8007464
+ * @summary Add graph inference support
+ *          smoke test for graph inference
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType54.java
+ */
+import java.util.stream.*;
+import java.util.*;
+import static java.util.stream.Collectors.*;
+
+class TargetType54 {
+    void test(Stream<Integer> si) {
+        List<Integer> l1 = si.collect(toList());
+        List<Integer> l2 = si.collect(toCollection(ArrayList::new));
+        m(si.collect(toList()));
+        m(si.collect(toCollection(ArrayList::new)));
+    }
+
+    void m(List<Integer> l) { }
+}
diff --git a/langtools/test/tools/javac/lambda/TargetType55.java b/langtools/test/tools/javac/lambda/TargetType55.java
new file mode 100644
index 0000000..3484a74
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType55.java
@@ -0,0 +1,42 @@
+/*
+ * 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 8007464
+ * @summary Add graph inference
+ *          support smoke test for graph inference
+ * @compile TargetType55.java
+ */
+import java.util.function.*;
+
+class TargetType55  {
+
+    <R> void m(Function<Integer, R> collector) { }
+
+    <T, D> Function<T, Integer> g(D d, BinaryOperator<D> reducer) { return null; }
+
+    public void test() {
+        m(g((Integer)null, (x,y)->1));
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/TargetType56.java b/langtools/test/tools/javac/lambda/TargetType56.java
new file mode 100644
index 0000000..c292b2d
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType56.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          smoke test for graph inference
+ * @compile TargetType56.java
+ */
+class TargetType56 {
+    <Z> Z m(Z z) { return null; }
+
+    void test() {
+        double d1 = m(1);
+        double d2 = m((Integer)null);
+        double d3 = m(m(1));
+        double d4 = m(m((Integer)null));
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/TargetType57.java b/langtools/test/tools/javac/lambda/TargetType57.java
new file mode 100644
index 0000000..23f7a13
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType57.java
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          more smoke tests for graph inference
+ * @compile/fail/ref=TargetType57.out -XDrawDiagnostics TargetType57.java
+ */
+import java.util.*;
+import java.util.function.*;
+
+class TargetType57 {
+
+    void test(List<Integer> list) {
+        m(list, s -> s.intValue(), s -> s.nonExistentMethod());
+    }
+
+    <U, R, S_IN, S_OUT> R m(List<S_IN> list,
+                        Function<S_IN, S_OUT> f1,
+                        Function<S_OUT, R> f2) { return null; }
+}
diff --git a/langtools/test/tools/javac/lambda/TargetType57.out b/langtools/test/tools/javac/lambda/TargetType57.out
new file mode 100644
index 0000000..8475e6b
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType57.out
@@ -0,0 +1,2 @@
+TargetType57.java:14:42: compiler.err.cant.resolve.location.args: kindname.method, nonExistentMethod, , , (compiler.misc.location.1: kindname.variable, s, java.lang.Integer)
+1 error
diff --git a/langtools/test/tools/javac/lambda/TargetType58.java b/langtools/test/tools/javac/lambda/TargetType58.java
new file mode 100644
index 0000000..4ba44a9
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType58.java
@@ -0,0 +1,46 @@
+/*
+ * 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 8007464
+ * @summary Add graph inference support
+ *          more smoke tests for graph inference
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType58.java
+ */
+import java.util.*;
+import java.util.function.*;
+import java.util.stream.*;
+
+class TargetType58 {
+
+    void test(List<Integer> li) {
+        g(li, s -> s.substream(200), Collections.emptyList());
+    }
+
+    <T, U, S_OUT extends Stream<U>,
+            I extends Iterable<U>> Collection<U> g(Collection<T> coll, Function<Stream<T>, S_OUT> f, I i) {
+        return null;
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/TargetType59.java b/langtools/test/tools/javac/lambda/TargetType59.java
new file mode 100644
index 0000000..64fc92e
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType59.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          more smoke tests for graph inference
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType59.java
+ */
+import java.util.*;
+import java.util.function.*;
+import java.util.stream.*;
+
+class TargetType59 {
+
+    <T, R> Collector<T, R> m(Supplier<? extends R> supplier, BiConsumer<R, T> accumulator) {
+        return null;
+    }
+
+    <T, C extends Collection<T>> Collector<T,C> test1(Supplier<C> collectionFactory) {
+        return m(collectionFactory, Collection::add);
+    }
+
+    Collector<String, StringBuilder> test2(Supplier<StringBuilder> sb) {
+        return m(sb, StringBuilder::append);
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/TargetType61.java b/langtools/test/tools/javac/lambda/TargetType61.java
new file mode 100644
index 0000000..1eae34e
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType61.java
@@ -0,0 +1,47 @@
+/*
+ * 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 8007464
+ * @summary Add graph inference support
+ *          check that new wildcards inference strategy doesn't run into 7190296
+ * @compile TargetType61.java
+ */
+class TargetType61 {
+
+    interface Stream<T> {
+        void forEach(Sink<? super T> sink);
+    }
+
+    interface Sink<T> {
+        void put(T t);
+    }
+
+    public boolean add(CharSequence s) { return false; }
+
+    public void addAll(Stream<? extends CharSequence> stream) {
+        stream.forEach(this::add);
+        stream.forEach(e -> { add(e); });
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/TargetType62.java b/langtools/test/tools/javac/lambda/TargetType62.java
new file mode 100644
index 0000000..49436b6
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType62.java
@@ -0,0 +1,46 @@
+/*
+ * 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 8007464
+ * @summary Add graph inference support
+ *          check that new wildcards inference strategy doesn't run into 7190296
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType62.java
+ */
+import java.util.*;
+import java.util.function.*;
+import java.util.stream.*;
+
+class TargetType61 {
+
+    Collector test(Function<Integer, Integer> classifier) {
+        return g(classifier, TreeMap::new, m(HashSet::new));
+    }
+
+    <R> Collector<Integer, R> m(Supplier<R> s) { return null; }
+
+    <T, K, D, M extends Map<K, D>>
+            Collector<T, M> g(Function<T, K> classifier, Supplier<M> mapFactory, Collector<T, D> downstream) { return null; }
+}
diff --git a/langtools/test/tools/javac/lib/DPrinter.java b/langtools/test/tools/javac/lib/DPrinter.java
index 45d1296..0e71f57 100644
--- a/langtools/test/tools/javac/lib/DPrinter.java
+++ b/langtools/test/tools/javac/lib/DPrinter.java
@@ -1006,6 +1006,7 @@
         public Void visitUndetVar(UndetVar type, Void ignore) {
             for (UndetVar.InferenceBound ib: UndetVar.InferenceBound.values())
                 printList("bounds." + ib, type.getBounds(ib));
+            printInt("declaredCount", type.declaredCount);
             printType("inst", type.inst, Details.SUMMARY);
             return visitDelegatedType(type);
         }
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/ElementRepAnnoTester.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/ElementRepAnnoTester.java
new file mode 100644
index 0000000..3de12e6
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/ElementRepAnnoTester.java
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.MirroredTypeException;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+
+public class ElementRepAnnoTester extends JavacTestingAbstractProcessor {
+    // All methods to test.
+    final EnumSet<TestMethod> ALL_TEST_METHODS = EnumSet.allOf(TestMethod.class);
+    int count = 0;
+    int error = 0;
+
+    public boolean process(Set<? extends TypeElement> annotations,
+            RoundEnvironment roundEnv) {
+        if (!roundEnv.processingOver()) {
+            List<String> superClass = Arrays.asList("A", "B", "C", "D", "E",
+                    "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P");
+            // Go through all test classes
+            for (Element element : roundEnv.getRootElements()) {
+                // For now, no testing super classes (TODO)
+                if (element.getKind() == ElementKind.CLASS
+                        && !superClass.contains(element.getSimpleName().toString())) {
+                    // Compare expected and actual values from methods.
+                    checkAnnoValues(element, ALL_TEST_METHODS);
+                    // Now, look for enclosed elements in test classes.
+                    for (Element elements : element.getEnclosedElements()) {
+                        // Look for Methods annotations.
+                        if (elements.getKind() == ElementKind.METHOD
+                                && elements.getSimpleName().toString().equals("testMethod")) {
+                            checkAnnoValues(elements, ALL_TEST_METHODS);
+                        }
+                        // Look for Field annotations.
+                        if (elements.getKind() == ElementKind.FIELD
+                                && elements.getSimpleName().toString().equals("testField")) {
+                            checkAnnoValues(elements, ALL_TEST_METHODS);
+                        }
+                    }
+                }
+            }
+
+            if (error != 0) {
+                System.out.println("Total tests : " + count);
+                System.out.println("Total test failures : " + error);
+                throw new RuntimeException();
+            } else {
+                System.out.println("ALL TESTS PASSED. " + count);
+            }
+        }
+        return true;
+    }
+
+    enum TestMethod {
+        getAnnotation,
+        getAnnotationsByType,
+        getAllAnnotationMirrors,
+        getAnnotationMirrors
+    }
+
+    protected void checkAnnoValues(Element element, EnumSet<TestMethod> testMethods) {
+        boolean baseAnnoPresent = false;
+        boolean conAnnoPresent = false;
+        ExpectedBase eb = null;
+        ExpectedContainer ec = null;
+        // Getting the expected values to compare with.
+        eb = element.getAnnotation(ExpectedBase.class);
+        ec = element.getAnnotation(ExpectedContainer.class);
+
+        if (eb == null) {
+            System.out.println("Did not find ExpectedBase Annotation in  "
+                    + element.getSimpleName().toString() + ", Test will exit");
+            throw new RuntimeException();
+        }
+        if (ec == null) {
+            System.out.println("Did not find ExpectedContainer Annotation in "
+                    + element.getSimpleName().toString() + " Test will exit");
+            throw new RuntimeException();
+        }
+        // Look if all test cases have ExpectedBase and ExpectedContainer values().
+        TypeMirror valueBase = null;
+        TypeMirror valueCon = null;
+
+        try {
+            eb.value();
+        } catch (MirroredTypeException mte) {
+            valueBase = mte.getTypeMirror();
+        }
+
+        try {
+            ec.value();
+        } catch (MirroredTypeException mte1) {
+            valueCon = mte1.getTypeMirror();
+        }
+
+        String expectedBaseAnno = valueBase.toString();
+        String expectedConAnno = valueCon.toString();
+
+        if (!expectedBaseAnno.equals("java.lang.annotation.Annotation")) {
+            baseAnnoPresent = true;
+        }
+        if (!expectedConAnno.equalsIgnoreCase("java.lang.annotation.Annotation")) {
+            conAnnoPresent = true;
+        }
+
+        // Look into TestMethod and compare method's output with expected values.
+        for (TestMethod testMethod : testMethods) {
+            boolean isBasePass = true;
+            boolean isConPass = true;
+
+            switch (testMethod) {
+                case getAnnotation:
+                    if (baseAnnoPresent) {
+                        count++;
+                        Annotation actualAnno = getAnnotationBase(element);
+                        String expectedAnno = eb.getAnnotation();
+                        isBasePass = compareAnnotation(actualAnno, expectedAnno);
+                    }
+                    if (conAnnoPresent) {
+                        count++;
+                        Annotation actualAnno = getAnnotationContainer(element);
+                        String expectedAnno = ec.getAnnotation();
+                        isConPass = compareAnnotation(actualAnno, expectedAnno);
+                    }
+                    if (!isBasePass || !isConPass) {
+                        System.out.println("FAIL in " + element.getSimpleName()
+                                + "-" + element.getKind()
+                                + " method: getAnnotation(class <T>)");
+                        error++;
+                    }
+                    break;
+
+                case getAnnotationMirrors:
+                    if (baseAnnoPresent) {
+                        count++;
+                        List<? extends AnnotationMirror> actualDeclAnnos =
+                                element.getAnnotationMirrors();
+                        String[] expectedAnnos = eb.getAnnotationMirrors();
+                        isBasePass = compareArrVals(actualDeclAnnos, expectedAnnos);
+                    }
+                    if (conAnnoPresent) {
+                        isConPass = true;
+                    }
+                    if (!isBasePass || !isConPass) {
+                        System.out.println("FAIL in " + element.getSimpleName()
+                                + "-" + element.getKind()
+                                + " method: getAnnotationMirrors()");
+                        error++;
+                    }
+                    break;
+
+                case getAnnotationsByType:
+                    if (baseAnnoPresent) {
+                        count++;
+                        Annotation[] actualAnnosArgs = getAnnotationsBase(element);
+                        String[] expectedAnnos = eb.getAnnotationsByType();
+                        isBasePass = compareArrVals(actualAnnosArgs, expectedAnnos);
+                    }
+                    if (conAnnoPresent) {
+                        count++;
+                        Annotation[] actualAnnosArgs = getAnnotationsContainer(element);
+                        String[] expectedAnnos = ec.getAnnotationsByType();
+                        isConPass = compareArrVals(actualAnnosArgs, expectedAnnos);
+                    }
+                    if (!isBasePass || !isConPass) {
+                        System.out.println("FAIL in " + element.getSimpleName()
+                                + "-" + element.getKind()
+                                + " method: getAnnotationsByType(class <T>)");
+                        error++;
+                    }
+                    break;
+
+                case getAllAnnotationMirrors:
+                    if (baseAnnoPresent) {
+                        count++;
+                        Elements elements = processingEnv.getElementUtils();
+                        List<? extends AnnotationMirror> actualAnnosMirrors =
+                                elements.getAllAnnotationMirrors(element);
+                        String[] expectedAnnos = eb.getAllAnnotationMirrors();
+                        isBasePass = compareArrVals(actualAnnosMirrors, expectedAnnos);
+                    }
+                    if (conAnnoPresent) {
+                        isConPass = true;
+                    }
+                    if (!isBasePass || !isConPass) {
+                        System.out.println("FAIL in " + element.getSimpleName()
+                                + "-" + element.getKind()
+                                + " method: getAllAnnotationMirrors(e)");
+                        error++;
+                    }
+                    break;
+            }
+        }
+    }
+    // Sort tests to be run with different anno processors.
+    final List<String> singularAnno = Arrays.asList(
+            "SingularBasicTest"
+            );
+    final List<String> singularInheritedAnno = Arrays.asList(
+            "SingularInheritedATest"
+            );
+    final List<String> repeatableAnno = Arrays.asList(
+            "RepeatableBasicTest",
+            "MixRepeatableAndOfficialContainerBasicTest",
+            "OfficialContainerBasicTest",
+            "RepeatableOfficialContainerBasicTest"
+            );
+    final List<String> repeatableInheritedAnno = Arrays.asList(
+            "RepeatableInheritedTest",
+            "RepeatableOverrideATest",
+            "RepeatableOverrideBTest",
+            "OfficialContainerInheritedTest",
+            "MixRepeatableAndOfficialContainerInheritedA1Test",
+            "MixRepeatableAndOfficialContainerInheritedB1Test",
+            "MixRepeatableAndOfficialContainerInheritedA2Test",
+            "MixRepeatableAndOfficialContainerInheritedB2Test"
+            );
+    final List<String> repeatableContainerInheritedAnno = Arrays.asList(
+            "RepeatableOfficialContainerInheritedTest"
+            );
+    final List<String> unofficialAnno = Arrays.asList(
+            "UnofficialContainerBasicTest",
+            "MixSingularAndUnofficialContainerBasicTest"
+            );
+    final List<String> unofficialInheritedAnno = Arrays.asList(
+            "UnofficialContainerInheritedTest",
+            "SingularInheritedBTest",
+            "MixSingularAndUnofficialContainerInheritedA1Test",
+            "MixSingularAndUnofficialContainerInheritedB1Test",
+            "MixSingularAndUnofficialContainerInheritedA2Test",
+            "MixSingularAndUnofficialContainerInheritedB2Test"
+            );
+    // Respective container annotation for the different test cases to test.
+    final List<String> repeatableAnnoContainer = repeatableAnno;
+    final List<String> repeatableInheritedAnnoContainer = repeatableInheritedAnno;
+    final List<String> repeatableContainerInheritedAnnoContainer =
+            repeatableContainerInheritedAnno;
+    final List<String> unofficialAnnoContainer = unofficialAnno;
+    final List<String> unofficialInheritedAnnoContainer = unofficialInheritedAnno;
+
+    // Variables to verify if all test cases have been run.
+    private Annotation specialAnno = new Annotation() {
+       @Override
+        public Class annotationType() {
+            return null;
+        }
+    };
+    private Annotation[] specialAnnoArray = new Annotation[1];
+    private List<AnnotationMirror> specialAnnoMirrors =
+            new java.util.ArrayList<AnnotationMirror>(2);
+
+    private Annotation getAnnotationBase(Element e) {
+        Annotation actualAnno = specialAnno;
+
+        if (singularAnno.contains(
+                e.getEnclosingElement().toString())
+                || singularAnno.contains(
+                e.getSimpleName().toString())
+                || unofficialAnno.contains(
+                e.getEnclosingElement().toString())
+                || unofficialAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(Foo.class);
+        }
+        if (singularInheritedAnno.contains(
+                e.getEnclosingElement().toString())
+                || singularInheritedAnno.contains(
+                e.getSimpleName().toString())
+                || unofficialInheritedAnno.contains(
+                e.getEnclosingElement().toString())
+                || unofficialInheritedAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(FooInherited.class);
+        }
+        if (repeatableAnno.contains(
+                e.getEnclosingElement().toString())
+                || repeatableAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(Bar.class);
+        }
+        if (repeatableInheritedAnno.contains(
+                e.getEnclosingElement().toString())
+                || repeatableInheritedAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(BarInherited.class);
+        }
+        if (repeatableContainerInheritedAnno.contains(
+                e.getEnclosingElement().toString())
+                || repeatableContainerInheritedAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(BarInheritedContainer.class);
+        }
+        return actualAnno;
+    }
+
+    private Annotation getAnnotationContainer(Element e) {
+        Annotation actualAnno = specialAnno;
+
+        if (repeatableAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || repeatableAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(BarContainer.class);
+        }
+        if (repeatableInheritedAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || repeatableInheritedAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(BarInheritedContainer.class);
+        }
+        if (repeatableContainerInheritedAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || repeatableContainerInheritedAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(BarInheritedContainerContainer.class);
+        }
+        if (unofficialAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || unofficialAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(UnofficialContainer.class);
+        }
+        if (unofficialInheritedAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || unofficialInheritedAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnno = e.getAnnotation(UnofficialInheritedContainer.class);
+        }
+        return actualAnno;
+    }
+
+    private Annotation[] getAnnotationsBase(Element e) {
+        Annotation[] actualAnnosArgs = specialAnnoArray;
+
+        if (singularAnno.contains(
+                e.getEnclosingElement().toString())
+                || singularAnno.contains(
+                e.getSimpleName().toString())
+                || unofficialAnno.contains(
+                e.getEnclosingElement().toString())
+                || unofficialAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(Foo.class);
+        }
+        if (singularInheritedAnno.contains(
+                e.getEnclosingElement().toString())
+                || singularInheritedAnno.contains(
+                e.getSimpleName().toString())
+                || unofficialInheritedAnno.contains(
+                e.getEnclosingElement().toString())
+                || unofficialInheritedAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(FooInherited.class);
+        }
+        if (repeatableAnno.contains(
+                e.getEnclosingElement().toString())
+                || repeatableAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(Bar.class);
+        }
+        if (repeatableInheritedAnno.contains(
+                e.getEnclosingElement().toString())
+                || repeatableInheritedAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(BarInherited.class);
+        }
+        if (repeatableContainerInheritedAnno.contains(
+                e.getEnclosingElement().toString())
+                || repeatableContainerInheritedAnno.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(BarInheritedContainer.class);
+        }
+        return actualAnnosArgs;
+    }
+
+    private Annotation[] getAnnotationsContainer(Element e) {
+        Annotation[] actualAnnosArgs = specialAnnoArray;
+
+        if (repeatableAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || repeatableAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(BarContainer.class);
+        }
+        if (repeatableInheritedAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || repeatableInheritedAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(BarInheritedContainer.class);
+        }
+        if (repeatableContainerInheritedAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || repeatableContainerInheritedAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(BarInheritedContainerContainer.class);
+        }
+        if (unofficialAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || unofficialAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(UnofficialContainer.class);
+        }
+        if (unofficialInheritedAnnoContainer.contains(
+                e.getEnclosingElement().toString())
+                || unofficialInheritedAnnoContainer.contains(
+                e.getSimpleName().toString())) {
+            actualAnnosArgs = e.getAnnotationsByType(UnofficialInheritedContainer.class);
+        }
+        return actualAnnosArgs;
+    }
+
+    // Array comparison: Length should be same and all expected values
+    // should be present in actualAnnos[].
+    private boolean compareArrVals(Annotation[] actualAnnos, String[] expectedAnnos) {
+        // Look if test case was run.
+        if (actualAnnos == specialAnnoArray) {
+            return false; // no testcase matches
+        }
+        if (actualAnnos.length != expectedAnnos.length) {
+            System.out.println("Length not same. "
+                    + " actualAnnos length = " + actualAnnos.length
+                    + " expectedAnnos length = " + expectedAnnos.length);
+            printArrContents(actualAnnos);
+            printArrContents(expectedAnnos);
+            return false;
+        } else {
+            int i = 0;
+            String[] actualArr = new String[actualAnnos.length];
+            for (Annotation a : actualAnnos) {
+                actualArr[i++] = a.toString();
+            }
+            List<String> actualList = Arrays.asList(actualArr);
+            List<String> expectedList = Arrays.asList(expectedAnnos);
+
+            if (!actualList.containsAll(expectedList)) {
+                System.out.println("Array values are not same");
+                printArrContents(actualAnnos);
+                printArrContents(expectedAnnos);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // Array comparison: Length should be same and all expected values
+    // should be present in actualAnnos List<?>.
+    private boolean compareArrVals(List<? extends AnnotationMirror> actualAnnos,
+            String[] expectedAnnos) {
+        // Look if test case was run.
+        if (actualAnnos == specialAnnoMirrors) {
+            return false; //no testcase run
+        }
+        if (actualAnnos.size() != expectedAnnos.length) {
+            System.out.println("Length not same. "
+                    + " actualAnnos length = " + actualAnnos.size()
+                    + " expectedAnnos length = " + expectedAnnos.length);
+            printArrContents(actualAnnos);
+            printArrContents(expectedAnnos);
+            return false;
+        } else {
+            int i = 0;
+            String[] actualArr = new String[actualAnnos.size()];
+            String annoTypeName = "";
+            for (AnnotationMirror annotationMirror : actualAnnos) {
+                if (annotationMirror.getAnnotationType().toString().contains("Expected")) {
+                    annoTypeName = annotationMirror.getAnnotationType().toString();
+                } else {
+                     annoTypeName = annotationMirror.toString();
+                }
+                actualArr[i++] = annoTypeName;
+            }
+            List<String> actualList = Arrays.asList(actualArr);
+            List<String> expectedList = Arrays.asList(expectedAnnos);
+
+            if (!actualList.containsAll(expectedList)) {
+                System.out.println("Array values are not same");
+                printArrContents(actualAnnos);
+                printArrContents(expectedAnnos);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void printArrContents(Annotation[] actualAnnos) {
+        for (Annotation a : actualAnnos) {
+            System.out.println("actualAnnos values = " + a);
+        }
+    }
+
+    private void printArrContents(String[] expectedAnnos) {
+        for (String s : expectedAnnos) {
+            System.out.println("expectedAnnos values =  " + s);
+        }
+    }
+
+    private void printArrContents(List<? extends AnnotationMirror> actualAnnos) {
+        for (AnnotationMirror annotationMirror : actualAnnos) {
+            System.out.println("actualAnnos values = " + annotationMirror);
+        }
+    }
+
+    private boolean compareAnnotation(Annotation actualAnno, String expectedAnno) {
+        //String actualAnnoName = "";
+        boolean isSame = true;
+        // Look if test case was run.
+        if (actualAnno == specialAnno) {
+            return false; //no testcase run
+        }
+        if (actualAnno != null) {
+            if (!actualAnno.toString().equalsIgnoreCase(expectedAnno)) {
+                System.out.println("Anno did not match. "
+                        + " expectedAnno = " + expectedAnno
+                        + " actualAnno = " + actualAnno);
+                isSame = false;
+            } else {
+                isSame = true;
+            }
+        } else {
+            if (expectedAnno.compareToIgnoreCase("null") == 0) {
+                isSame = true;
+            } else {
+                System.out.println("Actual anno is null");
+                isSame = false;
+            }
+        }
+        return isSame;
+    }
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerBasicTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerBasicTest.java
new file mode 100644
index 0000000..c000729
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerBasicTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixRepeatableAndOfficialContainerBasicTest.java
+ */
+
+@ExpectedBase(
+        value = Bar.class,
+        getAnnotation = "@Bar(value=0)",
+        getAnnotationsByType = {
+            "@Bar(value=0)",
+            "@Bar(value=1)",
+            "@Bar(value=2)"
+        },
+        getAllAnnotationMirrors = {
+            "@Bar(0)",
+            "@BarContainer({@Bar(1), @Bar(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@Bar(0)",
+            "@BarContainer({@Bar(1), @Bar(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarContainer.class,
+        getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+        getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+@Bar(value = 0)
+@BarContainer(value = {@Bar(value = 1), @Bar(value = 2)})
+class MixRepeatableAndOfficialContainerBasicTest {
+
+    @ExpectedBase(
+            value = Bar.class,
+            getAnnotation = "@Bar(value=0)",
+            getAnnotationsByType = {
+                "@Bar(value=0)",
+                "@Bar(value=1)",
+                "@Bar(value=2)"
+            },
+            getAllAnnotationMirrors = {
+                "@Bar(0)",
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@Bar(0)",
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = BarContainer.class,
+            getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+            getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+    @Bar(value = 0)
+    @BarContainer(value = {@Bar(value = 1), @Bar(value = 2)})
+    int testField = 0;
+
+    @ExpectedBase(
+            value = Bar.class,
+            getAnnotation = "@Bar(value=0)",
+            getAnnotationsByType = {
+                "@Bar(value=0)",
+                "@Bar(value=1)",
+                "@Bar(value=2)"
+            },
+            getAllAnnotationMirrors = {
+                "@Bar(0)",
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@Bar(0)",
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = BarContainer.class,
+            getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+            getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+    @Bar(value = 0)
+    @BarContainer(value = {@Bar(value = 1), @Bar(value = 2)})
+    void testMethod() {}
+   }
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java
new file mode 100644
index 0000000..222cf01
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA1Test.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/*
+ * @ignore
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixRepeatableAndOfficialContainerInheritedA1Test.java
+ */
+
+@BarInherited(value = 0)
+class E {}
+
+@ExpectedBase(
+        value = BarInherited.class,
+        getAnnotation = "@BarInherited(value=0)",
+        getAnnotationsByType = {
+            "@BarInherited(value=1)",
+            "@BarInherited(value=2)"
+        },
+        getAllAnnotationMirrors = {
+            "@BarInherited(0)",
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainer.class,
+        getAnnotation = "@BarInheritedContainer("
+        + "value=[@BarInherited(value=1), @BarInherited(value=2)])",
+        getAnnotationsByType = {"@BarInheritedContainer("
+                + "value=[@BarInherited(value=1), @BarInherited(value=2)])"})
+@BarInheritedContainer(value = {@BarInherited(value = 1), @BarInherited(value = 2)})
+class MixRepeatableAndOfficialContainerInheritedA1Test extends E {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA2Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA2Test.java
new file mode 100644
index 0000000..5aa833e
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedA2Test.java
@@ -0,0 +1,67 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixRepeatableAndOfficialContainerInheritedA2Test.java
+ */
+
+@BarInherited(value = 0)
+class N {}
+
+@ExpectedBase(
+        value = BarInherited.class,
+        getAnnotation = "@BarInherited(value=3)",
+        getAnnotationsByType = {
+            "@BarInherited(value=1)",
+            "@BarInherited(value=2)",
+            "@BarInherited(value=3)"
+        },
+        getAllAnnotationMirrors = {
+            "@BarInherited(3)",
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarInherited(3)",
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainer.class,
+        getAnnotation = "@BarInheritedContainer("
+        + "value=[@BarInherited(value=1), @BarInherited(value=2)])",
+        getAnnotationsByType = {"@BarInheritedContainer("
+                + "value=[@BarInherited(value=1), @BarInherited(value=2)])"})
+@BarInheritedContainer(value = {@BarInherited(value = 1), @BarInherited(value = 2)})
+@BarInherited(value = 3)
+class MixRepeatableAndOfficialContainerInheritedA2Test extends N {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java
new file mode 100644
index 0000000..333b960
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB1Test.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/*
+ * @ignore
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixRepeatableAndOfficialContainerInheritedB1Test.java
+ */
+
+@BarInheritedContainer(value = {@BarInherited(value = 1), @BarInherited(value = 2)})
+class M {}
+
+@ExpectedBase(
+        value = BarInherited.class,
+        getAnnotation = "@BarInherited(value=0)",
+        getAnnotationsByType = {"@BarInherited(value=0)"},
+        getAllAnnotationMirrors = {
+            "@BarInherited(0)",
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarInherited(0)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainer.class,
+        getAnnotation = "@BarInheritedContainer("
+        + "value=[@BarInherited(value=1), @BarInherited(value=2)])",
+        getAnnotationsByType = {"@BarInheritedContainer("
+                + "value=[@BarInherited(value=1), @BarInherited(value=2)])"})
+@BarInherited(value = 0)
+class MixRepeatableAndOfficialContainerInheritedB1Test extends M {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java
new file mode 100644
index 0000000..0197738
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixRepeatableAndOfficialContainerInheritedB2Test.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/*
+ * @ignore
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixRepeatableAndOfficialContainerInheritedB2Test.java
+ */
+
+@BarInheritedContainer(value = {@BarInherited(value = 1), @BarInherited(value = 2)})
+@BarInherited(value = 3)
+class H {}
+
+@ExpectedBase(
+        value = BarInherited.class,
+        getAnnotation = "@BarInherited(value=0)",
+        getAnnotationsByType = {"@BarInherited(value=0)"},
+        getAllAnnotationMirrors = {
+            "@BarInherited(0)",
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarInherited(0)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainer.class,
+        getAnnotation = "@BarInheritedContainer("
+        + "value=[@BarInherited(value=1), @BarInherited(value=2)])",
+        getAnnotationsByType = {"@BarInheritedContainer("
+                + "value=[@BarInherited(value=1), @BarInherited(value=2)])"})
+@BarInherited(value = 0)
+class MixRepeatableAndOfficialContainerInheritedB2Test extends H {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerBasicTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerBasicTest.java
new file mode 100644
index 0000000..319a728
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerBasicTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only MixSingularAndUnofficialContainerBasicTest.java
+ */
+
+@ExpectedBase(
+        value = Foo.class,
+        getAnnotation = "@Foo(value=0)",
+        getAnnotationsByType = {"@Foo(value=0)"},
+        getAllAnnotationMirrors = {
+            "@Foo(0)",
+            "@UnofficialContainer({@Foo(1), @Foo(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@Foo(0)",
+            "@UnofficialContainer({@Foo(1), @Foo(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = UnofficialContainer.class,
+        getAnnotation = "@UnofficialContainer("
+        + "value=[@Foo(value=1), @Foo(value=2)])",
+        getAnnotationsByType = {"@UnofficialContainer("
+                + "value=[@Foo(value=1), @Foo(value=2)])"})
+@Foo(value = 0)
+@UnofficialContainer(value = {@Foo(value = 1), @Foo(value = 2)})
+class MixSingularAndUnofficialContainerBasicTest {
+
+    @ExpectedBase(
+            value = Foo.class,
+            getAnnotation = "@Foo(value=0)",
+            getAnnotationsByType = {"@Foo(value=0)"},
+            getAllAnnotationMirrors = {
+                "@Foo(0)",
+                "@UnofficialContainer({@Foo(1), @Foo(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@Foo(0)",
+                "@UnofficialContainer({@Foo(1), @Foo(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = UnofficialContainer.class,
+            getAnnotation = "@UnofficialContainer("
+            + "value=[@Foo(value=1), @Foo(value=2)])",
+            getAnnotationsByType = {"@UnofficialContainer("
+                    + "value=[@Foo(value=1), @Foo(value=2)])"})
+    @Foo(value = 0)
+    @UnofficialContainer(value = {@Foo(value = 1), @Foo(value = 2)})
+    int testField = 0;
+
+    @ExpectedBase(
+            value = Foo.class,
+            getAnnotation = "@Foo(value=0)",
+            getAnnotationsByType = {"@Foo(value=0)"},
+            getAllAnnotationMirrors = {
+                "@Foo(0)",
+                "@UnofficialContainer({@Foo(1), @Foo(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@Foo(0)",
+                "@UnofficialContainer({@Foo(1), @Foo(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = UnofficialContainer.class,
+            getAnnotation = "@UnofficialContainer("
+            + "value=[@Foo(value=1), @Foo(value=2)])",
+            getAnnotationsByType = {"@UnofficialContainer("
+                    + "value=[@Foo(value=1), @Foo(value=2)])"})
+    @Foo(value = 0)
+    @UnofficialContainer(value = {@Foo(value = 1), @Foo(value = 2)})
+    void testMethod() {}
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedA1Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedA1Test.java
new file mode 100644
index 0000000..f21de09
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedA1Test.java
@@ -0,0 +1,61 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixSingularAndUnofficialContainerInheritedA1Test.java
+ */
+
+@FooInherited(value = 0)
+class L {}
+
+@ExpectedBase(
+        value = FooInherited.class,
+        getAnnotation = "@FooInherited(value=0)",
+        getAnnotationsByType = {"@FooInherited(value=0)"},
+        getAllAnnotationMirrors = {
+            "@FooInherited(0)",
+            "@UnofficialInheritedContainer({@FooInherited(1), @FooInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@UnofficialInheritedContainer({@FooInherited(1), @FooInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = UnofficialInheritedContainer.class,
+        getAnnotation = "@UnofficialInheritedContainer("
+        + "value=[@FooInherited(value=1), @FooInherited(value=2)])",
+        getAnnotationsByType = {"@UnofficialInheritedContainer("
+                + "value=[@FooInherited(value=1), @FooInherited(value=2)])"})
+@UnofficialInheritedContainer(value = {@FooInherited(value = 1), @FooInherited(value = 2)})
+class MixSingularAndUnofficialContainerInheritedA1Test extends L {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedA2Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedA2Test.java
new file mode 100644
index 0000000..3354483
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedA2Test.java
@@ -0,0 +1,63 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixSingularAndUnofficialContainerInheritedA2Test.java
+ */
+
+@FooInherited(value = 0)
+class K {}
+
+@ExpectedBase(
+        value = FooInherited.class,
+        getAnnotation = "@FooInherited(value=3)",
+        getAnnotationsByType = {"@FooInherited(value=3)"},
+        getAllAnnotationMirrors = {
+            "@FooInherited(3)",
+            "@UnofficialInheritedContainer({@FooInherited(1), @FooInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@UnofficialInheritedContainer({@FooInherited(1), @FooInherited(2)})",
+            "@FooInherited(3)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = UnofficialInheritedContainer.class,
+        getAnnotation = "@UnofficialInheritedContainer("
+        + "value=[@FooInherited(value=1), @FooInherited(value=2)])",
+        getAnnotationsByType = {"@UnofficialInheritedContainer("
+                + "value=[@FooInherited(value=1), @FooInherited(value=2)])"})
+@UnofficialInheritedContainer(value = {@FooInherited(value = 1), @FooInherited(value = 2)})
+@FooInherited(value = 3)
+class MixSingularAndUnofficialContainerInheritedA2Test extends K {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedB1Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedB1Test.java
new file mode 100644
index 0000000..12daba2
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedB1Test.java
@@ -0,0 +1,61 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixSingularAndUnofficialContainerInheritedB1Test.java
+ */
+
+@UnofficialInheritedContainer(value = {@FooInherited(value = 1),@FooInherited(value = 2)})
+class J {}
+
+@ExpectedBase(
+        value = FooInherited.class,
+        getAnnotation = "@FooInherited(value=0)",
+        getAnnotationsByType = {"@FooInherited(value=0)"},
+        getAllAnnotationMirrors = {
+            "@FooInherited(0)",
+            "@UnofficialInheritedContainer({@FooInherited(1), @FooInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@FooInherited(0)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = UnofficialInheritedContainer.class,
+        getAnnotation = "@UnofficialInheritedContainer("
+        + "value=[@FooInherited(value=1), @FooInherited(value=2)])",
+        getAnnotationsByType = {"@UnofficialInheritedContainer("
+                + "value=[@FooInherited(value=1), @FooInherited(value=2)])"})
+@FooInherited(value = 0)
+class MixSingularAndUnofficialContainerInheritedB1Test extends J {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedB2Test.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedB2Test.java
new file mode 100644
index 0000000..9b4dbd3
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/MixSingularAndUnofficialContainerInheritedB2Test.java
@@ -0,0 +1,62 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * MixSingularAndUnofficialContainerInheritedB2Test.java
+ */
+
+@UnofficialInheritedContainer(value = {@FooInherited(value = 1), @FooInherited(value = 2)})
+@FooInherited(value = 3)
+class G {}
+
+@ExpectedBase(
+        value = FooInherited.class,
+        getAnnotation = "@FooInherited(value=0)",
+        getAnnotationsByType = {"@FooInherited(value=0)"},
+        getAllAnnotationMirrors = {
+            "@FooInherited(0)",
+            "@UnofficialInheritedContainer({@FooInherited(1), @FooInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@FooInherited(0)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = UnofficialInheritedContainer.class,
+        getAnnotation = "@UnofficialInheritedContainer("
+        + "value=[@FooInherited(value=1), @FooInherited(value=2)])",
+        getAnnotationsByType = {"@UnofficialInheritedContainer("
+                + "value=[@FooInherited(value=1), @FooInherited(value=2)])"})
+@FooInherited(value = 0)
+class MixSingularAndUnofficialContainerInheritedB2Test extends G{}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/OfficialContainerBasicTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/OfficialContainerBasicTest.java
new file mode 100644
index 0000000..0b39e09
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/OfficialContainerBasicTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only OfficialContainerBasicTest.java
+ */
+
+@ExpectedBase(
+        value = Bar.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {
+            "@Bar(value=1)",
+            "@Bar(value=2)"
+        },
+        getAllAnnotationMirrors = {
+            "@BarContainer({@Bar(1), @Bar(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarContainer({@Bar(1), @Bar(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarContainer.class,
+        getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+        getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+@BarContainer(value = {@Bar(value = 1), @Bar(value = 2)})
+class OfficialContainerBasicTest {
+
+    @ExpectedBase(
+            value = Bar.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {
+                "@Bar(value=1)",
+                "@Bar(value=2)"
+            },
+            getAllAnnotationMirrors = {
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = BarContainer.class,
+            getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+            getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+    @BarContainer(value = {@Bar(value = 1), @Bar(value = 2)})
+    int testField = 0;
+
+    @ExpectedBase(
+            value = Bar.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {
+                "@Bar(value=1)",
+                "@Bar(value=2)"
+            },
+            getAllAnnotationMirrors = {
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = BarContainer.class,
+            getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+            getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+    @BarContainer(value = {@Bar(value = 1), @Bar(value = 2)})
+    void testMethod() {}
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/OfficialContainerInheritedTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/OfficialContainerInheritedTest.java
new file mode 100644
index 0000000..8aa58b2
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/OfficialContainerInheritedTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only OfficialContainerInheritedTest.java
+ */
+
+@BarInheritedContainer(value = {@BarInherited(value = 1), @BarInherited(value = 2)})
+class D {}
+
+@ExpectedBase(
+        value = BarInherited.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {
+            "@BarInherited(value=1)",
+            "@BarInherited(value=2)"
+        },
+        getAllAnnotationMirrors = {
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainer.class,
+        getAnnotation = "@BarInheritedContainer("
+        + "value=[@BarInherited(value=1), @BarInherited(value=2)])",
+        getAnnotationsByType = {"@BarInheritedContainer("
+                + "value=[@BarInherited(value=1), @BarInherited(value=2)])"})
+class OfficialContainerInheritedTest extends D {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableBasicTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableBasicTest.java
new file mode 100644
index 0000000..03eebd5
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableBasicTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only RepeatableBasicTest.java
+ */
+
+@ExpectedBase(
+        value = Bar.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {
+            "@Bar(value=1)",
+            "@Bar(value=2)"
+        },
+        getAllAnnotationMirrors = {
+            "@BarContainer({@Bar(1), @Bar(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarContainer({@Bar(1), @Bar(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarContainer.class,
+        getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+        getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+@Bar(value = 1)
+@Bar(value = 2)
+class RepeatableBasicTest {
+
+    @ExpectedBase(
+            value = Bar.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {
+                "@Bar(value=1)",
+                "@Bar(value=2)"
+            },
+            getAllAnnotationMirrors = {
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = BarContainer.class,
+            getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+            getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+    @Bar(value = 1)
+    @Bar(value = 2)
+    int testField = 0;
+
+    @ExpectedBase(
+            value = Bar.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {
+                "@Bar(value=1)",
+                "@Bar(value=2)"
+            },
+            getAllAnnotationMirrors = {
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@BarContainer({@Bar(1), @Bar(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = BarContainer.class,
+            getAnnotation = "@BarContainer(value=[@Bar(value=1), @Bar(value=2)])",
+            getAnnotationsByType = {"@BarContainer(value=[@Bar(value=1), @Bar(value=2)])"})
+    @Bar(value = 1)
+    @Bar(value = 2)
+    void testMethod() {}
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableInheritedTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableInheritedTest.java
new file mode 100644
index 0000000..2be810e
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableInheritedTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only RepeatableInheritedTest.java
+ */
+
+@BarInherited(value = 1)
+@BarInherited(value = 2)
+class I {}
+
+@ExpectedBase(
+        value = BarInherited.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {
+            "@BarInherited(value=1)",
+            "@BarInherited(value=2)"
+        },
+        getAllAnnotationMirrors = {
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainer.class,
+        getAnnotation = "@BarInheritedContainer("
+        + "value=[@BarInherited(value=1), @BarInherited(value=2)])",
+        getAnnotationsByType = {"@BarInheritedContainer("
+                + "value=[@BarInherited(value=1), @BarInherited(value=2)])"})
+class RepeatableInheritedTest extends I {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOfficialContainerBasicTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOfficialContainerBasicTest.java
new file mode 100644
index 0000000..2745a18
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOfficialContainerBasicTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only RepeatableOfficialContainerBasicTest.java
+ */
+
+@ExpectedBase(
+        value = Bar.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {},
+        getAllAnnotationMirrors = {
+            "@BarContainerContainer({@BarContainer({@Bar(1)}), @BarContainer({@Bar(2)})})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarContainerContainer({@BarContainer({@Bar(1)}), @BarContainer({@Bar(2)})})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarContainer.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {
+            "@BarContainer(value=[@Bar(value=1)])",
+            "@BarContainer(value=[@Bar(value=2)])"})
+@BarContainer(value = {@Bar(value = 1)})
+@BarContainer(value = {@Bar(value = 2)})
+class RepeatableOfficialContainerBasicTest {
+
+    @ExpectedBase(
+            value = Bar.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {},
+            getAllAnnotationMirrors = {
+                "@BarContainerContainer({@BarContainer({@Bar(1)}), @BarContainer({@Bar(2)})})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@BarContainerContainer({@BarContainer({@Bar(1)}), @BarContainer({@Bar(2)})})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = BarContainer.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {
+                "@BarContainer(value=[@Bar(value=1)])",
+                "@BarContainer(value=[@Bar(value=2)])"})
+    @BarContainer(value = {@Bar(value = 1)})
+    @BarContainer(value = {@Bar(value = 2)})
+    int testField = 0;
+
+    @ExpectedBase(
+            value = Bar.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {},
+            getAllAnnotationMirrors = {
+                "@BarContainerContainer({@BarContainer({@Bar(1)}), @BarContainer({@Bar(2)})})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@BarContainerContainer({@BarContainer({@Bar(1)}), @BarContainer({@Bar(2)})})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = BarContainer.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {
+                "@BarContainer(value=[@Bar(value=1)])",
+                "@BarContainer(value=[@Bar(value=2)])"})
+    @BarContainer(value = {@Bar(value = 1)})
+    @BarContainer(value = {@Bar(value = 2)})
+    void testMethod() {}
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOfficialContainerInheritedTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOfficialContainerInheritedTest.java
new file mode 100644
index 0000000..c375565
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOfficialContainerInheritedTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * RepeatableOfficialContainerInheritedTest.java
+ */
+
+@BarInheritedContainer(value = {@BarInherited(value = 1)})
+@BarInheritedContainer(value = {@BarInherited(value = 2)})
+class O {}
+
+@ExpectedBase(
+        value = BarInheritedContainer.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {
+            "@BarInheritedContainer(value=[@BarInherited(value=1)])",
+            "@BarInheritedContainer(value=[@BarInherited(value=2)])"
+        },
+        getAllAnnotationMirrors = {
+            "@BarInheritedContainerContainer("
+                + "{@BarInheritedContainer({@BarInherited(1)}),"
+                + " @BarInheritedContainer({@BarInherited(2)})})",
+                "ExpectedBase",
+                "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainerContainer.class,
+        getAnnotation = "@BarInheritedContainerContainer("
+        + "value=[@BarInheritedContainer(value=[@BarInherited(value=1)]),"
+        + " @BarInheritedContainer(value=[@BarInherited(value=2)])])",
+        getAnnotationsByType = {"@BarInheritedContainerContainer("
+                + "value=[@BarInheritedContainer(value=[@BarInherited(value=1)]),"
+        + " @BarInheritedContainer(value=[@BarInherited(value=2)])])"})
+class RepeatableOfficialContainerInheritedTest extends O {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java
new file mode 100644
index 0000000..df0d46a
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideATest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/*
+ * @ignore
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only RepeatableOverrideATest.java
+ */
+
+@BarInherited(value = 1)
+@BarInherited(value = 2)
+class B {}
+
+@ExpectedBase(
+        value = BarInherited.class,
+        getAnnotation = "@BarInherited(value=3)",
+        getAnnotationsByType = {"@BarInherited(value=3)"},
+        getAllAnnotationMirrors = {
+            "@BarInherited(3)",
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarInherited(3)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainer.class,
+        getAnnotation = "@BarInheritedContainer("
+        + "value=[@BarInherited(value=1), @BarInherited(value=2)])",
+        getAnnotationsByType = {"@BarInheritedContainer("
+                + "value=[@BarInherited(value=1), @BarInherited(value=2)])"})
+@BarInherited(value = 3)
+class RepeatableOverrideATest extends B {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java
new file mode 100644
index 0000000..e9bd3ae
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/RepeatableOverrideBTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/*
+ * @ignore
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only RepeatableOverrideBTest.java
+ */
+
+@BarInherited(value = 0)
+class C {}
+
+@ExpectedBase(
+        value = BarInherited.class,
+        getAnnotation = "@BarInherited(value=0)",
+        getAnnotationsByType = {
+            "@BarInherited(value=1)",
+            "@BarInherited(value=2)"
+        },
+        getAllAnnotationMirrors = {
+            "@BarInherited(0)",
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@BarInheritedContainer({@BarInherited(1), @BarInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = BarInheritedContainer.class,
+        getAnnotation = "@BarInheritedContainer("
+        + "value=[@BarInherited(value=1), @BarInherited(value=2)])",
+        getAnnotationsByType = {"@BarInheritedContainer("
+                + "value=[@BarInherited(value=1), @BarInherited(value=2)])"})
+@BarInherited(value = 1)
+@BarInherited(value = 2)
+class RepeatableOverrideBTest extends C {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularBasicTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularBasicTest.java
new file mode 100644
index 0000000..efed629
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularBasicTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only SingularBasicTest.java
+ */
+
+@ExpectedBase(
+        value = Foo.class,
+        getAnnotation = "@Foo(value=0)",
+        getAnnotationsByType = {"@Foo(value=0)"},
+        getAllAnnotationMirrors = {
+            "@Foo(0)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@Foo(0)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer
+@Foo(value = 0)
+public class SingularBasicTest {
+
+    @ExpectedBase(
+            value = Foo.class,
+            getAnnotation = "@Foo(value=0)",
+            getAnnotationsByType = {"@Foo(value=0)"},
+            getAllAnnotationMirrors = {
+                "@Foo(0)",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@Foo(0)",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer
+    @Foo(value = 0)
+    int testField = 0;
+
+    @ExpectedBase(
+            value = Foo.class,
+            getAnnotation = "@Foo(value=0)",
+            getAnnotationsByType = {"@Foo(value=0)"},
+            getAllAnnotationMirrors = {
+                "@Foo(0)",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@Foo(0)",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer
+    @Foo(value = 0)
+    void testMethod() {
+    }
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularInheritedATest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularInheritedATest.java
new file mode 100644
index 0000000..c48c453
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularInheritedATest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only SingularInheritedATest.java
+ */
+
+@FooInherited(value = 0)
+class A {}
+
+@ExpectedBase(
+        value = FooInherited.class,
+        getAnnotation = "@FooInherited(value=0)",
+        getAnnotationsByType = {"@FooInherited(value=0)"},
+        getAllAnnotationMirrors = {
+            "@FooInherited(0)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer
+class SingularInheritedATest extends A {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularInheritedBTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularInheritedBTest.java
new file mode 100644
index 0000000..fb3a371
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/SingularInheritedBTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only SingularInheritedBTest.java
+ */
+
+@FooInherited(value = 1)
+class P {}
+
+@ExpectedBase(
+        value = FooInherited.class,
+        getAnnotation = "@FooInherited(value=2)",
+        getAnnotationsByType = {"@FooInherited(value=2)"},
+        getAllAnnotationMirrors = {
+            "@FooInherited(2)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@FooInherited(2)",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = UnofficialInheritedContainer.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {})
+@FooInherited(value = 2)
+class SingularInheritedBTest extends P {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/UnofficialContainerBasicTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/UnofficialContainerBasicTest.java
new file mode 100644
index 0000000..33eac13
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/UnofficialContainerBasicTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only UnofficialContainerBasicTest.java
+ */
+
+@ExpectedBase(
+        value = Foo.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {},
+        getAllAnnotationMirrors = {
+            "@UnofficialContainer({@Foo(1), @Foo(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "@UnofficialContainer({@Foo(1), @Foo(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = UnofficialContainer.class,
+        getAnnotation = "@UnofficialContainer(value=[@Foo(value=1), @Foo(value=2)])",
+        getAnnotationsByType = {"@UnofficialContainer(value=[@Foo(value=1), @Foo(value=2)])"})
+@UnofficialContainer(value = {@Foo(value = 1), @Foo(value = 2)})
+class UnofficialContainerBasicTest {
+
+    @ExpectedBase(
+            value = Foo.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {},
+            getAllAnnotationMirrors = {
+                "@UnofficialContainer({@Foo(1), @Foo(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@UnofficialContainer({@Foo(1), @Foo(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = UnofficialContainer.class,
+            getAnnotation = "@UnofficialContainer(value=[@Foo(value=1), @Foo(value=2)])",
+            getAnnotationsByType = {"@UnofficialContainer(value=[@Foo(value=1), @Foo(value=2)])"})
+    @UnofficialContainer(value = {@Foo(value = 1), @Foo(value = 2)})
+    int testField = 0;
+
+    @ExpectedBase(
+            value = Foo.class,
+            getAnnotation = "null",
+            getAnnotationsByType = {},
+            getAllAnnotationMirrors = {
+                "@UnofficialContainer({@Foo(1), @Foo(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            },
+            getAnnotationMirrors = {
+                "@UnofficialContainer({@Foo(1), @Foo(2)})",
+                "ExpectedBase",
+                "ExpectedContainer"
+            })
+    @ExpectedContainer(
+            value = UnofficialContainer.class,
+            getAnnotation = "@UnofficialContainer(value=[@Foo(value=1), @Foo(value=2)])",
+            getAnnotationsByType = {"@UnofficialContainer(value=[@Foo(value=1), @Foo(value=2)])"})
+    @UnofficialContainer(value = {@Foo(value = 1), @Foo(value = 2)})
+    void testMethod() {}
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/UnofficialContainerInheritedTest.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/UnofficialContainerInheritedTest.java
new file mode 100644
index 0000000..9fc3ba1
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/UnofficialContainerInheritedTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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     8004822
+ * @author  mnunez
+ * @summary Language model api test basics for repeating annotations
+ * @library /tools/javac/lib
+ * @library supportingAnnotations
+ * @build   JavacTestingAbstractProcessor ElementRepAnnoTester
+ * @compile -processor ElementRepAnnoTester -proc:only
+ * UnofficialContainerInheritedTest.java
+ */
+
+@UnofficialInheritedContainer(value = {@FooInherited(value = 1),@FooInherited(value = 2)})
+class F {}
+
+@ExpectedBase(
+        value = FooInherited.class,
+        getAnnotation = "null",
+        getAnnotationsByType = {},
+        getAllAnnotationMirrors = {
+            "@UnofficialInheritedContainer({@FooInherited(1), @FooInherited(2)})",
+            "ExpectedBase",
+            "ExpectedContainer"
+        },
+        getAnnotationMirrors = {
+            "ExpectedBase",
+            "ExpectedContainer"
+        })
+@ExpectedContainer(
+        value = UnofficialInheritedContainer.class,
+        getAnnotation = "@UnofficialInheritedContainer("
+        + "value=[@FooInherited(value=1), @FooInherited(value=2)])",
+        getAnnotationsByType = {"@UnofficialInheritedContainer("
+                + "value=[@FooInherited(value=1), @FooInherited(value=2)])"})
+class UnofficialContainerInheritedTest extends F {}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/Bar.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/Bar.java
new file mode 100644
index 0000000..6eaf680
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/Bar.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(BarContainer.class)
+public @interface Bar {
+    int value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarContainer.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarContainer.java
new file mode 100644
index 0000000..688042e
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarContainer.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(BarContainerContainer.class)
+public @interface BarContainer {
+    Bar[] value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarContainerContainer.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarContainerContainer.java
new file mode 100644
index 0000000..9285014
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarContainerContainer.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface BarContainerContainer {
+    BarContainer[] value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInherited.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInherited.java
new file mode 100644
index 0000000..e30d3de
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInherited.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Repeatable(BarInheritedContainer.class)
+public @interface BarInherited {
+    int value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInheritedContainer.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInheritedContainer.java
new file mode 100644
index 0000000..ee8cfdb
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInheritedContainer.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Repeatable(BarInheritedContainerContainer.class)
+public @interface BarInheritedContainer {
+    BarInherited[] value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInheritedContainerContainer.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInheritedContainerContainer.java
new file mode 100644
index 0000000..d814a50
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/BarInheritedContainerContainer.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface BarInheritedContainerContainer {
+    BarInheritedContainer[] value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/ExpectedBase.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/ExpectedBase.java
new file mode 100644
index 0000000..6cfc0f4
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/ExpectedBase.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExpectedBase {
+    Class<? extends Annotation> value() default Annotation.class;
+    String getAnnotation() default "";
+    String[] getAllAnnotationMirrors() default {};
+    String[] getAnnotationMirrors() default {};
+    // Java SE 8 methods.
+    String[] getAnnotationsByType() default {};
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/ExpectedContainer.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/ExpectedContainer.java
new file mode 100644
index 0000000..2e2d39b
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/ExpectedContainer.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExpectedContainer {
+    Class<? extends Annotation> value() default Annotation.class;
+    String getAnnotation() default "";
+    // Java SE 8 methods.
+    String[] getAnnotationsByType() default {};
+    }
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/Foo.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/Foo.java
new file mode 100644
index 0000000..5a4acab
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/Foo.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Foo {
+    int value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/FooInherited.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/FooInherited.java
new file mode 100644
index 0000000..2681d1f
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/FooInherited.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface FooInherited {
+    int value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/UnofficialContainer.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/UnofficialContainer.java
new file mode 100644
index 0000000..06c8cbf
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/UnofficialContainer.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UnofficialContainer {
+    Foo[] value();
+}
diff --git a/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/UnofficialInheritedContainer.java b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/UnofficialInheritedContainer.java
new file mode 100644
index 0000000..e862b92
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/element/repeatingAnnotations/supportingAnnotations/UnofficialInheritedContainer.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface UnofficialInheritedContainer {
+    FooInherited[] value();
+}
diff --git a/langtools/test/tools/javac/processing/model/util/elements/TestIsFunctionalInterface.java b/langtools/test/tools/javac/processing/model/util/elements/TestIsFunctionalInterface.java
new file mode 100644
index 0000000..791b574
--- /dev/null
+++ b/langtools/test/tools/javac/processing/model/util/elements/TestIsFunctionalInterface.java
@@ -0,0 +1,115 @@
+/*
+ * 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 8007574
+ * @summary Test Elements.isFunctionalInterface
+ * @author  Joseph D. Darcy
+ * @library /tools/javac/lib
+ * @build   JavacTestingAbstractProcessor TestIsFunctionalInterface
+ * @compile -processor TestIsFunctionalInterface TestIsFunctionalInterface.java
+ */
+
+import java.util.Set;
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import static javax.lang.model.SourceVersion.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+import static javax.lang.model.util.ElementFilter.*;
+import static javax.tools.Diagnostic.Kind.*;
+import static javax.tools.StandardLocation.*;
+import java.io.*;
+
+/**
+ * Test basic workings of Elements.isFunctionalInterface
+ */
+public class TestIsFunctionalInterface extends JavacTestingAbstractProcessor {
+    private int count = 0;
+    public boolean process(Set<? extends TypeElement> annotations,
+                           RoundEnvironment roundEnv) {
+        if (!roundEnv.processingOver()) {
+            for(TypeElement type : typesIn(roundEnv.getElementsAnnotatedWith(ExpectedIsFunInt.class))) {
+                count++;
+                System.out.println(type);
+                if (elements.isFunctionalInterface(type) !=
+                    type.getAnnotation(ExpectedIsFunInt.class).value()) {
+                    messager.printMessage(ERROR,
+                                          "Mismatch between expected and computed isFunctionalInterface",
+                                          type);
+                }
+            }
+        } else {
+            if (count <= 0)
+                messager.printMessage(ERROR, "No types with ExpectedIsFunInt processed.");
+            }
+    return true;
+    }
+}
+
+@interface ExpectedIsFunInt {
+    boolean value();
+}
+
+// Examples below from the lambda specification documents.
+
+@ExpectedIsFunInt(false) // Equals is already an implicit member
+interface Foo1 { boolean equals(Object obj); }
+
+@ExpectedIsFunInt(true) // Bar has one abstract non-Object method
+interface Bar1 extends Foo1 { int compare(String o1, String o2); }
+
+
+@ExpectedIsFunInt(true) // Comparator has one abstract non-Object method
+interface LocalComparator<T> {
+ boolean equals(Object obj);
+ int compare(T o1, T o2);
+}
+
+@ExpectedIsFunInt(false) // Method Object.clone is not public
+interface Foo2 {
+  int m();
+  Object clone();
+}
+
+interface X1 { int m(Iterable<String> arg); }
+interface Y1 { int m(Iterable<String> arg); }
+@ExpectedIsFunInt(true) // Two methods, but they have the same signature
+interface Z1 extends X1, Y1 {}
+
+interface X2 { Iterable m(Iterable<String> arg); }
+interface Y2 { Iterable<String> m(Iterable arg); }
+@ExpectedIsFunInt(true) // Y.m is a subsignature & return-type-substitutable
+interface Z2 extends X2, Y2 {}
+
+interface Action<T> {
+    T doit();
+}
+@ExpectedIsFunInt(true)
+interface LocalExecutor { <T> T execute(Action<T> a); }
+
+interface X5 { <T> T execute(Action<T> a); }
+interface Y5 { <S> S execute(Action<S> a); }
+@ExpectedIsFunInt(true) // Functional: signatures are "the same"
+interface Exec5 extends X5, Y5 {}
diff --git a/langtools/test/tools/javac/profiles/ProfileOptionTest.java b/langtools/test/tools/javac/profiles/ProfileOptionTest.java
new file mode 100644
index 0000000..648cef3
--- /dev/null
+++ b/langtools/test/tools/javac/profiles/ProfileOptionTest.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2011, 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 8004182
+ * @summary Add support for profiles in javac
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.jvm.Profile;
+import com.sun.tools.javac.jvm.Target;
+
+
+public class ProfileOptionTest {
+    public static void main(String... args) throws Exception {
+        new ProfileOptionTest().run();
+    }
+
+    private final JavaCompiler javac = JavacTool.create();
+    private final StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
+
+
+    // ---------- Test cases, invoked reflectively via run. ----------
+
+    @Test
+    void testInvalidProfile_CommandLine() throws Exception {
+        JavaFileObject fo = new StringJavaFileObject("Test.java", "class Test { }");
+        String badName = "foo";
+        List<String> opts = Arrays.asList("-profile", badName);
+        StringWriter sw = new StringWriter();
+        try {
+            JavacTask task = (JavacTask) javac.getTask(sw, fm, null, opts, null,
+                Arrays.asList(fo));
+            throw new Exception("expected exception not thrown");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    @Test
+    void testInvalidProfile_API() throws Exception {
+        String badName = "foo";
+        String[] opts = { "-profile", badName };
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = com.sun.tools.javac.Main.compile(opts, pw);
+
+        // sadly, command line errors are not (yet?) reported to
+        // the diag listener
+        String out = sw.toString();
+        if (!out.isEmpty())
+            System.err.println(out.trim());
+
+        if (!out.contains("invalid profile: " + badName)) {
+            error("expected message not found");
+        }
+    }
+
+    @Test
+    void testTargetProfileCombinations() throws Exception {
+        JavaFileObject fo = new StringJavaFileObject("Test.java", "class Test { }");
+        for (Target t: Target.values()) {
+            switch (t) {
+                case JDK1_1: case JDK1_2: // no equivalent -source
+                case JDK1_4_1: case JDK1_4_2: case JSR14: // transitional values
+                    continue;
+            }
+
+            for (Profile p: Profile.values()) {
+                List<String> opts = new ArrayList<String>();
+                opts.addAll(Arrays.asList("-source", t.name, "-target", t.name));
+                opts.add("-Xlint:-options"); // dont warn about no -bootclasspath
+                if (p != Profile.DEFAULT)
+                    opts.addAll(Arrays.asList("-profile", p.name));
+                StringWriter sw = new StringWriter();
+                JavacTask task = (JavacTask) javac.getTask(sw, fm, null, opts, null,
+                        Arrays.asList(fo));
+                task.analyze();
+
+                // sadly, command line errors are not (yet?) reported to
+                // the diag listener
+                String out = sw.toString();
+                if (!out.isEmpty())
+                    System.err.println(out.trim());
+
+                switch (t) {
+                    case JDK1_8:
+                        if (!out.isEmpty())
+                            error("unexpected output from compiler");
+                        break;
+                    default:
+                        if (p != Profile.DEFAULT
+                                && !out.contains("profile " + p.name
+                                    + " is not valid for target release " + t.name)) {
+                            error("expected message not found");
+                        }
+                }
+            }
+        }
+    }
+
+    @Test
+    void testClassesInProfiles() throws Exception {
+        for (Profile p: Profile.values()) {
+            for (Map.Entry<Profile, List<JavaFileObject>> e: testClasses.entrySet()) {
+                for (JavaFileObject fo: e.getValue()) {
+                    DiagnosticCollector<JavaFileObject> dl =
+                            new DiagnosticCollector<JavaFileObject>();
+                    List<String> opts = (p == Profile.DEFAULT)
+                            ? Collections.<String>emptyList()
+                            : Arrays.asList("-profile", p.name);
+                    JavacTask task = (JavacTask) javac.getTask(null, fm, dl, opts, null,
+                            Arrays.asList(fo));
+                    task.analyze();
+
+                    List<String> expectDiagCodes = (p.value >= e.getKey().value)
+                            ? Collections.<String>emptyList()
+                            : Arrays.asList("compiler.err.not.in.profile");
+
+                    checkDiags(opts + " " + fo.getName(), dl.getDiagnostics(), expectDiagCodes);
+                }
+            }
+        }
+    }
+
+    Map<Profile, List<JavaFileObject>> testClasses =
+            new EnumMap<Profile, List<JavaFileObject>>(Profile.class);
+
+    void initTestClasses() {
+        // The following table assumes the existence of specific classes
+        // in specific profiles, as defined in the Java SE 8 spec.
+        init(Profile.COMPACT1,
+                java.lang.String.class);
+
+        init(Profile.COMPACT2,
+                javax.xml.XMLConstants.class);
+
+        init(Profile.COMPACT3,
+                javax.script.Bindings.class,
+                com.sun.security.auth.PolicyFile.class); // specifically included in 3
+
+        init(Profile.DEFAULT,
+                java.beans.BeanInfo.class,
+                javax.management.remote.rmi._RMIServer_Stub.class); // specifically excluded in 3
+    }
+
+    void init(Profile p, Class<?>... classes) {
+        List<JavaFileObject> srcs = new ArrayList<JavaFileObject>();
+        for (Class<?> c: classes) {
+            String name = "T" + c.getSimpleName();
+            String src =
+                    "class T" + name + "{" + "\n" +
+                    "    Class<?> c = " + c.getName() + ".class;\n" +
+                    "}";
+            srcs.add(new StringJavaFileObject(name + ".java", src));
+        }
+        testClasses.put(p, srcs);
+    }
+
+    void checkDiags(String msg, List<Diagnostic<? extends JavaFileObject>> diags, List<String> expectDiagCodes) {
+        System.err.print(msg);
+        if (diags.isEmpty())
+            System.err.println(" OK");
+        else {
+            System.err.println();
+            System.err.println(diags);
+        }
+
+        List<String> foundDiagCodes = new ArrayList<String>();
+        for (Diagnostic<? extends JavaFileObject> d: diags)
+            foundDiagCodes.add(d.getCode());
+
+        if (!foundDiagCodes.equals(expectDiagCodes)) {
+            System.err.println("Found diag codes:    " + foundDiagCodes);
+            System.err.println("Expected diag codes: " + expectDiagCodes);
+            error("expected diagnostics not found");
+        }
+    }
+
+    /** Marker annotation for test cases. */
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Test { }
+
+    /** Run all test cases. */
+    void run() throws Exception {
+        initTestClasses();
+
+        for (Method m: getClass().getDeclaredMethods()) {
+            Annotation a = m.getAnnotation(Test.class);
+            if (a != null) {
+                System.err.println(m.getName());
+                try {
+                    m.invoke(this, new Object[] { });
+                } catch (InvocationTargetException e) {
+                    Throwable cause = e.getCause();
+                    throw (cause instanceof Exception) ? ((Exception) cause) : e;
+                }
+                System.err.println();
+            }
+        }
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+
+    private static class StringJavaFileObject extends SimpleJavaFileObject {
+        StringJavaFileObject(String name, String text) {
+            super(URI.create(name), JavaFileObject.Kind.SOURCE);
+            this.text = text;
+        }
+        @Override
+        public CharSequence getCharContent(boolean b) {
+            return text;
+        }
+        private String text;
+    }
+}
diff --git a/langtools/test/tools/javadoc/doclint/DocLintTest.java b/langtools/test/tools/javadoc/doclint/DocLintTest.java
index 22557fa..346b457 100644
--- a/langtools/test/tools/javadoc/doclint/DocLintTest.java
+++ b/langtools/test/tools/javadoc/doclint/DocLintTest.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8004834
+ * @bug 8004834 8007610
  * @summary Add doclint support into javadoc
  */
 
@@ -157,6 +157,10 @@
                 Main.Result.OK,
                 EnumSet.of(Message.DL_WRN12));
 
+        test(Arrays.asList(rawDiags, "-private"),
+                Main.Result.ERROR,
+                EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12));
+
         test(Arrays.asList(rawDiags, "-Xdoclint:syntax", "-private"),
                 Main.Result.ERROR,
                 EnumSet.of(Message.DL_ERR6, Message.DL_WRN12));
diff --git a/langtools/test/tools/javap/8006334/JavapTaskCtorFailWithNPE.java b/langtools/test/tools/javap/8006334/JavapTaskCtorFailWithNPE.java
new file mode 100644
index 0000000..1ba5f9a
--- /dev/null
+++ b/langtools/test/tools/javap/8006334/JavapTaskCtorFailWithNPE.java
@@ -0,0 +1,85 @@
+/*
+ * 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 8006334
+ * @summary javap: JavapTask constructor breaks with null pointer exception if
+ * parameter options is null
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Locale;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import com.sun.tools.javap.JavapFileManager;
+import com.sun.tools.javap.JavapTask;
+
+public class JavapTaskCtorFailWithNPE {
+
+    //we will also check the output just to confirm that we get the expected one
+    private static final String expOutput =
+        "Compiled from \"JavapTaskCtorFailWithNPE.java\"\n" +
+        "public class JavapTaskCtorFailWithNPE {\n" +
+        "  public JavapTaskCtorFailWithNPE();\n" +
+        "  public static void main(java.lang.String[]);\n" +
+        "}\n";
+
+    public static void main(String[] args) {
+        new JavapTaskCtorFailWithNPE().run();
+    }
+
+    private void run() {
+        File classToCheck = new File(System.getProperty("test.classes"),
+            getClass().getSimpleName() + ".class");
+
+        DiagnosticCollector<JavaFileObject> dc =
+                new DiagnosticCollector<JavaFileObject>();
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        JavaFileManager fm = JavapFileManager.create(dc, pw);
+        JavapTask t = new JavapTask(pw, fm, dc, null,
+                Arrays.asList(classToCheck.getPath()));
+        boolean ok = t.run();
+        if (!ok)
+            throw new Error("javap failed unexpectedly");
+
+        List<Diagnostic<? extends JavaFileObject>> diags = dc.getDiagnostics();
+        for (Diagnostic<? extends JavaFileObject> d: diags) {
+            if (d.getKind() == Diagnostic.Kind.ERROR)
+                throw new AssertionError(d.getMessage(Locale.ENGLISH));
+        }
+        String lineSep = System.getProperty("line.separator");
+        String out = sw.toString().replace(lineSep, "\n");
+        if (!out.equals(expOutput)) {
+            throw new AssertionError("The output is not equal to the one expected");
+        }
+    }
+
+}
diff --git a/make/scripts/webrev.ksh b/make/scripts/webrev.ksh
index b4ba97b..527b5d4 100644
--- a/make/scripts/webrev.ksh
+++ b/make/scripts/webrev.ksh
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
 # Use is subject to license terms.
 #
 # This script takes a file list and a workspace and builds a set of html files
@@ -27,7 +27,7 @@
 # Documentation is available via 'webrev -h'.
 #
 
-WEBREV_UPDATED=23.18-hg
+WEBREV_UPDATED=23.18-hg+jbs
 
 HTML='<?xml version="1.0"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
@@ -146,7 +146,7 @@
 #
 bug2url()
 {
-	sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL'&\">&</a>|g'
+	sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL$IDPREFIX'&\">&</a>|g'
 }
 
 #
@@ -230,8 +230,8 @@
 #   $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \
 #         new/usr/src/tools/scripts/webrev.sh \
 #         webrev.sh usr/src/tools/scripts \
-#         '<a href="http://monaco.sfbay.sun.com/detail.jsp?cr=1234567">
-#          1234567</a> my bugid' > <file>.html
+#         '<a href="https://jbs.oracle.com/bugs/browse/JDK-1234567">
+#          JDK-1234567</a> my bugid' > <file>.html
 #
 # framed_sdiff() is then called which creates $2.frames.html
 # in the webrev tree.
@@ -1160,7 +1160,7 @@
 	            print "$comm"
 	            return
 	        fi
-	  
+
 	        print "$comm" | html_quote | bug2url | sac2url
                 )
         fi
@@ -1418,7 +1418,7 @@
                   next;}
         END       {for (tree in trees)
                         { rev=revs[trees[tree]];
-                          if (rev > 0) 
+                          if (rev > 0)
                                 {printf("%s %d\n",trees[tree],rev-1)}
                         }}' | while read LINE
     do
@@ -1459,7 +1459,7 @@
 {
     TREE=$1
     HGCMD="hg -R $CWS/$TREE status $FSTAT_OPT"
-    
+
     $HGCMD -mdn 2>/dev/null | $FILTER | while read F
     do
         echo $TREE/$F
@@ -1543,7 +1543,7 @@
 			 if (n == 0)
 				{ printf("A %s/%s\n",tree,$2)}
 			 else
-				{ printf("A %s\n",$2)}; 
+				{ printf("A %s\n",$2)};
 			 next}
 	/^ /		{n=index($1,tree);
 			 if (n == 0)
@@ -1604,7 +1604,7 @@
 # We need at least one of default-push or default paths set in .hg/hgrc
 # If neither are set we don't know who to compare with.
 
-function flist_from_mercurial 
+function flist_from_mercurial
 {
 #	if [ "${PWS##ssh://}" != "$PWS" -o \
 #	     "${PWS##http://}" != "$PWS" -o \
@@ -1757,7 +1757,7 @@
 	elif [[ "$OS" == "Linux" ]]; then
 	    DEVTOOLS="/java/devtools/linux/bin"
 	fi
-	    
+
 	ppath=$PATH
 	ppath=$ppath:/usr/sfw/bin:/usr/bin:/usr/sbin
 	ppath=$ppath:/opt/teamware/bin:/opt/onbld/bin
@@ -1844,7 +1844,7 @@
 	ssh_host=`echo $CMD | sed -e 's/ssh:\/\/\([^/]*\)\/.*/\1/'`
 	ssh_dir=`echo $CMD | sed -e 's/ssh:\/\/[^/]*\/\(.*\)/\1/'`
     fi
-    
+
 }
 
 function build_old_new_mercurial
@@ -2096,7 +2096,7 @@
 		PARENT_REV=$OPTARG;;
 
 	v)	print "$0 version: $WEBREV_UPDATED";;
-		
+
 
 	?)	usage;;
 	esac
@@ -2338,7 +2338,7 @@
 	#
 	[[ -z $codemgr_ws && -n $CODEMGR_WS ]] && codemgr_ws=$CODEMGR_WS
 	[[ -z $codemgr_ws && -n $WSPACE ]] && codemgr_ws=`$WSPACE name`
-	    
+
 	if [[ -n $codemgr_ws && ! -d $codemgr_ws ]]; then
 		print -u2 "$codemgr_ws: no such workspace"
 		exit 1
@@ -2521,10 +2521,16 @@
 #    Bug IDs will be replaced by a URL.  Order of precedence
 #    is: default location, $WEBREV_BUGURL, the -O flag.
 #
-BUGURL='http://monaco.sfbay.sun.com/detail.jsp?cr='
+BUGURL='https://jbs.oracle.com/bugs/browse/'
 [[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL"
-[[ -n "$Oflag" ]] && \
+if [[ -n "$Oflag" ]]; then
+    CRID=`echo $CRID | sed -e 's/JDK-//'`
     BUGURL='http://bugs.sun.com/bugdatabase/view_bug.do?bug_id='
+    IDPREFIX=''
+else
+    IDPREFIX='JDK-'
+fi
+
 
 #
 #    Likewise, ARC cases will be replaced by a URL.  Order of precedence
@@ -2561,7 +2567,7 @@
 
 #
 # Should we ignore changes in white spaces when generating diffs?
-# 
+#
 if [[ -n $bflag ]]; then
     DIFFOPTS="-t"
 else
@@ -2748,7 +2754,7 @@
 		fi
 	    fi
 	else
-	    
+
 	    #
 	    # If we have old and new versions of the file then run the
 	    # appropriate diffs.  This is complicated by a couple of factors:
@@ -3000,22 +3006,31 @@
 # external URL has a <title> like:
 # <title>Bug ID: 6641309 Wrong Cookie separator used in HttpURLConnection</title>
 # while internal URL has <title> like:
-# <title>6641309: Wrong Cookie separator used in HttpURLConnection</title>
+# <title>[#JDK-6641309] Wrong Cookie separator used in HttpURLConnection</title>
 #
 if [[ -n $CRID ]]; then
     for id in $CRID
     do
+        if [[ -z "$Oflag" ]]; then
+            #add "JDK-" to raw bug id for jbs links.
+            id=`echo ${id} | sed 's/^\([0-9]\{5,\}\)$/JDK-\1/'`
+        fi
         print "<tr><th>Bug id:</th><td>"
         url="${BUGURL}${id}"
-        if [[ -n $WGET ]]; then
-            msg=`$WGET -q $url -O - | grep '<title>' | sed 's/<title>\(.*\)<\/title>/\1/' | sed 's/Bug ID://'`
-        fi
-        if [[ -n $msg ]]; then
-            print "<a href=\"$url\">$msg</a>"
+        if [[ -n "$Oflag" ]]; then
+            cleanup='s/Bug ID: \([0-9]\{5,\}\) \(.*\)/JDK-\1 : \2/'
         else
-            print $id | bug2url
+            cleanup='s|\[#\(JDK-[0-9]\{5,\}\)\] \(.*\)|\1 : \2|'
         fi
-        
+        if [[ -n $WGET ]]; then
+            msg=`$WGET --timeout=10 --tries=1 -q $url -O - | grep '<title>' | sed 's/<title>\(.*\)<\/title>/\1/' | sed "$cleanup"`
+        fi
+        if [[ -z $msg ]]; then
+            msg="${id}"
+        fi
+
+        print "<a href=\"$url\">$msg</a>"
+
         print "</td></tr>"
     done
 fi
@@ -3179,4 +3194,3 @@
 
 print "Done."
 print "Output to: $WDIR"
-
diff --git a/test/Makefile b/test/Makefile
index 701d39c..80f0b24 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -38,8 +38,8 @@
 define SUBDIR_TEST # subdirectory target
 if [ -d $1 ] ; then \
   if [ -r $1/test/Makefile ] ; then \
-    echo "$(MAKE) -C $1/test $2" ; \
-    $(MAKE) -C $1/test $2 ; \
+    echo "$(MAKE) -k -C $1/test $2" ; \
+    $(MAKE) -k -C $1/test $2 ; \
   else \
     echo "ERROR: File does not exist: $1/test/Makefile"; \
     exit 1; \
@@ -53,7 +53,7 @@
 LANGTOOLS_TEST_LIST = langtools_jtreg
 
 # Test target list for jdk repository
-JDK_DEFAULT_TEST_LIST = \
+JDK_ALL_TEST_LIST = \
 	jdk_beans1 \
 	jdk_io  \
 	jdk_lang  \
@@ -64,10 +64,7 @@
 	jdk_security1 \
 	jdk_text  \
 	jdk_util  \
-	jdk_time
-
-# These tests are not part of the default testing list
-JDK_NONDEFAULT_TEST_LIST = \
+	jdk_time \
 	jdk_awt \
 	jdk_beans2 jdk_beans3  \
 	jdk_management \
@@ -80,14 +77,14 @@
 	jdk_jdi \
 	jdk_jfr
 
-# All jdk tests
-JDK_ALL_TEST_LIST = $(JDK_DEFAULT_TEST_LIST) $(JDK_NONDEFAULT_TEST_LIST)
+# Theses are meta test targets in jdk
+JDK_META_TEST_LIST = jdk_all jdk_default jdk_core
 
 # These are the current jck test targets in the jdk repository
 JDK_JCK7_LIST = jck7devtools jck7compiler jck7runtime
 
-# Default test target (everything)
-default: $(JDK_DEFAULT_TEST_LIST) $(LANGTOOLS_TEST_LIST)
+# Default test target (core)
+default: jdk_core $(LANGTOOLS_TEST_LIST)
 
 # All testing
 all: $(JDK_ALL_TEST_LIST) $(LANGTOOLS_TEST_LIST)
@@ -95,7 +92,8 @@
 # Test targets
 $(LANGTOOLS_TEST_LIST):
 	@$(NO_STOPPING)$(call SUBDIR_TEST, $(LANGTOOLS_DIR), $(subst langtools_,,$@))
-$(JDK_ALL_TEST_LIST) $(JDK_JCK7_LIST):
+
+$(JDK_ALL_TEST_LIST) $(JDK_META_TEST_LIST) $(JDK_JCK7_LIST):
 	@$(NO_STOPPING)$(call SUBDIR_TEST, $(JDK_DIR), $@)
 
 clean:
@@ -104,7 +102,7 @@
 
 # Phony targets (e.g. these are not filenames)
 .PHONY: all clean \
-        $(JDK_ALL_TEST_LIST) $(JDK_JCK7_LIST) \
+        $(JDK_ALL_TEST_LIST) $(JDK_META_TEST_LIST) $(JDK_JCK7_LIST) \
         $(LANGTOOLS_TEST_LIST)
 
 ################################################################