/*
 * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
/*
    @test
    @summary test Resource Bundle for bug 4168625
    @build Bug4168625Class Bug4168625Getter Bug4168625Resource Bug4168625Resource3 Bug4168625Resource3_en Bug4168625Resource3_en_CA Bug4168625Resource3_en_IE Bug4168625Resource3_en_US Bug4168625Resource2_en_US Bug4168625Resource2
    @run main/timeout=600 Bug4168625Test
    @bug 4168625
*/
/*
 *
 *
 * (C) Copyright IBM Corp. 1999 - All Rights Reserved
 *
 * Portions Copyright 2007 by Sun Microsystems, Inc.,
 * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of Sun Microsystems, Inc. ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Sun.
 *
 * The original version of this source code and documentation is
 * copyrighted and owned by IBM. These materials are provided
 * under terms of a License Agreement between IBM and Sun.
 * This technology is protected by multiple US and International
 * patents. This notice and attribution to IBM may not be removed.
 *
 */

import java.util.*;
import java.io.*;

/**
 *  This test tries to correct three efficiency problems with the caching
 *  mechanism of ResourceBundle.  All tests assume that none of the bundles
 *  have been previously loaded and cached.  It also allows concurrent loads
 *  of resource bundles to be performed if the bundles are unrelated (ex. a
 *  load of a local system resource by one thread while another thread is
 *  doing a slow load over a network).
 */
public class Bug4168625Test extends RBTestFmwk {
    public static void main(String[] args) throws Exception {
        new Bug4168625Test().run(args);
    }

    /**
     * Verify that getBundle will do something reasonable when part of the
     * resource hierarchy is missing.
     */
    public void testMissingParent() throws Exception {
        final Locale oldDefault = Locale.getDefault();
        Locale.setDefault(new Locale("en", "US"));
        try {
            final Locale loc = new Locale("jf", "jf");
            ResourceBundle bundle = ResourceBundle.getBundle("Bug4168625Resource2", loc);
            final String s1 = bundle.getString("name");
            if (!s1.equals("Bug4168625Resource2_en_US")) {
                errln("getBundle did not find leaf bundle: "+bundle.getClass().getName());
            }
            final String s2 = bundle.getString("baseName");
            if (!s2.equals("Bug4168625Resource2")) {
                errln("getBundle did not set up proper inheritance chain");
            }
        } finally {
            Locale.setDefault(oldDefault);
        }
    }

    /**
     *  Previous versions of ResourceBundle have had the following
     *  caching behavior.  Assume the classes
     *  Bug4168625Resource_fr_FR, Bug4168625Resource_fr,
     *  Bug4168625Resource_en_US, and Bug4168625Resource_en don't
     *  exist.  The class Bug4168625Resource does.  Assume the default
     *  locale is en_US.
     *  <P>
     *  <pre>
     *  getBundle("Bug4168625Resource", new Locale("fr", "FR"));
     *      -->try to load Bug4168625Resource_fr_FR
     *      -->try to load Bug4168625Resource_fr
     *      -->try to load Bug4168625Resource_en_US
     *      -->try to load Bug4168625Resource_en
     *      -->load Bug4168625Resource
     *      -->cache Bug4168625Resource as Bug4168625Resource
     *      -->cache Bug4168625Resource as Bug4168625Resource_en
     *      -->cache Bug4168625Resource as Bug4168625Resource_en_US
     *      -->return Bug4168625Resource
     *  getBundle("Bug4168625Resource", new Locale("fr", "FR"));
     *      -->try to load Bug4168625Resource_fr_FR
     *      -->try to load Bug4168625Resource_fr
     *      -->find cached Bug4168625Resource_en_US
     *      -->return Bug4168625Resource_en_US (which is realy Bug4168625Resource)
     *  </pre>
     *  <P>
     *  The second call causes two loads for Bug4168625Resource_fr_FR and
     *  Bug4168625Resource_en which have already been tried and failed.  These
     *  two loads should have been cached as Bug4168625Resource by the first
     *  call.
     *
     *  The following, more efficient behavior is desired:
     *  <P>
     *  <pre>
     *  getBundle("Bug4168625Resource", new Locale("fr", "FR"));
     *      -->try to load Bug4168625Resource_fr_FR
     *      -->try to load Bug4168625Resource_fr
     *      -->try to load Bug4168625Resource_en_US
     *      -->try to load Bug4168625Resource_en
     *      -->load Bug4168625Resource
     *      -->cache Bug4168625Resource as Bug4168625Resource
     *      -->cache Bug4168625Resource as Bug4168625Resource_en
     *      -->cache Bug4168625Resource as Bug4168625Resource_en_US
     *      -->cache Bug4168625Resource as Bug4168625Resource_fr
     *      -->cache Bug4168625Resource as Bug4168625Resource_fr_FR
     *      -->return Bug4168625Resource
     *  getBundle("Bug4168625Resource", new Locale("fr", "FR"));
     *      -->find cached Bug4168625Resource_fr_FR
     *      -->return Bug4168625Resource_en_US (which is realy Bug4168625Resource)
     *  </pre>
     *  <P>
     *
     */
    public void testCacheFailures() throws Exception {
        checkResourceLoading("Bug4168625Resource", new Locale("fr", "FR"));
    }

