/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sis.util.iso;

import java.util.Map;
import java.util.HashMap;
import java.util.SortedMap;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import java.util.IllformedLocaleException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import org.opengis.annotation.UML;
import org.opengis.util.CodeList;
import org.opengis.util.InternationalString;
import org.opengis.util.ControlledVocabulary;
import org.apache.sis.util.Static;
import org.apache.sis.util.Locales;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.collection.BackingStoreException;
import org.apache.sis.internal.system.Loggers;

// Branch-dependent imports
import org.apache.sis.internal.jdk8.JDK8;


/**
 * Static methods working on GeoAPI types and {@link CodeList} values.
 * This class provides:
 *
 * <ul>
 *   <li>Methods for fetching the ISO name or description of a code list:<ul>
 *     <li>{@link #getStandardName(Class)}            for ISO name</li>
 *     <li>{@link #getListName(ControlledVocabulary)} for ISO name</li>
 *     <li>{@link #getDescription(Class)}             for a description</li>
 *   </ul></li>
 *   <li>Methods for fetching the ISO name or description of a code value:<ul>
 *     <li>{@link #getCodeName(ControlledVocabulary)}    for ISO name,</li>
 *     <li>{@link #getCodeTitle(ControlledVocabulary)}   for a label or title</li>
 *     <li>{@link #getDescription(ControlledVocabulary)} for a more verbose description</li>
 *   </ul></li>
 *   <li>Methods for fetching an instance from a name (converse of above {@code get} methods):<ul>
 *     <li>{@link #forCodeName(Class, String, boolean)}</li>
 *     <li>{@link #forEnumName(Class, String)}</li>
 *   </ul></li>
 * </ul>
 *
 * <div class="section">Substituting a free text by a code list</div>
 * The ISO standard allows to substitute some character strings in the <cite>"free text"</cite> domain
 * by a {@link CodeList} value.
 *
 * <div class="note"><b>Example:</b>
 * in the following XML fragment, the {@code <gmi:type>} value is normally a {@code <gco:CharacterString>}
 * but has been replaced by a {@code SensorType} code below:
 *
 * {@preformat xml
 *   <gmi:MI_Instrument>
 *     <gmi:type>
 *       <gmi:MI_SensorTypeCode
 *           codeList="http://navigator.eumetsat.int/metadata_schema/eum/resources/Codelist/eum_gmxCodelists.xml#CI_SensorTypeCode"
 *           codeListValue="RADIOMETER">Radiometer</gmi:MI_SensorTypeCode>
 *     </gmi:type>
 *   </gmi:MI_Instrument>
 * }
 * </div>
 *
 * Such substitution can be done with:
 *
 * <ul>
 *   <li>{@link #getCodeTitle(ControlledVocabulary)} for getting the {@link InternationalString} instance
 *       to store in a metadata property.</li>
 *   <li>{@link #forCodeTitle(CharSequence)} for retrieving the {@link CodeList} previously stored as an
 *       {@code InternationalString}.</li>
 * </ul>
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @since   0.3
 * @version 0.7
 * @module
 */
public final class Types extends Static {
    /**
     * The separator character between class name and attribute name in resource files.
     */
    private static final char SEPARATOR = '.';

    /**
     * The types for ISO 19115 UML identifiers. The keys are UML identifiers. Values
     * are either class names as {@link String} objects, or the {@link Class} instances.
     * This map will be built only when first needed.
     *
     * @see #forStandardName(String)
     */
    private static Map<Object,Object> typeForNames;

    /**
     * Do not allow instantiation of this class.
     */
    private Types() {
    }

