/*
 * 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;

import java.util.Set;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.lang.reflect.Type;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.WildcardType;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Modifier;
import org.opengis.annotation.UML;

import static org.apache.sis.util.collection.Containers.hashMapCapacity;
import static org.apache.sis.internal.system.Modules.INTERNAL_CLASSNAME_PREFIX;


/**
 * Static methods working on {@link Class} objects.
 * This class defines helper methods for working with reflection.
 * Some functionalities are:
 *
 * <ul>
 *   <li>Add or remove dimension to an array type
 *       ({@link #changeArrayDimension(Class, int) changeArrayDimension})</li>
 *   <li>Find the common parent of two or more classes
 *       ({@link #findCommonClass(Class, Class) findCommonClass},
 *        {@link #findCommonInterfaces(Class, Class) findCommonInterfaces})</li>
 *   <li>Getting the bounds of a parameterized field or method
 *       ({@link #boundOfParameterizedProperty(Method) boundOfParameterizedProperty})</li>
 *   <li>Getting a short class name ({@link #getShortName(Class) getShortName},
 *       {@link #getShortClassName(Object) getShortClassName})</li>
 * </ul>
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 1.0
 * @since   0.3
 * @module
 */
public final class Classes extends Static {
    /**
     * An empty array of classes.
     */
    @SuppressWarnings({"unchecked","rawtypes"})
    private static final Class<Object>[] EMPTY_ARRAY = new Class[0];

    /**
     * Methods to be rejected by {@link #isPossibleGetter(Method)}. They are mostly methods inherited
     * from {@link Object}. Only no-argument methods having a non-void return value need to be
     * declared in this list.
     *
     * <p>Note that testing {@code type.getDeclaringClass().equals(Object.class)}
     * is not sufficient because those methods may be overridden in subclasses.</p>
     */
    private static final String[] EXCLUDES = {
        "clone", "getClass", "hashCode", "toString", "toWKT"
    };

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

    /**
     * Changes the array dimension by the given amount. The given class can be a primitive type,
     * a Java object, or an array of the above. If the given {@code change} is positive, then the
     * array dimension will be increased by that amount. For example a change of +1 dimension will
     * change an {@code int} class into {@code int[]}, and a {@code String[]} class into {@code String[][]}.
     * A change of +2 dimensions is like applying two times a change of +1 dimension.
     *
     * <p>The change of dimension can also be negative. For example a change of -1 dimension will
     * change a {@code String[]} class into a {@code String}. More specifically:</p>
     *
     * <ul>
     *   <li>If the given {@code element} is null, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given {@code change} is 0, then the given {@code element} is returned unchanged.</li>
     *   <li>Otherwise if the given {@code change} is negative, then {@link Class#getComponentType()} is invoked
     *       {@code abs(change)} times. The result is a {@code null} value if {@code abs(change)} is greater than
     *       the array dimension.</li>
     *   <li>Otherwise if {@code element} is {@link Void#TYPE}, then this method returns {@code Void.TYPE}
     *       since arrays of {@code void} do not exist.</li>
     *   <li>Otherwise this method returns a class that represents an array of the given class augmented by
     *       the given amount of dimensions.</li>
     * </ul>
     *
     * @param  element  the type of elements in the array.
     * @param  change   the change of dimension, as a negative or positive number.
     * @return the type of an array of the given element type augmented by the given
     *         number of dimensions (which may be negative), or {@code null}.
     */
    public static Class<?> changeArrayDimension(Class<?> element, int change) {
        if (change != 0 && element != null) {
            if (change < 0) {
                do element = element.getComponentType();
                while (element!=null && ++change != 0);
            } else if (element != Void.TYPE) {
                final StringBuilder buffer = new StringBuilder();
                do buffer.insert(0, '[');
                while (--change != 0);
                if (element.isPrimitive()) {
                    buffer.append(Numbers.getInternal(element));
                } else if (element.isArray()) {
                    buffer.append(element.getName());
                } else {
                    buffer.append('L').append(element.getName()).append(';');
                }
                final String name = buffer.toString();
                try {
                    element = Class.forName(name);
                } catch (ClassNotFoundException e) {
                    throw new TypeNotPresentException(name, e);
                    // Should never happen because we are creating an array of an existing class.
                }
            }
        }
        return element;
    }

