changeset 10607:19e02e44f2c8

Merge
author asaha
date Mon, 01 Dec 2014 11:37:49 -0800
parents 8425e4fb182c 1c7cd8256690
children e0c7864bbca3
files .hgtags src/share/classes/sun/security/ssl/Handshaker.java
diffstat 21 files changed, 1485 insertions(+), 967 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Nov 19 15:29:32 2014 -0800
+++ b/.hgtags	Mon Dec 01 11:37:49 2014 -0800
@@ -345,6 +345,9 @@
 1e79baf89075967bddc64921d2680d8c1123f654 jdk8u31-b05
 b6aeaae6dd9d3a17564130af142b4734c643267e jdk8u31-b06
 34a484abc5d5391623294743d15e234a99d04dd7 jdk8u31-b07
+ca1adc7c848370dda8dbf9e3a970c3e6427fb05b jdk8u31-b08
+1c0cc3bbe07d52906d7ffbb72fa4733c327f1326 jdk8u31-b09
+291505d802d9075e227f9ee865a67234e1d737cf jdk8u31-b10
 e6ed015afbbf3459ba3297e270b4f3170e989c80 jdk8u40-b00
 6e223d48080ef40f4ec11ecbcd19b4a20813b9eb jdk8u40-b01
 4797cd0713b44b009525f1276d571ade7e24f3f5 jdk8u40-b02
@@ -361,4 +364,5 @@
 ba80109a9b3eb92b56012c9ec3aafd9aee2efa69 jdk8u40-b13
 ffc348308de2e872f5d510d440604c3726a67a18 jdk8u40-b14
 31dac938108da722c56a0526fba7f6ae84773056 jdk8u40-b15
+9dc67d03e6e540f646f27092ed23e94e95fa789e jdk8u40-b16
 1ecc234bd38950a2bc047aa253a5e803f0836a4e jdk8u45-b00
--- a/make/data/tzdata/VERSION	Wed Nov 19 15:29:32 2014 -0800
+++ b/make/data/tzdata/VERSION	Mon Dec 01 11:37:49 2014 -0800
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2014i
+tzdata2014j
--- a/make/data/tzdata/africa	Wed Nov 19 15:29:32 2014 -0800
+++ b/make/data/tzdata/africa	Mon Dec 01 11:37:49 2014 -0800
@@ -29,20 +29,19 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2013-02-21):
+# From Paul Eggert (2014-10-31):
 #
-# A good source for time zone historical data outside the U.S. is
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -88,7 +87,6 @@
 #	 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
@@ -169,9 +167,7 @@
 			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
+# See Africa/Nairobi.
 
 # Democratic Republic of the Congo
 # See Africa/Lagos for the western part and Africa/Maputo for the eastern.
@@ -195,9 +191,7 @@
 Link Africa/Abidjan Atlantic/St_Helena	# St Helena
 
 # Djibouti
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Djibouti	2:52:36 -	LMT	1911 Jul
-			3:00	-	EAT
+# See Africa/Nairobi.
 
 ###############################################################################
 
@@ -410,27 +404,8 @@
 # See Africa/Lagos.
 
 # 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 (2014-07-31):
-# Like the Swahili of Kenya and Tanzania, many Ethiopians keep a
-# 12-hour clock starting at our 06:00, so their "8 o'clock" is our
-# 02:00 or 14:00.  Keep this in mind when you ask the time in Amharic.
-#
-# Shanks & Pottenger write that Ethiopia had six narrowly-spaced time
-# zones between 1870 and 1890, that they merged to 38E50 (2:35:20) in
-# 1890, and that they switched to 3:00 on 1936-05-05.  Perhaps 38E50
-# was for Adis Dera.  Quite likely the Shanks data entries are wrong
-# anyway.
-# 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
+# See Africa/Nairobi.
 
 # Gabon
 # See Africa/Lagos.
@@ -474,6 +449,15 @@
 			2:30	-	BEAT	1940
 			2:45	-	BEAUT	1960
 			3:00	-	EAT
+Link Africa/Nairobi Africa/Addis_Ababa	 # Ethiopia
+Link Africa/Nairobi Africa/Asmara	 # Eritrea
+Link Africa/Nairobi Africa/Dar_es_Salaam # Tanzania
+Link Africa/Nairobi Africa/Djibouti
+Link Africa/Nairobi Africa/Kampala	 # Uganda
+Link Africa/Nairobi Africa/Mogadishu	 # Somalia
+Link Africa/Nairobi Indian/Antananarivo	 # Madagascar
+Link Africa/Nairobi Indian/Comoro
+Link Africa/Nairobi Indian/Mayotte
 
 # Lesotho
 # See Africa/Johannesburg.
@@ -551,11 +535,7 @@
 			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
+# See Africa/Nairobi.
 
 # Malawi
 # See Africa/Maputo.
@@ -658,9 +638,7 @@
 # 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
+# See Africa/Nairobi.
 
 # Morocco
 # See the 'europe' file for Spanish Morocco (Africa/Ceuta).
@@ -1072,11 +1050,7 @@
 # See Africa/Abidjan.
 
 # 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
+# See Africa/Nairobi.
 
 # South Africa
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -1119,11 +1093,7 @@
 # See Africa/Johannesburg.
 
 # 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
+# See Africa/Nairobi.
 
 # Togo
 # See Africa/Abidjan.
@@ -1229,12 +1199,7 @@
 			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
+# See Africa/Nairobi.
 
 # Zambia
 # Zimbabwe
--- a/make/data/tzdata/asia	Wed Nov 19 15:29:32 2014 -0800
+++ b/make/data/tzdata/asia	Mon Dec 01 11:37:49 2014 -0800
@@ -29,20 +29,19 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2013-08-11):
+# From Paul Eggert (2014-10-31):
 #
-# A good source for time zone historical data outside the U.S. is
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -1686,44 +1685,70 @@
 # Korea (North and South)
 
 # From Annie I. Bang (2006-07-10):
-# 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.
+# http://www.koreaherald.com/view.php?ud=200607100012
+# Korea ran a daylight saving program from 1949-61 but stopped it
+# during the 1950-53 Korean War.  The system was temporarily enforced
+# between 1987 and 1988 ...
 
-# From Shanks & Pottenger:
+# From Sanghyuk Jung (2014-10-29):
+# http://mm.icann.org/pipermail/tz/2014-October/021830.html
+# According to the Korean Wikipedia
+# http://ko.wikipedia.org/wiki/한국_표준시
+# [oldid=12896437 2014-09-04 08:03 UTC]
+# DST in Republic of Korea was as follows....  And I checked old
+# newspapers in Korean, all articles correspond with data in Wikipedia.
+# For example, the article in 1948 (Korean Language) proved that DST
+# started at June 1 in that year.  For another example, the article in
+# 1988 said that DST started at 2:00 AM in that year.
+
 # 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
+Rule	ROK	1948	only	-	Jun	 1	0:00	1:00	D
+Rule	ROK	1948	only	-	Sep	13	0:00	0	S
+Rule	ROK	1949	only	-	Apr	 3	0:00	1:00	D
+Rule	ROK	1949	1951	-	Sep	Sun>=8	0:00	0	S
+Rule	ROK	1950	only	-	Apr	 1	0:00	1:00	D
+Rule	ROK	1951	only	-	May	 6	0:00	1:00	D
+Rule	ROK	1955	only	-	May	 5	0:00	1:00	D
+Rule	ROK	1955	only	-	Sep	 9	0:00	0	S
+Rule	ROK	1956	only	-	May	20	0:00	1:00	D
+Rule	ROK	1956	only	-	Sep	30	0:00	0	S
+Rule	ROK	1957	1960	-	May	Sun>=1	0:00	1:00	D
+Rule	ROK	1957	1960	-	Sep	Sun>=18	0:00	0	S
+Rule	ROK	1987	1988	-	May	Sun>=8	2:00	1:00	D
+Rule	ROK	1987	1988	-	Oct	Sun>=8	3:00	0	S
 
-# From Paul Eggert (2014-07-01):
-# The following entries are from Shanks & Pottenger, except that I
-# guessed that time zone abbreviations through 1945 followed the same
+# From Paul Eggert (2014-10-30):
+# The Korean Wikipedia entry gives the following sources for UT offsets:
+#
+# 1908: Official Journal Article No. 3994 (Edict No. 5)
+# 1912: Governor-General of Korea Official Gazette Issue No. 367
+#       (Announcement No. 338)
+# 1954: Presidential Decree No. 876 (1954-03-17)
+# 1961: Law No. 676 (1961-08-07)
+# 1987: Law No. 3919 (1986-12-31)
+#
+# The Wikipedia entry also has confusing information about a change
+# to UT+9 in April 1910, but then what would be the point of the later change
+# to UT+9 on 1912-01-01?  Omit the 1910 change for now.
+#
+# I guessed that time zone abbreviations through 1945 followed the same
 # rules as discussed under Taiwan, with nominal switches from JST to KST
 # when the respective cities were taken over by the Allies after WWII.
+#
+# For Pyongyang we have no information; guess no changes since World War II.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Seoul	8:27:52	-	LMT	1890
-			8:30	-	KST	1904 Dec
-			9:00	-	JCST	1928
-			8:30	-	KST	1932
+Zone	Asia/Seoul	8:27:52	-	LMT	1908 Apr  1
+			8:30	-	KST	1912 Jan  1
 			9:00	-	JCST	1937 Oct  1
 			9:00	-	JST	1945 Sep  8
 			9:00	-	KST	1954 Mar 21
-			8:00	ROK	K%sT	1961 Aug 10
-			8:30	-	KST	1968 Oct
+			8:30	ROK	K%sT	1961 Aug 10
 			9:00	ROK	K%sT
-Zone	Asia/Pyongyang	8:23:00 -	LMT	1890
-			8:30	-	KST	1904 Dec
-			9:00	-	JCST	1928
-			8:30	-	KST	1932
+Zone	Asia/Pyongyang	8:23:00 -	LMT	1908 Apr  1
+			8:30	-	KST	1912 Jan  1
 			9:00	-	JCST	1937 Oct  1
 			9:00	-	JST	1945 Aug 24
-			9:00	-	KST	1954 Mar 21
-			8:00	-	KST	1961 Aug 10
 			9:00	-	KST
 
 ###############################################################################
--- a/make/data/tzdata/australasia	Wed Nov 19 15:29:32 2014 -0800
+++ b/make/data/tzdata/australasia	Mon Dec 01 11:37:49 2014 -0800
@@ -820,19 +820,19 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2013-02-21):
-# A good source for time zone historical data outside the U.S. is
+# From Paul Eggert (2014-10-31):
+#
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
--- a/make/data/tzdata/europe	Wed Nov 19 15:29:32 2014 -0800
+++ b/make/data/tzdata/europe	Mon Dec 01 11:37:49 2014 -0800
@@ -29,16 +29,19 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2014-05-31):
-# A good source for time zone historical data outside the U.S. is
+# From Paul Eggert (2014-10-31):
+#
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
@@ -310,6 +313,14 @@
 #   "Timeball on the ballast office is down.  Dunsink time."
 #   -- James Joyce, Ulysses
 
+# "Countess Markievicz ... claimed that the [1916] abolition of Dublin Mean Time
+# was among various actions undertaken by the 'English' government that
+# would 'put the whole country into the SF (Sinn Féin) camp'.  She claimed
+# Irish 'public feeling (was) outraged by forcing of English time on us'."
+# -- Parsons M. Dublin lost its time zone - and 25 minutes - after 1916 Rising.
+# Irish Times 2014-10-27.
+# http://www.irishtimes.com/news/politics/dublin-lost-its-time-zone-and-25-minutes-after-1916-rising-1.1977411
+
 # From Joseph S. Myers (2005-01-26):
 # Irish laws are available online at <http://www.irishstatutebook.ie>.
 # These include various relating to legal time, for example:
@@ -617,6 +628,7 @@
 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	-
+# As described below, Russia's 2014 change affects Zone data, not Rule data.
 
 # From Alexander Krivenyshev (2011-06-14):
 # According to Kremlin press service, Russian President Dmitry Medvedev
--- a/make/data/tzdata/leapseconds	Wed Nov 19 15:29:32 2014 -0800
+++ b/make/data/tzdata/leapseconds	Mon Dec 01 11:37:49 2014 -0800
@@ -33,8 +33,8 @@
 # The NTP Timescale and Leap Seconds
 # http://www.eecis.udel.edu/~mills/leap.html
 
-# The International Earth Rotation Service periodically uses leap seconds
-# to keep UTC to within 0.9 s of UT1
+# The International Earth Rotation and Reference Systems 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 <http://dx.doi.org/10.1109/5.84965>.
--- a/make/data/tzdata/northamerica	Wed Nov 19 15:29:32 2014 -0800
+++ b/make/data/tzdata/northamerica	Mon Dec 01 11:37:49 2014 -0800
@@ -1014,19 +1014,19 @@
 ################################################################################
 
 
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data outside the U.S. is
+# From Paul Eggert (2014-10-31):
+#
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # Other sources occasionally used include:
 #
@@ -3154,13 +3154,17 @@
 # From Paul Eggert (2014-08-19):
 # The 2014-08-13 Cabinet meeting decided to stay on UTC-4 year-round.  See:
 # http://tcweeklynews.com/daylight-savings-time-to-be-maintained-p5353-127.htm
-# Model this as a switch from EST/EDT to AST on 2014-11-02 at 02:00.
+# Model this as a switch from EST/EDT to AST ...
+# From Chris Walton (2014-11-04):
+# ... the TCI government appears to have delayed the switch to
+# "permanent daylight saving time" by one year....
+# http://tcweeklynews.com/time-change-to-go-ahead-this-november-p5437-127.htm
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Grand_Turk	-4:44:32 -	LMT	1890
 			-5:07:11 -	KMT	1912 Feb # Kingston Mean Time
 			-5:00	-	EST	1979
-			-5:00	US	E%sT	2014 Nov  2  2:00
+			-5:00	US	E%sT	2015 Nov Sun>=1 2:00
 			-4:00	-	AST
 
 # British Virgin Is
--- a/make/data/tzdata/southamerica	Wed Nov 19 15:29:32 2014 -0800
+++ b/make/data/tzdata/southamerica	Mon Dec 01 11:37:49 2014 -0800
@@ -29,23 +29,23 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data outside the U.S. is
+# From Paul Eggert (2014-10-31):
+#
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
-#
-# For data circa 1899, a common source is:
-# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94.
-# http://www.jstor.org/stable/1774359
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
-# Except where otherwise noted, Shanks & Pottenger is the source for
-# entries through 1990, and IATA SSIM is the source for entries afterwards.
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94.
+# http://www.jstor.org/stable/1774359
 #
 # 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
