1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  *
   8  *   - Redistributions of source code must retain the above copyright
   9  *     notice, this list of conditions and the following disclaimer.
  10  *
  11  *   - Redistributions in binary form must reproduce the above copyright
  12  *     notice, this list of conditions and the following disclaimer in the
  13  *     documentation and/or other materials provided with the distribution.
  14  *
  15  *   - Neither the name of Oracle nor the names of its
  16  *     contributors may be used to endorse or promote products derived
  17  *     from this software without specific prior written permission.
  18  *
  19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30  */
  31 
  32 import java.lang.annotation.Annotation;
  33 import javax.annotation.processing.SupportedSourceVersion;
  34 import javax.lang.model.element.*;
  35 import javax.lang.model.element.Modifier;
  36 import javax.lang.model.type.*;
  37 import javax.lang.model.util.*;
  38 import java.lang.reflect.*;
  39 import java.io.Writer;
  40 import java.util.*;
  41 
  42 import static javax.lang.model.SourceVersion.RELEASE_8;
  43 import static java.util.Objects.*;
  44 
  45 /**
  46  * This class provides a proof-of-concept implementation of the {@code
  47  * javax.lang.model.*} API backed by core reflection. That is, rather
  48  * than having a source file or compile-time class file as the
  49  * originator of the information about an element or type, as done
  50  * during standard annotation processing, runtime core reflection
  51  * objects serve that purpose instead.
  52  *
  53  * With this kind of implementation, the same logic can be used for
  54  * both compile-time and runtime processing of annotations.
  55  *
  56  * The nested types in this class define a specialization of {@code
  57  * javax.lang.model.*} to provide some additional functionality and
  58  * type information. The original {@code javax.lang.model.*} API was
  59  * designed to accommodate such a specialization by using wildcards in
  60  * the return types of methods.
  61  *
  62  * It would be technically possible for further specializations of the
  63  * API implemented in this class to define alternative semantics of
  64  * annotation look-up. For example to allow one annotation to have the
  65  * effect of macro-expanding into a set of other annotations.
  66  *
  67  * Some aspects of the implementation are left as "exercises for the
  68  * reader" to complete if interested.
  69  *
  70  * When passed null pointers, the methods defined in this type will
  71  * generally throw null pointer exceptions.
  72  *
  73  * To get started, first compile this file with a command line like:
  74  *
  75  * <pre>
  76  * $JDK/bin/javac -parameters -Xdoclint:all/public -Xlint:all -d $OUTPUT_DIR CoreReflectionFactory.java
  77  * </pre>
  78  *
  79  * and then run the main method of {@code CoreReflectionFactory},
  80  * which will print out a representation of {@code
  81  * CoreReflectionFactory}. To use the printing logic defined in {@code
  82  * javac}, put {@code tools.jar} on the classpath as in:
  83  *
  84  * <pre>
  85  * $JDK/bin/java -cp $OUTPUT_DIR:$JDK_ROOT/lib/tools.jar CoreReflectionFactory
  86  * </pre>
  87  *
  88  * @author Joseph D. Darcy (darcy)
  89  * @author Joel Borggren-Franck (jfranck)
  90  */
  91 public class CoreReflectionFactory {
  92     private CoreReflectionFactory() {
  93         throw new AssertionError("No instances of CoreReflectionFactory for you!");
  94     }
  95 
  96     /**
  97      * Returns a reflection type element mirroring a {@code Class} object.
  98      * @return a reflection type element mirroring a {@code Class} object
  99      * @param clazz the {@code Class} to mirror
 100      */
 101     public static ReflectionTypeElement createMirror(Class<?> clazz) {
 102         return new CoreReflTypeElement(Objects.requireNonNull(clazz));
 103     }
 104 
 105     /**
 106      * Returns a reflection package element mirroring a {@code Package} object.
 107      * @return a reflection package element mirroring a {@code Package} object
 108      * @param pkg the {@code Package} to mirror
 109      */
 110     public static ReflectionPackageElement createMirror(Package pkg) {
 111         // Treat a null pkg to mean an unnamed package.
 112         return new CoreReflPackageElement(pkg);
 113     }
 114 
 115     /**
 116      * Returns a reflection variable element mirroring a {@code Field} object.
 117      * @return a reflection variable element mirroring a {@code Field} object
 118      * @param field the {@code Field} to mirror
 119      */
 120     public static ReflectionVariableElement createMirror(Field field) {
 121         return new CoreReflFieldVariableElement(Objects.requireNonNull(field));
 122     }
 123 
 124     /**
 125      * Returns a reflection executable element mirroring a {@code Method} object.
 126      * @return a reflection executable element mirroring a {@code Method} object
 127      * @param method the {@code Method} to mirror
 128      */
 129     public static ReflectionExecutableElement createMirror(Method method)  {
 130         return new CoreReflMethodExecutableElement(Objects.requireNonNull(method));
 131     }
 132 
 133     /**
 134      * Returns a reflection executable element mirroring a {@code Constructor} object.
 135      * @return a reflection executable element mirroring a {@code Constructor} object
 136      * @param constructor the {@code Constructor} to mirror
 137      */
 138     public static ReflectionExecutableElement createMirror(Constructor<?> constructor)  {
 139         return new CoreReflConstructorExecutableElement(Objects.requireNonNull(constructor));
 140     }
 141 
 142     /**
 143      * Returns a type parameter element mirroring a {@code TypeVariable} object.
 144      * @return a type parameter element mirroring a {@code TypeVariable} object
 145      * @param tv the {@code TypeVariable} to mirror
 146      */
 147     public static TypeParameterElement createMirror(java.lang.reflect.TypeVariable<?> tv) {
 148         return new CoreReflTypeParameterElement(Objects.requireNonNull(tv));
 149     }
 150 
 151     /**
 152      * Returns a variable element mirroring a {@code Parameter} object.
 153      * @return a variable element mirroring a {@code Parameter} object
 154      * @param p the {Parameter} to mirror
 155      */
 156     public static VariableElement createMirror(java.lang.reflect.Parameter p) {
 157         return new CoreReflParameterVariableElement(Objects.requireNonNull(p));
 158     }
 159 
 160     /**
 161      * Returns an annotation mirror mirroring an annotation object.
 162      * @return an annotation mirror mirroring an annotation object
 163      * @param annotation the annotation to mirror
 164      */
 165     public static AnnotationMirror createMirror(Annotation annotation)  {
 166         return new CoreReflAnnotationMirror(Objects.requireNonNull(annotation));
 167     }
 168 
 169     /**
 170      * Returns a {@code Types} utility object for type objects backed by core reflection.
 171      * @return a {@code Types} utility object for type objects backed by core reflection
 172      */
 173     public static Types getTypes() {
 174         return CoreReflTypes.instance();
 175     }
 176 
 177     /**
 178      * Returns an {@code Elements} utility object for type objects backed by core reflection.
 179      * @return an {@code Elements} utility object for type objects backed by core reflection
 180      */
 181     public static Elements getElements() {
 182         return CoreReflElements.instance();
 183     }
 184 
 185     // Helper
 186     private static TypeMirror createTypeMirror(Class<?> c) {
 187         return TypeFactory.instance(Objects.requireNonNull(c));
 188     }
 189 
 190     /**
 191      * Main method; prints out a representation of this class.
 192      * @param args command-line arguments, currently ignored
 193      */
 194     public static void main(String... args) {
 195         getElements().printElements(new java.io.PrintWriter(System.out),
 196                                     createMirror(CoreReflectionFactory.class));
 197     }
 198 
 199     /**
 200      * A specialization of {@code javax.lang.model.element.Element} that is
 201      * backed by core reflection.
 202      */
 203     public static interface ReflectionElement
 204         extends Element, AnnotatedElement {
 205 
 206         /**
 207          * {@inheritDoc}
 208          */
 209         @Override
 210         ReflectionElement getEnclosingElement();
 211 
 212         /**
 213          * {@inheritDoc}
 214          */
 215         @Override
 216         List<ReflectionElement> getEnclosedElements();
 217 
 218         /**
 219          * Applies a visitor to this element.
 220          *
 221          * @param v the visitor operating on this element
 222          * @param p additional parameter to the visitor
 223          * @param <R> the return type of the visitor's methods
 224          * @param <P> the type of the additional parameter to the visitor's methods
 225          * @return a visitor-specified result
 226          */
 227         <R,P> R accept(ReflectionElementVisitor<R,P> v, P p);
 228 
 229         // Functionality specific to the specialization
 230         /**
 231          * Returns the underlying core reflection source object, if applicable.
 232          * @return the underlying core reflection source object, if applicable
 233          */
 234         AnnotatedElement getSource();
 235 
 236         // Functionality from javax.lang.model.util.Elements
 237         /**
 238          * Returns the package of an element. The package of a package
 239          * is itself.
 240          * @return the package of an element
 241          */
 242         ReflectionPackageElement getPackage();
 243 
 244     }
 245 
 246     /**
 247      * A logical specialization of {@code
 248      * javax.lang.model.element.ElementVisitor} being backed by core
 249      * reflection.
 250      *
 251      * @param <R> the return type of this visitor's methods.
 252      * @param <P> the type of the additional parameter to this visitor's
 253      *            methods.
 254      */
 255     public static interface ReflectionElementVisitor<R, P> {
 256         /**
 257          * Visits an element.
 258          * @param e  the element to visit
 259          * @param p  a visitor-specified parameter
 260          * @return a visitor-specified result
 261          */
 262         R visit(ReflectionElement e, P p);
 263 
 264         /**
 265          * A convenience method equivalent to {@code v.visit(e, null)}.
 266          * @param e  the element to visit
 267          * @return a visitor-specified result
 268          */
 269         R visit(ReflectionElement e);
 270 
 271         /**
 272          * Visits a package element.
 273          * @param e  the element to visit
 274          * @param p  a visitor-specified parameter
 275          * @return a visitor-specified result
 276          */
 277         R visitPackage(ReflectionPackageElement e, P p);
 278 
 279         /**
 280          * Visits a type element.
 281          * @param e  the element to visit
 282          * @param p  a visitor-specified parameter
 283          * @return a visitor-specified result
 284          */
 285         R visitType(ReflectionTypeElement e, P p);
 286 
 287         /**
 288          * Visits a variable element.
 289          * @param e  the element to visit
 290          * @param p  a visitor-specified parameter
 291          * @return a visitor-specified result
 292          */
 293         R visitVariable(ReflectionVariableElement e, P p);
 294 
 295         /**
 296          * Visits an executable element.
 297          * @param e  the element to visit
 298          * @param p  a visitor-specified parameter
 299          * @return a visitor-specified result
 300          */
 301         R visitExecutable(ReflectionExecutableElement e, P p);
 302 
 303         /**
 304          * Visits a type parameter element.
 305          * @param e  the element to visit
 306          * @param p  a visitor-specified parameter
 307          * @return a visitor-specified result
 308          */
 309         R visitTypeParameter(ReflectionTypeParameterElement e, P p);
 310 
 311         /**
 312          * Visits an unknown kind of element.
 313          * This can occur if the language evolves and new kinds
 314          * of elements are added to the {@code Element} hierarchy.
 315          *
 316          * @param e  the element to visit
 317          * @param p  a visitor-specified parameter
 318          * @return a visitor-specified result
 319          * @throws UnknownElementException
 320          * a visitor implementation may optionally throw this exception
 321          */
 322         R visitUnknown(ReflectionElement e, P p);
 323     }
 324 
 325     /**
 326      * A specialization of {@code javax.lang.model.element.ExecutableElement} that is
 327      * backed by core reflection.
 328      */
 329     public static interface ReflectionExecutableElement
 330         extends ReflectionElement, ExecutableElement, ReflectionParameterizable {
 331 
 332         /**
 333          * {@inheritDoc}
 334          */
 335         @Override
 336         List<ReflectionTypeParameterElement> getTypeParameters();
 337 
 338         /**
 339          * {@inheritDoc}
 340          */
 341         @Override
 342         List<ReflectionVariableElement> getParameters();
 343 
 344         // Functionality specific to the specialization
 345         /**
 346          * Returns all parameters, including synthetic ones.
 347          * @return all parameters, including synthetic ones
 348          */
 349         List<ReflectionVariableElement> getAllParameters();
 350 
 351         /**
 352          * {@inheritDoc}
 353          */
 354         @Override
 355         Executable getSource();
 356 
 357         /**
 358          * Returns true if this executable is a synthetic construct; returns false otherwise.
 359          * @return true if this executable is a synthetic construct; returns false otherwise
 360          */
 361         boolean isSynthetic();
 362 
 363         /**
 364          * Returns true if this executable is a bridge method; returns false otherwise.
 365          * @return true if this executable is a bridge method; returns false otherwise
 366          */
 367         boolean isBridge();
 368     }
 369 
 370     /**
 371      * A specialization of {@code javax.lang.model.element.PackageElement} being
 372      * backed by core reflection.
 373      */
 374     public static interface ReflectionPackageElement
 375         extends ReflectionElement, PackageElement {
 376 
 377         // Functionality specific to the specialization
 378         /**
 379          * {@inheritDoc}
 380          */
 381         @Override
 382         Package getSource();
 383     }
 384 
 385     /**
 386      * A specialization of {@code javax.lang.model.element.TypeElement} that is
 387      * backed by core reflection.
 388      */
 389     public static interface ReflectionTypeElement
 390         extends ReflectionElement, TypeElement, ReflectionParameterizable {
 391 
 392         /**
 393          * {@inheritDoc}
 394          */
 395         @Override
 396         List<ReflectionTypeParameterElement> getTypeParameters();
 397 
 398         /**
 399          * {@inheritDoc}
 400          */
 401         @Override
 402         List<ReflectionElement> getEnclosedElements();
 403 
 404         // Methods specific to the specialization, but functionality
 405         // also present in javax.lang.model.util.Elements.
 406         /**
 407          * Returns all members of a type element, whether inherited or
 408          * declared directly. For a class the result also includes its
 409          * constructors, but not local or anonymous classes.
 410          * @return all members of the type
 411          */
 412         List<ReflectionElement> getAllMembers();
 413 
 414         /**
 415          * Returns the binary name of a type element.
 416          * @return the binary name of a type element
 417          */
 418         Name getBinaryName();
 419 
 420         // Functionality specific to the specialization
 421         /**
 422          * {@inheritDoc}
 423          */
 424         @Override
 425         Class<?> getSource();
 426     }
 427 
 428     /**
 429      * A specialization of {@code javax.lang.model.element.TypeParameterElement} being
 430      * backed by core reflection.
 431      */
 432     public static interface ReflectionTypeParameterElement
 433         extends ReflectionElement, TypeParameterElement {
 434 
 435         /**
 436          * {@inheritDoc}
 437          */
 438         @Override
 439         ReflectionElement getGenericElement();
 440 
 441         // Functionality specific to the specialization
 442 
 443         // Conceptually should have an override for getSource
 444         // returning GenericDeclaration, but GenericDeclaration
 445         // doesn't currently implement AnnotatedElement.
 446 //         /**
 447 //          * {@inheritDoc}
 448 //          */
 449 //         @Override
 450 //         java.lang.reflect.GenericDeclaration getSource();
 451     }
 452 
 453     /**
 454      * A specialization of {@code javax.lang.model.element.VariableElement} that is
 455      * backed by core reflection.
 456      */
 457     public static interface ReflectionVariableElement
 458         extends ReflectionElement, VariableElement {
 459 
 460         // Functionality specific to the specialization
 461         /**
 462          * Returns true if this variable is a synthetic construct; returns false otherwise.
 463          * @return true if this variable is a synthetic construct; returns false otherwise
 464          */
 465         boolean isSynthetic();
 466 
 467         /**
 468          * Returns true if this variable is implicitly declared in source code; returns false otherwise.
 469          * @return true if this variable is implicitly declared in source code; returns false otherwise
 470          */
 471         boolean isImplicit();
 472 
 473         // The VariableElement concept covers fields, variables, and
 474         // method and constructor parameters. Therefore, this
 475         // interface cannot define a more precise override of
 476         // getSource since those three concept have different core
 477         // reflection types with no supertype more precise than
 478         // AnnotatedElement.
 479     }
 480 
 481     /**
 482      * A specialization of {@code javax.lang.model.element.Parameterizable} being
 483      * backed by core reflection.
 484      */
 485     public static interface ReflectionParameterizable
 486         extends ReflectionElement, Parameterizable {
 487         @Override
 488         List<ReflectionTypeParameterElement> getTypeParameters();
 489     }
 490 
 491     /**
 492      * Base class for concrete visitors of elements backed by core reflection.
 493      */
 494     public static abstract class AbstractReflectionElementVisitor8<R, P>
 495         extends AbstractElementVisitor8<R, P>
 496         implements ReflectionElementVisitor<R, P> {
 497         protected AbstractReflectionElementVisitor8() {
 498             super();
 499         }
 500     }
 501 
 502     /**
 503      * Base class for simple visitors of elements that are backed by core reflection.
 504      */
 505     @SupportedSourceVersion(value=RELEASE_8)
 506     public static abstract class SimpleReflectionElementVisitor8<R, P>
 507         extends SimpleElementVisitor8<R, P>
 508         implements ReflectionElementVisitor<R, P> {
 509 
 510         protected SimpleReflectionElementVisitor8(){
 511             super();
 512         }
 513 
 514         protected SimpleReflectionElementVisitor8(R defaultValue) {
 515             super(defaultValue);
 516         }
 517 
 518         // Create manual "bridge methods" for now.
 519 
 520         @Override
 521         public final R visitPackage(PackageElement e, P p) {
 522             return visitPackage((ReflectionPackageElement) e , p);
 523         }
 524 
 525         @Override
 526         public final R visitType(TypeElement e, P p) {
 527             return visitType((ReflectionTypeElement) e , p);
 528         }
 529 
 530         @Override
 531         public final R visitVariable(VariableElement e, P p) {
 532             return visitVariable((ReflectionVariableElement) e , p);
 533         }
 534 
 535         @Override
 536         public final R visitExecutable(ExecutableElement e, P p) {
 537             return visitExecutable((ReflectionExecutableElement) e , p);
 538         }
 539 
 540         @Override
 541         public final R visitTypeParameter(TypeParameterElement e, P p) {
 542             return visitTypeParameter((ReflectionTypeParameterElement) e , p);
 543         }
 544     }
 545 
 546     /**
 547      * {@inheritDoc}
 548      */
 549     public static interface ReflectionElements  extends Elements {
 550         /**
 551          * Returns the innermost enclosing {@link ReflectionTypeElement}
 552          * of the {@link ReflectionElement} or {@code null} if the
 553          * supplied ReflectionElement is toplevel or represents a
 554          * Package.
 555          *
 556          * @param e the {@link ReflectionElement} whose innermost
 557          * enclosing {@link ReflectionTypeElement} is sought
 558          * @return the innermost enclosing {@link
 559          * ReflectionTypeElement} or @{code null} if the parameter
 560          * {@code e} is a toplevel element or a package
 561          */
 562         ReflectionTypeElement getEnclosingTypeElement(ReflectionElement e);
 563 
 564         /**
 565          * {@inheritDoc}
 566          */
 567         @Override
 568         List<? extends ReflectionElement> getAllMembers(TypeElement type);
 569 
 570         /**
 571          * {@inheritDoc}
 572          */
 573         @Override
 574         ReflectionPackageElement getPackageElement(CharSequence name);
 575 
 576         /**
 577          * {@inheritDoc}
 578          */
 579         @Override
 580         ReflectionPackageElement getPackageOf(Element type);
 581 
 582         /**
 583          * {@inheritDoc}
 584          */
 585         @Override
 586         ReflectionTypeElement getTypeElement(CharSequence name);
 587     }
 588 
 589     // ------------------------- Implementation classes ------------------------
 590 
 591     // Exercise for the reader: review the CoreReflElement class
 592     // hierarchy below with an eye toward exposing it as an extensible
 593     // API that could be subclassed to provide customized behavior,
 594     // such as alternate annotation lookup semantics.
 595 
 596     private static abstract class CoreReflElement
 597         implements ReflectionElement, AnnotatedElement {
 598         public abstract AnnotatedElement getSource();
 599 
 600         protected CoreReflElement() {
 601             super();
 602         }
 603 
 604         // ReflectionElement methods
 605         @Override
 606         public ReflectionPackageElement getPackage() {
 607             throw new UnsupportedOperationException();
 608         }
 609 
 610         @Override
 611         public TypeMirror asType() {
 612             throw new UnsupportedOperationException(getClass().toString());
 613         }
 614 
 615         @Override
 616         public List<? extends AnnotationMirror> getAnnotationMirrors() {
 617             Annotation[] annotations = getSource().getDeclaredAnnotations();
 618             int len = annotations.length;
 619 
 620             if (len > 0) {
 621                 List<AnnotationMirror> res = new ArrayList<>(len);
 622                 for (Annotation a : annotations) {
 623                     res.add(createMirror(a));
 624                 }
 625                 return Collections.unmodifiableList(res);
 626             } else {
 627                 return Collections.emptyList();
 628             }
 629         }
 630 
 631         @Override
 632         public Set<Modifier> getModifiers() {
 633             return ModifierUtil.instance(0, false);
 634         }
 635 
 636         @Override
 637         public abstract Name getSimpleName();
 638 
 639         @Override
 640         public abstract ReflectionElement getEnclosingElement();
 641 
 642         @Override
 643         public abstract List<ReflectionElement> getEnclosedElements();
 644 
 645         //AnnotatedElement methods
 646         @Override
 647         public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
 648             return getSource().getAnnotation(annotationClass);
 649         }
 650 
 651         @Override
 652         public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
 653             return getSource().getAnnotationsByType(annotationClass);
 654         }
 655 
 656         @Override
 657         public Annotation[] getAnnotations() {
 658             return getSource().getAnnotations();
 659         }
 660 
 661         @Override
 662         public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
 663             return getSource().getDeclaredAnnotation(annotationClass);
 664         }
 665 
 666         @Override
 667         public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
 668             return getSource().getDeclaredAnnotationsByType(annotationClass);
 669         }
 670 
 671         @Override
 672         public Annotation[] getDeclaredAnnotations() {
 673             return getSource().getDeclaredAnnotations();
 674         }
 675 
 676         // java.lang.Object methods
 677         @Override
 678         public boolean equals(Object obj) {
 679             if (obj instanceof CoreReflElement) {
 680                 CoreReflElement other = (CoreReflElement)obj;
 681                 return Objects.equals(other.getSource(), this.getSource());
 682             }
 683             return false;
 684         }
 685 
 686         @Override
 687         public int hashCode() {
 688             return Objects.hashCode(getSource());
 689         }
 690 
 691         @Override
 692         public String toString() {
 693             return getKind().toString() + " " + getSimpleName().toString();
 694         }
 695     }
 696 
 697     // Type
 698     private static class CoreReflTypeElement extends CoreReflElement
 699         implements ReflectionTypeElement {
 700         private final Class<?> source;
 701 
 702         protected CoreReflTypeElement(Class<?> source) {
 703             Objects.requireNonNull(source);
 704             if (source.isPrimitive() ||
 705                 source.isArray()) {
 706                 throw new IllegalArgumentException("Cannot create a ReflectionTypeElement based on class: " + source);
 707             }
 708 
 709             this.source = source;
 710         }
 711 
 712         @Override
 713         public TypeMirror asType() {
 714             return createTypeMirror(source);
 715         }
 716 
 717         @Override
 718         public Class<?> getSource() {
 719             return source;
 720         }
 721 
 722         @Override
 723         public boolean equals(Object o) {
 724             if (o instanceof CoreReflTypeElement) {
 725                 return source.equals(((CoreReflTypeElement)o).getSource());
 726             } else {
 727                 return false;
 728             }
 729         }
 730 
 731         @Override
 732         public <R,P> R accept(ElementVisitor<R,P> v, P p) {
 733             return v.visitType(this, p);
 734         }
 735 
 736         @Override
 737         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
 738             return v.visitType(this, p);
 739         }
 740 
 741         @Override
 742         public Set<Modifier> getModifiers() {
 743             return ModifierUtil.instance(source.getModifiers() &
 744                                          (source.isInterface() ?
 745                                           java.lang.reflect.Modifier.interfaceModifiers() :
 746                                           java.lang.reflect.Modifier.classModifiers()),
 747                                          false);
 748         }
 749 
 750         @Override
 751         public List<ReflectionElement> getEnclosedElements() {
 752             List<ReflectionElement> enclosedElements = new ArrayList<>();
 753 
 754             for (Class<?> declaredClass : source.getDeclaredClasses()) {
 755                 enclosedElements.add(createMirror(declaredClass));
 756             }
 757 
 758             // Add elements in the conventional ordering: fields, then
 759             // constructors, then methods.
 760             for (Field f : source.getDeclaredFields()) {
 761                 enclosedElements.add(createMirror(f));
 762             }
 763 
 764             for (Constructor<?> c : source.getDeclaredConstructors()) {
 765                 enclosedElements.add(createMirror(c));
 766             }
 767 
 768             for (Method m : source.getDeclaredMethods()) {
 769                 enclosedElements.add(createMirror(m));
 770             }
 771 
 772             return (enclosedElements.isEmpty() ?
 773                     Collections.emptyList():
 774                     Collections.unmodifiableList(enclosedElements));
 775         }
 776 
 777         // Review for default method handling.
 778         @Override
 779         public List<ReflectionElement> getAllMembers() {
 780             List<ReflectionElement> allMembers = new ArrayList<>();
 781 
 782             // If I only had a MultiMap ...
 783             List<ReflectionElement> fields = new ArrayList<>();
 784             List<ReflectionExecutableElement> methods = new ArrayList<>();
 785             List<ReflectionElement> classes = new ArrayList<>();
 786 
 787             // Add all fields for this class
 788             for (Field f : source.getDeclaredFields()) {
 789                 fields.add(createMirror(f));
 790             }
 791 
 792             // Add all methods for this class
 793             for (Method m : source.getDeclaredMethods()) {
 794                 methods.add(createMirror(m));
 795             }
 796 
 797             // Add all classes for this class, except anonymous/local as per Elements.getAllMembers doc
 798             for (Class<?> c : source.getDeclaredClasses()) {
 799                 if (c.isLocalClass() || c.isAnonymousClass())
 800                     continue;
 801                 classes.add(createMirror(c));
 802             }
 803 
 804             Class<?> cls = source;
 805             if (cls.isInterface()) {
 806                 cls = null;
 807             }
 808             do {
 809                 // Walk up superclasses adding non-private elements.
 810                 // If source is an interface, just add Object's
 811                 // elements.
 812 
 813                 if (cls == null) {
 814                     cls = java.lang.Object.class;
 815                 } else {
 816                     cls = cls.getSuperclass();
 817                 }
 818 
 819                 addMembers(cls, fields, methods, classes);
 820 
 821             } while (cls != java.lang.Object.class);
 822 
 823             // add members on (super)interface(s)
 824             Set<Class<?>> seenInterfaces = new HashSet<>();
 825             Queue<Class<?>> interfaces = new LinkedList<>();
 826             if (source.isInterface()) {
 827                 seenInterfaces.add(source);
 828                 interfaces.add(source);
 829             } else {
 830                 Class<?>[] ifaces = source.getInterfaces();
 831                 for (Class<?> iface : ifaces) {
 832                     seenInterfaces.add(iface);
 833                     interfaces.add(iface);
 834                 }
 835             }
 836 
 837             while (interfaces.peek() != null) {
 838                 Class<?> head = interfaces.remove();
 839                 addMembers(head, fields, methods, classes);
 840 
 841                 Class<?>[] ifaces = head.getInterfaces();
 842                 for (Class<?> iface : ifaces) {
 843                     if (!seenInterfaces.contains(iface)) {
 844                         seenInterfaces.add(iface);
 845                         interfaces.add(iface);
 846                     }
 847                 }
 848             }
 849 
 850             // Add constructors
 851             for (Constructor<?> c : source.getDeclaredConstructors()) {
 852                 allMembers.add(createMirror(c));
 853             }
 854 
 855             // Add all unique methods
 856             allMembers.addAll(methods);
 857 
 858             // Add all unique fields
 859             allMembers.addAll(fields);
 860 
 861             // Add all unique classes
 862             allMembers.addAll(classes);
 863 
 864             return Collections.unmodifiableList(allMembers);
 865         }
 866 
 867         private void addMembers(Class<?> cls,
 868                                 List<ReflectionElement> fields,
 869                                 List<ReflectionExecutableElement> methods,
 870                                 List<ReflectionElement> classes) {
 871             Elements elements = getElements();
 872 
 873             for (Field f : cls.getDeclaredFields()) {
 874                 if (java.lang.reflect.Modifier.isPrivate(f.getModifiers())) { continue; }
 875                 ReflectionElement tmp = createMirror(f);
 876                 boolean add = true;
 877                 for (ReflectionElement e : fields) {
 878                     if (elements.hides(e, tmp)) {
 879                         add = false;
 880                         break;
 881                     }
 882                 }
 883                 if (add) {
 884                     fields.add(tmp);
 885                 }
 886             }
 887 
 888             for (Method m : cls.getDeclaredMethods()) {
 889                 if (java.lang.reflect.Modifier.isPrivate(m.getModifiers()))
 890                     continue;
 891 
 892                 ReflectionExecutableElement tmp = createMirror(m);
 893                 boolean add = true;
 894                 for (ReflectionExecutableElement e : methods) {
 895                     if (elements.hides(e, tmp)) {
 896                         add = false;
 897                         break;
 898                     } else if (elements.overrides(e, tmp, this)) {
 899                         add = false;
 900                         break;
 901                     }
 902                 }
 903                 if (add) {
 904                     methods.add(tmp);
 905                 }
 906             }
 907 
 908             for (Class<?> c : cls.getDeclaredClasses()) {
 909                 if (java.lang.reflect.Modifier.isPrivate(c.getModifiers()) ||
 910                     c.isLocalClass() ||
 911                     c.isAnonymousClass())
 912                     continue;
 913 
 914                 ReflectionElement tmp = createMirror(c);
 915                 boolean add = true;
 916                 for (ReflectionElement e : classes) {
 917                     if (elements.hides(e, tmp)) {
 918                         add = false;
 919                         break;
 920                     }
 921                 }
 922                 if (add) {
 923                     classes.add(tmp);
 924                 }
 925             }
 926         }
 927 
 928         @Override
 929         public ElementKind getKind() {
 930             if (source.isInterface()) {
 931                 if (source.isAnnotation())
 932                     return ElementKind.ANNOTATION_TYPE;
 933                 else
 934                     return ElementKind.INTERFACE;
 935             } else if (source.isEnum()) {
 936                 return ElementKind.ENUM;
 937             } else
 938                 return ElementKind.CLASS;
 939         }
 940 
 941         @Override
 942         public NestingKind getNestingKind() {
 943             if (source.isAnonymousClass())
 944                 return NestingKind.ANONYMOUS;
 945             else if (source.isLocalClass())
 946                 return NestingKind.LOCAL;
 947             else if (source.isMemberClass())
 948                 return NestingKind.MEMBER;
 949             else return
 950                 NestingKind.TOP_LEVEL;
 951         }
 952 
 953         @Override
 954         public Name getQualifiedName() {
 955             String name = source.getCanonicalName(); // TODO, this should be a FQN for
 956                                                      // the current element
 957             if (name == null)
 958                 name = "";
 959             return StringName.instance(name);
 960         }
 961 
 962         @Override
 963         public Name getSimpleName() {
 964             return StringName.instance(source.getSimpleName());
 965         }
 966 
 967         @Override
 968         public TypeMirror getSuperclass() {
 969             if (source.equals(java.lang.Object.class)) {
 970                 return NoType.getNoneInstance();
 971             } else {
 972                 return createTypeMirror(source.getSuperclass());
 973             }
 974         }
 975 
 976         @Override
 977         public List<? extends TypeMirror> getInterfaces() {
 978             Class[] interfaces = source.getInterfaces();
 979             int len = interfaces.length;
 980             List<TypeMirror> res = new ArrayList<>(len);
 981 
 982             if (len > 0) {
 983                 for (Class<?> c : interfaces) {
 984                     res.add(createTypeMirror(c));
 985                 }
 986             } else {
 987                 return Collections.emptyList();
 988             }
 989             return Collections.unmodifiableList(res);
 990         }
 991 
 992         @Override
 993         public List<ReflectionTypeParameterElement> getTypeParameters() {
 994             return createTypeParameterList(source);
 995         }
 996 
 997         @Override
 998         public ReflectionElement getEnclosingElement() {
 999             // Returns the package of a top-level type and returns the
1000             // immediately lexically enclosing element for a nested type.
1001 
1002             switch(getNestingKind()) {
1003             case TOP_LEVEL:
1004                 return createMirror(source.getPackage());
1005             case MEMBER:
1006                 return createMirror(source.getEnclosingClass());
1007             default:
1008                 if (source.getEnclosingConstructor() != null) {
1009                     return createMirror(source.getEnclosingConstructor());
1010                 } else if (source.getEnclosingMethod() != null) {
1011                     return createMirror(source.getEnclosingMethod());
1012                 } else {
1013                     return createMirror(source.getEnclosingClass());
1014                 }
1015             }
1016         }
1017 
1018         @Override
1019         public Name getBinaryName() {
1020             return StringName.instance(getSource().getName());
1021         }
1022     }
1023 
1024     private static abstract class CoreReflExecutableElement extends CoreReflElement
1025         implements ReflectionExecutableElement {
1026 
1027         protected Executable source = null;
1028         protected final List<CoreReflParameterVariableElement> parameters;
1029 
1030         protected CoreReflExecutableElement(Executable source,
1031                                             List<CoreReflParameterVariableElement> parameters) {
1032             this.source = Objects.requireNonNull(source);
1033             this.parameters = Objects.requireNonNull(parameters);
1034         }
1035 
1036         @Override
1037         public <R,P> R accept(ElementVisitor<R,P> v, P p) {
1038             return v.visitExecutable(this, p);
1039         }
1040 
1041         @Override
1042         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
1043             return v.visitExecutable(this, p);
1044         }
1045 
1046         @Override
1047         public abstract ExecutableType asType();
1048 
1049         // Only Types and Packages enclose elements; see Element.getEnclosedElements()
1050         @Override
1051         public List<ReflectionElement> getEnclosedElements() {
1052             return Collections.emptyList();
1053         }
1054 
1055         @Override
1056         public List<ReflectionVariableElement> getParameters() {
1057             List<ReflectionVariableElement> tmp = new ArrayList<>();
1058             for (ReflectionVariableElement parameter : parameters) {
1059                 if (!parameter.isSynthetic())
1060                     tmp.add(parameter);
1061             }
1062             return tmp;
1063         }
1064 
1065         @Override
1066         public List<ReflectionVariableElement> getAllParameters() {
1067             // Could "fix" this if the return type included wildcards
1068             @SuppressWarnings("unchecked")
1069             List<ReflectionVariableElement> tmp = (List<ReflectionVariableElement>)(List)parameters;
1070             return tmp;
1071         }
1072 
1073         @Override
1074         public List<? extends TypeMirror> getThrownTypes() {
1075             Class<?>[] thrown = source.getExceptionTypes();
1076             int len = thrown.length;
1077             List<TypeMirror> res = new ArrayList<>(len);
1078 
1079             if (len > 0) {
1080                 for (Class<?> c : thrown) {
1081                     res.add(createTypeMirror(c));
1082                 }
1083             } else {
1084                 return Collections.emptyList();
1085             }
1086             return Collections.unmodifiableList(res);
1087         }
1088 
1089         @Override
1090         public boolean isVarArgs() {
1091             return source.isVarArgs();
1092         }
1093 
1094         @Override
1095         public boolean isSynthetic() {
1096             return source.isSynthetic();
1097         }
1098 
1099         @Override
1100         public boolean isBridge() {
1101             return false;
1102         }
1103 
1104         @Override
1105         public List<ReflectionTypeParameterElement> getTypeParameters() {
1106             return createTypeParameterList(source);
1107         }
1108 
1109         public abstract AnnotationValue getDefaultValue();
1110 
1111         @Override
1112         public TypeMirror getReceiverType() {
1113             // New in JDK 8
1114             throw new UnsupportedOperationException(this.toString());
1115         }
1116     }
1117 
1118     private static class CoreReflConstructorExecutableElement
1119         extends CoreReflExecutableElement {
1120 
1121         protected CoreReflConstructorExecutableElement(Constructor<?> source) {
1122             super(Objects.requireNonNull(source),
1123                   createParameterList(source));
1124         }
1125 
1126         @Override
1127         public  Constructor<?> getSource() {
1128             return (Constructor<?>)source;
1129         }
1130 
1131         @Override
1132         public TypeMirror getReturnType() {
1133             return NoType.getVoidInstance();
1134         }
1135 
1136         @Override
1137         public ExecutableType asType() {
1138             throw new UnsupportedOperationException(getClass().toString());
1139         }
1140 
1141         @Override
1142         public boolean equals(Object o) {
1143             if (o instanceof CoreReflConstructorExecutableElement) {
1144                 return source.equals(((CoreReflConstructorExecutableElement)o).getSource());
1145             } else {
1146                 return false;
1147             }
1148         }
1149 
1150         @Override
1151         public ElementKind getKind() {
1152             return ElementKind.CONSTRUCTOR;
1153         }
1154 
1155         @Override
1156         public Set<Modifier> getModifiers() {
1157             return ModifierUtil.instance(source.getModifiers() &
1158                                          java.lang.reflect.Modifier.constructorModifiers(), false);
1159         }
1160 
1161         @Override
1162         public ReflectionElement getEnclosingElement() {
1163             return createMirror(source.getDeclaringClass());
1164         }
1165 
1166         @Override
1167         public Name getSimpleName() {
1168             return StringName.instance("<init>");
1169         }
1170 
1171         @Override
1172         public AnnotationValue getDefaultValue() {
1173             // a constructor is never an annotation element
1174             return null;
1175         }
1176 
1177         @Override
1178         public boolean isDefault() {
1179             return false; // A constructor cannot be a default method
1180         }
1181     }
1182 
1183     private static class CoreReflMethodExecutableElement
1184         extends CoreReflExecutableElement {
1185 
1186         protected CoreReflMethodExecutableElement(Method source) {
1187             super(Objects.requireNonNull(source),
1188                   createParameterList(source));
1189             this.source = source;
1190         }
1191 
1192         @Override
1193         public Method getSource() {
1194             return (Method)source;
1195         }
1196 
1197         @Override
1198         public TypeMirror getReturnType() {
1199             return TypeFactory.instance(getSource().getReturnType());
1200         }
1201 
1202         @Override
1203         public boolean equals(Object o) {
1204             if (o instanceof CoreReflMethodExecutableElement) {
1205                 return source.equals( ((CoreReflMethodExecutableElement)o).getSource());
1206             } else {
1207                 return false;
1208             }
1209         }
1210 
1211         @Override
1212         public ElementKind getKind() {
1213             return ElementKind.METHOD;
1214         }
1215 
1216         @Override
1217         public Set<Modifier> getModifiers() {
1218             return ModifierUtil.instance(source.getModifiers() &
1219                                          java.lang.reflect.Modifier.methodModifiers(),
1220                                          isDefault());
1221         }
1222 
1223         @Override
1224         public ReflectionElement getEnclosingElement() {
1225             return createMirror(source.getDeclaringClass());
1226         }
1227 
1228         @Override
1229         public Name getSimpleName() {
1230             return StringName.instance(source.getName());
1231         }
1232 
1233         @Override
1234         public AnnotationValue getDefaultValue() {
1235             Object value = getSource().getDefaultValue();
1236             if (null == value) {
1237                 return null;
1238             } else {
1239                 return new CoreReflAnnotationValue(value);
1240             }
1241         }
1242 
1243         @Override
1244         public boolean isDefault() {
1245             return getSource().isDefault();
1246         }
1247 
1248         @Override
1249         public boolean isBridge() {
1250             return getSource().isBridge();
1251         }
1252 
1253         @Override
1254         public ExecutableType asType() {
1255             return TypeFactory.instance(getSource());
1256         }
1257     }
1258 
1259     private static List<CoreReflParameterVariableElement> createParameterList(Executable source) {
1260         Parameter[] parameters = source.getParameters();
1261         int length = parameters.length;
1262         if (length == 0)
1263             return Collections.emptyList();
1264         else {
1265             List<CoreReflParameterVariableElement> tmp = new ArrayList<>(length);
1266             for (Parameter parameter : parameters) {
1267                 tmp.add(new CoreReflParameterVariableElement(parameter));
1268             }
1269             return Collections.unmodifiableList(tmp);
1270         }
1271     }
1272 
1273     private static List<ReflectionTypeParameterElement> createTypeParameterList(GenericDeclaration source) {
1274         java.lang.reflect.TypeVariable<?>[] typeParams = source.getTypeParameters();
1275         int length = typeParams.length;
1276         if (length == 0)
1277             return Collections.emptyList();
1278         else {
1279             List<ReflectionTypeParameterElement> tmp = new ArrayList<>(length);
1280             for (java.lang.reflect.TypeVariable<?> typeVar : typeParams)
1281                 tmp.add(new CoreReflTypeParameterElement(typeVar));
1282             return Collections.unmodifiableList(tmp);
1283         }
1284     }
1285 
1286     private static class CoreReflTypeParameterElement
1287         extends CoreReflElement
1288         implements ReflectionTypeParameterElement {
1289 
1290         private final GenericDeclaration source;
1291         private final java.lang.reflect.TypeVariable<?> sourceTypeVar;
1292 
1293         protected CoreReflTypeParameterElement(java.lang.reflect.TypeVariable<?> sourceTypeVar) {
1294             this.sourceTypeVar = Objects.requireNonNull(sourceTypeVar);
1295             this.source = Objects.requireNonNull(sourceTypeVar.getGenericDeclaration());
1296         }
1297 
1298         @Override
1299         public AnnotatedElement getSource() {
1300             return (AnnotatedElement)source;
1301         }
1302 
1303         protected java.lang.reflect.TypeVariable<?> getSourceTypeVar() {
1304             return sourceTypeVar;
1305         }
1306 
1307         @Override
1308         public boolean equals(Object o) {
1309             if (o instanceof CoreReflTypeParameterElement) {
1310                 return sourceTypeVar.equals(((CoreReflTypeParameterElement)o).sourceTypeVar);
1311             } else {
1312                 return false;
1313             }
1314         }
1315 
1316         @Override
1317         public <R,P> R accept(ElementVisitor<R,P> v, P p) {
1318             return v.visitTypeParameter(this, p);
1319         }
1320 
1321         @Override
1322         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
1323             return v.visitTypeParameter(this, p);
1324         }
1325 
1326         @Override
1327         public List<ReflectionElement> getEnclosedElements() {
1328             return Collections.emptyList();
1329         }
1330 
1331         @Override
1332         public ReflectionElement getEnclosingElement() {
1333             if (source instanceof Class)
1334                 return createMirror((Class<?>)source);
1335             else if (source instanceof Method)
1336                 return createMirror((Method)source);
1337             else if (source instanceof Constructor)
1338                 return createMirror((Constructor<?>)source);
1339             else
1340                 throw new AssertionError("Unexpected enclosing element: " + source);
1341         }
1342 
1343         @Override
1344         public ElementKind getKind() {
1345             return ElementKind.TYPE_PARAMETER;
1346         }
1347 
1348         @Override
1349         public Name getSimpleName() {
1350             return StringName.instance(sourceTypeVar.getName());
1351         }
1352 
1353         // TypeParameterElement methods
1354         @Override
1355         public ReflectionElement getGenericElement() {
1356             return getEnclosingElement(); // As per the doc,
1357                                           // getEnclosingElement and
1358                                           // getGenericElement return
1359                                           // the same information.
1360         }
1361 
1362         @Override
1363         public List<? extends TypeMirror> getBounds() {
1364             Type[] types = getSourceTypeVar().getBounds();
1365             int len = types.length;
1366 
1367             if (len > 0) {
1368                 List<TypeMirror> res = new ArrayList<>(len);
1369                 for (Type t : types) {
1370                     res.add(TypeFactory.instance(t));
1371                 }
1372                 return Collections.unmodifiableList(res);
1373             } else {
1374                 return Collections.emptyList();
1375             }
1376         }
1377     }
1378 
1379     private abstract static class CoreReflVariableElement extends CoreReflElement
1380         implements ReflectionVariableElement {
1381 
1382         protected CoreReflVariableElement() {}
1383 
1384         // Element visitor
1385         @Override
1386         public <R,P> R accept(ElementVisitor<R,P>v, P p) {
1387             return v.visitVariable(this, p);
1388         }
1389 
1390         // ReflectElement visitor
1391         @Override
1392         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
1393             return v.visitVariable(this, p);
1394         }
1395 
1396         @Override
1397         public List<ReflectionElement> getEnclosedElements() {
1398             return Collections.emptyList();
1399         }
1400 
1401         @Override
1402         public ReflectionElement getEnclosingElement() {
1403             return null;
1404         }
1405 
1406         @Override
1407         public boolean isSynthetic() {
1408             return false;
1409         }
1410 
1411         @Override
1412         public boolean isImplicit() {
1413             return false;
1414         }
1415     }
1416 
1417     private static class CoreReflFieldVariableElement extends CoreReflVariableElement {
1418         private final Field source;
1419 
1420         protected CoreReflFieldVariableElement(Field source) {
1421             this.source = Objects.requireNonNull(source);
1422         }
1423 
1424         @Override
1425         public Field getSource() {
1426             return source;
1427         }
1428 
1429         @Override
1430         public TypeMirror asType() {
1431             return createTypeMirror(getSource().getType());
1432         }
1433 
1434         @Override
1435         public ElementKind getKind() {
1436             if (source.isEnumConstant())
1437                 return ElementKind.ENUM_CONSTANT;
1438             else
1439                 return ElementKind.FIELD;
1440         }
1441 
1442         @Override
1443         public Set<Modifier> getModifiers() {
1444             return ModifierUtil.instance(source.getModifiers() &
1445                                          java.lang.reflect.Modifier.fieldModifiers(), false);
1446         }
1447 
1448         @Override
1449         public Name getSimpleName() {
1450             return StringName.instance(source.getName());
1451         }
1452 
1453         @Override
1454         public ReflectionElement getEnclosingElement() {
1455             return createMirror(source.getDeclaringClass());
1456         }
1457 
1458         @Override
1459         public boolean equals(Object o) {
1460             if (o instanceof CoreReflFieldVariableElement) {
1461                 return Objects.equals(source,
1462                                       ((CoreReflFieldVariableElement)o).getSource());
1463             } else {
1464                 return false;
1465             }
1466         }
1467 
1468         @Override
1469         public Object getConstantValue() {
1470             Field target = source;
1471 
1472             // The api says only Strings and primitives may be compile time constants.
1473             // Ensure field is that, and final.
1474             //
1475             // Also, we don't have an instance so restrict to static Fields
1476             //
1477             if (!(source.getType().equals(java.lang.String.class)
1478                   || source.getType().isPrimitive())) {
1479                 return null;
1480             }
1481             final int modifiers = target.getModifiers();
1482             if (!( java.lang.reflect.Modifier.isFinal(modifiers) &&
1483                    java.lang.reflect.Modifier.isStatic(modifiers))) {
1484                 return null;
1485             }
1486 
1487             try {
1488                 return target.get(null);
1489             } catch (IllegalAccessException e) {
1490                 try {
1491                     target.setAccessible(true);
1492                     return target.get(null);
1493                 } catch (IllegalAccessException i) {
1494                     throw new SecurityException(i);
1495                 }
1496             }
1497         }
1498     }
1499 
1500     private static class CoreReflParameterVariableElement
1501         extends CoreReflVariableElement {
1502         private final Parameter source;
1503 
1504         protected CoreReflParameterVariableElement(Parameter source) {
1505             this.source = Objects.requireNonNull(source);
1506         }
1507 
1508         @Override
1509         public Parameter getSource() {
1510             return source;
1511         }
1512 
1513         @Override
1514         public Set<Modifier> getModifiers() {
1515             return ModifierUtil.instance(source.getModifiers() &
1516                                          java.lang.reflect.Modifier.parameterModifiers(), false);
1517         }
1518 
1519         @Override
1520         public TypeMirror asType() {
1521             // TODO : switch to parameterized type
1522             return createTypeMirror(source.getType());
1523         }
1524 
1525         @Override
1526         public ElementKind getKind() {
1527             return ElementKind.PARAMETER;
1528         }
1529 
1530         @Override
1531         public Name getSimpleName() {
1532             return StringName.instance(source.getName());
1533         }
1534 
1535         @Override
1536         public ReflectionElement getEnclosingElement() {
1537             Executable enclosing = source.getDeclaringExecutable();
1538             if (enclosing instanceof Method)
1539                 return createMirror((Method)enclosing);
1540             else if (enclosing instanceof Constructor)
1541                 return createMirror((Constructor<?>)enclosing);
1542             else
1543                 throw new AssertionError("Bad enclosing value.");
1544         }
1545 
1546         @Override
1547         public boolean equals(Object o) {
1548             if (o instanceof CoreReflParameterVariableElement) {
1549                 return source.equals(((CoreReflParameterVariableElement) o).getSource());
1550             } else
1551                 return false;
1552         }
1553 
1554         // VariableElement methods
1555         @Override
1556         public Object getConstantValue() {
1557             return null;
1558         }
1559 
1560         @Override
1561         public boolean isSynthetic() {
1562             return source.isSynthetic();
1563         }
1564 
1565         @Override
1566         public boolean isImplicit() {
1567             return source.isImplicit();
1568         }
1569     }
1570 
1571     private static class CoreReflPackageElement extends CoreReflElement
1572         implements ReflectionPackageElement {
1573 
1574         private final Package source;
1575 
1576         protected CoreReflPackageElement(Package source) {
1577             this.source = source;
1578         }
1579 
1580         @Override
1581         public Package getSource() {
1582             return source;
1583         }
1584 
1585         @Override
1586         public <R,P> R accept(ElementVisitor<R,P> v, P p) {
1587             return v.visitPackage(this, p);
1588         }
1589 
1590         @Override
1591         public <R,P> R accept(ReflectionElementVisitor<R,P> v, P p) {
1592             return v.visitPackage(this, p);
1593         }
1594 
1595         @Override
1596         public boolean equals(Object o) {
1597             if (o instanceof CoreReflPackageElement) {
1598                 return Objects.equals(source,
1599                                       ((CoreReflPackageElement)o).getSource());
1600             } else {
1601                 return false;
1602             }
1603         }
1604 
1605         @Override
1606         public ElementKind getKind() {
1607             return ElementKind.PACKAGE;
1608         }
1609 
1610         @Override
1611         public ReflectionElement getEnclosingElement() {
1612             return null;
1613         }
1614 
1615         @Override
1616         public List<ReflectionElement> getEnclosedElements() {
1617             throw new UnsupportedOperationException();
1618         }
1619 
1620         @Override
1621         public Name getQualifiedName() {
1622             return StringName.instance((source != null) ?
1623                                        source.getName() :
1624                                        "" );
1625         }
1626 
1627         @Override
1628         public Name getSimpleName() {
1629             String n = ((source != null) ?
1630                         source.getName() :
1631                         "");
1632             int index = n.lastIndexOf('.');
1633             if (index > 0) {
1634                 return StringName.instance(n.substring(index + 1, n.length()));
1635             } else {
1636                 return StringName.instance(n);
1637             }
1638         }
1639 
1640         @Override
1641         public boolean isUnnamed() {
1642             if (source != null) {
1643                 String name = source.getName();
1644                 return(name == null || name.isEmpty());
1645             } else
1646                 return true;
1647         }
1648     }
1649 
1650     private static class CoreReflAnnotationMirror
1651         implements javax.lang.model.element.AnnotationMirror {
1652         private final Annotation annotation;
1653 
1654         protected CoreReflAnnotationMirror(Annotation annotation) {
1655             this.annotation = Objects.requireNonNull(annotation);
1656         }
1657 
1658         @Override
1659         public DeclaredType getAnnotationType() {
1660             return (DeclaredType)TypeFactory.instance(annotation.annotationType());
1661         }
1662 
1663         @Override
1664         public Map<? extends ReflectionExecutableElement, ? extends AnnotationValue> getElementValues() {
1665             // This differs from the javac implementation in that it returns default values
1666 
1667             Method[] elems = annotation.annotationType().getDeclaredMethods();
1668             int len = elems.length;
1669 
1670             if (len > 0) {
1671                 Map<ReflectionExecutableElement, AnnotationValue> res = new HashMap<>();
1672                 for (Method m : elems) {
1673                     AnnotationValue v;
1674                     try {
1675                         v = new CoreReflAnnotationValue(m.invoke(annotation));
1676                     } catch (IllegalAccessException e) {
1677                         try {
1678                             m.setAccessible(true);
1679                             v = new CoreReflAnnotationValue(m.invoke(annotation));
1680                         } catch (IllegalAccessException i) {
1681                             throw new SecurityException(i);
1682                         } catch (InvocationTargetException ee) {
1683                             throw new RuntimeException(ee);
1684                         }
1685                     } catch (InvocationTargetException ee) {
1686                         throw new RuntimeException(ee);
1687                     }
1688                     ReflectionExecutableElement e = createMirror(m);
1689                     res.put(e, v);
1690                 }
1691 
1692                 return Collections.unmodifiableMap(res);
1693             } else {
1694                 return Collections.emptyMap();
1695             }
1696         }
1697 
1698         @Override
1699         public boolean equals(Object other) {
1700             if (other instanceof CoreReflAnnotationMirror) {
1701                 return annotation.equals(((CoreReflAnnotationMirror)other).annotation);
1702             } else {
1703                 return false;
1704             }
1705         }
1706 
1707         @Override
1708         public int hashCode() {
1709             return Objects.hashCode(annotation);
1710         }
1711 
1712         @Override
1713         public String toString() {
1714             return annotation.toString();
1715         }
1716     }
1717 
1718     private static class CoreReflAnnotationValue
1719         implements javax.lang.model.element.AnnotationValue {
1720         private Object value = null;
1721 
1722         protected CoreReflAnnotationValue(Object value) {
1723             // Is this constraint really necessary?
1724             Objects.requireNonNull(value);
1725             this.value = value;
1726         }
1727 
1728         @Override
1729         public Object getValue() {
1730             return value;
1731         }
1732 
1733         @Override
1734         public String toString() {
1735             return value.toString();
1736         }
1737 
1738         @Override
1739         public <R,P> R accept(AnnotationValueVisitor<R,P> v, P p) {
1740             return v.visit(this, p);
1741         }
1742     }
1743 
1744     // Helper utility classes
1745 
1746     private static class StringName implements Name {
1747         private String name;
1748 
1749         private StringName(String name) {
1750             this.name = Objects.requireNonNull(name);
1751         }
1752 
1753         public static StringName instance(String name) {
1754             return new StringName(name);
1755         }
1756 
1757         @Override
1758         public int length() {
1759             return name.length();
1760         }
1761 
1762         @Override
1763         public char charAt(int index) {
1764             return name.charAt(index);
1765         }
1766 
1767         @Override
1768         public CharSequence subSequence(int start, int end) {
1769             return name.subSequence(start, end);
1770         }
1771 
1772         @Override
1773         public String toString() {
1774             return name;
1775         }
1776 
1777         @Override
1778         public boolean equals(Object other) {
1779             if (other instanceof StringName) {
1780                 return name.equals(((StringName) other).name);
1781             } else {
1782                 return false;
1783             }
1784         }
1785 
1786         @Override
1787         public int hashCode() {
1788             return name.hashCode();
1789         }
1790 
1791         @Override
1792         public boolean contentEquals(CharSequence cs) {
1793             return name.contentEquals(cs);
1794         }
1795     }
1796 
1797     /*
1798      * Given an {@code int} value of modifiers, return a proper immutable set
1799      * of {@code Modifier}s as a result.
1800      */
1801     private static class ModifierUtil {
1802         private ModifierUtil() {
1803             throw new AssertionError("No instances for you.");
1804         }
1805 
1806         // Exercise for the reader: explore if caching of sets of
1807         // Modifiers would be helpful.
1808 
1809         public static Set<Modifier> instance(int modifiers, boolean isDefault) {
1810             Set<Modifier> modSet = EnumSet.noneOf(Modifier.class);
1811 
1812             if (java.lang.reflect.Modifier.isAbstract(modifiers))
1813                 modSet.add(Modifier.ABSTRACT);
1814 
1815             if (java.lang.reflect.Modifier.isFinal(modifiers))
1816                 modSet.add(Modifier.FINAL);
1817 
1818             if (java.lang.reflect.Modifier.isNative(modifiers))
1819                 modSet.add(Modifier.NATIVE);
1820 
1821             if (java.lang.reflect.Modifier.isPrivate(modifiers))
1822                 modSet.add(Modifier.PRIVATE);
1823 
1824             if (java.lang.reflect.Modifier.isProtected(modifiers))
1825                 modSet.add(Modifier.PROTECTED);
1826 
1827             if (java.lang.reflect.Modifier.isPublic(modifiers))
1828                 modSet.add(Modifier.PUBLIC);
1829 
1830             if (java.lang.reflect.Modifier.isStatic(modifiers))
1831                 modSet.add(Modifier.STATIC);
1832 
1833             if (java.lang.reflect.Modifier.isStrict(modifiers))
1834                 modSet.add(Modifier.STRICTFP);
1835 
1836             if (java.lang.reflect.Modifier.isSynchronized(modifiers))
1837                 modSet.add(Modifier.SYNCHRONIZED);
1838 
1839             if (java.lang.reflect.Modifier.isTransient(modifiers))
1840                 modSet.add(Modifier.TRANSIENT);
1841 
1842             if (java.lang.reflect.Modifier.isVolatile(modifiers))
1843                 modSet.add(Modifier.VOLATILE);
1844 
1845             if (isDefault)
1846                 modSet.add(Modifier.DEFAULT);
1847 
1848             return Collections.unmodifiableSet(modSet);
1849         }
1850     }
1851 
1852     private abstract static class AbstractTypeMirror implements TypeMirror {
1853         private final TypeKind kind;
1854 
1855         protected AbstractTypeMirror(TypeKind kind) {
1856             this.kind = Objects.requireNonNull(kind);
1857         }
1858 
1859         @Override
1860         public TypeKind getKind() {
1861             return kind;
1862         }
1863 
1864         @Override
1865         public <R,P> R accept(TypeVisitor<R,P> v, P p) {
1866             return v.visit(this, p);
1867         }
1868 
1869         //Types methods
1870         abstract List<? extends TypeMirror> directSuperTypes();
1871 
1872         TypeMirror capture() {
1873             // Exercise for the reader: make this abstract and implement in subtypes
1874             throw new UnsupportedOperationException();
1875         }
1876 
1877         TypeMirror erasure() {
1878             // Exercise for the reader: make this abstract and implement in subtypes
1879             throw new UnsupportedOperationException();
1880         }
1881 
1882         // Exercise for the reader: implement the AnnotatedConstruct methods
1883         @Override
1884         public List<? extends AnnotationMirror> getAnnotationMirrors() {
1885             throw new UnsupportedOperationException();
1886         }
1887 
1888         @Override
1889         public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1890             throw new UnsupportedOperationException();
1891         }
1892 
1893         @Override
1894         public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
1895             throw new UnsupportedOperationException();
1896         }
1897     }
1898 
1899     private static class CoreReflArrayType extends AbstractTypeMirror
1900         implements javax.lang.model.type.ArrayType,
1901                    Reifiable {
1902         private Class<?> source = null;
1903         private Class<?> component = null;
1904         private TypeMirror eagerComponent = null;
1905 
1906         protected CoreReflArrayType(Class<?> source) {
1907             super(TypeKind.ARRAY);
1908             this.source = source;
1909             this.component = source.getComponentType();
1910             this.eagerComponent = TypeFactory.instance(component);
1911         }
1912 
1913         public TypeMirror getComponentType() {
1914             return eagerComponent;
1915         }
1916 
1917         @Override
1918         public Class<?> getSource() {
1919             return source;
1920         }
1921 
1922         @Override
1923         List<? extends TypeMirror> directSuperTypes() {
1924             final TypeMirror componentType = getComponentType();
1925             final TypeMirror[] directSupers;
1926 
1927             // JLS v4 4.10.3
1928             if (componentType.getKind().isPrimitive() ||
1929                 component.equals(java.lang.Object.class)) {
1930                 directSupers = new TypeMirror[3];
1931                 directSupers[0] = TypeFactory.instance(java.lang.Object.class);
1932                 directSupers[1] = TypeFactory.instance(java.lang.Cloneable.class);
1933                 directSupers[2] = TypeFactory.instance(java.io.Serializable.class);
1934             } else if (componentType.getKind() == TypeKind.ARRAY) {
1935                 List<? extends TypeMirror> componentDirectSupertypes = CoreReflTypes.instance().directSupertypes(componentType);
1936                 directSupers = new TypeMirror[componentDirectSupertypes.size()];
1937                 for (int i = 0; i < directSupers.length; i++) {
1938                     directSupers[i] = new CoreReflArrayType(Array.newInstance(((Reifiable)componentDirectSupertypes.get(i)).getSource(), 0).getClass());
1939                 }
1940             } else {
1941                 Class<?> superClass = component.getSuperclass();
1942                 Class<?>[] interfaces = component.getInterfaces();
1943                 directSupers = new TypeMirror[1 + interfaces.length];
1944 
1945                 directSupers[0] = TypeFactory.instance(Array.newInstance(superClass, 0).getClass());
1946 
1947                 for (int i = 0; i < interfaces.length; i++) {
1948                     directSupers[i + 1] = TypeFactory.instance(Array.newInstance(interfaces[i],0).getClass());
1949                 }
1950             }
1951 
1952             return Collections.unmodifiableList(Arrays.asList(directSupers));
1953         }
1954 
1955         @Override
1956         public String toString() {
1957             return getKind() + " of " + getComponentType().toString();
1958         }
1959     }
1960 
1961     private static class CaptureTypeVariable extends AbstractTypeMirror implements javax.lang.model.type.TypeVariable {
1962         private TypeMirror source = null;
1963         private TypeMirror upperBound = null;
1964         private TypeMirror lowerBound = null;
1965 
1966         CaptureTypeVariable(TypeMirror source,
1967                             TypeMirror upperBound,
1968                             TypeMirror lowerBound) {
1969             super(TypeKind.TYPEVAR);
1970 
1971             this.source = Objects.requireNonNull(source);
1972             this.upperBound = (upperBound == null ? CoreReflTypes.instance().getNullType() : upperBound);
1973             this.lowerBound = (lowerBound == null ? CoreReflTypes.instance().getNullType() : lowerBound);
1974         }
1975 
1976         protected Class<?> getSource() {
1977             if (source instanceof CoreReflDeclaredType) {
1978                 return ((CoreReflDeclaredType)source).getSource();
1979             } else {
1980                 return null;
1981             }
1982         }
1983 
1984         @Override
1985         public TypeMirror getUpperBound() {
1986             return upperBound;
1987         }
1988 
1989         @Override
1990         public TypeMirror getLowerBound() {
1991             return lowerBound;
1992         }
1993 
1994         @Override
1995         public Element asElement() {
1996             if (null == getSource()) {
1997                 return null;
1998             }
1999             return CoreReflectionFactory.createMirror(getSource());
2000         }
2001 
2002         @Override
2003         List<? extends TypeMirror> directSuperTypes() {
2004             throw new UnsupportedOperationException();
2005 
2006         }
2007 
2008         @Override
2009         public String toString() {
2010             return getKind() + " CAPTURE of: " + source.toString();
2011         }
2012     }
2013 
2014     private static class CoreReflElements implements ReflectionElements {
2015         private CoreReflElements() {} // mostly one instance for you
2016 
2017         private static CoreReflElements instance = new CoreReflElements();
2018 
2019         static CoreReflElements instance() {
2020             return instance;
2021         }
2022 
2023         /**
2024          * {@inheritDoc}
2025          */
2026         @Override
2027         public ReflectionPackageElement getPackageElement(CharSequence name) {
2028             return createMirror(Package.getPackage(name.toString()));
2029         }
2030 
2031         /**
2032          * {@inheritDoc}
2033          */
2034         @Override
2035         public ReflectionTypeElement getTypeElement(CharSequence name) {
2036             // where name is a Canonical Name jls 6.7
2037             // but this method will probably accept an equivalent FQN
2038             // depending on Class.forName(String)
2039 
2040             ReflectionTypeElement tmp = null;
2041 
2042             // Filter out arrays
2043             String n = name.toString();
2044             if (n.contains("[")) return null;
2045             if (n.equals("")) return null;
2046 
2047             // The intention of this loop is to handle nested
2048             // elements.  If finding the element using Class.forName
2049             // fails, an attempt is made to find the element as an
2050             // enclosed element by trying fo find a prefix of the name
2051             // (dropping a trailing ".xyz") and looking for "xyz" as
2052             // an enclosed element.
2053 
2054             Deque<String> parts = new ArrayDeque<>();
2055             boolean again;
2056             do {
2057                 again = false;
2058                 try {
2059                     tmp = createMirror(Class.forName(n));
2060                 } catch (ClassNotFoundException e) {
2061                     tmp = null;
2062                 }
2063 
2064                 if (tmp != null) {
2065                     if (parts.isEmpty()) {
2066                         return tmp;
2067                     }
2068 
2069                     tmp = findInner(tmp, parts);
2070                     if (tmp != null) {
2071                         return tmp;
2072                     }
2073                 }
2074 
2075                 int indx = n.lastIndexOf('.');
2076                 if (indx > -1) {
2077                     parts.addFirst(n.substring(indx + 1));
2078                     n = n.substring(0, indx);
2079                     again = true;
2080                 }
2081             } while (again);
2082 
2083             return null;
2084         }
2085 
2086         // Recursively finds enclosed type elements named as part.top() popping part and repeating
2087         private ReflectionTypeElement findInner(ReflectionTypeElement e, Deque<String> parts) {
2088             if (parts.isEmpty()) {
2089                 return e;
2090             }
2091 
2092             String part = parts.removeFirst();
2093             List<ReflectionElement> enclosed = e.getEnclosedElements();
2094             for (ReflectionElement elm : enclosed) {
2095                 if ((elm.getKind() == ElementKind.CLASS ||
2096                      elm.getKind() == ElementKind.INTERFACE ||
2097                      elm.getKind() == ElementKind.ENUM ||
2098                      elm.getKind() == ElementKind.ANNOTATION_TYPE)
2099                     && elm.getSimpleName().toString().equals(part)) {
2100                     ReflectionTypeElement t = findInner((ReflectionTypeElement)elm, parts);
2101                     if (t != null) {
2102                         return t;
2103                     }
2104                 }
2105             }
2106             return null;
2107         }
2108 
2109         /**
2110          * {@inheritDoc}
2111          */
2112         @Override
2113         public Map<? extends ReflectionExecutableElement, ? extends AnnotationValue>
2114             getElementValuesWithDefaults(AnnotationMirror a) {
2115             if (a instanceof CoreReflAnnotationMirror) {
2116                 return ((CoreReflAnnotationMirror)a).getElementValues();
2117             } else {
2118                 throw new IllegalArgumentException();
2119             }
2120         }
2121 
2122         /**
2123          * {@inheritDoc}
2124          */
2125         @Override
2126         public String getDocComment(Element e) {
2127             checkElement(e);
2128             return null; // As per the doc
2129         }
2130 
2131         /**
2132          * {@inheritDoc}
2133          */
2134         @Override
2135         public boolean isDeprecated(Element e) {
2136             checkElement(e);
2137             return ((CoreReflElement)e).getSource().isAnnotationPresent(java.lang.Deprecated.class);
2138         }
2139 
2140         /**
2141          * {@inheritDoc}
2142          */
2143         @Override
2144         public Name getBinaryName(TypeElement type) {
2145             checkElement(type);
2146             return StringName.instance(((CoreReflTypeElement)type)
2147                                        .getSource()
2148                                        .getName());
2149         }
2150 
2151         /**
2152          * {@inheritDoc}
2153          */
2154         @Override
2155         public ReflectionPackageElement getPackageOf(Element type) {
2156             checkElement(type);
2157             if (type instanceof ReflectionPackageElement) {
2158                 return (ReflectionPackageElement)type;
2159             }
2160 
2161             Package p;
2162             if (type instanceof CoreReflTypeElement) {
2163                 p = ((CoreReflTypeElement)type).getSource().getPackage();
2164             } else {
2165                 CoreReflTypeElement enclosingTypeElement = (CoreReflTypeElement)getEnclosingTypeElement((ReflectionElement)type);
2166                 p = enclosingTypeElement.getSource().getPackage();
2167             }
2168 
2169             return createMirror(p);
2170         }
2171 
2172         /**
2173          * {@inheritDoc}
2174          */
2175         @Override
2176         public List<? extends ReflectionElement> getAllMembers(TypeElement type) {
2177             checkElement(type);
2178             return getAllMembers((ReflectionTypeElement)type);
2179         }
2180 
2181         // Exercise for the reader: should this method, and similar
2182         // ones that specialize on the more specific argument types,
2183         // be addd to the public ReflectionElements API?
2184         public List<? extends ReflectionElement> getAllMembers(ReflectionTypeElement type) {
2185             return type.getAllMembers();
2186         }
2187 
2188         /**
2189          * {@inheritDoc}
2190          */
2191         @Override
2192         public List<? extends AnnotationMirror> getAllAnnotationMirrors(Element e) {
2193             checkElement(e);
2194             AnnotatedElement ae = CoreReflElement.class.cast(e).getSource();
2195             Annotation[] annotations = ae.getAnnotations();
2196             int len = annotations.length;
2197 
2198             if (len > 0) {
2199                 List<AnnotationMirror> res = new ArrayList<>(len);
2200                 for (Annotation a : annotations) {
2201                     res.add(createMirror(a));
2202                 }
2203                 return Collections.unmodifiableList(res);
2204             } else {
2205                 List<AnnotationMirror> ret = Collections.emptyList();
2206                 return ret;
2207             }
2208         }
2209 
2210         /**
2211          * {@inheritDoc}
2212          */
2213         @Override
2214         public boolean hides(Element hider, Element hidden) {
2215             checkElement(hider);
2216             checkElement(hidden);
2217 
2218             // Names must be equal
2219             if (!hider.getSimpleName().equals(hidden.getSimpleName())) {
2220                 return false;
2221             }
2222 
2223             // Hides isn't reflexive
2224             if (hider.equals(hidden)) {
2225                 return false;
2226             }
2227 
2228             // Hider and hidden needs to be field, method or type
2229             // and fields hide fields, types hide types, methods hide methods
2230             // IE a Field doesn't hide a Methods etc
2231             ElementKind hiderKind = hider.getKind();
2232             ElementKind hiddenKind = hidden.getKind();
2233             if (hiderKind.isField() && !hiddenKind.isField()) {
2234                 return false;
2235             } else if (hiderKind.isClass() &&
2236                        !(hiddenKind.isClass() || hiddenKind.isInterface())) {
2237                 return false;
2238             } else if (hiderKind.isInterface() &&
2239                        !(hiddenKind.isClass() || hiddenKind.isInterface())) {
2240                 return false;
2241             } else if (hiderKind == ElementKind.METHOD && hiddenKind != ElementKind.METHOD) {
2242                 return false;
2243             } else if (!(hiderKind.isClass() ||
2244                          hiderKind.isInterface() ||
2245                          hiderKind.isField() ||
2246                          hiderKind == ElementKind.METHOD)) {
2247                 return false;
2248             }
2249 
2250             Set<Modifier> hm = hidden.getModifiers();
2251             // jls 8.4.8.2 only static methods can hide methods
2252             if (hider.getKind() == ElementKind.METHOD) {
2253                 if (!hider.getModifiers().contains(Modifier.STATIC)) {
2254                     return false; // hider not static
2255                 } else if (!hm.contains(Modifier.STATIC)) { // we know it's a method
2256                     return false; // hidden not static
2257                 }
2258 
2259                 // For methods we also need to check parameter types
2260                 Class<?>[] h1 = ((CoreReflMethodExecutableElement)hider).getSource().getParameterTypes();
2261                 Class<?>[] h2 = ((CoreReflMethodExecutableElement)hidden).getSource().getParameterTypes();
2262                 if (h1.length != h2.length) {
2263                     return false;
2264                 }
2265                 for (int i = 0; i < h1.length; i++) {
2266                     if (h1[i] != h2[i]) {
2267                         return false;
2268                     }
2269                 }
2270             }
2271 
2272             // You can only hide visible elements
2273             if (hm.contains(Modifier.PRIVATE)) {
2274                 return false; // hidden private, can't be hidden
2275             } else if ((!(hm.contains(Modifier.PUBLIC) || hm.contains(Modifier.PROTECTED))) && // not private, not (public or protected) IE package private
2276                        (!getPackageOf(hider).equals(getPackageOf(hidden)))) {
2277                 return false; // hidden package private, and different packages, IE not visible
2278             }
2279 
2280             // Ok so now hider actually hides hidden if hider is
2281             // declared on a subtype of hidden.
2282             //
2283             // TODO: should this be a proper subtype or is that taken
2284             // care of by the reflexive check in the beginning?
2285             //
2286             TypeMirror hiderType = getEnclosingTypeElement((ReflectionElement)hider).asType();
2287             TypeMirror hiddenType = getEnclosingTypeElement((ReflectionElement)hidden).asType();
2288 
2289             return getTypes().isSubtype(hiderType, hiddenType);
2290         }
2291 
2292         /**
2293          * {@inheritDoc}
2294          */
2295         @Override
2296         public ReflectionTypeElement getEnclosingTypeElement(ReflectionElement e) {
2297             if (e.getKind() == ElementKind.PACKAGE) {
2298                 return null;
2299             }
2300 
2301             if(e instanceof CoreReflTypeParameterElement) {
2302                 ReflectionElement encElem = ((CoreReflTypeParameterElement)e).getEnclosingElement();
2303                 if (encElem instanceof ReflectionTypeElement) {
2304                     return (ReflectionTypeElement)encElem;
2305                 } else  {
2306                     return getEnclosingTypeElement(encElem);
2307                 }
2308             }
2309 
2310             Class<?> encl = null;
2311             if (e instanceof CoreReflTypeElement) {
2312                 encl = ((CoreReflTypeElement)e).getSource().getDeclaringClass();
2313             } else if (e instanceof CoreReflExecutableElement) {
2314                 encl = (((CoreReflExecutableElement)e).getSource()).getDeclaringClass();
2315             } else if (e instanceof CoreReflFieldVariableElement) {
2316                 encl = ((CoreReflFieldVariableElement)e).getSource().getDeclaringClass();
2317             } else if (e instanceof CoreReflParameterVariableElement) {
2318                 encl = ((CoreReflParameterVariableElement)e).getSource().getDeclaringExecutable().getDeclaringClass();
2319             }
2320 
2321             return encl == null ? null : createMirror(encl);
2322         }
2323 
2324         /**
2325          *{@inheritDoc}
2326          *
2327          * Note that this implementation does not handle the situation
2328          * where A overrides B and B overrides C but A does not
2329          * directly override C. In this case, this implementation will
2330          * erroneously return false.
2331          */
2332         @Override
2333         public boolean overrides(ExecutableElement overrider, ExecutableElement overridden,
2334                                  TypeElement type) {
2335             checkElement(overrider);
2336             checkElement(overridden);
2337             checkElement(type);
2338 
2339             // TODO handle transitive overrides
2340             return overridesDirect(overrider, overridden, type);
2341         }
2342 
2343         private boolean overridesDirect(ExecutableElement overrider, ExecutableElement overridden,
2344                                          TypeElement type) {
2345             // Should we check that at least one of the types
2346             // overrider has is in fact a supertype of the TypeElement
2347             // 'type' supplied?
2348 
2349             CoreReflExecutableElement rider = (CoreReflExecutableElement)overrider;
2350             CoreReflExecutableElement ridden = (CoreReflExecutableElement)overridden;
2351             CoreReflTypeElement riderType = (CoreReflTypeElement)type;
2352 
2353             // Names must match, redundant - see subsignature below
2354             if (!rider.getSimpleName().equals(ridden.getSimpleName())) {
2355                 return false;
2356             }
2357 
2358             // Constructors don't override
2359             // TODO: verify this fact
2360             if (rider.getKind() == ElementKind.CONSTRUCTOR ||
2361                 ridden.getKind() == ElementKind.CONSTRUCTOR) {
2362                 return false;
2363             }
2364 
2365             // Overridden must be visible to be overridden
2366             // TODO Fix transitive visibility/override
2367             Set<Modifier> rm = ridden.getModifiers();
2368             if (rm.contains(Modifier.PRIVATE)) {
2369                 return false; // overridden private, can't be overridden
2370             } else if ((!(rm.contains(Modifier.PUBLIC) || rm.contains(Modifier.PROTECTED))) && // not private, not (public or protected) IE package private
2371                        (!getPackageOf(rider).equals(getPackageOf(ridden)))) {
2372                 return false; // ridden package private, and different packages, IE not visible
2373             }
2374 
2375             // Static methods doesn't override
2376             if (rm.contains(Modifier.STATIC) ||
2377                 rider.getModifiers().contains(Modifier.STATIC)) {
2378                 return false;
2379             }
2380 
2381             // Declaring class of overrider must be a subclass of declaring class of overridden
2382             // except we use the parameter type as declaring class of overrider
2383             if (!getTypes().isSubtype(riderType.asType(), getEnclosingTypeElement(ridden).asType())) {
2384                 return false;
2385             }
2386 
2387             // Now overrider overrides overridden if the signature of rider is a subsignature of ridden
2388             return getTypes().isSubsignature(rider.asType(), ridden.asType());
2389         }
2390 
2391         /**
2392          *{@inheritDoc}
2393          */
2394         @Override
2395         public String getConstantExpression(Object value) {
2396             return Constants.format(value);
2397         }
2398 
2399         // If CoreReflectionFactory were a proper part of the JDK, the
2400         // analogous functionality in javac could be reused.
2401         private static class Constants {
2402             /**
2403              * Returns a string representation of a constant value (given in
2404              * standard wrapped representation), quoted and formatted as in
2405              * Java source.
2406              */
2407             public static String format(Object value) {
2408                 if (value instanceof Byte)      return formatByte((Byte) value);
2409                 if (value instanceof Short)     return formatShort((Short) value);
2410                 if (value instanceof Long)      return formatLong((Long) value);
2411                 if (value instanceof Float)     return formatFloat((Float) value);
2412                 if (value instanceof Double)    return formatDouble((Double) value);
2413                 if (value instanceof Character) return formatChar((Character) value);
2414                 if (value instanceof String)    return formatString((String) value);
2415                 if (value instanceof Integer ||
2416                     value instanceof Boolean)   return value.toString();
2417                 else
2418                     throw new IllegalArgumentException("Argument is not a primitive type or a string; it " +
2419                                                        ((value == null) ?
2420                                                         "is a null value." :
2421                                                         "has class " +
2422                                                         value.getClass().getName()) + "." );
2423             }
2424 
2425             private static String formatByte(byte b) {
2426                 return String.format("(byte)0x%02x", b);
2427             }
2428 
2429             private static String formatShort(short s) {
2430                 return String.format("(short)%d", s);
2431             }
2432 
2433             private static String formatLong(long lng) {
2434                 return lng + "L";
2435             }
2436 
2437             private static String formatFloat(float f) {
2438                 if (Float.isNaN(f))
2439                     return "0.0f/0.0f";
2440                 else if (Float.isInfinite(f))
2441                     return (f < 0) ? "-1.0f/0.0f" : "1.0f/0.0f";
2442                 else
2443                     return f + "f";
2444             }
2445 
2446             private static String formatDouble(double d) {
2447                 if (Double.isNaN(d))
2448                     return "0.0/0.0";
2449                 else if (Double.isInfinite(d))
2450                     return (d < 0) ? "-1.0/0.0" : "1.0/0.0";
2451                 else
2452                     return d + "";
2453             }
2454 
2455             private static String formatChar(char c) {
2456                 return '\'' + quote(c) + '\'';
2457             }
2458 
2459             private static String formatString(String s) {
2460                 return '"' + quote(s) + '"';
2461             }
2462 
2463             /**
2464              * Escapes each character in a string that has an escape sequence or
2465              * is non-printable ASCII.  Leaves non-ASCII characters alone.
2466              */
2467             private static String quote(String s) {
2468                 StringBuilder buf = new StringBuilder();
2469                 for (int i = 0; i < s.length(); i++) {
2470                     buf.append(quote(s.charAt(i)));
2471                 }
2472                 return buf.toString();
2473             }
2474 
2475             /**
2476              * Escapes a character if it has an escape sequence or is
2477              * non-printable ASCII.  Leaves ASCII characters alone.
2478              */
2479             private static String quote(char ch) {
2480                 switch (ch) {
2481                 case '\b':  return "\\b";
2482                 case '\f':  return "\\f";
2483                 case '\n':  return "\\n";
2484                 case '\r':  return "\\r";
2485                 case '\t':  return "\\t";
2486                 case '\'':  return "\\'";
2487                 case '\"':  return "\\\"";
2488                 case '\\':  return "\\\\";
2489                 default:
2490                     return (isPrintableAscii(ch))
2491                         ? String.valueOf(ch)
2492                         : String.format("\\u%04x", (int) ch);
2493                 }
2494             }
2495 
2496             /**
2497              * Is a character printable ASCII?
2498              */
2499             private static boolean isPrintableAscii(char ch) {
2500                 return ch >= ' ' && ch <= '~';
2501             }
2502         }
2503 
2504         /**
2505          * {@inheritDoc}
2506          */
2507         @Override
2508         public void printElements(Writer w, Element... elements) {
2509             ElementVisitor<?, ?> printer = getPrinter(w);
2510             try {
2511                 for (Element e : elements) {
2512                     checkElement(e);
2513                     printer.visit(e);
2514                 }
2515             } finally {
2516                 try {
2517                     w.flush();
2518                 } catch (java.io.IOException e) { /* Ignore */;}
2519             }
2520         }
2521 
2522         private ElementVisitor<?, ?> getPrinter(Writer w) {
2523             // First try a reflective call into javac and if that
2524             // fails, fallback to a very simple toString-based
2525             // scanner.
2526             try {
2527                 //reflective form of
2528                 // return new com.sun.tools.javac.processing.PrintingProcessor.PrintingElementVisitor(w, getElements());
2529                 Class<?> printProcClass =
2530                     ClassLoader.getSystemClassLoader().loadClass("com.sun.tools.javac.processing.PrintingProcessor$PrintingElementVisitor");
2531                 Constructor<?> printProcCtor = printProcClass.getConstructor(Writer.class, Elements.class);
2532                 return (ElementVisitor) printProcCtor.newInstance(w, getElements());
2533             } catch (ReflectiveOperationException | SecurityException e) {
2534                 return new ElementScanner8<Writer, Void>(w){
2535                     @Override
2536                     public Writer scan(Element e, Void v) {
2537                         try {
2538                             DEFAULT_VALUE.append(e.toString());
2539                             DEFAULT_VALUE.append("\n");
2540                         } catch (java.io.IOException ioe) {
2541                             throw new RuntimeException(ioe);
2542                         }
2543                         return DEFAULT_VALUE;
2544                     }
2545                 };
2546             }
2547         }
2548 
2549         /**
2550          * {@inheritDoc}
2551          */
2552         @Override
2553         public Name getName(CharSequence cs) {
2554             return StringName.instance(cs.toString());
2555         }
2556 
2557         private void checkElement(Element e) {
2558             if(!(e instanceof CoreReflElement)) {
2559                 throw new IllegalArgumentException();
2560             }
2561         }
2562 
2563         @Override
2564         public boolean isFunctionalInterface(TypeElement e) {
2565             throw new UnsupportedOperationException();
2566             // Update once this functionality is in core reflection
2567         }
2568     }
2569 
2570     private static class CoreReflTypes implements javax.lang.model.util.Types {
2571         private static Types instance = new CoreReflTypes();
2572 
2573         public static Types instance() {
2574             return instance;
2575         }
2576 
2577         // Private to suppress instantiation
2578         private CoreReflTypes() {}
2579 
2580         // Types methods
2581         @Override
2582         public Element asElement(TypeMirror t) {
2583             checkType(t);
2584             if (t instanceof javax.lang.model.type.TypeVariable) {
2585                 ((javax.lang.model.type.TypeVariable)t).asElement();
2586             } else if (t instanceof DeclaredType) {
2587                 return ((DeclaredType)t).asElement();
2588             }
2589             return null;
2590         }
2591 
2592         @Override
2593         public boolean isSameType(TypeMirror t1, TypeMirror t2) {
2594             if (t1.getKind() != t2.getKind()) {
2595                 return false;
2596             }
2597 
2598             if (t1.getKind() == TypeKind.WILDCARD ||
2599                 t2.getKind() == TypeKind.WILDCARD) {
2600                 // Wildcards are not equal to any type
2601                 return false;
2602             }
2603 
2604             if (t1 instanceof CoreReflDeclaredType &&
2605                 t2 instanceof CoreReflDeclaredType) {
2606                 return ((CoreReflDeclaredType)t1).isSameType((CoreReflDeclaredType)t2);
2607             } else if (t1 instanceof PrimitiveType &&
2608                        t2 instanceof PrimitiveType) {
2609                 return t1.getKind() == t2.getKind();
2610             } else if (t1 instanceof NoType &&
2611                        t2 instanceof NoType) {
2612                 return true;
2613             } else if (t1 instanceof NullType &&
2614                        t2 instanceof NullType) {
2615                 return true;
2616             } else if (t1 instanceof ArrayType &&
2617                        t2 instanceof ArrayType) {
2618                 return isSameType(((ArrayType)t1).getComponentType(), ((ArrayType)t2).getComponentType());
2619             }
2620 
2621             return false;
2622         }
2623 
2624         @Override
2625         public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
2626             checkType(t1);
2627             checkType(t2);
2628 
2629             if (isSameType(t1, t2)) {
2630                 return true;
2631             } else if(t1.getKind() == TypeKind.NULL) {
2632                 return true;
2633             }
2634 
2635             // This depth first traversal should terminate due to the ban on circular inheritance
2636             List<? extends TypeMirror> directSupertypes = directSupertypes(t1);
2637             if (directSupertypes.isEmpty()) {
2638                 return false;
2639             }
2640             for (TypeMirror ti : directSupertypes) {
2641                 if (isSameType(ti, t2) || isSubtype(ti, t2)) {
2642                     return true;
2643                 }
2644             }
2645             return false;
2646         }
2647 
2648         @Override
2649         public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
2650             throw new UnsupportedOperationException();
2651         }
2652 
2653         @Override
2654         public boolean contains(TypeMirror t1, TypeMirror t2) {
2655             throw new UnsupportedOperationException();
2656         }
2657 
2658         @Override
2659         public boolean isSubsignature(ExecutableType m1, ExecutableType m2) {
2660             checkType(m1);
2661             checkType(m2);
2662 
2663             ExecutableMethodType m0 = (ExecutableMethodType)m1;
2664 
2665             return m0.sameSignature((ExecutableMethodType)m2) || m0.sameSignature((ExecutableMethodType)erasure(m2));
2666         }
2667 
2668         @Override
2669         public List<? extends TypeMirror> directSupertypes(TypeMirror t) {
2670             checkType(t);
2671             if (t instanceof ExecutableType ||
2672                 t.getKind() == TypeKind.PACKAGE) {
2673                 throw new IllegalArgumentException("You can't ask for direct supertypes for type: " + t);
2674             }
2675             return ((AbstractTypeMirror)t).directSuperTypes();
2676         }
2677 
2678         @Override
2679         public TypeMirror erasure(TypeMirror t) {
2680             checkType(t);
2681             return ((AbstractTypeMirror)t).erasure();
2682         }
2683 
2684         @Override
2685         public TypeElement boxedClass(javax.lang.model.type.PrimitiveType p) {
2686             throw new UnsupportedOperationException();
2687         }
2688 
2689         @Override
2690         public PrimitiveType unboxedType(TypeMirror t) {
2691             throw new UnsupportedOperationException();
2692         }
2693 
2694         @Override
2695         public TypeMirror capture(TypeMirror t) {
2696             checkType(t);
2697             return ((AbstractTypeMirror)t).capture();
2698         }
2699 
2700         @Override
2701         public PrimitiveType getPrimitiveType(TypeKind kind) {
2702             return PrimitiveType.instance(kind);
2703         }
2704 
2705         @Override
2706         public NullType getNullType() {
2707             return CoreReflNullType.getInstance();
2708         }
2709 
2710         @Override
2711         public javax.lang.model.type.NoType getNoType(TypeKind kind) {
2712             if (kind == TypeKind.NONE) {
2713                 return NoType.getNoneInstance();
2714             } else if (kind == TypeKind.VOID) {
2715                 return NoType.getVoidInstance();
2716             } else {
2717                 throw new IllegalArgumentException("No NoType of kind: " + kind);
2718             }
2719         }
2720 
2721         @Override
2722         public ArrayType getArrayType(TypeMirror componentType) {
2723             throw new UnsupportedOperationException();
2724         }
2725 
2726         @Override
2727         public javax.lang.model.type.WildcardType getWildcardType(TypeMirror extendsBound,
2728                                                                   TypeMirror superBound) {
2729             throw new UnsupportedOperationException();
2730         }
2731 
2732         @Override
2733         public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) {
2734             throw new UnsupportedOperationException();
2735         }
2736 
2737         @Override
2738         public javax.lang.model.type.DeclaredType getDeclaredType(javax.lang.model.type.DeclaredType containing,
2739                                                                   TypeElement typeElem,
2740                                                                   TypeMirror... typeArgs) {
2741             throw new UnsupportedOperationException();
2742         }
2743 
2744         @Override
2745         public TypeMirror asMemberOf(javax.lang.model.type.DeclaredType containing, Element element) {
2746             throw new UnsupportedOperationException();
2747         }
2748 
2749         private void checkType(TypeMirror t) {
2750             if (!(t instanceof AbstractTypeMirror)) {
2751                 throw new IllegalArgumentException("This Types implementation can only operate on CoreReflectionFactory type classes");
2752             }
2753         }
2754     }
2755 
2756     private abstract static class CoreReflDeclaredType extends AbstractTypeMirror
2757         implements javax.lang.model.type.DeclaredType {
2758         private Class<?> source = null;
2759 
2760         private CoreReflDeclaredType(Class<?> source) {
2761             super(TypeKind.DECLARED);
2762             this.source = source;
2763         }
2764 
2765         static DeclaredType instance(Class<?> source, Type genericSource) {
2766             if (genericSource instanceof ParameterizedType) {
2767                 return new ParameterizedDeclaredType(source, (ParameterizedType)genericSource);
2768             } else if (genericSource instanceof Class) { // This happens when a field has a raw type
2769                 if (!source.equals(genericSource)) {
2770                     throw new IllegalArgumentException("Don't know how to handle this");
2771                 }
2772                 return instance(source);
2773             }
2774             throw new IllegalArgumentException("Don't know how to create a declared type from: " +
2775                                                source +
2776                                                " and genericSource " +
2777                                                genericSource);
2778         }
2779 
2780         static DeclaredType instance(Class<?> source) {
2781             return new RawDeclaredType(source);
2782         }
2783 
2784         protected Class<?> getSource() {
2785             return source;
2786         }
2787 
2788         @Override
2789         public Element asElement() {
2790             return CoreReflectionFactory.createMirror(getSource());
2791         }
2792 
2793         abstract boolean isSameType(DeclaredType other);
2794 
2795         @Override
2796         TypeMirror capture() {
2797             return new CaptureDeclaredType(this);
2798         }
2799 
2800         private static class CaptureDeclaredType extends CoreReflDeclaredType {
2801             CoreReflDeclaredType cap;
2802             CaptureDeclaredType(CoreReflDeclaredType t) {
2803                 super(t.source);
2804                 this.cap = t;
2805             }
2806 
2807             @Override
2808             public List<? extends TypeMirror> getTypeArguments() {
2809                 List<? extends TypeMirror> wrapped = cap.getTypeArguments();
2810                 ArrayList<TypeMirror> res = new ArrayList<>(wrapped.size());
2811                 res.ensureCapacity(wrapped.size());
2812 
2813                 for (int i = 0; i < wrapped.size(); i++) {
2814                     TypeMirror t = wrapped.get(i);
2815 
2816                     if (t instanceof javax.lang.model.type.WildcardType) {
2817                         res.add(i, convert(t));
2818                     } else {
2819                         res.add(i, t);
2820                     }
2821                 }
2822                 return Collections.unmodifiableList(res);
2823             }
2824 
2825             private TypeMirror convert(TypeMirror t) {
2826                 if (!(t instanceof javax.lang.model.type.WildcardType)) {
2827                     throw new IllegalArgumentException();
2828                 } else {
2829                     javax.lang.model.type.WildcardType w = (javax.lang.model.type.WildcardType)t;
2830                     return TypeFactory.typeVariableInstance(w, w.getExtendsBound(), w.getSuperBound());
2831                 }
2832             }
2833 
2834             @Override
2835             public TypeMirror getEnclosingType() {
2836                 return cap.getEnclosingType();
2837             }
2838 
2839             @Override
2840             List<? extends TypeMirror> directSuperTypes() {
2841                 return cap.directSuperTypes();
2842             }
2843 
2844             @Override
2845             boolean isSameType(DeclaredType other) {
2846                 return other == this;
2847             }
2848 
2849             @Override
2850             public String toString() {
2851                 return " CAPTURE of: " + cap.toString();
2852             }
2853         }
2854 
2855         private static class RawDeclaredType extends CoreReflDeclaredType
2856             implements Reifiable {
2857             private RawDeclaredType(Class<?> source) {
2858                 super(source);
2859             }
2860 
2861             @Override
2862             public Class<?> getSource() {
2863                 return super.getSource();
2864             }
2865 
2866             @Override
2867             public TypeMirror getEnclosingType() {
2868                 Class<?> enclosing = getSource().getEnclosingClass();
2869                 if (null == enclosing) {
2870                     return NoType.getNoneInstance();
2871                 } else {
2872                     return TypeFactory.instance(enclosing);
2873                 }
2874             }
2875 
2876             @Override
2877             public List<? extends TypeMirror> getTypeArguments() {
2878                 return Collections.emptyList();
2879             }
2880 
2881             @Override
2882             List<? extends TypeMirror> directSuperTypes() {
2883                 if (getSource().isEnum()) {
2884                     return enumSuper();
2885                 }
2886 
2887                 if (getSource() == java.lang.Object.class) {
2888                     return Collections.emptyList();
2889                 }
2890                 List<TypeMirror> res = new ArrayList<>();
2891                 Type[] superInterfaces = getSource().getInterfaces();
2892                 if (!getSource().isInterface()) {
2893                     res.add(TypeFactory.instance(getSource().getSuperclass()));
2894                 } else if (superInterfaces.length == 0) {
2895                     // Interfaces that don't extend another interface
2896                     // have java.lang.Object as a direct supertype.
2897                     return Collections.unmodifiableList(Arrays.asList(TypeFactory.instance(java.lang.Object.class)));
2898                 }
2899 
2900                 for (Type t : superInterfaces) {
2901                     res.add(TypeFactory.instance(t));
2902                 }
2903                 return Collections.unmodifiableList(res);
2904             }
2905 
2906             private List<? extends TypeMirror> enumSuper() {
2907                 Class<?> rawSuper = getSource().getSuperclass();
2908                 Type[] actualArgs = ((ParameterizedTypeImpl)getSource().getGenericSuperclass()).getActualTypeArguments();
2909 
2910                 // Reconsider this : assume the problem is making
2911                 // Enum<MyEnum> rather than just a raw enum.
2912                 return Collections.unmodifiableList(Arrays.asList(TypeFactory.instance(ParameterizedTypeImpl.make(rawSuper,
2913                                                                                                                   Arrays.copyOf(actualArgs,
2914                                                                                                                                 actualArgs.length),
2915                                                                                                                   null))));
2916             }
2917 
2918             @Override
2919             boolean isSameType(DeclaredType other) {
2920                 if (other instanceof RawDeclaredType) {
2921                     return Objects.equals(getSource(), ((RawDeclaredType)other).getSource());
2922                 } else {
2923                     return false;
2924                 }
2925             }
2926 
2927             @Override
2928             public String toString() {
2929                 return getSource().toString();
2930             }
2931         }
2932 
2933         private static class ParameterizedDeclaredType extends CoreReflDeclaredType {
2934             private ParameterizedType genericSource = null;
2935             private ParameterizedDeclaredType(Class<?> source, ParameterizedType genericSource) {
2936                 super(source);
2937                 this.genericSource = genericSource;
2938             }
2939 
2940             @Override
2941             public TypeMirror getEnclosingType() {
2942                 Type me = genericSource;
2943                 Type owner = GenericTypes.getEnclosingType(me);
2944                 if (owner == null) {
2945                     return NoType.getNoneInstance();
2946                 }
2947                 return TypeFactory.instance(owner);
2948             }
2949 
2950             @Override
2951             public List<? extends TypeMirror> getTypeArguments() {
2952                 Type[] typeArgs = genericSource.getActualTypeArguments();
2953 
2954                 int length = typeArgs.length;
2955                 if (length == 0)
2956                     return Collections.emptyList();
2957                 else {
2958                     List<TypeMirror> tmp = new ArrayList<>(length);
2959                     for (Type t : typeArgs) {
2960                         tmp.add(TypeFactory.instance(t));
2961                     }
2962                     return Collections.unmodifiableList(tmp);
2963                 }
2964             }
2965 
2966             @Override
2967             List<? extends TypeMirror> directSuperTypes() {
2968                 if (getSource() == java.lang.Object.class) {
2969                     return Collections.emptyList();
2970                 }
2971 
2972                 List<TypeMirror> res = new ArrayList<>();
2973                 Type[] superInterfaces = getSource().getGenericInterfaces();
2974                 if (!getSource().isInterface()) {
2975                     // Replace actual type arguments with our type arguments
2976                     res.add(TypeFactory.instance(substituteTypeArgs(getSource().getGenericSuperclass())));
2977                 } else if (superInterfaces.length == 0) {
2978                     // Interfaces that don't extend another interface
2979                     // have java.lang.Object as a direct supertype, plus
2980                     // possibly the interface's raw type
2981                     res.add(TypeFactory.instance(java.lang.Object.class));
2982                 }
2983 
2984                 for (Type t : superInterfaces) {
2985                     res.add(TypeFactory.instance(substituteTypeArgs(t)));
2986                 }
2987 
2988                 res.add(TypeFactory.instance(getSource())); // Add raw type
2989                 return Collections.unmodifiableList(res);
2990             }
2991 
2992             private Type substituteTypeArgs(Type type) {
2993                 if (!(type instanceof ParameterizedType)) {
2994                     return type;
2995                 }
2996 
2997                 ParameterizedType target = (ParameterizedType)type;
2998                 // Cast to get a Class instead of a plain type.
2999                 Class<?> raw = ((ParameterizedTypeImpl)target).getRawType();
3000                 Type[] actualArgs = genericSource.getActualTypeArguments();
3001 
3002                 return  ParameterizedTypeImpl.make(raw, Arrays.copyOf(actualArgs, actualArgs.length), null);
3003             }
3004 
3005             @Override
3006             boolean isSameType(DeclaredType other) {
3007                 if (other instanceof ParameterizedDeclaredType) {
3008                     return GenericTypes.isSameGenericType(genericSource,
3009                                                           ((ParameterizedDeclaredType)other).genericSource);
3010                 } else {
3011                     return false;
3012                 }
3013             }
3014 
3015             @Override
3016             public String toString() {
3017                 return getKind().toString() + " " + genericSource.toString();
3018             }
3019         }
3020 
3021         /**
3022          * Implementing class for ParameterizedType interface.
3023          * Derived from sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
3024          */
3025 
3026         private static class ParameterizedTypeImpl implements ParameterizedType {
3027             private Type[] actualTypeArguments;
3028             private Class<?>  rawType;
3029             private Type   ownerType;
3030 
3031             private ParameterizedTypeImpl(Class<?> rawType,
3032                                           Type[] actualTypeArguments,
3033                                           Type ownerType) {
3034                 this.actualTypeArguments = actualTypeArguments;
3035                 this.rawType             = rawType;
3036                 if (ownerType != null) {
3037                     this.ownerType = ownerType;
3038                 } else {
3039                     this.ownerType = rawType.getDeclaringClass();
3040                 }
3041                 validateConstructorArguments();
3042             }
3043 
3044             private void validateConstructorArguments() {
3045                 java.lang.reflect.TypeVariable/*<?>*/[] formals = rawType.getTypeParameters();
3046                 // check correct arity of actual type args
3047                 if (formals.length != actualTypeArguments.length){
3048                     throw new MalformedParameterizedTypeException();
3049                 }
3050             }
3051 
3052             /**
3053              * Static factory. Given a (generic) class, actual type arguments
3054              * and an owner type, creates a parameterized type.
3055              * This class can be instantiated with a a raw type that does not
3056              * represent a generic type, provided the list of actual type
3057              * arguments is empty.
3058              * If the ownerType argument is null, the declaring class of the
3059              * raw type is used as the owner type.
3060              * <p> This method throws a MalformedParameterizedTypeException
3061              * under the following circumstances:
3062              * If the number of actual type arguments (i.e., the size of the
3063              * array {@code typeArgs}) does not correspond to the number of
3064              * formal type arguments.
3065              * If any of the actual type arguments is not an instance of the
3066              * bounds on the corresponding formal.
3067              * @param rawType the Class representing the generic type declaration being
3068              * instantiated
3069              * @param actualTypeArguments - a (possibly empty) array of types
3070              * representing the actual type arguments to the parameterized type
3071              * @param ownerType - the enclosing type, if known.
3072              * @return An instance of {@code ParameterizedType}
3073              * @throws MalformedParameterizedTypeException - if the instantiation
3074              * is invalid
3075              */
3076             public static ParameterizedTypeImpl make(Class<?> rawType,
3077                                                      Type[] actualTypeArguments,
3078                                                      Type ownerType) {
3079                 return new ParameterizedTypeImpl(rawType, actualTypeArguments,
3080                                                  ownerType);
3081             }
3082 
3083 
3084             /**
3085              * Returns an array of {@code Type} objects representing the actual type
3086              * arguments to this type.
3087              *
3088              * <p>Note that in some cases, the returned array be empty. This can occur
3089              * if this type represents a non-parameterized type nested within
3090              * a parameterized type.
3091              *
3092              * @return an array of {@code Type} objects representing the actual type
3093              *     arguments to this type
3094              * @throws {@code TypeNotPresentException} if any of the
3095              *     actual type arguments refers to a non-existent type declaration
3096              * @throws {@code MalformedParameterizedTypeException} if any of the
3097              *     actual type parameters refer to a parameterized type that cannot
3098              *     be instantiated for any reason
3099              * @since 1.5
3100              */
3101             public Type[] getActualTypeArguments() {
3102                 return actualTypeArguments.clone();
3103             }
3104 
3105             /**
3106              * Returns the {@code Type} object representing the class or interface
3107              * that declared this type.
3108              *
3109              * @return the {@code Type} object representing the class or interface
3110              *     that declared this type
3111              */
3112             public Class<?> getRawType() {
3113                 return rawType;
3114             }
3115 
3116 
3117             /**
3118              * Returns a {@code Type} object representing the type that this type
3119              * is a member of.  For example, if this type is {@code O<T>.I<S>},
3120              * return a representation of {@code O<T>}.
3121              *
3122              * <p>If this type is a top-level type, {@code null} is returned.
3123              *
3124              * @return a {@code Type} object representing the type that
3125              *     this type is a member of. If this type is a top-level type,
3126              *     {@code null} is returned
3127              */
3128             public Type getOwnerType() {
3129                 return ownerType;
3130             }
3131 
3132             /*
3133              * From the JavaDoc for java.lang.reflect.ParameterizedType
3134              * "Instances of classes that implement this interface must
3135              * implement an equals() method that equates any two instances
3136              * that share the same generic type declaration and have equal
3137              * type parameters."
3138              */
3139             @Override
3140             public boolean equals(Object o) {
3141                 if (o instanceof ParameterizedType) {
3142                     // Check that information is equivalent
3143                     ParameterizedType that = (ParameterizedType) o;
3144 
3145                     if (this == that)
3146                         return true;
3147 
3148                     Type thatOwner   = that.getOwnerType();
3149                     Type thatRawType = that.getRawType();
3150 
3151                     return Objects.equals(ownerType, thatOwner) &&
3152                         Objects.equals(rawType, thatRawType) &&
3153                         Arrays.equals(actualTypeArguments, // avoid clone
3154                                       that.getActualTypeArguments());
3155                 } else
3156                     return false;
3157             }
3158 
3159             @Override
3160             public int hashCode() {
3161                 return
3162                     Arrays.hashCode(actualTypeArguments) ^
3163                     Objects.hashCode(ownerType) ^
3164                     Objects.hashCode(rawType);
3165             }
3166 
3167             public String toString() {
3168                 StringBuilder sb = new StringBuilder();
3169 
3170                 if (ownerType != null) {
3171                     if (ownerType instanceof Class)
3172                         sb.append(((Class)ownerType).getName());
3173                     else
3174                         sb.append(ownerType.toString());
3175 
3176                     sb.append(".");
3177 
3178                     if (ownerType instanceof ParameterizedTypeImpl) {
3179                         // Find simple name of nested type by removing the
3180                         // shared prefix with owner.
3181                         sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
3182                                                              ""));
3183                     } else
3184                         sb.append(rawType.getName());
3185                 } else
3186                     sb.append(rawType.getName());
3187 
3188                 if (actualTypeArguments != null &&
3189                     actualTypeArguments.length > 0) {
3190                     sb.append("<");
3191                     boolean first = true;
3192                     for (Type t: actualTypeArguments) {
3193                         if (!first)
3194                             sb.append(", ");
3195                         if (t instanceof Class)
3196                             sb.append(((Class)t).getName());
3197                         else
3198                             sb.append(t.toString());
3199                         first = false;
3200                     }
3201                     sb.append(">");
3202                 }
3203 
3204                 return sb.toString();
3205             }
3206         }
3207 
3208     }
3209 
3210     private static class ErasedMethodType extends ExecutableMethodType implements javax.lang.model.type.ExecutableType {
3211         private final Method m;
3212 
3213         ErasedMethodType(Method m) {
3214             super(m);
3215             this.m = Objects.requireNonNull(m);
3216         }
3217 
3218         @Override
3219         public List<javax.lang.model.type.TypeVariable> getTypeVariables() {
3220             return Collections.emptyList();
3221         }
3222 
3223         @Override
3224         public List<? extends TypeMirror> getThrownTypes() {
3225             Class<?>[] exceptions = m.getExceptionTypes();
3226             int len = exceptions.length;
3227 
3228             if (len > 0) {
3229                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3230                 for (Class<?> t : exceptions) {
3231                     res.add(TypeFactory.instance(t));
3232                 }
3233                 return Collections.unmodifiableList(res);
3234             } else {
3235                 List<TypeMirror> ret = Collections.emptyList();
3236                 return ret;
3237             }
3238         }
3239 
3240         @Override
3241         public List<? extends TypeMirror> getParameterTypes() {
3242             Class<?>[] params = m.getParameterTypes();
3243             int len = params.length;
3244 
3245             if (len > 0) {
3246                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3247                 for (Class<?> t : params) {
3248                     res.add(TypeFactory.instance(t));
3249                 }
3250                 return Collections.unmodifiableList(res);
3251             } else {
3252                 List<TypeMirror> ret = Collections.emptyList();
3253                 return ret;
3254             }
3255         }
3256 
3257         @Override
3258         public TypeMirror getReturnType() {
3259             return TypeFactory.instance(m.getReturnType());
3260         }
3261 
3262         @Override
3263         TypeMirror erasure() {
3264             return this;
3265         }
3266     }
3267 
3268     private static class ErrorType extends AbstractTypeMirror implements javax.lang.model.type.ErrorType {
3269         private static ErrorType errorType = new ErrorType();
3270 
3271         public static ErrorType getErrorInstance() {
3272             return errorType;
3273         }
3274 
3275         private ErrorType() {
3276             super(TypeKind.ERROR);
3277         }
3278 
3279         @Override
3280         public List<? extends TypeMirror> getTypeArguments() {
3281             throw new UnsupportedOperationException();
3282         }
3283 
3284         @Override
3285         public TypeMirror getEnclosingType() {
3286             throw new UnsupportedOperationException();
3287         }
3288 
3289         @Override
3290         public Element asElement() {
3291             throw new UnsupportedOperationException();
3292         }
3293 
3294         @Override
3295         List<? extends TypeMirror> directSuperTypes() {
3296             throw new UnsupportedOperationException();
3297         }
3298     }
3299 
3300     private static class ExecutableMethodType extends AbstractTypeMirror
3301         implements javax.lang.model.type.ExecutableType {
3302         private final Method m;
3303 
3304         ExecutableMethodType(Method m) {
3305             super(TypeKind.EXECUTABLE);
3306             this.m = Objects.requireNonNull(m);
3307         }
3308 
3309         @Override
3310         public List<? extends TypeMirror> getThrownTypes() {
3311             Type[] exceptions = m.getGenericExceptionTypes();
3312             int len = exceptions.length;
3313 
3314             if (len > 0) {
3315                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3316                 for (Type t : exceptions) {
3317                     res.add(TypeFactory.instance(t));
3318                 }
3319                 return Collections.unmodifiableList(res);
3320             } else {
3321                 List<TypeMirror> ret = Collections.emptyList();
3322                 return ret;
3323             }
3324         }
3325 
3326         @Override
3327         public List<javax.lang.model.type.TypeVariable> getTypeVariables() {
3328             java.lang.reflect.TypeVariable[] variables = m.getTypeParameters();
3329             int len = variables.length;
3330 
3331             if (len > 0) {
3332                 List<javax.lang.model.type.TypeVariable> res = new ArrayList<>(len);
3333                 for (java.lang.reflect.TypeVariable<?> t : variables) {
3334                     res.add(TypeFactory.typeVariableInstance(t));
3335                 }
3336                 return Collections.unmodifiableList(res);
3337             } else {
3338                 return Collections.emptyList();
3339             }
3340         }
3341 
3342         @Override
3343         public TypeMirror getReturnType() {
3344             return TypeFactory.instance(m.getGenericReturnType());
3345         }
3346 
3347         @Override
3348         public List<? extends TypeMirror> getParameterTypes() {
3349             Type[] params = m.getGenericParameterTypes();
3350             int len = params.length;
3351 
3352             if (len > 0) {
3353                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3354                 for (Type t : params) {
3355                     res.add(TypeFactory.instance(t));
3356                 }
3357                 return Collections.unmodifiableList(res);
3358             } else {
3359                 return Collections.emptyList();
3360             }
3361         }
3362 
3363         @Override
3364         List<? extends TypeMirror> directSuperTypes() {
3365             // Spec says we don't need this
3366             throw new UnsupportedOperationException();
3367         }
3368 
3369         @Override
3370         TypeMirror erasure() {
3371             return new ErasedMethodType(m);
3372         }
3373 
3374         @Override
3375         public TypeMirror getReceiverType() {
3376             throw new UnsupportedOperationException();
3377         }
3378 
3379         boolean sameSignature(ExecutableMethodType other){
3380             if (!m.getName().equals(other.m.getName())) {
3381                 return false;
3382             }
3383 
3384             List<? extends TypeMirror> thisParams = getParameterTypes();
3385             List<? extends TypeMirror> otherParams = other.getParameterTypes();
3386             if (thisParams.size() != otherParams.size()) {
3387                 return false;
3388             }
3389             for (int i = 0; i < thisParams.size(); i++) {
3390                 if (!CoreReflTypes.instance().isSameType(thisParams.get(i), otherParams.get(i))) {
3391                     return false;
3392                 }
3393             }
3394             return true;
3395         }
3396     }
3397 
3398     private static class GenericTypes {
3399         public static boolean isSameGenericType(Type t1, Type t2) {
3400             if (t1 instanceof Class) {
3401                 return ((Class)t1).equals(t2);
3402             } else if (t1 instanceof ParameterizedType) {
3403                 return ((ParameterizedType)t1).equals(t2);
3404             }
3405             throw new UnsupportedOperationException();
3406         }
3407 
3408         public static Type getEnclosingType(Type t1) {
3409             if (t1 instanceof Class) {
3410                 return ((Class)t1).getEnclosingClass();
3411             } else if (t1 instanceof ParameterizedType) {
3412                 return ((ParameterizedType)t1).getOwnerType();
3413             }
3414             throw new UnsupportedOperationException();
3415         }
3416     }
3417 
3418     private static class IntersectionDeclaredType extends AbstractTypeMirror
3419         implements javax.lang.model.type.DeclaredType {
3420         private Type[] sources = null;
3421 
3422         IntersectionDeclaredType(Type[] sources) {
3423             super(TypeKind.DECLARED);
3424             this.sources = Arrays.copyOf(Objects.requireNonNull(sources),
3425                                          sources.length);
3426         }
3427 
3428         @Override
3429         public TypeMirror getEnclosingType() {
3430             return NoType.getNoneInstance();
3431         }
3432 
3433         @Override
3434         public  Element asElement() {
3435             throw new UnsupportedOperationException();
3436         }
3437 
3438         @Override
3439         public List<? extends TypeMirror> getTypeArguments() {
3440             throw new UnsupportedOperationException();
3441         }
3442 
3443         @Override
3444         List<? extends TypeMirror> directSuperTypes() {
3445             int len = sources.length;
3446 
3447             if (len > 0) {
3448                 List<TypeMirror> res = new ArrayList<TypeMirror>(len);
3449                 for (Type c : sources) {
3450                     res.add(TypeFactory.instance(c));
3451                 }
3452                 return Collections.unmodifiableList(res);
3453             } else {
3454                 return Collections.emptyList();
3455             }
3456         }
3457     }
3458 
3459     private static class ModelWildcardType extends AbstractTypeMirror
3460         implements javax.lang.model.type.WildcardType {
3461         private java.lang.reflect.WildcardType genericSource;
3462 
3463         ModelWildcardType(java.lang.reflect.WildcardType genericSource) {
3464             super(TypeKind.WILDCARD);
3465             this.genericSource = Objects.requireNonNull(genericSource);
3466         }
3467 
3468         @Override
3469         List<? extends TypeMirror> directSuperTypes() {
3470             // TODO Add support for this operation
3471             throw new UnsupportedOperationException();
3472         }
3473 
3474         @Override
3475         public TypeMirror getExtendsBound() {
3476             Type[] t = genericSource.getUpperBounds();
3477 
3478             if (t.length == 1) {
3479                 if (t[0].equals(Object.class) && getSuperBound() != null) { // can't have both lower and upper explicit
3480                     return null;
3481                 }
3482                 return TypeFactory.instance(t[0]);
3483             }
3484             throw new UnsupportedOperationException(); // TODO: intersection type?
3485         }
3486 
3487         @Override
3488         public TypeMirror getSuperBound() {
3489             Type[] t = genericSource.getLowerBounds();
3490 
3491             if (t.length == 0) { // bound is null
3492                 return null;
3493             } else if (t.length == 1) {
3494                 return TypeFactory.instance(t[0]);
3495             }
3496             throw new UnsupportedOperationException(); // TODO: intersection type?
3497         }
3498 
3499         @Override
3500         public String toString() {
3501             return getKind() + " " + genericSource.toString();
3502         }
3503     }
3504 
3505     private static class NoType extends AbstractTypeMirror
3506         implements javax.lang.model.type.NoType {
3507         private static NoType noneType = new NoType(TypeKind.NONE, "none");
3508         private static NoType packageType = new NoType(TypeKind.PACKAGE, "package");
3509         private static NoType voidType = new NoType(TypeKind.VOID, "void");
3510 
3511         private String str;
3512 
3513         public static NoType getNoneInstance() {
3514             return noneType;
3515         }
3516 
3517         public static NoType getPackageInstance() {
3518             return packageType;
3519         }
3520 
3521         public static NoType getVoidInstance() {
3522             return voidType;
3523         }
3524 
3525         private NoType(TypeKind k, String str) {
3526             super(k);
3527             this.str = str;
3528         }
3529 
3530         @Override
3531         List<? extends TypeMirror> directSuperTypes() {
3532             // TODO We don't need this for the Package instance, how about the others?
3533             throw new UnsupportedOperationException();
3534         }
3535 
3536         @Override
3537         public String toString() {
3538             return str;
3539         }
3540     }
3541 
3542     private static class CoreReflNullType extends AbstractTypeMirror
3543         implements javax.lang.model.type.NullType {
3544         private static CoreReflNullType nullType = new CoreReflNullType();
3545 
3546         public static NullType getInstance() {
3547             return nullType;
3548         }
3549 
3550         private CoreReflNullType() {
3551             super(TypeKind.NULL);
3552         }
3553 
3554         @Override
3555         List<? extends TypeMirror> directSuperTypes() {
3556             // JLS 4.10.2 says:
3557             // "The direct supertypes of the null type are all reference types other than the null type itself."
3558             // TODO return null? an empty list? the error type? anyhow fix this
3559             throw new UnsupportedOperationException();
3560         }
3561     }
3562 
3563     private static interface Reifiable {
3564         Class<?> getSource();
3565     }
3566 
3567     private static class PrimitiveType extends AbstractTypeMirror
3568         implements javax.lang.model.type.PrimitiveType,
3569                    Reifiable {
3570         private Class<?> source;
3571 
3572         private static PrimitiveType booleanInstance = new PrimitiveType(TypeKind.BOOLEAN, boolean.class);
3573         private static PrimitiveType byteInstance =    new PrimitiveType(TypeKind.BYTE, byte.class);
3574         private static PrimitiveType charInstance =    new PrimitiveType(TypeKind.CHAR, char.class);
3575         private static PrimitiveType shortInstance =   new PrimitiveType(TypeKind.SHORT, short.class);
3576         private static PrimitiveType intInstance =     new PrimitiveType(TypeKind.INT, int.class);
3577         private static PrimitiveType longInstance =    new PrimitiveType(TypeKind.LONG, long.class);
3578         private static PrimitiveType floatInstance =   new PrimitiveType(TypeKind.FLOAT, float.class);
3579         private static PrimitiveType doubleInstance =  new PrimitiveType(TypeKind.DOUBLE, double.class);
3580 
3581         private PrimitiveType(TypeKind kind, Class<?> source) {
3582             super(kind);
3583             this.source = source;
3584         }
3585 
3586         @Override
3587         public Class<?> getSource() {
3588             return source;
3589         }
3590 
3591         static PrimitiveType instance(Class<?> c) {
3592             switch(c.getName()) {
3593             case "boolean":
3594                 return booleanInstance;
3595             case "byte":
3596                 return byteInstance;
3597             case "char":
3598                 return charInstance;
3599             case "short":
3600                 return shortInstance;
3601             case "int":
3602                 return intInstance;
3603             case "long":
3604                 return longInstance;
3605             case "float":
3606                 return floatInstance;
3607             case "double":
3608                 return doubleInstance;
3609             default:
3610                 throw new IllegalArgumentException();
3611             }
3612         }
3613 
3614         static PrimitiveType instance(TypeKind k) {
3615             switch(k) {
3616             case BOOLEAN:
3617                 return booleanInstance;
3618             case BYTE:
3619                 return byteInstance;
3620             case CHAR:
3621                 return charInstance;
3622             case SHORT:
3623                 return shortInstance;
3624             case INT:
3625                 return intInstance;
3626             case LONG:
3627                 return longInstance;
3628             case FLOAT:
3629                 return floatInstance;
3630             case DOUBLE:
3631                 return doubleInstance;
3632             default:
3633                 throw new IllegalArgumentException();
3634             }
3635         }
3636 
3637         @Override
3638         public String toString() {
3639             return source.getName();
3640         }
3641 
3642         //Types methods
3643         @Override
3644         List<? extends TypeMirror> directSuperTypes() {
3645             switch (getKind()) {
3646             case DOUBLE:
3647                 return Collections.emptyList();
3648             case FLOAT:
3649                 return Arrays.asList(doubleInstance);
3650             case LONG:
3651                 return Arrays.asList(floatInstance);
3652             case INT:
3653                 return Arrays.asList(longInstance);
3654             case CHAR:
3655                 return Arrays.asList(intInstance);
3656             case SHORT:
3657                 return Arrays.asList(intInstance);
3658             case BYTE:
3659                 return Arrays.asList(shortInstance);
3660             default:
3661                 return Collections.emptyList();
3662             }
3663         }
3664     }
3665 
3666     private static class TypeFactory {
3667         private TypeFactory() { }// no instances for you
3668 
3669         public static TypeMirror instance(Class<?> c) {
3670             if (c.isPrimitive()) {
3671                 if (c.getName().equals("void")) {
3672                     return NoType.getVoidInstance();
3673                 } else {
3674                     return PrimitiveType.instance(c);
3675                 }
3676             } else if (c.isArray()) {
3677                 return new CoreReflArrayType(c);
3678             } else if (c.isAnonymousClass() ||
3679                        c.isLocalClass() ||
3680                        c.isMemberClass() ||
3681                        c.isInterface() || // covers annotations
3682                        c.isEnum()) {
3683                 return CoreReflDeclaredType.instance(c);
3684             } else { // plain old class ??
3685                 return CoreReflDeclaredType.instance(c);
3686             }
3687         }
3688 
3689         public static TypeMirror instance(Type t) {
3690             if (t instanceof Class) {
3691                 return instance((Class)t);
3692             } else if (t instanceof ParameterizedType) {
3693                 ParameterizedType tmp = (ParameterizedType)t;
3694                 Type raw = tmp.getRawType();
3695                 if (!(raw instanceof Class)) {
3696                     throw new IllegalArgumentException(t + " " + raw );
3697                 }
3698                 return CoreReflDeclaredType.instance((Class)raw, tmp);
3699             } else if (t instanceof java.lang.reflect.WildcardType) {
3700                 return new ModelWildcardType((java.lang.reflect.WildcardType)t);
3701             } else if (t instanceof java.lang.reflect.TypeVariable) {
3702             return new CoreReflTypeVariable((java.lang.reflect.TypeVariable)t);
3703             }
3704             throw new IllegalArgumentException("Don't know how to make instance from: " + t.getClass());
3705         }
3706 
3707         public static TypeMirror instance(Field f) {
3708             return CoreReflDeclaredType.instance(f.getType(), f.getGenericType());
3709         }
3710 
3711         public static ExecutableType instance(Method m) {
3712             return new ExecutableMethodType(m);
3713         }
3714 
3715         public static javax.lang.model.type.TypeVariable typeVariableInstance(java.lang.reflect.TypeVariable<?> v) {
3716             return new CoreReflTypeVariable(v);
3717         }
3718 
3719         public static javax.lang.model.type.TypeVariable typeVariableInstance(TypeMirror source,
3720                                                         TypeMirror upperBound,
3721                                                         TypeMirror lowerBound) {
3722             return new CaptureTypeVariable(source, upperBound, lowerBound);
3723         }
3724     }
3725 
3726     private static class CoreReflTypeVariable extends AbstractTypeMirror
3727         implements javax.lang.model.type.TypeVariable {
3728         private final java.lang.reflect.TypeVariable<?> source;
3729         private boolean isCapture = false;
3730 
3731         protected CoreReflTypeVariable(java.lang.reflect.TypeVariable<?> source) {
3732             super(TypeKind.TYPEVAR);
3733             Objects.requireNonNull(source);
3734             this.source = source;
3735         }
3736 
3737         @Override
3738         public TypeMirror getUpperBound() {
3739             return new IntersectionDeclaredType(source.getBounds());
3740         }
3741 
3742         @Override
3743         public TypeMirror getLowerBound() {
3744             return CoreReflTypes.instance().getNullType();
3745         }
3746 
3747         @Override
3748         public Element asElement() {
3749             return CoreReflectionFactory.createMirror(source);
3750         }
3751 
3752         @Override
3753         List<? extends TypeMirror> directSuperTypes() {
3754             return ((AbstractTypeMirror)getUpperBound()).directSuperTypes();
3755         }
3756 
3757         @Override
3758         public int hashCode() {
3759             return source.hashCode();
3760         }
3761 
3762         @Override
3763         public boolean equals(Object other) {
3764             if (other instanceof CoreReflTypeVariable) {
3765                 return this.source.equals(((CoreReflTypeVariable)other).source);
3766             } else {
3767                 return false;
3768             }
3769         }
3770     }
3771 }