    /**
     * Returns the upper bounds of the parameterized type of the given property.
     * If the property does not have a parameterized type, returns {@code null}.
     *
     * <p>This method is typically used for fetching the type of elements in a collection.
     * We do not provide a method working from a {@link Class} instance because of the way
     * parameterized types are implemented in Java (by erasure).</p>
     *
     * <b>Examples:</b> When invoking this method for a field of the type below:
     * <ul>
     *   <li>{@code Set<Number>} returns {@code Number.class}.</li>
     *
     *   <li>{@code Set<? extends Number>} returns {@code Number.class} as well, since that
     *       collection can not (in theory) contain instances of super-classes; {@code Number}
     *       is the <cite>upper bound</cite>.</li>
     *
     *   <li>{@code Set<? super Number>} returns {@code Object.class}, because that collection
     *       is allowed to contain such elements.</li>
     *
     *   <li>{@code Set} returns {@code null} because that collection is un-parameterized.</li>
     * </ul>
     *
     * @param  field  the field for which to obtain the parameterized type.
     * @return the upper bound of parameterized type, or {@code null} if the given field
     *         is not of a parameterized type.
     */
    public static Class<?> boundOfParameterizedProperty(final Field field) {
        return getActualTypeArgument(field.getGenericType());
    }

    /**
     * If the given method is a getter or a setter for a parameterized property, returns the
     * upper bounds of the parameterized type. Otherwise returns {@code null}. This method
     * provides the same semantic than {@link #boundOfParameterizedProperty(Field)}, but
     * works on a getter or setter method rather then the field. See the javadoc of above
     * method for more details.
     *
     * <p>This method is typically used for fetching the type of elements in a collection.
     * We do not provide a method working from a {@link Class} instance because of the way
     * parameterized types are implemented in Java (by erasure).</p>
     *
     * @param  method  the getter or setter method for which to obtain the parameterized type.
     * @return the upper bound of parameterized type, or {@code null} if the given method
     *         does not operate on an object of a parameterized type.
     */
    public static Class<?> boundOfParameterizedProperty(final Method method) {
        Class<?> c = getActualTypeArgument(method.getGenericReturnType());
        if (c == null) {
            final Type[] parameters = method.getGenericParameterTypes();
            if (parameters != null && parameters.length == 1) {
                c = getActualTypeArgument(parameters[0]);
            }
        }
        return c;
    }

    /**
     * Delegates to {@link ParameterizedType#getActualTypeArguments()} and returns the result as a
     * {@link Class}, provided that every objects are of the expected classes and the result was
     * an array of length 1 (so there is no ambiguity). Otherwise returns {@code null}.
     */
    private static Class<?> getActualTypeArgument(Type type) {
        if (type instanceof ParameterizedType) {
            Type[] p = ((ParameterizedType) type).getActualTypeArguments();
            while (p != null && p.length == 1) {
                type = p[0];
                if (type instanceof WildcardType) {
                    p = ((WildcardType) type).getUpperBounds();
                    continue;
                }
                /*
                 * At this point we are not going to continue the loop anymore.
                 * Check if we have an array, then check the (component) class.
                 */
                if (type instanceof ParameterizedType) {
                    /*
                     * Example: replace ParameterDescriptor<?> by ParameterDescriptor
                     * before we test if (type instanceof Class<?>).
                     */
                    type = ((ParameterizedType) type).getRawType();
                }
                int dimension = 0;
                while (type instanceof GenericArrayType) {
                    type = ((GenericArrayType) type).getGenericComponentType();
                    dimension++;
                }
                if (type instanceof Class<?>) {
                    return changeArrayDimension((Class<?>) type, dimension);
                }
                break;                                      // Unknown type.
            }
        }
        return null;
    }

