public static String getLocalizedString(String key, Locale locale, List arguments,
            ResourceBundle bundle)
    {
        if (key == null) {
            throw new NullPointerException("Key cannot be null");
        }
        if (locale == null) {
            locale = JiveGlobals.getLocale();
        }

        String value = getDefaultLocalizedString(key);

        // See if the bundle has a value
        try {
            // The jdk caches resource bundles on its own, so we won't bother.
            value = bundle.getString(key);
            // perform argument substitutions
            if (arguments != null) {
                MessageFormat messageFormat = new MessageFormat("");
                messageFormat.setLocale(bundle.getLocale());
                messageFormat.applyPattern(value);
                try {
                    // This isn't fool-proof, but it's better than nothing
                    // The idea is to try and convert strings into the
                    // types of objects that the formatters expects
                    // i.e. Numbers and Dates
                    Format[] formats = messageFormat.getFormats();
                    for (int i = 0; i < formats.length; i++) {
                        Format format = formats[i];
                        if (format != null) {
                            if (format instanceof DateFormat) {
                                if (arguments.size() > i) {
                                    Object val = arguments.get(i);
                                    if (val instanceof String) {
                                        DateFormat dateFmt = (DateFormat)format;
                                        try {
                                            val = dateFmt.parse((String)val);
                                            arguments.set(i, val);
                                        }
                                        catch (ParseException e) {
                                            Log.error(e.getMessage(), e);
                                        }
                                    }
                                }
                            }
                            else if (format instanceof NumberFormat) {
                                if (arguments.size() > i) {
                                    Object val = arguments.get(i);
                                    if (val instanceof String) {
                                        NumberFormat nbrFmt = (NumberFormat)format;
                                        try {
                                            val = nbrFmt.parse((String)val);
                                            arguments.set(i, val);
                                        }
                                        catch (ParseException e) {
                                            Log.error(e.getMessage(), e);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    value = messageFormat.format(arguments.toArray());
                }
                catch (IllegalArgumentException e) {
                    Log.error("Unable to format resource string for key: "
                            + key + ", argument type not supported");
                }
            }
        }
        catch (java.util.MissingResourceException mre) {
            Log.warn("Missing resource for key: " + key
                    + " in locale " + locale.toString());
        }

        return value;
    }
Returns an internationalized string loaded from a resource bundle using
the passed in Locale substituting the passed in arguments. Substitution
is handled using the {@link MessageFormat} class.

@param key the key to use for retrieving the string from the
     appropriate resource bundle.
@param locale the locale to use for retrieving the appropriate
     locale-specific string.
@param arguments a list of objects to use which are formatted, then
     inserted into the pattern at the appropriate places.
@param bundle The resource bundle from which to return the localized
     string.
@return the localized string.
xmppserver/src/main/java/org/jivesoftware/util/LocaleUtils.java