--- a/src/share/classes/sun/awt/resources/awt_ja.properties	Wed Nov 19 15:29:32 2014 -0800
+++ b/src/share/classes/sun/awt/resources/awt_ja.properties	Mon Dec 01 11:37:49 2014 -0800
@@ -176,8 +176,8 @@
 AWT.InputMethodLanguage.ja=\u65E5\u672C\u8A9E
 AWT.InputMethodLanguage.ko=\u97D3\u56FD\u8A9E
 AWT.InputMethodLanguage.zh=\u4E2D\u56FD\u8A9E
-AWT.InputMethodLanguage.zh_CN=\u4E2D\u56FD\u8A9E(\u7C21\u4F53\u5B57)
-AWT.InputMethodLanguage.zh_TW=\u4E2D\u56FD\u8A9E(\u7E41\u4F53\u5B57)
+AWT.InputMethodLanguage.zh_CN=\u7C21\u4F53\u5B57\u4E2D\u56FD\u8A9E
+AWT.InputMethodLanguage.zh_TW=\u7E41\u4F53\u5B57\u4E2D\u56FD\u8A9E
 AWT.InputMethodCreationFailed={0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u7406\u7531: {1}
 
 # Property to select between on-the-spot and below-the-spot
--- a/src/share/classes/sun/launcher/resources/launcher_de.properties	Wed Nov 19 15:29:32 2014 -0800
+++ b/src/share/classes/sun/launcher/resources/launcher_de.properties	Mon Dec 01 11:37:49 2014 -0800
@@ -34,7 +34,7 @@
 java.launcher.ergo.message2  =\                  weil die Ausf\u00FChrung auf einem Server-Class-Rechner erfolgt.\n
 
 # Translators please note do not translate the options themselves
-java.launcher.opt.footer     =\    -cp <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n    -classpath <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n                  Eine durch {0} getrennte Liste mit Verzeichnissen, JAR-Archiven\n                  und ZIP-Archiven zur Suche nach Klassendateien.\n    -D<name>=<value>\n                  Legt eine Systemeigenschaft fest\n    -verbose:[class|gc|jni]\n                  Aktiviert die Verbose-Ausgabe\n    -version      Druckt Produktversion und beendet das Programm\n    -version:<value>\n                  Erfordert die angegebene Version zur Ausf\u00FChrung\n    -showversion  Druckt Produktversion und f\u00E4hrt fort\n    -jre-restrict-search | -no-jre-restrict-search\n                  Bezieht private JREs des Benutzers in Versionssuche ein bzw. schlie\u00DFt sie aus\n    -? -help      Druckt diese Hilfemeldung\n    -X            Druckt Hilfe zu Nicht-Standardoptionen\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  Aktiviert Assertionen mit angegebener Granularit\u00E4t\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  Deaktiviert Assertionen mit angegebener Granularit\u00E4t\n    -esa | -enablesystemassertions\n                  Aktiviert Systemassertionen\n    -dsa | -disablesystemassertions\n                  Deaktiviert Systemassertionen\n    -agentlib:<libname>[=<options>]\n                  L\u00E4dt native Agent Library <libname>, z.B. -agentlib:hprof\n                  siehe auch -agentlib:jdwp=help und -agentlib:hprof=help\n    -agentpath:<pathname>[=<options>]\n                  L\u00E4dt native Agent Library nach vollem Pfadnamen\n    -javaagent:<jarpath>[=<options>]\n                  L\u00E4dt Java-Programmiersprachen-Agent, siehe java.lang.instrument\n    -splash:<imagepath>\n                  Zeigt Startbildschirm mit angegebenem Bild\nWeitere Einzelheiten finden Sie unter http://www.oracle.com/technetwork/java/javase/documentation/index.html
+java.launcher.opt.footer     =\    -cp <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n    -classpath <Klassensuchpfad von Verzeichnissen und ZIP-/JAR-Dateien>\n                  Eine durch {0} getrennte Liste mit Verzeichnissen, JAR-Archiven\n                  und ZIP-Archiven zur Suche nach Klassendateien.\n    -D<name>=<value>\n                  Legt eine Systemeigenschaft fest\n    -verbose:[class|gc|jni]\n                  Aktiviert die Verbose-Ausgabe\n    -version      Druckt Produktversion und beendet das Programm\n    -version:<value>\n                  Erfordert die angegebene Version zur Ausf\u00FChrung\n    -showversion  Druckt Produktversion und f\u00E4hrt fort\n    -jre-restrict-search | -no-jre-restrict-search\n                  Bezieht private JREs des Benutzers in Versionssuche ein bzw. schlie\u00DFt sie aus\n    -? -help      Druckt diese Hilfemeldung\n    -X            Druckt Hilfe zu Nicht-Standardoptionen\n    -ea[:<packagename>...|:<classname>]\n    -enableassertions[:<packagename>...|:<classname>]\n                  Aktiviert Assertions mit angegebener Granularit\u00E4t\n    -da[:<packagename>...|:<classname>]\n    -disableassertions[:<packagename>...|:<classname>]\n                  Deaktiviert Assertions mit angegebener Granularit\u00E4t\n    -esa | -enablesystemassertions\n                  Aktiviert Systemassertionen\n    -dsa | -disablesystemassertions\n                  Deaktiviert Systemassertionen\n    -agentlib:<libname>[=<options>]\n                  L\u00E4dt native Agent Library <libname>, z.B. -agentlib:hprof\n                  siehe auch -agentlib:jdwp=help und -agentlib:hprof=help\n    -agentpath:<pathname>[=<options>]\n                  L\u00E4dt native Agent Library nach vollem Pfadnamen\n    -javaagent:<jarpath>[=<options>]\n                  L\u00E4dt Java-Programmiersprachen-Agent, siehe java.lang.instrument\n    -splash:<imagepath>\n                  Zeigt Startbildschirm mit angegebenem Bild\nWeitere Einzelheiten finden Sie unter http://www.oracle.com/technetwork/java/javase/documentation/index.html
 
 # Translators please note do not translate the options themselves
 java.launcher.X.usage=\    -Xmixed           Ausf\u00FChrung im gemischten Modus (Standard)\n    -Xint             Nur Ausf\u00FChrung im interpretierten Modus\n    -Xbootclasspath:<Verzeichnisse und ZIP-/JAR-Dateien durch {0} getrennt>\n                      Legt Suchpfad f\u00FCr Bootstrap-Klassen und Ressourcen fest\n    -Xbootclasspath/a:<Verzeichnisse und ZIP-/JAR-Dateien durch {0} getrennt>\n                      H\u00E4ngt an das Ende des Bootstrap Classpath an\n    -Xbootclasspath/p:<Verzeichnisse und ZIP-/JAR-Dateien durch {0} getrennt>\n                      Stellt Bootstrap Classpath voran\n    -Xdiag            Zeigt zus\u00E4tzliche Diagnosemeldungen an\n    -Xnoclassgc       Deaktiviert Klassen-Garbage Collection\n    -Xincgc           Aktiviert inkrementelle Garbage Collection\n    -Xloggc:<file>    Loggt GC-Status in einer Datei mit Zeitstempeln\n    -Xbatch           Deaktiviert Hintergrundkompilierung\n    -Xms<size>        Legt anf\u00E4ngliche Java Heap-Gr\u00F6\u00DFe fest\n    -Xmx<size>        Legt maximale Java Heap-Gr\u00F6\u00DFe fest\n    -Xss<size>        Legt Java-Threadstackgr\u00F6\u00DFe fest\n    -Xprof            Gibt CPU-Profiling-Daten aus\n    -Xfuture          Aktiviert strengste Pr\u00FCfungen, antizipiert zuk\u00FCnftigen Standardwert\n    -Xrs              Reduziert Verwendung von BS-Signalen durch Java/VM (siehe Dokumentation)\n    -Xcheck:jni       F\u00FChrt zus\u00E4tzliche Pr\u00FCfungen f\u00FCr JNI-Funktionen durch\n    -Xshare:off       Kein Versuch, gemeinsame Klassendaten zu verwenden\n    -Xshare:auto      Verwendet gemeinsame Klassendaten, wenn m\u00F6glich (Standard)\n    -Xshare:on        Erfordert die Verwendung gemeinsamer Klassendaten, sonst verl\u00E4uft der Vorgang nicht erfolgreich.\n    -XshowSettings    Zeigt alle Einstellungen und f\u00E4hrt fort\n    -XshowSettings:all\n                      Zeigt alle Einstellungen und f\u00E4hrt fort\n    -XshowSettings:vm Zeigt alle VM-bezogenen Einstellungen und f\u00E4hrt fort\n    -XshowSettings:properties\n                      Zeigt alle Eigenschaftseinstellungen und f\u00E4hrt fort\n    -XshowSettings:locale\n                      Zeigt alle gebietsschemabezogenen Einstellungen und f\u00E4hrt fort\n\nDie -X-Optionen sind keine Standardoptionen und k\u00F6nnen ohne Vorank\u00FCndigung ge\u00E4ndert werden.\n
--- a/src/windows/native/sun/management/OperatingSystemImpl.c	Wed Nov 19 15:29:32 2014 -0800
+++ b/src/windows/native/sun/management/OperatingSystemImpl.c	Mon Dec 01 11:37:49 2014 -0800
@@ -53,8 +53,6 @@
 typedef unsigned __int32 juint;
 typedef unsigned __int64 julong;
 
-typedef enum boolean_values { false=0, true=1};
-
 static void set_low(jlong* value, jint low) {
     *value &= (jlong)0xffffffff << 32;
     *value |= (jlong)(julong)(juint)low;
@@ -66,22 +64,22 @@
 }
 
 static jlong jlong_from(jint h, jint l) {
-  jlong result = 0; // initialization to avoid warning
-  set_high(&result, h);
-  set_low(&result,  l);
-  return result;
+    jlong result = 0; // initialization to avoid warning
+    set_high(&result, h);
+    set_low(&result,  l);
+    return result;
 }
 
 static HANDLE main_process;
 
-int perfiInit(void);
+static void perfInit(void);
 
 JNIEXPORT void JNICALL
 Java_sun_management_OperatingSystemImpl_initialize
   (JNIEnv *env, jclass cls)
 {
     main_process = GetCurrentProcess();
-     perfiInit();
+    perfInit();
 }
 
 JNIEXPORT jlong JNICALL
@@ -155,26 +153,7 @@
     return (jlong) ms.ullTotalPhys;
 }
 
-// Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
-// Let's just ignore it, since we make sure we have enough buffer anyway.
-static int
-pdh_fail(PDH_STATUS pdhStat) {
-    return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
-}
-
-// INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
-//       http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
-// The index value for the base system counters and objects like processor,
-// process, thread, memory, and so forth are always the same irrespective
-// of the localized version of the operating system or service pack installed.
-#define PDH_PROCESSOR_IDX        ((DWORD) 238)
-#define PDH_PROCESSOR_TIME_IDX        ((DWORD)   6)
-#define PDH_PRIV_PROCESSOR_TIME_IDX ((DWORD) 144)
-#define PDH_PROCESS_IDX            ((DWORD) 230)
-#define PDH_ID_PROCESS_IDX        ((DWORD) 784)
-#define PDH_CONTEXT_SWITCH_RATE_IDX ((DWORD) 146)
-#define PDH_SYSTEM_IDX            ((DWORD)   2)
-#define PDH_VIRTUAL_BYTES_IDX        ((DWORD) 174)
+/* Performance Data Helper API (PDH) support */
 
 typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(
                            HQUERY      hQuery,
@@ -183,48 +162,44 @@
                            HCOUNTER    *phCounter
                            );
 typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)(
-                          LPCWSTR     szDataSource,
-                          DWORD       dwUserData,
-                          HQUERY      *phQuery
-                          );
+                           LPCWSTR     szDataSource,
+                           DWORD       dwUserData,
+                           HQUERY      *phQuery
+                           );
+typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
+                           HQUERY      hQuery
+                           );
+
+typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
+                           LPCTSTR     szDataSource,
+                           LPCTSTR     szMachineName,
+                           LPCTSTR     szObjectName,
+                           LPTSTR      mszCounterList,
+                           LPDWORD     pcchCounterListLength,
+                           LPTSTR      mszInstanceList,
+                           LPDWORD     pcchInstanceListLength,
+                           DWORD       dwDetailLevel,
+                           DWORD       dwFlags
+                           );
+typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
+                           HCOUNTER   hCounter
+                           );
+typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
+                           LPCSTR     szMachineName,
+                           DWORD      dwNameIndex,
+                           LPSTR      szNameBuffer,
+                           LPDWORD    pcchNameBufferSize
+                           );
 typedef DWORD (WINAPI *PdhCloseQueryFunc)(
                       HQUERY      hQuery
                       );
-typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
-                             HQUERY      hQuery
-                             );
+
 typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)(
-                            HCOUNTER                hCounter,
-                            DWORD                   dwFormat,
-                            LPDWORD                 lpdwType,
-                            PPDH_FMT_COUNTERVALUE   pValue
-                            );
-typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
-                            LPCTSTR    szDataSource,
-                            LPCTSTR    szMachineName,
-                            LPCTSTR    szObjectName,
-                            LPTSTR     mszCounterList,
-                            LPDWORD    pcchCounterListLength,
-                            LPTSTR     mszInstanceList,
-                            LPDWORD    pcchInstanceListLength,
-                            DWORD      dwDetailLevel,
-                            DWORD      dwFlags
-                            );
-typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
-                          HCOUNTER  hCounter
-                          );
-typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
-                              LPCSTR  szMachineName,
-                              DWORD   dwNameIndex,
-                              LPSTR   szNameBuffer,
-                              LPDWORD pcchNameBufferSize
-                              );
-typedef PDH_STATUS (WINAPI *PdhMakeCounterPathFunc)(
-                            PDH_COUNTER_PATH_ELEMENTS *pCounterPathElements,
-                            LPTSTR szFullPathBuffer,
-                            LPDWORD pcchBufferSize,
-                            DWORD dwFlags
-                            );
+                      HCOUNTER                hCounter,
+                      DWORD                   dwFormat,
+                      LPDWORD                 lpdwType,
+                      PPDH_FMT_COUNTERVALUE   pValue
+                      );
 
 static PdhAddCounterFunc PdhAddCounter_i;
 static PdhOpenQueryFunc PdhOpenQuery_i;