    /**
     * Returns the class of the specified object, or {@code null} if {@code object} is null.
     * This method is also useful for fetching the class of an object known only by its bound
     * type. As of Java 6, the usual pattern:
     *
     * {@preformat java
     *     Number n = 0;
     *     Class<? extends Number> c = n.getClass();
     * }
     *
     * doesn't seem to work if {@link Number} is replaced by a parameterized type {@code T}.
     *
     * @param  <T>     the type of the given object.
     * @param  object  the object for which to get the class, or {@code null}.
     * @return the class of the given object, or {@code null} if the given object was null.
     */
    @SuppressWarnings("unchecked")
    @Workaround(library="JDK", version="1.7")
    public static <T> Class<? extends T> getClass(final T object) {
        return (object != null) ? (Class<? extends T>) object.getClass() : null;
    }

    /**
     * Returns the classes of all objects in the given collection. If the given collection
     * contains some null elements, then the returned set will contain a null element as well.
     * The returned set is modifiable and can be freely updated by the caller.
     *
     * <p>Note that interfaces are not included in the returned set.</p>
     *
     * @param  <T>      the base type of elements in the given collection.
     * @param  objects  the collection of objects.
     * @return the set of classes of all objects in the given collection.
     */
    private static <T> Set<Class<? extends T>> getClasses(final Iterable<? extends T> objects) {
        final Set<Class<? extends T>> types = new LinkedHashSet<>();
        for (final T object : objects) {
            types.add(getClass(object));
        }
        return types;
    }

    /**
     * Returns the first type or super-type (including interface) considered "standard" in Apache SIS sense.
     * This method applies the following heuristic rules, in that order:
     *
     * <ul>
     *   <li>If the given type implements at least one interface having the {@link UML} annotation,
     *       then the first annotated interface is returned.</li>
     *   <li>Otherwise the first public class or parent class is returned.</li>
     * </ul>
     *
     * Those heuristic rules may be adjusted in any future Apache SIS version.
     *
     * @param  <T>   the compile-time type argument.
     * @param  type  the type for which to get the standard interface or class. May be {@code null}.
     * @return a standard interface implemented by {@code type}, or otherwise the most specific public class.
     *         Is {@code null} if the given {@code type} argument was null.
     *
     * @since 1.0
     */
    public static <T> Class<? super T> getStandardType(final Class<T> type) {
        for (final Class<? super T> candidate : getAllInterfaces(type)) {
            if (candidate.isAnnotationPresent(UML.class)) {
                return candidate;
            }
        }
        for (Class<? super T> candidate = type; candidate != null; candidate = candidate.getSuperclass()) {
            if (Modifier.isPublic(candidate.getModifiers()) && !candidate.getName().startsWith(INTERNAL_CLASSNAME_PREFIX)) {
                return candidate;
            }
        }
        return type;
    }

    /**
     * Returns every interfaces implemented, directly or indirectly, by the given class or interface.
     * This is similar to {@link Class#getInterfaces()} except that this method searches recursively
     * in the super-interfaces. For example if the given type is {@link java.util.ArrayList}, then
     * the returned set will contain {@link java.util.List} (which is implemented directly)
     * together with its parent interfaces {@link Collection} and {@link Iterable}.
     *
     * @param  <T>   the compile-time type of the {@code Class} argument.
     * @param  type  the class or interface for which to get all implemented interfaces.
     * @return all implemented interfaces (not including the given {@code type} if it was an interface),
     *         or an empty array if none.
     *
     * @see Class#getInterfaces()
     */
    @SuppressWarnings({"unchecked","rawtypes"})                             // Generic array creation.
    public static <T> Class<? super T>[] getAllInterfaces(final Class<T> type) {
        final Set<Class<?>> interfaces = getInterfaceSet(type);
        return (interfaces != null) ? interfaces.toArray(new Class[interfaces.size()]) : EMPTY_ARRAY;
    }