    /**
     * Returns the ISO name for the given class, or {@code null} if none.
     * This method can be used for GeoAPI interfaces or {@link CodeList}.
     *
     * <div class="note"><b>Examples:</b>
     * <ul>
     *   <li><code>getStandardName({@linkplain org.opengis.metadata.citation.Citation}.class)</code>
     *       (an interface) returns {@code "CI_Citation"}.</li>
     *   <li><code>getStandardName({@linkplain org.opengis.referencing.cs.AxisDirection}.class)</code>
     *       (a code list) returns {@code "CS_AxisDirection"}.</li>
     * </ul>
     * </div>
     *
     * This method looks for the {@link UML} annotation on the given type. It does not search for
     * parent classes or interfaces if the given type is not directly annotated (i.e. {@code @UML}
     * annotations are not inherited). If no annotation is found, then this method does not fallback
     * on the Java name since, as the name implies, this method is about standard names.
     *
     * @param  type The GeoAPI interface or code list from which to get the ISO name, or {@code null}.
     * @return The ISO name for the given type, or {@code null} if none or if the given type is {@code null}.
     *
     * @see #forStandardName(String)
     */
    public static String getStandardName(final Class<?> type) {
        if (type != null) {
            final UML uml = type.getAnnotation(UML.class);
            if (uml != null) {
                final String id = uml.identifier();
                if (id != null && !id.isEmpty()) {
                    /*
                     * Workaround: I though that annotation strings were interned like any other constants,
                     * but it does not seem to be the case as of JDK7.  To verify if this explicit call to
                     * String.intern() is still needed in a future JDK release, see the workaround comment
                     * in the org.apache.sis.metadata.PropertyAccessor.name(…) method.
                     */
                    return id.intern();
                }
            }
        }
        return null;
    }

    /**
     * Returns the ISO classname (if available) or the Java classname (as a fallback) of the given
     * enumeration or code list value. This method uses the {@link UML} annotation if it exists, or
     * fallback on the {@linkplain Class#getSimpleName() simple class name} otherwise.
     *
     * <div class="note"><b>Examples:</b>
     * <ul>
     *   <li>{@code getListName(ParameterDirection.IN_OUT)}      returns {@code "SV_ParameterDirection"}.</li>
     *   <li>{@code getListName(AxisDirection.NORTH)}            returns {@code "CS_AxisDirection"}.</li>
     *   <li>{@code getListName(CharacterSet.UTF_8)}             returns {@code "MD_CharacterSetCode"}.</li>
     *   <li>{@code getListName(ImagingCondition.BLURRED_IMAGE)} returns {@code "MD_ImagingConditionCode"}.</li>
     * </ul>
     * </div>
     *
     * @param  code The code for which to get the class name, or {@code null}.
     * @return The ISO (preferred) or Java (fallback) class name, or {@code null} if the given code is null.
     */
    public static String getListName(final ControlledVocabulary code) {
        if (code == null) {
            return null;
        }
        final Class<?> type = (code instanceof Enum<?>) ? ((Enum<?>) code).getDeclaringClass() : code.getClass();
        final String id = getStandardName(type);
        return (id != null) ? id : type.getSimpleName();
    }

    /**
     * Returns the ISO name (if available) or the Java name (as a fallback) of the given enumeration or code list
     * value. If the value has no {@link UML} identifier, then the programmatic name is used as a fallback.
     *
     * <div class="note"><b>Examples:</b>
     * <ul>
     *   <li>{@code getCodeName(ParameterDirection.IN_OUT)}      returns {@code "in/out"}.</li>
     *   <li>{@code getCodeName(AxisDirection.NORTH)}            returns {@code "north"}.</li>
     *   <li>{@code getCodeName(CharacterSet.UTF_8)}             returns {@code "utf8"}.</li>
     *   <li>{@code getCodeName(ImagingCondition.BLURRED_IMAGE)} returns {@code "blurredImage"}.</li>
     * </ul>
     * </div>
     *
     * @param  code The code for which to get the name, or {@code null}.
     * @return The UML identifiers or programmatic name for the given code,
     *         or {@code null} if the given code is null.
     *
     * @see #getCodeLabel(ControlledVocabulary)
     * @see #getCodeTitle(ControlledVocabulary)
     * @see #getDescription(ControlledVocabulary)
     * @see #forCodeName(Class, String, boolean)
     */
    public static String getCodeName(final ControlledVocabulary code) {
        if (code == null) {
            return null;
        }
        final String id = code.identifier();
        return (id != null && !id.isEmpty()) ? id : code.name();
    }