    /**
     *  Previous versions of ResourceBundle have had the following
     *  caching behavior.  Assume the current locale is locale is en_US.
     *  The classes Bug4168625Resource_en_US, and Bug4168625Resource_en don't
     *  exist.  The class Bug4168625Resource does.
     *  <P>
     *  <pre>
     *  getBundle("Bug4168625Resource", new Locale("en", "US"));
     *      -->try to load Bug4168625Resource_en_US
     *      -->try to load Bug4168625Resource_en
     *      -->try to load Bug4168625Resource_en_US
     *      -->try to load Bug4168625Resource_en
     *      -->load Bug4168625Resource
     *      -->cache Bug4168625Resource as Bug4168625Resource
     *      -->cache Bug4168625Resource as Bug4168625Resource_en
     *      -->cache Bug4168625Resource as Bug4168625Resource_en_US
     *      -->return Bug4168625Resource
     *  </pre>
     *  <P>
     *  The redundant loads of Bug4168625Resource_en_US and Bug4168625Resource_en
     *  should not occur.  The desired behavior is as follows:
     *  <P>
     *  <pre>
     *  getBundle("Bug4168625Resource", new Locale("en", "US"));
     *      -->try to load Bug4168625Resource_en_US
     *      -->try to load Bug4168625Resource_en
     *      -->load Bug4168625Resource
     *      -->cache Bug4168625Resource as Bug4168625Resource
     *      -->cache Bug4168625Resource as Bug4168625Resource_en
     *      -->cache Bug4168625Resource as Bug4168625Resource_en_US
     *      -->return Bug4168625Resource
     *  </pre>
     *  <P>
     */
    public void testRedundantLoads() throws Exception {
        checkResourceLoading("Bug4168625Resource", Locale.getDefault());
    }

    /**
     * Ensure that resources are only loaded once and are cached correctly
     */
    private void checkResourceLoading(String resName, Locale l) throws Exception {
        final Loader loader = new Loader( new String[] { "Bug4168625Class" }, new String[] { "Bug4168625Resource3_en_US", "Bug4168625Resource3_en_CA" });
        final Class c = loader.loadClass("Bug4168625Class");
        Bug4168625Getter test = (Bug4168625Getter)c.newInstance();
        final String resClassName;
        if (l.toString().length() > 0) {
            resClassName = resName+"_"+l;
        } else {
            resClassName = resName;
        }

        Object bundle = test.getResourceBundle(resName, l);
        loader.logClasses("Initial lookup of "+resClassName+" generated the following loads:");

        final Vector lastLoad = new Vector(loader.loadedClasses.size());
        boolean dups = false;
        for (int i = loader.loadedClasses.size() - 1; i >= 0 ; i--) {
            final Object item = loader.loadedClasses.elementAt(i);
            loader.loadedClasses.removeElementAt(i);
            if (loader.loadedClasses.contains(item)) {
                logln("Resource loaded more than once: "+item);
                dups = true;
            } else {
                lastLoad.addElement(item);
            }
        }
        if (dups) {
            errln("ResourceBundle loaded some classes multiple times");
        }

        loader.loadedClasses.removeAllElements();
        bundle = test.getResourceBundle(resName, l);
        loader.logClasses("Second lookup of "+resClassName+" generated the following loads:");

        dups = false;
        for (int i = 0; i < loader.loadedClasses.size(); i++) {
            Object item = loader.loadedClasses.elementAt(i);
            if (lastLoad.contains(item)) {
                logln("ResourceBundle did not cache "+item+" correctly");
                dups = true;
            }
        }
        if (dups) {
            errln("Resource bundle not caching some classes properly");
        }
    }