@@ -234,76 +209,757 @@
 static PdhEnumObjectItemsFunc PdhEnumObjectItems_i;
 static PdhRemoveCounterFunc PdhRemoveCounter_i;
 static PdhLookupPerfNameByIndexFunc PdhLookupPerfNameByIndex_i;
-static PdhMakeCounterPathFunc PdhMakeCounterPath_i;
 
-static HANDLE thisProcess;
-static double cpuFactor;
-static DWORD  num_cpus;
-
-#define FT2JLONG(X)  ((((jlong)X.dwHighDateTime) << 32) | ((jlong)X.dwLowDateTime))
-#define COUNTER_BUF_SIZE 256
-// Min time between query updates.
-#define MIN_UPDATE_INTERVAL 500
-#define CONFIG_SUCCESSFUL 0
-
-/**
+/*
  * Struct for PDH queries.
  */
 typedef struct {
     HQUERY      query;
-    uint64_t      lastUpdate; // Last time query was updated (current millis).
+    uint64_t    lastUpdate; // Last time query was updated (ticks)
 } UpdateQueryS, *UpdateQueryP;
 
-/**
- * Struct for the processor load counters.
+// Min time between query updates (ticks)
+static const int MIN_UPDATE_INTERVAL = 500;
+
+/*
+ * Struct for a PDH query with multiple counters.
  */
 typedef struct {
-    UpdateQueryS      query;
-    HCOUNTER*      counters;
-    int          noOfCounters;
+    UpdateQueryS  query;
+    HCOUNTER*     counters;
+    int           noOfCounters;
 } MultipleCounterQueryS, *MultipleCounterQueryP;
 
-/**
- * Struct for the jvm process load counter.
+/*
+ * Struct for a PDH query with a single counter.
  */
 typedef struct {
-    UpdateQueryS      query;
+    UpdateQueryS  query;
     HCOUNTER      counter;
 } SingleCounterQueryS, *SingleCounterQueryP;
 
-static char* getProcessPDHHeader(void);
 
-/**
- * Currently available counters.
+typedef struct {
+    CRITICAL_SECTION cs;
+    DWORD owningThread;
+    DWORD recursionCount;
+} PdhCriticalSectionS, *PdhCriticalSectionP;
+
+static PdhCriticalSectionS initializationLock;
+
+static void InitializePdhCriticalSection(PdhCriticalSectionP criticalSection) {
+    assert(criticalSection);
+
+    InitializeCriticalSection(&criticalSection->cs);
+    criticalSection->owningThread = 0;
+    criticalSection->recursionCount = 0;
+}
+
+static void EnterPdhCriticalSection(PdhCriticalSectionP criticalSection) {
+    assert(criticalSection);
+
+    EnterCriticalSection(&criticalSection->cs);
+    criticalSection->recursionCount++;
+    if (!criticalSection->owningThread) {
+        criticalSection->owningThread = GetCurrentThreadId();
+    }
+}
+
+static void LeavePdhCriticalSection(PdhCriticalSectionP criticalSection) {
+    assert(criticalSection);
+    assert(GetCurrentThreadId() == criticalSection->owningThread);
+    assert(criticalSection->recursionCount >= 1);
+
+    criticalSection->recursionCount--;
+    if (!criticalSection->recursionCount) {
+        criticalSection->owningThread = 0;
+    }
+    LeaveCriticalSection(&criticalSection->cs);
+}
+
+/*
+ * INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
+ *   http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
+ * The index value for the base system counters and objects like processor,
+ * process, thread, memory, and so forth are always the same irrespective
+ * of the localized version of the operating system or service pack installed.
+ * To find the correct index for an object or counter, inspect the registry key/value:
+ * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter]
  */
-static SingleCounterQueryS cntCtxtSwitchRate;
-static SingleCounterQueryS cntVirtualSize;
-static SingleCounterQueryS cntProcLoad;
-static SingleCounterQueryS cntProcSystemLoad;
-static MultipleCounterQueryS multiCounterCPULoad;
+static const DWORD PDH_PROCESSOR_IDX = 238;
+static const DWORD PDH_PROCESSOR_TIME_IDX = 6;
+static const DWORD PDH_PROCESS_IDX = 230;
+static const DWORD PDH_ID_PROCESS_IDX = 784;
 
-static CRITICAL_SECTION processHeaderLock;
-static CRITICAL_SECTION initializationLock;
+/* useful pdh fmt's */
+static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s";
+static const size_t OBJECT_COUNTER_FMT_LEN = 2;
+static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s";
+static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4;
+static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s";
+static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5;
 
-/**
- * Initialize the perf module at startup.
+static const char* pdhProcessImageName = NULL; /* "java" */
+static char* pdhIDProcessCounterFmt = NULL;    /* "\Process(java#%d)\ID Process" */
+
+static int numberOfJavaProcessesAtInitialization = 0;
+
+/*
+ * Currently used CPU queries/counters and variables
  */