    /**
     * Returns a unlocalized title for the given enumeration or code list value.
     * This method builds a title using heuristics rules, which should give reasonable
     * results without the need of resource bundles. For better results, consider using
     * {@link #getCodeTitle(ControlledVocabulary)} instead.
     *
     * <p>The current heuristic implementation iterates over {@linkplain CodeList#names() all code names},
     * selects the longest one excluding the {@linkplain CodeList#name() field name} if possible, then
     * {@linkplain CharSequences#camelCaseToSentence(CharSequence) makes a sentence} from that name.</p>
     *
     * <div class="note"><b>Examples:</b>
     * <ul>
     *   <li>{@code getCodeLabel(AxisDirection.NORTH)} returns {@code "North"}.</li>
     *   <li>{@code getCodeLabel(CharacterSet.UTF_8)} returns {@code "UTF-8"}.</li>
     *   <li>{@code getCodeLabel(ImagingCondition.BLURRED_IMAGE)} returns {@code "Blurred image"}.</li>
     * </ul>
     * </div>
     *
     * @param  code The code from which to get a title, or {@code null}.
     * @return A unlocalized title for the given code, or {@code null} if the given code is null.
     *
     * @see #getCodeName(ControlledVocabulary)
     * @see #getCodeTitle(ControlledVocabulary)
     * @see #getDescription(ControlledVocabulary)
     */
    public static String getCodeLabel(final ControlledVocabulary code) {
        if (code == null) {
            return null;
        }
        String id = code.identifier();
        final String name = code.name();
        if (id == null) {
            id = name;
        }
        for (final String candidate : code.names()) {
            if (!candidate.equals(name) && candidate.length() >= id.length()) {
                id = candidate;
            }
        }
        return CharSequences.camelCaseToSentence(id).toString();
    }

    /**
     * Returns the title of the given enumeration or code list value. Title are usually much shorter than descriptions.
     * English titles are often the same than the {@linkplain #getCodeLabel(ControlledVocabulary) code labels}.
     *
     * <p>The code or enumeration value given in argument to this method can be retrieved from the returned title
     * with the {@link #forCodeTitle(CharSequence)} method. See <cite>Substituting a free text by a code list</cite>
     * in this class javadoc for more information.</p>
     *
     * @param  code The code for which to get the title, or {@code null}.
     * @return The title, or {@code null} if the given code is null.
     *
     * @see #getDescription(ControlledVocabulary)
     * @see #forCodeTitle(CharSequence)
     */
    public static InternationalString getCodeTitle(final ControlledVocabulary code) {
        return (code != null) ? new CodeTitle(code) : null;
    }

    /**
     * Returns the description of the given enumeration or code list value, or {@code null} if none.
     * For a description of the code list as a whole instead than a particular code,
     * see {@link Types#getDescription(Class)}.
     *
     * @param  code The code for which to get the localized description, or {@code null}.
     * @return The description, or {@code null} if none or if the given code is null.
     *
     * @see #getCodeTitle(ControlledVocabulary)
     * @see #getDescription(Class)
     */
    public static InternationalString getDescription(final ControlledVocabulary code) {
        if (code != null) {
            final String resources = getResources(code.getClass().getName());
            if (resources != null) {
                return new Description(resources, Description.resourceKey(code));
            }
        }
        return null;
    }

    /**
     * Returns a description for the given class, or {@code null} if none.
     * This method can be used for GeoAPI interfaces or {@link CodeList}.
     *
     * @param  type The GeoAPI interface or code list from which to get the description, or {@code null}.
     * @return The description, or {@code null} if none or if the given type is {@code null}.
     *
     * @see #getDescription(ControlledVocabulary)
     */
    public static InternationalString getDescription(final Class<?> type) {
        final String name = getStandardName(type);
        if (name != null) {
            final String resources = getResources(type.getName());
            if (resources != null) {
                return new Description(resources, name);
            }
        }
        return null;
    }

    /**
     * Returns a description for the given property, or {@code null} if none.
     * The given type shall be a GeoAPI interface, and the given property shall
     * be a UML identifier. If any of the input argument is {@code null}, then
     * this method returns {@code null}.
     *
     * @param  type     The GeoAPI interface from which to get the description of a property, or {@code null}.
     * @param  property The ISO name of the property for which to get the description, or {@code null}.
     * @return The description, or {@code null} if none or if the given type or property name is {@code null}.
     */
    public static InternationalString getDescription(final Class<?> type, final String property) {
        if (property != null) {
            final String name = getStandardName(type);
            if (name != null) {
                final String resources = getResources(type.getName());
                if (resources != null) {
                    return new Description(resources, name + SEPARATOR + property);
                }
            }
        }
        return null;
    }