    /**
     *  Previous versions of ResourceBundle exhibited the following caching behavior.
     *  Assume the class Bug4168625Resource_en exists. Bug4168625Resource_en_US does
     *  not.  Two threads, ThreadA and ThreadB both try to get the same bundle.
     *  <P>
     *  <pre>
     *  ThreadA.getBundle("Bug4168625Resource", new Locale("en", "US"));
     *      A-->try to load Bug4168625Resource_en_US
     *  ThreadB.getBundle("Bug4168625Resource", new Locale("en", "US"));
     *      B-->try to load Bug4168625Resource_en_US
     *      B-->load Bug4168625Resource_en (#1)
     *      A-->load Bug4168625Resource_en (#2)
     *      A-->cache Bug4168625Resource_en (#2) as Bug4168625Resource_en
     *      A-->cache Bug4168625Resource_en (#2) as Bug4168625Resource_en_US
     *      A-->return Bug4168625Resource_en (#2)
     *      B-->cache Bug4168625Resource_en (#1) as Bug4168625Resource_en
     *      B-->cache Bug4168625Resource_en (#1) as Bug4168625Resource_en_US
     *      B-->return Bug4168625Resource_en (#1)
     *  </pre>
     *  <P>
     *  Both threads try and fail to load Bug4168625Resource_en_US.  Both
     *  threads load Bug4168625Resource_en.  Both threads get their own copy
     *  of the Bug4168625Resource_en resource.
     *
     *  The desired behavior is as follows:
     *  <P>
     *  <pre>
     *  ThreadA.getBundle("Bug4168625Resource", new Locale("en", "US"));
     *      A-->try to load Bug4168625Resource_en_US
     *  ThreadB.getBundle("Bug4168625Resource", new Locale("en", "US"));
     *      B-->try to load Bug4168625Resource_en_US
     *      B-->load Bug4168625Resource_en
     *      A-->load Bug4168625Resource_en (block in ResourceBundle.getBundle)
     *      B-->cache Bug4168625Resource_en as Bug4168625Resource_en
     *      B-->cache Bug4168625Resource_en as Bug4168625Resource_en_US
     *      A-->return Bug4168625Resource_en
     *      B-->return Bug4168625Resource_en
     *  </pre>
     *  <P>
     *  Note that both threads return the same bundle object.
     */
    public void testConcurrentLoading1() throws Exception {
        final Loader loader = new Loader( new String[] { "Bug4168625Class" }, new String[] { "Bug4168625Resource3_en_US", "Bug4168625Resource3_en_CA" });
        final Class c = loader.loadClass("Bug4168625Class");
        final Bug4168625Getter test = (Bug4168625Getter)c.newInstance();

            //both threads want the same resource
        ConcurrentLoadingThread thread1 = new ConcurrentLoadingThread(loader, test, new Locale("en", "US"));
        ConcurrentLoadingThread thread2 = new ConcurrentLoadingThread(loader, test, new Locale("en", "US"));

        thread1.start();            //start thread 1
        loader.waitForNotify(1);    //wait for thread1 to do getBundle & block in loader
        thread2.start();            //start second thread
        loader.waitForNotify(2, 1000);  //wait until thread2 blocks somewhere in getBundle
        thread1.ping();             //continue both threads
        thread2.ping();

        thread1.join();             //wait unitl both threads complete
        thread2.join();

            //Now, examine the class loads that were done.
        loader.logClasses("Classes loaded after completion of both threads:");

        boolean dups = false;
        for (int i = loader.loadedClasses.size() - 1; i >= 0 ; i--) {
            final Object item = loader.loadedClasses.elementAt(i);
            loader.loadedClasses.removeElementAt(i);
            if (loader.loadedClasses.contains(item)) {
                logln("Resource loaded more than once: "+item);
                dups = true;
            }
        }
        if (dups) {
            errln("ResourceBundle loaded some classes multiple times");
        }
    }