-int
-perfiInit(void)
-{
-    InitializeCriticalSection(&processHeaderLock);
-    InitializeCriticalSection(&initializationLock);
+static SingleCounterQueryP processTotalCPULoad = NULL;
+static MultipleCounterQueryP multiCounterCPULoad = NULL;
+static double cpuFactor = .0;
+static DWORD  numCpus = 0;
+
+/*
+ * Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
+ * Let's just ignore it, since we make sure we have enough buffer anyway.
+ */
+static int
+pdhFail(PDH_STATUS pdhStat) {
+    return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
+}
+
+static const char*
+allocateAndCopy(const char* const originalString) {
+    size_t len;
+    char* allocatedString;
+
+    assert(originalString);
+
+    len = strlen(originalString);
+
+    allocatedString = malloc(len + 1);
+
+    if (!allocatedString) {
+        return NULL;
+    }
+
+    strncpy(allocatedString, originalString, len);
+    allocatedString[len] = '\0';
+
+    return allocatedString;
+}
+
+/*
+ * Allocates memory into the supplied pointer and
+ * fills it with the localized PDH artifact description, if indexed correctly.
+ * Caller owns the memory from the point of returning from this function.
+ *
+ * @param index    the PDH counter index as specified in the registry
+ * @param ppBuffer pointer to a char*.
+ * @return         0 if successful, negative on failure.
+ */
+static int
+lookupNameByIndex(DWORD index, char** ppBuffer) {
+    DWORD size;
+
+    assert(ppBuffer);
+
+    /* determine size needed */
+    if (PdhLookupPerfNameByIndex_i(NULL, index, NULL, &size) != PDH_MORE_DATA) {
+      /* invalid index? */
+      return -1;
+    }
+
+    *ppBuffer = malloc((size_t)size);
+
+    if (!*ppBuffer) {
+        return -1;
+    }
+
+    if (PdhLookupPerfNameByIndex_i(NULL, index, *ppBuffer, &size) != ERROR_SUCCESS) {
+        free(*ppBuffer);
+        *ppBuffer = NULL;
+        return -1;
+    }
+
+    /* windows vista does not null-terminate the string
+     * (although the docs says it will) */
+    (*ppBuffer)[size - 1] = '\0';
+
     return 0;
 }
 
-/**
+/*
+* Construct a fully qualified PDH path
+*
+* @param objectName   a PDH Object string representation (required)
+* @param counterName  a PDH Counter string representation (required)
+* @param imageName    a process image name string, ex. "java" (opt)
+* @param instance     an instance string, ex. "0", "1", ... (opt)
+* @return             the fully qualified PDH path.
+*
+* Caller will own the returned malloc:ed string
+*/
+static const char*
+makeFullCounterPath(const char* const objectName,
+                    const char* const counterName,
+                    const char* const imageName,
+                    const char* const instance) {
+
+    size_t fullCounterPathLen;
+    char* fullCounterPath;
+
+    assert(objectName);
+    assert(counterName);
+
+    fullCounterPathLen = strlen(objectName);
+    fullCounterPathLen += strlen(counterName);
+
+    if (imageName) {
+        /*
+         * For paths using the "Process" Object.
+         *
+         * Examples:
+         * abstract: "\Process(imageName#instance)\Counter"
+         * actual:   "\Process(java#2)\ID Process"
+         */
+        fullCounterPathLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
+        fullCounterPathLen += strlen(imageName);
+
+        /*
+         * imageName must be passed together with an associated
+         * instance "number" ("0", "1", "2", ...).
+         * This is required in order to create valid "Process" Object paths.
+         *
+         * Examples: "\Process(java#0)", \Process(java#1"), ...
+         */
+        assert(instance);
+
+        fullCounterPathLen += strlen(instance);
+
+        fullCounterPath = malloc(fullCounterPathLen + 1);
+
+        if (!fullCounterPath) {
+            return NULL;
+        }
+
+        _snprintf(fullCounterPath,
+                  fullCounterPathLen,
+                  PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
+                  objectName,
+                  imageName,
+                  instance,
+                  counterName);
+    } else {
+        if (instance) {
+            /*
+             * For paths where the Object has multiple instances.
+             *
+             * Examples:
+             * abstract: "\Object(instance)\Counter"
+             * actual:   "\Processor(0)\% Privileged Time"
+             */
+            fullCounterPathLen += strlen(instance);
+            fullCounterPathLen += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN;
+        } else {
+            /*
+             * For "normal" paths.
+             *
+             * Examples:
+             * abstract: "\Object\Counter"
+             * actual:   "\Memory\Available Mbytes"
+             */
+            fullCounterPathLen += OBJECT_COUNTER_FMT_LEN;
+        }
+
+        fullCounterPath = malloc(fullCounterPathLen + 1);
+
+        if (!fullCounterPath) {
+            return NULL;
+        }
+
+        if (instance) {
+            _snprintf(fullCounterPath,
+                      fullCounterPathLen,
+                      OBJECT_WITH_INSTANCES_COUNTER_FMT,
+                      objectName,
+                      instance,
+                      counterName);
+        } else {
+            _snprintf(fullCounterPath,
+                      fullCounterPathLen,
+                      OBJECT_COUNTER_FMT,
+                      objectName,
+                      counterName);
+        }
+    }
+
+    fullCounterPath[fullCounterPathLen] = '\0';
+
+    return fullCounterPath;
+}
+
+/*
+ * Resolves an index for a PDH artifact to
+ * a localized, malloc:ed string representation.
+ * Caller will own the returned malloc:ed string.
+ *
+ * @param pdhArtifactIndex  PDH index
+ * @return                  malloc:ed string representation
+ *                          of the requested pdh artifact (localized).
+ *                          NULL on failure.
+ */
+static const char*
+getPdhLocalizedArtifact(DWORD pdhArtifactIndex) {
+    char* pdhLocalizedArtifactString;
+
+    if (lookupNameByIndex(pdhArtifactIndex,
+                          &pdhLocalizedArtifactString) != 0) {
+        return NULL;
+    }
+
+    return pdhLocalizedArtifactString;
+}
+
+static void
+pdhCleanup(HQUERY* const query, HCOUNTER* const counter) {
+    if (counter && *counter) {
+        PdhRemoveCounter_i(*counter);
+        *counter = NULL;
+    }
+    if (query && *query) {
+        PdhCloseQuery_i(*query);
+        *query = NULL;
+    }
+}
+
+static void
+destroySingleCounter(SingleCounterQueryP counterQuery) {
+    if (counterQuery) {
+        pdhCleanup(&counterQuery->query.query, &counterQuery->counter);
+    }
+}
+
+static void
+destroyMultiCounter(MultipleCounterQueryP multiCounterQuery) {
+    int i;
+    if (multiCounterQuery) {
+        if (multiCounterQuery->counters) {
+            for (i = 0; i < multiCounterQuery->noOfCounters; i++) {
+                pdhCleanup(NULL, &multiCounterQuery->counters[i]);
+            }
+            free(multiCounterQuery->counters);
+            multiCounterQuery->counters = NULL;
+        }
+        pdhCleanup(&multiCounterQuery->query.query, NULL);
+    }
+}
+
+static int
+openQuery(HQUERY* const query) {
+    assert(query);
+
+    if (PdhOpenQuery_i(NULL, 0, query) != ERROR_SUCCESS) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static int
+addCounter(HQUERY query,
+           const char* const fullCounterPath,
+           HCOUNTER* const counter) {
+
+    assert(fullCounterPath);
+    assert(counter);
+
+    if (PdhAddCounter_i(query,
+                        fullCounterPath,
+                        0,
+                        counter) != ERROR_SUCCESS) {
+        return -1;
+    }
+
+    return 0;
+}
+
+/*
+ * Sets up the supplied SingleCounterQuery to listen for the specified counter.
+ *
+ * @param counterQuery       the counter query to set up.
+ * @param fullCounterPath    the string specifying the full path to the counter.
+ * @returns                  0 if successful, negative on failure.
+ */
+static int
+initializeSingleCounterQuery(SingleCounterQueryP counterQuery,
+                             const char* const fullCounterPath) {
+    assert(counterQuery);
+    assert(fullCounterPath);
+
+    if (openQuery(&counterQuery->query.query) == 0) {
+        if (addCounter(counterQuery->query.query,
+                       fullCounterPath,
+                       &counterQuery->counter) == 0) {
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+/*
+ * Sets up a SingleCounterQuery
+ *
+ * param counter             the counter query to set up.
+ * param localizedObject     string representing the PDH object to query
+ * param localizedCounter    string representing the PDH counter to query
+ * param processImageName    if the counter query needs the process image name ("java")
+ * param instance            if the counter has instances, this is the instance ("\Processor(0)\")
+                                 where 0 is the instance
+ * param firstSampleOnInit   for counters that need two queries to yield their values,
+                                 the first query can be issued just after initialization
+ *
+ * @returns                   0 if successful, negative on failure.
+ */
+static int
+initializeSingleCounter(SingleCounterQueryP const counter,
+                        const char* const localizedObject,
+                        const char* const localizedCounter,
+                        const char* const processImageName,
+                        const char* const instance,
+                        BOOL firstSampleOnInit) {
+    int retValue = -1;
+
+    const char* fullCounterPath = makeFullCounterPath(localizedObject,
+                                                      localizedCounter,
+                                                      processImageName,
+                                                      instance);
+
+    if (fullCounterPath) {
+
+        assert(counter);
+
+        if (initializeSingleCounterQuery(counter, fullCounterPath) == 0) {
+            /*
+             * According to the MSDN documentation, rate counters must be read twice:
+             *
+             * "Obtaining the value of rate counters such as Page faults/sec requires that
+             *  PdhCollectQueryData be called twice, with a specific time interval between
+             *  the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to
+             *  implement the waiting period between the two calls to PdhCollectQueryData."
+             *
+             *  Take the first sample here already to allow for the next (first) "real" sample
+             *  to succeed.
+             */
+            if (firstSampleOnInit) {
+                PdhCollectQueryData_i(counter->query.query);
+            }
+
+            retValue = 0;
+        }
+        free((char*)fullCounterPath);
+    }
+
+    return retValue;
+}
+
+static void
+perfInit(void) {
+    InitializePdhCriticalSection(&initializationLock);
+}
+
+static int
+getProcessID() {
+    static int myPid = 0;
+    if (0 == myPid) {
+        myPid = _getpid();
+    }
+    return myPid;
+}
+
+/*
+ * Working against the Process object and it's related counters is inherently problematic
+ * when using the PDH API:
+ *
+ * For PDH, a process is not primarily identified by it's process id,
+ * but with a sequential number, for example \Process(java#0), \Process(java#1), ....
+ * The really bad part is that this list is reset as soon as one process exits:
+ * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc.
+ *
+ * The PDH query api requires a process identifier to be submitted when registering
+ * a query, but as soon as the list resets, the query is invalidated (since the name
+ * changed).
+ *
+ * Solution:
+ * The #number identifier for a Process query can only decrease after process creation.
+ *
+ * Therefore we create an array of counter queries for all process object instances
+ * up to and including ourselves:
+ *
+ * Ex. we come in as third process instance (java#2), we then create and register
+ * queries for the following Process object instances:
+ * java#0, java#1, java#2
+ *
+ * currentQueryIndexForProcess() keeps track of the current "correct" query
+ * (in order to keep this index valid when the list resets from underneath,
+ * ensure to call getCurrentQueryIndexForProcess() before every query involving
+ * Process object instance data).
+ */
+static int
+currentQueryIndexForProcess(void) {
+    HQUERY tmpQuery = NULL;
+    HCOUNTER handleCounter = NULL;
+    int retValue = -1;
+
+    assert(pdhProcessImageName);
+    assert(pdhIDProcessCounterFmt);
+
+    if (openQuery(&tmpQuery) == 0) {
+        int index;
+
+        /* iterate over all instance indexes and try to find our own pid */
+        for (index = 0; index < INT_MAX; ++index) {
+            char fullIDProcessCounterPath[MAX_PATH];
+            PDH_FMT_COUNTERVALUE counterValue;
+            PDH_STATUS res;
+
+            _snprintf(fullIDProcessCounterPath,
+                      MAX_PATH,
+                      pdhIDProcessCounterFmt,
+                      index);
+
+            if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) {
+                break;
+            }
+
+            res = PdhCollectQueryData_i(tmpQuery);
+
+            if (PDH_INVALID_HANDLE == res || PDH_NO_DATA == res) {
+                break;
+            }
+
+            PdhGetFormattedCounterValue_i(handleCounter,
+                                          PDH_FMT_LONG,
+                                          NULL,
+                                          &counterValue);
+            /*
+             * This check seems to be needed for Win2k SMP boxes, since
+             * they for some reason don't return PDH_NO_DATA for non existing
+             * counters.
+             */
+            if (counterValue.CStatus != PDH_CSTATUS_VALID_DATA) {
+                break;
+            }
+
+            if ((LONG)getProcessID() == counterValue.longValue) {
+                retValue = index;
+                break;
+            }
+        }
+    }
+
+    pdhCleanup(&tmpQuery, &handleCounter);
+
+    return retValue;
+}
+
+/*
+ * If successful, returns the #index corresponding to our PID
+ * as resolved by the pdh query:
+ * "\Process(java#index)\ID Process" (or localized equivalent)
+ *
+ * This function should be called before attempting to read
+ * from any Process related counter(s), and the return value
+ * is the index to be used for indexing an array of Process object query's:
+ *
+ * Example:
+ * processTotalCPULoad[currentQueryIndex].query
+ *
+ * Returns -1 on failure.
+ */
+static int
+getCurrentQueryIndexForProcess() {
+    int currentQueryIndex = currentQueryIndexForProcess();
+
+    assert(currentQueryIndex >= 0 &&
+           currentQueryIndex < numberOfJavaProcessesAtInitialization);
+
+    return currentQueryIndex;
+}
+
+/*
+ * Returns the PDH string identifying the current process image name.
+ * Use this name as a qualifier when getting counters from the PDH Process Object
+ * representing your process.
+
+ * Example:
+ * "\Process(java#0)\Virtual Bytes" - where "java" is the PDH process
+ * image name.
+ *
+ * Please note that the process image name is not necessarily "java",
+ * hence the use of GetModuleFileName() to detect the process image name.
+ *
+ * @return   the process image name to be used when retrieving
+ *           PDH counters from the current process. The caller will
+             own the returned malloc:ed string. NULL if failure.
+ */
+static const char*
+getPdhProcessImageName() {
+    char moduleName[MAX_PATH];
+    char* processImageName;
+    char* dotPos;
+
+    // Find our module name and use it to extract the image name used by PDH
+    DWORD getmfnReturn = GetModuleFileName(NULL, moduleName, sizeof(moduleName));
+
+    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+        return NULL;
+    }
+
+    if (getmfnReturn >= MAX_PATH || 0 == getmfnReturn) {
+        return NULL;
+    }
+
+    processImageName = strrchr(moduleName, '\\'); //drop path
+    processImageName++;                           //skip slash
+    dotPos = strrchr(processImageName, '.');      //drop .exe
+    dotPos[0] = '\0';
+
+    return allocateAndCopy(processImageName);
+}
+
+/*
+ * Sets up the supplied MultipleCounterQuery to check on the processors via PDH CPU counters.
+ * TODO: Refactor and prettify as with the the SingleCounter queries
+ * if more MultipleCounterQueries are discovered/needed.
+ *
+ * @param multiCounterCPULoad  a pointer to a MultipleCounterQueryS, will be filled in with
+ *                             the necessary info to check the PDH processor counters.
+ * @return                     0 if successful, negative on failure.
+ */
+static int
+initializeMultipleCounterForCPUs(MultipleCounterQueryP multiCounterCPULoad) {
+    DWORD cSize = 0;
+    DWORD iSize = 0;
+    DWORD pCount;
+    DWORD index;
+    char* processor = NULL; //'Processor' == PDH_PROCESSOR_IDX
+    char* time = NULL;      //'Time' == PDH_PROCESSOR_TIME_IDX
+    char* instances = NULL;
+    char* tmp;
+    int   retValue = -1;
+    PDH_STATUS pdhStat;
+
+    if (lookupNameByIndex(PDH_PROCESSOR_IDX, &processor) != 0) {
+        goto end;
+    }
+
+    if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, &time) != 0) {
+        goto end;
+    }
+
+    //ok, now we have enough to enumerate all processors.
+    pdhStat = PdhEnumObjectItems_i(
+                                   NULL, // reserved
+                                   NULL, // local machine
+                                   processor, // object to enumerate
+                                   NULL, // pass in NULL buffers
+                                   &cSize, // and 0 length to get
+                                   NULL, // required size
+                                   &iSize, // of the buffers in chars
+                                   PERF_DETAIL_WIZARD, // counter detail level
+                                   0);
+
+    if (pdhFail(pdhStat)) {
+        goto end;
+    }
+
+    instances = calloc(iSize, 1);
+
+    if (!instances) {
+        goto end;
+    }
+
+    cSize = 0;
+
+    pdhStat = PdhEnumObjectItems_i(
+                                   NULL, // reserved
+                                   NULL, // local machine
+                                   processor, // object to enumerate
+                                   NULL, // pass in NULL buffers
+                                   &cSize,
+                                   instances, // now allocated to be filled in
+                                   &iSize, // and size is known
+                                   PERF_DETAIL_WIZARD, // counter detail level
+                                   0);
+
+    if (pdhFail(pdhStat)) {
+        goto end;
+    }
+
+    // enumerate the Processor instances ("\Processor(0)", "\Processor(1)", ..., "\Processor(_Total)")
+    for (pCount = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], pCount++);
+
+    assert(pCount == numCpus+1);
+
+    //ok, we now have the number of Processor instances - allocate an HCOUNTER for each
+    multiCounterCPULoad->counters = (HCOUNTER*)malloc(pCount * sizeof(HCOUNTER));
+
+    if (!multiCounterCPULoad->counters) {
+        goto end;
+    }
+
+    multiCounterCPULoad->noOfCounters = pCount;
+
+    if (openQuery(&multiCounterCPULoad->query.query) != 0) {
+        goto end;
+    }
+
+    // fetch instance and register its corresponding HCOUNTER with the query
+    for (index = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], ++index) {
+        const char* const fullCounterPath = makeFullCounterPath(processor, time, NULL, tmp);
+
+        if (!fullCounterPath) {
+            goto end;
+        }
+
+        retValue = addCounter(multiCounterCPULoad->query.query,
+                              fullCounterPath,
+                              &multiCounterCPULoad->counters[index]);
+
+        free((char*)fullCounterPath);
+
+        if (retValue != 0) {
+            goto end;
+        }
+    }
+
+    // Query once to initialize the counters which require at least two samples
+    // (like the % CPU usage) to calculate correctly.
+    PdhCollectQueryData_i(multiCounterCPULoad->query.query);
+
+  end:
+    if (processor) {
+        free(processor);
+    }
+
+    if (time) {
+        free(time);
+    }
+
+    if (instances) {
+        free(instances);
+    }
+
+    return retValue;
+}
+
+/*
  * Dynamically sets up function pointers to the PDH library.
  *
- * @return CONFIG_SUCCESSFUL on success, negative on failure.
+ * @param h  HMODULE for the PDH library
+ * @return   0 on success, negative on failure.
  */
 static int
-get_functions(HMODULE h, char *ebuf, size_t elen) {
-    // The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods
+bindPdhFunctionPointers(HMODULE h) {
+    assert(h);
+    assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+    /* The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods */
     PdhAddCounter_i         = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA");
     PdhOpenQuery_i         = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA");
     PdhCloseQuery_i         = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery");
@@ -312,42 +968,41 @@
     PdhEnumObjectItems_i         = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA");
     PdhRemoveCounter_i         = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter");
     PdhLookupPerfNameByIndex_i     = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA");
-    PdhMakeCounterPath_i         = (PdhMakeCounterPathFunc)GetProcAddress(h, "PdhMakeCounterPathA");
 
-    if (PdhAddCounter_i == NULL || PdhOpenQuery_i == NULL ||
-    PdhCloseQuery_i == NULL || PdhCollectQueryData_i == NULL ||
-    PdhGetFormattedCounterValue_i == NULL || PdhEnumObjectItems_i == NULL ||
-    PdhRemoveCounter_i == NULL || PdhLookupPerfNameByIndex_i == NULL || PdhMakeCounterPath_i == NULL)
+    if (!PdhAddCounter_i || !PdhOpenQuery_i ||
+        !PdhCloseQuery_i || !PdhCollectQueryData_i ||
+        !PdhGetFormattedCounterValue_i || !PdhEnumObjectItems_i ||
+        !PdhRemoveCounter_i || !PdhLookupPerfNameByIndex_i)
     {
-        _snprintf(ebuf, elen, "Required method could not be found.");
         return -1;
     }
-    return CONFIG_SUCCESSFUL;
+    return 0;
 }
 
-/**
+/*
  * Returns the counter value as a double for the specified query.
  * Will collect the query data and update the counter values as necessary.
  *
  * @param query       the query to update (if needed).
- * @param c          the counter to read.
+ * @param c           the counter to read.
  * @param value       where to store the formatted value.
  * @param format      the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc)
- * @return            CONFIG_SUCCESSFUL if no error
+ * @return            0 if no error
  *                    -1 if PdhCollectQueryData fails
  *                    -2 if PdhGetFormattedCounterValue fails
  */
 static int
 getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) {
-    clock_t now;
-    now = clock();
+    clock_t now = clock();
 
-    // Need to limit how often we update the query
-    // to mimise the heisenberg effect.
-    // (PDH behaves erratically if the counters are
-    // queried too often, especially counters that
-    // store and use values from two consecutive updates,
-    // like cpu load.)
+    /*
+     * Need to limit how often we update the query
+     * to minimize the Heisenberg effect.
+     * (PDH behaves erratically if the counters are
+     * queried too often, especially counters that
+     * store and use values from two consecutive updates,
+     * like cpu load.)
+     */
     if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) {
         if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) {
             return -1;
@@ -358,500 +1013,308 @@
     if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) {
         return -2;
     }
-    return CONFIG_SUCCESSFUL;
+
+    return 0;
 }
 
-/**
- * Places the resolved counter name of the counter at the specified index in the
- * supplied buffer. There must be enough space in the buffer to hold the counter name.
- *
- * @param index   the counter index as specified in the registry.
- * @param buf     the buffer in which to place the counter name.
- * @param size      the size of the counter name buffer.
- * @param ebuf    the error message buffer.
- * @param elen    the length of the error buffer.
- * @return        CONFIG_SUCCESSFUL if successful, negative on failure.
- */
 static int