    /**
     * Implementation of {@link #getAllInterfaces(Class)} returning a {@link Set}.
     * The public API exposes the method returning an array instead than a set for
     * the following reasons:
     *
     * <ul>
     *   <li>Consistency with other methods ({@link #getLeafInterfaces(Class, Class)},
     *       {@link Class#getInterfaces()}).</li>
     *   <li>Because arrays in Java are covariant, while the {@code Set} are not.
     *       Consequently callers can cast {@code Class<? super T>[]} to {@code Class<?>[]}
     *       while they can not cast {@code Set<Class<? super T>>} to {@code Set<Class<?>>}.</li>
     * </ul>
     *
     * @param  type  the class or interface for which to get all implemented interfaces.
     * @return all implemented interfaces (not including the given {@code type} if it was an interface),
     *         or {@code null} if none. Callers can freely modify the returned set.
     */
    static Set<Class<?>> getInterfaceSet(Class<?> type) {
        Set<Class<?>> interfaces = null;
        while (type != null) {
            interfaces = getInterfaceSet(type, interfaces);
            type = type.getSuperclass();
        }
        return interfaces;
    }

    /**
     * Adds to the given set every interfaces implemented by the given class or interface.
     *
     * @param  type   the type for which to add the interfaces in the given set.
     * @param  addTo  the set where to add interfaces, or {@code null} if not yet created.
     * @return the given set (may be {@code null}), or a new set if the given set was null
     *         and at least one interface has been found.
     */
    private static Set<Class<?>> getInterfaceSet(final Class<?> type, Set<Class<?>> addTo) {
        final Class<?>[] interfaces = type.getInterfaces();
        for (final Class<?> candidate : interfaces) {
            if (addTo == null) {
                addTo = new LinkedHashSet<>(hashMapCapacity(interfaces.length));
            }
            if (addTo.add(candidate)) {
                getInterfaceSet(candidate, addTo);
            }
        }
        return addTo;
    }