    private class ConcurrentLoadingThread extends Thread {
        private Loader loader;
        public Object bundle;
        private Bug4168625Getter test;
        private Locale locale;
        private String resourceName = "Bug4168625Resource3";
        public ConcurrentLoadingThread(Loader loader, Bug4168625Getter test, Locale l, String resourceName) {
            this.loader = loader;
            this.test = test;
            this.locale = l;
            this.resourceName = resourceName;
        }
        public ConcurrentLoadingThread(Loader loader, Bug4168625Getter test, Locale l) {
            this.loader = loader;
            this.test = test;
            this.locale = l;
        }
        public void run() {
            try {
                logln(">>"+threadName()+">run");
                bundle = test.getResourceBundle(resourceName, locale);
            } catch (Exception e) {
                errln("TEST CAUGHT UNEXPECTED EXCEPTION: "+e);
            } finally {
                logln("<<"+threadName()+"<run");
            }
        }
        public synchronized void waitUntilPinged() {
            logln(">>"+threadName()+">waitUntilPinged");
            loader.notifyEveryone();
            try {
                wait(30000);    //wait 30 seconds max.
            } catch (InterruptedException e) {
                logln("Test deadlocked.");
            }
            logln("<<"+threadName()+"<waitUntilPinged");
        }
        public synchronized void ping() {
            logln(">>"+threadName()+">ping "+threadName(this));
            notifyAll();
            logln("<<"+threadName()+"<ping "+threadName(this));
        }
    };

    /**
     * This test ensures that multiple resources can be loading at the same
     * time as long as they don't depend on each other in some way.
     */
    public void testConcurrentLoading2() throws Exception {
        final Loader loader = new Loader( new String[] { "Bug4168625Class" }, new String[] { "Bug4168625Resource3_en_US", "Bug4168625Resource3_en_CA" });
        final Class c = loader.loadClass("Bug4168625Class");
        final Bug4168625Getter test = (Bug4168625Getter)c.newInstance();

        ConcurrentLoadingThread thread1 = new ConcurrentLoadingThread(loader, test, new Locale("en", "CA"));
        ConcurrentLoadingThread thread2 = new ConcurrentLoadingThread(loader, test, new Locale("en", "IE"));

        thread1.start();            //start thread 1
        loader.waitForNotify(1);    //wait for thread1 to do getBundle & block in loader
        thread2.start();            //start second thread
        thread2.join(1000);         //wait until thread2 blocks somewhere in getBundle

            //Thread1 should be blocked inside getBundle at the class loader
            //Thread2 should have completed its getBundle call and terminated
        if (!thread1.isAlive() || thread2.isAlive()) {
            errln("ResourceBundle.getBundle not allowing legal concurrent loads");
        }

        thread1.ping();             //continue thread1
        thread1.join();
        thread2.join();
    }

    /**
     * This test ensures that a resource loads correctly (with all its parents)
     * when memory is very low (ex. the cache gets purged during a load).
     */
    public void testLowMemoryLoad() throws Exception {
        final String[] classToLoad = { "Bug4168625Class" };
        final String[] classToWait = { "Bug4168625Resource3_en_US","Bug4168625Resource3_en","Bug4168625Resource3" };
        final Loader loader = new Loader(classToLoad, classToWait);
        final Class c = loader.loadClass("Bug4168625Class");
        final Bug4168625Getter test = (Bug4168625Getter)c.newInstance();
        causeResourceBundleCacheFlush();

        ConcurrentLoadingThread thread1 = new ConcurrentLoadingThread(loader, test, new Locale("en", "US"));
        thread1.start();            //start thread 1
        loader.waitForNotify(1);    //wait for thread1 to do getBundle(en_US) & block in loader
        causeResourceBundleCacheFlush();    //cause a cache flush
        thread1.ping();             //kick thread 1
        loader.waitForNotify(2);    //wait for thread1 to do getBundle(en) & block in loader
        causeResourceBundleCacheFlush();    //cause a cache flush
        thread1.ping();             //kick thread 1
        loader.waitForNotify(3);    //wait for thread1 to do getBundle(en) & block in loader
        causeResourceBundleCacheFlush();    //cause a cache flush
        thread1.ping();             //kick thread 1
        thread1.ping();             //kick thread 1
        thread1.join(1000);         //wait until thread2 blocks somewhere in getBundle

        ResourceBundle bundle = (ResourceBundle)thread1.bundle;
        String s1 = bundle.getString("Bug4168625Resource3_en_US");
        String s2 = bundle.getString("Bug4168625Resource3_en");
        String s3 = bundle.getString("Bug4168625Resource3");
        if ((s1 == null) || (s2 == null) || (s3 == null)) {
            errln("Bundle not constructed correctly.  The parent chain is incorrect.");
        }
    }

