Work on javac branch seems to have some results, so merge it
authorJaroslav Tulach <jtulach@netbeans.org>
Thu, 03 Oct 2013 15:51:55 +0200
changeset 1336804f6f982f4e
parent 1335 f194f314cac0
parent 1329 c1893bd50f35
child 1337 c794024954b5
Work on javac branch seems to have some results, so merge it
dew/src/main/java/org/apidesign/bck2brwsr/dew/Compile.java
launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java
launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java
rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java
rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java
rt/emul/mini/src/main/java/java/lang/Class.java
rt/emul/mini/src/main/java/java/lang/String.java
     1.1 --- a/dew/pom.xml	Thu Oct 03 15:43:10 2013 +0200
     1.2 +++ b/dew/pom.xml	Thu Oct 03 15:51:55 2013 +0200
     1.3 @@ -87,5 +87,18 @@
     1.4        <artifactId>javaquery.api</artifactId>
     1.5        <version>${project.version}</version>
     1.6      </dependency>
     1.7 +    <dependency>
     1.8 +      <groupId>org.apidesign.bck2brwsr</groupId>
     1.9 +      <artifactId>vmtest</artifactId>
    1.10 +      <version>${project.version}</version>
    1.11 +      <scope>test</scope>
    1.12 +      <type>jar</type>
    1.13 +    </dependency>
    1.14 +    <dependency>
    1.15 +      <groupId>${project.groupId}</groupId>
    1.16 +      <artifactId>launcher.http</artifactId>
    1.17 +      <version>${project.version}</version>
    1.18 +      <scope>test</scope>
    1.19 +    </dependency>
    1.20    </dependencies>
    1.21  </project>
     2.1 --- a/dew/src/test/java/org/apidesign/bck2brwsr/dew/CompileTest.java	Thu Oct 03 15:43:10 2013 +0200
     2.2 +++ b/dew/src/test/java/org/apidesign/bck2brwsr/dew/CompileTest.java	Thu Oct 03 15:51:55 2013 +0200
     2.3 @@ -18,15 +18,17 @@
     2.4  package org.apidesign.bck2brwsr.dew;
     2.5  
     2.6  import java.io.IOException;
     2.7 +import org.apidesign.bck2brwsr.vmtest.Compare;
     2.8 +import org.apidesign.bck2brwsr.vmtest.VMTest;
     2.9  import static org.testng.Assert.*;
    2.10 -import org.testng.annotations.Test;
    2.11 +import org.testng.annotations.Factory;
    2.12  
    2.13  /**
    2.14   *
    2.15   * @author Jaroslav Tulach <jtulach@netbeans.org>
    2.16   */
    2.17  public class CompileTest  {
    2.18 -    @Test public void testCompile() throws IOException {
    2.19 +    @Compare public void testCompile() throws IOException {
    2.20          String html = "<html><body>"
    2.21                  + " <button id='btn'>Hello!</button>"
    2.22                  + "</body></html>";
    2.23 @@ -42,4 +44,8 @@
    2.24          assertNotNull(result.get("x/y/z/X.class"), "Class X is compiled: " + result);
    2.25          assertNotNull(result.get("x/y/z/Index.class"), "Class Index is compiled: " + result);
    2.26      }
    2.27 +    
    2.28 +    @Factory public static Object[] create() {
    2.29 +        return VMTest.create(CompileTest.class);
    2.30 +    }
    2.31  }
     3.1 --- a/pom.xml	Thu Oct 03 15:43:10 2013 +0200
     3.2 +++ b/pom.xml	Thu Oct 03 15:51:55 2013 +0200
     3.3 @@ -16,6 +16,7 @@
     3.4        <netbeans.version>RELEASE73</netbeans.version>
     3.5        <license>COPYING</license>
     3.6        <net.java.html.version>0.6</net.java.html.version>
     3.7 +      <netbeans.compile.on.save>none</netbeans.compile.on.save>
     3.8    </properties>
     3.9    <modules>
    3.10      <module>dew</module>
     4.1 --- a/rt/emul/compact/src/main/java/java/lang/System.java	Thu Oct 03 15:43:10 2013 +0200
     4.2 +++ b/rt/emul/compact/src/main/java/java/lang/System.java	Thu Oct 03 15:51:55 2013 +0200
     4.3 @@ -17,6 +17,10 @@
     4.4   */
     4.5  package java.lang;
     4.6  
     4.7 +import java.io.ByteArrayInputStream;
     4.8 +import java.io.ByteArrayOutputStream;
     4.9 +import java.io.InputStream;
    4.10 +import java.io.PrintStream;
    4.11  import org.apidesign.bck2brwsr.core.JavaScriptBody;
    4.12  
    4.13  /** Poor man's re-implementation of most important System methods.
    4.14 @@ -40,9 +44,15 @@
    4.15      }
    4.16  
    4.17      public static String getProperty(String name) {
    4.18 +        if ("os.name".equals(name)) {
    4.19 +            return userAgent();
    4.20 +        }
    4.21          return null;
    4.22      }
    4.23      
    4.24 +    @JavaScriptBody(args = {}, body = "return navigator.userAgent;")
    4.25 +    private static native String userAgent();
    4.26 +    
    4.27      public static String getProperty(String key, String def) {
    4.28          return def;
    4.29      }
    4.30 @@ -62,4 +72,16 @@
    4.31      @JavaScriptBody(args = { "exitCode" }, body = "window.close();")
    4.32      public static void exit(int exitCode) {
    4.33      }
    4.34 +    
    4.35 +    public final static InputStream in;
    4.36 +
    4.37 +    public final static PrintStream out;
    4.38 +
    4.39 +    public final static PrintStream err;
    4.40 +    
    4.41 +    static {
    4.42 +        in = new ByteArrayInputStream(new byte[0]);
    4.43 +        out = err = new PrintStream(new ByteArrayOutputStream());
    4.44 +    }
    4.45 +    
    4.46  }
     5.1 --- a/rt/emul/compact/src/main/java/java/util/Locale.java	Thu Oct 03 15:43:10 2013 +0200
     5.2 +++ b/rt/emul/compact/src/main/java/java/util/Locale.java	Thu Oct 03 15:51:55 2013 +0200
     5.3 @@ -45,23 +45,6 @@
     5.4  import java.io.ObjectOutputStream;
     5.5  import java.io.ObjectStreamField;
     5.6  import java.io.Serializable;
     5.7 -import java.security.AccessController;
     5.8 -import java.text.MessageFormat;
     5.9 -import java.util.spi.LocaleNameProvider;
    5.10 -
    5.11 -import sun.security.action.GetPropertyAction;
    5.12 -import sun.util.LocaleServiceProviderPool;
    5.13 -import sun.util.locale.BaseLocale;
    5.14 -import sun.util.locale.InternalLocaleBuilder;
    5.15 -import sun.util.locale.LanguageTag;
    5.16 -import sun.util.locale.LocaleExtensions;
    5.17 -import sun.util.locale.LocaleObjectCache;
    5.18 -import sun.util.locale.LocaleSyntaxException;
    5.19 -import sun.util.locale.LocaleUtils;
    5.20 -import sun.util.locale.ParseStatus;
    5.21 -import sun.util.locale.UnicodeLocaleExtension;
    5.22 -import sun.util.resources.LocaleData;
    5.23 -import sun.util.resources.OpenListResourceBundle;
    5.24  
    5.25  /**
    5.26   * A <code>Locale</code> object represents a specific geographical, political,
    5.27 @@ -408,8 +391,6 @@
    5.28   */
    5.29  public final class Locale implements Cloneable, Serializable {
    5.30  
    5.31 -    static private final  Cache LOCALECACHE = new Cache();
    5.32 -
    5.33      /** Useful constant for language.
    5.34       */
    5.35      static public final Locale ENGLISH = createConstant("en", "");
    5.36 @@ -533,14 +514,10 @@
    5.37      private static final int DISPLAY_COUNTRY  = 1;
    5.38      private static final int DISPLAY_VARIANT  = 2;
    5.39      private static final int DISPLAY_SCRIPT   = 3;
    5.40 +    private String language;
    5.41 +    private String country;
    5.42 +    private String variant;
    5.43  
    5.44 -    /**
    5.45 -     * Private constructor used by getInstance method
    5.46 -     */
    5.47 -    private Locale(BaseLocale baseLocale, LocaleExtensions extensions) {
    5.48 -        this.baseLocale = baseLocale;
    5.49 -        this.localeExtensions = extensions;
    5.50 -    }
    5.51  
    5.52      /**
    5.53       * Construct a locale from language, country and variant.
    5.54 @@ -572,8 +549,9 @@
    5.55          if (language== null || country == null || variant == null) {
    5.56              throw new NullPointerException();
    5.57          }
    5.58 -        baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
    5.59 -        localeExtensions = getCompatibilityExtensions(language, "", country, variant);
    5.60 +        this.language = language;
    5.61 +        this.country = country;
    5.62 +        this.variant = variant;
    5.63      }
    5.64  
    5.65      /**
    5.66 @@ -631,96 +609,7 @@
    5.67       * constants due to making shortcuts.
    5.68       */
    5.69      private static Locale createConstant(String lang, String country) {
    5.70 -        BaseLocale base = BaseLocale.createInstance(lang, country);
    5.71 -        return getInstance(base, null);
    5.72 -    }
    5.73 -
    5.74 -    /**
    5.75 -     * Returns a <code>Locale</code> constructed from the given
    5.76 -     * <code>language</code>, <code>country</code> and
    5.77 -     * <code>variant</code>. If the same <code>Locale</code> instance
    5.78 -     * is available in the cache, then that instance is
    5.79 -     * returned. Otherwise, a new <code>Locale</code> instance is
    5.80 -     * created and cached.
    5.81 -     *
    5.82 -     * @param language lowercase 2 to 8 language code.
    5.83 -     * @param country uppercase two-letter ISO-3166 code and numric-3 UN M.49 area code.
    5.84 -     * @param variant vendor and browser specific code. See class description.
    5.85 -     * @return the <code>Locale</code> instance requested
    5.86 -     * @exception NullPointerException if any argument is null.
    5.87 -     */
    5.88 -    static Locale getInstance(String language, String country, String variant) {
    5.89 -        return getInstance(language, "", country, variant, null);
    5.90 -    }
    5.91 -
    5.92 -    static Locale getInstance(String language, String script, String country,
    5.93 -                                      String variant, LocaleExtensions extensions) {
    5.94 -        if (language== null || script == null || country == null || variant == null) {
    5.95 -            throw new NullPointerException();
    5.96 -        }
    5.97 -
    5.98 -        if (extensions == null) {
    5.99 -            extensions = getCompatibilityExtensions(language, script, country, variant);
   5.100 -        }
   5.101 -
   5.102 -        BaseLocale baseloc = BaseLocale.getInstance(language, script, country, variant);
   5.103 -        return getInstance(baseloc, extensions);
   5.104 -    }
   5.105 -
   5.106 -    static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
   5.107 -        LocaleKey key = new LocaleKey(baseloc, extensions);
   5.108 -        return LOCALECACHE.get(key);
   5.109 -    }
   5.110 -
   5.111 -    private static class Cache extends LocaleObjectCache<LocaleKey, Locale> {
   5.112 -        private Cache() {
   5.113 -        }
   5.114 -
   5.115 -        @Override
   5.116 -        protected Locale createObject(LocaleKey key) {
   5.117 -            return new Locale(key.base, key.exts);
   5.118 -        }
   5.119 -    }
   5.120 -
   5.121 -    private static final class LocaleKey {
   5.122 -        private final BaseLocale base;
   5.123 -        private final LocaleExtensions exts;
   5.124 -        private final int hash;
   5.125 -
   5.126 -        private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) {
   5.127 -            base = baseLocale;
   5.128 -            exts = extensions;
   5.129 -
   5.130 -            // Calculate the hash value here because it's always used.
   5.131 -            int h = base.hashCode();
   5.132 -            if (exts != null) {
   5.133 -                h ^= exts.hashCode();
   5.134 -            }
   5.135 -            hash = h;
   5.136 -        }
   5.137 -
   5.138 -        @Override
   5.139 -        public boolean equals(Object obj) {
   5.140 -            if (this == obj) {
   5.141 -                return true;
   5.142 -            }
   5.143 -            if (!(obj instanceof LocaleKey)) {
   5.144 -                return false;
   5.145 -            }
   5.146 -            LocaleKey other = (LocaleKey)obj;
   5.147 -            if (hash != other.hash || !base.equals(other.base)) {
   5.148 -                return false;
   5.149 -            }
   5.150 -            if (exts == null) {
   5.151 -                return other.exts == null;
   5.152 -            }
   5.153 -            return exts.equals(other.exts);
   5.154 -        }
   5.155 -
   5.156 -        @Override
   5.157 -        public int hashCode() {
   5.158 -            return hash;
   5.159 -        }
   5.160 +        return new Locale(lang, country);
   5.161      }
   5.162  
   5.163      /**
   5.164 @@ -736,104 +625,7 @@
   5.165       * @return the default locale for this instance of the Java Virtual Machine
   5.166       */
   5.167      public static Locale getDefault() {
   5.168 -        // do not synchronize this method - see 4071298
   5.169 -        // it's OK if more than one default locale happens to be created
   5.170 -        if (defaultLocale == null) {
   5.171 -            initDefault();
   5.172 -        }
   5.173 -        return defaultLocale;
   5.174 -    }
   5.175 -
   5.176 -    /**
   5.177 -     * Gets the current value of the default locale for the specified Category
   5.178 -     * for this instance of the Java Virtual Machine.
   5.179 -     * <p>
   5.180 -     * The Java Virtual Machine sets the default locale during startup based
   5.181 -     * on the host environment. It is used by many locale-sensitive methods
   5.182 -     * if no locale is explicitly specified. It can be changed using the
   5.183 -     * setDefault(Locale.Category, Locale) method.
   5.184 -     *
   5.185 -     * @param category - the specified category to get the default locale
   5.186 -     * @throws NullPointerException - if category is null
   5.187 -     * @return the default locale for the specified Category for this instance
   5.188 -     *     of the Java Virtual Machine
   5.189 -     * @see #setDefault(Locale.Category, Locale)
   5.190 -     * @since 1.7
   5.191 -     */
   5.192 -    public static Locale getDefault(Locale.Category category) {
   5.193 -        // do not synchronize this method - see 4071298
   5.194 -        // it's OK if more than one default locale happens to be created
   5.195 -        switch (category) {
   5.196 -        case DISPLAY:
   5.197 -            if (defaultDisplayLocale == null) {
   5.198 -                initDefault(category);
   5.199 -            }
   5.200 -            return defaultDisplayLocale;
   5.201 -        case FORMAT:
   5.202 -            if (defaultFormatLocale == null) {
   5.203 -                initDefault(category);
   5.204 -            }
   5.205 -            return defaultFormatLocale;
   5.206 -        default:
   5.207 -            assert false: "Unknown Category";
   5.208 -        }
   5.209 -        return getDefault();
   5.210 -    }
   5.211 -
   5.212 -    private static void initDefault() {
   5.213 -        String language, region, script, country, variant;
   5.214 -        language = AccessController.doPrivileged(
   5.215 -            new GetPropertyAction("user.language", "en"));
   5.216 -        // for compatibility, check for old user.region property
   5.217 -        region = AccessController.doPrivileged(
   5.218 -            new GetPropertyAction("user.region"));
   5.219 -        if (region != null) {
   5.220 -            // region can be of form country, country_variant, or _variant
   5.221 -            int i = region.indexOf('_');
   5.222 -            if (i >= 0) {
   5.223 -                country = region.substring(0, i);
   5.224 -                variant = region.substring(i + 1);
   5.225 -            } else {
   5.226 -                country = region;
   5.227 -                variant = "";
   5.228 -            }
   5.229 -            script = "";
   5.230 -        } else {
   5.231 -            script = AccessController.doPrivileged(
   5.232 -                new GetPropertyAction("user.script", ""));
   5.233 -            country = AccessController.doPrivileged(
   5.234 -                new GetPropertyAction("user.country", ""));
   5.235 -            variant = AccessController.doPrivileged(
   5.236 -                new GetPropertyAction("user.variant", ""));
   5.237 -        }
   5.238 -        defaultLocale = getInstance(language, script, country, variant, null);
   5.239 -    }
   5.240 -
   5.241 -    private static void initDefault(Locale.Category category) {
   5.242 -        // make sure defaultLocale is initialized
   5.243 -        if (defaultLocale == null) {
   5.244 -            initDefault();
   5.245 -        }
   5.246 -
   5.247 -        Locale defaultCategoryLocale = getInstance(
   5.248 -            AccessController.doPrivileged(
   5.249 -                new GetPropertyAction(category.languageKey, defaultLocale.getLanguage())),
   5.250 -            AccessController.doPrivileged(
   5.251 -                new GetPropertyAction(category.scriptKey, defaultLocale.getScript())),
   5.252 -            AccessController.doPrivileged(
   5.253 -                new GetPropertyAction(category.countryKey, defaultLocale.getCountry())),
   5.254 -            AccessController.doPrivileged(
   5.255 -                new GetPropertyAction(category.variantKey, defaultLocale.getVariant())),
   5.256 -            null);
   5.257 -
   5.258 -        switch (category) {
   5.259 -        case DISPLAY:
   5.260 -            defaultDisplayLocale = defaultCategoryLocale;
   5.261 -            break;
   5.262 -        case FORMAT:
   5.263 -            defaultFormatLocale = defaultCategoryLocale;
   5.264 -            break;
   5.265 -        }
   5.266 +        return Locale.US;
   5.267      }
   5.268  
   5.269      /**
   5.270 @@ -864,60 +656,8 @@
   5.271       * @see SecurityManager#checkPermission
   5.272       * @see java.util.PropertyPermission
   5.273       */
   5.274 -    public static synchronized void setDefault(Locale newLocale) {
   5.275 -        setDefault(Category.DISPLAY, newLocale);
   5.276 -        setDefault(Category.FORMAT, newLocale);
   5.277 -        defaultLocale = newLocale;
   5.278 -    }
   5.279 -
   5.280 -    /**
   5.281 -     * Sets the default locale for the specified Category for this instance
   5.282 -     * of the Java Virtual Machine. This does not affect the host locale.
   5.283 -     * <p>
   5.284 -     * If there is a security manager, its checkPermission method is called
   5.285 -     * with a PropertyPermission("user.language", "write") permission before
   5.286 -     * the default locale is changed.
   5.287 -     * <p>
   5.288 -     * The Java Virtual Machine sets the default locale during startup based
   5.289 -     * on the host environment. It is used by many locale-sensitive methods
   5.290 -     * if no locale is explicitly specified.
   5.291 -     * <p>
   5.292 -     * Since changing the default locale may affect many different areas of
   5.293 -     * functionality, this method should only be used if the caller is
   5.294 -     * prepared to reinitialize locale-sensitive code running within the
   5.295 -     * same Java Virtual Machine.
   5.296 -     * <p>
   5.297 -     *
   5.298 -     * @param category - the specified category to set the default locale
   5.299 -     * @param newLocale - the new default locale
   5.300 -     * @throws SecurityException - if a security manager exists and its
   5.301 -     *     checkPermission method doesn't allow the operation.
   5.302 -     * @throws NullPointerException - if category and/or newLocale is null
   5.303 -     * @see SecurityManager#checkPermission(java.security.Permission)
   5.304 -     * @see PropertyPermission
   5.305 -     * @see #getDefault(Locale.Category)
   5.306 -     * @since 1.7
   5.307 -     */
   5.308 -    public static synchronized void setDefault(Locale.Category category,
   5.309 -        Locale newLocale) {
   5.310 -        if (category == null)
   5.311 -            throw new NullPointerException("Category cannot be NULL");
   5.312 -        if (newLocale == null)
   5.313 -            throw new NullPointerException("Can't set default locale to NULL");
   5.314 -
   5.315 -        SecurityManager sm = System.getSecurityManager();
   5.316 -        if (sm != null) sm.checkPermission(new PropertyPermission
   5.317 -                        ("user.language", "write"));
   5.318 -        switch (category) {
   5.319 -        case DISPLAY:
   5.320 -            defaultDisplayLocale = newLocale;
   5.321 -            break;
   5.322 -        case FORMAT:
   5.323 -            defaultFormatLocale = newLocale;
   5.324 -            break;
   5.325 -        default:
   5.326 -            assert false: "Unknown Category";
   5.327 -        }
   5.328 +    public static void setDefault(Locale newLocale) {
   5.329 +        throw new SecurityException();
   5.330      }
   5.331  
   5.332      /**
   5.333 @@ -931,57 +671,7 @@
   5.334       * @return An array of installed locales.
   5.335       */
   5.336      public static Locale[] getAvailableLocales() {
   5.337 -        return LocaleServiceProviderPool.getAllAvailableLocales();
   5.338 -    }
   5.339 -
   5.340 -    /**
   5.341 -     * Returns a list of all 2-letter country codes defined in ISO 3166.
   5.342 -     * Can be used to create Locales.
   5.343 -     * <p>
   5.344 -     * <b>Note:</b> The <code>Locale</code> class also supports other codes for
   5.345 -     * country (region), such as 3-letter numeric UN M.49 area codes.
   5.346 -     * Therefore, the list returned by this method does not contain ALL valid
   5.347 -     * codes that can be used to create Locales.
   5.348 -     */
   5.349 -    public static String[] getISOCountries() {
   5.350 -        if (isoCountries == null) {
   5.351 -            isoCountries = getISO2Table(LocaleISOData.isoCountryTable);
   5.352 -        }
   5.353 -        String[] result = new String[isoCountries.length];
   5.354 -        System.arraycopy(isoCountries, 0, result, 0, isoCountries.length);
   5.355 -        return result;
   5.356 -    }
   5.357 -
   5.358 -    /**
   5.359 -     * Returns a list of all 2-letter language codes defined in ISO 639.
   5.360 -     * Can be used to create Locales.
   5.361 -     * <p>
   5.362 -     * <b>Note:</b>
   5.363 -     * <ul>
   5.364 -     * <li>ISO 639 is not a stable standard&mdash; some languages' codes have changed.
   5.365 -     * The list this function returns includes both the new and the old codes for the
   5.366 -     * languages whose codes have changed.
   5.367 -     * <li>The <code>Locale</code> class also supports language codes up to
   5.368 -     * 8 characters in length.  Therefore, the list returned by this method does
   5.369 -     * not contain ALL valid codes that can be used to create Locales.
   5.370 -     * </ul>
   5.371 -     */
   5.372 -    public static String[] getISOLanguages() {
   5.373 -        if (isoLanguages == null) {
   5.374 -            isoLanguages = getISO2Table(LocaleISOData.isoLanguageTable);
   5.375 -        }
   5.376 -        String[] result = new String[isoLanguages.length];
   5.377 -        System.arraycopy(isoLanguages, 0, result, 0, isoLanguages.length);
   5.378 -        return result;
   5.379 -    }
   5.380 -
   5.381 -    private static final String[] getISO2Table(String table) {
   5.382 -        int len = table.length() / 5;
   5.383 -        String[] isoTable = new String[len];
   5.384 -        for (int i = 0, j = 0; i < len; i++, j += 5) {
   5.385 -            isoTable[i] = table.substring(j, j + 2);
   5.386 -        }
   5.387 -        return isoTable;
   5.388 +        return new Locale[] { Locale.US };
   5.389      }
   5.390  
   5.391      /**
   5.392 @@ -1004,7 +694,7 @@
   5.393       * @see #getDisplayLanguage
   5.394       */
   5.395      public String getLanguage() {
   5.396 -        return baseLocale.getLanguage();
   5.397 +        return language;
   5.398      }
   5.399  
   5.400      /**
   5.401 @@ -1018,7 +708,7 @@
   5.402       * @since 1.7
   5.403       */
   5.404      public String getScript() {
   5.405 -        return baseLocale.getScript();
   5.406 +        return "";
   5.407      }
   5.408  
   5.409      /**
   5.410 @@ -1030,7 +720,7 @@
   5.411       * @see #getDisplayCountry
   5.412       */
   5.413      public String getCountry() {
   5.414 -        return baseLocale.getRegion();
   5.415 +        return country;
   5.416      }
   5.417  
   5.418      /**
   5.419 @@ -1040,7 +730,11 @@
   5.420       * @see #getDisplayVariant
   5.421       */
   5.422      public String getVariant() {
   5.423 -        return baseLocale.getVariant();
   5.424 +        return variant;
   5.425 +    }
   5.426 +    
   5.427 +    String getRegion() {
   5.428 +        return getCountry();
   5.429      }
   5.430  
   5.431      /**
   5.432 @@ -1059,10 +753,7 @@
   5.433       * @since 1.7
   5.434       */
   5.435      public String getExtension(char key) {
   5.436 -        if (!LocaleExtensions.isValidKey(key)) {
   5.437 -            throw new IllegalArgumentException("Ill-formed extension key: " + key);
   5.438 -        }
   5.439 -        return (localeExtensions == null) ? null : localeExtensions.getExtensionValue(key);
   5.440 +        return null;
   5.441      }
   5.442  
   5.443      /**
   5.444 @@ -1075,10 +766,7 @@
   5.445       * @since 1.7
   5.446       */
   5.447      public Set<Character> getExtensionKeys() {
   5.448 -        if (localeExtensions == null) {
   5.449 -            return Collections.emptySet();
   5.450 -        }
   5.451 -        return localeExtensions.getKeys();
   5.452 +        return Collections.emptySet();
   5.453      }
   5.454  
   5.455      /**
   5.456 @@ -1090,10 +778,7 @@
   5.457       * @since 1.7
   5.458       */
   5.459      public Set<String> getUnicodeLocaleAttributes() {
   5.460 -        if (localeExtensions == null) {
   5.461 -            return Collections.emptySet();
   5.462 -        }
   5.463 -        return localeExtensions.getUnicodeLocaleAttributes();
   5.464 +        return Collections.emptySet();
   5.465      }
   5.466  
   5.467      /**
   5.468 @@ -1111,10 +796,7 @@
   5.469       * @since 1.7
   5.470       */
   5.471      public String getUnicodeLocaleType(String key) {
   5.472 -        if (!UnicodeLocaleExtension.isKey(key)) {
   5.473 -            throw new IllegalArgumentException("Ill-formed Unicode locale key: " + key);
   5.474 -        }
   5.475 -        return (localeExtensions == null) ? null : localeExtensions.getUnicodeLocaleType(key);
   5.476 +        return null;
   5.477      }
   5.478  
   5.479      /**
   5.480 @@ -1126,32 +808,10 @@
   5.481       * @since 1.7
   5.482       */
   5.483      public Set<String> getUnicodeLocaleKeys() {
   5.484 -        if (localeExtensions == null) {
   5.485 -            return Collections.emptySet();
   5.486 -        }
   5.487 -        return localeExtensions.getUnicodeLocaleKeys();
   5.488 +        return Collections.emptySet();
   5.489      }
   5.490  
   5.491      /**
   5.492 -     * Package locale method returning the Locale's BaseLocale,
   5.493 -     * used by ResourceBundle
   5.494 -     * @return base locale of this Locale
   5.495 -     */
   5.496 -    BaseLocale getBaseLocale() {
   5.497 -        return baseLocale;
   5.498 -    }
   5.499 -
   5.500 -    /**
   5.501 -     * Package private method returning the Locale's LocaleExtensions,
   5.502 -     * used by ResourceBundle.
   5.503 -     * @return locale exnteions of this Locale,
   5.504 -     *         or {@code null} if no extensions are defined
   5.505 -     */
   5.506 -     LocaleExtensions getLocaleExtensions() {
   5.507 -         return localeExtensions;
   5.508 -     }
   5.509 -
   5.510 -    /**
   5.511       * Returns a string representation of this <code>Locale</code>
   5.512       * object, consisting of language, country, variant, script,
   5.513       * and extensions as below:
   5.514 @@ -1195,11 +855,12 @@
   5.515       */
   5.516      @Override
   5.517      public final String toString() {
   5.518 +        Locale baseLocale = this;
   5.519          boolean l = (baseLocale.getLanguage().length() != 0);
   5.520          boolean s = (baseLocale.getScript().length() != 0);
   5.521          boolean r = (baseLocale.getRegion().length() != 0);
   5.522          boolean v = (baseLocale.getVariant().length() != 0);
   5.523 -        boolean e = (localeExtensions != null && localeExtensions.getID().length() != 0);
   5.524 +        boolean e = false; //(localeExtensions != null && localeExtensions.getID().length() != 0);
   5.525  
   5.526          StringBuilder result = new StringBuilder(baseLocale.getLanguage());
   5.527          if (r || (l && (v || s || e))) {
   5.528 @@ -1221,635 +882,13 @@
   5.529              if (!s) {
   5.530                  result.append('#');
   5.531              }
   5.532 -            result.append(localeExtensions.getID());
   5.533 +//            result.append(localeExtensions.getID());
   5.534          }
   5.535  
   5.536          return result.toString();
   5.537      }
   5.538  
   5.539 -    /**
   5.540 -     * Returns a well-formed IETF BCP 47 language tag representing
   5.541 -     * this locale.
   5.542 -     *
   5.543 -     * <p>If this <code>Locale</code> has a language, country, or
   5.544 -     * variant that does not satisfy the IETF BCP 47 language tag
   5.545 -     * syntax requirements, this method handles these fields as
   5.546 -     * described below:
   5.547 -     *
   5.548 -     * <p><b>Language:</b> If language is empty, or not <a
   5.549 -     * href="#def_language" >well-formed</a> (for example "a" or
   5.550 -     * "e2"), it will be emitted as "und" (Undetermined).
   5.551 -     *
   5.552 -     * <p><b>Country:</b> If country is not <a
   5.553 -     * href="#def_region">well-formed</a> (for example "12" or "USA"),
   5.554 -     * it will be omitted.
   5.555 -     *
   5.556 -     * <p><b>Variant:</b> If variant <b>is</b> <a
   5.557 -     * href="#def_variant">well-formed</a>, each sub-segment
   5.558 -     * (delimited by '-' or '_') is emitted as a subtag.  Otherwise:
   5.559 -     * <ul>
   5.560 -     *
   5.561 -     * <li>if all sub-segments match <code>[0-9a-zA-Z]{1,8}</code>
   5.562 -     * (for example "WIN" or "Oracle_JDK_Standard_Edition"), the first
   5.563 -     * ill-formed sub-segment and all following will be appended to
   5.564 -     * the private use subtag.  The first appended subtag will be
   5.565 -     * "lvariant", followed by the sub-segments in order, separated by
   5.566 -     * hyphen. For example, "x-lvariant-WIN",
   5.567 -     * "Oracle-x-lvariant-JDK-Standard-Edition".
   5.568 -     *
   5.569 -     * <li>if any sub-segment does not match
   5.570 -     * <code>[0-9a-zA-Z]{1,8}</code>, the variant will be truncated
   5.571 -     * and the problematic sub-segment and all following sub-segments
   5.572 -     * will be omitted.  If the remainder is non-empty, it will be
   5.573 -     * emitted as a private use subtag as above (even if the remainder
   5.574 -     * turns out to be well-formed).  For example,
   5.575 -     * "Solaris_isjustthecoolestthing" is emitted as
   5.576 -     * "x-lvariant-Solaris", not as "solaris".</li></ul>
   5.577 -     *
   5.578 -     * <p><b>Special Conversions:</b> Java supports some old locale
   5.579 -     * representations, including deprecated ISO language codes,
   5.580 -     * for compatibility. This method performs the following
   5.581 -     * conversions:
   5.582 -     * <ul>
   5.583 -     *
   5.584 -     * <li>Deprecated ISO language codes "iw", "ji", and "in" are
   5.585 -     * converted to "he", "yi", and "id", respectively.
   5.586 -     *
   5.587 -     * <li>A locale with language "no", country "NO", and variant
   5.588 -     * "NY", representing Norwegian Nynorsk (Norway), is converted
   5.589 -     * to a language tag "nn-NO".</li></ul>
   5.590 -     *
   5.591 -     * <p><b>Note:</b> Although the language tag created by this
   5.592 -     * method is well-formed (satisfies the syntax requirements
   5.593 -     * defined by the IETF BCP 47 specification), it is not
   5.594 -     * necessarily a valid BCP 47 language tag.  For example,
   5.595 -     * <pre>
   5.596 -     *   new Locale("xx", "YY").toLanguageTag();</pre>
   5.597 -     *
   5.598 -     * will return "xx-YY", but the language subtag "xx" and the
   5.599 -     * region subtag "YY" are invalid because they are not registered
   5.600 -     * in the IANA Language Subtag Registry.
   5.601 -     *
   5.602 -     * @return a BCP47 language tag representing the locale
   5.603 -     * @see #forLanguageTag(String)
   5.604 -     * @since 1.7
   5.605 -     */
   5.606 -    public String toLanguageTag() {
   5.607 -        LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions);
   5.608 -        StringBuilder buf = new StringBuilder();
   5.609 -
   5.610 -        String subtag = tag.getLanguage();
   5.611 -        if (subtag.length() > 0) {
   5.612 -            buf.append(LanguageTag.canonicalizeLanguage(subtag));
   5.613 -        }
   5.614 -
   5.615 -        subtag = tag.getScript();
   5.616 -        if (subtag.length() > 0) {
   5.617 -            buf.append(LanguageTag.SEP);
   5.618 -            buf.append(LanguageTag.canonicalizeScript(subtag));
   5.619 -        }
   5.620 -
   5.621 -        subtag = tag.getRegion();
   5.622 -        if (subtag.length() > 0) {
   5.623 -            buf.append(LanguageTag.SEP);
   5.624 -            buf.append(LanguageTag.canonicalizeRegion(subtag));
   5.625 -        }
   5.626 -
   5.627 -        List<String>subtags = tag.getVariants();
   5.628 -        for (String s : subtags) {
   5.629 -            buf.append(LanguageTag.SEP);
   5.630 -            // preserve casing
   5.631 -            buf.append(s);
   5.632 -        }
   5.633 -
   5.634 -        subtags = tag.getExtensions();
   5.635 -        for (String s : subtags) {
   5.636 -            buf.append(LanguageTag.SEP);
   5.637 -            buf.append(LanguageTag.canonicalizeExtension(s));
   5.638 -        }
   5.639 -
   5.640 -        subtag = tag.getPrivateuse();
   5.641 -        if (subtag.length() > 0) {
   5.642 -            if (buf.length() > 0) {
   5.643 -                buf.append(LanguageTag.SEP);
   5.644 -            }
   5.645 -            buf.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP);
   5.646 -            // preserve casing
   5.647 -            buf.append(subtag);
   5.648 -        }
   5.649 -
   5.650 -        return buf.toString();
   5.651 -    }
   5.652 -
   5.653 -    /**
   5.654 -     * Returns a locale for the specified IETF BCP 47 language tag string.
   5.655 -     *
   5.656 -     * <p>If the specified language tag contains any ill-formed subtags,
   5.657 -     * the first such subtag and all following subtags are ignored.  Compare
   5.658 -     * to {@link Locale.Builder#setLanguageTag} which throws an exception
   5.659 -     * in this case.
   5.660 -     *
   5.661 -     * <p>The following <b>conversions</b> are performed:<ul>
   5.662 -     *
   5.663 -     * <li>The language code "und" is mapped to language "".
   5.664 -     *
   5.665 -     * <li>The language codes "he", "yi", and "id" are mapped to "iw",
   5.666 -     * "ji", and "in" respectively. (This is the same canonicalization
   5.667 -     * that's done in Locale's constructors.)
   5.668 -     *
   5.669 -     * <li>The portion of a private use subtag prefixed by "lvariant",
   5.670 -     * if any, is removed and appended to the variant field in the
   5.671 -     * result locale (without case normalization).  If it is then
   5.672 -     * empty, the private use subtag is discarded:
   5.673 -     *
   5.674 -     * <pre>
   5.675 -     *     Locale loc;
   5.676 -     *     loc = Locale.forLanguageTag("en-US-x-lvariant-POSIX");
   5.677 -     *     loc.getVariant(); // returns "POSIX"
   5.678 -     *     loc.getExtension('x'); // returns null
   5.679 -     *
   5.680 -     *     loc = Locale.forLanguageTag("de-POSIX-x-URP-lvariant-Abc-Def");
   5.681 -     *     loc.getVariant(); // returns "POSIX_Abc_Def"
   5.682 -     *     loc.getExtension('x'); // returns "urp"
   5.683 -     * </pre>
   5.684 -     *
   5.685 -     * <li>When the languageTag argument contains an extlang subtag,
   5.686 -     * the first such subtag is used as the language, and the primary
   5.687 -     * language subtag and other extlang subtags are ignored:
   5.688 -     *
   5.689 -     * <pre>
   5.690 -     *     Locale.forLanguageTag("ar-aao").getLanguage(); // returns "aao"
   5.691 -     *     Locale.forLanguageTag("en-abc-def-us").toString(); // returns "abc_US"
   5.692 -     * </pre>
   5.693 -     *
   5.694 -     * <li>Case is normalized except for variant tags, which are left
   5.695 -     * unchanged.  Language is normalized to lower case, script to
   5.696 -     * title case, country to upper case, and extensions to lower
   5.697 -     * case.
   5.698 -     *
   5.699 -     * <li>If, after processing, the locale would exactly match either
   5.700 -     * ja_JP_JP or th_TH_TH with no extensions, the appropriate
   5.701 -     * extensions are added as though the constructor had been called:
   5.702 -     *
   5.703 -     * <pre>
   5.704 -     *    Locale.forLanguageTag("ja-JP-x-lvariant-JP").toLanguageTag();
   5.705 -     *    // returns "ja-JP-u-ca-japanese-x-lvariant-JP"
   5.706 -     *    Locale.forLanguageTag("th-TH-x-lvariant-TH").toLanguageTag();
   5.707 -     *    // returns "th-TH-u-nu-thai-x-lvariant-TH"
   5.708 -     * <pre></ul>
   5.709 -     *
   5.710 -     * <p>This implements the 'Language-Tag' production of BCP47, and
   5.711 -     * so supports grandfathered (regular and irregular) as well as
   5.712 -     * private use language tags.  Stand alone private use tags are
   5.713 -     * represented as empty language and extension 'x-whatever',
   5.714 -     * and grandfathered tags are converted to their canonical replacements
   5.715 -     * where they exist.
   5.716 -     *
   5.717 -     * <p>Grandfathered tags with canonical replacements are as follows:
   5.718 -     *
   5.719 -     * <table>
   5.720 -     * <tbody align="center">
   5.721 -     * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>modern replacement</th></tr>
   5.722 -     * <tr><td>art-lojban</td><td>&nbsp;</td><td>jbo</td></tr>
   5.723 -     * <tr><td>i-ami</td><td>&nbsp;</td><td>ami</td></tr>
   5.724 -     * <tr><td>i-bnn</td><td>&nbsp;</td><td>bnn</td></tr>
   5.725 -     * <tr><td>i-hak</td><td>&nbsp;</td><td>hak</td></tr>
   5.726 -     * <tr><td>i-klingon</td><td>&nbsp;</td><td>tlh</td></tr>
   5.727 -     * <tr><td>i-lux</td><td>&nbsp;</td><td>lb</td></tr>
   5.728 -     * <tr><td>i-navajo</td><td>&nbsp;</td><td>nv</td></tr>
   5.729 -     * <tr><td>i-pwn</td><td>&nbsp;</td><td>pwn</td></tr>
   5.730 -     * <tr><td>i-tao</td><td>&nbsp;</td><td>tao</td></tr>
   5.731 -     * <tr><td>i-tay</td><td>&nbsp;</td><td>tay</td></tr>
   5.732 -     * <tr><td>i-tsu</td><td>&nbsp;</td><td>tsu</td></tr>
   5.733 -     * <tr><td>no-bok</td><td>&nbsp;</td><td>nb</td></tr>
   5.734 -     * <tr><td>no-nyn</td><td>&nbsp;</td><td>nn</td></tr>
   5.735 -     * <tr><td>sgn-BE-FR</td><td>&nbsp;</td><td>sfb</td></tr>
   5.736 -     * <tr><td>sgn-BE-NL</td><td>&nbsp;</td><td>vgt</td></tr>
   5.737 -     * <tr><td>sgn-CH-DE</td><td>&nbsp;</td><td>sgg</td></tr>
   5.738 -     * <tr><td>zh-guoyu</td><td>&nbsp;</td><td>cmn</td></tr>
   5.739 -     * <tr><td>zh-hakka</td><td>&nbsp;</td><td>hak</td></tr>
   5.740 -     * <tr><td>zh-min-nan</td><td>&nbsp;</td><td>nan</td></tr>
   5.741 -     * <tr><td>zh-xiang</td><td>&nbsp;</td><td>hsn</td></tr>
   5.742 -     * </tbody>
   5.743 -     * </table>
   5.744 -     *
   5.745 -     * <p>Grandfathered tags with no modern replacement will be
   5.746 -     * converted as follows:
   5.747 -     *
   5.748 -     * <table>
   5.749 -     * <tbody align="center">
   5.750 -     * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>converts to</th></tr>
   5.751 -     * <tr><td>cel-gaulish</td><td>&nbsp;</td><td>xtg-x-cel-gaulish</td></tr>
   5.752 -     * <tr><td>en-GB-oed</td><td>&nbsp;</td><td>en-GB-x-oed</td></tr>
   5.753 -     * <tr><td>i-default</td><td>&nbsp;</td><td>en-x-i-default</td></tr>
   5.754 -     * <tr><td>i-enochian</td><td>&nbsp;</td><td>und-x-i-enochian</td></tr>
   5.755 -     * <tr><td>i-mingo</td><td>&nbsp;</td><td>see-x-i-mingo</td></tr>
   5.756 -     * <tr><td>zh-min</td><td>&nbsp;</td><td>nan-x-zh-min</td></tr>
   5.757 -     * </tbody>
   5.758 -     * </table>
   5.759 -     *
   5.760 -     * <p>For a list of all grandfathered tags, see the
   5.761 -     * IANA Language Subtag Registry (search for "Type: grandfathered").
   5.762 -     *
   5.763 -     * <p><b>Note</b>: there is no guarantee that <code>toLanguageTag</code>
   5.764 -     * and <code>forLanguageTag</code> will round-trip.
   5.765 -     *
   5.766 -     * @param languageTag the language tag
   5.767 -     * @return The locale that best represents the language tag.
   5.768 -     * @throws NullPointerException if <code>languageTag</code> is <code>null</code>
   5.769 -     * @see #toLanguageTag()
   5.770 -     * @see java.util.Locale.Builder#setLanguageTag(String)
   5.771 -     * @since 1.7
   5.772 -     */
   5.773 -    public static Locale forLanguageTag(String languageTag) {
   5.774 -        LanguageTag tag = LanguageTag.parse(languageTag, null);
   5.775 -        InternalLocaleBuilder bldr = new InternalLocaleBuilder();
   5.776 -        bldr.setLanguageTag(tag);
   5.777 -        BaseLocale base = bldr.getBaseLocale();
   5.778 -        LocaleExtensions exts = bldr.getLocaleExtensions();
   5.779 -        if (exts == null && base.getVariant().length() > 0) {
   5.780 -            exts = getCompatibilityExtensions(base.getLanguage(), base.getScript(),
   5.781 -                                              base.getRegion(), base.getVariant());
   5.782 -        }
   5.783 -        return getInstance(base, exts);
   5.784 -    }
   5.785 -
   5.786 -    /**
   5.787 -     * Returns a three-letter abbreviation of this locale's language.
   5.788 -     * If the language matches an ISO 639-1 two-letter code, the
   5.789 -     * corresponding ISO 639-2/T three-letter lowercase code is
   5.790 -     * returned.  The ISO 639-2 language codes can be found on-line,
   5.791 -     * see "Codes for the Representation of Names of Languages Part 2:
   5.792 -     * Alpha-3 Code".  If the locale specifies a three-letter
   5.793 -     * language, the language is returned as is.  If the locale does
   5.794 -     * not specify a language the empty string is returned.
   5.795 -     *
   5.796 -     * @return A three-letter abbreviation of this locale's language.
   5.797 -     * @exception MissingResourceException Throws MissingResourceException if
   5.798 -     * three-letter language abbreviation is not available for this locale.
   5.799 -     */
   5.800 -    public String getISO3Language() throws MissingResourceException {
   5.801 -        String lang = baseLocale.getLanguage();
   5.802 -        if (lang.length() == 3) {
   5.803 -            return lang;
   5.804 -        }
   5.805 -
   5.806 -        String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
   5.807 -        if (language3 == null) {
   5.808 -            throw new MissingResourceException("Couldn't find 3-letter language code for "
   5.809 -                    + lang, "FormatData_" + toString(), "ShortLanguage");
   5.810 -        }
   5.811 -        return language3;
   5.812 -    }
   5.813 -
   5.814 -    /**
   5.815 -     * Returns a three-letter abbreviation for this locale's country.
   5.816 -     * If the country matches an ISO 3166-1 alpha-2 code, the
   5.817 -     * corresponding ISO 3166-1 alpha-3 uppercase code is returned.
   5.818 -     * If the locale doesn't specify a country, this will be the empty
   5.819 -     * string.
   5.820 -     *
   5.821 -     * <p>The ISO 3166-1 codes can be found on-line.
   5.822 -     *
   5.823 -     * @return A three-letter abbreviation of this locale's country.
   5.824 -     * @exception MissingResourceException Throws MissingResourceException if the
   5.825 -     * three-letter country abbreviation is not available for this locale.
   5.826 -     */
   5.827 -    public String getISO3Country() throws MissingResourceException {
   5.828 -        String country3 = getISO3Code(baseLocale.getRegion(), LocaleISOData.isoCountryTable);
   5.829 -        if (country3 == null) {
   5.830 -            throw new MissingResourceException("Couldn't find 3-letter country code for "
   5.831 -                    + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry");
   5.832 -        }
   5.833 -        return country3;
   5.834 -    }
   5.835 -
   5.836 -    private static final String getISO3Code(String iso2Code, String table) {
   5.837 -        int codeLength = iso2Code.length();
   5.838 -        if (codeLength == 0) {
   5.839 -            return "";
   5.840 -        }
   5.841 -
   5.842 -        int tableLength = table.length();
   5.843 -        int index = tableLength;
   5.844 -        if (codeLength == 2) {
   5.845 -            char c1 = iso2Code.charAt(0);
   5.846 -            char c2 = iso2Code.charAt(1);
   5.847 -            for (index = 0; index < tableLength; index += 5) {
   5.848 -                if (table.charAt(index) == c1
   5.849 -                    && table.charAt(index + 1) == c2) {
   5.850 -                    break;
   5.851 -                }
   5.852 -            }
   5.853 -        }
   5.854 -        return index < tableLength ? table.substring(index + 2, index + 5) : null;
   5.855 -    }
   5.856 -
   5.857 -    /**
   5.858 -     * Returns a name for the locale's language that is appropriate for display to the
   5.859 -     * user.
   5.860 -     * If possible, the name returned will be localized for the default locale.
   5.861 -     * For example, if the locale is fr_FR and the default locale
   5.862 -     * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
   5.863 -     * the default locale is fr_FR, getDisplayLanguage() will return "anglais".
   5.864 -     * If the name returned cannot be localized for the default locale,
   5.865 -     * (say, we don't have a Japanese name for Croatian),
   5.866 -     * this function falls back on the English name, and uses the ISO code as a last-resort
   5.867 -     * value.  If the locale doesn't specify a language, this function returns the empty string.
   5.868 -     */
   5.869 -    public final String getDisplayLanguage() {
   5.870 -        return getDisplayLanguage(getDefault(Category.DISPLAY));
   5.871 -    }
   5.872 -
   5.873 -    /**
   5.874 -     * Returns a name for the locale's language that is appropriate for display to the
   5.875 -     * user.
   5.876 -     * If possible, the name returned will be localized according to inLocale.
   5.877 -     * For example, if the locale is fr_FR and inLocale
   5.878 -     * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
   5.879 -     * inLocale is fr_FR, getDisplayLanguage() will return "anglais".
   5.880 -     * If the name returned cannot be localized according to inLocale,
   5.881 -     * (say, we don't have a Japanese name for Croatian),
   5.882 -     * this function falls back on the English name, and finally
   5.883 -     * on the ISO code as a last-resort value.  If the locale doesn't specify a language,
   5.884 -     * this function returns the empty string.
   5.885 -     *
   5.886 -     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
   5.887 -     */
   5.888 -    public String getDisplayLanguage(Locale inLocale) {
   5.889 -        return getDisplayString(baseLocale.getLanguage(), inLocale, DISPLAY_LANGUAGE);
   5.890 -    }
   5.891 -
   5.892 -    /**
   5.893 -     * Returns a name for the the locale's script that is appropriate for display to
   5.894 -     * the user. If possible, the name will be localized for the default locale.  Returns
   5.895 -     * the empty string if this locale doesn't specify a script code.
   5.896 -     *
   5.897 -     * @return the display name of the script code for the current default locale
   5.898 -     * @since 1.7
   5.899 -     */
   5.900 -    public String getDisplayScript() {
   5.901 -        return getDisplayScript(getDefault());
   5.902 -    }
   5.903 -
   5.904 -    /**
   5.905 -     * Returns a name for the locale's script that is appropriate
   5.906 -     * for display to the user. If possible, the name will be
   5.907 -     * localized for the given locale. Returns the empty string if
   5.908 -     * this locale doesn't specify a script code.
   5.909 -     *
   5.910 -     * @return the display name of the script code for the current default locale
   5.911 -     * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
   5.912 -     * @since 1.7
   5.913 -     */
   5.914 -    public String getDisplayScript(Locale inLocale) {
   5.915 -        return getDisplayString(baseLocale.getScript(), inLocale, DISPLAY_SCRIPT);
   5.916 -    }
   5.917 -
   5.918 -    /**
   5.919 -     * Returns a name for the locale's country that is appropriate for display to the
   5.920 -     * user.
   5.921 -     * If possible, the name returned will be localized for the default locale.
   5.922 -     * For example, if the locale is fr_FR and the default locale
   5.923 -     * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
   5.924 -     * the default locale is fr_FR, getDisplayCountry() will return "Etats-Unis".
   5.925 -     * If the name returned cannot be localized for the default locale,
   5.926 -     * (say, we don't have a Japanese name for Croatia),
   5.927 -     * this function falls back on the English name, and uses the ISO code as a last-resort
   5.928 -     * value.  If the locale doesn't specify a country, this function returns the empty string.
   5.929 -     */
   5.930 -    public final String getDisplayCountry() {
   5.931 -        return getDisplayCountry(getDefault(Category.DISPLAY));
   5.932 -    }
   5.933 -
   5.934 -    /**
   5.935 -     * Returns a name for the locale's country that is appropriate for display to the
   5.936 -     * user.
   5.937 -     * If possible, the name returned will be localized according to inLocale.
   5.938 -     * For example, if the locale is fr_FR and inLocale
   5.939 -     * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
   5.940 -     * inLocale is fr_FR, getDisplayCountry() will return "Etats-Unis".
   5.941 -     * If the name returned cannot be localized according to inLocale.
   5.942 -     * (say, we don't have a Japanese name for Croatia),
   5.943 -     * this function falls back on the English name, and finally
   5.944 -     * on the ISO code as a last-resort value.  If the locale doesn't specify a country,
   5.945 -     * this function returns the empty string.
   5.946 -     *
   5.947 -     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
   5.948 -     */
   5.949 -    public String getDisplayCountry(Locale inLocale) {
   5.950 -        return getDisplayString(baseLocale.getRegion(), inLocale, DISPLAY_COUNTRY);
   5.951 -    }
   5.952 -
   5.953 -    private String getDisplayString(String code, Locale inLocale, int type) {
   5.954 -        if (code.length() == 0) {
   5.955 -            return "";
   5.956 -        }
   5.957 -
   5.958 -        if (inLocale == null) {
   5.959 -            throw new NullPointerException();
   5.960 -        }
   5.961 -
   5.962 -        try {
   5.963 -            OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
   5.964 -            String key = (type == DISPLAY_VARIANT ? "%%"+code : code);
   5.965 -            String result = null;
   5.966 -
   5.967 -            // Check whether a provider can provide an implementation that's closer
   5.968 -            // to the requested locale than what the Java runtime itself can provide.
   5.969 -            LocaleServiceProviderPool pool =
   5.970 -                LocaleServiceProviderPool.getPool(LocaleNameProvider.class);
   5.971 -            if (pool.hasProviders()) {
   5.972 -                result = pool.getLocalizedObject(
   5.973 -                                    LocaleNameGetter.INSTANCE,
   5.974 -                                    inLocale, bundle, key,
   5.975 -                                    type, code);
   5.976 -            }
   5.977 -
   5.978 -            if (result == null) {
   5.979 -                result = bundle.getString(key);
   5.980 -            }
   5.981 -
   5.982 -            if (result != null) {
   5.983 -                return result;
   5.984 -            }
   5.985 -        }
   5.986 -        catch (Exception e) {
   5.987 -            // just fall through
   5.988 -        }
   5.989 -        return code;
   5.990 -    }
   5.991 -
   5.992 -    /**
   5.993 -     * Returns a name for the locale's variant code that is appropriate for display to the
   5.994 -     * user.  If possible, the name will be localized for the default locale.  If the locale
   5.995 -     * doesn't specify a variant code, this function returns the empty string.
   5.996 -     */
   5.997 -    public final String getDisplayVariant() {
   5.998 -        return getDisplayVariant(getDefault(Category.DISPLAY));
   5.999 -    }
  5.1000 -
  5.1001 -    /**
  5.1002 -     * Returns a name for the locale's variant code that is appropriate for display to the
  5.1003 -     * user.  If possible, the name will be localized for inLocale.  If the locale
  5.1004 -     * doesn't specify a variant code, this function returns the empty string.
  5.1005 -     *
  5.1006 -     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
  5.1007 -     */
  5.1008 -    public String getDisplayVariant(Locale inLocale) {
  5.1009 -        if (baseLocale.getVariant().length() == 0)
  5.1010 -            return "";
  5.1011 -
  5.1012 -        OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
  5.1013 -
  5.1014 -        String names[] = getDisplayVariantArray(bundle, inLocale);
  5.1015 -
  5.1016 -        // Get the localized patterns for formatting a list, and use
  5.1017 -        // them to format the list.
  5.1018 -        String listPattern = null;
  5.1019 -        String listCompositionPattern = null;
  5.1020 -        try {
  5.1021 -            listPattern = bundle.getString("ListPattern");
  5.1022 -            listCompositionPattern = bundle.getString("ListCompositionPattern");
  5.1023 -        } catch (MissingResourceException e) {
  5.1024 -        }
  5.1025 -        return formatList(names, listPattern, listCompositionPattern);
  5.1026 -    }
  5.1027 -
  5.1028 -    /**
  5.1029 -     * Returns a name for the locale that is appropriate for display to the
  5.1030 -     * user. This will be the values returned by getDisplayLanguage(),
  5.1031 -     * getDisplayScript(), getDisplayCountry(), and getDisplayVariant() assembled
  5.1032 -     * into a single string. The the non-empty values are used in order,
  5.1033 -     * with the second and subsequent names in parentheses.  For example:
  5.1034 -     * <blockquote>
  5.1035 -     * language (script, country, variant)<br>
  5.1036 -     * language (country)<br>
  5.1037 -     * language (variant)<br>
  5.1038 -     * script (country)<br>
  5.1039 -     * country<br>
  5.1040 -     * </blockquote>
  5.1041 -     * depending on which fields are specified in the locale.  If the
  5.1042 -     * language, sacript, country, and variant fields are all empty,
  5.1043 -     * this function returns the empty string.
  5.1044 -     */
  5.1045 -    public final String getDisplayName() {
  5.1046 -        return getDisplayName(getDefault(Category.DISPLAY));
  5.1047 -    }
  5.1048 -
  5.1049 -    /**
  5.1050 -     * Returns a name for the locale that is appropriate for display
  5.1051 -     * to the user.  This will be the values returned by
  5.1052 -     * getDisplayLanguage(), getDisplayScript(),getDisplayCountry(),
  5.1053 -     * and getDisplayVariant() assembled into a single string.
  5.1054 -     * The non-empty values are used in order,
  5.1055 -     * with the second and subsequent names in parentheses.  For example:
  5.1056 -     * <blockquote>
  5.1057 -     * language (script, country, variant)<br>
  5.1058 -     * language (country)<br>
  5.1059 -     * language (variant)<br>
  5.1060 -     * script (country)<br>
  5.1061 -     * country<br>
  5.1062 -     * </blockquote>
  5.1063 -     * depending on which fields are specified in the locale.  If the
  5.1064 -     * language, script, country, and variant fields are all empty,
  5.1065 -     * this function returns the empty string.
  5.1066 -     *
  5.1067 -     * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
  5.1068 -     */
  5.1069 -    public String getDisplayName(Locale inLocale) {
  5.1070 -        OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
  5.1071 -
  5.1072 -        String languageName = getDisplayLanguage(inLocale);
  5.1073 -        String scriptName = getDisplayScript(inLocale);
  5.1074 -        String countryName = getDisplayCountry(inLocale);
  5.1075 -        String[] variantNames = getDisplayVariantArray(bundle, inLocale);
  5.1076 -
  5.1077 -        // Get the localized patterns for formatting a display name.
  5.1078 -        String displayNamePattern = null;
  5.1079 -        String listPattern = null;
  5.1080 -        String listCompositionPattern = null;
  5.1081 -        try {
  5.1082 -            displayNamePattern = bundle.getString("DisplayNamePattern");
  5.1083 -            listPattern = bundle.getString("ListPattern");
  5.1084 -            listCompositionPattern = bundle.getString("ListCompositionPattern");
  5.1085 -        } catch (MissingResourceException e) {
  5.1086 -        }
  5.1087 -
  5.1088 -        // The display name consists of a main name, followed by qualifiers.
  5.1089 -        // Typically, the format is "MainName (Qualifier, Qualifier)" but this
  5.1090 -        // depends on what pattern is stored in the display locale.
  5.1091 -        String   mainName       = null;
  5.1092 -        String[] qualifierNames = null;
  5.1093 -
  5.1094 -        // The main name is the language, or if there is no language, the script,
  5.1095 -        // then if no script, the country. If there is no language/script/country
  5.1096 -        // (an anomalous situation) then the display name is simply the variant's
  5.1097 -        // display name.
  5.1098 -        if (languageName.length() == 0 && scriptName.length() == 0 && countryName.length() == 0) {
  5.1099 -            if (variantNames.length == 0) {
  5.1100 -                return "";
  5.1101 -            } else {
  5.1102 -                return formatList(variantNames, listPattern, listCompositionPattern);
  5.1103 -            }
  5.1104 -        }
  5.1105 -        ArrayList<String> names = new ArrayList<>(4);
  5.1106 -        if (languageName.length() != 0) {
  5.1107 -            names.add(languageName);
  5.1108 -        }
  5.1109 -        if (scriptName.length() != 0) {
  5.1110 -            names.add(scriptName);
  5.1111 -        }
  5.1112 -        if (countryName.length() != 0) {
  5.1113 -            names.add(countryName);
  5.1114 -        }
  5.1115 -        if (variantNames.length != 0) {
  5.1116 -            for (String var : variantNames) {
  5.1117 -                names.add(var);
  5.1118 -            }
  5.1119 -        }
  5.1120 -
  5.1121 -        // The first one in the main name
  5.1122 -        mainName = names.get(0);
  5.1123 -
  5.1124 -        // Others are qualifiers
  5.1125 -        int numNames = names.size();
  5.1126 -        qualifierNames = (numNames > 1) ?
  5.1127 -                names.subList(1, numNames).toArray(new String[numNames - 1]) : new String[0];
  5.1128 -
  5.1129 -        // Create an array whose first element is the number of remaining
  5.1130 -        // elements.  This serves as a selector into a ChoiceFormat pattern from
  5.1131 -        // the resource.  The second and third elements are the main name and
  5.1132 -        // the qualifier; if there are no qualifiers, the third element is
  5.1133 -        // unused by the format pattern.
  5.1134 -        Object[] displayNames = {
  5.1135 -            new Integer(qualifierNames.length != 0 ? 2 : 1),
  5.1136 -            mainName,
  5.1137 -            // We could also just call formatList() and have it handle the empty
  5.1138 -            // list case, but this is more efficient, and we want it to be
  5.1139 -            // efficient since all the language-only locales will not have any
  5.1140 -            // qualifiers.
  5.1141 -            qualifierNames.length != 0 ? formatList(qualifierNames, listPattern, listCompositionPattern) : null
  5.1142 -        };
  5.1143 -
  5.1144 -        if (displayNamePattern != null) {
  5.1145 -            return new MessageFormat(displayNamePattern).format(displayNames);
  5.1146 -        }
  5.1147 -        else {
  5.1148 -            // If we cannot get the message format pattern, then we use a simple
  5.1149 -            // hard-coded pattern.  This should not occur in practice unless the
  5.1150 -            // installation is missing some core files (FormatData etc.).
  5.1151 -            StringBuilder result = new StringBuilder();
  5.1152 -            result.append((String)displayNames[1]);
  5.1153 -            if (displayNames.length > 2) {
  5.1154 -                result.append(" (");
  5.1155 -                result.append((String)displayNames[2]);
  5.1156 -                result.append(')');
  5.1157 -            }
  5.1158 -            return result.toString();
  5.1159 -        }
  5.1160 -    }
  5.1161 -
  5.1162 +    
  5.1163      /**
  5.1164       * Overrides Cloneable.
  5.1165       */
  5.1166 @@ -1870,691 +909,34 @@
  5.1167       */
  5.1168      @Override
  5.1169      public int hashCode() {
  5.1170 -        int hc = hashCodeValue;
  5.1171 -        if (hc == 0) {
  5.1172 -            hc = baseLocale.hashCode();
  5.1173 -            if (localeExtensions != null) {
  5.1174 -                hc ^= localeExtensions.hashCode();
  5.1175 -            }
  5.1176 -            hashCodeValue = hc;
  5.1177 -        }
  5.1178 -        return hc;
  5.1179 +        int hash = 3;
  5.1180 +        hash = 43 * hash + Objects.hashCode(this.language);
  5.1181 +        hash = 43 * hash + Objects.hashCode(this.country);
  5.1182 +        hash = 43 * hash + Objects.hashCode(this.variant);
  5.1183 +        return hash;
  5.1184      }
  5.1185  
  5.1186      // Overrides
  5.1187 -
  5.1188 -    /**
  5.1189 -     * Returns true if this Locale is equal to another object.  A Locale is
  5.1190 -     * deemed equal to another Locale with identical language, script, country,
  5.1191 -     * variant and extensions, and unequal to all other objects.
  5.1192 -     *
  5.1193 -     * @return true if this Locale is equal to the specified object.
  5.1194 -     */
  5.1195      @Override
  5.1196      public boolean equals(Object obj) {
  5.1197 -        if (this == obj)                      // quick check
  5.1198 -            return true;
  5.1199 -        if (!(obj instanceof Locale))
  5.1200 -            return false;
  5.1201 -        BaseLocale otherBase = ((Locale)obj).baseLocale;
  5.1202 -        if (!baseLocale.equals(otherBase)) {
  5.1203 +        if (obj == null) {
  5.1204              return false;
  5.1205          }
  5.1206 -        if (localeExtensions == null) {
  5.1207 -            return ((Locale)obj).localeExtensions == null;
  5.1208 +        if (getClass() != obj.getClass()) {
  5.1209 +            return false;
  5.1210          }
  5.1211 -        return localeExtensions.equals(((Locale)obj).localeExtensions);
  5.1212 +        final Locale other = (Locale) obj;
  5.1213 +        if (!Objects.equals(this.language, other.language)) {
  5.1214 +            return false;
  5.1215 +        }
  5.1216 +        if (!Objects.equals(this.country, other.country)) {
  5.1217 +            return false;
  5.1218 +        }
  5.1219 +        if (!Objects.equals(this.variant, other.variant)) {
  5.1220 +            return false;
  5.1221 +        }
  5.1222 +        return true;
  5.1223      }
  5.1224  
  5.1225 -    // ================= privates =====================================
  5.1226  
  5.1227 -    private transient BaseLocale baseLocale;
  5.1228 -    private transient LocaleExtensions localeExtensions;
  5.1229 -
  5.1230 -    /**
  5.1231 -     * Calculated hashcode
  5.1232 -     */
  5.1233 -    private transient volatile int hashCodeValue = 0;
  5.1234 -
  5.1235 -    private static Locale defaultLocale = null;
  5.1236 -    private static Locale defaultDisplayLocale = null;
  5.1237 -    private static Locale defaultFormatLocale = null;
  5.1238 -
  5.1239 -    /**
  5.1240 -     * Return an array of the display names of the variant.
  5.1241 -     * @param bundle the ResourceBundle to use to get the display names
  5.1242 -     * @return an array of display names, possible of zero length.
  5.1243 -     */
  5.1244 -    private String[] getDisplayVariantArray(OpenListResourceBundle bundle, Locale inLocale) {
  5.1245 -        // Split the variant name into tokens separated by '_'.
  5.1246 -        StringTokenizer tokenizer = new StringTokenizer(baseLocale.getVariant(), "_");
  5.1247 -        String[] names = new String[tokenizer.countTokens()];
  5.1248 -
  5.1249 -        // For each variant token, lookup the display name.  If
  5.1250 -        // not found, use the variant name itself.
  5.1251 -        for (int i=0; i<names.length; ++i) {
  5.1252 -            names[i] = getDisplayString(tokenizer.nextToken(),
  5.1253 -                                inLocale, DISPLAY_VARIANT);
  5.1254 -        }
  5.1255 -
  5.1256 -        return names;
  5.1257 -    }
  5.1258 -
  5.1259 -    /**
  5.1260 -     * Format a list using given pattern strings.
  5.1261 -     * If either of the patterns is null, then a the list is
  5.1262 -     * formatted by concatenation with the delimiter ','.
  5.1263 -     * @param stringList the list of strings to be formatted.
  5.1264 -     * @param listPattern should create a MessageFormat taking 0-3 arguments
  5.1265 -     * and formatting them into a list.
  5.1266 -     * @param listCompositionPattern should take 2 arguments
  5.1267 -     * and is used by composeList.
  5.1268 -     * @return a string representing the list.
  5.1269 -     */
  5.1270 -    private static String formatList(String[] stringList, String listPattern, String listCompositionPattern) {
  5.1271 -        // If we have no list patterns, compose the list in a simple,
  5.1272 -        // non-localized way.
  5.1273 -        if (listPattern == null || listCompositionPattern == null) {
  5.1274 -            StringBuffer result = new StringBuffer();
  5.1275 -            for (int i=0; i<stringList.length; ++i) {
  5.1276 -                if (i>0) result.append(',');
  5.1277 -                result.append(stringList[i]);
  5.1278 -            }
  5.1279 -            return result.toString();
  5.1280 -        }
  5.1281 -
  5.1282 -        // Compose the list down to three elements if necessary
  5.1283 -        if (stringList.length > 3) {
  5.1284 -            MessageFormat format = new MessageFormat(listCompositionPattern);
  5.1285 -            stringList = composeList(format, stringList);
  5.1286 -        }
  5.1287 -
  5.1288 -        // Rebuild the argument list with the list length as the first element
  5.1289 -        Object[] args = new Object[stringList.length + 1];
  5.1290 -        System.arraycopy(stringList, 0, args, 1, stringList.length);
  5.1291 -        args[0] = new Integer(stringList.length);
  5.1292 -
  5.1293 -        // Format it using the pattern in the resource
  5.1294 -        MessageFormat format = new MessageFormat(listPattern);
  5.1295 -        return format.format(args);
  5.1296 -    }
  5.1297 -
  5.1298 -    /**
  5.1299 -     * Given a list of strings, return a list shortened to three elements.
  5.1300 -     * Shorten it by applying the given format to the first two elements
  5.1301 -     * recursively.
  5.1302 -     * @param format a format which takes two arguments
  5.1303 -     * @param list a list of strings
  5.1304 -     * @return if the list is three elements or shorter, the same list;
  5.1305 -     * otherwise, a new list of three elements.
  5.1306 -     */
  5.1307 -    private static String[] composeList(MessageFormat format, String[] list) {
  5.1308 -        if (list.length <= 3) return list;
  5.1309 -
  5.1310 -        // Use the given format to compose the first two elements into one
  5.1311 -        String[] listItems = { list[0], list[1] };
  5.1312 -        String newItem = format.format(listItems);
  5.1313 -
  5.1314 -        // Form a new list one element shorter
  5.1315 -        String[] newList = new String[list.length-1];
  5.1316 -        System.arraycopy(list, 2, newList, 1, newList.length-1);
  5.1317 -        newList[0] = newItem;
  5.1318 -
  5.1319 -        // Recurse
  5.1320 -        return composeList(format, newList);
  5.1321 -    }
  5.1322 -
  5.1323 -    /**
  5.1324 -     * @serialField language    String
  5.1325 -     *      language subtag in lower case. (See <a href="java/util/Locale.html#getLanguage()">getLanguage()</a>)
  5.1326 -     * @serialField country     String
  5.1327 -     *      country subtag in upper case. (See <a href="java/util/Locale.html#getCountry()">getCountry()</a>)
  5.1328 -     * @serialField variant     String
  5.1329 -     *      variant subtags separated by LOWLINE characters. (See <a href="java/util/Locale.html#getVariant()">getVariant()</a>)
  5.1330 -     * @serialField hashcode    int
  5.1331 -     *      deprecated, for forward compatibility only
  5.1332 -     * @serialField script      String
  5.1333 -     *      script subtag in title case (See <a href="java/util/Locale.html#getScript()">getScript()</a>)
  5.1334 -     * @serialField extensions  String
  5.1335 -     *      canonical representation of extensions, that is,
  5.1336 -     *      BCP47 extensions in alphabetical order followed by
  5.1337 -     *      BCP47 private use subtags, all in lower case letters
  5.1338 -     *      separated by HYPHEN-MINUS characters.
  5.1339 -     *      (See <a href="java/util/Locale.html#getExtensionKeys()">getExtensionKeys()</a>,
  5.1340 -     *      <a href="java/util/Locale.html#getExtension(char)">getExtension(char)</a>)
  5.1341 -     */
  5.1342 -    private static final ObjectStreamField[] serialPersistentFields = {
  5.1343 -        new ObjectStreamField("language", String.class),
  5.1344 -        new ObjectStreamField("country", String.class),
  5.1345 -        new ObjectStreamField("variant", String.class),
  5.1346 -        new ObjectStreamField("hashcode", int.class),
  5.1347 -        new ObjectStreamField("script", String.class),
  5.1348 -        new ObjectStreamField("extensions", String.class),
  5.1349 -    };
  5.1350 -
  5.1351 -    /**
  5.1352 -     * Serializes this <code>Locale</code> to the specified <code>ObjectOutputStream</code>.
  5.1353 -     * @param out the <code>ObjectOutputStream</code> to write
  5.1354 -     * @throws IOException
  5.1355 -     * @since 1.7
  5.1356 -     */
  5.1357 -    private void writeObject(ObjectOutputStream out) throws IOException {
  5.1358 -        ObjectOutputStream.PutField fields = out.putFields();
  5.1359 -        fields.put("language", baseLocale.getLanguage());
  5.1360 -        fields.put("script", baseLocale.getScript());
  5.1361 -        fields.put("country", baseLocale.getRegion());
  5.1362 -        fields.put("variant", baseLocale.getVariant());
  5.1363 -        fields.put("extensions", localeExtensions == null ? "" : localeExtensions.getID());
  5.1364 -        fields.put("hashcode", -1); // place holder just for backward support
  5.1365 -        out.writeFields();
  5.1366 -    }
  5.1367 -
  5.1368 -    /**
  5.1369 -     * Deserializes this <code>Locale</code>.
  5.1370 -     * @param in the <code>ObjectInputStream</code> to read
  5.1371 -     * @throws IOException
  5.1372 -     * @throws ClassNotFoundException
  5.1373 -     * @throws IllformdLocaleException
  5.1374 -     * @since 1.7
  5.1375 -     */
  5.1376 -    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
  5.1377 -        ObjectInputStream.GetField fields = in.readFields();
  5.1378 -        String language = (String)fields.get("language", "");
  5.1379 -        String script = (String)fields.get("script", "");
  5.1380 -        String country = (String)fields.get("country", "");
  5.1381 -        String variant = (String)fields.get("variant", "");
  5.1382 -        String extStr = (String)fields.get("extensions", "");
  5.1383 -        baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
  5.1384 -        if (extStr.length() > 0) {
  5.1385 -            try {
  5.1386 -                InternalLocaleBuilder bldr = new InternalLocaleBuilder();
  5.1387 -                bldr.setExtensions(extStr);
  5.1388 -                localeExtensions = bldr.getLocaleExtensions();
  5.1389 -            } catch (LocaleSyntaxException e) {
  5.1390 -                throw new IllformedLocaleException(e.getMessage());
  5.1391 -            }
  5.1392 -        } else {
  5.1393 -            localeExtensions = null;
  5.1394 -        }
  5.1395 -    }
  5.1396 -
  5.1397 -    /**
  5.1398 -     * Returns a cached <code>Locale</code> instance equivalent to
  5.1399 -     * the deserialized <code>Locale</code>. When serialized
  5.1400 -     * language, country and variant fields read from the object data stream
  5.1401 -     * are exactly "ja", "JP", "JP" or "th", "TH", "TH" and script/extensions
  5.1402 -     * fields are empty, this method supplies <code>UNICODE_LOCALE_EXTENSION</code>
  5.1403 -     * "ca"/"japanese" (calendar type is "japanese") or "nu"/"thai" (number script
  5.1404 -     * type is "thai"). See <a href="Locale.html#special_cases_constructor"/>Special Cases</a>
  5.1405 -     * for more information.
  5.1406 -     *
  5.1407 -     * @return an instance of <code>Locale</code> equivalent to
  5.1408 -     * the deserialized <code>Locale</code>.
  5.1409 -     * @throws java.io.ObjectStreamException
  5.1410 -     */
  5.1411 -    private Object readResolve() throws java.io.ObjectStreamException {
  5.1412 -        return getInstance(baseLocale.getLanguage(), baseLocale.getScript(),
  5.1413 -                baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);
  5.1414 -    }
  5.1415 -
  5.1416 -    private static volatile String[] isoLanguages = null;
  5.1417 -
  5.1418 -    private static volatile String[] isoCountries = null;
  5.1419 -
  5.1420 -    private static String convertOldISOCodes(String language) {
  5.1421 -        // we accept both the old and the new ISO codes for the languages whose ISO
  5.1422 -        // codes have changed, but we always store the OLD code, for backward compatibility
  5.1423 -        language = LocaleUtils.toLowerString(language).intern();
  5.1424 -        if (language == "he") {
  5.1425 -            return "iw";
  5.1426 -        } else if (language == "yi") {
  5.1427 -            return "ji";
  5.1428 -        } else if (language == "id") {
  5.1429 -            return "in";
  5.1430 -        } else {
  5.1431 -            return language;
  5.1432 -        }
  5.1433 -    }
  5.1434 -
  5.1435 -    private static LocaleExtensions getCompatibilityExtensions(String language,
  5.1436 -                                                               String script,
  5.1437 -                                                               String country,
  5.1438 -                                                               String variant) {
  5.1439 -        LocaleExtensions extensions = null;
  5.1440 -        // Special cases for backward compatibility support
  5.1441 -        if (LocaleUtils.caseIgnoreMatch(language, "ja")
  5.1442 -                && script.length() == 0
  5.1443 -                && LocaleUtils.caseIgnoreMatch(country, "jp")
  5.1444 -                && "JP".equals(variant)) {
  5.1445 -            // ja_JP_JP -> u-ca-japanese (calendar = japanese)
  5.1446 -            extensions = LocaleExtensions.CALENDAR_JAPANESE;
  5.1447 -        } else if (LocaleUtils.caseIgnoreMatch(language, "th")
  5.1448 -                && script.length() == 0
  5.1449 -                && LocaleUtils.caseIgnoreMatch(country, "th")
  5.1450 -                && "TH".equals(variant)) {
  5.1451 -            // th_TH_TH -> u-nu-thai (numbersystem = thai)
  5.1452 -            extensions = LocaleExtensions.NUMBER_THAI;
  5.1453 -        }
  5.1454 -        return extensions;
  5.1455 -    }
  5.1456 -
  5.1457 -    /**
  5.1458 -     * Obtains a localized locale names from a LocaleNameProvider
  5.1459 -     * implementation.
  5.1460 -     */
  5.1461 -    private static class LocaleNameGetter
  5.1462 -        implements LocaleServiceProviderPool.LocalizedObjectGetter<LocaleNameProvider, String> {
  5.1463 -        private static final LocaleNameGetter INSTANCE = new LocaleNameGetter();
  5.1464 -
  5.1465 -        public String getObject(LocaleNameProvider localeNameProvider,
  5.1466 -                                Locale locale,
  5.1467 -                                String key,
  5.1468 -                                Object... params) {
  5.1469 -            assert params.length == 2;
  5.1470 -            int type = (Integer)params[0];
  5.1471 -            String code = (String)params[1];
  5.1472 -
  5.1473 -            switch(type) {
  5.1474 -            case DISPLAY_LANGUAGE:
  5.1475 -                return localeNameProvider.getDisplayLanguage(code, locale);
  5.1476 -            case DISPLAY_COUNTRY:
  5.1477 -                return localeNameProvider.getDisplayCountry(code, locale);
  5.1478 -            case DISPLAY_VARIANT:
  5.1479 -                return localeNameProvider.getDisplayVariant(code, locale);
  5.1480 -            case DISPLAY_SCRIPT:
  5.1481 -                return localeNameProvider.getDisplayScript(code, locale);
  5.1482 -            default:
  5.1483 -                assert false; // shouldn't happen
  5.1484 -            }
  5.1485 -
  5.1486 -            return null;
  5.1487 -        }
  5.1488 -    }
  5.1489 -
  5.1490 -    /**
  5.1491 -     * Enum for locale categories.  These locale categories are used to get/set
  5.1492 -     * the default locale for the specific functionality represented by the
  5.1493 -     * category.
  5.1494 -     *
  5.1495 -     * @see #getDefault(Locale.Category)
  5.1496 -     * @see #setDefault(Locale.Category, Locale)
  5.1497 -     * @since 1.7
  5.1498 -     */
  5.1499 -    public enum Category {
  5.1500 -
  5.1501 -        /**
  5.1502 -         * Category used to represent the default locale for
  5.1503 -         * displaying user interfaces.
  5.1504 -         */
  5.1505 -        DISPLAY("user.language.display",
  5.1506 -                "user.script.display",
  5.1507 -                "user.country.display",
  5.1508 -                "user.variant.display"),
  5.1509 -
  5.1510 -        /**
  5.1511 -         * Category used to represent the default locale for
  5.1512 -         * formatting dates, numbers, and/or currencies.
  5.1513 -         */
  5.1514 -        FORMAT("user.language.format",
  5.1515 -               "user.script.format",
  5.1516 -               "user.country.format",
  5.1517 -               "user.variant.format");
  5.1518 -
  5.1519 -        Category(String languageKey, String scriptKey, String countryKey, String variantKey) {
  5.1520 -            this.languageKey = languageKey;
  5.1521 -            this.scriptKey = scriptKey;
  5.1522 -            this.countryKey = countryKey;
  5.1523 -            this.variantKey = variantKey;
  5.1524 -        }
  5.1525 -
  5.1526 -        final String languageKey;
  5.1527 -        final String scriptKey;
  5.1528 -        final String countryKey;
  5.1529 -        final String variantKey;
  5.1530 -    }
  5.1531 -
  5.1532 -    /**
  5.1533 -     * <code>Builder</code> is used to build instances of <code>Locale</code>
  5.1534 -     * from values configured by the setters.  Unlike the <code>Locale</code>
  5.1535 -     * constructors, the <code>Builder</code> checks if a value configured by a
  5.1536 -     * setter satisfies the syntax requirements defined by the <code>Locale</code>
  5.1537 -     * class.  A <code>Locale</code> object created by a <code>Builder</code> is
  5.1538 -     * well-formed and can be transformed to a well-formed IETF BCP 47 language tag
  5.1539 -     * without losing information.
  5.1540 -     *
  5.1541 -     * <p><b>Note:</b> The <code>Locale</code> class does not provide any
  5.1542 -     * syntactic restrictions on variant, while BCP 47 requires each variant
  5.1543 -     * subtag to be 5 to 8 alphanumerics or a single numeric followed by 3
  5.1544 -     * alphanumerics.  The method <code>setVariant</code> throws
  5.1545 -     * <code>IllformedLocaleException</code> for a variant that does not satisfy
  5.1546 -     * this restriction. If it is necessary to support such a variant, use a
  5.1547 -     * Locale constructor.  However, keep in mind that a <code>Locale</code>
  5.1548 -     * object created this way might lose the variant information when
  5.1549 -     * transformed to a BCP 47 language tag.
  5.1550 -     *
  5.1551 -     * <p>The following example shows how to create a <code>Locale</code> object
  5.1552 -     * with the <code>Builder</code>.
  5.1553 -     * <blockquote>
  5.1554 -     * <pre>
  5.1555 -     *     Locale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
  5.1556 -     * </pre>
  5.1557 -     * </blockquote>
  5.1558 -     *
  5.1559 -     * <p>Builders can be reused; <code>clear()</code> resets all
  5.1560 -     * fields to their default values.
  5.1561 -     *
  5.1562 -     * @see Locale#forLanguageTag
  5.1563 -     * @since 1.7
  5.1564 -     */
  5.1565 -    public static final class Builder {
  5.1566 -        private final InternalLocaleBuilder localeBuilder;
  5.1567 -
  5.1568 -        /**
  5.1569 -         * Constructs an empty Builder. The default value of all
  5.1570 -         * fields, extensions, and private use information is the
  5.1571 -         * empty string.
  5.1572 -         */
  5.1573 -        public Builder() {
  5.1574 -            localeBuilder = new InternalLocaleBuilder();
  5.1575 -        }
  5.1576 -
  5.1577 -        /**
  5.1578 -         * Resets the <code>Builder</code> to match the provided
  5.1579 -         * <code>locale</code>.  Existing state is discarded.
  5.1580 -         *
  5.1581 -         * <p>All fields of the locale must be well-formed, see {@link Locale}.
  5.1582 -         *
  5.1583 -         * <p>Locales with any ill-formed fields cause
  5.1584 -         * <code>IllformedLocaleException</code> to be thrown, except for the
  5.1585 -         * following three cases which are accepted for compatibility
  5.1586 -         * reasons:<ul>
  5.1587 -         * <li>Locale("ja", "JP", "JP") is treated as "ja-JP-u-ca-japanese"
  5.1588 -         * <li>Locale("th", "TH", "TH") is treated as "th-TH-u-nu-thai"
  5.1589 -         * <li>Locale("no", "NO", "NY") is treated as "nn-NO"</ul>
  5.1590 -         *
  5.1591 -         * @param locale the locale
  5.1592 -         * @return This builder.
  5.1593 -         * @throws IllformedLocaleException if <code>locale</code> has
  5.1594 -         * any ill-formed fields.
  5.1595 -         * @throws NullPointerException if <code>locale</code> is null.
  5.1596 -         */
  5.1597 -        public Builder setLocale(Locale locale) {
  5.1598 -            try {
  5.1599 -                localeBuilder.setLocale(locale.baseLocale, locale.localeExtensions);
  5.1600 -            } catch (LocaleSyntaxException e) {
  5.1601 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1602 -            }
  5.1603 -            return this;
  5.1604 -        }
  5.1605 -
  5.1606 -        /**
  5.1607 -         * Resets the Builder to match the provided IETF BCP 47
  5.1608 -         * language tag.  Discards the existing state.  Null and the
  5.1609 -         * empty string cause the builder to be reset, like {@link
  5.1610 -         * #clear}.  Grandfathered tags (see {@link
  5.1611 -         * Locale#forLanguageTag}) are converted to their canonical
  5.1612 -         * form before being processed.  Otherwise, the language tag
  5.1613 -         * must be well-formed (see {@link Locale}) or an exception is
  5.1614 -         * thrown (unlike <code>Locale.forLanguageTag</code>, which
  5.1615 -         * just discards ill-formed and following portions of the
  5.1616 -         * tag).
  5.1617 -         *
  5.1618 -         * @param languageTag the language tag
  5.1619 -         * @return This builder.
  5.1620 -         * @throws IllformedLocaleException if <code>languageTag</code> is ill-formed
  5.1621 -         * @see Locale#forLanguageTag(String)
  5.1622 -         */
  5.1623 -        public Builder setLanguageTag(String languageTag) {
  5.1624 -            ParseStatus sts = new ParseStatus();
  5.1625 -            LanguageTag tag = LanguageTag.parse(languageTag, sts);
  5.1626 -            if (sts.isError()) {
  5.1627 -                throw new IllformedLocaleException(sts.getErrorMessage(), sts.getErrorIndex());
  5.1628 -            }
  5.1629 -            localeBuilder.setLanguageTag(tag);
  5.1630 -            return this;
  5.1631 -        }
  5.1632 -
  5.1633 -        /**
  5.1634 -         * Sets the language.  If <code>language</code> is the empty string or
  5.1635 -         * null, the language in this <code>Builder</code> is removed.  Otherwise,
  5.1636 -         * the language must be <a href="./Locale.html#def_language">well-formed</a>
  5.1637 -         * or an exception is thrown.
  5.1638 -         *
  5.1639 -         * <p>The typical language value is a two or three-letter language
  5.1640 -         * code as defined in ISO639.
  5.1641 -         *
  5.1642 -         * @param language the language
  5.1643 -         * @return This builder.
  5.1644 -         * @throws IllformedLocaleException if <code>language</code> is ill-formed
  5.1645 -         */
  5.1646 -        public Builder setLanguage(String language) {
  5.1647 -            try {
  5.1648 -                localeBuilder.setLanguage(language);
  5.1649 -            } catch (LocaleSyntaxException e) {
  5.1650 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1651 -            }
  5.1652 -            return this;
  5.1653 -        }
  5.1654 -
  5.1655 -        /**
  5.1656 -         * Sets the script. If <code>script</code> is null or the empty string,
  5.1657 -         * the script in this <code>Builder</code> is removed.
  5.1658 -         * Otherwise, the script must be <a href="./Locale.html#def_script">well-formed</a> or an
  5.1659 -         * exception is thrown.
  5.1660 -         *
  5.1661 -         * <p>The typical script value is a four-letter script code as defined by ISO 15924.
  5.1662 -         *
  5.1663 -         * @param script the script
  5.1664 -         * @return This builder.
  5.1665 -         * @throws IllformedLocaleException if <code>script</code> is ill-formed
  5.1666 -         */
  5.1667 -        public Builder setScript(String script) {
  5.1668 -            try {
  5.1669 -                localeBuilder.setScript(script);
  5.1670 -            } catch (LocaleSyntaxException e) {
  5.1671 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1672 -            }
  5.1673 -            return this;
  5.1674 -        }
  5.1675 -
  5.1676 -        /**
  5.1677 -         * Sets the region.  If region is null or the empty string, the region
  5.1678 -         * in this <code>Builder</code> is removed.  Otherwise,
  5.1679 -         * the region must be <a href="./Locale.html#def_region">well-formed</a> or an
  5.1680 -         * exception is thrown.
  5.1681 -         *
  5.1682 -         * <p>The typical region value is a two-letter ISO 3166 code or a
  5.1683 -         * three-digit UN M.49 area code.
  5.1684 -         *
  5.1685 -         * <p>The country value in the <code>Locale</code> created by the
  5.1686 -         * <code>Builder</code> is always normalized to upper case.
  5.1687 -         *
  5.1688 -         * @param region the region
  5.1689 -         * @return This builder.
  5.1690 -         * @throws IllformedLocaleException if <code>region</code> is ill-formed
  5.1691 -         */
  5.1692 -        public Builder setRegion(String region) {
  5.1693 -            try {
  5.1694 -                localeBuilder.setRegion(region);
  5.1695 -            } catch (LocaleSyntaxException e) {
  5.1696 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1697 -            }
  5.1698 -            return this;
  5.1699 -        }
  5.1700 -
  5.1701 -        /**
  5.1702 -         * Sets the variant.  If variant is null or the empty string, the
  5.1703 -         * variant in this <code>Builder</code> is removed.  Otherwise, it
  5.1704 -         * must consist of one or more <a href="./Locale.html#def_variant">well-formed</a>
  5.1705 -         * subtags, or an exception is thrown.
  5.1706 -         *
  5.1707 -         * <p><b>Note:</b> This method checks if <code>variant</code>
  5.1708 -         * satisfies the IETF BCP 47 variant subtag's syntax requirements,
  5.1709 -         * and normalizes the value to lowercase letters.  However,
  5.1710 -         * the <code>Locale</code> class does not impose any syntactic
  5.1711 -         * restriction on variant, and the variant value in
  5.1712 -         * <code>Locale</code> is case sensitive.  To set such a variant,
  5.1713 -         * use a Locale constructor.
  5.1714 -         *
  5.1715 -         * @param variant the variant
  5.1716 -         * @return This builder.
  5.1717 -         * @throws IllformedLocaleException if <code>variant</code> is ill-formed
  5.1718 -         */
  5.1719 -        public Builder setVariant(String variant) {
  5.1720 -            try {
  5.1721 -                localeBuilder.setVariant(variant);
  5.1722 -            } catch (LocaleSyntaxException e) {
  5.1723 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1724 -            }
  5.1725 -            return this;
  5.1726 -        }
  5.1727 -
  5.1728 -        /**
  5.1729 -         * Sets the extension for the given key. If the value is null or the
  5.1730 -         * empty string, the extension is removed.  Otherwise, the extension
  5.1731 -         * must be <a href="./Locale.html#def_extensions">well-formed</a> or an exception
  5.1732 -         * is thrown.
  5.1733 -         *
  5.1734 -         * <p><b>Note:</b> The key {@link Locale#UNICODE_LOCALE_EXTENSION
  5.1735 -         * UNICODE_LOCALE_EXTENSION} ('u') is used for the Unicode locale extension.
  5.1736 -         * Setting a value for this key replaces any existing Unicode locale key/type
  5.1737 -         * pairs with those defined in the extension.
  5.1738 -         *
  5.1739 -         * <p><b>Note:</b> The key {@link Locale#PRIVATE_USE_EXTENSION
  5.1740 -         * PRIVATE_USE_EXTENSION} ('x') is used for the private use code. To be
  5.1741 -         * well-formed, the value for this key needs only to have subtags of one to
  5.1742 -         * eight alphanumeric characters, not two to eight as in the general case.
  5.1743 -         *
  5.1744 -         * @param key the extension key
  5.1745 -         * @param value the extension value
  5.1746 -         * @return This builder.
  5.1747 -         * @throws IllformedLocaleException if <code>key</code> is illegal
  5.1748 -         * or <code>value</code> is ill-formed
  5.1749 -         * @see #setUnicodeLocaleKeyword(String, String)
  5.1750 -         */
  5.1751 -        public Builder setExtension(char key, String value) {
  5.1752 -            try {
  5.1753 -                localeBuilder.setExtension(key, value);
  5.1754 -            } catch (LocaleSyntaxException e) {
  5.1755 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1756 -            }
  5.1757 -            return this;
  5.1758 -        }
  5.1759 -
  5.1760 -        /**
  5.1761 -         * Sets the Unicode locale keyword type for the given key.  If the type
  5.1762 -         * is null, the Unicode keyword is removed.  Otherwise, the key must be
  5.1763 -         * non-null and both key and type must be <a
  5.1764 -         * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
  5.1765 -         * is thrown.
  5.1766 -         *
  5.1767 -         * <p>Keys and types are converted to lower case.
  5.1768 -         *
  5.1769 -         * <p><b>Note</b>:Setting the 'u' extension via {@link #setExtension}
  5.1770 -         * replaces all Unicode locale keywords with those defined in the
  5.1771 -         * extension.
  5.1772 -         *
  5.1773 -         * @param key the Unicode locale key
  5.1774 -         * @param type the Unicode locale type
  5.1775 -         * @return This builder.
  5.1776 -         * @throws IllformedLocaleException if <code>key</code> or <code>type</code>
  5.1777 -         * is ill-formed
  5.1778 -         * @throws NullPointerException if <code>key</code> is null
  5.1779 -         * @see #setExtension(char, String)
  5.1780 -         */
  5.1781 -        public Builder setUnicodeLocaleKeyword(String key, String type) {
  5.1782 -            try {
  5.1783 -                localeBuilder.setUnicodeLocaleKeyword(key, type);
  5.1784 -            } catch (LocaleSyntaxException e) {
  5.1785 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1786 -            }
  5.1787 -            return this;
  5.1788 -        }
  5.1789 -
  5.1790 -        /**
  5.1791 -         * Adds a unicode locale attribute, if not already present, otherwise
  5.1792 -         * has no effect.  The attribute must not be null and must be <a
  5.1793 -         * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
  5.1794 -         * is thrown.
  5.1795 -         *
  5.1796 -         * @param attribute the attribute
  5.1797 -         * @return This builder.
  5.1798 -         * @throws NullPointerException if <code>attribute</code> is null
  5.1799 -         * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
  5.1800 -         * @see #setExtension(char, String)
  5.1801 -         */
  5.1802 -        public Builder addUnicodeLocaleAttribute(String attribute) {
  5.1803 -            try {
  5.1804 -                localeBuilder.addUnicodeLocaleAttribute(attribute);
  5.1805 -            } catch (LocaleSyntaxException e) {
  5.1806 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1807 -            }
  5.1808 -            return this;
  5.1809 -        }
  5.1810 -
  5.1811 -        /**
  5.1812 -         * Removes a unicode locale attribute, if present, otherwise has no
  5.1813 -         * effect.  The attribute must not be null and must be <a
  5.1814 -         * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
  5.1815 -         * is thrown.
  5.1816 -         *
  5.1817 -         * <p>Attribute comparision for removal is case-insensitive.
  5.1818 -         *
  5.1819 -         * @param attribute the attribute
  5.1820 -         * @return This builder.
  5.1821 -         * @throws NullPointerException if <code>attribute</code> is null
  5.1822 -         * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
  5.1823 -         * @see #setExtension(char, String)
  5.1824 -         */
  5.1825 -        public Builder removeUnicodeLocaleAttribute(String attribute) {
  5.1826 -            try {
  5.1827 -                localeBuilder.removeUnicodeLocaleAttribute(attribute);
  5.1828 -            } catch (LocaleSyntaxException e) {
  5.1829 -                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
  5.1830 -            }
  5.1831 -            return this;
  5.1832 -        }
  5.1833 -
  5.1834 -        /**
  5.1835 -         * Resets the builder to its initial, empty state.
  5.1836 -         *
  5.1837 -         * @return This builder.
  5.1838 -         */
  5.1839 -        public Builder clear() {
  5.1840 -            localeBuilder.clear();
  5.1841 -            return this;
  5.1842 -        }
  5.1843 -
  5.1844 -        /**
  5.1845 -         * Resets the extensions to their initial, empty state.
  5.1846 -         * Language, script, region and variant are unchanged.
  5.1847 -         *
  5.1848 -         * @return This builder.
  5.1849 -         * @see #setExtension(char, String)
  5.1850 -         */
  5.1851 -        public Builder clearExtensions() {
  5.1852 -            localeBuilder.clearExtensions();
  5.1853 -            return this;
  5.1854 -        }
  5.1855 -
  5.1856 -        /**
  5.1857 -         * Returns an instance of <code>Locale</code> created from the fields set
  5.1858 -         * on this builder.
  5.1859 -         *
  5.1860 -         * <p>This applies the conversions listed in {@link Locale#forLanguageTag}
  5.1861 -         * when constructing a Locale. (Grandfathered tags are handled in
  5.1862 -         * {@link #setLanguageTag}.)
  5.1863 -         *
  5.1864 -         * @return A Locale.
  5.1865 -         */
  5.1866 -        public Locale build() {
  5.1867 -            BaseLocale baseloc = localeBuilder.getBaseLocale();
  5.1868 -            LocaleExtensions extensions = localeBuilder.getLocaleExtensions();
  5.1869 -            if (extensions == null && baseloc.getVariant().length() > 0) {
  5.1870 -                extensions = getCompatibilityExtensions(baseloc.getLanguage(), baseloc.getScript(),
  5.1871 -                        baseloc.getRegion(), baseloc.getVariant());
  5.1872 -            }
  5.1873 -            return Locale.getInstance(baseloc, extensions);
  5.1874 -        }
  5.1875 -    }
  5.1876  }
     6.1 --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Thu Oct 03 15:43:10 2013 +0200
     6.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Thu Oct 03 15:51:55 2013 +0200
     6.3 @@ -20,6 +20,7 @@
     6.4  import java.io.UnsupportedEncodingException;
     6.5  import java.net.MalformedURLException;
     6.6  import java.net.URL;
     6.7 +import java.util.Locale;
     6.8  import org.apidesign.bck2brwsr.vmtest.Compare;
     6.9  import org.apidesign.bck2brwsr.vmtest.VMTest;
    6.10  import org.testng.annotations.Factory;
    6.11 @@ -161,6 +162,19 @@
    6.12          assert res.equals("ba") : "Expecting ba: " + res;
    6.13          return res;
    6.14      }
    6.15 +    
    6.16 +    @Compare public String localeUS() {
    6.17 +        return Locale.US.toString();
    6.18 +    }
    6.19 +    
    6.20 +    @Compare public String localeFrench() {
    6.21 +        return Locale.FRENCH.toString();
    6.22 +    }
    6.23 +    
    6.24 +    
    6.25 +    @Compare public String formatSimple() {
    6.26 +        return String.format((Locale)null, "Hello %s!", "World");
    6.27 +    }
    6.28  
    6.29      @Compare public String replaceWithItself() {
    6.30          return "org.apidesign.bck2brwsr.core.JavaScriptBody".replace(".", "\\.");
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ExceptionsTest.java	Thu Oct 03 15:51:55 2013 +0200
     7.3 @@ -0,0 +1,68 @@
     7.4 +/**
     7.5 + * Back 2 Browser Bytecode Translator
     7.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     7.7 + *
     7.8 + * This program is free software: you can redistribute it and/or modify
     7.9 + * it under the terms of the GNU General Public License as published by
    7.10 + * the Free Software Foundation, version 2 of the License.
    7.11 + *
    7.12 + * This program is distributed in the hope that it will be useful,
    7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.15 + * GNU General Public License for more details.
    7.16 + *
    7.17 + * You should have received a copy of the GNU General Public License
    7.18 + * along with this program. Look for COPYING file in the top folder.
    7.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    7.20 + */
    7.21 +package org.apidesign.bck2brwsr.tck;
    7.22 +
    7.23 +import java.io.ByteArrayOutputStream;
    7.24 +import java.io.PrintStream;
    7.25 +import java.io.PrintWriter;
    7.26 +import java.io.StringWriter;
    7.27 +import java.io.UnsupportedEncodingException;
    7.28 +import org.apidesign.bck2brwsr.vmtest.Compare;
    7.29 +import org.apidesign.bck2brwsr.vmtest.VMTest;
    7.30 +import org.testng.annotations.Factory;
    7.31 +
    7.32 +/**
    7.33 + *
    7.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    7.35 + */
    7.36 +public class ExceptionsTest {
    7.37 +    @Compare public String firstLineIsTheSame() throws UnsupportedEncodingException {
    7.38 +        MyException ex = new MyException("Hello");
    7.39 +        ByteArrayOutputStream out = new ByteArrayOutputStream();
    7.40 +        PrintStream ps = new PrintStream(out);
    7.41 +        ex.printStackTrace(ps);
    7.42 +        ps.flush();
    7.43 +        
    7.44 +        String s = new String(out.toByteArray(), "UTF-8");
    7.45 +        int newLine = s.indexOf('\n');
    7.46 +        return s.substring(0, newLine);
    7.47 +    }
    7.48 +
    7.49 +    @Compare public String firstLineIsTheSameWithWriter() throws UnsupportedEncodingException {
    7.50 +        MyException ex = new MyException("Hello");
    7.51 +        StringWriter sw = new StringWriter();
    7.52 +        PrintWriter pw = new PrintWriter(sw);
    7.53 +        ex.printStackTrace(pw);
    7.54 +        pw.flush();
    7.55 +        
    7.56 +        String s = sw.toString();
    7.57 +        int newLine = s.indexOf('\n');
    7.58 +        return s.substring(0, newLine);
    7.59 +    }
    7.60 +    
    7.61 +    static class MyException extends Exception {
    7.62 +        public MyException(String message) {
    7.63 +            super(message);
    7.64 +        }
    7.65 +    }
    7.66 +    
    7.67 +    
    7.68 +    @Factory public static Object[] create() {
    7.69 +        return VMTest.create(ExceptionsTest.class);
    7.70 +    }
    7.71 +}
     8.1 --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Thu Oct 03 15:43:10 2013 +0200
     8.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Thu Oct 03 15:51:55 2013 +0200
     8.3 @@ -19,6 +19,7 @@
     8.4  
     8.5  import java.lang.annotation.Retention;
     8.6  import java.lang.annotation.RetentionPolicy;
     8.7 +import java.lang.reflect.Constructor;
     8.8  import java.lang.reflect.Method;
     8.9  import java.util.Arrays;
    8.10  import java.util.Collections;
    8.11 @@ -72,6 +73,14 @@
    8.12      @Compare public String isRunnableHasRunMethod() throws NoSuchMethodException {
    8.13          return Runnable.class.getMethod("run").getName();
    8.14      }
    8.15 +
    8.16 +    @Compare public String isRunnableDeclaresRunMethod() throws NoSuchMethodException {
    8.17 +        return Runnable.class.getDeclaredMethod("run").getName();
    8.18 +    }
    8.19 +    
    8.20 +    @Compare public String intValue() throws Exception {
    8.21 +        return Integer.class.getConstructor(int.class).newInstance(10).toString();
    8.22 +    }
    8.23      
    8.24      @Compare public String namesOfMethods() {
    8.25          StringBuilder sb = new StringBuilder();
    8.26 @@ -86,6 +95,19 @@
    8.27          return sb.toString();
    8.28      }
    8.29  
    8.30 +    @Compare public String paramsOfConstructors() {
    8.31 +        StringBuilder sb = new StringBuilder();
    8.32 +        String[] arr = new String[20];
    8.33 +        int i = 0;
    8.34 +        for (Constructor<?> m : StaticUse.class.getConstructors()) {
    8.35 +            arr[i++] = m.getName();
    8.36 +        }
    8.37 +        for (String s : sort(arr, i)) {
    8.38 +            sb.append(s).append("\n");
    8.39 +        }
    8.40 +        return sb.toString();
    8.41 +    }
    8.42 +
    8.43      @Compare public String namesOfDeclaringClassesOfMethods() {
    8.44          StringBuilder sb = new StringBuilder();
    8.45          String[] arr = new String[20];
     9.1 --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java	Thu Oct 03 15:43:10 2013 +0200
     9.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java	Thu Oct 03 15:51:55 2013 +0200
     9.3 @@ -18,6 +18,7 @@
     9.4  package org.apidesign.bck2brwsr.tck;
     9.5  
     9.6  import java.io.InputStream;
     9.7 +import java.net.URL;
     9.8  import org.apidesign.bck2brwsr.vmtest.Compare;
     9.9  import org.apidesign.bck2brwsr.vmtest.VMTest;
    9.10  import org.testng.annotations.Factory;
    9.11 @@ -50,6 +51,11 @@
    9.12          return sb.toString();
    9.13      }
    9.14      
    9.15 +    @Compare public String toURIFromURL() throws Exception {
    9.16 +        URL u = new URL("http://apidesign.org");
    9.17 +        return u.toURI().toString();
    9.18 +    }
    9.19 +    
    9.20      @Factory public static Object[] create() {
    9.21          return VMTest.create(ResourcesTest.class);
    9.22      }
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/SystemTest.java	Thu Oct 03 15:51:55 2013 +0200
    10.3 @@ -0,0 +1,36 @@
    10.4 +/**
    10.5 + * Back 2 Browser Bytecode Translator
    10.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    10.7 + *
    10.8 + * This program is free software: you can redistribute it and/or modify
    10.9 + * it under the terms of the GNU General Public License as published by
   10.10 + * the Free Software Foundation, version 2 of the License.
   10.11 + *
   10.12 + * This program is distributed in the hope that it will be useful,
   10.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.15 + * GNU General Public License for more details.
   10.16 + *
   10.17 + * You should have received a copy of the GNU General Public License
   10.18 + * along with this program. Look for COPYING file in the top folder.
   10.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   10.20 + */
   10.21 +package org.apidesign.bck2brwsr.tck;
   10.22 +
   10.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   10.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   10.25 +import org.testng.annotations.Factory;
   10.26 +
   10.27 +/**
   10.28 + *
   10.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   10.30 + */
   10.31 +public class SystemTest {
   10.32 +    @Compare public boolean nonNullOSName() {
   10.33 +        return System.getProperty("os.name") != null;
   10.34 +    }
   10.35 +
   10.36 +    @Factory public static Object[] create() {
   10.37 +        return VMTest.create(SystemTest.class);
   10.38 +    }
   10.39 +}
    11.1 --- a/rt/emul/mini/pom.xml	Thu Oct 03 15:43:10 2013 +0200
    11.2 +++ b/rt/emul/mini/pom.xml	Thu Oct 03 15:51:55 2013 +0200
    11.3 @@ -31,12 +31,48 @@
    11.4    <build>
    11.5        <plugins>
    11.6            <plugin>
    11.7 +              <artifactId>maven-antrun-plugin</artifactId>
    11.8 +              <version>1.7</version>
    11.9 +              <executions>
   11.10 +                  <execution>
   11.11 +                      <phase>generate-sources</phase>
   11.12 +                      <configuration>
   11.13 +                          <target>
   11.14 +                              <mkdir dir="${project.build.directory}/bootcp"/>
   11.15 +                              <copy todir="${project.build.directory}/bootcp">
   11.16 +                                  <resources>
   11.17 +                                      <!-- copy all resources that are in
   11.18 +                                        compact profile, but are referenced from
   11.19 +                                        the mini profile
   11.20 +                                      -->
   11.21 +                                      <javaresource name="java/net/URI.class"/>
   11.22 +                                      <javaresource name="java/net/URISyntaxException.class"/>
   11.23 +                                      <javaresource name="java/util/Locale.class"/>
   11.24 +                                      <javaresource name="java/io/OutputStream.class"/>
   11.25 +                                      <javaresource name="java/io/FilterOutputStream.class"/>
   11.26 +                                      <javaresource name="java/io/PrintStream.class"/>
   11.27 +                                      <javaresource name="java/io/PrintWriter.class"/>
   11.28 +                                      <javaresource name="java/io/Writer.class"/>
   11.29 +                                  </resources>
   11.30 +                              </copy>
   11.31 +                          </target>
   11.32 +                      </configuration>
   11.33 +                      <goals>
   11.34 +                          <goal>run</goal>
   11.35 +                      </goals>
   11.36 +                  </execution>
   11.37 +              </executions>
   11.38 +          </plugin>
   11.39 +          <plugin>
   11.40                <groupId>org.apache.maven.plugins</groupId>
   11.41                <artifactId>maven-compiler-plugin</artifactId>
   11.42                <version>2.5.1</version>
   11.43                <configuration>
   11.44                    <compilerArguments>
   11.45 -                      <bootclasspath>netbeans.ignore.jdk.bootsclasspath</bootclasspath>
   11.46 +                      <!--
   11.47 +                        <bootclasspath>netbeans.ignore.jdk.bootsclasspath</bootclasspath>
   11.48 +                      -->
   11.49 +                      <bootclasspath>${project.build.directory}/bootcp/</bootclasspath>
   11.50                    </compilerArguments>
   11.51                   <source>1.7</source>
   11.52                   <target>1.7</target>
    12.1 --- a/rt/emul/mini/src/main/java/java/lang/Class.java	Thu Oct 03 15:43:10 2013 +0200
    12.2 +++ b/rt/emul/mini/src/main/java/java/lang/Class.java	Thu Oct 03 15:51:55 2013 +0200
    12.3 @@ -29,6 +29,7 @@
    12.4  import org.apidesign.bck2brwsr.emul.reflect.AnnotationImpl;
    12.5  import java.io.InputStream;
    12.6  import java.lang.annotation.Annotation;
    12.7 +import java.lang.reflect.Constructor;
    12.8  import java.lang.reflect.Field;
    12.9  import java.lang.reflect.Method;
   12.10  import java.lang.reflect.TypeVariable;
   12.11 @@ -975,6 +976,319 @@
   12.12      }
   12.13      
   12.14      /**
   12.15 +     * Returns an array of {@code Field} objects reflecting all the fields
   12.16 +     * declared by the class or interface represented by this
   12.17 +     * {@code Class} object. This includes public, protected, default
   12.18 +     * (package) access, and private fields, but excludes inherited fields.
   12.19 +     * The elements in the array returned are not sorted and are not in any
   12.20 +     * particular order.  This method returns an array of length 0 if the class
   12.21 +     * or interface declares no fields, or if this {@code Class} object
   12.22 +     * represents a primitive type, an array class, or void.
   12.23 +     *
   12.24 +     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
   12.25 +     *
   12.26 +     * @return    the array of {@code Field} objects representing all the
   12.27 +     * declared fields of this class
   12.28 +     * @exception  SecurityException
   12.29 +     *             If a security manager, <i>s</i>, is present and any of the
   12.30 +     *             following conditions is met:
   12.31 +     *
   12.32 +     *             <ul>
   12.33 +     *
   12.34 +     *             <li> invocation of
   12.35 +     *             {@link SecurityManager#checkMemberAccess
   12.36 +     *             s.checkMemberAccess(this, Member.DECLARED)} denies
   12.37 +     *             access to the declared fields within this class
   12.38 +     *
   12.39 +     *             <li> the caller's class loader is not the same as or an
   12.40 +     *             ancestor of the class loader for the current class and
   12.41 +     *             invocation of {@link SecurityManager#checkPackageAccess
   12.42 +     *             s.checkPackageAccess()} denies access to the package
   12.43 +     *             of this class
   12.44 +     *
   12.45 +     *             </ul>
   12.46 +     *
   12.47 +     * @since JDK1.1
   12.48 +     */
   12.49 +    public Field[] getDeclaredFields() throws SecurityException {
   12.50 +        throw new SecurityException();
   12.51 +    }
   12.52 +
   12.53 +    /**
   12.54 +     * <b>Bck2Brwsr</b> emulation can only seek public methods, otherwise it
   12.55 +     * throws a {@code SecurityException}.
   12.56 +     * <p>
   12.57 +     * Returns a {@code Method} object that reflects the specified
   12.58 +     * declared method of the class or interface represented by this
   12.59 +     * {@code Class} object. The {@code name} parameter is a
   12.60 +     * {@code String} that specifies the simple name of the desired
   12.61 +     * method, and the {@code parameterTypes} parameter is an array of
   12.62 +     * {@code Class} objects that identify the method's formal parameter
   12.63 +     * types, in declared order.  If more than one method with the same
   12.64 +     * parameter types is declared in a class, and one of these methods has a
   12.65 +     * return type that is more specific than any of the others, that method is
   12.66 +     * returned; otherwise one of the methods is chosen arbitrarily.  If the
   12.67 +     * name is "&lt;init&gt;"or "&lt;clinit&gt;" a {@code NoSuchMethodException}
   12.68 +     * is raised.
   12.69 +     *
   12.70 +     * @param name the name of the method
   12.71 +     * @param parameterTypes the parameter array
   12.72 +     * @return    the {@code Method} object for the method of this class
   12.73 +     * matching the specified name and parameters
   12.74 +     * @exception NoSuchMethodException if a matching method is not found.
   12.75 +     * @exception NullPointerException if {@code name} is {@code null}
   12.76 +     * @exception  SecurityException
   12.77 +     *             If a security manager, <i>s</i>, is present and any of the
   12.78 +     *             following conditions is met:
   12.79 +     *
   12.80 +     *             <ul>
   12.81 +     *
   12.82 +     *             <li> invocation of
   12.83 +     *             {@link SecurityManager#checkMemberAccess
   12.84 +     *             s.checkMemberAccess(this, Member.DECLARED)} denies
   12.85 +     *             access to the declared method
   12.86 +     *
   12.87 +     *             <li> the caller's class loader is not the same as or an
   12.88 +     *             ancestor of the class loader for the current class and
   12.89 +     *             invocation of {@link SecurityManager#checkPackageAccess
   12.90 +     *             s.checkPackageAccess()} denies access to the package
   12.91 +     *             of this class
   12.92 +     *
   12.93 +     *             </ul>
   12.94 +     *
   12.95 +     * @since JDK1.1
   12.96 +     */
   12.97 +    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
   12.98 +    throws NoSuchMethodException, SecurityException {
   12.99 +        try {
  12.100 +            return getMethod(name, parameterTypes);
  12.101 +        } catch (NoSuchMethodException ex) {
  12.102 +            throw new SecurityException();
  12.103 +        }
  12.104 +    }
  12.105 +
  12.106 +    /**
  12.107 +     * Returns a {@code Field} object that reflects the specified declared
  12.108 +     * field of the class or interface represented by this {@code Class}
  12.109 +     * object. The {@code name} parameter is a {@code String} that
  12.110 +     * specifies the simple name of the desired field.  Note that this method
  12.111 +     * will not reflect the {@code length} field of an array class.
  12.112 +     *
  12.113 +     * @param name the name of the field
  12.114 +     * @return the {@code Field} object for the specified field in this
  12.115 +     * class
  12.116 +     * @exception NoSuchFieldException if a field with the specified name is
  12.117 +     *              not found.
  12.118 +     * @exception NullPointerException if {@code name} is {@code null}
  12.119 +     * @exception  SecurityException
  12.120 +     *             If a security manager, <i>s</i>, is present and any of the
  12.121 +     *             following conditions is met:
  12.122 +     *
  12.123 +     *             <ul>
  12.124 +     *
  12.125 +     *             <li> invocation of
  12.126 +     *             {@link SecurityManager#checkMemberAccess
  12.127 +     *             s.checkMemberAccess(this, Member.DECLARED)} denies
  12.128 +     *             access to the declared field
  12.129 +     *
  12.130 +     *             <li> the caller's class loader is not the same as or an
  12.131 +     *             ancestor of the class loader for the current class and
  12.132 +     *             invocation of {@link SecurityManager#checkPackageAccess
  12.133 +     *             s.checkPackageAccess()} denies access to the package
  12.134 +     *             of this class
  12.135 +     *
  12.136 +     *             </ul>
  12.137 +     *
  12.138 +     * @since JDK1.1
  12.139 +     */
  12.140 +    public Field getDeclaredField(String name)
  12.141 +    throws SecurityException {
  12.142 +        throw new SecurityException();
  12.143 +    }
  12.144 +    
  12.145 +    /**
  12.146 +     * Returns an array containing {@code Constructor} objects reflecting
  12.147 +     * all the public constructors of the class represented by this
  12.148 +     * {@code Class} object.  An array of length 0 is returned if the
  12.149 +     * class has no public constructors, or if the class is an array class, or
  12.150 +     * if the class reflects a primitive type or void.
  12.151 +     *
  12.152 +     * Note that while this method returns an array of {@code
  12.153 +     * Constructor<T>} objects (that is an array of constructors from
  12.154 +     * this class), the return type of this method is {@code
  12.155 +     * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
  12.156 +     * might be expected.  This less informative return type is
  12.157 +     * necessary since after being returned from this method, the
  12.158 +     * array could be modified to hold {@code Constructor} objects for
  12.159 +     * different classes, which would violate the type guarantees of
  12.160 +     * {@code Constructor<T>[]}.
  12.161 +     *
  12.162 +     * @return the array of {@code Constructor} objects representing the
  12.163 +     *  public constructors of this class
  12.164 +     * @exception  SecurityException
  12.165 +     *             If a security manager, <i>s</i>, is present and any of the
  12.166 +     *             following conditions is met:
  12.167 +     *
  12.168 +     *             <ul>
  12.169 +     *
  12.170 +     *             <li> invocation of
  12.171 +     *             {@link SecurityManager#checkMemberAccess
  12.172 +     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
  12.173 +     *             access to the constructors within this class
  12.174 +     *
  12.175 +     *             <li> the caller's class loader is not the same as or an
  12.176 +     *             ancestor of the class loader for the current class and
  12.177 +     *             invocation of {@link SecurityManager#checkPackageAccess
  12.178 +     *             s.checkPackageAccess()} denies access to the package
  12.179 +     *             of this class
  12.180 +     *
  12.181 +     *             </ul>
  12.182 +     *
  12.183 +     * @since JDK1.1
  12.184 +     */
  12.185 +    public Constructor<?>[] getConstructors() throws SecurityException {
  12.186 +        return MethodImpl.findConstructors(this, 0x01);
  12.187 +    }
  12.188 +
  12.189 +    /**
  12.190 +     * Returns a {@code Constructor} object that reflects the specified
  12.191 +     * public constructor of the class represented by this {@code Class}
  12.192 +     * object. The {@code parameterTypes} parameter is an array of
  12.193 +     * {@code Class} objects that identify the constructor's formal
  12.194 +     * parameter types, in declared order.
  12.195 +     *
  12.196 +     * If this {@code Class} object represents an inner class
  12.197 +     * declared in a non-static context, the formal parameter types
  12.198 +     * include the explicit enclosing instance as the first parameter.
  12.199 +     *
  12.200 +     * <p> The constructor to reflect is the public constructor of the class
  12.201 +     * represented by this {@code Class} object whose formal parameter
  12.202 +     * types match those specified by {@code parameterTypes}.
  12.203 +     *
  12.204 +     * @param parameterTypes the parameter array
  12.205 +     * @return the {@code Constructor} object of the public constructor that
  12.206 +     * matches the specified {@code parameterTypes}
  12.207 +     * @exception NoSuchMethodException if a matching method is not found.
  12.208 +     * @exception  SecurityException
  12.209 +     *             If a security manager, <i>s</i>, is present and any of the
  12.210 +     *             following conditions is met:
  12.211 +     *
  12.212 +     *             <ul>
  12.213 +     *
  12.214 +     *             <li> invocation of
  12.215 +     *             {@link SecurityManager#checkMemberAccess
  12.216 +     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
  12.217 +     *             access to the constructor
  12.218 +     *
  12.219 +     *             <li> the caller's class loader is not the same as or an
  12.220 +     *             ancestor of the class loader for the current class and
  12.221 +     *             invocation of {@link SecurityManager#checkPackageAccess
  12.222 +     *             s.checkPackageAccess()} denies access to the package
  12.223 +     *             of this class
  12.224 +     *
  12.225 +     *             </ul>
  12.226 +     *
  12.227 +     * @since JDK1.1
  12.228 +     */
  12.229 +    public Constructor<T> getConstructor(Class<?>... parameterTypes)
  12.230 +    throws NoSuchMethodException, SecurityException {
  12.231 +        Constructor c = MethodImpl.findConstructor(this, parameterTypes);
  12.232 +        if (c == null) {
  12.233 +            StringBuilder sb = new StringBuilder();
  12.234 +            sb.append(getName()).append('(');
  12.235 +            String sep = "";
  12.236 +            for (int i = 0; i < parameterTypes.length; i++) {
  12.237 +                sb.append(sep).append(parameterTypes[i].getName());
  12.238 +                sep = ", ";
  12.239 +            }
  12.240 +            sb.append(')');
  12.241 +            throw new NoSuchMethodException(sb.toString());
  12.242 +        }
  12.243 +        return c;
  12.244 +    }
  12.245 +
  12.246 +    /**
  12.247 +     * Returns an array of {@code Constructor} objects reflecting all the
  12.248 +     * constructors declared by the class represented by this
  12.249 +     * {@code Class} object. These are public, protected, default
  12.250 +     * (package) access, and private constructors.  The elements in the array
  12.251 +     * returned are not sorted and are not in any particular order.  If the
  12.252 +     * class has a default constructor, it is included in the returned array.
  12.253 +     * This method returns an array of length 0 if this {@code Class}
  12.254 +     * object represents an interface, a primitive type, an array class, or
  12.255 +     * void.
  12.256 +     *
  12.257 +     * <p> See <em>The Java Language Specification</em>, section 8.2.
  12.258 +     *
  12.259 +     * @return    the array of {@code Constructor} objects representing all the
  12.260 +     * declared constructors of this class
  12.261 +     * @exception  SecurityException
  12.262 +     *             If a security manager, <i>s</i>, is present and any of the
  12.263 +     *             following conditions is met:
  12.264 +     *
  12.265 +     *             <ul>
  12.266 +     *
  12.267 +     *             <li> invocation of
  12.268 +     *             {@link SecurityManager#checkMemberAccess
  12.269 +     *             s.checkMemberAccess(this, Member.DECLARED)} denies
  12.270 +     *             access to the declared constructors within this class
  12.271 +     *
  12.272 +     *             <li> the caller's class loader is not the same as or an
  12.273 +     *             ancestor of the class loader for the current class and
  12.274 +     *             invocation of {@link SecurityManager#checkPackageAccess
  12.275 +     *             s.checkPackageAccess()} denies access to the package
  12.276 +     *             of this class
  12.277 +     *
  12.278 +     *             </ul>
  12.279 +     *
  12.280 +     * @since JDK1.1
  12.281 +     */
  12.282 +    public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
  12.283 +        throw new SecurityException();
  12.284 +    }
  12.285 +    /**
  12.286 +     * Returns a {@code Constructor} object that reflects the specified
  12.287 +     * constructor of the class or interface represented by this
  12.288 +     * {@code Class} object.  The {@code parameterTypes} parameter is
  12.289 +     * an array of {@code Class} objects that identify the constructor's
  12.290 +     * formal parameter types, in declared order.
  12.291 +     *
  12.292 +     * If this {@code Class} object represents an inner class
  12.293 +     * declared in a non-static context, the formal parameter types
  12.294 +     * include the explicit enclosing instance as the first parameter.
  12.295 +     *
  12.296 +     * @param parameterTypes the parameter array
  12.297 +     * @return    The {@code Constructor} object for the constructor with the
  12.298 +     * specified parameter list
  12.299 +     * @exception NoSuchMethodException if a matching method is not found.
  12.300 +     * @exception  SecurityException
  12.301 +     *             If a security manager, <i>s</i>, is present and any of the
  12.302 +     *             following conditions is met:
  12.303 +     *
  12.304 +     *             <ul>
  12.305 +     *
  12.306 +     *             <li> invocation of
  12.307 +     *             {@link SecurityManager#checkMemberAccess
  12.308 +     *             s.checkMemberAccess(this, Member.DECLARED)} denies
  12.309 +     *             access to the declared constructor
  12.310 +     *
  12.311 +     *             <li> the caller's class loader is not the same as or an
  12.312 +     *             ancestor of the class loader for the current class and
  12.313 +     *             invocation of {@link SecurityManager#checkPackageAccess
  12.314 +     *             s.checkPackageAccess()} denies access to the package
  12.315 +     *             of this class
  12.316 +     *
  12.317 +     *             </ul>
  12.318 +     *
  12.319 +     * @since JDK1.1
  12.320 +     */
  12.321 +    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
  12.322 +    throws NoSuchMethodException, SecurityException {
  12.323 +        return getConstructor(parameterTypes);
  12.324 +    }
  12.325 +    
  12.326 +    
  12.327 +    /**
  12.328       * Character.isDigit answers {@code true} to some non-ascii
  12.329       * digits.  This one does not.
  12.330       */
    13.1 --- a/rt/emul/mini/src/main/java/java/lang/String.java	Thu Oct 03 15:43:10 2013 +0200
    13.2 +++ b/rt/emul/mini/src/main/java/java/lang/String.java	Thu Oct 03 15:51:55 2013 +0200
    13.3 @@ -27,6 +27,7 @@
    13.4  
    13.5  import java.io.UnsupportedEncodingException;
    13.6  import java.util.Comparator;
    13.7 +import java.util.Locale;
    13.8  import org.apidesign.bck2brwsr.core.ExtraJavaScript;
    13.9  import org.apidesign.bck2brwsr.core.JavaScriptBody;
   13.10  import org.apidesign.bck2brwsr.core.JavaScriptOnly;
   13.11 @@ -2456,7 +2457,9 @@
   13.12       * @see     java.lang.String#toUpperCase(Locale)
   13.13       * @since   1.1
   13.14       */
   13.15 -//    public String toLowerCase(Locale locale) {
   13.16 +    public String toLowerCase(java.util.Locale locale) {
   13.17 +        return toLowerCase();
   13.18 +    }
   13.19  //        if (locale == null) {
   13.20  //            throw new NullPointerException();
   13.21  //        }
   13.22 @@ -2571,7 +2574,7 @@
   13.23       */
   13.24      @JavaScriptBody(args = {}, body = "return this.toLowerCase();")
   13.25      public String toLowerCase() {
   13.26 -        throw new UnsupportedOperationException("Should be supported but without connection to locale");
   13.27 +        return null;
   13.28      }
   13.29  
   13.30      /**
   13.31 @@ -2622,8 +2625,10 @@
   13.32       * @see     java.lang.String#toLowerCase(Locale)
   13.33       * @since   1.1
   13.34       */
   13.35 +    public String toUpperCase(Locale locale) {
   13.36 +        return toUpperCase();
   13.37 +    }
   13.38      /* not for javascript 
   13.39 -    public String toUpperCase(Locale locale) {
   13.40          if (locale == null) {
   13.41              throw new NullPointerException();
   13.42          }
   13.43 @@ -2737,7 +2742,7 @@
   13.44       */
   13.45      @JavaScriptBody(args = {}, body = "return this.toUpperCase();")
   13.46      public String toUpperCase() {
   13.47 -        throw new UnsupportedOperationException();
   13.48 +        return null;
   13.49      }
   13.50  
   13.51      /**
   13.52 @@ -2848,7 +2853,7 @@
   13.53       * @since  1.5
   13.54       */
   13.55      public static String format(String format, Object ... args) {
   13.56 -        throw new UnsupportedOperationException();
   13.57 +        return format((Locale)null, format, args);
   13.58      }
   13.59  
   13.60      /**
   13.61 @@ -2891,9 +2896,15 @@
   13.62       * @see  java.util.Formatter
   13.63       * @since  1.5
   13.64       */
   13.65 -//    public static String format(Locale l, String format, Object ... args) {
   13.66 -//        return new Formatter(l).format(format, args).toString();
   13.67 -//    }
   13.68 +    public static String format(Locale l, String format, Object ... args) {
   13.69 +        String p = format;
   13.70 +        for (int i = 0; i < args.length; i++) {
   13.71 +            String v = args[i] == null ? "null" : args[i].toString();
   13.72 +            p = p.replaceFirst("%s", v);
   13.73 +        }
   13.74 +        return p;
   13.75 +        // return new Formatter(l).format(format, args).toString();
   13.76 +    }
   13.77  
   13.78      /**
   13.79       * Returns the string representation of the <code>Object</code> argument.
    14.1 --- a/rt/emul/mini/src/main/java/java/lang/Throwable.java	Thu Oct 03 15:43:10 2013 +0200
    14.2 +++ b/rt/emul/mini/src/main/java/java/lang/Throwable.java	Thu Oct 03 15:51:55 2013 +0200
    14.3 @@ -641,90 +641,28 @@
    14.4      @JavaScriptBody(args = {  }, body = "console.warn(this.toString());")
    14.5      public native void printStackTrace();
    14.6  
    14.7 -//    /**
    14.8 -//     * Prints this throwable and its backtrace to the specified print stream.
    14.9 -//     *
   14.10 -//     * @param s {@code PrintStream} to use for output
   14.11 -//     */
   14.12 -//    public void printStackTrace(PrintStream s) {
   14.13 -//        printStackTrace(new WrappedPrintStream(s));
   14.14 -//    }
   14.15 -//
   14.16 -//    private void printStackTrace(PrintStreamOrWriter s) {
   14.17 -//        // Guard against malicious overrides of Throwable.equals by
   14.18 -//        // using a Set with identity equality semantics.
   14.19 -////        Set<Throwable> dejaVu =
   14.20 -////            Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
   14.21 -////        dejaVu.add(this);
   14.22 -//
   14.23 -//        synchronized (s.lock()) {
   14.24 -//            // Print our stack trace
   14.25 -//            s.println(this);
   14.26 -//            StackTraceElement[] trace = getOurStackTrace();
   14.27 -//            for (StackTraceElement traceElement : trace)
   14.28 -//                s.println("\tat " + traceElement);
   14.29 -//
   14.30 -//            // Print suppressed exceptions, if any
   14.31 -////            for (Throwable se : getSuppressed())
   14.32 -////                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
   14.33 -//
   14.34 -//            // Print cause, if any
   14.35 -//            Throwable ourCause = getCause();
   14.36 -////            if (ourCause != null)
   14.37 -////                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
   14.38 -//        }
   14.39 -//    }
   14.40 -//
   14.41 -//    /**
   14.42 -//     * Print our stack trace as an enclosed exception for the specified
   14.43 -//     * stack trace.
   14.44 -//     */
   14.45 -//    private void printEnclosedStackTrace(PrintStreamOrWriter s,
   14.46 -//                                         StackTraceElement[] enclosingTrace,
   14.47 -//                                         String caption,
   14.48 -//                                         String prefix,
   14.49 -//                                         Object dejaVu) {
   14.50 -//        assert Thread.holdsLock(s.lock());
   14.51 -//        {
   14.52 -//            // Compute number of frames in common between this and enclosing trace
   14.53 -//            StackTraceElement[] trace = getOurStackTrace();
   14.54 -//            int m = trace.length - 1;
   14.55 -//            int n = enclosingTrace.length - 1;
   14.56 -//            while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
   14.57 -//                m--; n--;
   14.58 -//            }
   14.59 -//            int framesInCommon = trace.length - 1 - m;
   14.60 -//
   14.61 -//            // Print our stack trace
   14.62 -//            s.println(prefix + caption + this);
   14.63 -//            for (int i = 0; i <= m; i++)
   14.64 -//                s.println(prefix + "\tat " + trace[i]);
   14.65 -//            if (framesInCommon != 0)
   14.66 -//                s.println(prefix + "\t... " + framesInCommon + " more");
   14.67 -//
   14.68 -//            // Print suppressed exceptions, if any
   14.69 -//            for (Throwable se : getSuppressed())
   14.70 -//                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
   14.71 -//                                           prefix +"\t", dejaVu);
   14.72 -//
   14.73 -//            // Print cause, if any
   14.74 -//            Throwable ourCause = getCause();
   14.75 -//            if (ourCause != null)
   14.76 -//                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
   14.77 -//        }
   14.78 -//    }
   14.79 -//
   14.80 -//    /**
   14.81 -//     * Prints this throwable and its backtrace to the specified
   14.82 -//     * print writer.
   14.83 -//     *
   14.84 -//     * @param s {@code PrintWriter} to use for output
   14.85 -//     * @since   JDK1.1
   14.86 -//     */
   14.87 -//    public void printStackTrace(PrintWriter s) {
   14.88 -//        printStackTrace(new WrappedPrintWriter(s));
   14.89 -//    }
   14.90 -//
   14.91 +    /**
   14.92 +     * Prints this throwable and its backtrace to the specified print stream.
   14.93 +     *
   14.94 +     * @param s {@code PrintStream} to use for output
   14.95 +     */
   14.96 +    public void printStackTrace(PrintStream s) {
   14.97 +        s.print(getClass().getName());
   14.98 +        s.print(": ");
   14.99 +        s.println(getMessage());
  14.100 +    }
  14.101 +
  14.102 +    /**
  14.103 +     * Prints this throwable and its backtrace to the specified
  14.104 +     * print writer.
  14.105 +     *
  14.106 +     * @param s {@code PrintWriter} to use for output
  14.107 +     * @since   JDK1.1
  14.108 +     */
  14.109 +    public void printStackTrace(PrintWriter s) {
  14.110 +        s.append(getClass().getName()).append(": ").println(getMessage());
  14.111 +    }
  14.112 +
  14.113  //    /**
  14.114  //     * Wrapper class for PrintStream and PrintWriter to enable a single
  14.115  //     * implementation of printStackTrace.
    15.1 --- a/rt/emul/mini/src/main/java/java/lang/reflect/Constructor.java	Thu Oct 03 15:43:10 2013 +0200
    15.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Constructor.java	Thu Oct 03 15:51:55 2013 +0200
    15.3 @@ -26,6 +26,10 @@
    15.4  package java.lang.reflect;
    15.5  
    15.6  import java.lang.annotation.Annotation;
    15.7 +import static java.lang.reflect.Method.fromPrimitive;
    15.8 +import static java.lang.reflect.Method.getAccess;
    15.9 +import static java.lang.reflect.Method.getParameterTypes;
   15.10 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   15.11  import org.apidesign.bck2brwsr.emul.reflect.TypeProvider;
   15.12  
   15.13  /**
   15.14 @@ -53,44 +57,20 @@
   15.15                                                      GenericDeclaration,
   15.16                                                      Member {
   15.17  
   15.18 -    private Class<T>            clazz;
   15.19 -    private int                 slot;
   15.20 -    private Class<?>[]          parameterTypes;
   15.21 -    private Class<?>[]          exceptionTypes;
   15.22 -    private int                 modifiers;
   15.23 -    // Generics and annotations support
   15.24 -    private transient String    signature;
   15.25 -    private byte[]              annotations;
   15.26 -    private byte[]              parameterAnnotations;
   15.27 -
   15.28 -
   15.29 -    // For sharing of ConstructorAccessors. This branching structure
   15.30 -    // is currently only two levels deep (i.e., one root Constructor
   15.31 -    // and potentially many Constructor objects pointing to it.)
   15.32 -    private Constructor<T>      root;
   15.33 +    private final Class<T> clazz;
   15.34 +    private final Object data;
   15.35 +    private final String sig;
   15.36  
   15.37      /**
   15.38       * Package-private constructor used by ReflectAccess to enable
   15.39       * instantiation of these objects in Java code from the java.lang
   15.40       * package via sun.reflect.LangReflectAccess.
   15.41       */
   15.42 -    Constructor(Class<T> declaringClass,
   15.43 -                Class<?>[] parameterTypes,
   15.44 -                Class<?>[] checkedExceptions,
   15.45 -                int modifiers,
   15.46 -                int slot,
   15.47 -                String signature,
   15.48 -                byte[] annotations,
   15.49 -                byte[] parameterAnnotations)
   15.50 +    Constructor(Class<T> declaringClass, Object data, String sig)
   15.51      {
   15.52          this.clazz = declaringClass;
   15.53 -        this.parameterTypes = parameterTypes;
   15.54 -        this.exceptionTypes = checkedExceptions;
   15.55 -        this.modifiers = modifiers;
   15.56 -        this.slot = slot;
   15.57 -        this.signature = signature;
   15.58 -        this.annotations = annotations;
   15.59 -        this.parameterAnnotations = parameterAnnotations;
   15.60 +        this.data = data;
   15.61 +        this.sig = sig;
   15.62      }
   15.63  
   15.64      /**
   15.65 @@ -126,7 +106,7 @@
   15.66       * @see Modifier
   15.67       */
   15.68      public int getModifiers() {
   15.69 -        return modifiers;
   15.70 +        return getAccess(data);
   15.71      }
   15.72  
   15.73      /**
   15.74 @@ -159,7 +139,7 @@
   15.75       * represents
   15.76       */
   15.77      public Class<?>[] getParameterTypes() {
   15.78 -        return (Class<?>[]) parameterTypes.clone();
   15.79 +        return Method.getParameterTypes(sig);
   15.80      }
   15.81  
   15.82  
   15.83 @@ -205,7 +185,7 @@
   15.84       * constructor this object represents
   15.85       */
   15.86      public Class<?>[] getExceptionTypes() {
   15.87 -        return (Class<?>[])exceptionTypes.clone();
   15.88 +        throw new UnsupportedOperationException();
   15.89      }
   15.90  
   15.91  
   15.92 @@ -242,20 +222,9 @@
   15.93       * same formal parameter types.
   15.94       */
   15.95      public boolean equals(Object obj) {
   15.96 -        if (obj != null && obj instanceof Constructor) {
   15.97 -            Constructor<?> other = (Constructor<?>)obj;
   15.98 -            if (getDeclaringClass() == other.getDeclaringClass()) {
   15.99 -                /* Avoid unnecessary cloning */
  15.100 -                Class<?>[] params1 = parameterTypes;
  15.101 -                Class<?>[] params2 = other.parameterTypes;
  15.102 -                if (params1.length == params2.length) {
  15.103 -                    for (int i = 0; i < params1.length; i++) {
  15.104 -                        if (params1[i] != params2[i])
  15.105 -                            return false;
  15.106 -                    }
  15.107 -                    return true;
  15.108 -                }
  15.109 -            }
  15.110 +        if (obj instanceof Constructor) {
  15.111 +            Constructor other = (Constructor)obj;
  15.112 +            return data == other.data;
  15.113          }
  15.114          return false;
  15.115      }
  15.116 @@ -293,13 +262,14 @@
  15.117              }
  15.118              sb.append(Field.getTypeName(getDeclaringClass()));
  15.119              sb.append("(");
  15.120 -            Class<?>[] params = parameterTypes; // avoid clone
  15.121 +            Class<?>[] params = getParameterTypes(); // avoid clone
  15.122              for (int j = 0; j < params.length; j++) {
  15.123                  sb.append(Field.getTypeName(params[j]));
  15.124                  if (j < (params.length - 1))
  15.125                      sb.append(",");
  15.126              }
  15.127              sb.append(")");
  15.128 +            /*
  15.129              Class<?>[] exceptions = exceptionTypes; // avoid clone
  15.130              if (exceptions.length > 0) {
  15.131                  sb.append(" throws ");
  15.132 @@ -309,6 +279,7 @@
  15.133                          sb.append(",");
  15.134                  }
  15.135              }
  15.136 +            */
  15.137              return sb.toString();
  15.138          } catch (Exception e) {
  15.139              return "<" + e + ">";
  15.140 @@ -452,9 +423,29 @@
  15.141          throws InstantiationException, IllegalAccessException,
  15.142                 IllegalArgumentException, InvocationTargetException
  15.143      {
  15.144 -        throw new SecurityException();
  15.145 +        Class[] types = getParameterTypes();
  15.146 +        if (types.length != initargs.length) {
  15.147 +            throw new IllegalArgumentException("Types len " + types.length + " args: " + initargs.length);
  15.148 +        } else {
  15.149 +            initargs = initargs.clone();
  15.150 +            for (int i = 0; i < types.length; i++) {
  15.151 +                Class c = types[i];
  15.152 +                if (c.isPrimitive() && initargs[i] != null) {
  15.153 +                    initargs[i] = Method.toPrimitive(initargs[i]);
  15.154 +                }
  15.155 +            }
  15.156 +        }
  15.157 +        return (T) newInstance0(this.getDeclaringClass(), "cons__" + sig, initargs);
  15.158      }
  15.159  
  15.160 +    @JavaScriptBody(args = { "self", "sig", "args" }, body =
  15.161 +          "\nvar c = self.cnstr;"
  15.162 +        + "\nvar inst = c();"
  15.163 +        + "\nc[sig].apply(inst, args);"
  15.164 +        + "\nreturn inst;"
  15.165 +    )
  15.166 +    private static native Object newInstance0(Class<?> self, String sig, Object[] args);
  15.167 +    
  15.168      /**
  15.169       * Returns {@code true} if this constructor was declared to take
  15.170       * a variable number of arguments; returns {@code false}
  15.171 @@ -481,22 +472,6 @@
  15.172          return Modifier.isSynthetic(getModifiers());
  15.173      }
  15.174  
  15.175 -    int getSlot() {
  15.176 -        return slot;
  15.177 -    }
  15.178 -
  15.179 -   String getSignature() {
  15.180 -            return signature;
  15.181 -   }
  15.182 -
  15.183 -    byte[] getRawAnnotations() {
  15.184 -        return annotations;
  15.185 -    }
  15.186 -
  15.187 -    byte[] getRawParameterAnnotations() {
  15.188 -        return parameterAnnotations;
  15.189 -    }
  15.190 -
  15.191      /**
  15.192       * @throws NullPointerException {@inheritDoc}
  15.193       * @since 1.5
  15.194 @@ -532,11 +507,11 @@
  15.195       * @since 1.5
  15.196       */
  15.197      public Annotation[][] getParameterAnnotations() {
  15.198 -        int numParameters = parameterTypes.length;
  15.199 -        if (parameterAnnotations == null)
  15.200 -            return new Annotation[numParameters][0];
  15.201 +//        int numParameters = parameterTypes.length;
  15.202 +//        if (parameterAnnotations == null)
  15.203 +//            return new Annotation[numParameters][0];
  15.204          
  15.205 -        return new Annotation[numParameters][0]; // XXX
  15.206 +        return new Annotation[0][0]; // XXX
  15.207  /*
  15.208          Annotation[][] result = AnnotationParser.parseParameterAnnotations(
  15.209              parameterAnnotations,
    16.1 --- a/rt/emul/mini/src/main/java/java/lang/reflect/Method.java	Thu Oct 03 15:43:10 2013 +0200
    16.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Method.java	Thu Oct 03 15:51:55 2013 +0200
    16.3 @@ -113,7 +113,7 @@
    16.4      }
    16.5      
    16.6      @JavaScriptBody(args = "self", body = "return self.access;")
    16.7 -    private static native int getAccess(Object self);
    16.8 +    static native int getAccess(Object self);
    16.9      
   16.10      /**
   16.11       * Returns an array of {@code TypeVariable} objects that represent the
   16.12 @@ -183,6 +183,10 @@
   16.13       * represents
   16.14       */
   16.15      public Class<?>[] getParameterTypes() {
   16.16 +        return getParameterTypes(sig);
   16.17 +    }
   16.18 +    
   16.19 +    static Class<?>[] getParameterTypes(String sig) {
   16.20          Class[] arr = new Class[MethodImpl.signatureElements(sig) - 1];
   16.21          Enumeration<Class> en = MethodImpl.signatureParser(sig);
   16.22          en.nextElement(); // return type
   16.23 @@ -583,7 +587,7 @@
   16.24      private static native Integer fromRaw(Class<?> cls, String m, Object o);
   16.25  
   16.26      @JavaScriptBody(args = { "o" }, body = "return o.valueOf();")
   16.27 -    private static native Object toPrimitive(Object o);
   16.28 +    static native Object toPrimitive(Object o);
   16.29      
   16.30      /**
   16.31       * Returns {@code true} if this method is a bridge
   16.32 @@ -692,6 +696,11 @@
   16.33              protected Method create(Class<?> declaringClass, String name, Object data, String sig) {
   16.34                  return new Method(declaringClass, name, data, sig);
   16.35              }
   16.36 +
   16.37 +            @Override
   16.38 +            protected Constructor create(Class<?> declaringClass, Object data, String sig) {
   16.39 +                return new Constructor(declaringClass, data, sig);
   16.40 +            }
   16.41          };
   16.42      }
   16.43  }
    17.1 --- a/rt/emul/mini/src/main/java/java/net/URL.java	Thu Oct 03 15:43:10 2013 +0200
    17.2 +++ b/rt/emul/mini/src/main/java/java/net/URL.java	Thu Oct 03 15:51:55 2013 +0200
    17.3 @@ -920,6 +920,23 @@
    17.4      }
    17.5  
    17.6      /**
    17.7 +     * Returns a {@link java.net.URI} equivalent to this URL.
    17.8 +     * This method functions in the same way as <code>new URI (this.toString())</code>.
    17.9 +     * <p>Note, any URL instance that complies with RFC 2396 can be converted
   17.10 +     * to a URI. However, some URLs that are not strictly in compliance
   17.11 +     * can not be converted to a URI.
   17.12 +     *
   17.13 +     * @exception URISyntaxException if this URL is not formatted strictly according to
   17.14 +     *            to RFC2396 and cannot be converted to a URI.
   17.15 +     *
   17.16 +     * @return    a URI instance equivalent to this URL.
   17.17 +     * @since 1.5
   17.18 +     */
   17.19 +    public URI toURI() throws URISyntaxException {
   17.20 +        return new URI (toString());
   17.21 +    }
   17.22 +
   17.23 +    /**
   17.24       * Returns a {@link java.net.URLConnection URLConnection} instance that
   17.25       * represents a connection to the remote object referred to by the
   17.26       * {@code URL}.
    18.1 --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Thu Oct 03 15:43:10 2013 +0200
    18.2 +++ b/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Thu Oct 03 15:51:55 2013 +0200
    18.3 @@ -18,6 +18,7 @@
    18.4  package org.apidesign.bck2brwsr.emul.reflect;
    18.5  
    18.6  import java.lang.reflect.Array;
    18.7 +import java.lang.reflect.Constructor;
    18.8  import java.lang.reflect.Method;
    18.9  import java.util.Enumeration;
   18.10  import org.apidesign.bck2brwsr.core.JavaScriptBody;
   18.11 @@ -37,15 +38,17 @@
   18.12      }
   18.13  
   18.14      protected abstract Method create(Class<?> declaringClass, String name, Object data, String sig);
   18.15 +    protected abstract Constructor create(Class<?> declaringClass, Object data, String sig);
   18.16      
   18.17      
   18.18      //
   18.19      // bck2brwsr implementation
   18.20      //
   18.21  
   18.22 -    @JavaScriptBody(args = {"clazz", "prefix"},
   18.23 +    @JavaScriptBody(args = {"clazz", "prefix", "cnstr"},
   18.24          body = ""
   18.25 -        + "var c = clazz.cnstr.prototype;"
   18.26 +        + "var c = clazz.cnstr;\n"
   18.27 +        + "if (!cnstr) c = c.prototype;"
   18.28          + "var arr = new Array();\n"
   18.29          + "for (m in c) {\n"
   18.30          + "  if (m.indexOf(prefix) === 0) {\n"
   18.31 @@ -57,11 +60,55 @@
   18.32          + "}\n"
   18.33          + "return arr;")
   18.34      private static native Object[] findMethodData(
   18.35 -        Class<?> clazz, String prefix);
   18.36 +        Class<?> clazz, String prefix, boolean cnstr);
   18.37  
   18.38 +    public static Constructor findConstructor(
   18.39 +        Class<?> clazz, Class<?>... parameterTypes) {
   18.40 +        Object[] data = findMethodData(clazz, "cons__", true);
   18.41 +        BIG: for (int i = 0; i < data.length; i += 3) {
   18.42 +            String sig = ((String) data[i]).substring(6);
   18.43 +            Class<?> cls = (Class<?>) data[i + 2];
   18.44 +            Constructor tmp = INSTANCE.create(cls, data[i + 1], sig);
   18.45 +            Class<?>[] tmpParms = tmp.getParameterTypes();
   18.46 +            if (parameterTypes.length != tmpParms.length) {
   18.47 +                continue;
   18.48 +            }
   18.49 +            for (int j = 0; j < tmpParms.length; j++) {
   18.50 +                if (!parameterTypes[j].equals(tmpParms[j])) {
   18.51 +                    continue BIG;
   18.52 +                }
   18.53 +            }
   18.54 +            return tmp;
   18.55 +        }
   18.56 +        return null;
   18.57 +    }
   18.58 +
   18.59 +    public static Constructor[] findConstructors(Class<?> clazz, int mask) {
   18.60 +        Object[] namesAndData = findMethodData(clazz, "", true);
   18.61 +        int cnt = 0;
   18.62 +        for (int i = 0; i < namesAndData.length; i += 3) {
   18.63 +            String sig = (String) namesAndData[i];
   18.64 +            Object data = namesAndData[i + 1];
   18.65 +            if (!sig.startsWith("cons__")) {
   18.66 +                continue;
   18.67 +            }
   18.68 +            sig = sig.substring(6);
   18.69 +            Class<?> cls = (Class<?>) namesAndData[i + 2];
   18.70 +            final Constructor m = INSTANCE.create(cls, data, sig);
   18.71 +            if ((m.getModifiers() & mask) == 0) {
   18.72 +                continue;
   18.73 +            }
   18.74 +            namesAndData[cnt++] = m;
   18.75 +        }
   18.76 +        Constructor[] arr = new Constructor[cnt];
   18.77 +        for (int i = 0; i < cnt; i++) {
   18.78 +            arr[i] = (Constructor) namesAndData[i];
   18.79 +        }
   18.80 +        return arr;
   18.81 +    }
   18.82      public static Method findMethod(
   18.83          Class<?> clazz, String name, Class<?>... parameterTypes) {
   18.84 -        Object[] data = findMethodData(clazz, name + "__");
   18.85 +        Object[] data = findMethodData(clazz, name + "__", false);
   18.86          BIG: for (int i = 0; i < data.length; i += 3) {
   18.87              String sig = ((String) data[i]).substring(name.length() + 2);
   18.88              Class<?> cls = (Class<?>) data[i + 2];
   18.89 @@ -81,7 +128,7 @@
   18.90      }
   18.91  
   18.92      public static Method[] findMethods(Class<?> clazz, int mask) {
   18.93 -        Object[] namesAndData = findMethodData(clazz, "");
   18.94 +        Object[] namesAndData = findMethodData(clazz, "", false);
   18.95          int cnt = 0;
   18.96          for (int i = 0; i < namesAndData.length; i += 3) {
   18.97              String sig = (String) namesAndData[i];