    /**
     * The {@link InternationalString} returned by the {@code Types.getDescription(…)} methods.
     *
     * @author  Martin Desruisseaux (Geomatys)
     * @since   0.3
     * @version 0.3
     * @module
     */
    private static class Description extends ResourceInternationalString {
        /**
         * For cross-version compatibility.
         */
        private static final long serialVersionUID = -6202647167398898834L;

        /**
         * The class loader to use for fetching GeoAPI resources.
         * Since the resources are bundled in the GeoAPI JAR file,
         * we use the instance that loaded GeoAPI for more determinist behavior.
         */
        private static final ClassLoader CLASSLOADER = UML.class.getClassLoader();

        /**
         * Creates a new international string from the specified resource bundle and key.
         *
         * @param resources The name of the resource bundle, as a fully qualified class name.
         * @param key       The key for the resource to fetch.
         */
        Description(final String resources, final String key) {
            super(resources, key);
        }

        /**
         * Loads the resources using the class loader used for loading GeoAPI interfaces.
         */
        @Override
        protected final ResourceBundle getBundle(final Locale locale) {
            return ResourceBundle.getBundle(resources, locale, CLASSLOADER);
        }

        /**
         * Returns the description for the given locale, or fallback on a default description
         * if no resources exist for that locale.
         */
        @Override
        public final String toString(final Locale locale) {
            try {
                return super.toString(locale);
            } catch (MissingResourceException e) {
                Logging.recoverableException(Logging.getLogger(Loggers.LOCALIZATION), ResourceInternationalString.class, "toString", e);
                return fallback();
            }
        }

        /**
         * Returns a fallback if no resource is found.
         */
        String fallback() {
            return CharSequences.camelCaseToSentence(key.substring(key.lastIndexOf(SEPARATOR) + 1)).toString();
        }

        /**
         * Returns the resource key for the given code list.
         */
        static String resourceKey(final ControlledVocabulary code) {
            String key = getCodeName(code);
            if (key.indexOf(SEPARATOR) < 0) {
                key = getListName(code) + SEPARATOR + key;
            }
            return key;
        }
    }

    /**
     * The {@link InternationalString} returned by the {@code Types.getCodeTitle(…)} method.
     * The code below is a duplicated - in a different way - of {@code CodeListUID(CodeList)}
     * constructor ({@link org.apache.sis.internal.jaxb.code package}). This duplication exists
     * because {@code CodeListUID} constructor stores more information in an opportunist way.
     * If this method is updated, please update {@code CodeListUID(CodeList)} accordingly.
     *
     * @author  Martin Desruisseaux (Geomatys)
     * @since   0.3
     * @version 0.3
     * @module
     */
    private static final class CodeTitle extends Description {
        /**
         * For cross-version compatibility.
         */
        private static final long serialVersionUID = 3306532357801489365L;

        /**
         * The code list for which to create a title.
         */
        final ControlledVocabulary code;

        /**
         * Creates a new international string for the given code list element.
         *
         * @param code The code list for which to create a title.
         */
        CodeTitle(final ControlledVocabulary code) {
            super("org.opengis.metadata.CodeLists", resourceKey(code));
            this.code = code;
        }

        /**
         * Returns a fallback if no resource is found.
         */
        @Override
        String fallback() {
            return getCodeLabel(code);
        }
    }

    /**
     * Returns the resource name for the given GeoAPI type, or {@code null} if none.
     *
     * @param  classname The fully qualified name of the GeoAPI type.
     * @return The resource bundle to load, or {@code null} if none.
     */
    static String getResources(final String classname) {
        String resources = "org.opengis.metadata.Descriptions";
        if (classname.regionMatches(0, resources, 0, 21)) { // 21 is the location after the last dot.
            return resources;
        }
        // Add more checks here (maybe in a loop) if there is more resource candidates.
        return null;
    }