    /**
     * A simple class loader that loads classes from the current
     * working directory.  The loader will block the current thread
     * of execution before it returns when it tries to load
     * the class "Bug4168625Resource3_en_US".
     */
    private static final String CLASS_PREFIX = "";
    private static final String CLASS_SUFFIX = ".class";

    private static final class SimpleLoader extends ClassLoader {
        private boolean network = false;

        public SimpleLoader() {
            this.network = false;
        }
        public SimpleLoader(boolean simulateNetworkLoad) {
            this.network = simulateNetworkLoad;
        }
        public Class loadClass(final String className, final boolean resolveIt)
                throws ClassNotFoundException {
            Class result;
            synchronized (this) {
                result = findLoadedClass(className);
                if (result == null) {
                    if (network) {
                        try {
                             Thread.sleep(100);
                        } catch (java.lang.InterruptedException e) {
                        }
                    }
                    result = super.findSystemClass(className);
                    if ((result != null) && resolveIt) {
                        resolveClass(result);
                    }
                }
            }
            return result;
        }
    }

    private final class Loader extends ClassLoader {
        public final Vector loadedClasses = new Vector();
        private String[] classesToLoad;
        private String[] classesToWaitFor;

        public Loader() {
            classesToLoad = new String[0];
            classesToWaitFor = new String[0];
        }

        public Loader(final String[] classesToLoadIn, final String[] classesToWaitForIn) {
            classesToLoad = classesToLoadIn;
            classesToWaitFor = classesToWaitForIn;
        }

        /**
         * Load a class.  Files we can load take preference over ones the system
         * can load.
         */
        private byte[] getClassData(final String className) {
            boolean shouldLoad = false;
            for (int i = classesToLoad.length-1; i >= 0; --i) {
                if (className.equals(classesToLoad[i])) {
                    shouldLoad = true;
                    break;
                }
            }

            if (shouldLoad) {
                final String name = CLASS_PREFIX+className+CLASS_SUFFIX;
                try {
                    final InputStream fi = this.getClass().getClassLoader().getResourceAsStream(name);
                    final byte[] result = new byte[fi.available()];
                    fi.read(result);
                    return result;
                } catch (Exception e) {
                    logln("Error loading test class: "+name);
                    logln(e.toString());
                    return null;
                }
            } else {
                return null;
            }
        }

        /**
         * Load a class.  Files we can load take preference over ones the system
         * can load.
         */
        public Class loadClass(final String className, final boolean resolveIt)
                throws ClassNotFoundException {
            Class result;
            synchronized (this) {
                logln(">>"+threadName()+">load "+className);
                loadedClasses.addElement(className);

                result = findLoadedClass(className);
                if (result == null) {
                    final byte[] classData = getClassData(className);
                    if (classData == null) {
                        //we don't have a local copy of this one
                        logln("Loading system class: "+className);
                        result = loadFromSystem(className);
                    } else {
                        result = defineClass(classData, 0, classData.length);
                        if (result == null) {
                            //there was an error defining the class
                            result = loadFromSystem(className);
                        }
                    }
                    if ((result != null) && resolveIt) {
                        resolveClass(result);
                    }
                }
            }
            for (int i = classesToWaitFor.length-1; i >= 0; --i) {
                if (className.equals(classesToWaitFor[i])) {
                    rendezvous();
                    break;
                }
            }
            logln("<<"+threadName()+"<load "+className);
            return result;
        }

        /**
         * Delegate loading to the system loader
         */
        private Class loadFromSystem(String className) throws ClassNotFoundException {
            return super.findSystemClass(className);
        }

        public void logClasses(String title) {
            logln(title);
            for (int i = 0; i < loadedClasses.size(); i++) {
                logln("    "+loadedClasses.elementAt(i));
            }
            logln("");
        }