-find_name(DWORD index, char *buf, DWORD size) {
-    PDH_STATUS res;
+allocateAndInitializePdhConstants() {
+    const char* pdhLocalizedProcessObject = NULL;
+    const char* pdhLocalizedIDProcessCounter = NULL;
+    size_t pdhIDProcessCounterFmtLen;
+    int currentQueryIndex;
+    int retValue = -1;
 
-    if ((res = PdhLookupPerfNameByIndex_i(NULL, index, buf, &size)) != ERROR_SUCCESS) {
+    assert(GetCurrentThreadId() == initializationLock.owningThread);
 
-        /* printf("Could not open counter %d: error=0x%08x", index, res); */
-        /* if (res == PDH_CSTATUS_NO_MACHINE) { */
-        /*      printf("User probably does not have sufficient privileges to use"); */
-        /*      printf("performance counters. If you are running on Windows 2003"); */
-        /*      printf("or Windows Vista, make sure the user is in the"); */
-        /*      printf("Performance Logs user group."); */
-        /* } */
+    assert(!pdhProcessImageName);
+    pdhProcessImageName = getPdhProcessImageName();
+    if (!pdhProcessImageName) {
+        goto end;
+    }
+
+    pdhLocalizedProcessObject = getPdhLocalizedArtifact(PDH_PROCESS_IDX);
+    if (!pdhLocalizedProcessObject) {
+        goto end;
+    }
+
+    pdhLocalizedIDProcessCounter = getPdhLocalizedArtifact(PDH_ID_PROCESS_IDX);
+    if (!pdhLocalizedIDProcessCounter) {
+        goto end;
+    }
+
+    assert(!pdhIDProcessCounterFmt);
+
+    pdhIDProcessCounterFmtLen = strlen(pdhProcessImageName);
+    pdhIDProcessCounterFmtLen += strlen(pdhLocalizedProcessObject);
+    pdhIDProcessCounterFmtLen += strlen(pdhLocalizedIDProcessCounter);
+    pdhIDProcessCounterFmtLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
+    pdhIDProcessCounterFmtLen += 2; // "%d"
+
+    assert(pdhIDProcessCounterFmtLen < MAX_PATH);
+    pdhIDProcessCounterFmt = malloc(pdhIDProcessCounterFmtLen + 1);
+    if (!pdhIDProcessCounterFmt) {
+        goto end;
+    }
+
+    /* "\Process(java#%d)\ID Process" */
+    _snprintf(pdhIDProcessCounterFmt,
+              pdhIDProcessCounterFmtLen,
+              PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
+              pdhLocalizedProcessObject,
+              pdhProcessImageName,
+              "%d",
+              pdhLocalizedIDProcessCounter);
+
+    pdhIDProcessCounterFmt[pdhIDProcessCounterFmtLen] = '\0';
+
+    assert(0 == numberOfJavaProcessesAtInitialization);
+    currentQueryIndex = currentQueryIndexForProcess();
+    if (-1 == currentQueryIndex) {
+        goto end;
+    }
+
+    numberOfJavaProcessesAtInitialization = currentQueryIndex + 1;
+    assert(numberOfJavaProcessesAtInitialization >= 1);
+
+    retValue = 0;
+
+  end:
+
+    if (pdhLocalizedProcessObject) {
+        free((char*)pdhLocalizedProcessObject);
+    }
+
+    if (pdhLocalizedIDProcessCounter) {
+        free((char*)pdhLocalizedIDProcessCounter);
+    }
+
+    return retValue;
+}
+
+static void
+deallocatePdhConstants() {
+    assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+    if (pdhProcessImageName) {
+        free((char*)pdhProcessImageName);
+        pdhProcessImageName = NULL;
+    }
+
+    if (pdhIDProcessCounterFmt) {
+      free(pdhIDProcessCounterFmt);
+      pdhIDProcessCounterFmt = NULL;
+    }
+
+    numberOfJavaProcessesAtInitialization = 0;
+}
+
+static int
+initializeCPUCounters() {
+    SYSTEM_INFO si;
+    char* localizedProcessObject;
+    char* localizedProcessorTimeCounter;
+    int i;
+    int retValue = -1;
+
+    assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+    assert(0 == numCpus);
+    GetSystemInfo(&si);
+    numCpus = si.dwNumberOfProcessors;
+    assert(numCpus >= 1);
+
+    /* Initialize the denominator for the jvm load calculations */
+    assert(.0 == cpuFactor);
+    cpuFactor = numCpus * 100;
+
+    if (lookupNameByIndex(PDH_PROCESS_IDX,
+                          &localizedProcessObject) == 0) {
+
+        if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX,
+                              &localizedProcessorTimeCounter) == 0) {
+
+            assert(processTotalCPULoad);
+            assert(pdhProcessImageName);
+
+            for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
+                char instanceIndexBuffer[32];
+                retValue = initializeSingleCounter(&processTotalCPULoad[i],
+                                                   localizedProcessObject,
+                                                   localizedProcessorTimeCounter,
+                                                   pdhProcessImageName,
+                                                   itoa(i, instanceIndexBuffer, 10),
+                                                   TRUE);
+                if (retValue != 0) {
+                    break;
+                }
+            }
+            free(localizedProcessorTimeCounter);
+        }
+        free(localizedProcessObject);
+    }
+
+    if (retValue != 0) {
         return -1;
     }
 
-    if (size == 0) {
-        /* printf("Failed to get counter name for %d: empty string", index); */
+    assert(multiCounterCPULoad);
+    return initializeMultipleCounterForCPUs(multiCounterCPULoad);
+}
+
+static void
+deallocateCPUCounters() {
+    int i;
+
+    assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+    if (processTotalCPULoad) {
+        for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
+            destroySingleCounter(&processTotalCPULoad[i]);
+        }
+        free(processTotalCPULoad);
+        processTotalCPULoad = NULL;
+    }
+
+    if (multiCounterCPULoad) {
+        destroyMultiCounter(multiCounterCPULoad);
+        free(multiCounterCPULoad);
+        multiCounterCPULoad = NULL;
+    }
+
+    cpuFactor = .0;
+    numCpus = 0;
+}
+
+static void
+pdhInitErrorHandler(HMODULE h) {
+    assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+    deallocatePdhConstants();
+
+    if (h) {
+        FreeLibrary(h);
+    }
+}
+
+/*
+ * Helper to initialize the PDH library, function pointers and constants.
+ *
+ * @return  0 if successful, negative on failure.
+ */
+static int
+pdhInit() {
+    static BOOL initialized = FALSE;
+    int retValue;
+
+    if (initialized) {
+        return 0;
+    }
+
+    retValue = 0;
+
+    EnterPdhCriticalSection(&initializationLock); {
+        if (!initialized) {
+            HMODULE h = NULL;
+            if ((h = LoadLibrary("pdh.dll")) == NULL) {
+                retValue = -1;
+            } else if (bindPdhFunctionPointers(h) < 0) {
+                retValue = -1;
+            } else if (allocateAndInitializePdhConstants() < 0) {
+                retValue = -1;
+            }
+
+            if (0 == retValue) {
+                initialized = TRUE;
+            } else {
+                pdhInitErrorHandler(h);
+            }
+        }
+    } LeavePdhCriticalSection(&initializationLock);
+
+    return retValue;
+}
+
+static int
+allocateCPUCounters() {
+    assert(GetCurrentThreadId() == initializationLock.owningThread);
+    assert(numberOfJavaProcessesAtInitialization >= 1);
+    assert(!processTotalCPULoad);
+    assert(!multiCounterCPULoad);
+
+    /*
+     * Create an array of Process object queries, for each instance
+     * up to and including our own (java#0, java#1, java#2, ...).
+     */
+    processTotalCPULoad = calloc(numberOfJavaProcessesAtInitialization,
+                                 sizeof(SingleCounterQueryS));
+
+    if (!processTotalCPULoad) {
         return -1;
     }
 
-    // windows vista does not null-terminate the string (allthough the docs says it will)
-    buf[size - 1] = '\0';
-    return CONFIG_SUCCESSFUL;
-}
+    multiCounterCPULoad = calloc(1, sizeof(MultipleCounterQueryS));
 