    /**
     * Returns all known values for the given type of code list or enumeration.
     * Note that the size of the returned array may growth between different invocations of this method,
     * since users can add their own codes to an existing list.
     *
     * <div class="note"><b>Note:</b>
     * This method works with both {@link Enum} and {@link CodeList}. However if the type is known to be an
     * {@code Enum}, then the standard {@link Class#getEnumConstants()} method is more efficient.</div>
     *
     * @param <T> The compile-time type given as the {@code codeType} parameter.
     * @param codeType The type of code list or enumeration.
     * @return The list of values for the given code list or enumeration, or an empty array if none.
     *
     * @see Class#getEnumConstants()
     */
    @SuppressWarnings("unchecked")
    public static <T extends ControlledVocabulary> T[] getCodeValues(final Class<T> codeType) {
        Object values;
        try {
            values = codeType.getMethod("values", (Class<?>[]) null).invoke(null, (Object[]) null);
        } catch (InvocationTargetException e) {
            final Throwable cause = e.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            }
            if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new UndeclaredThrowableException(cause);
        } catch (NoSuchMethodException | IllegalAccessException e) {
            values = Array.newInstance(codeType, 0);
        }
        return (T[]) values;
    }

    /**
     * Returns the GeoAPI interface for the given ISO name, or {@code null} if none.
     * The identifier argument shall be the value documented in the {@link UML#identifier()}
     * annotation associated with the GeoAPI interface.
     *
     * <div class="note"><b>Examples:</b>
     * <ul>
     *   <li>{@code forStandardName("CI_Citation")}      returns <code>{@linkplain org.opengis.metadata.citation.Citation}.class</code></li>
     *   <li>{@code forStandardName("CS_AxisDirection")} returns <code>{@linkplain org.opengis.referencing.cs.AxisDirection}.class</code></li>
     * </ul>
     * </div>
     *
     * Only identifiers for the stable part of GeoAPI are recognized. This method does not handle
     * the identifiers for the {@code geoapi-pending} module.
     *
     * @param  identifier The ISO {@linkplain UML} identifier, or {@code null}.
     * @return The GeoAPI interface, or {@code null} if the given identifier is {@code null} or unknown.
     */
    public static synchronized Class<?> forStandardName(final String identifier) {
        if (identifier == null) {
            return null;
        }
        if (typeForNames == null) {
            final Class<UML> c = UML.class;
            final InputStream in = c.getResourceAsStream("class-index.properties");
            if (in == null) {
                throw new MissingResourceException("class-index.properties", c.getName(), identifier);
            }
            final Properties props = new Properties();
            try {
                props.load(in);
                in.close();
            } catch (IOException | IllegalArgumentException e) {
                throw new BackingStoreException(e);
            }
            typeForNames = new HashMap<>(props);
            JDK8.putIfAbsent(typeForNames, "MI_SensorTypeCode", "org.apache.sis.internal.metadata.SensorType");
        }
        final Object value = typeForNames.get(identifier);
        if (value == null || value instanceof Class<?>) {
            return (Class<?>) value;
        }
        final Class<?> type;
        try {
            type = Class.forName((String) value);
        } catch (ClassNotFoundException e) {
            throw new TypeNotPresentException((String) value, e);
        }
        typeForNames.put(identifier, type);
        return type;
    }

    /**
     * Returns the enumeration value of the given type that matches the given name, or {@code null} if none.
     * This method is similar to the standard {@code Enum.valueOf(…)} method, except that this method is more
     * tolerant on string comparisons:
     *
     * <ul>
     *   <li>Name comparisons are case-insensitive.</li>
     *   <li>Only {@linkplain Character#isLetterOrDigit(int) letter and digit} characters are compared.
     *       Spaces and punctuation characters like {@code '_'} and {@code '-'} are ignored.</li>
     * </ul>
     *
     * If there is no match, this method returns {@code null} — it does not thrown an exception,
     * unless the given class is not an enumeration.
     *
     * @param <T>      The compile-time type given as the {@code enumType} parameter.
     * @param enumType The type of enumeration.
     * @param name     The name of the enumeration value to obtain, or {@code null}.
     * @return A value matching the given name, or {@code null} if the name is null
     *         or if no matching enumeration is found.
     *
     * @see Enum#valueOf(Class, String)
     *
     * @since 0.5
     */
    public static <T extends Enum<T>> T forEnumName(final Class<T> enumType, String name) {
        name = CharSequences.trimWhitespaces(name);
        if (name != null && !name.isEmpty()) try {
            return Enum.valueOf(enumType, name);
        } catch (IllegalArgumentException e) {
            final T[] values = enumType.getEnumConstants();
            if (values == null) {
                throw e;
            }
            if (values instanceof ControlledVocabulary[]) {
                for (final ControlledVocabulary code : (ControlledVocabulary[]) values) {
                    for (final String candidate : code.names()) {
                        if (CodeListFilter.accept(candidate, name)) {
                            return enumType.cast(code);
                        }
                    }
                }
            } else {
                for (final Enum<?> code : values) {
                    if (CodeListFilter.accept(code.name(), name)) {
                        return enumType.cast(code);
                    }
                }
            }
        }
        return null;
    }

    /**
     * Returns the code of the given type that matches the given name, or optionally returns a new one if none
     * match the name. This method performs the same work than the GeoAPI {@code CodeList.valueOf(…)} method,
     * except that this method is more tolerant on string comparisons when looking for an existing code:
     *
     * <ul>
     *   <li>Name comparisons are case-insensitive.</li>
     *   <li>Only {@linkplain Character#isLetterOrDigit(int) letter and digit} characters are compared.
     *       Spaces and punctuation characters like {@code '_'} and {@code '-'} are ignored.</li>
     * </ul>
     *
     * If no match is found, then a new code is created only if the {@code canCreate} argument is {@code true}.
     * Otherwise this method returns {@code null}.
     *
     * @param <T>        The compile-time type given as the {@code codeType} parameter.
     * @param codeType   The type of code list.
     * @param name       The name of the code to obtain, or {@code null}.
     * @param canCreate  {@code true} if this method is allowed to create new code.
     * @return A code matching the given name, or {@code null} if the name is null
     *         or if no matching code is found and {@code canCreate} is {@code false}.
     *
     * @see #getCodeName(ControlledVocabulary)
     * @see CodeList#valueOf(Class, String)
     */
    public static <T extends CodeList<T>> T forCodeName(final Class<T> codeType, String name, final boolean canCreate) {
        name = CharSequences.trimWhitespaces(name);
        if (name == null || name.isEmpty()) {
            return null;
        }
        return CodeList.valueOf(codeType, new CodeListFilter(name, canCreate));
    }

    /**
     * Returns the code list or enumeration value for the given title, or {@code null} if none.
     * The current implementation performs the following choice:
     *
     * <ul>
     *   <li>If the given title is a value returned by a previous call to {@link #getCodeTitle(ControlledVocabulary)},
     *       returns the code or enumeration value used for creating that title.</li>
     *   <li>Otherwise returns {@code null}.</li>
     * </ul>
     *
     * @param  title The title for which to get a code or enumeration value, or {@code null}.
     * @return The code or enumeration value associated with the given title, or {@code null}.
     *
     * @since 0.7
     *
     * @see #getCodeTitle(ControlledVocabulary)
     */
    public static ControlledVocabulary forCodeTitle(final CharSequence title) {
        return (title instanceof CodeTitle) ? ((CodeTitle) title).code : null;
    }

    /**
     * Returns an international string for the values in the given properties map, or {@code null} if none.
     * This method is used when a property in a {@link java.util.Map} may have many localized variants.
     * For example the given map may contains a {@code "remarks"} property defined by values associated to
     * the {@code "remarks_en"} and {@code "remarks_fr"} keys, for English and French locales respectively.
     *
     * <p>If the given map is {@code null}, then this method returns {@code null}.
     * Otherwise this method iterates over the entries having a key that starts with the specified prefix,
     * followed by the {@code '_'} character. For each such key:</p>
     *
     * <ul>
     *   <li>If the key is exactly equals to {@code prefix}, selects {@link Locale#ROOT}.</li>
     *   <li>Otherwise the characters after {@code '_'} are parsed as an ISO language and country code
     *       by the {@link Locales#parse(String, int)} method. Note that 3-letters codes are replaced
     *       by their 2-letters counterparts on a <cite>best effort</cite> basis.</li>
     *   <li>The value for the decoded locale is added in the international string to be returned.</li>
     * </ul>
     *
     * @param  properties The map from which to get the string values for an international string, or {@code null}.
     * @param  prefix     The prefix of keys to use for creating the international string.
     * @return The international string, or {@code null} if the given map is null or does not contain values
     *         associated to keys starting with the given prefix.
     * @throws IllegalArgumentException If a key starts by the given prefix and:
     *         <ul>
     *           <li>The key suffix is an illegal {@link Locale} code,</li>
     *           <li>or the value associated to that key is a not a {@link CharSequence}.</li>
     *         </ul>
     *
     * @see Locales#parse(String, int)
     * @see DefaultInternationalString#DefaultInternationalString(Map)
     *
     * @since 0.4
     */
    public static InternationalString toInternationalString(Map<String,?> properties, final String prefix)
            throws IllegalArgumentException
    {
        ArgumentChecks.ensureNonEmpty("prefix", prefix);
        if (properties == null) {
            return null;
        }
        /*
         * If the given map is an instance of SortedMap using the natural ordering of keys,
         * we can skip all keys that lexicographically precedes the given prefix.
         */
        boolean isSorted = false;
        if (properties instanceof SortedMap<?,?>) {
            final SortedMap<String,?> sorted = (SortedMap<String,?>) properties;
            if (sorted.comparator() == null) { // We want natural ordering.
                properties = sorted.tailMap(prefix);
                isSorted = true;
            }
        }
        /*
         * Now iterates over the map entry and lazily create the InternationalString
         * only when first needed. In most cases, we have 0 or 1 matching entry.
         */
        CharSequence i18n = null;
        Locale firstLocale = null;
        DefaultInternationalString dis = null;
        final int offset = prefix.length();
        for (final Map.Entry<String,?> entry : properties.entrySet()) {
            final String key = entry.getKey();
            if (key == null) {
                continue; // Tolerance for Map that accept null keys.
            }
            if (!key.startsWith(prefix)) {
                if (isSorted) break; // If the map is sorted, there is no need to check next entries.
                continue;
            }
            final Locale locale;
            if (key.length() == offset) {
                locale = Locale.ROOT;
            } else {
                final char c = key.charAt(offset);
                if (c != '_') {
                    if (isSorted && c > '_') break;
                    continue;
                }
                final int s = offset + 1;
                try {
                    locale = Locales.parse(key, s);
                } catch (IllformedLocaleException e) {
                    throw new IllegalArgumentException(Errors.getResources(properties).getString(
                            Errors.Keys.IllegalLanguageCode_1, '(' + key.substring(0, s) + '）' + key.substring(s), e));
                }
            }
            final Object value = entry.getValue();
            if (value != null) {
                if (!(value instanceof CharSequence)) {
                    throw new IllegalArgumentException(Errors.getResources(properties)
                            .getString(Errors.Keys.IllegalPropertyValueClass_2, key, value.getClass()));
                }
                if (i18n == null) {
                    i18n = (CharSequence) value;
                    firstLocale = locale;
                } else {
                    if (dis == null) {
                        dis = new DefaultInternationalString();
                        dis.add(firstLocale, i18n);
                        i18n = dis;
                    }
                    dis.add(locale, (CharSequence) value);
                }
            }
        }
        return toInternationalString(i18n);
    }

    /**
     * Returns the given characters sequence as an international string. If the given sequence is
     * null or an instance of {@link InternationalString}, then this method returns it unchanged.
     * Otherwise, this method copies the {@link InternationalString#toString()} value in a new
     * {@link SimpleInternationalString} instance and returns it.
     *
     * @param  string The characters sequence to convert, or {@code null}.
     * @return The given sequence as an international string,
     *         or {@code null} if the given sequence was null.
     *
     * @see DefaultNameFactory#createInternationalString(Map)
     */
    public static InternationalString toInternationalString(final CharSequence string) {
        if (string == null || string instanceof InternationalString) {
            return (InternationalString) string;
        }
        return new SimpleInternationalString(string.toString());
    }

    /**
     * Returns the given array of {@code CharSequence}s as an array of {@code InternationalString}s.
     * If the given array is null or an instance of {@code InternationalString[]}, then this method
     * returns it unchanged. Otherwise a new array of type {@code InternationalString[]} is created
     * and every elements from the given array is copied or
     * {@linkplain #toInternationalString(CharSequence) casted} in the new array.
     *
     * <p>If a defensive copy of the {@code strings} array is wanted, then the caller needs to check
     * if the returned array is the same instance than the one given in argument to this method.</p>
     *
     * @param  strings The characters sequences to convert, or {@code null}.
     * @return The given array as an array of type {@code InternationalString[]},
     *         or {@code null} if the given array was null.
     */
    public static InternationalString[] toInternationalStrings(final CharSequence... strings) {
        if (strings == null || strings instanceof InternationalString[]) {
            return (InternationalString[]) strings;
        }
        final InternationalString[] copy = new InternationalString[strings.length];
        for (int i=0; i<strings.length; i++) {
            copy[i] = toInternationalString(strings[i]);
        }
        return copy;
    }
}