        public int notifyCount = 0;
        public int waitForNotify(int count) {
            return waitForNotify(count, 0);
        }
        public synchronized int waitForNotify(int count, long time) {
            logln(">>"+threadName()+">waitForNotify");
            if (count > notifyCount) {
                try {
                    wait(time);
                } catch (InterruptedException e) {
                }
            } else {
                logln("  count("+count+") > notifyCount("+notifyCount+")");
            }
            logln("<<"+threadName()+"<waitForNotify");
            return notifyCount;
        }
        private synchronized void notifyEveryone() {
            logln(">>"+threadName()+">notifyEveryone");
            notifyCount++;
            notifyAll();
            logln("<<"+threadName()+"<notifyEveryone");
        }
        private void rendezvous() {
            final Thread current = Thread.currentThread();
            if (current instanceof ConcurrentLoadingThread) {
                ((ConcurrentLoadingThread)current).waitUntilPinged();
            }
        }
    }

    private static String threadName() {
        return threadName(Thread.currentThread());
    }

    private static String threadName(Thread t) {
        String temp = t.toString();
        int ndx = temp.indexOf("Thread[");
        temp = temp.substring(ndx + "Thread[".length());
        ndx = temp.indexOf(',');
        temp = temp.substring(0, ndx);
        return temp;
    }

    /** Fill memory to force all SoftReferences to be GCed */
    private void causeResourceBundleCacheFlush() {
        logln("Filling memory...");
        int allocationSize = 1024;
        Vector memoryHog = new Vector();
        try {
            while (true) {
                memoryHog.addElement(new byte[allocationSize]);
                allocationSize *= 2;
            }
        } catch (Throwable e) {
            logln("Caught "+e+" filling memory");
        } finally{
            memoryHog = null;
            System.gc();
        }
        logln("last allocation size: " + allocationSize);
    }

    /**
     *  NOTE: this problem is not externally testable and can only be
     *  verified through code inspection unless special code to force
     *  a task switch is inserted into ResourceBundle.
     *  The class Bug4168625Resource_sp exists.  It's parent bundle
     *  (Bug4168625Resource) contains a resource string with the tag
     *  "language" but Bug4168625Resource_sp does not.
     *  Assume two threads are executing, ThreadA and ThreadB and they both
     *  load a resource Bug4168625Resource with from sp locale.
     *  ResourceBundle.getBundle adds a bundle to the bundle cache (in
     *  findBundle) before it sets the bundle's parent (in getBundle after
     *  returning from findBundle).
     *  <P>
     *  <pre>
     *  ThreadA.getBundle("Bug4168625Resource", new Locale("sp"));
     *      A-->load Bug4168625Resource_sp
     *      A-->find cached Bug4168625Resource
     *      A-->cache Bug4168625Resource_sp as Bug4168625Resource_sp
     *  ThreadB.getBundle("Bug4168625Resource", new Locale("sp"));
     *      B-->find cached Bug4168625Resource_sp
     *      B-->return Bug4168625Resource_sp
     *  ThreadB.bundle.getString("language");
     *      B-->try to find "language" in Bug4168625Resource_sp
     *      B-->Bug4168625Resource_sp does not have a parent, so return null;
     *  ThreadB.System.out.println("Some unknown country");
     *      A-->set parent of Bug4168625Resource_sp to Bug4168625Resource
     *      A-->return Bug4168625Resource_sp (the same bundle ThreadB got)
     *  ThreadA.bundle.getString("language");
     *      A-->try to find "language" in Bug4168625Resource_sp
     *      A-->try to find "language" in Bug4168625Resource (parent of Bug4168625Resource_sp)
     *      A-->return the string
     *  ThreadA.System.out.println("Langauge = "+country);
     *  ThreadB.bundle.getString("language");
     *      B-->try to find "language" in Bug4168625Resource_sp
     *      B-->try to find "language" in Bug4168625Resource (parent of Bug4168625Resource_sp)
     *      B-->return the string
     *  ThreadB.System.out.println("Langauge = "+country);
     *  </pre>
     *  <P>
     *  Note that the first call to getString() by ThreadB returns null, but the second
     *  returns a value.  Thus to ThreadB, the bundle appears to change.  ThreadA gets
     *  the expected results right away.
     */
}
