gt:                     String name = ((Tree.BaseType) type).getIdentifier().getText();
context: /*
   * Copyright Red Hat Inc. and/or its affiliates and other contributors
   * as indicated by the authors tag. All rights reserved.
   *
   * This copyrighted material is made available to anyone wishing to use,
   * modify, copy, or redistribute it subject to the terms and conditions
   * of the GNU General Public License version 2.
   * 
   * This particular file is subject to the "Classpath" exception as provided in the 
   * LICENSE file that accompanied this code.
   * 
   * This program is distributed in the hope that it will be useful, but WITHOUT A
   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
   * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
   * You should have received a copy of the GNU General Public License,
   * along with this distribution; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   * MA  02110-1301, USA.
   */
  
  package com.redhat.ceylon.compiler.java.codegen;
  
  import static com.redhat.ceylon.compiler.typechecker.tree.TreeUtil.isForBackend;
  
  import java.util.Iterator;
  
  import javax.tools.JavaFileObject;
  
  import com.redhat.ceylon.common.Backend;
  import com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException;
  import com.redhat.ceylon.compiler.java.loader.SourceDeclarationVisitor;
  import com.redhat.ceylon.compiler.typechecker.context.PhasedUnit;
  import com.redhat.ceylon.compiler.typechecker.tree.Tree;
  import com.redhat.ceylon.compiler.typechecker.tree.Tree.ClassOrInterface;
  import com.redhat.ceylon.compiler.typechecker.tree.Tree.CompilationUnit;
  import com.redhat.ceylon.compiler.typechecker.tree.Tree.Declaration;
  import com.redhat.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor;
  import com.redhat.ceylon.compiler.typechecker.tree.Tree.PackageDescriptor;
  import com.redhat.ceylon.compiler.typechecker.tree.TreeUtil;
  import com.redhat.ceylon.model.loader.NamingBase.Suffix;
  import com.redhat.ceylon.model.loader.model.OutputElement;
  import com.redhat.ceylon.model.typechecker.model.FunctionOrValue;
  import com.redhat.ceylon.model.typechecker.model.Parameter;
  import com.redhat.ceylon.model.typechecker.model.Setter;
  import com.redhat.ceylon.model.typechecker.model.TypedDeclaration;
  import com.redhat.ceylon.model.typechecker.model.Value;
  import com.sun.tools.javac.code.Flags;
  import com.sun.tools.javac.main.OptionName;
  import com.sun.tools.javac.tree.JCTree;
  import com.sun.tools.javac.tree.JCTree.JCAnnotation;
  import com.sun.tools.javac.tree.JCTree.JCBlock;
  import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  import com.sun.tools.javac.tree.JCTree.JCExpression;
  import com.sun.tools.javac.tree.JCTree.JCImport;
  import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
  import com.sun.tools.javac.tree.JCTree.JCModifiers;
  import com.sun.tools.javac.tree.JCTree.JCNewClass;
  import com.sun.tools.javac.tree.JCTree.JCStatement;
  import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
  import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  import com.sun.tools.javac.util.Context;
  import com.sun.tools.javac.util.List;
  import com.sun.tools.javac.util.ListBuffer;
  import com.sun.tools.javac.util.Name;
  import com.sun.tools.javac.util.Options;
  import com.sun.tools.javac.util.Position.LineMap;
  
  /**
   * Main transformer that delegates all transforming of ceylon to java to auxiliary classes.
   */
  public class CeylonTransformer extends AbstractTransformer {
      private Options options;
      private LineMap map;
      private JavaFileObject fileObject;
      public int disableAnnotations = 0;
      static final int DISABLE_MODEL_ANNOS = 1<<0;
      static final int DISABLE_USER_ANNOS = 1<<1;
      CeylonVisitor visitor;
      
      public static CeylonTransformer getInstance(Context context) {
          CeylonTransformer trans = context.get(CeylonTransformer.class);
          if (trans == null) {
              trans = new CeylonTransformer(context);
              context.put(CeylonTransformer.class, trans);
          }
          return trans;
      }
  
      public CeylonTransformer(Context context) {
          super(context);
          setup(context);
      }
  
      private void setup(Context context) {
          options = Options.instance(context);
          // It's a bit weird to see "invokedynamic" set here,
          // but it has to be done before Resolve.instance().
          options.put("invokedynamic", "invokedynamic");
      }
  
      @Override
      public void setMap(LineMap map) {
          this.map = map;
      }
  
      @Override
      protected LineMap getMap() {
          return map;
      }
  
      public void setFileObject(JavaFileObject fileObject) {
          this.fileObject = fileObject;
      }
      
      public JavaFileObject getFileObject() {
          return fileObject;
      }
  
      /**
       * In this pass we only make an empty placeholder which we'll fill in the
       * EnterCeylon phase later on
       */
      public JCCompilationUnit makeJCCompilationUnitPlaceholder(Tree.CompilationUnit t, JavaFileObject file, String pkgName, PhasedUnit phasedUnit) {
          JCExpression pkg = pkgName != null ? getPackage(pkgName) : null;
          at(t);
          
          List<JCTree> defs = makeDefs(t);
          
          JCCompilationUnit topLev = new CeylonCompilationUnit(List.<JCTree.JCAnnotation> nil(), pkg, defs, null, null, null, null, t, phasedUnit);
  
          topLev.lineMap = getMap();
          topLev.sourcefile = file;
          topLev.isCeylonProgram = true;
  
          return topLev;
      }
  
      private enum WantedDeclaration {
          Normal, Annotation, AnnotationSequence;
      }
      
      private List<JCTree> makeDefs(CompilationUnit t) {
          final ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
          
          t.visit(new SourceDeclarationVisitor(){
              @Override
              public void loadFromSource(Declaration decl) {
                  if(!checkNative(decl))
                      return;
                  long flags = decl instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
                  String name = Naming.toplevelClassName("", decl);
                  
                  defs.add(makeClassDef(decl, flags, name, WantedDeclaration.Normal));
                  if(decl instanceof Tree.AnyInterface){
                      String implName = Naming.getImplClassName(name);
                      defs.add(makeClassDef(decl, 0, implName, WantedDeclaration.Normal));
                  }
                  // only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
                  if(options.get(OptionName.BOOTSTRAPCEYLON) != null
                          && decl instanceof Tree.AnyClass
                          && TreeUtil.hasAnnotation(decl.getAnnotationList(), "annotation", decl.getUnit())){
                      String annotationName = Naming.suffixName(Suffix.$annotation$, name);
                      defs.add(makeClassDef(decl, Flags.ANNOTATION, annotationName, WantedDeclaration.Annotation));
                      
                      for(Tree.StaticType sat : ((Tree.AnyClass)decl).getSatisfiedTypes().getTypes()){
                          if(sat instanceof Tree.BaseType 
                                  && ((Tree.BaseType) sat).getIdentifier().getText().equals("SequencedAnnotation")){
                              String annotationsName = Naming.suffixName(Suffix.$annotations$, name);
                              defs.add(makeClassDef(decl, Flags.ANNOTATION, annotationsName, WantedDeclaration.AnnotationSequence));
                          }
                      }
                  }
              }
  
              private JCTree makeClassDef(Declaration decl, long flags, String name, WantedDeclaration wantedDeclaration) {
                  ListBuffer<JCTree.JCTypeParameter> typarams = new ListBuffer<JCTree.JCTypeParameter>();
                  if(decl instanceof Tree.ClassOrInterface){
                      Tree.ClassOrInterface classDecl = (ClassOrInterface) decl;
                      if(classDecl.getTypeParameterList() != null){
                          for(Tree.TypeParameterDeclaration typeParamDecl : classDecl.getTypeParameterList().getTypeParameterDeclarations()){
                              // we don't need a valid name, just a name, and making it BOGUS helps us find it later if it turns out
                              // we failed to reset everything properly
                              typarams.add(make().TypeParameter(names().fromString("BOGUS-"+typeParamDecl.getIdentifier().getText()), List.<JCExpression>nil()));
                          }
                      }
                  }
  
                  return make().ClassDef(make().Modifiers(flags | Flags.PUBLIC), names().fromString(name), 
                          typarams.toList(), null, List.<JCExpression>nil(), makeClassBody(decl, wantedDeclaration));
              }
  
              private List<JCTree> makeClassBody(Declaration decl, WantedDeclaration wantedDeclaration) {
                  // only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
                  if(wantedDeclaration == WantedDeclaration.Annotation){
                      ListBuffer<JCTree> body = new ListBuffer<JCTree>();
                      for(Tree.Parameter param : ((Tree.ClassDefinition)decl).getParameterList().getParameters()){
                          String name;
                          
                          JCExpression type = make().TypeArray(make().Type(syms().stringType));
                          if(param instanceof Tree.InitializerParameter)
                              name = ((Tree.InitializerParameter)param).getIdentifier().getText();
                          else if(param instanceof Tree.ParameterDeclaration){
                              Tree.TypedDeclaration typedDeclaration = ((Tree.ParameterDeclaration)param).getTypedDeclaration();
                              name = typedDeclaration.getIdentifier().getText();
                              type = getAnnotationTypeFor(typedDeclaration.getType());
                          }else
                              name = "ERROR";
                          JCMethodDecl method
                              = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString(name), 
                                  type,
                                  List.<JCTypeParameter>nil(), 
                                  List.<JCVariableDecl>nil(),
                                  List.<JCExpression>nil(), 
                                  null, 
                                  null);
                          body.append(method);
                      }
                      return body.toList();
                  }
                  if(wantedDeclaration == WantedDeclaration.AnnotationSequence){
                      String name = Naming.toplevelClassName("", decl);
                      String annotationName = Naming.suffixName(Suffix.$annotation$, name);
                      JCExpression type = make().TypeArray(make().Ident(names().fromString(annotationName)));
                      JCMethodDecl method
                              = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString("value"), 
                                  type,
                                  List.<JCTypeParameter>nil(), 
                                  List.<JCVariableDecl>nil(),
                                  List.<JCExpression>nil(), 
                                  null, 
                                  null);
                      return List.<JCTree>of(method);
                  }
                  return List.<JCTree>nil();
              }
  
              private JCExpression getAnnotationTypeFor(Tree.Type type) {
                  if(type instanceof Tree.BaseType){
  