    /**
     * Returns the interfaces implemented by the given class and assignable to the given base
     * interface, or an empty array if none. If more than one interface extends the given base,
     * then the most specialized interfaces are returned. For example if the given class
     * implements both the {@link Set} and {@link Collection} interfaces, then the returned
     * array contains only the {@code Set} interface.
     *
     * <h4>Example</h4>
     * {@code getLeafInterfaces(ArrayList.class, Collection.class)} returns an array of length 1
     * containing {@code List.class}.
     *
     * @param  <T>   the type of the {@code baseInterface} class argument.
     * @param  type  a class for which the implemented interfaces are desired, or {@code null}.
     * @param  baseInterface  the base type of the interfaces to search.
     * @return the leaf interfaces matching the given criterion, or an empty array if none.
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<? extends T>[] getLeafInterfaces(Class<?> type, final Class<T> baseInterface) {
        int count = 0;
        Class<?>[] types = EMPTY_ARRAY;
        while (type != null) {
            final Class<?>[] candidates = type.getInterfaces();
next:       for (final Class<?> candidate : candidates) {
                if (baseInterface == null || baseInterface.isAssignableFrom(candidate)) {
                    /*
                     * At this point, we have an interface to be included in the returned array.
                     * If a more specialized interface existed before 'candidate', forget the
                     * candidate.
                     */
                    for (int i=0; i<count; i++) {
                        final Class<?> old = types[i];
                        if (candidate.isAssignableFrom(old)) {
                            continue next;                      // A more specialized interface already exists.
                        }
                        if (old.isAssignableFrom(candidate)) {
                            types[i] = candidate;               // This interface specializes a previous interface.
                            continue next;
                        }
                    }
                    if (types == EMPTY_ARRAY) {
                        types = candidates;
                    }
                    if (count >= types.length) {
                        types = Arrays.copyOf(types, types.length + candidates.length);
                    }
                    types[count++] = candidate;
                }
            }
            type = type.getSuperclass();
        }
        return (Class[]) ArraysExt.resize(types, count);
    }

    /**
     * Returns the most specific class implemented by the objects in the given collection.
     * If there is more than one specialized class, returns their {@linkplain #findCommonClass
     * most specific common super class}.
     *
     * <p>This method searches for classes only, not interfaces.</p>
     *
     * @param  objects  a collection of objects. May contains duplicated values and null values.
     * @return the most specialized class, or {@code null} if the given collection does not contain
     *         at least one non-null element.
     */
    public static Class<?> findSpecializedClass(final Iterable<?> objects) {
        final Set<Class<?>> types = getClasses(objects);
        types.remove(null);
        /*
         * Removes every classes in the types collection which are assignable from an other
         * class from the same collection. As a result, the collection should contains only
         * leaf classes.
         */
        for (final Iterator<Class<?>> it=types.iterator(); it.hasNext();) {
            final Class<?> candidate = it.next();
            for (final Class<?> type : types) {
                if (candidate != type && candidate.isAssignableFrom(type)) {
                    it.remove();
                    break;
                }
            }
        }
        return common(types);
    }

    /**
     * Returns the most specific class which is a common parent of all the specified classes.
     * This method is not public in order to make sure that it contains only classes, not
     * interfaces, since our implementation is not designed for multi-inheritances.
     *
     * @param  types  the collection where to search for a common parent.
     * @return the common parent, or {@code null} if the given collection is empty.
     */
    private static Class<?> common(final Set<Class<?>> types) {
        final Iterator<Class<?>> it = types.iterator();
        if (!it.hasNext()) {
            return null;
        }
        Class<?> type = it.next();
        while (it.hasNext()) {
            type = findCommonClass(type, it.next());
        }
        return type;
    }

    /**
     * Returns the most specific class which {@linkplain Class#isAssignableFrom is assignable from}
     * the type of all given objects. If no element in the given collection has a type assignable
     * from the type of all other elements, then this method searches for a common
     * {@linkplain Class#getSuperclass super class}.
     *
     * <p>This method searches for classes only, not interfaces.</p>
     *
     * @param  objects  a collection of objects. May contains duplicated values and null values.
     * @return the most specific class common to all supplied objects, or {@code null} if the
     *         given collection does not contain at least one non-null element.
     */
    public static Class<?> findCommonClass(final Iterable<?> objects) {
        final Set<Class<?>> types = getClasses(objects);
        types.remove(null);
        return common(types);
    }

    /**
     * Returns the most specific class which {@linkplain Class#isAssignableFrom is assignable from}
     * the given classes or a parent of those classes. This method returns either {@code c1},
     * {@code c2} or a common parent of {@code c1} and {@code c2}.
     *
     * <p>This method considers classes only, not the interfaces.</p>
     *
     * @param  c1  the first class, or {@code null}.
     * @param  c2  the second class, or {@code null}.
     * @return the most specific class common to the supplied classes, or {@code null}
     *         if both {@code c1} and {@code c2} are null.
     */
    public static Class<?> findCommonClass(Class<?> c1, Class<?> c2) {
        if (c1 == null) return c2;
        if (c2 == null) return c1;
        do {
            if (c1.isAssignableFrom(c2)) {
                return c1;
            }
            if (c2.isAssignableFrom(c1)) {
                return c2;
            }
            c1 = c1.getSuperclass();
            c2 = c2.getSuperclass();
        } while (c1 != null && c2 != null);
        return Object.class;
    }

    /**
     * Returns the interfaces which are implemented by the two given classes. The returned set
     * does not include the parent interfaces. For example if the two given objects implement the
     * {@link Collection} interface, then the returned set will contain the {@code Collection}
     * type but not the {@link Iterable} type, since it is implied by the collection type.
     *
     * @param  c1  the first class.
     * @param  c2  the second class.
     * @return the interfaces common to both classes, or an empty set if none.
     *         Callers can freely modify the returned set.
     */
    public static Set<Class<?>> findCommonInterfaces(final Class<?> c1, final Class<?> c2) {
        final Set<Class<?>> interfaces = getInterfaceSet(c1);
        final Set<Class<?>> buffer     = getInterfaceSet(c2);               // To be recycled.
        if (interfaces == null || buffer == null) {
            return Collections.emptySet();
        }
        interfaces.retainAll(buffer);
        for (Iterator<Class<?>> it=interfaces.iterator(); it.hasNext();) {
            final Class<?> candidate = it.next();
            buffer.clear();     // Safe because the buffer can not be Collections.EMPTY_SET at this point.
            getInterfaceSet(candidate, buffer);
            if (interfaces.removeAll(buffer)) {
                it = interfaces.iterator();
            }
        }
        return interfaces;
    }

    /**
     * Returns {@code true} if the two specified objects implements exactly the same set
     * of interfaces. Only interfaces assignable to {@code baseInterface} are compared.
     * Declaration order doesn't matter.
     *
     * <div class="note"><b>Example:</b>
     * in ISO 19111, different interfaces exist for different coordinate system (CS) geometries
     * ({@code CartesianCS}, {@code PolarCS}, etc.). One can check if two implementations have
     * the same geometry with the following code:
     *
     * {@preformat java
     *     if (implementSameInterfaces(cs1, cs2, CoordinateSystem.class)) {
     *         // The two Coordinate System are of the same kind.
     *     }
     * }
     * </div>
     *
     * @param object1  the first object to check for interfaces.
     * @param object2  the second object to check for interfaces.
     * @param baseInterface  the parent of all interfaces to check.
     * @return {@code true} if both objects implement the same set of interfaces,
     *         considering only sub-interfaces of {@code baseInterface}.
     */
    public static boolean implementSameInterfaces(final Class<?> object1, final Class<?> object2, final Class<?> baseInterface) {
        if (object1 == object2) {
            return true;
        }
        if (object1 == null || object2 == null) {
            return false;
        }
        final Class<?>[] c1 = getLeafInterfaces(object1, baseInterface);
        final Class<?>[] c2 = getLeafInterfaces(object2, baseInterface);
        /*
         * For each interface in the 'c1' array, check if
         * this interface exists also in the 'c2' array.
         */
        int n = c2.length;
cmp:    for (final Class<?> c : c1) {
            for (int j=n; --j>=0;) {
                if (c == c2[j]) {
                    System.arraycopy(c2, j+1, c2, j, --n-j);
                    continue cmp;
                }
            }
            return false;                       // Interface not found in 'c2'.
        }
        return n == 0;                          // If n>0, at least one interface was not found in 'c1'.
    }

    /**
     * Returns the name of the given class without package name, but including the names of enclosing
     * classes if any. This method is similar to the {@link Class#getSimpleName()} method, except that
     * if the given class is an inner class, then the returned value is prefixed with the outer class
     * name. An other difference is that if the given class is local or anonymous, then this method
     * returns the name of the parent class.
     *
     * <p>The following table compares the various kind of names for some examples:</p>
     *
     * <table class="sis">
     *   <caption>Class name comparisons</caption>
     *   <tr>
     *     <th>Class</th>
     *     <th>{@code getName()}</th>
     *     <th>{@code getSimpleName()}</th>
     *     <th>{@code getCanonicalName()}</th>
     *     <th>{@code getShortName()}</th>
     *   </tr>
     *   <tr>
     *     <td>{@link String}</td>
     *     <td>{@code "java.lang.String"}</td>
     *     <td>{@code "String"}</td>
     *     <td>{@code "java.lang.String"}</td>
     *     <td>{@code "String"}</td>
     *   </tr>
     *   <tr>
     *     <td>{@code double[]}</td>
     *     <td>{@code "[D"}</td>
     *     <td>{@code "double[]"}</td>
     *     <td>{@code "double[]"}</td>
     *     <td>{@code "double[]"}</td>
     *   </tr>
     *   <tr>
     *     <td>{@link java.awt.geom.Point2D.Double}</td>
     *     <td>{@code "java.awt.geom.Point2D$Double"}</td>
     *     <td>{@code "Double"}</td>
     *     <td>{@code "java.awt.geom.Point2D.Double"}</td>
     *     <td>{@code "Point2D.Double"}</td>
     *   </tr>
     *   <tr>
     *     <td>Anonymous {@link Comparable}</td>
     *     <td>{@code "com.mycompany.myclass$1"}</td>
     *     <td>{@code ""}</td>
     *     <td>{@code null}</td>
     *     <td>{@code "Object"}</td>
     *   </tr>
     * </table>
     *
     * @param  classe  the object class (may be {@code null}).
     * @return the simple name with outer class name (if any) of the first non-anonymous
     *         class in the hierarchy, or {@code "<*>"} if the given class is null.
     *
     * @see #getShortClassName(Object)
     * @see Class#getSimpleName()
     */
    public static String getShortName(Class<?> classe) {
        if (classe == null) {
            return "<*>";
        }
        while (classe.isAnonymousClass()) {
            classe = classe.getSuperclass();
        }
        String name = classe.getSimpleName();
        final Class<?> enclosing = classe.getEnclosingClass();
        if (enclosing != null) {
            name = getShortName(enclosing) + '.' + name;
        }
        return name;
    }

    /**
     * Returns the class name of the given object without package name, but including the enclosing class names
     * if any. Invoking this method is equivalent to invoking {@code getShortName(object.getClass())} except for
     * {@code null} value. See {@link #getShortName(Class)} for more information on the class name returned by
     * this method.
     *
     * @param  object  the object (may be {@code null}).
     * @return the simple class name with outer class name (if any) of the first non-anonymous
     *         class in the hierarchy, or {@code "<*>"} if the given object is null.
     *
     * @see #getShortName(Class)
     */
    public static String getShortClassName(final Object object) {
        return getShortName(getClass(object));
    }

    /**
     * Returns {@code true} if the given type is assignable to one of the given allowed types.
     * More specifically, if at least one {@code allowedTypes[i]} element exists for which
     * <code>allowedTypes[i].{@linkplain Class#isAssignableFrom(Class) isAssignableFrom}(type)</code>
     * returns {@code true}, then this method returns {@code true}.
     *
     * <p>Special cases:</p>
     * <ul>
     *   <li>If {@code type} is null, then this method returns {@code false}.</li>
     *   <li>If {@code allowedTypes} is null, then this method returns {@code true}.
     *       This is to be interpreted as "no restriction on the allowed types".</li>
     *   <li>Any null element in the {@code allowedTypes} array are silently ignored.</li>
     * </ul>
     *
     * @param  type  the type to be tested, or {@code null}.
     * @param  allowedTypes  the allowed types.
     * @return {@code true} if the given type is assignable to one of the allowed types.
     */
    public static boolean isAssignableToAny(final Class<?> type, final Class<?>... allowedTypes) {
        if (type != null) {
            if (allowedTypes == null) {
                return true;
            }
            for (final Class<?> candidate : allowedTypes) {
                if (candidate != null && candidate.isAssignableFrom(type)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Returns {@code true} if the given method may possibly be the getter method for a property.
     * This method implements the algorithm used by SIS in order to identify getter methods in
     * {@linkplain org.opengis.metadata metadata} interfaces. We do not rely on naming convention
     * (method names starting with "{@code get}" or "{@code is}" prefixes) because not every methods
     * follow such convention (e.g. {@link org.opengis.metadata.quality.ConformanceResult#pass()}).
     *
     * <p>The current implementation returns {@code true} if the given method meets all the
     * following conditions. Note that a {@code true} value is not a guaranteed that the given
     * method is really a getter. The caller is encouraged to perform additional checks if
     * possible.</p>
     *
     * <ul>
     *   <li>The method does no expect any argument.</li>
     *   <li>The method returns a value (anything except {@code void}).</li>
     *   <li>The method name is not {@link Object#clone() clone}, {@link Object#getClass() getClass},
     *       {@link Object#hashCode() hashCode}, {@link Object#toString() toString} or
     *       {@link org.opengis.referencing.IdentifiedObject#toWKT() toWKT}.</li>
     *   <li>The method is not {@linkplain Method#isSynthetic() synthetic}.</li>
     * </ul>
     *
     * <p>Those conditions may be updated in any future SIS version.</p>
     *
     * @param  method  the method to inspect.
     * @return {@code true} if the given method may possibly be a non-deprecated getter method.
     */
    public static boolean isPossibleGetter(final Method method) {
        return method.getReturnType() != Void.TYPE &&
               method.getParameterCount() == 0 &&
              !method.isSynthetic() &&
              !ArraysExt.contains(EXCLUDES, method.getName());
    }
}