-/**
- * Sets up the supplied SingleCounterQuery to listen for the specified counter.
- * initPDH() must have been run prior to calling this function!
- *
- * @param counterQuery   the counter query to set up.
- * @param counterString  the string specifying the path to the counter.
- * @param ebuf           the error buffer.
- * @param elen           the length of the error buffer.
- * @returns              CONFIG_SUCCESSFUL if successful, negative on failure.
- */
-static int
-initSingleCounterQuery(SingleCounterQueryP counterQuery, char *counterString) {
-    if (PdhOpenQuery_i(NULL, 0, &counterQuery->query.query) != ERROR_SUCCESS) {
-        /* printf("Could not open query for %s", counterString); */
+    if (!multiCounterCPULoad) {
         return -1;
     }
-    if (PdhAddCounter_i(counterQuery->query.query, counterString, 0, &counterQuery->counter) != ERROR_SUCCESS) {
-        /* printf("Could not add counter %s for query", counterString); */
-        if (counterQuery->counter != NULL) {
-            PdhRemoveCounter_i(counterQuery->counter);
-        }
-        if (counterQuery->query.query != NULL) {
-            PdhCloseQuery_i(counterQuery->query.query);
-        }
-        memset(counterQuery, 0, sizeof(SingleCounterQueryS));
-        return -1;
-    }
-    return CONFIG_SUCCESSFUL;
-}
 
-/**
- * Sets up the supplied SingleCounterQuery to listen for the time spent
- * by the HotSpot process.
- *
- * @param counterQuery   the counter query to set up as a process counter.
- * @param ebuf           the error buffer.
- * @param elen           the length of the error buffer.
- * @returns              CONFIG_SUCCESSFUL if successful, negative on failure.
- */
-static int
-initProcLoadCounter(void) {
-    char time[COUNTER_BUF_SIZE];
-    char counter[COUNTER_BUF_SIZE*2];
-
-    if (find_name(PDH_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
-        return -1;
-    }
-    _snprintf(counter, sizeof(counter)-1, "%s\\%s", getProcessPDHHeader(), time);
-    return initSingleCounterQuery(&cntProcLoad, counter);
+    return 0;
 }
 
 static int
-initProcSystemLoadCounter(void) {
-    char time[COUNTER_BUF_SIZE];
-    char counter[COUNTER_BUF_SIZE*2];
+initializePdhCPUCounters() {
+    static BOOL initialized = FALSE;
+    int retValue;
 
-    if (find_name(PDH_PRIV_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
-        return -1;
+    if (initialized) {
+        return 0;
     }
-    _snprintf(counter, sizeof(counter)-1, "%s\\%s", getProcessPDHHeader(), time);
-    return initSingleCounterQuery(&cntProcSystemLoad, counter);
+
+    retValue = 0;
+
+    EnterPdhCriticalSection(&initializationLock); {
+        if (!initialized) {
+            if (pdhInit() < 0) {
+                retValue = -1;
+            }  else if (allocateCPUCounters() < 0) {
+                retValue = -1;
+            } else if (initializeCPUCounters() < 0) {
+                retValue = -1;
+            }
+
+            if (0 == retValue) {
+                initialized = TRUE;
+            } else {
+              deallocateCPUCounters();
+            }
+        }
+    } LeavePdhCriticalSection(&initializationLock);
+
+    return retValue;
 }
 
-/**
- * Sets up the supplied MultipleCounterQuery to check on the processors.
- * (Comment: Refactor and prettify as with the the SingleCounter queries
- * if more MultipleCounterQueries are discovered.)
- *
- * initPDH() must have been run prior to calling this function.
- *
- * @param multiQuery  a pointer to a MultipleCounterQueryS, will be filled in with
- *                    the necessary info to check the PDH processor counters.
- * @return            CONFIG_SUCCESSFUL if successful, negative on failure.
- */
 static int
-initProcessorCounters(void) {
-    char          processor[COUNTER_BUF_SIZE]; //'Processor' == #238
-    char          time[COUNTER_BUF_SIZE];      //'Time' == 6
-    DWORD      c_size, i_size;
-    HQUERY     tmpQuery;
-    DWORD      i, p_count;
-    BOOL          error;
-    char         *instances, *tmp;
-    PDH_STATUS pdhStat;
-
-    c_size   = i_size = 0;
-    tmpQuery = NULL;
-    error    = false;
-
-    // This __try / __except stuff is there since Windows 2000 beta (or so) sometimes triggered
-    // an access violation when the user had insufficient privileges to use the performance
-    // counters. This was previously guarded by a very ugly piece of code which disabled the
-    // global trap handling in JRockit. Don't know if this really is needed anymore, but otoh,
-    // if we keep it we don't crash on Win2k beta. /Ihse, 2005-05-30
-    __try {
-        if (find_name(PDH_PROCESSOR_IDX, processor, sizeof(processor)-1) < 0) {
-            return -1;
-        }
-    } __except (EXCEPTION_EXECUTE_HANDLER) { // We'll catch all exceptions here.
-        /* printf("User does not have sufficient privileges to use performance counters"); */
-        return -1;
-    }
-
-    if (find_name(PDH_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
-        return -1;
-    }
-    //ok, now we have enough to enumerate all processors.
-    pdhStat = PdhEnumObjectItems_i (
-                    NULL,                   // reserved
-                    NULL,                   // local machine
-                    processor,          // object to enumerate
-                    NULL,              // pass in NULL buffers
-                    &c_size,              // and 0 length to get
-                    NULL,              // required size
-                    &i_size,              // of the buffers in chars
-                    PERF_DETAIL_WIZARD,     // counter detail level
-                    0);
-    if (pdh_fail(pdhStat)) {
-        /* printf("could not enumerate processors (1) error=%d", pdhStat); */
-        return -1;
-    }
-
-    // use calloc because windows vista does not null terminate the instance names (allthough the docs says it will)
-    instances = calloc(i_size, 1);
-    if (instances == NULL) {
-        /* printf("could not allocate memory (1) %d bytes", i_size); */
-        error = true;
-        goto end;
-    }
-
-    c_size  = 0;
-    pdhStat = PdhEnumObjectItems_i (
-                    NULL,                   // reserved
-                    NULL,                   // local machine
-                    processor,              // object to enumerate
-                    NULL,              // pass in NULL buffers
-                    &c_size,              // and 0 length to get
-                    instances,          // required size
-                    &i_size,              // of the buffers in chars
-                    PERF_DETAIL_WIZARD,     // counter detail level
-                    0);
-
-    if (pdh_fail(pdhStat)) {
-        /* printf("could not enumerate processors (2) error=%d", pdhStat); */
-        error = true;
-        goto end;
-    }
-    //count perf count instances.
-    for (p_count = 0, tmp = instances; *tmp != 0; tmp = &tmp[lstrlen(tmp)+1], p_count++);
-
-    //is this correct for HT?
-    assert(p_count == num_cpus+1);
-
-    //ok, have number of perf counters.
-    multiCounterCPULoad.counters = calloc(p_count, sizeof(HCOUNTER));
-    if (multiCounterCPULoad.counters == NULL) {
-        /* printf("could not allocate memory (2) count=%d", p_count); */
-        error = true;
-        goto end;
-    }
-
-    multiCounterCPULoad.noOfCounters = p_count;
-
-    if (PdhOpenQuery_i(NULL, 0, &multiCounterCPULoad.query.query) != ERROR_SUCCESS) {
-        /* printf("could not create query"); */
-        error = true;
-        goto end;
-    }
-    //now, fetch the counters.
-    for (i = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[lstrlen(tmp)+1], i++) {
-    char counter[2*COUNTER_BUF_SIZE];
-
-    _snprintf(counter, sizeof(counter)-1, "\\%s(%s)\\%s", processor, tmp, time);
-
-    if (PdhAddCounter_i(multiCounterCPULoad.query.query, counter, 0, &multiCounterCPULoad.counters[i]) != ERROR_SUCCESS) {
-            /* printf("error adding processor counter %s", counter); */
-            error = true;
-            goto end;
-        }
-    }
-
-    free(instances);
-    instances = NULL;
-
-    // Query once to initialize the counters needing at least two queries
-    // (like the % CPU usage) to calculate correctly.
-    if (PdhCollectQueryData_i(multiCounterCPULoad.query.query) != ERROR_SUCCESS)
-        error = true;
-
- end:
-    if (instances != NULL) {
-        free(instances);
-    }
-    if (tmpQuery != NULL) {
-        PdhCloseQuery_i(tmpQuery);
-    }
-    if (error) {
-        int i;
-
-        if (multiCounterCPULoad.counters != NULL) {
-            for (i = 0; i < multiCounterCPULoad.noOfCounters; i++) {
-                if (multiCounterCPULoad.counters[i] != NULL) {
-                    PdhRemoveCounter_i(multiCounterCPULoad.counters[i]);
-                }
-            }
-            free(multiCounterCPULoad.counters[i]);
-        }
-        if (multiCounterCPULoad.query.query != NULL) {
-            PdhCloseQuery_i(multiCounterCPULoad.query.query);
-        }
-        memset(&multiCounterCPULoad, 0, sizeof(MultipleCounterQueryS));
-        return -1;
-    }
-    return CONFIG_SUCCESSFUL;
+perfCPUInit() {
+    return initializePdhCPUCounters();
 }
 
-/**
- * Help function that initializes the PDH process header for the JRockit process.
- * (You should probably use getProcessPDHHeader() instead!)
- *
- * initPDH() must have been run prior to calling this function.
- *
- * @param ebuf the error buffer.
- * @param elen the length of the error buffer.
- *
- * @return the PDH instance description corresponding to the JVM process.
- */
-static char*
-initProcessPDHHeader(void) {
-    static char hotspotheader[2*COUNTER_BUF_SIZE];
+static double
+perfGetProcessCPULoad() {
+    PDH_FMT_COUNTERVALUE cv;
+    int currentQueryIndex;
 
-    char           counter[2*COUNTER_BUF_SIZE];
-    char           processes[COUNTER_BUF_SIZE];   //'Process' == #230
-    char           pid[COUNTER_BUF_SIZE];           //'ID Process' == 784
-    char           module_name[MAX_PATH];
-    PDH_STATUS  pdhStat;
-    DWORD       c_size = 0, i_size = 0;
-    HQUERY      tmpQuery = NULL;
-    int           i, myPid = _getpid();
-    BOOL           error = false;
-    char          *instances, *tmp, *instance_name, *dot_pos;
-
-    tmpQuery = NULL;
-    myPid    = _getpid();
-    error    = false;
-
-    if (find_name(PDH_PROCESS_IDX, processes, sizeof(processes) - 1) < 0) {
-        return NULL;
-    }
-
-    if (find_name(PDH_ID_PROCESS_IDX, pid, sizeof(pid) - 1) < 0) {
-        return NULL;
-    }
-    //time is same.
-
-    c_size = 0;
-    i_size = 0;
-
-    pdhStat = PdhEnumObjectItems_i (
-                    NULL,                   // reserved
-                    NULL,                   // local machine
-                    processes,              // object to enumerate
-                    NULL,                   // pass in NULL buffers
-                    &c_size,              // and 0 length to get
-                    NULL,              // required size
-                    &i_size,              // of the buffers in chars
-                    PERF_DETAIL_WIZARD,     // counter detail level
-                    0);
-
-    //ok, now we have enough to enumerate all processes
-    if (pdh_fail(pdhStat)) {
-        /* printf("Could not enumerate processes (1) error=%d", pdhStat); */
-        return NULL;
-    }
-
-    // use calloc because windows vista does not null terminate the instance names (allthough the docs says it will)
-    if ((instances = calloc(i_size, 1)) == NULL) {
-        /* printf("Could not allocate memory %d bytes", i_size); */
-        error = true;
-        goto end;
-    }
-
-    c_size = 0;
-
-    pdhStat = PdhEnumObjectItems_i (
-                    NULL,                   // reserved
-                    NULL,                   // local machine
-                    processes,              // object to enumerate
-                    NULL,              // pass in NULL buffers
-                    &c_size,              // and 0 length to get
-                    instances,          // required size
-                    &i_size,              // of the buffers in chars
-                    PERF_DETAIL_WIZARD,     // counter detail level
-                    0);
-
-    // ok, now we have enough to enumerate all processes
-    if (pdh_fail(pdhStat)) {
-        /* printf("Could not enumerate processes (2) error=%d", pdhStat); */
-        error = true;
-        goto end;
-    }
-
-    if (PdhOpenQuery_i(NULL, 0, &tmpQuery) != ERROR_SUCCESS) {
-        /* printf("Could not create temporary query"); */
-        error = true;
-        goto end;
-    }
-
-    // Find our module name and use it to extract the instance name used by PDH
-    if (GetModuleFileName(NULL, module_name, MAX_PATH) >= MAX_PATH-1) {
-        /* printf("Module name truncated"); */
-        error = true;
-        goto end;
-    }
-    instance_name = strrchr(module_name, '\\'); //drop path
-    instance_name++;                            //skip slash
-    dot_pos = strchr(instance_name, '.');       //drop .exe
-    dot_pos[0] = '\0';
-
-    //now, fetch the counters.
-    for (tmp = instances; *tmp != 0 && !error; tmp = &tmp[lstrlen(tmp)+1]) {
-        HCOUNTER  hc = NULL;
-        BOOL done = false;
-
-        // Skip until we find our own process name
-        if (strcmp(tmp, instance_name) != 0) {
-            continue;
-        }
-
-        // iterate over all instance indexes and try to find our own pid
-        for (i = 0; !done && !error; i++){
-            PDH_STATUS res;
-            _snprintf(counter, sizeof(counter)-1, "\\%s(%s#%d)\\%s", processes, tmp, i, pid);
-
-            if (PdhAddCounter_i(tmpQuery, counter, 0, &hc) != ERROR_SUCCESS) {
-                /* printf("Failed to create process id query"); */
-                error = true;
-                goto end;
-            }
-
-            res = PdhCollectQueryData_i(tmpQuery);
-
-            if (res == PDH_INVALID_HANDLE) {
-                /* printf("Failed to query process id"); */
-                res = -1;
-                done = true;
-            } else if (res == PDH_NO_DATA) {
-                done = true;
-            } else {
-                PDH_FMT_COUNTERVALUE cv;
-
-                PdhGetFormattedCounterValue_i(hc, PDH_FMT_LONG, NULL, &cv);
-               /*
-                 * This check seems to be needed for Win2k SMP boxes, since
-                 * they for some reason don't return PDH_NO_DATA for non existing
-                 * counters.
-                 */
-                if (cv.CStatus != PDH_CSTATUS_VALID_DATA) {
-                    done = true;
-                } else if (cv.longValue == myPid) {
-                    _snprintf(hotspotheader, sizeof(hotspotheader)-1, "\\%s(%s#%d)\0", processes, tmp, i);
-                    PdhRemoveCounter_i(hc);
-                    goto end;
-                }
-            }
-            PdhRemoveCounter_i(hc);
-        }
-    }
- end:
-    if (instances != NULL) {
-        free(instances);
-    }
-    if (tmpQuery != NULL) {
-        PdhCloseQuery_i(tmpQuery);
-    }
-    if (error) {
-        return NULL;
-    }
-    return hotspotheader;
-}
-
-/**
- * Returns the PDH string prefix identifying the HotSpot process. Use this prefix when getting
- * counters from the PDH process object representing HotSpot.
- *
- * Note: this call may take some time to complete.
- *
- * @param ebuf error buffer.
- * @param elen error buffer length.
- *
- * @return the header to be used when retrieving PDH counters from the HotSpot process.
- * Will return NULL if the call failed.
- */
-static char *
-getProcessPDHHeader(void) {
-    static char *processHeader = NULL;
-
-    EnterCriticalSection(&processHeaderLock); {
-        if (processHeader == NULL) {
-            processHeader = initProcessPDHHeader();
-        }
-    } LeaveCriticalSection(&processHeaderLock);
-    return processHeader;
-}
-
-int perfInit(void);
-
-double
-perfGetCPULoad(int which)
-{
-    PDH_FMT_COUNTERVALUE cv;
-    HCOUNTER            c;
-
-    if (perfInit() < 0) {
+    if (perfCPUInit() < 0) {
         // warn?
         return -1.0;
     }
 
-    if (multiCounterCPULoad.query.query == NULL) {
-        // warn?
-        return -1.0;
-    }
+    currentQueryIndex = getCurrentQueryIndexForProcess();
 
-    if (which == -1) {
-        c = multiCounterCPULoad.counters[multiCounterCPULoad.noOfCounters - 1];
-    } else {
-        if (which < multiCounterCPULoad.noOfCounters) {
-            c = multiCounterCPULoad.counters[which];
-        } else {
-            return -1.0;
-        }
-    }
-    if (getPerformanceData(&multiCounterCPULoad.query, c, &cv, PDH_FMT_DOUBLE ) == CONFIG_SUCCESSFUL) {
-        return cv.doubleValue / 100;
-    }
-    return -1.0;
-}
-
-double
-perfGetProcessLoad(void)
-{
-    PDH_FMT_COUNTERVALUE cv;
-
-    if (perfInit() < 0) {
-        // warn?
-        return -1.0;
-    }
-
-    if (cntProcLoad.query.query == NULL) {
-        // warn?
-        return -1.0;
-    }
-
-    if (getPerformanceData(&cntProcLoad.query, cntProcLoad.counter, &cv, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == CONFIG_SUCCESSFUL) {
+    if (getPerformanceData(&processTotalCPULoad[currentQueryIndex].query,
+                           processTotalCPULoad[currentQueryIndex].counter,
+                           &cv,
+                           PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == 0) {
         double d = cv.doubleValue / cpuFactor;
         d = min(1, d);
         d = max(0, d);
@@ -860,70 +1323,29 @@
     return -1.0;
 }
 
-/**
- * Helper to initialize the PDH library. Loads the library and sets up the functions.
- * Note that once loaded, we will never unload the PDH library.
- *
- * @return  CONFIG_SUCCESSFUL if successful, negative on failure.
- */
-int
-perfInit(void) {
-    static HMODULE    h;
-    static BOOL        running, inited;
+static double
+perfGetCPULoad(int which) {
+    PDH_FMT_COUNTERVALUE cv;
+    HCOUNTER c;
 
-    int error;
-
-    if (running) {
-        return CONFIG_SUCCESSFUL;
+    if (perfCPUInit() < 0) {
+        // warn?
+        return -1.0;
     }
 
-    error = CONFIG_SUCCESSFUL;
-
-    // this is double checked locking again, but we try to bypass the worst by
-    // implicit membar at end of lock.
-    EnterCriticalSection(&initializationLock); {
-        if (!inited) {
-            char         buf[64] = "";
-            SYSTEM_INFO si;
-
-            // CMH. But windows will not care about our affinity when giving
-            // us measurements. Need the real, raw num cpus.
-
-            GetSystemInfo(&si);
-            num_cpus  = si.dwNumberOfProcessors;
-            // Initialize the denominator for the jvm load calculations
-            cpuFactor = num_cpus * 100;
-
-            /**
-             * Do this dynamically, so we don't fail to start on systems without pdh.
-             */
-            if ((h = LoadLibrary("pdh.dll")) == NULL) {
-                /* printf("Could not load pdh.dll (%d)", GetLastError()); */
-                error = -2;
-            } else if (get_functions(h, buf, sizeof(buf)) < 0) {
-                FreeLibrary(h);
-                h = NULL;
-                error = -2;
-               /* printf("Failed to init pdh functions: %s.\n", buf); */
-            } else {
-                if (initProcessorCounters() != 0) {
-                    /* printf("Failed to init system load counters.\n"); */
-                } else if (initProcLoadCounter() != 0) {
-                    /* printf("Failed to init process load counter.\n"); */
-                } else if (initProcSystemLoadCounter() != 0) {
-                    /* printf("Failed to init process system load counter.\n"); */
-                } else {
-                    inited = true;
-                }
-            }
+    if (-1 == which) {
+        c = multiCounterCPULoad->counters[multiCounterCPULoad->noOfCounters - 1];
+    } else {
+        if (which < multiCounterCPULoad->noOfCounters) {
+            c = multiCounterCPULoad->counters[which];
+        } else {
+            return -1.0;
         }
-    } LeaveCriticalSection(&initializationLock);
-
-    if (inited && error == CONFIG_SUCCESSFUL) {
-        running = true;
     }
-
-    return error;
+    if (getPerformanceData(&multiCounterCPULoad->query, c, &cv, PDH_FMT_DOUBLE ) == 0) {
+        return cv.doubleValue / 100;
+    }
+    return -1.0;
 }
 
 JNIEXPORT jdouble JNICALL
@@ -937,5 +1359,5 @@
 Java_sun_management_OperatingSystemImpl_getProcessCpuLoad
 (JNIEnv *env, jobject dummy)
 {
-    return perfGetProcessLoad();
+    return perfGetProcessCPULoad();
 }
--- a/test/sun/util/calendar/zi/tzdata/VERSION	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/VERSION	Mon Dec 01 11:37:49 2014 -0800
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2014g
+tzdata2014j
--- a/test/sun/util/calendar/zi/tzdata/africa	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/africa	Mon Dec 01 11:37:49 2014 -0800
@@ -29,20 +29,19 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2013-02-21):
+# From Paul Eggert (2014-10-31):
 #
-# A good source for time zone historical data outside the U.S. is
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -88,7 +87,6 @@
 #	 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
@@ -133,23 +131,13 @@
 # See Africa/Lagos.
 
 # Botswana
-# From Paul Eggert (2013-02-21):
-# Milne says they were regulated by the Cape Town Signal in 1899;
-# assume they switched to 2:00 when Cape Town did.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Gaborone	1:43:40 -	LMT	1885
-			1:30	-	SAST	1903 Mar
-			2:00	-	CAT	1943 Sep 19  2:00
-			2:00	1:00	CAST	1944 Mar 19  2:00
-			2:00	-	CAT
+# See Africa/Maputo.
 
 # Burkina Faso
 # See Africa/Abidjan.
 
 # Burundi
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Bujumbura	1:57:28	-	LMT	1890
-			2:00	-	CAT
+# See Africa/Maputo.
 
 # Cameroon
 # See Africa/Lagos.
@@ -179,15 +167,10 @@
 			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
+# See Africa/Nairobi.
 
 # Democratic Republic of the Congo
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Lubumbashi	1:49:52 -	LMT	1897 Nov 9
-			2:00	-	CAT
-# The above is for the eastern part; see Africa/Lagos for the western part.
+# See Africa/Lagos for the western part and Africa/Maputo for the eastern.
 
 # Republic of the Congo
 # See Africa/Lagos.
@@ -208,9 +191,7 @@
 Link Africa/Abidjan Atlantic/St_Helena	# St Helena
 
 # Djibouti
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Djibouti	2:52:36 -	LMT	1911 Jul
-			3:00	-	EAT
+# See Africa/Nairobi.
 
 ###############################################################################
 
@@ -339,7 +320,7 @@
 # Egypt is to change back to Daylight system on May 15
 # http://english.ahram.org.eg/NewsContent/1/64/100735/Egypt/Politics-/Egypts-government-to-reapply-daylight-saving-time-.aspx
 
-# From Gunther Vermier (2015-05-13):
+# From Gunther Vermier (2014-05-13):
 # our Egypt office confirms that the change will be at 15 May "midnight" (24:00)
 
 # From Imed Chihi (2014-06-04):
@@ -423,27 +404,8 @@
 # See Africa/Lagos.
 
 # 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 (2014-07-31):
-# Like the Swahili of Kenya and Tanzania, many Ethiopians keep a
-# 12-hour clock starting at our 06:00, so their "8 o'clock" is our
-# 02:00 or 14:00.  Keep this in mind when you ask the time in Amharic.
-#
-# Shanks & Pottenger write that Ethiopia had six narrowly-spaced time
-# zones between 1870 and 1890, that they merged to 38E50 (2:35:20) in
-# 1890, and that they switched to 3:00 on 1936-05-05.  Perhaps 38E50
-# was for Adis Dera.  Quite likely the Shanks data entries are wrong
-# anyway.
-# 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
+# See Africa/Nairobi.
 
 # Gabon
 # See Africa/Lagos.
@@ -487,13 +449,18 @@
 			2:30	-	BEAT	1940
 			2:45	-	BEAUT	1960
 			3:00	-	EAT
+Link Africa/Nairobi Africa/Addis_Ababa	 # Ethiopia
+Link Africa/Nairobi Africa/Asmara	 # Eritrea
+Link Africa/Nairobi Africa/Dar_es_Salaam # Tanzania
+Link Africa/Nairobi Africa/Djibouti
+Link Africa/Nairobi Africa/Kampala	 # Uganda
+Link Africa/Nairobi Africa/Mogadishu	 # Somalia
+Link Africa/Nairobi Indian/Antananarivo	 # Madagascar
+Link Africa/Nairobi Indian/Comoro
+Link Africa/Nairobi Indian/Mayotte
 
 # 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
+# See Africa/Johannesburg.
 
 # Liberia
 # From Paul Eggert (2006-03-22):
@@ -568,16 +535,10 @@
 			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
+# See Africa/Nairobi.
 
 # Malawi
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Blantyre	2:20:00 -	LMT	1903 Mar
-			2:00	-	CAT
+# See Africa/Maputo.
 
 # Mali
 # Mauritania
@@ -677,9 +638,7 @@
 # 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
+# See Africa/Nairobi.
 
 # Morocco
 # See the 'europe' file for Spanish Morocco (Africa/Ceuta).
@@ -987,6 +946,13 @@
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Maputo	2:10:20 -	LMT	1903 Mar
 			2:00	-	CAT
+Link Africa/Maputo Africa/Blantyre	# Malawi
+Link Africa/Maputo Africa/Bujumbura	# Burundi
+Link Africa/Maputo Africa/Gaborone	# Botswana
+Link Africa/Maputo Africa/Harare	# Zimbabwe
+Link Africa/Maputo Africa/Kigali	# Rwanda
+Link Africa/Maputo Africa/Lubumbashi	# E Dem. Rep. of Congo
+Link Africa/Maputo Africa/Lusaka	# Zambia
 
 # Namibia
 # The 1994-04-03 transition is from Shanks & Pottenger.
@@ -1054,9 +1020,7 @@
 # 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
+# See Africa/Maputo.
 
 # St Helena
 # See Africa/Abidjan.
@@ -1086,11 +1050,7 @@
 # See Africa/Abidjan.
 
 # 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
+# See Africa/Nairobi.
 
 # South Africa
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -1100,6 +1060,9 @@
 Zone Africa/Johannesburg 1:52:00 -	LMT	1892 Feb 8
 			1:30	-	SAST	1903 Mar
 			2:00	SA	SAST
+Link Africa/Johannesburg Africa/Maseru	   # Lesotho
+Link Africa/Johannesburg Africa/Mbabane    # Swaziland
+#
 # Marion and Prince Edward Is
 # scientific station since 1947
 # no information
@@ -1127,16 +1090,10 @@
 Link Africa/Khartoum Africa/Juba
 
 # Swaziland
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Mbabane	2:04:24 -	LMT	1903 Mar
-			2:00	-	SAST
+# See Africa/Johannesburg.
 
 # 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
+# See Africa/Nairobi.
 
 # Togo
 # See Africa/Abidjan.
@@ -1242,19 +1199,8 @@
 			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
+# See Africa/Nairobi.
 
 # 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
+# See Africa/Maputo.
--- a/test/sun/util/calendar/zi/tzdata/asia	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/asia	Mon Dec 01 11:37:49 2014 -0800
@@ -29,20 +29,19 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2013-08-11):
+# From Paul Eggert (2014-10-31):
 #
-# A good source for time zone historical data outside the U.S. is
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -70,10 +69,11 @@
 #	3:30 IRST IRDT	Iran
 #	4:00 GST	Gulf*
 #	5:30 IST	India
-#	7:00 ICT	Indochina*
+#	7:00 ICT	Indochina, most times and locations*
 #	7:00 WIB	west Indonesia (Waktu Indonesia Barat)
 #	8:00 WITA	central Indonesia (Waktu Indonesia Tengah)
 #	8:00 CST	China
+#	8:00 IDT	Indochina, 1943-45, 1947-55, 1960-75 (some locations)*
 #	8:00 JWST	Western Standard Time (Japan, 1896/1937)*
 #	9:00 JCST	Central Standard Time (Japan, 1896/1937)
 #	9:00 WIT	east Indonesia (Waktu Indonesia Timur)
@@ -294,12 +294,8 @@
 			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
+# See Asia/Bangkok.
+
 
 # China
 
@@ -916,6 +912,10 @@
 
 # Indonesia
 #
+# From Paul Eggert (2014-09-06):
+# The 1876 Report of the Secretary of the [US] Navy, p 306 says that Batavia
+# civil time was 7:07:12.5; round to even for Jakarta.
+#
 # 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
@@ -1685,44 +1685,70 @@
 # Korea (North and South)
 
 # From Annie I. Bang (2006-07-10):
-# 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.
+# http://www.koreaherald.com/view.php?ud=200607100012
+# Korea ran a daylight saving program from 1949-61 but stopped it
+# during the 1950-53 Korean War.  The system was temporarily enforced
+# between 1987 and 1988 ...
 
-# From Shanks & Pottenger:
+# From Sanghyuk Jung (2014-10-29):
+# http://mm.icann.org/pipermail/tz/2014-October/021830.html
+# According to the Korean Wikipedia
+# http://ko.wikipedia.org/wiki/한국_표준시
+# [oldid=12896437 2014-09-04 08:03 UTC]
+# DST in Republic of Korea was as follows....  And I checked old
+# newspapers in Korean, all articles correspond with data in Wikipedia.
+# For example, the article in 1948 (Korean Language) proved that DST
+# started at June 1 in that year.  For another example, the article in
+# 1988 said that DST started at 2:00 AM in that year.
+
 # 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
+Rule	ROK	1948	only	-	Jun	 1	0:00	1:00	D
+Rule	ROK	1948	only	-	Sep	13	0:00	0	S
+Rule	ROK	1949	only	-	Apr	 3	0:00	1:00	D
+Rule	ROK	1949	1951	-	Sep	Sun>=8	0:00	0	S
+Rule	ROK	1950	only	-	Apr	 1	0:00	1:00	D
+Rule	ROK	1951	only	-	May	 6	0:00	1:00	D
+Rule	ROK	1955	only	-	May	 5	0:00	1:00	D
+Rule	ROK	1955	only	-	Sep	 9	0:00	0	S
+Rule	ROK	1956	only	-	May	20	0:00	1:00	D
+Rule	ROK	1956	only	-	Sep	30	0:00	0	S
+Rule	ROK	1957	1960	-	May	Sun>=1	0:00	1:00	D
+Rule	ROK	1957	1960	-	Sep	Sun>=18	0:00	0	S
+Rule	ROK	1987	1988	-	May	Sun>=8	2:00	1:00	D
+Rule	ROK	1987	1988	-	Oct	Sun>=8	3:00	0	S
 
-# From Paul Eggert (2014-07-01):
-# The following entries are from Shanks & Pottenger, except that I
-# guessed that time zone abbreviations through 1945 followed the same
+# From Paul Eggert (2014-10-30):
+# The Korean Wikipedia entry gives the following sources for UT offsets:
+#
+# 1908: Official Journal Article No. 3994 (Edict No. 5)
+# 1912: Governor-General of Korea Official Gazette Issue No. 367
+#       (Announcement No. 338)
+# 1954: Presidential Decree No. 876 (1954-03-17)
+# 1961: Law No. 676 (1961-08-07)
+# 1987: Law No. 3919 (1986-12-31)
+#
+# The Wikipedia entry also has confusing information about a change
+# to UT+9 in April 1910, but then what would be the point of the later change
+# to UT+9 on 1912-01-01?  Omit the 1910 change for now.
+#
+# I guessed that time zone abbreviations through 1945 followed the same
 # rules as discussed under Taiwan, with nominal switches from JST to KST
 # when the respective cities were taken over by the Allies after WWII.
+#
+# For Pyongyang we have no information; guess no changes since World War II.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Seoul	8:27:52	-	LMT	1890
-			8:30	-	KST	1904 Dec
-			9:00	-	JCST	1928
-			8:30	-	KST	1932
+Zone	Asia/Seoul	8:27:52	-	LMT	1908 Apr  1
+			8:30	-	KST	1912 Jan  1
 			9:00	-	JCST	1937 Oct  1
 			9:00	-	JST	1945 Sep  8
 			9:00	-	KST	1954 Mar 21
-			8:00	ROK	K%sT	1961 Aug 10
-			8:30	-	KST	1968 Oct
+			8:30	ROK	K%sT	1961 Aug 10
 			9:00	ROK	K%sT
-Zone	Asia/Pyongyang	8:23:00 -	LMT	1890
-			8:30	-	KST	1904 Dec
-			9:00	-	JCST	1928
-			8:30	-	KST	1932
+Zone	Asia/Pyongyang	8:23:00 -	LMT	1908 Apr  1
+			8:30	-	KST	1912 Jan  1
 			9:00	-	JCST	1937 Oct  1
 			9:00	-	JST	1945 Aug 24
-			9:00	-	KST	1954 Mar 21
-			8:00	-	KST	1961 Aug 10
 			9:00	-	KST
 
 ###############################################################################
@@ -1733,12 +1759,8 @@
 			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
+# See Asia/Bangkok.
+
 
 # Lebanon
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -2751,6 +2773,8 @@
 Zone	Asia/Bangkok	6:42:04	-	LMT	1880
 			6:42:04	-	BMT	1920 Apr # Bangkok Mean Time
 			7:00	-	ICT
+Link Asia/Bangkok Asia/Phnom_Penh	# Cambodia
+Link Asia/Bangkok Asia/Vientiane	# Laos
 
 # Turkmenistan
 # From Shanks & Pottenger.
@@ -2788,22 +2812,65 @@
 
 # Vietnam
 
-# From Paul Eggert (2013-02-21):
+# From Paul Eggert (2014-10-04):
 # Milne gives 7:16:56 for the meridian of Saigon in 1899, as being
 # used in Lower Laos, Cambodia, and Annam.  But this is quite a ways
 # from Saigon's location.  For now, ignore this and stick with Shanks
-# and Pottenger.
+# and Pottenger for LMT before 1906.
 
 # From Arthur David Olson (2008-03-18):
 # The English-language name of Vietnam's most populous city is "Ho Chi Minh
 # City"; use Ho_Chi_Minh below to avoid a name of more than 14 characters.
 
-# From Shanks & Pottenger:
+# From Paul Eggert (2014-10-21) after a heads-up from Trần Ngọc Quân:
+# Trần Tiến Bình's authoritative book "Lịch Việt Nam: thế kỷ XX-XXI (1901-2100)"
+# (Nhà xuất bản Văn Hoá - Thông Tin, Hanoi, 2005), pp 49-50,
+# is quoted verbatim in:
+# http://www.thoigian.com.vn/?mPage=P80D01
+# is translated by Brian Inglis in:
+# http://mm.icann.org/pipermail/tz/2014-October/021654.html
+# and is the basis for the information below.
+#
+# The 1906 transition was effective July 1 and standardized Indochina to
+# Phù Liễn Observatory, legally 104 deg. 17'17" east of Paris.
+# It's unclear whether this meant legal Paris Mean Time (00:09:21) or
+# the Paris Meridian (2 deg. 20'14.03" E); the former yields 07:06:30.1333...
+# and the latter 07:06:29.333... so either way it rounds to 07:06:30,
+# which is used below even though the modern-day Phù Liễn Observatory
+# is closer to 07:06:31.  Abbreviate Phù Liễn Mean Time as PLMT.
+#
+# The following transitions occurred in Indochina in general (before 1954)
+# and in South Vietnam in particular (after 1954):
+# To 07:00 on 1911-05-01.
+# To 08:00 on 1942-12-31 at 23:00.
+# To 09:00 in 1945-03-14 at 23:00.
+# To 07:00 on 1945-09-02 in Vietnam.
+# To 08:00 on 1947-04-01 in French-controlled Indochina.
+# To 07:00 on 1955-07-01 in South Vietnam.
+# To 08:00 on 1959-12-31 at 23:00 in South Vietnam.
+# To 07:00 on 1975-06-13 in South Vietnam.
+#
+# Trần cites the following sources; it's unclear which supplied the info above.
+#
+# Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội,
+# No. 9, Paris, February 1982.
+#
+# Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)",
+# NXB Thống kê, Hanoi, 2000.
+#
+# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu",
+# NXB Thuận Hoá, Huế, 1995.
+
 # 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
+Zone Asia/Ho_Chi_Minh	7:06:40 -	LMT	1906 Jul  1
+			7:06:30	-	PLMT	1911 May  1
+			7:00	-	ICT	1942 Dec 31 23:00
+			8:00	-	IDT	1945 Mar 14 23:00
+			9:00	-	JST	1945 Sep  2
+			7:00	-	ICT	1947 Apr  1
+			8:00	-	IDT	1955 Jul  1
+			7:00	-	ICT	1959 Dec 31 23:00
+			8:00	-	IDT	1975 Jun 13
 			7:00	-	ICT
 
 # Yemen
--- a/test/sun/util/calendar/zi/tzdata/australasia	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/australasia	Mon Dec 01 11:37:49 2014 -0800
@@ -354,20 +354,27 @@
 # Fiji will end DST on 2014-01-19 02:00:
 # http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-%281%29.aspx
 
-# From Paul Eggert (2014-01-10):
-# For now, guess that Fiji springs forward the Sunday before the fourth
-# Monday in October, and springs back the penultimate Sunday in January.
-# This is ad hoc, but matches recent practice.
+# From Ken Rylander (2014-10-20):
+# DST will start Nov. 2 this year.
+# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-SUNDAY,-NOVEMBER-2ND.aspx
+
+# From Paul Eggert (2014-10-20):
+# For now, guess DST from 02:00 the first Sunday in November to
+# 03:00 the first Sunday on or after January 18.  Although ad hoc, it
+# matches this year's plan and seems more likely to match future
+# practice than guessing no DST.
 
 # 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>=21	2:00	1:00	S
+Rule	Fiji	2010	2013	-	Oct	Sun>=21	2:00	1:00	S
 Rule	Fiji	2011	only	-	Mar	Sun>=1	3:00	0	-
 Rule	Fiji	2012	2013	-	Jan	Sun>=18	3:00	0	-
-Rule	Fiji	2014	max	-	Jan	Sun>=18	2:00	0	-
+Rule	Fiji	2014	only	-	Jan	Sun>=18	2:00	0	-
+Rule	Fiji	2014	max	-	Nov	Sun>=1	2:00	1:00	S
+Rule	Fiji	2015	max	-	Jan	Sun>=18	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Pacific/Fiji	11:55:44 -	LMT	1915 Oct 26 # Suva
 			12:00	Fiji	FJ%sT	# Fiji Time
@@ -542,6 +549,30 @@
 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
+#
+# From Paul Eggert (2014-10-13):
+# Base the Bougainville entry on the Arawa-Kieta region, which appears to have
+# the most people even though it was devastated in the Bougainville Civil War.
+#
+# Although Shanks gives 1942-03-15 / 1943-11-01 for JST, these dates
+# are apparently rough guesswork from the starts of military campaigns.
+# The World War II entries below are instead based on Arawa-Kieta.
+# The Japanese occupied Kieta in July 1942,
+# according to the Pacific War Online Encyclopedia
+# http://pwencycl.kgbudge.com/B/o/Bougainville.htm
+# and seem to have controlled it until their 1945-08-21 surrender.
+#
+# The Autonomous Region of Bougainville plans to switch from UTC+10 to UTC+11
+# on 2014-12-28 at 02:00.  They call UTC+11 "Bougainville Standard Time";
+# abbreviate this as BST.  See:
+# http://www.bougainville24.com/bougainville-issues/bougainville-gets-own-timezone/
+#
+Zone Pacific/Bougainville 10:22:16 -	LMT	1880
+			 9:48:32 -	PMMT	1895
+			10:00	-	PGT	1942 Jul
+			 9:00	-	JST	1945 Aug 21
+			10:00	-	PGT	2014 Dec 28  2:00
+			11:00	-	BST
 
 # Pitcairn
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -789,19 +820,19 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2013-02-21):
-# A good source for time zone historical data outside the U.S. is
+# From Paul Eggert (2014-10-31):
+#
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -826,6 +857,7 @@
 #	 10:00	AEST	AEDT	Eastern Australia
 #	 10:00	ChST		Chamorro
 #	 10:30	LHST	LHDT	Lord Howe*
+#	 11:00	BST		Bougainville*
 #	 11:30	NZMT	NZST	New Zealand through 1945
 #	 12:00	NZST	NZDT	New Zealand 1946-present
 #	 12:15	CHAST		Chatham through 1945*
--- a/test/sun/util/calendar/zi/tzdata/europe	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/europe	Mon Dec 01 11:37:49 2014 -0800
@@ -29,16 +29,19 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2014-05-31):
-# A good source for time zone historical data outside the U.S. is
+# From Paul Eggert (2014-10-31):
+#
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
@@ -91,10 +94,11 @@
 #        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       BST           British Standard (1968-1971)
 #        1:00       CET CEST CEMT Central Europe
 #        1:00:14    SET           Swedish (1879-1899)*
 #        2:00       EET EEST      Eastern Europe
-#        3:00       FET           Further-eastern Europe*
+#        3:00       FET           Further-eastern Europe (2011-2014)*
 #        3:00       MSK MSD  MSM* Moscow
 
 # From Peter Ilieve (1994-12-04),
@@ -309,6 +313,14 @@
 #   "Timeball on the ballast office is down.  Dunsink time."
 #   -- James Joyce, Ulysses
 
+# "Countess Markievicz ... claimed that the [1916] abolition of Dublin Mean Time
+# was among various actions undertaken by the 'English' government that
+# would 'put the whole country into the SF (Sinn Féin) camp'.  She claimed
+# Irish 'public feeling (was) outraged by forcing of English time on us'."
+# -- Parsons M. Dublin lost its time zone - and 25 minutes - after 1916 Rising.
+# Irish Times 2014-10-27.
+# http://www.irishtimes.com/news/politics/dublin-lost-its-time-zone-and-25-minutes-after-1916-rising-1.1977411
+
 # From Joseph S. Myers (2005-01-26):
 # Irish laws are available online at <http://www.irishstatutebook.ie>.
 # These include various relating to legal time, for example:
@@ -616,6 +628,7 @@
 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	-
+# As described below, Russia's 2014 change affects Zone data, not Rule data.
 
 # From Alexander Krivenyshev (2011-06-14):
 # According to Kremlin press service, Russian President Dmitry Medvedev
@@ -746,6 +759,13 @@
 # http://www.belta.by/ru/all_news/society/V-Belarusi-otmenjaetsja-perexod-na-sezonnoe-vremja_i_572952.html
 # http://naviny.by/rubrics/society/2011/09/16/ic_articles_116_175144/
 # http://news.tut.by/society/250578.html
+#
+# From Alexander Bokovoy (2014-10-09):
+# Belarussian government decided against changing to winter time....
+# http://eng.belta.by/all_news/society/Belarus-decides-against-adjusting-time-in-Russias-wake_i_76335.html
+# From Paul Eggert (2014-10-08):
+# Hence Belarus can share time zone abbreviations with Moscow again.
+#
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Minsk	1:50:16 -	LMT	1880
 			1:50	-	MMT	1924 May  2 # Minsk Mean Time
@@ -758,7 +778,8 @@
 			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
+			3:00	-	FET	2014 Oct 26  1:00s
+			3:00	-	MSK
 
 # Belgium
 #
@@ -2524,7 +2545,7 @@
 # The Kemerovo region will remain at UTC+7 through the 2014-10-26 change, thus
 # realigning itself with KRAT.
 
-Zone Asia/Novokuznetsk	 5:48:48 -	NMT	1920 Jan  6
+Zone Asia/Novokuznetsk	 5:48:48 -	LMT	1924 May  1
 			 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
--- a/test/sun/util/calendar/zi/tzdata/leapseconds	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/leapseconds	Mon Dec 01 11:37:49 2014 -0800
@@ -33,8 +33,8 @@
 # The NTP Timescale and Leap Seconds
 # http://www.eecis.udel.edu/~mills/leap.html
 
-# The International Earth Rotation Service periodically uses leap seconds
-# to keep UTC to within 0.9 s of UT1
+# The International Earth Rotation and Reference Systems 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 <http://dx.doi.org/10.1109/5.84965>.
--- a/test/sun/util/calendar/zi/tzdata/northamerica	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/northamerica	Mon Dec 01 11:37:49 2014 -0800
@@ -300,6 +300,12 @@
 # time zone, but we do go by the Eastern time zone because so many people work
 # in Columbus."
 
+# From Paul Eggert (2014-09-06):
+# Monthly Notices of the Royal Astronomical Society 44, 4 (1884-02-08), 208
+# says that New York City Hall time was 3 minutes 58.4 seconds fast of
+# Eastern time (i.e., -4:56:01.6) just before the 1883 switch.  Round to the
+# nearest second.
+
 # 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
@@ -1008,19 +1014,19 @@
 ################################################################################
 
 
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data outside the U.S. is
+# From Paul Eggert (2014-10-31):
+#
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
 # Other sources occasionally used include:
 #
@@ -1118,17 +1124,16 @@
 # 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):
+# From Paul Eggert (2014-10-18):
 # H. David Matthews and Mary Vincent's map
 # "It's about TIME", _Canadian Geographic_ (September-October 1998)
-# http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp
+# http://www.canadiangeographic.ca/Magazine/SO98/alacarte.asp
 # 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
-# information about standard and daylight saving time zones in Canada.
-# http://inms-ienm.nrc-cnrc.gc.ca/en/time_services/daylight_saving_e.php
-# (updated periodically).
+# National Research Council Canada maintains info about time zones and DST.
+# http://www.nrc-cnrc.gc.ca/eng/services/time/time_zones.html
+# http://www.nrc-cnrc.gc.ca/eng/services/time/faq/index.html#Q5
 # Its unofficial information is often taken from Matthews and Vincent.
 
 # From Paul Eggert (2006-06-27):
@@ -1993,10 +1998,7 @@
 # [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
+# According to ...
 # 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
@@ -2005,9 +2007,11 @@
 # 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):
+# From Paul Eggert (2014-10-17):
 # For lack of better information, assume that Southampton Island observed
-# daylight saving only during wartime.
+# daylight saving only during wartime.  Gwillim Law's email also
+# mentioned maps now maintained by National Research Council Canada;
+# see above for an up-to-date link.
 
 # From Chris Walton (2007-03-01):
 # ... the community of Resolute (located on Cornwallis Island in
@@ -3008,10 +3012,21 @@
 # Shanks & Pottenger give -5:07:12, but Milne records -5:07:10.41 from an
 # unspecified official document, and says "This time is used throughout the
 # island".  Go with Milne.  Round to the nearest second as required by zic.
+#
+# Shanks & Pottenger give April 28 for the 1974 spring-forward transition, but
+# Lance Neita writes that Prime Minister Michael Manley decreed it January 5.
+# Assume Neita meant Jan 6 02:00, the same as the US.  Neita also writes that
+# Manley's supporters associated this act with Manley's nickname "Joshua"
+# (recall that in the Bible the sun stood still at Joshua's request),
+# and with the Rod of Correction which Manley said he had received from
+# Haile Selassie, Emperor of Ethiopia.  See:
+# Neita L. The politician in all of us. Jamaica Observer 2014-09-20
+# http://www.jamaicaobserver.com/columns/The-politician-in-all-of-us_17573647
+#
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Jamaica	-5:07:11 -	LMT	1890        # Kingston
 			-5:07:11 -	KMT	1912 Feb    # Kingston Mean Time
-			-5:00	-	EST	1974 Apr 28  2:00
+			-5:00	-	EST	1974
 			-5:00	US	E%sT	1984
 			-5:00	-	EST
 
@@ -3139,13 +3154,17 @@
 # From Paul Eggert (2014-08-19):
 # The 2014-08-13 Cabinet meeting decided to stay on UTC-4 year-round.  See:
 # http://tcweeklynews.com/daylight-savings-time-to-be-maintained-p5353-127.htm
-# Model this as a switch from EST/EDT to AST on 2014-11-02 at 02:00.
+# Model this as a switch from EST/EDT to AST ...
+# From Chris Walton (2014-11-04):
+# ... the TCI government appears to have delayed the switch to
+# "permanent daylight saving time" by one year....
+# http://tcweeklynews.com/time-change-to-go-ahead-this-november-p5437-127.htm
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Grand_Turk	-4:44:32 -	LMT	1890
 			-5:07:11 -	KMT	1912 Feb # Kingston Mean Time
 			-5:00	-	EST	1979
-			-5:00	US	E%sT	2014 Nov  2  2:00
+			-5:00	US	E%sT	2015 Nov Sun>=1 2:00
 			-4:00	-	AST
 
 # British Virgin Is
--- a/test/sun/util/calendar/zi/tzdata/southamerica	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/southamerica	Mon Dec 01 11:37:49 2014 -0800
@@ -29,23 +29,23 @@
 # tz@iana.org for general use in the future).  For more, please see
 # the file CONTRIBUTING in the tz distribution.
 
-# From Paul Eggert (2006-03-22):
-# A good source for time zone historical data outside the U.S. is
+# From Paul Eggert (2014-10-31):
+#
+# Unless otherwise specified, the source for data through 1990 is:
 # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
 # San Diego: ACS Publications, Inc. (2003).
-#
-# For data circa 1899, a common source is:
-# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94.
-# http://www.jstor.org/stable/1774359
+# Unfortunately this book contains many errors and cites no sources.
 #
 # 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.
+# of the IATA's data after 1990.  Except where otherwise noted,
+# IATA SSIM is the source for entries after 1990.
 #
-# Except where otherwise noted, Shanks & Pottenger is the source for
-# entries through 1990, and IATA SSIM is the source for entries afterwards.
+# For data circa 1899, a common source is:
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94.
+# http://www.jstor.org/stable/1774359
 #
 # 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
--- a/test/sun/util/calendar/zi/tzdata/zone.tab	Wed Nov 19 15:29:32 2014 -0800
+++ b/test/sun/util/calendar/zi/tzdata/zone.tab	Mon Dec 01 11:37:49 2014 -0800
@@ -330,7 +330,8 @@
 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
+PG	-0930+14710	Pacific/Port_Moresby	most locations
+PG	-0613+15534	Pacific/Bougainville	Bougainville
 PH	+1435+12100	Asia/Manila
 PK	+2452+06703	Asia/Karachi
 PL	+5215+02100	Europe/Warsaw