001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.internal;
014
015import static org.apache.juneau.internal.ClassFlags.*;
016import static org.apache.juneau.internal.CollectionUtils.*;
017
018import java.io.*;
019import java.lang.annotation.*;
020import java.lang.reflect.*;
021import java.util.*;
022import java.util.concurrent.*;
023
024import org.apache.juneau.*;
025import org.apache.juneau.utils.*;
026
027/**
028 * Class-related utility methods.
029 */
030public final class ClassUtils {
031
032   private static final Map<Class<?>,ConstructorCacheEntry> CONSTRUCTOR_CACHE = new ConcurrentHashMap<>();
033
034   /**
035    * Given the specified list of objects, return readable names for the class types of the objects.
036    *
037    * @param o The objects.
038    * @return An array of readable class type strings.
039    */
040   public static ObjectList getReadableClassNames(Object[] o) {
041      ObjectList l = new ObjectList();
042      for (int i = 0; i < o.length; i++)
043         l.add(o[i] == null ? "null" : getReadableClassName(o[i].getClass()));
044      return l;
045   }
046
047   /**
048    * Shortcut for calling <code><jsm>getReadableClassName</jsm>(c.getName())</code>
049    *
050    * @param c The class.
051    * @return A readable class type name, or <jk>null</jk> if parameter is <jk>null</jk>.
052    */
053   public static String getReadableClassName(Class<?> c) {
054      if (c == null)
055         return null;
056      return getReadableClassName(c.getName());
057   }
058
059   /**
060    * Shortcut for calling <code><jsm>getReadableClassName</jsm>(c.getClass().getName())</code>
061    *
062    * @param o The object whose class we want to render.
063    * @return A readable class type name, or <jk>null</jk> if parameter is <jk>null</jk>.
064    */
065   public static String getReadableClassNameForObject(Object o) {
066      if (o == null)
067         return null;
068      return getReadableClassName(o.getClass().getName());
069   }
070
071   /**
072    * Converts the specified class name to a readable form when class name is a special construct like <js>"[[Z"</js>.
073    *
074    * <h5 class='section'>Example:</h5>
075    * <p class='bcode w800'>
076    *    <jsm>getReadableClassName</jsm>(<js>"java.lang.Object"</js>);  <jc>// Returns "java.lang.Object"</jc>
077    *    <jsm>getReadableClassName</jsm>(<js>"boolean"</js>);  <jc>// Returns "boolean"</jc>
078    *    <jsm>getReadableClassName</jsm>(<js>"[Z"</js>);  <jc>// Returns "boolean[]"</jc>
079    *    <jsm>getReadableClassName</jsm>(<js>"[[Z"</js>);  <jc>// Returns "boolean[][]"</jc>
080    *    <jsm>getReadableClassName</jsm>(<js>"[Ljava.lang.Object;"</js>);  <jc>// Returns "java.lang.Object[]"</jc>
081    *    <jsm>getReadableClassName</jsm>(<jk>null</jk>);  <jc>// Returns null</jc>
082    * </p>
083    *
084    * @param className The class name.
085    * @return A readable class type name, or <jk>null</jk> if parameter is <jk>null</jk>.
086    */
087   public static String getReadableClassName(String className) {
088      if (className == null)
089         return null;
090      if (! StringUtils.startsWith(className, '['))
091         return className;
092      int depth = 0;
093      for (int i = 0; i < className.length(); i++) {
094         if (className.charAt(i) == '[')
095            depth++;
096         else
097            break;
098      }
099      char type = className.charAt(depth);
100      String c;
101      switch (type) {
102         case 'Z': c = "boolean"; break;
103         case 'B': c = "byte"; break;
104         case 'C': c = "char"; break;
105         case 'D': c = "double"; break;
106         case 'F': c = "float"; break;
107         case 'I': c = "int"; break;
108         case 'J': c = "long"; break;
109         case 'S': c = "short"; break;
110         default: c = className.substring(depth+1, className.length()-1);
111      }
112      StringBuilder sb = new StringBuilder(c.length() + 2*depth).append(c);
113      for (int i = 0; i < depth; i++)
114         sb.append("[]");
115      return sb.toString();
116   }
117
118   /**
119    * Converts the string generated by {@link #getReadableClassName(Class)} back into a {@link Class}.
120    *
121    * <p>
122    * Generics are stripped from the string since they cannot be converted to a class.
123    *
124    * @param cl The classloader to use to load the class.
125    * @param name The readable class name.
126    * @return The class object.
127    * @throws ClassNotFoundException
128    */
129   public static Class<?> getClassFromReadableName(ClassLoader cl, String name) throws ClassNotFoundException {
130      return cl.loadClass(name);
131   }
132
133   /**
134    * Returns <jk>true</jk> if <code>parent</code> is a parent class of <code>child</code>.
135    *
136    * @param parent The parent class.
137    * @param child The child class.
138    * @param strict If <jk>true</jk> returns <jk>false</jk> if the classes are the same.
139    * @return <jk>true</jk> if <code>parent</code> is a parent class of <code>child</code>.
140    */
141   public static boolean isParentClass(Class<?> parent, Class<?> child, boolean strict) {
142      return parent.isAssignableFrom(child) && ((!strict) || ! parent.equals(child));
143   }
144
145   /**
146    * Returns <jk>true</jk> if <code>parent</code> is a parent class or the same as <code>child</code>.
147    *
148    * @param parent The parent class.
149    * @param child The child class.
150    * @return <jk>true</jk> if <code>parent</code> is a parent class or the same as <code>child</code>.
151    */
152   public static boolean isParentClass(Class<?> parent, Class<?> child) {
153      return isParentClass(parent, child, false);
154   }
155
156   /**
157    * Returns <jk>true</jk> if <code>parent</code> is a parent class or the same as <code>child</code>.
158    *
159    * @param parent The parent class.
160    * @param child The child class.
161    * @return <jk>true</jk> if <code>parent</code> is a parent class or the same as <code>child</code>.
162    */
163   public static boolean isParentClass(Class<?> parent, Type child) {
164      if (child instanceof Class)
165         return isParentClass(parent, (Class<?>)child);
166      return false;
167   }
168
169   /**
170    * Returns the signature of the specified method.
171    *
172    * <p>
173    * For no-arg methods, the signature will be a simple string such as <js>"toString"</js>.
174    * For methods with one or more args, the arguments will be fully-qualified class names (e.g.
175    * <js>"append(java.util.StringBuilder,boolean)"</js>)
176    *
177    * @param m The methods to get the signature on.
178    * @return The methods signature.
179    */
180   public static String getMethodSignature(Method m) {
181      StringBuilder sb = new StringBuilder(m.getName());
182      Class<?>[] pt = m.getParameterTypes();
183      if (pt.length > 0) {
184         sb.append('(');
185         for (int i = 0; i < pt.length; i++) {
186            if (i > 0)
187               sb.append(',');
188            sb.append(getReadableClassName(pt[i]));
189         }
190         sb.append(')');
191      }
192      return sb.toString();
193   }
194
195   private static final Map<Class<?>, Class<?>>
196      pmap1 = new HashMap<>(),
197      pmap2 = new HashMap<>();
198   static {
199      pmap1.put(boolean.class, Boolean.class);
200      pmap1.put(byte.class, Byte.class);
201      pmap1.put(short.class, Short.class);
202      pmap1.put(char.class, Character.class);
203      pmap1.put(int.class, Integer.class);
204      pmap1.put(long.class, Long.class);
205      pmap1.put(float.class, Float.class);
206      pmap1.put(double.class, Double.class);
207      pmap2.put(Boolean.class, boolean.class);
208      pmap2.put(Byte.class, byte.class);
209      pmap2.put(Short.class, short.class);
210      pmap2.put(Character.class, char.class);
211      pmap2.put(Integer.class, int.class);
212      pmap2.put(Long.class, long.class);
213      pmap2.put(Float.class, float.class);
214      pmap2.put(Double.class, double.class);
215   }
216
217   /**
218    * Returns <jk>true</jk> if the {@link #getPrimitiveWrapper(Class)} class returns a value for the specified class.
219    *
220    * @param c The class.
221    * @return <jk>true</jk> if the {@link #getPrimitiveWrapper(Class)} class returns a value for the specified class.
222    */
223   public static boolean hasPrimitiveWrapper(Class<?> c) {
224      return pmap1.containsKey(c);
225   }
226
227   /**
228    * If the specified class is a primitive (e.g. <code><jk>int</jk>.<jk>class</jk></code>) returns it's wrapper class
229    * (e.g. <code>Integer.<jk>class</jk></code>).
230    *
231    * @param c The class.
232    * @return The wrapper class, or <jk>null</jk> if class is not a primitive.
233    */
234   public static Class<?> getPrimitiveWrapper(Class<?> c) {
235      return pmap1.get(c);
236   }
237
238   /**
239    * If the specified class is a primitive wrapper (e.g. <code><jk>Integer</jk>.<jk>class</jk></code>) returns it's
240    * primitive class (e.g. <code>int.<jk>class</jk></code>).
241    *
242    * @param c The class.
243    * @return The primitive class, or <jk>null</jk> if class is not a primitive wrapper.
244    */
245   public static Class<?> getPrimitiveForWrapper(Class<?> c) {
246      return pmap2.get(c);
247   }
248
249   /**
250    * If the specified class is a primitive (e.g. <code><jk>int</jk>.<jk>class</jk></code>) returns it's wrapper class
251    * (e.g. <code>Integer.<jk>class</jk></code>).
252    *
253    * @param c The class.
254    * @return The wrapper class if it's primitive, or the same class if class is not a primitive.
255    */
256   public static Class<?> getWrapperIfPrimitive(Class<?> c) {
257      if (! c.isPrimitive())
258         return c;
259      return pmap1.get(c);
260   }
261
262   /**
263    * Returns <jk>true</jk> if all specified flags are applicable to the specified class.
264    *
265    * @param x The class to test.
266    * @param flags The flags to test for.
267    * @return <jk>true</jk> if all specified flags are applicable to the specified class.
268    */
269   public static boolean isAll(Class<?> x, ClassFlags...flags) {
270      for (ClassFlags f : flags) {
271         switch (f) {
272            case DEPRECATED:
273               if (isNotDeprecated(x))
274                  return false;
275               break;
276            case NOT_DEPRECATED:
277               if (isDeprecated(x))
278                  return false;
279               break;
280            case PUBLIC:
281               if (isNotPublic(x))
282                  return false;
283               break;
284            case NOT_PUBLIC:
285               if (isPublic(x))
286                  return false;
287               break;
288            case STATIC:
289               if (isNotStatic(x))
290                  return false;
291               break;
292            case NOT_STATIC:
293               if (isStatic(x))
294                  return false;
295               break;
296            case ABSTRACT:
297               if (isNotAbstract(x))
298                  return false;
299               break;
300            case NOT_ABSTRACT:
301               if (isAbstract(x))
302                  return false;
303               break;
304            case HAS_ARGS:
305            case HAS_NO_ARGS:
306            case TRANSIENT:
307            case NOT_TRANSIENT:
308            default:
309               break;
310
311         }
312      }
313      return true;
314   }
315
316   /**
317    * Returns <jk>true</jk> if all specified flags are applicable to the specified method.
318    *
319    * @param x The method to test.
320    * @param flags The flags to test for.
321    * @return <jk>true</jk> if all specified flags are applicable to the specified method.
322    */
323   public static boolean isAll(Method x, ClassFlags...flags) {
324      for (ClassFlags f : flags) {
325         switch (f) {
326            case DEPRECATED:
327               if (isNotDeprecated(x))
328                  return false;
329               break;
330            case NOT_DEPRECATED:
331               if (isDeprecated(x))
332                  return false;
333               break;
334            case HAS_ARGS:
335               if (hasNoArgs(x))
336                  return false;
337               break;
338            case HAS_NO_ARGS:
339               if (hasArgs(x))
340                  return false;
341               break;
342            case PUBLIC:
343               if (isNotPublic(x))
344                  return false;
345               break;
346            case NOT_PUBLIC:
347               if (isPublic(x))
348                  return false;
349               break;
350            case STATIC:
351               if (isNotStatic(x))
352                  return false;
353               break;
354            case NOT_STATIC:
355               if (isStatic(x))
356                  return false;
357               break;
358            case ABSTRACT:
359               if (isNotAbstract(x))
360                  return false;
361               break;
362            case NOT_ABSTRACT:
363               if (isAbstract(x))
364                  return false;
365               break;
366            case TRANSIENT:
367            case NOT_TRANSIENT:
368            default:
369               break;
370
371         }
372      }
373      return true;
374   }
375
376   /**
377    * Returns <jk>true</jk> if all specified flags are applicable to the specified constructor.
378    *
379    * @param x The constructor to test.
380    * @param flags The flags to test for.
381    * @return <jk>true</jk> if all specified flags are applicable to the specified constructor.
382    */
383   public static boolean isAll(Constructor<?> x, ClassFlags...flags) {
384      for (ClassFlags f : flags) {
385         switch (f) {
386            case DEPRECATED:
387               if (isNotDeprecated(x))
388                  return false;
389               break;
390            case NOT_DEPRECATED:
391               if (isDeprecated(x))
392                  return false;
393               break;
394            case HAS_ARGS:
395               if (hasNoArgs(x))
396                  return false;
397               break;
398            case HAS_NO_ARGS:
399               if (hasArgs(x))
400                  return false;
401               break;
402            case PUBLIC:
403               if (isNotPublic(x))
404                  return false;
405               break;
406            case NOT_PUBLIC:
407               if (isPublic(x))
408                  return false;
409               break;
410            case STATIC:
411            case NOT_STATIC:
412            case ABSTRACT:
413            case NOT_ABSTRACT:
414            case TRANSIENT:
415            case NOT_TRANSIENT:
416            default:
417               break;
418
419         }
420      }
421      return true;
422   }
423
424   /**
425    * Returns <jk>true</jk> if all specified flags are applicable to the specified field.
426    *
427    * @param x The field to test.
428    * @param flags The flags to test for.
429    * @return <jk>true</jk> if all specified flags are applicable to the specified field.
430    */
431   public static boolean isAll(Field x, ClassFlags...flags) {
432      for (ClassFlags f : flags) {
433         switch (f) {
434            case DEPRECATED:
435               if (isNotDeprecated(x))
436                  return false;
437               break;
438            case NOT_DEPRECATED:
439               if (isDeprecated(x))
440                  return false;
441               break;
442            case HAS_ARGS:
443               break;
444            case HAS_NO_ARGS:
445               break;
446            case PUBLIC:
447               if (isNotPublic(x))
448                  return false;
449               break;
450            case NOT_PUBLIC:
451               if (isPublic(x))
452                  return false;
453               break;
454            case STATIC:
455               if (isNotStatic(x))
456                  return false;
457               break;
458            case NOT_STATIC:
459               if (isStatic(x))
460                  return false;
461               break;
462            case TRANSIENT:
463               if (isNotTransient(x))
464                  return false;
465               break;
466            case NOT_TRANSIENT:
467               if (isTransient(x))
468                  return false;
469               break;
470            case ABSTRACT:
471            case NOT_ABSTRACT:
472            default:
473               break;
474
475         }
476      }
477      return true;
478   }
479
480   /**
481    * Returns <jk>true</jk> if all specified flags are applicable to the specified class.
482    *
483    * @param x The class to test.
484    * @param flags The flags to test for.
485    * @return <jk>true</jk> if all specified flags are applicable to the specified class.
486    */
487   public static boolean isAny(Class<?> x, ClassFlags...flags) {
488      for (ClassFlags f : flags) {
489         switch (f) {
490            case DEPRECATED:
491               if (isDeprecated(x))
492                  return true;
493               break;
494            case NOT_DEPRECATED:
495               if (isNotDeprecated(x))
496                  return true;
497               break;
498            case PUBLIC:
499               if (isPublic(x))
500                  return true;
501               break;
502            case NOT_PUBLIC:
503               if (isNotPublic(x))
504                  return true;
505               break;
506            case STATIC:
507               if (isStatic(x))
508                  return true;
509               break;
510            case NOT_STATIC:
511               if (isNotStatic(x))
512                  return true;
513               break;
514            case ABSTRACT:
515               if (isAbstract(x))
516                  return true;
517               break;
518            case NOT_ABSTRACT:
519               if (isNotAbstract(x))
520                  return true;
521               break;
522            case TRANSIENT:
523            case NOT_TRANSIENT:
524            case HAS_ARGS:
525            case HAS_NO_ARGS:
526            default:
527               break;
528
529         }
530      }
531      return false;
532   }
533
534   /**
535    * Returns <jk>true</jk> if all specified flags are applicable to the specified method.
536    *
537    * @param x The method to test.
538    * @param flags The flags to test for.
539    * @return <jk>true</jk> if all specified flags are applicable to the specified method.
540    */
541   public static boolean isAny(Method x, ClassFlags...flags) {
542      for (ClassFlags f : flags) {
543         switch (f) {
544            case DEPRECATED:
545               if (isDeprecated(x))
546                  return true;
547               break;
548            case NOT_DEPRECATED:
549               if (isNotDeprecated(x))
550                  return true;
551               break;
552            case HAS_ARGS:
553               if (hasArgs(x))
554                  return true;
555               break;
556            case HAS_NO_ARGS:
557               if (hasNoArgs(x))
558                  return true;
559               break;
560            case PUBLIC:
561               if (isPublic(x))
562                  return true;
563               break;
564            case NOT_PUBLIC:
565               if (isNotPublic(x))
566                  return true;
567               break;
568            case STATIC:
569               if (isStatic(x))
570                  return true;
571               break;
572            case NOT_STATIC:
573               if (isNotStatic(x))
574                  return true;
575               break;
576            case ABSTRACT:
577               if (isAbstract(x))
578                  return true;
579               break;
580            case NOT_ABSTRACT:
581               if (isNotAbstract(x))
582                  return true;
583               break;
584            case TRANSIENT:
585            case NOT_TRANSIENT:
586            default:
587               break;
588
589         }
590      }
591      return false;
592   }
593
594   /**
595    * Returns <jk>true</jk> if all specified flags are applicable to the specified constructor.
596    *
597    * @param x The constructor to test.
598    * @param flags The flags to test for.
599    * @return <jk>true</jk> if all specified flags are applicable to the specified constructor.
600    */
601   public static boolean isAny(Constructor<?> x, ClassFlags...flags) {
602      for (ClassFlags f : flags) {
603         switch (f) {
604            case DEPRECATED:
605               if (isDeprecated(x))
606                  return true;
607               break;
608            case NOT_DEPRECATED:
609               if (isNotDeprecated(x))
610                  return true;
611               break;
612            case HAS_ARGS:
613               if (hasArgs(x))
614                  return true;
615               break;
616            case HAS_NO_ARGS:
617               if (hasNoArgs(x))
618                  return true;
619               break;
620            case PUBLIC:
621               if (isPublic(x))
622                  return true;
623               break;
624            case NOT_PUBLIC:
625               if (isNotPublic(x))
626                  return true;
627               break;
628            case STATIC:
629            case NOT_STATIC:
630            case ABSTRACT:
631            case NOT_ABSTRACT:
632            case TRANSIENT:
633            case NOT_TRANSIENT:
634            default:
635               break;
636
637         }
638      }
639      return false;
640   }
641
642   /**
643    * Returns <jk>true</jk> if all specified flags are applicable to the specified field.
644    *
645    * @param x The field to test.
646    * @param flags The flags to test for.
647    * @return <jk>true</jk> if all specified flags are applicable to the specified field.
648    */
649   public static boolean isAny(Field x, ClassFlags...flags) {
650      for (ClassFlags f : flags) {
651         switch (f) {
652            case DEPRECATED:
653               if (isDeprecated(x))
654                  return true;
655               break;
656            case NOT_DEPRECATED:
657               if (isNotDeprecated(x))
658                  return true;
659               break;
660            case PUBLIC:
661               if (isPublic(x))
662                  return true;
663               break;
664            case NOT_PUBLIC:
665               if (isNotPublic(x))
666                  return true;
667               break;
668            case STATIC:
669               if (isStatic(x))
670                  return true;
671               break;
672            case NOT_STATIC:
673               if (isNotStatic(x))
674                  return true;
675               break;
676            case TRANSIENT:
677               if (isTransient(x))
678                  return true;
679               break;
680            case NOT_TRANSIENT:
681               if (isNotTransient(x))
682                  return true;
683               break;
684            case HAS_ARGS:
685            case HAS_NO_ARGS:
686            case ABSTRACT:
687            case NOT_ABSTRACT:
688            default:
689               break;
690
691         }
692      }
693      return false;
694   }
695
696   /**
697    * Returns <jk>true</jk> if the specified method has the specified arguments.
698    *
699    * @param x The method to test.
700    * @param args The arguments to test for.
701    * @return <jk>true</jk> if the specified method has the specified arguments in the exact order.
702    */
703   public static boolean hasArgs(Method x, Class<?>...args) {
704      Class<?>[] pt = x.getParameterTypes();
705      if (pt.length == args.length) {
706         for (int i = 0; i < pt.length; i++)
707            if (! pt[i].equals(args[i]))
708               return false;
709         return true;
710      }
711      return false;
712   }
713
714   /**
715    * Returns <jk>true</jk> if the specified constructor has the specified arguments.
716    *
717    * @param x The constructor to test.
718    * @param args The arguments to test for.
719    * @return <jk>true</jk> if the specified constructor has the specified arguments in the exact order.
720    */
721   public static boolean hasArgs(Constructor<?> x, Class<?>...args) {
722      Class<?>[] pt = x.getParameterTypes();
723      if (pt.length == args.length) {
724         for (int i = 0; i < pt.length; i++)
725            if (! pt[i].equals(args[i]))
726               return false;
727         return true;
728      }
729      return false;
730   }
731
732   /**
733    * Returns <jk>true</jk> if the specified constructor has one or more arguments.
734    *
735    * @param x The method to test.
736    * @return <jk>true</jk> if the specified constructor has one or more arguments.
737    */
738   public static boolean hasArgs(Constructor<?> x) {
739      return x.getParameterTypes().length > 0;
740   }
741
742   /**
743    * Returns <jk>true</jk> if the specified constructor has zero arguments.
744    *
745    * @param x The method to test.
746    * @return <jk>true</jk> if the specified constructor has zero arguments.
747    */
748   public static boolean hasNoArgs(Constructor<?> x) {
749      return x.getParameterTypes().length == 0;
750   }
751
752   /**
753    * Returns <jk>true</jk> if the specified constructor has the specified number of arguments.
754    *
755    * @param x The method to test.
756    * @param number The number of expected arguments.
757    * @return <jk>true</jk> if the specified method has the specified number of arguments.
758    */
759   public static boolean hasNumArgs(Method x, int number) {
760      return x.getParameterTypes().length == number;
761   }
762
763   /**
764    * Returns <jk>true</jk> if the specified constructor has the specified number of arguments.
765    *
766    * @param x The constructor to test.
767    * @param number The number of expected arguments.
768    * @return <jk>true</jk> if the specified constructor has the specified number of arguments.
769    */
770   public static boolean hasNumArgs(Constructor<?> x, int number) {
771      return x.getParameterTypes().length == number;
772   }
773
774   /**
775    * Returns <jk>true</jk> if the specified method has at most only the specified arguments in any order.
776    *
777    * @param x The method to test.
778    * @param args The arguments to test for.
779    * @return <jk>true</jk> if the specified method has at most only the specified arguments in any order.
780    */
781   public static boolean hasFuzzyArgs(Method x, Class<?>...args) {
782      return fuzzyArgsMatch(x.getParameterTypes(), args) != -1;
783   }
784
785   /**
786    * Returns <jk>true</jk> if the specified constructor has at most only the specified arguments in any order.
787    *
788    * @param x The constructor to test.
789    * @param args The arguments to test for.
790    * @return <jk>true</jk> if the specified constructor has at most only the specified arguments in any order.
791    */
792   public static boolean hasFuzzyArgs(Constructor<?> x, Class<?>...args) {
793      return fuzzyArgsMatch(x.getParameterTypes(), args) != -1;
794   }
795
796   /**
797    * Returns <jk>true</jk> if the specified class has the {@link Deprecated @Deprecated} annotation on it.
798    *
799    * @param c The class.
800    * @return <jk>true</jk> if the specified class has the {@link Deprecated @Deprecated} annotation on it.
801    */
802   public static boolean isDeprecated(Class<?> c) {
803      return c.isAnnotationPresent(Deprecated.class);
804   }
805
806   /**
807    * Returns <jk>true</jk> if the specified method has the {@link Deprecated @Deprecated} annotation on it.
808    *
809    * @param m The method.
810    * @return <jk>true</jk> if the specified method has the {@link Deprecated @Deprecated} annotation on it.
811    */
812   public static boolean isDeprecated(Method m) {
813      return m.isAnnotationPresent(Deprecated.class);
814
815   }
816
817   /**
818    * Returns <jk>true</jk> if the specified constructor has the {@link Deprecated @Deprecated} annotation on it.
819    *
820    * @param c The constructor.
821    * @return <jk>true</jk> if the specified constructor has the {@link Deprecated @Deprecated} annotation on it.
822    */
823   public static boolean isDeprecated(Constructor<?> c) {
824      return c.isAnnotationPresent(Deprecated.class);
825   }
826
827   /**
828    * Returns <jk>true</jk> if the specified field has the {@link Deprecated @Deprecated} annotation on it.
829    *
830    * @param f The field.
831    * @return <jk>true</jk> if the specified field has the {@link Deprecated @Deprecated} annotation on it.
832    */
833   public static boolean isDeprecated(Field f) {
834      return f.isAnnotationPresent(Deprecated.class);
835   }
836
837   /**
838    * Returns <jk>true</jk> if the specified class doesn't have the {@link Deprecated @Deprecated} annotation on it.
839    *
840    * @param c The class.
841    * @return <jk>true</jk> if the specified class doesn't have the {@link Deprecated @Deprecated} annotation on it.
842    */
843   public static boolean isNotDeprecated(Class<?> c) {
844      return ! c.isAnnotationPresent(Deprecated.class);
845   }
846
847   /**
848    * Returns <jk>true</jk> if the specified method doesn't have the {@link Deprecated @Deprecated} annotation on it.
849    *
850    * @param m The method.
851    * @return <jk>true</jk> if the specified method doesn't have the {@link Deprecated @Deprecated} annotation on it.
852    */
853   public static boolean isNotDeprecated(Method m) {
854      return ! m.isAnnotationPresent(Deprecated.class);
855
856   }
857
858   /**
859    * Returns <jk>true</jk> if the specified constructor doesn't have the {@link Deprecated @Deprecated} annotation on it.
860    *
861    * @param c The constructor.
862    * @return <jk>true</jk> if the specified constructor doesn't have the {@link Deprecated @Deprecated} annotation on it.
863    */
864   public static boolean isNotDeprecated(Constructor<?> c) {
865      return ! c.isAnnotationPresent(Deprecated.class);
866   }
867
868   /**
869    * Returns <jk>true</jk> if the specified field doesn't have the {@link Deprecated @Deprecated} annotation on it.
870    *
871    * @param f The field.
872    * @return <jk>true</jk> if the specified field doesn't have the {@link Deprecated @Deprecated} annotation on it.
873    */
874   public static boolean isNotDeprecated(Field f) {
875      return ! f.isAnnotationPresent(Deprecated.class);
876   }
877
878   /**
879    * Returns <jk>true</jk> if the specified class is public.
880    *
881    * @param c The class.
882    * @return <jk>true</jk> if the specified class is public.
883    */
884   public static boolean isPublic(Class<?> c) {
885      return Modifier.isPublic(c.getModifiers());
886   }
887
888   /**
889    * Returns <jk>true</jk> if the specified class is not public.
890    *
891    * @param c The class.
892    * @return <jk>true</jk> if the specified class is not public.
893    */
894   public static boolean isNotPublic(Class<?> c) {
895      return ! Modifier.isPublic(c.getModifiers());
896   }
897
898   /**
899    * Returns <jk>true</jk> if the specified class is public.
900    *
901    * @param c The class.
902    * @return <jk>true</jk> if the specified class is public.
903    */
904   public static boolean isStatic(Class<?> c) {
905      return Modifier.isStatic(c.getModifiers());
906   }
907
908   /**
909    * Returns <jk>true</jk> if the specified class is not static.
910    *
911    * @param c The class.
912    * @return <jk>true</jk> if the specified class is not static.
913    */
914   public static boolean isNotStatic(Class<?> c) {
915      return ! Modifier.isStatic(c.getModifiers());
916   }
917
918   /**
919    * Returns <jk>true</jk> if the specified class is abstract.
920    *
921    * @param c The class.
922    * @return <jk>true</jk> if the specified class is abstract.
923    */
924   public static boolean isAbstract(Class<?> c) {
925      return Modifier.isAbstract(c.getModifiers());
926   }
927
928   /**
929    * Returns <jk>true</jk> if the specified class is not abstract.
930    *
931    * @param c The class.
932    * @return <jk>true</jk> if the specified class is not abstract.
933    */
934   public static boolean isNotAbstract(Class<?> c) {
935      return ! Modifier.isAbstract(c.getModifiers());
936   }
937
938   /**
939    * Returns <jk>true</jk> if the specified method is abstract.
940    *
941    * @param m The method.
942    * @return <jk>true</jk> if the specified method is abstract.
943    */
944   public static boolean isAbstract(Method m) {
945      return Modifier.isAbstract(m.getModifiers());
946   }
947
948   /**
949    * Returns <jk>true</jk> if the specified method is not abstract.
950    *
951    * @param m The method.
952    * @return <jk>true</jk> if the specified method is not abstract.
953    */
954   public static boolean isNotAbstract(Method m) {
955      return ! Modifier.isAbstract(m.getModifiers());
956   }
957
958   /**
959    * Returns <jk>true</jk> if the specified method is public.
960    *
961    * @param m The method.
962    * @return <jk>true</jk> if the specified method is public.
963    */
964   public static boolean isPublic(Method m) {
965      return Modifier.isPublic(m.getModifiers());
966   }
967
968   /**
969    * Returns <jk>true</jk> if the specified method is not public.
970    *
971    * @param m The method.
972    * @return <jk>true</jk> if the specified method is not public.
973    */
974   public static boolean isNotPublic(Method m) {
975      return ! Modifier.isPublic(m.getModifiers());
976   }
977
978   /**
979    * Returns <jk>true</jk> if the specified field is public.
980    *
981    * @param f The field.
982    * @return <jk>true</jk> if the specified field is public.
983    */
984   public static boolean isPublic(Field f) {
985      return Modifier.isPublic(f.getModifiers());
986   }
987
988   /**
989    * Returns <jk>true</jk> if the specified field is not public.
990    *
991    * @param f The field.
992    * @return <jk>true</jk> if the specified field is not public.
993    */
994   public static boolean isNotPublic(Field f) {
995      return ! Modifier.isPublic(f.getModifiers());
996   }
997
998   /**
999    * Returns <jk>true</jk> if the specified method is static.
1000    *
1001    * @param m The method.
1002    * @return <jk>true</jk> if the specified method is static.
1003    */
1004   public static boolean isStatic(Method m) {
1005      return Modifier.isStatic(m.getModifiers());
1006   }
1007
1008   /**
1009    * Returns <jk>true</jk> if the specified method is not static.
1010    *
1011    * @param m The method.
1012    * @return <jk>true</jk> if the specified method is not static.
1013    */
1014   public static boolean isNotStatic(Method m) {
1015      return !  Modifier.isStatic(m.getModifiers());
1016   }
1017
1018   /**
1019    * Returns <jk>true</jk> if the specified field is static.
1020    *
1021    * @param f The field.
1022    * @return <jk>true</jk> if the specified field is static.
1023    */
1024   public static boolean isStatic(Field f) {
1025      return Modifier.isStatic(f.getModifiers());
1026   }
1027
1028   /**
1029    * Returns <jk>true</jk> if the specified field is not static.
1030    *
1031    * @param f The field.
1032    * @return <jk>true</jk> if the specified field is not static.
1033    */
1034   public static boolean isNotStatic(Field f) {
1035      return ! Modifier.isStatic(f.getModifiers());
1036   }
1037
1038   /**
1039    * Returns <jk>true</jk> if the specified constructor is public.
1040    *
1041    * @param c The constructor.
1042    * @return <jk>true</jk> if the specified constructor is public.
1043    */
1044   public static boolean isPublic(Constructor<?> c) {
1045      return Modifier.isPublic(c.getModifiers());
1046   }
1047
1048   /**
1049    * Returns <jk>true</jk> if the specified constructor is not public.
1050    *
1051    * @param c The constructor.
1052    * @return <jk>true</jk> if the specified constructor is not public.
1053    */
1054   public static boolean isNotPublic(Constructor<?> c) {
1055      return ! Modifier.isPublic(c.getModifiers());
1056   }
1057
1058   /**
1059    * Returns <jk>true</jk> if the specified field is transient.
1060    *
1061    * @param f The field.
1062    * @return <jk>true</jk> if the specified field is transient.
1063    */
1064   public static boolean isTransient(Field f) {
1065      return Modifier.isTransient(f.getModifiers());
1066   }
1067
1068   /**
1069    * Returns <jk>true</jk> if the specified field is not transient.
1070    *
1071    * @param f The field.
1072    * @return <jk>true</jk> if the specified field is not transient.
1073    */
1074   public static boolean isNotTransient(Field f) {
1075      return ! Modifier.isTransient(f.getModifiers());
1076   }
1077
1078   /**
1079    * Returns <jk>true</jk> if the specified method has one or more arguments.
1080    *
1081    * @param x The method to test.
1082    * @return <jk>true</jk> if the specified method has one or more arguments.
1083    */
1084   public static boolean hasArgs(Method x) {
1085      return x.getParameterTypes().length > 0;
1086   }
1087
1088   /**
1089    * Returns <jk>true</jk> if the specified method has zero arguments.
1090    *
1091    * @param x The method to test.
1092    * @return <jk>true</jk> if the specified method has zero arguments.
1093    */
1094   public static boolean hasNoArgs(Method x) {
1095      return x.getParameterTypes().length == 0;
1096   }
1097
1098   /**
1099    * Returns <jk>true</jk> if the specified method has the specified name.
1100    *
1101    * @param m The method to test.
1102    * @param name The name to test for.
1103    * @return <jk>true</jk> if the specified method has the specified name.
1104    */
1105   public static boolean hasName(Method m, String name) {
1106      return m.getName().equals(name);
1107   }
1108
1109   /**
1110    * Returns <jk>true</jk> if the specified method has the specified return type.
1111    *
1112    * @param m The method to test.
1113    * @param c The return type to test for.
1114    * @return <jk>true</jk> if the specified method has the specified return type.
1115    */
1116   public static boolean hasReturnType(Method m, Class<?> c) {
1117      return m.getReturnType() == c;
1118   }
1119
1120   /**
1121    * Returns <jk>true</jk> if the specified method has the specified parent return type.
1122    *
1123    * @param m The method to test.
1124    * @param c The return type to test for.
1125    * @return <jk>true</jk> if the specified method has the specified parent return type.
1126    */
1127   public static boolean hasReturnTypeParent(Method m, Class<?> c) {
1128      return isParentClass(c, m.getReturnType());
1129   }
1130
1131   //-----------------------------------------------------------------------------------------------------------------
1132   // Method annotations.
1133   //-----------------------------------------------------------------------------------------------------------------
1134
1135   /**
1136    * Returns all annotations of the specified type defined on the specified method.
1137    *
1138    * @param a
1139    *    The annotation to search for.
1140    * @param m
1141    *    The method to find the annotation on.
1142    * @param searchParentMethods
1143    *    If <jk>true</jk>, searches methods with the same signature on the parent classes or interfaces.
1144    * @param searchReturnType
1145    *    If <jk>true</jk>, searches the return type on the method for the specified annotation.
1146    * @param parentFirst
1147    *    If <jk>true</jk>, returns the results in parent-to-child order.
1148    * @return
1149    *    A list of all matching annotations found, or an empty list if none found.
1150    */
1151   @SuppressWarnings("unchecked")
1152   public static <T extends Annotation> List<T> getAnnotations(Class<T> a, Method m, boolean searchParentMethods, boolean searchReturnType, boolean parentFirst) {
1153      List<T> l = new ArrayList<>();
1154      List<Method> methods = searchParentMethods ? findMatchingMethods(m) : Collections.singletonList(m);
1155      for (Method m2 : methods)
1156         for (Annotation a2 :  m2.getAnnotations())
1157            if (a.isInstance(a2))
1158               l.add((T)a2);
1159      if (searchReturnType) {
1160         Type t = m.getGenericReturnType();
1161         if (Value.isType(t))
1162            appendAnnotations(a, Value.getParameterType(t), l);
1163         else
1164            appendAnnotations(a, t, l);
1165      }
1166      if (parentFirst)
1167         Collections.reverse(l);
1168      return l;
1169   }
1170
1171   /**
1172    * Shortcut for calling <code>getAnnotations(a, m, <jk>true</jk>, <jk>true</jk>, <jk>false</jk>);</code>
1173    *
1174    * <p>
1175    * Annotations are ordered method first, then return class, then return superclasses.
1176    *
1177    * @param a The annotation to look for.
1178    * @param m The method being inspected.
1179    * @return All instances of the annotation with the
1180    */
1181   public static <T extends Annotation> List<T> getAnnotations(Class<T> a, Method m) {
1182      return getAnnotations(a, m, true, true, false);
1183   }
1184
1185   /**
1186    * Shortcut for calling <code>getAnnotations(a, m, <jk>true</jk>, <jk>true</jk>, <jk>true</jk>);</code>
1187    *
1188    * @param a The annotation to look for.
1189    * @param m The method being inspected.
1190    * @return All instances of the annotation with the
1191    */
1192   public static <T extends Annotation> List<T> getAnnotationsParentFirst(Class<T> a, Method m) {
1193      return getAnnotations(a, m, true, true, true);
1194   }
1195
1196   /**
1197    * Finds the annotation of the specified type defined on the specified method.
1198    *
1199    * @param a
1200    *    The annotation to search for.
1201    * @param m
1202    *    The method to find the annotation on.
1203    * @param searchParentMethods
1204    *    If <jk>true</jk>, searches methods with the same signature on the parent classes or interfaces.
1205    *    <br>The search is performed in child-to-parent order.
1206    * @param searchReturnType
1207    *    If <jk>true</jk>, searches the return type on the method for the specified annotation.
1208    * @return
1209    *    The annotation if found, or <jk>null</jk> if not.
1210    */
1211   @SuppressWarnings("unchecked")
1212   public static <T extends Annotation> T getAnnotation(Class<T> a, Method m, boolean searchParentMethods, boolean searchReturnType) {
1213      List<Method> methods = searchParentMethods ? findMatchingMethods(m) : Collections.singletonList(m);
1214      for (Method m2 : methods)
1215         for (Annotation a2 :  m2.getAnnotations())
1216            if (a.isInstance(a2))
1217               return (T)a2;
1218      if (searchReturnType) {
1219         Type t = m.getGenericReturnType();
1220         if (Value.isType(t))
1221            return getAnnotation(a, Value.getParameterType(t));
1222         return getAnnotation(a, t);
1223      }
1224      return null;
1225   }
1226
1227   /**
1228    * Shortcut for calling <code>getAnnotation(a, m, true, true);
1229    *
1230    * @param a
1231    *    The annotation to search for.
1232    * @param m
1233    *    The method to find the annotation on.
1234    * @return
1235    *    The annotation if found, or <jk>null</jk> if not.
1236    */
1237   public static <T extends Annotation> T getAnnotation(Class<T> a, Method m) {
1238      return getAnnotation(a, m, true, true);
1239   }
1240
1241   //-----------------------------------------------------------------------------------------------------------------
1242   // Method argument annotations.
1243   //-----------------------------------------------------------------------------------------------------------------
1244
1245   /**
1246    * Returns all annotations of the specified type defined on the specified method argument.
1247    *
1248    * @param a
1249    *    The annotation to search for.
1250    * @param m
1251    *    The method containing the argument to find the annotation on.
1252    * @param index
1253    *    The argument index position.
1254    * @param searchParentMethods
1255    *    If <jk>true</jk>, searches methods with the same signature on the parent classes or interfaces.
1256    * @param searchArgType
1257    *    If <jk>true</jk>, searches the argument type for the specified annotation.
1258    * @param parentFirst
1259    *    If <jk>true</jk>, returns the results in parent-to-child order.
1260    * @return
1261    *    A list of all matching annotations found, or an empty list if none found.
1262    */
1263   @SuppressWarnings("unchecked")
1264   public static <T extends Annotation> List<T> getAnnotations(Class<T> a, Method m, int index, boolean searchParentMethods, boolean searchArgType, boolean parentFirst) {
1265      List<T> l = new ArrayList<>();
1266      List<Method> methods = searchParentMethods ? findMatchingMethods(m) : Collections.singletonList(m);
1267      for (Method m2 : methods)
1268         for (Annotation a2 :  m2.getParameterAnnotations()[index])
1269            if (a.isInstance(a2))
1270               l.add((T)a2);
1271      if (searchArgType) {
1272         Type t = m.getGenericParameterTypes()[index];
1273         if (Value.isType(t))
1274            appendAnnotations(a, Value.getParameterType(t), l);
1275         else
1276            appendAnnotations(a, t, l);
1277      }
1278      if (parentFirst)
1279         Collections.reverse(l);
1280      return l;
1281   }
1282
1283   /**
1284    * Finds the annotation of the specified type defined on the specified method argument.
1285    *
1286    * @param a
1287    *    The annotation to search for.
1288    * @param m
1289    *    The method containing the argument to find the annotation on.
1290    * @param index
1291    *    The argument index position.
1292    * @param searchParentMethods
1293    *    If <jk>true</jk>, searches methods with the same signature on the parent classes or interfaces.
1294    *    <br>The search is performed in child-to-parent order.
1295    * @param searchArgType
1296    *    If <jk>true</jk>, searches the argument type for the specified annotation.
1297    * @return
1298    *    The annotation if found, or <jk>null</jk> if not.
1299    */
1300   @SuppressWarnings("unchecked")
1301   public static <T extends Annotation> T getAnnotation(Class<T> a, Method m, int index, boolean searchParentMethods, boolean searchArgType) {
1302      List<Method> methods = searchParentMethods ? findMatchingMethods(m) : Collections.singletonList(m);
1303      for (Method m2 : methods)
1304         for (Annotation a2 :  m2.getParameterAnnotations()[index])
1305            if (a.isInstance(a2))
1306               return (T)a2;
1307      if (searchArgType) {
1308         Type t = m.getGenericParameterTypes()[index];
1309         if (Value.isType(t))
1310            return getAnnotation(a, Value.getParameterType(t));
1311         return getAnnotation(a, t);
1312      }
1313      return null;
1314   }
1315
1316   /**
1317    * Shortcut for calling <code>getAnnotation(a, m, index, <jk>true</jk>, <jk>true</jk>);</code>
1318    *
1319    * @param a The annotation to check for.
1320    * @param m The method containing the parameter to check.
1321    * @param index The parameter index.
1322    * @return <jk>true</jk> if the {@link #getAnnotation(Class, Method, int)} returns a value.
1323    */
1324   public static <T extends Annotation> T getAnnotation(Class<T> a, Method m, int index) {
1325      return getAnnotation(a, m, index, true, true);
1326   }
1327
1328   /**
1329    * Shortcut for calling <code>getAnnotations(a, m, index, <jk>true</jk>, <jk>true</jk>, <jk>false</jk>);</code>
1330    *
1331    * @param a The annotation to look for.
1332    * @param m The method containing the parameter.
1333    * @param index The parameter index.
1334    * @return All instances of the annotation with the
1335    */
1336   public static <T extends Annotation> List<T> getAnnotations(Class<T> a, Method m, int index) {
1337      return getAnnotations(a, m, index, true, true, false);
1338   }
1339
1340   /**
1341    * Shortcut for calling <code>getAnnotations(a, m, index, <jk>true</jk>, <jk>true</jk>, <jk>true</jk>);</code>
1342    *
1343    * @param a The annotation to look for.
1344    * @param m The method containing the parameter.
1345    * @param index The parameter index.
1346    * @return All instances of the annotation with the
1347    */
1348   public static <T extends Annotation> List<T> getAnnotationsParentFirst(Class<T> a, Method m, int index) {
1349      return getAnnotations(a, m, index, true, true, true);
1350   }
1351
1352   /**
1353    * Given a specific method, finds all declared methods with the same name and arguments on all
1354    * superclasses and interfaces.
1355    *
1356    * @param m The method to find matches against.
1357    * @return
1358    *    All matching methods including the input method itself.
1359    *    Methods are ordered from child-to-parent order.
1360    */
1361   public static List<Method> findMatchingMethods(Method m) {
1362      return findMatchingMethods(new ArrayList<Method>(), m);
1363   }
1364
1365   private static List<Method> findMatchingMethods(List<Method> l, Method m) {
1366      l.add(m);
1367      Class<?> c = m.getDeclaringClass();
1368      Class<?> pc = c.getSuperclass();
1369      if (pc != null)
1370         for (Method m2 : pc.getDeclaredMethods())
1371            if (isSameMethod(m, m2))
1372               findMatchingMethods(l, m2);
1373      for (Class<?> ic : c.getInterfaces())
1374         for (Method m2 : ic.getDeclaredMethods())
1375            if (isSameMethod(m, m2))
1376               findMatchingMethods(l, m2);
1377      return l;
1378   }
1379
1380   private static boolean isSameMethod(Method m1, Method m2) {
1381      return m1.getName().equals(m2.getName()) && Arrays.equals(m1.getParameterTypes(), m2.getParameterTypes());
1382   }
1383
1384   /**
1385    * Locates the no-arg constructor for the specified class.
1386    *
1387    * <p>
1388    * Constructor must match the visibility requirements specified by parameter 'v'.
1389    * If class is abstract, always returns <jk>null</jk>.
1390    * Note that this also returns the 1-arg constructor for non-static member classes.
1391    *
1392    * @param c The class from which to locate the no-arg constructor.
1393    * @param v The minimum visibility.
1394    * @return The constructor, or <jk>null</jk> if no no-arg constructor exists with the required visibility.
1395    */
1396   @SuppressWarnings({"rawtypes","unchecked"})
1397   public static final <T> Constructor<T> findNoArgConstructor(Class<T> c, Visibility v) {
1398      int mod = c.getModifiers();
1399      if (Modifier.isAbstract(mod))
1400         return null;
1401      boolean isMemberClass = c.isMemberClass() && ! isStatic(c);
1402      for (Constructor cc : c.getConstructors()) {
1403         mod = cc.getModifiers();
1404         if (hasNumArgs(cc, isMemberClass ? 1 : 0) && v.isVisible(mod) && isNotDeprecated(cc))
1405            return v.transform(cc);
1406      }
1407      return null;
1408   }
1409
1410   /**
1411    * Finds the real parameter type of the specified class.
1412    *
1413    * @param c The class containing the parameters (e.g. PojoSwap&lt;T,S&gt;)
1414    * @param index The zero-based index of the parameter to resolve.
1415    * @param oc The class we're trying to resolve the parameter type for.
1416    * @return The resolved real class.
1417    */
1418   public static Class<?> resolveParameterType(Class<?> c, int index, Class<?> oc) {
1419
1420      // We need to make up a mapping of type names.
1421      Map<Type,Type> typeMap = new HashMap<>();
1422      while (c != oc.getSuperclass()) {
1423         extractTypes(typeMap, oc);
1424         oc = oc.getSuperclass();
1425      }
1426
1427      Type gsc = oc.getGenericSuperclass();
1428
1429      // Not actually a parameterized type.
1430      if (! (gsc instanceof ParameterizedType))
1431         return Object.class;
1432
1433      ParameterizedType opt = (ParameterizedType)gsc;
1434      Type actualType = opt.getActualTypeArguments()[index];
1435
1436      if (typeMap.containsKey(actualType))
1437         actualType = typeMap.get(actualType);
1438
1439      if (actualType instanceof Class) {
1440         return (Class<?>)actualType;
1441
1442      } else if (actualType instanceof GenericArrayType) {
1443         Class<?> cmpntType = (Class<?>)((GenericArrayType)actualType).getGenericComponentType();
1444         return Array.newInstance(cmpntType, 0).getClass();
1445
1446      } else if (actualType instanceof TypeVariable) {
1447         TypeVariable<?> typeVariable = (TypeVariable<?>)actualType;
1448         List<Class<?>> nestedOuterTypes = new LinkedList<>();
1449         for (Class<?> ec = oc.getEnclosingClass(); ec != null; ec = ec.getEnclosingClass()) {
1450            try {
1451               Class<?> outerClass = oc.getClass();
1452               nestedOuterTypes.add(outerClass);
1453               Map<Type,Type> outerTypeMap = new HashMap<>();
1454               extractTypes(outerTypeMap, outerClass);
1455               for (Map.Entry<Type,Type> entry : outerTypeMap.entrySet()) {
1456                  Type key = entry.getKey(), value = entry.getValue();
1457                  if (key instanceof TypeVariable) {
1458                     TypeVariable<?> keyType = (TypeVariable<?>)key;
1459                     if (keyType.getName().equals(typeVariable.getName()) && isInnerClass(keyType.getGenericDeclaration(), typeVariable.getGenericDeclaration())) {
1460                        if (value instanceof Class)
1461                           return (Class<?>)value;
1462                        typeVariable = (TypeVariable<?>)entry.getValue();
1463                     }
1464                  }
1465               }
1466            } catch (Exception e) {
1467               throw new RuntimeException(e);
1468            }
1469         }
1470         throw new FormattedRuntimeException("Could not resolve type: {0}", actualType);
1471      } else {
1472         throw new FormattedRuntimeException("Invalid type found in resolveParameterType: {0}", actualType);
1473      }
1474   }
1475
1476   /**
1477    * Invokes the specified method using fuzzy-arg matching.
1478    *
1479    * <p>
1480    * Arguments will be matched to the parameters based on the parameter types.
1481    * <br>Arguments can be in any order.
1482    * <br>Extra arguments will be ignored.
1483    * <br>Missing arguments will be left <jk>null</jk>.
1484    *
1485    * <p>
1486    * Note that this only works for methods that have distinguishable argument types.
1487    * <br>It's not going to work on methods with generic argument types like <code>Object</code>
1488    *
1489    * @param m The method being called.
1490    * @param pojo
1491    *    The POJO the method is being called on.
1492    *    <br>Can be <jk>null</jk> for static methods.
1493    * @param args
1494    *    The arguments to pass to the method.
1495    * @return
1496    *    The results of the method invocation.
1497    * @throws Exception
1498    */
1499   public static Object invokeMethodFuzzy(Method m, Object pojo, Object...args) throws Exception {
1500      return m.invoke(pojo, getMatchingArgs(m.getParameterTypes(), args));
1501   }
1502
1503   /**
1504    * Invokes the specified constructor using fuzzy-arg matching.
1505    *
1506    * <p>
1507    * Arguments will be matched to the parameters based on the parameter types.
1508    * <br>Arguments can be in any order.
1509    * <br>Extra arguments will be ignored.
1510    * <br>Missing arguments will be left <jk>null</jk>.
1511    *
1512    * <p>
1513    * Note that this only works for constructors that have distinguishable argument types.
1514    * <br>It's not going to work on constructors with generic argument types like <code>Object</code>
1515    *
1516    * @param c The constructor being called.
1517    * @param args
1518    *    The arguments to pass to the constructor.
1519    * @return
1520    *    The results of the method invocation.
1521    * @throws Exception
1522    */
1523   public static <T> T invokeConstructorFuzzy(Constructor<T> c, Object...args) throws Exception {
1524      return c.newInstance(getMatchingArgs(c.getParameterTypes(), args));
1525   }
1526
1527   private static boolean isInnerClass(GenericDeclaration od, GenericDeclaration id) {
1528      if (od instanceof Class && id instanceof Class) {
1529         Class<?> oc = (Class<?>)od;
1530         Class<?> ic = (Class<?>)id;
1531         while ((ic = ic.getEnclosingClass()) != null)
1532            if (ic == oc)
1533               return true;
1534      }
1535      return false;
1536   }
1537
1538   private static void extractTypes(Map<Type,Type> typeMap, Class<?> c) {
1539      Type gs = c.getGenericSuperclass();
1540      if (gs instanceof ParameterizedType) {
1541         ParameterizedType pt = (ParameterizedType)gs;
1542         Type[] typeParameters = ((Class<?>)pt.getRawType()).getTypeParameters();
1543         Type[] actualTypeArguments = pt.getActualTypeArguments();
1544         for (int i = 0; i < typeParameters.length; i++) {
1545            if (typeMap.containsKey(actualTypeArguments[i]))
1546               actualTypeArguments[i] = typeMap.get(actualTypeArguments[i]);
1547            typeMap.put(typeParameters[i], actualTypeArguments[i]);
1548         }
1549      }
1550   }
1551
1552   /**
1553    * Finds a public method with the specified parameters.
1554    *
1555    * @param c The class to look for the method.
1556    * @param name The method name.
1557    * @param returnType
1558    *    The return type of the method.
1559    *    Can be a super type of the actual return type.
1560    *    For example, if the actual return type is <code>CharSequence</code>, then <code>Object</code> will match but
1561    *    <code>String</code> will not.
1562    * @param argTypes
1563    *    The argument types of the method.
1564    *    Can be subtypes of the actual parameter types.
1565    *    For example, if the parameter type is <code>CharSequence</code>, then <code>String</code> will match but
1566    *    <code>Object</code> will not.
1567    * @return The matched method, or <jk>null</jk> if no match was found.
1568    */
1569   public static Method findPublicMethod(Class<?> c, String name, Class<?> returnType, Class<?>...argTypes) {
1570      for (Method m : c.getMethods()) {
1571         if (isPublic(m) && hasName(m, name) && hasReturnTypeParent(m, returnType) && argsMatch(m.getParameterTypes(), argTypes))
1572            return m;
1573      }
1574      return null;
1575   }
1576
1577   /**
1578    * Finds a public constructor with the specified parameters without throwing an exception.
1579    *
1580    * @param c The class to search for a constructor.
1581    * @param fuzzyArgs
1582    *    Use fuzzy-arg matching.
1583    *    Find a constructor that best matches the specified args.
1584    * @param argTypes
1585    *    The argument types in the constructor.
1586    *    Can be subtypes of the actual constructor argument types.
1587    * @return The matching constructor, or <jk>null</jk> if constructor could not be found.
1588    */
1589   public static <T> Constructor<T> findPublicConstructor(Class<T> c, boolean fuzzyArgs, Class<?>...argTypes) {
1590      return findConstructor(c, Visibility.PUBLIC, fuzzyArgs, argTypes);
1591   }
1592
1593   /**
1594    * Finds a constructor with the specified parameters without throwing an exception.
1595    *
1596    * @param c The class to search for a constructor.
1597    * @param vis The minimum visibility.
1598    * @param fuzzyArgs
1599    *    Use fuzzy-arg matching.
1600    *    Find a constructor that best matches the specified args.
1601    * @param argTypes
1602    *    The argument types in the constructor.
1603    *    Can be subtypes of the actual constructor argument types.
1604    * @return The matching constructor, or <jk>null</jk> if constructor could not be found.
1605    */
1606   @SuppressWarnings("unchecked")
1607   public static <T> Constructor<T> findConstructor(Class<T> c, Visibility vis, boolean fuzzyArgs, Class<?>...argTypes) {
1608      ConstructorCacheEntry cce = CONSTRUCTOR_CACHE.get(c);
1609      if (cce != null && argsMatch(cce.paramTypes, argTypes) && cce.isVisible(vis))
1610         return (Constructor<T>)cce.constructor;
1611
1612      if (fuzzyArgs) {
1613         int bestCount = -1;
1614         Constructor<?> bestMatch = null;
1615         for (Constructor<?> n : c.getDeclaredConstructors()) {
1616            if (vis.isVisible(n)) {
1617               int m = fuzzyArgsMatch(n.getParameterTypes(), argTypes);
1618               if (m > bestCount) {
1619                  bestCount = m;
1620                  bestMatch = n;
1621               }
1622            }
1623         }
1624         if (bestCount >= 0)
1625            CONSTRUCTOR_CACHE.put(c, new ConstructorCacheEntry(c, bestMatch));
1626         return (Constructor<T>)bestMatch;
1627      }
1628
1629      final boolean isMemberClass = c.isMemberClass() && ! isStatic(c);
1630      for (Constructor<?> n : c.getConstructors()) {
1631         Class<?>[] paramTypes = n.getParameterTypes();
1632         if (isMemberClass)
1633            paramTypes = Arrays.copyOfRange(paramTypes, 1, paramTypes.length);
1634         if (argsMatch(paramTypes, argTypes) && vis.isVisible(n)) {
1635            CONSTRUCTOR_CACHE.put(c, new ConstructorCacheEntry(c, n));
1636            return (Constructor<T>)n;
1637         }
1638      }
1639
1640      return null;
1641   }
1642
1643
1644
1645   private static final class ConstructorCacheEntry {
1646      final Constructor<?> constructor;
1647      final Class<?>[] paramTypes;
1648
1649      ConstructorCacheEntry(Class<?> forClass, Constructor<?> constructor) {
1650         this.constructor = constructor;
1651         this.paramTypes = constructor.getParameterTypes();
1652      }
1653
1654      boolean isVisible(Visibility vis) {
1655         return vis.isVisible(constructor);
1656      }
1657   }
1658
1659   /**
1660    * Returns <jk>true</jk> if the specified argument types are valid for the specified parameter types.
1661    *
1662    * @param paramTypes The parameters types specified on a method.
1663    * @param argTypes The class types of the arguments being passed to the method.
1664    * @return <jk>true</jk> if the arguments match the parameters.
1665    */
1666   public static boolean argsMatch(Class<?>[] paramTypes, Class<?>[] argTypes) {
1667      if (paramTypes.length == argTypes.length) {
1668         for (int i = 0; i < paramTypes.length; i++)
1669            if (! isParentClass(paramTypes[i], argTypes[i]))
1670               return false;
1671         return true;
1672      }
1673      return false;
1674   }
1675
1676   /**
1677    * Returns a number representing the number of arguments that match the specified parameters.
1678    *
1679    * @param paramTypes The parameters types specified on a method.
1680    * @param argTypes The class types of the arguments being passed to the method.
1681    * @return The number of matching arguments, or <code>-1</code> a parameter was found that isn't in the list of args.
1682    */
1683   public static int fuzzyArgsMatch(Class<?>[] paramTypes, Class<?>... argTypes) {
1684      int matches = 0;
1685      outer: for (Class<?> p : paramTypes) {
1686         p = getWrapperIfPrimitive(p);
1687         for (Class<?> a : argTypes) {
1688            if (isParentClass(p, a)) {
1689               matches++;
1690               continue outer;
1691            }
1692         }
1693         return -1;
1694      }
1695      return matches;
1696   }
1697
1698   /**
1699    * Finds the public constructor that can take in the specified arguments.
1700    *
1701    * @param c The class we're trying to construct.
1702    * @param args The arguments we want to pass into the constructor.
1703    * @return
1704    *    The constructor, or <jk>null</jk> if a public constructor could not be found that takes in the specified
1705    *    arguments.
1706    */
1707   public static <T> Constructor<T> findPublicConstructor(Class<T> c, Object...args) {
1708      return findPublicConstructor(c, false, getClasses(args));
1709   }
1710
1711   /**
1712    * Finds the public constructor that can take in the specified arguments.
1713    *
1714    * @param c The class we're trying to construct.
1715    * @param args The argument types we want to pass into the constructor.
1716    * @return
1717    *    The constructor, or <jk>null</jk> if a public constructor could not be found that takes in the specified
1718    *    arguments.
1719    */
1720   public static <T> Constructor<T> findPublicConstructor(Class<T> c, Class<?>...args) {
1721      return findPublicConstructor(c, false, args);
1722   }
1723
1724   /**
1725    * Finds the public constructor that can take in the specified arguments.
1726    *
1727    * @param c The class we're trying to construct.
1728    * @param fuzzyArgs
1729    *    Use fuzzy-arg matching.
1730    *    Find a constructor that best matches the specified args.
1731    * @param args The arguments we want to pass into the constructor.
1732    * @return
1733    *    The constructor, or <jk>null</jk> if a public constructor could not be found that takes in the specified
1734    *    arguments.
1735    */
1736   public static <T> Constructor<T> findPublicConstructor(Class<T> c, boolean fuzzyArgs, Object...args) {
1737      return findPublicConstructor(c, fuzzyArgs, getClasses(args));
1738   }
1739
1740   /**
1741    * Returns the class types for the specified arguments.
1742    *
1743    * @param args The objects we're getting the classes of.
1744    * @return The classes of the arguments.
1745    */
1746   public static Class<?>[] getClasses(Object...args) {
1747      Class<?>[] pt = new Class<?>[args.length];
1748      for (int i = 0; i < args.length; i++)
1749         pt[i] = args[i] == null ? null : args[i].getClass();
1750      return pt;
1751   }
1752
1753   /**
1754    * Returns a {@link MethodInfo} bean that describes the specified method.
1755    *
1756    * @param m The method to describe.
1757    * @return The bean with information about the method.
1758    */
1759   public static MethodInfo getMethodInfo(Method m) {
1760      return new MethodInfo(m);
1761   }
1762
1763   /**
1764    * Returns {@link MethodInfo} beans that describe the specified methods.
1765    *
1766    * @param m The methods to describe.
1767    * @return The beans with information about the methods.
1768    */
1769   public static MethodInfo[] getMethodInfo(Collection<Method> m) {
1770      MethodInfo[] mi = new MethodInfo[m.size()];
1771      int i = 0;
1772      for (Method mm : m)
1773         mi[i++] = getMethodInfo(mm);
1774      return mi;
1775   }
1776
1777   /**
1778    * Simple bean that shows the name, parameter types, and return type of a method.
1779    */
1780   @SuppressWarnings("javadoc")
1781   public static class MethodInfo {
1782      public final String methodName;
1783      public final String[] parameterTypes;
1784      public final String returnType;
1785
1786      MethodInfo(Method m) {
1787         methodName = m.getName();
1788         Type[] pt = m.getGenericParameterTypes();
1789         parameterTypes = new String[pt.length];
1790         for (int i  = 0; i < pt.length; i++)
1791            parameterTypes[i] = BeanContext.DEFAULT.getClassMeta(pt[i]).toString();
1792         returnType = BeanContext.DEFAULT.getClassMeta(m.getGenericReturnType()).toString();
1793      }
1794   }
1795
1796   /**
1797    * Creates an instance of the specified class.
1798    *
1799    * @param c
1800    *    The class to cast to.
1801    * @param c2
1802    *    The class to instantiate.
1803    *    Can also be an instance of the class.
1804    * @return
1805    *    The new class instance, or <jk>null</jk> if the class was <jk>null</jk> or is abstract or an interface.
1806    * @throws
1807    *    RuntimeException if constructor could not be found or called.
1808    */
1809   public static <T> T newInstance(Class<T> c, Object c2) {
1810      return newInstanceFromOuter(null, c, c2, false);
1811   }
1812
1813   /**
1814    * Creates an instance of the specified class.
1815    *
1816    * @param c
1817    *    The class to cast to.
1818    * @param c2
1819    *    The class to instantiate.
1820    *    Can also be an instance of the class.
1821    * @param fuzzyArgs
1822    *    Use fuzzy constructor arg matching.
1823    *    <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
1824    *    <br>No-arg constructors are also used if no other constructors are found.
1825    * @param args
1826    *    The arguments to pass to the constructor.
1827    * @return
1828    *    The new class instance, or <jk>null</jk> if the class was <jk>null</jk> or is abstract or an interface.
1829    * @throws
1830    *    RuntimeException if constructor could not be found or called.
1831    */
1832   public static <T> T newInstance(Class<T> c, Object c2, boolean fuzzyArgs, Object...args) {
1833      return newInstanceFromOuter(null, c, c2, fuzzyArgs, args);
1834   }
1835
1836   /**
1837    * Creates an instance of the specified class from within the context of another object.
1838    *
1839    * @param outer
1840    *    The outer object.
1841    *    Can be <jk>null</jk>.
1842    * @param c
1843    *    The class to cast to.
1844    * @param c2
1845    *    The class to instantiate.
1846    *    Can also be an instance of the class.
1847    * @param fuzzyArgs
1848    *    Use fuzzy constructor arg matching.
1849    *    <br>When <jk>true</jk>, constructor args can be in any order and extra args are ignored.
1850    *    <br>No-arg constructors are also used if no other constructors are found.
1851    * @param args
1852    *    The arguments to pass to the constructor.
1853    * @return
1854    *    The new class instance, or <jk>null</jk> if the class was <jk>null</jk> or is abstract or an interface.
1855    * @throws
1856    *    RuntimeException if constructor could not be found or called.
1857    */
1858   @SuppressWarnings("unchecked")
1859   public static <T> T newInstanceFromOuter(Object outer, Class<T> c, Object c2, boolean fuzzyArgs, Object...args) {
1860      if (c2 == null)
1861         return null;
1862      if (c2 instanceof Class) {
1863         try {
1864            Class<?> c3 = (Class<?>)c2;
1865            if (c3.isInterface() || isAbstract(c3))
1866               return null;
1867
1868            // First look for an exact match.
1869            Constructor<?> con = findPublicConstructor(c3, false, args);
1870            if (con != null)
1871               return (T)con.newInstance(args);
1872
1873            // Next look for an exact match including the outer.
1874            if (outer != null) {
1875               args = new AList<>().append(outer).appendAll(args).toArray();
1876               con = findPublicConstructor(c3, false, args);
1877               if (con != null)
1878                  return (T)con.newInstance(args);
1879            }
1880
1881            // Finally use fuzzy matching.
1882            if (fuzzyArgs) {
1883               con = findPublicConstructor(c3, true, args);
1884               if (con != null)
1885                  return (T)con.newInstance(getMatchingArgs(con.getParameterTypes(), args));
1886            }
1887
1888            throw new FormattedRuntimeException("Could not instantiate class {0}/{1}.  Constructor not found.", c.getName(), c2);
1889         } catch (Exception e) {
1890            throw new FormattedRuntimeException(e, "Could not instantiate class {0}", c.getName());
1891         }
1892      } else if (isParentClass(c, c2.getClass())) {
1893         return (T)c2;
1894      } else {
1895         throw new FormattedRuntimeException("Object of type {0} found but was expecting {1}.", c2.getClass(), c.getClass());
1896      }
1897   }
1898
1899   /**
1900    * Matches arguments to a list of parameter types.
1901    *
1902    * <p>
1903    * Extra parameters are ignored.
1904    * <br>Missing parameters are left null.
1905    *
1906    * @param paramTypes The parameter types.
1907    * @param args The arguments to match to the parameter types.
1908    * @return
1909    *    An array of parameters.
1910    */
1911   public static Object[] getMatchingArgs(Class<?>[] paramTypes, Object... args) {
1912      Object[] params = new Object[paramTypes.length];
1913      for (int i = 0; i < paramTypes.length; i++) {
1914         Class<?> pt = getWrapperIfPrimitive(paramTypes[i]);
1915         for (int j = 0; j < args.length; j++) {
1916            if (isParentClass(pt, args[j].getClass())) {
1917               params[i] = args[j];
1918               break;
1919            }
1920         }
1921      }
1922      return params;
1923   }
1924
1925   /**
1926    * Returns all the fields in the specified class and all parent classes.
1927    *
1928    * <p>
1929    * Fields are ordered in either parent-to-child, or child-to-parent order, then alphabetically.
1930    *
1931    * @param c The class to get all fields on.
1932    * @param parentFirst Order them in parent-class-to-child-class order, otherwise child-class-to-parent-class order.
1933    * @return An iterable of all fields in the specified class.
1934    */
1935   @SuppressWarnings("rawtypes")
1936   public static Iterable<Field> getAllFields(final Class c, final boolean parentFirst) {
1937      return new Iterable<Field>() {
1938         @Override
1939         public Iterator<Field> iterator() {
1940            return new Iterator<Field>(){
1941               final Iterator<Class<?>> classIterator = getParentClasses(c, parentFirst, false);
1942               Field[] fields = classIterator.hasNext() ? sort(classIterator.next().getDeclaredFields()) : new Field[0];
1943               int fIndex = 0;
1944               Field next;
1945
1946               @Override
1947               public boolean hasNext() {
1948                  prime();
1949                  return next != null;
1950               }
1951
1952               private void prime() {
1953                  if (next == null) {
1954                     while (fIndex >= fields.length) {
1955                        if (classIterator.hasNext()) {
1956                           fields = sort(classIterator.next().getDeclaredFields());
1957                           fIndex = 0;
1958                        } else {
1959                           fIndex = -1;
1960                        }
1961                     }
1962                     if (fIndex != -1)
1963                        next = fields[fIndex++];
1964                  }
1965               }
1966
1967               @Override
1968               public Field next() {
1969                  prime();
1970                  Field f = next;
1971                  next = null;
1972                  return f;
1973               }
1974
1975               @Override
1976               public void remove() {
1977               }
1978            };
1979         }
1980      };
1981   }
1982
1983   /**
1984    * Returns all the methods in the specified class and all parent classes.
1985    *
1986    * <p>
1987    * Methods are ordered in either parent-to-child, or child-to-parent order, then alphabetically.
1988    *
1989    * @param c The class to get all methods on.
1990    * @param parentFirst Order them in parent-class-to-child-class order, otherwise child-class-to-parent-class order.
1991    * @return An iterable of all methods in the specified class.
1992    */
1993   @SuppressWarnings("rawtypes")
1994   public static Iterable<Method> getAllMethods(final Class c, final boolean parentFirst) {
1995      return new Iterable<Method>() {
1996         @Override
1997         public Iterator<Method> iterator() {
1998            return new Iterator<Method>(){
1999               final Iterator<Class<?>> classIterator = getParentClasses(c, parentFirst, true);
2000               Method[] methods = classIterator.hasNext() ? sort(classIterator.next().getDeclaredMethods()) : new Method[0];
2001               int mIndex = 0;
2002               Method next;
2003
2004               @Override
2005               public boolean hasNext() {
2006                  prime();
2007                  return next != null;
2008               }
2009
2010               private void prime() {
2011                  if (next == null) {
2012                     while (mIndex >= methods.length) {
2013                        if (classIterator.hasNext()) {
2014                           methods = sort(classIterator.next().getDeclaredMethods());
2015                           mIndex = 0;
2016                        } else {
2017                           mIndex = -1;
2018                        }
2019                     }
2020                     if (mIndex != -1)
2021                        next = methods[mIndex++];
2022                  }
2023               }
2024
2025               @Override
2026               public Method next() {
2027                  prime();
2028                  Method m = next;
2029                  next = null;
2030                  return m;
2031               }
2032
2033               @Override
2034               public void remove() {
2035               }
2036            };
2037         }
2038      };
2039   }
2040
2041   private static Comparator<Method> METHOD_COMPARATOR = new Comparator<Method>() {
2042
2043      @Override
2044      public int compare(Method o1, Method o2) {
2045         int i = o1.getName().compareTo(o2.getName());
2046         if (i == 0) {
2047            i = o1.getParameterTypes().length - o2.getParameterTypes().length;
2048            if (i == 0) {
2049               for (int j = 0; j < o1.getParameterTypes().length && i == 0; j++) {
2050                  i = o1.getParameterTypes()[j].getName().compareTo(o2.getParameterTypes()[j].getName());
2051               }
2052            }
2053         }
2054         return i;
2055      }
2056   };
2057
2058   /**
2059    * Sorts methods in alphabetical order.
2060    *
2061    * @param m The methods to sort.
2062    * @return The same array, but with elements sorted.
2063    */
2064   public static Method[] sort(Method[] m) {
2065      Arrays.sort(m, METHOD_COMPARATOR);
2066      return m;
2067   }
2068
2069   private static Comparator<Field> FIELD_COMPARATOR = new Comparator<Field>() {
2070
2071      @Override
2072      public int compare(Field o1, Field o2) {
2073         return o1.getName().compareTo(o2.getName());
2074      }
2075   };
2076
2077   /**
2078    * Sorts methods in alphabetical order.
2079    *
2080    * @param m The methods to sort.
2081    * @return The same array, but with elements sorted.
2082    */
2083   public static Field[] sort(Field[] m) {
2084      Arrays.sort(m, FIELD_COMPARATOR);
2085      return m;
2086   }
2087
2088   /**
2089    * Returns a list of all the parent classes of the specified class including the class itself.
2090    *
2091    * @param c The class to retrieve the parent classes.
2092    * @param parentFirst In parent-to-child order, otherwise child-to-parent.
2093    * @param includeInterfaces Include interfaces.
2094    * @return An iterator of parent classes in the class hierarchy.
2095    */
2096   public static Iterator<Class<?>> getParentClasses(final Class<?> c, boolean parentFirst, boolean includeInterfaces) {
2097      List<Class<?>> l = getParentClasses(new ArrayList<Class<?>>(), c, parentFirst, includeInterfaces);
2098      return l.iterator();
2099   }
2100
2101   private static List<Class<?>> getParentClasses(List<Class<?>> l, Class<?> c, boolean parentFirst, boolean includeInterfaces) {
2102      if (parentFirst) {
2103         if (includeInterfaces)
2104            for (Class<?> i : c.getInterfaces())
2105               l.add(i);
2106         if (c.getSuperclass() != Object.class && c.getSuperclass() != null)
2107            getParentClasses(l, c.getSuperclass(), parentFirst, includeInterfaces);
2108         l.add(c);
2109      } else {
2110         l.add(c);
2111         if (c.getSuperclass() != Object.class && c.getSuperclass() != null)
2112            getParentClasses(l, c.getSuperclass(), parentFirst, includeInterfaces);
2113         if (includeInterfaces)
2114            for (Class<?> i : c.getInterfaces())
2115               l.add(i);
2116      }
2117      return l;
2118   }
2119
2120   /**
2121    * Returns the default value for the specified primitive class.
2122    *
2123    * @param primitiveClass The primitive class to get the default value for.
2124    * @return The default value, or <jk>null</jk> if the specified class is not a primitive class.
2125    */
2126   public static Object getPrimitiveDefault(Class<?> primitiveClass) {
2127      return primitiveDefaultMap.get(primitiveClass);
2128   }
2129
2130   private static final Map<Class<?>,Object> primitiveDefaultMap = Collections.unmodifiableMap(
2131      new AMap<Class<?>,Object>()
2132         .append(Boolean.TYPE, false)
2133         .append(Character.TYPE, (char)0)
2134         .append(Short.TYPE, (short)0)
2135         .append(Integer.TYPE, 0)
2136         .append(Long.TYPE, 0l)
2137         .append(Float.TYPE, 0f)
2138         .append(Double.TYPE, 0d)
2139         .append(Byte.TYPE, (byte)0)
2140         .append(Boolean.class, false)
2141         .append(Character.class, (char)0)
2142         .append(Short.class, (short)0)
2143         .append(Integer.class, 0)
2144         .append(Long.class, 0l)
2145         .append(Float.class, 0f)
2146         .append(Double.class, 0d)
2147         .append(Byte.class, (byte)0)
2148   );
2149
2150   /**
2151    * Returns a readable representation of the specified method.
2152    *
2153    * <p>
2154    * The format of the string is <js>"full-qualified-class.method-name(parameter-simple-class-names)"</js>.
2155    *
2156    * @param m The method to stringify.
2157    * @return The stringified method.
2158    */
2159   public static String toString(Method m) {
2160      StringBuilder sb = new StringBuilder(m.getDeclaringClass().getName() + "." + m.getName() + "(");
2161      for (int i = 0; i < m.getParameterTypes().length; i++) {
2162         if (i > 0)
2163            sb.append(",");
2164         sb.append(m.getParameterTypes()[i].getSimpleName());
2165      }
2166      sb.append(")");
2167      return sb.toString();
2168   }
2169
2170   /**
2171    * Returns a readable representation of the specified field.
2172    *
2173    * <p>
2174    * The format of the string is <js>"full-qualified-class.field-name"</js>.
2175    *
2176    * @param f The field to stringify.
2177    * @return The stringified field.
2178    */
2179   public static String toString(Field f) {
2180      return f.getDeclaringClass().getName() + "." + f.getName();
2181   }
2182
2183   /**
2184    * Throws an {@link IllegalArgumentException} if the parameters on the method are not in the specified list provided.
2185    *
2186    * @param m The method to test.
2187    * @param args The valid class types (exact) for the arguments.
2188    * @throws FormattedIllegalArgumentException If any of the parameters on the method weren't in the list.
2189    */
2190   public static void assertArgsOfType(Method m, Class<?>...args) throws FormattedIllegalArgumentException {
2191      for (Class<?> c1 : m.getParameterTypes()) {
2192         boolean foundMatch = false;
2193         for (Class<?> c2 : args)
2194            if (c1 == c2)
2195               foundMatch = true;
2196         if (! foundMatch)
2197            throw new FormattedIllegalArgumentException("Invalid argument of type {0} passed in method {1}.  Only arguments of type {2} are allowed.", c1, m, args);
2198      }
2199   }
2200
2201   /**
2202    * Finds the public static "fromString" method on the specified class.
2203    *
2204    * <p>
2205    * Looks for the following method names:
2206    * <ul>
2207    *    <li><code>fromString</code>
2208    *    <li><code>fromValue</code>
2209    *    <li><code>valueOf</code>
2210    *    <li><code>parse</code>
2211    *    <li><code>parseString</code>
2212    *    <li><code>forName</code>
2213    *    <li><code>forString</code>
2214    * </ul>
2215    *
2216    * @param c The class to find the method on.
2217    * @return The static method, or <jk>null</jk> if it couldn't be found.
2218    */
2219   public static Method findPublicFromStringMethod(Class<?> c) {
2220      for (String methodName : new String[]{"create","fromString","fromValue","valueOf","parse","parseString","forName","forString"})
2221         for (Method m : c.getMethods())
2222            if (isAll(m, STATIC, PUBLIC, NOT_DEPRECATED) && hasName(m, methodName) && hasReturnType(m, c) && hasArgs(m, String.class))
2223               return m;
2224      return null;
2225   }
2226
2227   /**
2228    * Find the public static creator method on the specified class.
2229    *
2230    * @param oc The created type.
2231    * @param ic The argument type.
2232    * @param name The method name.
2233    * @return The static method, or <jk>null</jk> if it couldn't be found.
2234    */
2235   public static Method findPublicStaticCreateMethod(Class<?> oc, Class<?> ic, String name) {
2236      for (Method m : oc.getMethods())
2237         if (isAll(m, STATIC, PUBLIC, NOT_DEPRECATED) && hasName(m, name) && hasReturnType(m, oc) && hasArgs(m, ic))
2238            return m;
2239      return null;
2240   }
2241
2242   /**
2243    * Constructs a new instance of the specified class from the specified string.
2244    *
2245    * <p>
2246    * Class must be one of the following:
2247    * <ul>
2248    *    <li>Have a public constructor that takes in a single <code>String</code> argument.
2249    *    <li>Have a static <code>fromString(String)</code> (or related) method.
2250    *       <br>See {@link #findPublicFromStringMethod(Class)} for the list of possible static method names.
2251    *    <li>Be an <code>enum</code>.
2252    * </ul>
2253    *
2254    * @param c The class.
2255    * @param s The string to create the instance from.
2256    * @return A new object instance, or <jk>null</jk> if a method for converting the string to an object could not be found.
2257    */
2258   public static <T> T fromString(Class<T> c, String s) {
2259      Transform<String,T> t = TransformCache.get(String.class, c);
2260      return t == null ? null : t.transform(s);
2261   }
2262
2263   /**
2264    * Converts an object to a string.
2265    *
2266    * <p>
2267    * Normally, this is just going to call <code>toString()</code> on the object.
2268    * However, the {@link Locale} and {@link TimeZone} objects are treated special so that the returned value
2269    * works with the {@link #fromString(Class, String)} method.
2270    *
2271    * @param o The object to convert to a string.
2272    * @return The stringified object, or <jk>null</jk> if the object was <jk>null</jk>.
2273    */
2274   @SuppressWarnings({ "unchecked" })
2275   public static String toString(Object o) {
2276      if (o == null)
2277         return null;
2278      Transform<Object,String> t = (Transform<Object,String>)TransformCache.get(o.getClass(), String.class);
2279      return t == null ? o.toString() : t.transform(o);
2280   }
2281
2282   /**
2283    * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions.
2284    *
2285    * @param x The constructor.
2286    * @param ignoreExceptions Ignore {@link SecurityException SecurityExceptions} and just return <jk>false</jk> if thrown.
2287    * @return <jk>true</jk> if call was successful.
2288    */
2289   public static boolean setAccessible(Constructor<?> x, boolean ignoreExceptions) {
2290      try {
2291         if (! (x == null || x.isAccessible()))
2292            x.setAccessible(true);
2293         return true;
2294      } catch (SecurityException e) {
2295         if (ignoreExceptions)
2296            return false;
2297         throw new ClassMetaRuntimeException("Could not set accessibility to true on constructor ''{0}''", x);
2298      }
2299   }
2300
2301   /**
2302    * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions.
2303    *
2304    * @param x The method.
2305    * @param ignoreExceptions Ignore {@link SecurityException SecurityExceptions} and just return <jk>false</jk> if thrown.
2306    * @return <jk>true</jk> if call was successful.
2307    */
2308   public static boolean setAccessible(Method x, boolean ignoreExceptions) {
2309      try {
2310         if (! (x == null || x.isAccessible()))
2311            x.setAccessible(true);
2312         return true;
2313      } catch (SecurityException e) {
2314         if (ignoreExceptions)
2315            return false;
2316         throw new ClassMetaRuntimeException("Could not set accessibility to true on method ''{0}''", x);
2317      }
2318   }
2319
2320   /**
2321    * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions.
2322    *
2323    * @param x The field.
2324    * @param ignoreExceptions Ignore {@link SecurityException SecurityExceptions} and just return <jk>false</jk> if thrown.
2325    * @return <jk>true</jk> if call was successful.
2326    */
2327   public static boolean setAccessible(Field x, boolean ignoreExceptions) {
2328      try {
2329         if (! (x == null || x.isAccessible()))
2330            x.setAccessible(true);
2331         return true;
2332      } catch (SecurityException e) {
2333         if (ignoreExceptions)
2334            return false;
2335         throw new ClassMetaRuntimeException("Could not set accessibility to true on field ''{0}''", x);
2336      }
2337   }
2338
2339   /**
2340    * Returns the simple name of a class.
2341    *
2342    * <p>
2343    * Similar to {@link Class#getSimpleName()}, but includes the simple name of an enclosing or declaring class.
2344    *
2345    * @param c The class to get the simple name on.
2346    * @return The simple name of a class.
2347    */
2348   public static String getSimpleName(Class<?> c) {
2349      if (c.isLocalClass())
2350         return getSimpleName(c.getEnclosingClass()) + '.' + c.getSimpleName();
2351      if (c.isMemberClass())
2352         return getSimpleName(c.getDeclaringClass()) + '.' + c.getSimpleName();
2353      return c.getSimpleName();
2354   }
2355
2356   /**
2357    * Returns the simple name of a class.
2358    *
2359    * <p>
2360    * Similar to {@link Class#getSimpleName()}, but includes the simple name of an enclosing or declaring class.
2361    *
2362    * @param t The class to get the simple name on.
2363    * @return The simple name of a class.
2364    */
2365   public static String getSimpleName(Type t) {
2366      if (t instanceof Class)
2367         return getSimpleName((Class<?>)t);
2368      if (t instanceof ParameterizedType) {
2369         StringBuilder sb = new StringBuilder();
2370         ParameterizedType pt = (ParameterizedType)t;
2371         sb.append(getSimpleName(pt.getRawType()));
2372         sb.append("<");
2373         boolean first = true;
2374         for (Type t2 : pt.getActualTypeArguments()) {
2375            if (! first)
2376               sb.append(',');
2377            first = false;
2378            sb.append(getSimpleName(t2));
2379         }
2380         sb.append(">");
2381         return sb.toString();
2382      }
2383      return null;
2384   }
2385
2386   /**
2387    * Returns <jk>true</jk> if the {@link #getAnnotation(Class, Method, int)} returns a value.
2388    *
2389    * @param a The annotation to check for.
2390    * @param m The method containing the parameter to check.
2391    * @param index The parameter index.
2392    * @return <jk>true</jk> if the {@link #getAnnotation(Class, Method, int)} returns a value.
2393    */
2394   public static boolean hasAnnotation(Class<? extends Annotation> a, Method m, int index) {
2395      return getAnnotation(a, m, index) != null;
2396   }
2397
2398   /**
2399    * Returns <jk>true</jk> if the {@link #getAnnotation(Class, Method)} returns a value.
2400    *
2401    * @param a The annotation to check for.
2402    * @param m The method to check.
2403    * @return <jk>true</jk> if the {@link #getAnnotation(Class, Method)} returns a value.
2404    */
2405   public static boolean hasAnnotation(Class<? extends Annotation> a, Method m) {
2406      return getAnnotation(a, m) != null;
2407   }
2408
2409   /**
2410    * Returns <jk>true</jk> if the {@link #getAnnotation(Class, Type)} returns a value.
2411    *
2412    * @param a The annotation to check for.
2413    * @param t The class to check.
2414    * @return <jk>true</jk> if the {@link #getAnnotation(Class, Type)} returns a value.
2415    */
2416   public static boolean hasAnnotation(Class<? extends Annotation> a, Type t) {
2417      return getAnnotation(a, t) != null;
2418   }
2419
2420   /**
2421    * Similar to {@link Class#getAnnotation(Class)} except also searches annotations on interfaces.
2422    *
2423    * @param <T> The annotation class type.
2424    * @param a The annotation class.
2425    * @param t The annotated class.
2426    * @return The annotation, or <jk>null</jk> if not found.
2427    */
2428   public static <T extends Annotation> T getAnnotation(Class<T> a, Type t) {
2429      Class<?> c = toClass(t);
2430      if (c != null) {
2431         T t2 = getDeclaredAnnotation(a, c);
2432         if (t2 != null)
2433            return t2;
2434
2435         t2 = getAnnotation(a, c.getSuperclass());
2436         if (t2 != null)
2437            return t2;
2438
2439         for (Class<?> c2 : c.getInterfaces()) {
2440            t2 = getAnnotation(a, c2);
2441            if (t2 != null)
2442               return t2;
2443         }
2444      }
2445      return null;
2446   }
2447
2448   /**
2449    * Returns the specified annotation only if it's been declared on the specified class.
2450    *
2451    * <p>
2452    * More efficient than calling {@link Class#getAnnotation(Class)} since it doesn't recursively look for the class
2453    * up the parent chain.
2454    *
2455    * @param <T> The annotation class type.
2456    * @param a The annotation class.
2457    * @param t The annotated class.
2458    * @return The annotation, or <jk>null</jk> if not found.
2459    */
2460   @SuppressWarnings("unchecked")
2461   public static <T extends Annotation> T getDeclaredAnnotation(Class<T> a, Type t) {
2462      Class<?> c = toClass(t);
2463      if (c != null)
2464         for (Annotation a2 : c.getDeclaredAnnotations())
2465            if (a2.annotationType() == a)
2466               return (T)a2;
2467      return null;
2468   }
2469
2470   /**
2471    * Returns all instances of the specified annotation on the specified class.
2472    *
2473    * <p>
2474    * Searches all superclasses and superinterfaces.
2475    * Results are ordered child-to-parent.
2476    *
2477    * @param <T> The annotation class type.
2478    * @param a The annotation class type.
2479    * @param t The class being searched.
2480    * @return The found matches, or an empty array if annotation was not found.
2481    */
2482   public static <T extends Annotation> List<T> getAnnotations(Class<T> a, Type t) {
2483      List<T> l = new LinkedList<>();
2484      appendAnnotations(a, t, l);
2485      return l;
2486   }
2487
2488   /**
2489    * Same as {@link #getAnnotations(Class, Type)} but returns the list in parent-to-child order.
2490    *
2491    * @param a The annotation class type.
2492    * @param t The class being searched.
2493    * @return The found matches, or an empty array if annotation was not found.
2494    */
2495   public static <T extends Annotation> List<T> getAnnotationsParentFirst(Class<T> a, Type t) {
2496      List<T> l = getAnnotations(a, t);
2497      Collections.reverse(l);
2498      return l;
2499   }
2500
2501   /**
2502    * Same as {@link #getAnnotations(Class, Type)} except returns the annotations as a map with the keys being the
2503    * class on which the annotation was found.
2504    *
2505    * <p>
2506    * Results are ordered child-to-parent.
2507    *
2508    * @param <T> The annotation class type.
2509    * @param a The annotation class type.
2510    * @param t The class being searched.
2511    * @return The found matches, or an empty map if annotation was not found.
2512    */
2513   public static <T extends Annotation> LinkedHashMap<Class<?>,T> getAnnotationsMap(Class<T> a, Type t) {
2514      LinkedHashMap<Class<?>,T> m = new LinkedHashMap<>();
2515      findAnnotationsMap(a, t, m);
2516      return m;
2517   }
2518
2519   /**
2520    * Same as {@link #getAnnotationsMap(Class, Type)} except returns results in parent-to-child order.
2521    *
2522    * @param <T> The annotation class type.
2523    * @param a The annotation class type.
2524    * @param t The class being searched.
2525    * @return The found matches, or an empty map if annotation was not found.
2526    */
2527   public static <T extends Annotation> LinkedHashMap<Class<?>,T> getAnnotationsMapParentFirst(Class<T> a, Type t) {
2528      return CollectionUtils.reverse(getAnnotationsMap(a, t));
2529   }
2530
2531   private static <T extends Annotation> void findAnnotationsMap(Class<T> a, Type t, Map<Class<?>,T> m) {
2532      Class<?> c = toClass(t);
2533      if (c != null) {
2534
2535         T t2 = getDeclaredAnnotation(a, c);
2536         if (t2 != null)
2537            m.put(c, t2);
2538
2539         findAnnotationsMap(a, c.getSuperclass(), m);
2540
2541         for (Class<?> c2 : c.getInterfaces())
2542            findAnnotationsMap(a, c2, m);
2543      }
2544   }
2545
2546   /**
2547    * Finds and appends the specified annotation on the specified class and superclasses/interfaces to the specified
2548    * list.
2549    *
2550    * @param a The annotation.
2551    * @param t The class.
2552    * @param l The list of annotations.
2553    */
2554   public static <T extends Annotation> void appendAnnotations(Class<T> a, Type t, List<T> l) {
2555      Class<?> c = toClass(t);
2556      if (c != null) {
2557         addIfNotNull(l, getDeclaredAnnotation(a, c));
2558
2559         if (c.getPackage() != null)
2560            addIfNotNull(l, c.getPackage().getAnnotation(a));
2561
2562         appendAnnotations(a, c.getSuperclass(), l);
2563
2564         for (Class<?> c2 : c.getInterfaces())
2565            appendAnnotations(a, c2, l);
2566      }
2567   }
2568
2569   /**
2570    * Returns the specified type as a <code>Class</code>.
2571    *
2572    * <p>
2573    * If it's already a <code>Class</code>, it just does a cast.
2574    * <br>If it's a <code>ParameterizedType</code>, it returns the raw type.
2575    *
2576    * @param t The type to convert.
2577    * @return The type converted to a <code>Class</code>, or <jk>null</jk> if it could not be converted.
2578    */
2579   public static Class<?> toClass(Type t) {
2580      if (t instanceof Class)
2581         return (Class<?>)t;
2582      if (t instanceof ParameterizedType) {
2583         ParameterizedType pt = (ParameterizedType)t;
2584         // The raw type should always be a class (right?)
2585         return (Class<?>)pt.getRawType();
2586      }
2587      return null;
2588   }
2589
2590   /**
2591    * Similar to {@link Class#getResourceAsStream(String)} except looks up the parent hierarchy for the existence of
2592    * the specified resource.
2593    *
2594    * @param c The class to return the resource on.
2595    * @param name The resource name.
2596    * @return An input stream on the specified resource, or <jk>null</jk> if the resource could not be found.
2597    */
2598   public static InputStream getResource(Class<?> c, String name) {
2599      if (name == null)
2600         return null;
2601      while (c != null) {
2602         InputStream is = c.getResourceAsStream(name);
2603         if (is != null)
2604            return is;
2605         c = c.getSuperclass();
2606      }
2607      return null;
2608   }
2609}