summaryrefslogblamecommitdiff
path: root/src/compiler/scala/reflect/internal/Definitions.scala
blob: 24fc7c7cc4d9f1b1df6197f4b587cec8af7d2fde (plain) (tree)
1
2
3
4
5
6
7
8
9
                            
                                

                          
 
                     
                
 
                            
                                              
              
                        
                                     
 
                                                           
                      
 

                                             

















                                                       






                                                                               
 
                                                                                                                  
                                                             
                                                                 
   
                                                                                                                             

                                                                
                                           
   
                                                                                                                                
                                                                         
 

                               
                             





















                                              
                               

     


















                                                                                           





                                                                                                                                     
                                                                                                    


                                                                                                    

                                                                                                       

                                                                                   
 




                                                       

                                           
                                                                                
 
                                 
                                                                 
 








                                                           


                                                                 
 

                                                                                                        
                                                                              
                                                    









                   
                                                                                           
                                                                         

   
                                                                                     
                                     
                                                
 


                                               





                                                                        






                                                                     

                                                   
     

                                                                           
                                                                                                       

                                                   
 







                                                                                    
                                                                                                         







                                                        
                                                                                 
                                                                                                                         

                                        
                                                                                                                                     




                                                                              
                                                                   
                                                               
                                                                  
                                                            
                                                                       
                                                              
 
                                                                 
 
                                              
                                              

                                                             
 
                                     


                                              
 

                                                                              
 























                                                                     
 











                                                                   
                


                                                                                     


                                                                     
                                                                    
                                             
                                    
 
                                                                                            
                                                                                                                    


                                                            

                                

                                                                                                                     
                   

                                                                      
 

                                                                                                                                      
                                       
                                                                            












                                                                                  
                                      
                                                                               
                                                                        
                                                                             

                                                                                                   

                                                                      
                                                                                    
 
                                    
                                                                             

                                                                                                     
                                                                         
                                                                        
                                                                             
                                                                               
                                                                
 
                          

                                                         





                                                                                                   
                                                                  
                                                         
 


                                                                     
                                                                         
                                                                
 








                                                                                             

                       

                                                                               
 
                                                                            
                                                                                         


                                                                           
                                                             




                                                                                      
                                                                                    

                                    

                                                                           
                                                                   


                                                                                       
                                                                


                                                                                      


                                                                                           
 
                                                                                        
                                                                                                                          
                                                                           
                                                                                             
                                                                                                        


                                                                                 
 



                                                                                                                                        

                                                                                    
 



                                                                                                        
                                                                                                  
 
                                                                                         



                                                                                                          
 





                                                                                             
                                               
                                                                                      





                                                                       
 
                                                                               

                          








                                                                                             
                                                            



                                                                                   
 
                               
                                                            
                                                                              
                                                           



                                                               

                                    

                                                                                   
                                                                 
                                                                               

                                                                                        



                                                                    
                                                                            
                                                               

                                                                
                                                                                               

                                                                



                                                                                             










                                                                                         







                                                                                                                  


                                                                                                                             
 

                                                                                                
 
                     

                                                           

                                                                  
 


                                                                                                           
 
                                                                               
 
                                                                                                
 

                                                                             
                                                                                 
 




                                                                                                                





                                                                    


                                                                      
 
                                                 
                                                                                             
                                                                                    
                                      
                                     
     




                                                                                                        

                                                             


                                                                                                                      
                                                                                                  






                                                                                                                           









                                                                               
                      


                                                                                                
 
                                            
                                                        
 
                                                                                         
                                                                                 
                                                                






                                                                
       

              
 

                                                                        





                                                                                   
















                                                                      






                                                                                                   
 
                                                                                          
                                                                                 

                                                                                        
                                                                                
 




                                                                                            
 



                                                                       
 
                                                                      
 


                                                                                      
 
                                                                
                                                    

                                                                



               




                                                                            





                                                                           
 







                                                                               
 
                                                  

                                                       
                              
                                                      
                                       
 

                                                                                
 



















                                                                            


                   
 
                                                                           



                                                            
                                                                                                                                                 

                                                                              
                                                                                             
 
                                                                                    

                                                   




                                                          
                                                                                       


                                                

                       
     
 
                                 





                                                                                       









                                                                                  
                                                                                                                                            

                                                                                                         
 
                                                                     















                                                                                  
                                                              













                                                                                    
 


                                                                                       




                                                                               
                      



                                                        







                                                                                                


                                                                      




                                                                                      
                                       
     






                                                                          


                                                  








                                                                                     
                                                    




                                                                                          

                                                                                                                              
                                                                                                 

                                                                      
                                                                                              
 







                                                                 
 
                    

                                                                                         

                                                                                     


                                                                 






                                                                           


                                                                                          



                                                                                  
 
                              


                                                                                                  

                  


























                                                                                                                          







                                                                         


                                                                                                                                       
                                                                              


                                                                                    







                                                                                                       
 
                                                                                                   



                                                                          
                                           



                                                  

                                              
                                                                                                           
                                                                                            
                                                                
          

     
                                                         

                                               

                                                              
 




                                                                                      
 










                                                                                          
     
 






                                                                   
                                            


















                                                                                     
 

                                                     
 
                                                   
                                                
 

                                                      
 
                                                    
                                                 
 


                                                                                 


                                                                                              













                                                                                  
                                                        
                                              



                                                                                    













                                                                                
       
     




                                                                         
     
 

                                                               
 




                                                                            
                                                                                  
     

                                                             
 

                                                     
 

                                                                  

                                                               
                      






                                                                                 
                                                                                               



         


                                                        
                                                                                          
 






                                                                                       
                                                    
 
                                                                                                        
                                                               

                                                            
 
                                                                                      
     
 
                                                                                                                                     





                                                                                                 
 
                                                     
     
 

                                    
                                                                                                                  

                                                                                     
                                                                                                                   

                                                                                          
 


                                                               
 
                                                                                

                                                                                         


                                                                                                          
                                                                                            
 
                                   
                                                                           

                                                                                               
                                                                                     
 
                                                                 
                                                                  
 

                                                                     
       
                                                
                                         
                                               

                                                          
                                                  



                                                          
 
                                            
                                       




                                                             
                                                                
                                                                                                

                                                                                         
                                           
                                                                                                
                                                                                           
                                                            
       
                           

                                                       

     



                                                                       
                                               
                                        
                                                 




                                                      
                                                          


                                                              
                                                 



                                                      










                                                                                          
                
                               
 

                                                                                      
                                                                                                         
                                                
 


                                                           

                                             
 
                                                                                                 
                                       


                               





                       
                           














                            
                            
                            
                 

                             
       
 
                          
            



                                                                           
                                                                    
                                                        
                                                               


                                                                                                           
                                                                                                   


                                                                                           
                         


               
                                                                                    
                                                         
                                                                       

        
                                                                  
                                                        
                                                             


     
/* NSC -- new Scala compiler
 * Copyright 2005-2011 LAMP/EPFL
 * @author  Martin Odersky
 */

package scala.reflect
package internal

import annotation.{ switch }
import scala.collection.{ mutable, immutable }
import Flags._
import PartialFunction._
import scala.reflect.{ mirror => rm }

trait Definitions extends reflect.api.StandardDefinitions {
  self: SymbolTable =>

  object definitions extends DefinitionsClass

  // [Eugene] find a way to make these non-lazy
  lazy val ByteTpe    = definitions.ByteClass.asType
  lazy val ShortTpe   = definitions.ShortClass.asType
  lazy val CharTpe    = definitions.CharClass.asType
  lazy val IntTpe     = definitions.IntClass.asType
  lazy val LongTpe    = definitions.LongClass.asType
  lazy val FloatTpe   = definitions.FloatClass.asType
  lazy val DoubleTpe  = definitions.DoubleClass.asType
  lazy val BooleanTpe = definitions.BooleanClass.asType
  lazy val UnitTpe    = definitions.UnitClass.asType
  lazy val AnyTpe     = definitions.AnyClass.asType
  lazy val ObjectTpe  = definitions.ObjectClass.asType
  lazy val AnyValTpe  = definitions.AnyValClass.asType
  lazy val AnyRefTpe  = definitions.AnyRefClass.asType
  lazy val NothingTpe = definitions.NothingClass.asType
  lazy val NullTpe    = definitions.NullClass.asType
  lazy val StringTpe  = definitions.StringClass.asType

  /** Since both the value parameter types and the result type may
   *  require access to the type parameter symbols, we model polymorphic
   *  creation as a function from those symbols to (formal types, result type).
   *  The Option is to distinguish between nullary methods and empty-param-list
   *  methods.
   */
  private type PolyMethodCreator = List[Symbol] => (Option[List[Type]], Type)

  private def enterNewClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): ClassSymbol = {
    val clazz = owner.newClassSymbol(name, NoPosition, flags)
    clazz setInfoAndEnter ClassInfoType(parents, newScope, clazz)
  }
  private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol = {
    val msym   = owner.newMethod(name.encode, NoPosition, flags)
    val params = msym.newSyntheticValueParams(formals)
    msym setInfo MethodType(params, restpe)
  }
  private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol =
    owner.info.decls enter newMethod(owner, name, formals, restpe, flags)

  // the scala value classes
  trait ValueClassDefinitions {
    self: DefinitionsClass =>

    import ClassfileConstants._

    private val nameToWeight = Map[Name, Int](
      tpnme.Byte   -> 2,
      tpnme.Char   -> 3,
      tpnme.Short  -> 4,
      tpnme.Int    -> 12,
      tpnme.Long   -> 24,
      tpnme.Float  -> 48,
      tpnme.Double -> 96
    )

    private val nameToTag = Map[Name, Char](
      tpnme.Byte    -> BYTE_TAG,
      tpnme.Char    -> CHAR_TAG,
      tpnme.Short   -> SHORT_TAG,
      tpnme.Int     -> INT_TAG,
      tpnme.Long    -> LONG_TAG,
      tpnme.Float   -> FLOAT_TAG,
      tpnme.Double  -> DOUBLE_TAG,
      tpnme.Boolean -> BOOL_TAG,
      tpnme.Unit    -> VOID_TAG
    )

    private def catastrophicFailure() =
      abort("Could not find value classes! This is a catastrophic failure.  scala " +
        scala.util.Properties.versionString)

    private def valueClassSymbol(name: TypeName): ClassSymbol = {
      getMember(ScalaPackageClass, name) match {
        case x: ClassSymbol => x
        case _              => catastrophicFailure()
      }
    }
    private def valueClassCompanion(name: TermName): ModuleSymbol = {
      getMember(ScalaPackageClass, name) match {
        case x: ModuleSymbol => x
        case _               => catastrophicFailure()
      }
    }
    private def valueCompanionMember(className: Name, methodName: TermName): MethodSymbol =
      getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName)

    private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f)
    private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = syms zip (syms map (x => f(x.name))) toMap
    private def symbolsMapFilt[T](syms: List[Symbol], p: Name => Boolean, f: Name => T) = symbolsMap(syms filter (x => p(x.name)), f)

    private def boxedName(name: Name) = sn.Boxed(name.toTypeName)

    lazy val abbrvTag         = symbolsMap(ScalaValueClasses, nameToTag) withDefaultValue OBJECT_TAG
    lazy val numericWeight    = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight)
    lazy val boxedModule      = classesMap(x => getModule(boxedName(x)))
    lazy val boxedClass       = classesMap(x => getClass(boxedName(x)))
    lazy val refClass         = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref"))
    lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref"))
    lazy val boxMethod        = classesMap(x => valueCompanionMember(x, nme.box))
    lazy val unboxMethod      = classesMap(x => valueCompanionMember(x, nme.unbox))

    def isNumericSubClass(sub: Symbol, sup: Symbol) = (
         (numericWeight contains sub)
      && (numericWeight contains sup)
      && (numericWeight(sup) % numericWeight(sub) == 0)
    )

    /** Is symbol a numeric value class? */
    def isNumericValueClass(sym: Symbol) = ScalaNumericValueClasses contains sym

    def isGetClass(sym: Symbol) =
      (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss)

    lazy val UnitClass    = valueClassSymbol(tpnme.Unit)
    lazy val ByteClass    = valueClassSymbol(tpnme.Byte)
    lazy val ShortClass   = valueClassSymbol(tpnme.Short)
    lazy val CharClass    = valueClassSymbol(tpnme.Char)
    lazy val IntClass     = valueClassSymbol(tpnme.Int)
    lazy val LongClass    = valueClassSymbol(tpnme.Long)
    lazy val FloatClass   = valueClassSymbol(tpnme.Float)
    lazy val DoubleClass  = valueClassSymbol(tpnme.Double)
    lazy val BooleanClass = valueClassSymbol(tpnme.Boolean)
      lazy val Boolean_and = getMember(BooleanClass, nme.ZAND)
      lazy val Boolean_or  = getMember(BooleanClass, nme.ZOR)
      lazy val Boolean_not = getMember(BooleanClass, nme.UNARY_!)

    lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass)

    def ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass)
    def ScalaValueClasses: List[ClassSymbol] = List(
      UnitClass,
      BooleanClass,
      ByteClass,
      ShortClass,
      CharClass,
      IntClass,
      LongClass,
      FloatClass,
      DoubleClass
    )
    def ScalaValueClassCompanions: List[Symbol] = ScalaValueClasses map (_.companionSymbol)
    def ScalaPrimitiveValueClasses: List[ClassSymbol] = ScalaValueClasses
  }

  abstract class DefinitionsClass extends AbsDefinitions with ValueClassDefinitions {
    private var isInitialized = false
    def isDefinitionsInitialized = isInitialized

    // symbols related to packages
    var emptypackagescope: Scope = null //debug

    // TODO - having these as objects means they elude the attempt to
    // add synchronization in SynchronizedSymbols.  But we should either
    // flip on object overrides or find some other accomodation, because
    // lazy vals are unnecessarily expensive relative to objects and it
    // is very beneficial for a handful of bootstrap symbols to have
    // first class identities
    sealed trait WellKnownSymbol extends Symbol {
      this initFlags TopLevelCreationFlags
    }
    // Features common to RootClass and RootPackage, the roots of all
    // type and term symbols respectively.
    sealed trait RootSymbol extends WellKnownSymbol {
      final override def isRootSymbol = true
      override def owner              = NoSymbol
      override def typeOfThis         = thisSym.tpe
    }
    // This is the package _root_.  The actual root cannot be referenced at
    // the source level, but _root_ is essentially a function => <root>.
    final object RootPackage extends PackageSymbol(NoSymbol, NoPosition, nme.ROOTPKG) with RootSymbol {
      this setInfo NullaryMethodType(RootClass.tpe)
      RootClass.sourceModule = this

      override def isRootPackage = true
    }
    // This is <root>, the actual root of everything except the package _root_.
    // <root> and _root_ (RootPackage and RootClass) should be the only "well known"
    // symbols owned by NoSymbol.  All owner chains should go through RootClass,
    // although it is probable that some symbols are created as direct children
    // of NoSymbol to ensure they will not be stumbled upon.  (We should designate
    // a better encapsulated place for that.)
    final object RootClass extends PackageClassSymbol(NoSymbol, NoPosition, tpnme.ROOT) with RootSymbol {
      this setInfo rootLoader

      override def isRoot            = true
      override def isEffectiveRoot   = true
      override def isStatic          = true
      override def isNestedClass     = false
      override def ownerOfNewSymbols = EmptyPackageClass
    }
    // The empty package, which holds all top level types without given packages.
    final object EmptyPackage extends PackageSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
      override def isEmptyPackage = true
    }
    final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
      override def isEffectiveRoot     = true
      override def isEmptyPackageClass = true
    }
    // It becomes tricky to create dedicated objects for other symbols because
    // of initialization order issues.
    lazy val JavaLangPackage      = getRequiredPackage(sn.JavaLang)
    lazy val JavaLangPackageClass = JavaLangPackage.moduleClass
    lazy val ScalaPackage         = getRequiredPackage(nme.scala_)
    lazy val ScalaPackageClass    = ScalaPackage.moduleClass
    lazy val RuntimePackage       = getRequiredPackage("scala.runtime")
    lazy val RuntimePackageClass  = RuntimePackage.moduleClass

    lazy val JavaLangEnumClass = requiredClass[java.lang.Enum[_]]

    // convenient one-argument parameter lists
    lazy val anyparam     = List(AnyClass.tpe)
    lazy val anyvalparam  = List(AnyValClass.typeConstructor)
    lazy val anyrefparam  = List(AnyRefClass.typeConstructor)

    // private parameter conveniences
    private def booltype    = BooleanClass.tpe
    private def inttype     = IntClass.tpe
    private def stringtype  = StringClass.tpe

    // Java types
    def javaTypeName(jclazz: Class[_]): TypeName = newTypeName(jclazz.getName)

    def javaTypeToValueClass(jtype: Class[_]): Symbol = jtype match {
      case java.lang.Void.TYPE      => UnitClass
      case java.lang.Byte.TYPE      => ByteClass
      case java.lang.Character.TYPE => CharClass
      case java.lang.Short.TYPE     => ShortClass
      case java.lang.Integer.TYPE   => IntClass
      case java.lang.Long.TYPE      => LongClass
      case java.lang.Float.TYPE     => FloatClass
      case java.lang.Double.TYPE    => DoubleClass
      case java.lang.Boolean.TYPE   => BooleanClass
      case _                        => NoSymbol
    }
    def valueClassToJavaType(sym: Symbol): Class[_] = sym match {
      case UnitClass    => java.lang.Void.TYPE
      case ByteClass    => java.lang.Byte.TYPE
      case CharClass    => java.lang.Character.TYPE
      case ShortClass   => java.lang.Short.TYPE
      case IntClass     => java.lang.Integer.TYPE
      case LongClass    => java.lang.Long.TYPE
      case FloatClass   => java.lang.Float.TYPE
      case DoubleClass  => java.lang.Double.TYPE
      case BooleanClass => java.lang.Boolean.TYPE
      case _            => null
    }

    private def fixupAsAnyTrait(tpe: Type): Type = tpe match {
      case ClassInfoType(parents, decls, clazz) =>
        if (parents.head.typeSymbol == AnyClass) tpe
        else {
          assert(parents.head.typeSymbol == ObjectClass, parents)
          ClassInfoType(AnyClass.tpe :: parents.tail, decls, clazz)
        }
      case PolyType(tparams, restpe) =>
        PolyType(tparams, fixupAsAnyTrait(restpe))
//      case _ => tpe
    }

    // top types
    lazy val AnyClass    = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT)
    lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.tpe)
    lazy val ObjectClass = getRequiredClass(sn.Object.toString)

    // Note: this is not the type alias AnyRef, it's a companion-like
    // object used by the @specialize annotation.
    lazy val AnyRefModule = getMember(ScalaPackageClass, nme.AnyRef)
    @deprecated("Use AnyRefModule", "2.10.0")
    def Predef_AnyRef = AnyRefModule

    lazy val AnyValClass: ClassSymbol = (ScalaPackageClass.info member tpnme.AnyVal orElse {
      val anyval    = enterNewClass(ScalaPackageClass, tpnme.AnyVal, List(AnyClass.tpe, NotNullClass.tpe), ABSTRACT)
      val av_constr = anyval.newClassConstructor(NoPosition)
      anyval.info.decls enter av_constr
      anyval
    }).asInstanceOf[ClassSymbol]

      lazy val AnyVal_getClass = enterNewMethod(AnyValClass, nme.getClass_, Nil, getClassReturnType(AnyValClass.tpe))

    // bottom types
    lazy val RuntimeNothingClass  = getClass(fulltpnme.RuntimeNothing)
    lazy val RuntimeNullClass     = getClass(fulltpnme.RuntimeNull)

    sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) {
      locally {
        this initFlags ABSTRACT | FINAL
        this setInfoAndEnter ClassInfoType(List(parent.tpe), newScope, this)
      }
      final override def isBottomClass = true
    }
    final object NothingClass extends BottomClassSymbol(tpnme.Nothing, AnyClass) {
      override def isSubClass(that: Symbol) = true
    }
    final object NullClass extends BottomClassSymbol(tpnme.Null, AnyRefClass) {
      override def isSubClass(that: Symbol) = (
           (that eq AnyClass)
        || (that ne NothingClass) && (that isSubClass ObjectClass)
      )
    }

    // exceptions and other throwables
    lazy val ClassCastExceptionClass        = requiredClass[ClassCastException]
    lazy val IndexOutOfBoundsExceptionClass = getClass(sn.IOOBException)
    lazy val InvocationTargetExceptionClass = getClass(sn.InvTargetException)
    lazy val MatchErrorClass                = requiredClass[MatchError]
    lazy val NonLocalReturnControlClass     = requiredClass[scala.runtime.NonLocalReturnControl[_]]
    lazy val NullPointerExceptionClass      = getClass(sn.NPException)
    lazy val ThrowableClass                 = getClass(sn.Throwable)
    lazy val UninitializedErrorClass        = requiredClass[UninitializedFieldError]

    // fundamental reference classes
    lazy val PartialFunctionClass       = requiredClass[PartialFunction[_,_]]
    lazy val AbstractPartialFunctionClass = getRequiredClass("scala.runtime.AbstractPartialFunction")
    lazy val SymbolClass                = getRequiredClass("scala.Symbol")
    lazy val StringClass                = requiredClass[java.lang.String]
    lazy val StringModule               = StringClass.linkedClassOfClass
    lazy val ClassClass                 = getRequiredClass("java.lang.Class")
      def Class_getMethod               = getMember(ClassClass, nme.getMethod_)
    lazy val DynamicClass               = requiredClass[Dynamic]

    // fundamental modules
    lazy val SysPackage = getPackageObject("scala.sys")
      def Sys_error    = getMember(SysPackage, nme.error)

    // Modules whose members are in the default namespace
    lazy val UnqualifiedModules = List(PredefModule, ScalaPackage, JavaLangPackage)
    // Those modules and their module classes
    lazy val UnqualifiedOwners  = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass)

    lazy val PredefModule      = requiredModule[scala.Predef.type]
    lazy val PredefModuleClass = PredefModule.moduleClass

      def Predef_classOf      = getMember(PredefModule, nme.classOf)
      def Predef_identity     = getMember(PredefModule, nme.identity)
      def Predef_conforms     = getMember(PredefModule, nme.conforms)
      def Predef_wrapRefArray = getMember(PredefModule, nme.wrapRefArray)
      def Predef_???          = getMember(PredefModule, nme.???)

    /** Is `sym` a member of Predef with the given name?
     *  Note: DON't replace this by sym == Predef_conforms/etc, as Predef_conforms is a `def`
     *  which does a member lookup (it can't be a lazy val because we might reload Predef
     *  during resident compilations).
     */
    def isPredefMemberNamed(sym: Symbol, name: Name) = (
      (sym.name == name) && (sym.owner == PredefModule.moduleClass)
    )

    /** Specialization.
     */
    lazy val SpecializableModule  = requiredModule[Specializable]
    lazy val GroupOfSpecializable = getMember(SpecializableModule, tpnme.Group)

    lazy val ConsoleModule: Symbol      = getRequiredModule("scala.Console")
    lazy val ScalaRunTimeModule: Symbol = getRequiredModule("scala.runtime.ScalaRunTime")
    lazy val SymbolModule: Symbol       = getRequiredModule("scala.Symbol")
    lazy val Symbol_apply               = SymbolModule.info decl nme.apply

      def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq)
      def arrayApplyMethod = getMember(ScalaRunTimeModule, nme.array_apply)
      def arrayUpdateMethod = getMember(ScalaRunTimeModule, nme.array_update)
      def arrayLengthMethod = getMember(ScalaRunTimeModule, nme.array_length)
      def arrayCloneMethod = getMember(ScalaRunTimeModule, nme.array_clone)
      def ensureAccessibleMethod = getMember(ScalaRunTimeModule, nme.ensureAccessible)
      def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements)

    // classes with special meanings
    lazy val StringAddClass   = getRequiredClass("scala.runtime.StringAdd")
    lazy val ArrowAssocClass  = getRequiredClass("scala.Predef.ArrowAssoc")
    lazy val StringAdd_+      = getMember(StringAddClass, nme.PLUS)
    lazy val NotNullClass     = getRequiredClass("scala.NotNull")
    lazy val ScalaNumberClass           = getRequiredClass("scala.math.ScalaNumber")
    lazy val TraitSetterAnnotationClass = getRequiredClass("scala.runtime.TraitSetter")
    lazy val DelayedInitClass = requiredClass[scala.DelayedInit]
      def delayedInitMethod = getMember(DelayedInitClass, nme.delayedInit)
      // a dummy value that communicates that a delayedInit call is compiler-generated
      // from phase UnCurry to phase Constructors
      // !!! This is not used anywhere (it was checked in that way.)
      // def delayedInitArgVal = EmptyPackageClass.newValue(NoPosition, nme.delayedInitArg)
      //   .setInfo(UnitClass.tpe)

    lazy val TypeConstraintClass   = getRequiredClass("scala.annotation.TypeConstraint")
    lazy val SingletonClass        = enterNewClass(ScalaPackageClass, tpnme.Singleton, anyparam, ABSTRACT | TRAIT | FINAL)
    lazy val SerializableClass     = getRequiredClass("scala.Serializable")
    lazy val JavaSerializableClass = getClass(sn.JavaSerializable) modifyInfo fixupAsAnyTrait
    lazy val ComparableClass       = getRequiredClass("java.lang.Comparable") modifyInfo fixupAsAnyTrait
    lazy val JavaCloneableClass    = getRequiredClass("java.lang.Cloneable")
    lazy val RemoteInterfaceClass  = getRequiredClass("java.rmi.Remote")
    lazy val RemoteExceptionClass  = getRequiredClass("java.rmi.RemoteException")

    lazy val ByNameParamClass       = specialPolyClass(tpnme.BYNAME_PARAM_CLASS_NAME, COVARIANT)(_ => AnyClass.tpe)
    lazy val EqualsPatternClass     = specialPolyClass(tpnme.EQUALS_PATTERN_NAME, 0L)(_ => AnyClass.tpe)
    lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe))
    lazy val RepeatedParamClass     = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe))
  
    lazy val MarkerCPSTypes = getClassIfDefined("scala.util.continuations.cpsParam")

    def isByNameParamType(tp: Type)        = tp.typeSymbol == ByNameParamClass
    def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass
    def isJavaRepeatedParamType(tp: Type)  = tp.typeSymbol == JavaRepeatedParamClass
    def isRepeatedParamType(tp: Type)      = isScalaRepeatedParamType(tp) || isJavaRepeatedParamType(tp)
    def isCastSymbol(sym: Symbol)          = sym == Any_asInstanceOf || sym == Object_asInstanceOf

    def isJavaVarArgsMethod(m: Symbol)       = m.isMethod && isJavaVarArgs(m.info.params)
    def isJavaVarArgs(params: Seq[Symbol])  = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe)
    def isScalaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe)
    def isVarArgsList(params: Seq[Symbol])  = params.nonEmpty && isRepeatedParamType(params.last.tpe)
    def isVarArgTypes(formals: Seq[Type])   = formals.nonEmpty && isRepeatedParamType(formals.last)

    def hasRepeatedParam(tp: Type): Boolean = tp match {
      case MethodType(formals, restpe) => isScalaVarArgs(formals) || hasRepeatedParam(restpe)
      case PolyType(_, restpe)         => hasRepeatedParam(restpe)
      case _                           => false
    }

    def isPrimitiveArray(tp: Type) = tp match {
      case TypeRef(_, ArrayClass, arg :: Nil) => isPrimitiveValueClass(arg.typeSymbol)
      case _                                  => false
    }
    def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match {
      case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == elem
      case _                                  => false
    }

    lazy val MatchingStrategyClass = getRequiredClass("scala.MatchingStrategy")

    // collections classes
    lazy val ConsClass          = getRequiredClass("scala.collection.immutable.$colon$colon")
    lazy val IterableClass      = getRequiredClass("scala.collection.Iterable")
    lazy val IteratorClass      = getRequiredClass("scala.collection.Iterator")
    lazy val ListClass          = getRequiredClass("scala.collection.immutable.List")
    lazy val SeqClass           = getRequiredClass("scala.collection.Seq")
    lazy val StringBuilderClass = getRequiredClass("scala.collection.mutable.StringBuilder")
    lazy val TraversableClass   = getRequiredClass("scala.collection.Traversable")

    lazy val ListModule       = getRequiredModule("scala.collection.immutable.List")
      lazy val List_apply = getMember(ListModule, nme.apply)
    lazy val NilModule        = getRequiredModule("scala.collection.immutable.Nil")
    lazy val SeqModule        = getRequiredModule("scala.collection.Seq")
    lazy val IteratorModule = getRequiredModule("scala.collection.Iterator")
      lazy val Iterator_apply = getMember(IteratorModule, nme.apply)

    // arrays and their members
    lazy val ArrayModule  = getRequiredModule("scala.Array")
      lazy val ArrayModule_overloadedApply = getMember(ArrayModule, nme.apply)
    lazy val ArrayClass   = getRequiredClass("scala.Array")
      lazy val Array_apply  = getMember(ArrayClass, nme.apply)
      lazy val Array_update = getMember(ArrayClass, nme.update)
      lazy val Array_length = getMember(ArrayClass, nme.length)
      lazy val Array_clone  = getMember(ArrayClass, nme.clone_)

    // reflection / structural types
    lazy val SoftReferenceClass     = requiredClass[java.lang.ref.SoftReference[_]]
    lazy val WeakReferenceClass     = requiredClass[java.lang.ref.WeakReference[_]]
    lazy val MethodClass            = getClass(sn.MethodAsObject)
      def methodClass_setAccessible = getMember(MethodClass, nme.setAccessible)
    lazy val EmptyMethodCacheClass  = getRequiredClass("scala.runtime.EmptyMethodCache")
    lazy val MethodCacheClass       = getRequiredClass("scala.runtime.MethodCache")
      def methodCache_find  = getMember(MethodCacheClass, nme.find_)
      def methodCache_add   = getMember(MethodCacheClass, nme.add_)

    // scala.reflect
    lazy val ReflectPackageClass = getMember(ScalaPackageClass, nme.reflect)
    lazy val ReflectPackage = getPackageObject("scala.reflect")
      def Reflect_mirror = getMember(ReflectPackage, nme.mirror)

    lazy val ExprClass     = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr)
         def ExprTree      = getMemberClass(ExprClass, nme.tree)
         def ExprTpe       = getMemberClass(ExprClass, nme.tpe)
         def ExprEval      = getMember(ExprClass, nme.eval)
         def ExprValue     = getMember(ExprClass, nme.value)
    lazy val ExprModule    = getMember(getRequiredClass("scala.reflect.api.Exprs"), nme.Expr)

    lazy val ClassTagModule        = requiredModule[scala.reflect.ClassTag[_]]
    lazy val ClassTagClass         = requiredClass[scala.reflect.ClassTag[_]]
    lazy val TypeTagsClass         = requiredClass[scala.reflect.api.TypeTags]
    lazy val TypeTagClass          = getMemberClass(TypeTagsClass, tpnme.TypeTag)
    lazy val TypeTagModule         = getMemberModule(TypeTagsClass, nme.TypeTag)
    lazy val ConcreteTypeTagClass  = getMemberClass(TypeTagsClass, tpnme.ConcreteTypeTag)
    lazy val ConcreteTypeTagModule = getMemberModule(TypeTagsClass, nme.ConcreteTypeTag)

         def ClassTagErasure       = getMemberMethod(ClassTagClass, nme.erasure)
         def ClassTagTpe           = getMemberMethod(ClassTagClass, nme.tpe)
         def TypeTagTpe            = getMemberMethod(TypeTagClass, nme.tpe)

    lazy val MacroContextClass                        = getRequiredClass("scala.reflect.makro.Context")
         def MacroContextPrefix                       = getMember(MacroContextClass, nme.prefix)
         def MacroContextPrefixType                   = getMember(MacroContextClass, tpnme.PrefixType)
         def MacroContextMirror                       = getMember(MacroContextClass, nme.mirror)
         def MacroContextReify                        = getMember(MacroContextClass, nme.reify)
    lazy val MacroImplAnnotation                      = getRequiredClass("scala.reflect.makro.internal.macroImpl")
    lazy val MacroInternalPackage                     = getPackageObject("scala.reflect.makro.internal")
         def MacroInternal_materializeClassTag        = getMemberMethod(MacroInternalPackage, nme.materializeClassTag)
         def MacroInternal_materializeTypeTag         = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag)
         def MacroInternal_materializeConcreteTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeConcreteTypeTag)

    lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature")
    lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature")

    // Option classes
    lazy val OptionClass: Symbol = requiredClass[Option[_]]
    lazy val SomeClass: Symbol   = requiredClass[Some[_]]
    lazy val NoneModule: Symbol  = getRequiredModule("scala.None")
    lazy val SomeModule: Symbol  = getRequiredModule("scala.Some")

    // [Eugene] how do I make this work without casts?
    // private lazy val importerFromRm = self.mkImporter(rm)
    private lazy val importerFromRm = self.mkImporter(rm).asInstanceOf[self.Importer { val from: rm.type }]

    def manifestToType(m: Manifest[_]): Type = importerFromRm.importType(m.tpe)

    def manifestToSymbol(m: Manifest[_]): Symbol = importerFromRm.importSymbol(m.tpe.typeSymbol)

    // The given symbol represents either String.+ or StringAdd.+
    def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+
    def isArrowAssoc(sym: Symbol) = ArrowAssocClass.tpe.decls.toList contains sym

    // The given symbol is a method with the right name and signature to be a runnable java program.
    def isJavaMainMethod(sym: Symbol) = (sym.name == nme.main) && (sym.info match {
      case MethodType(p :: Nil, restpe) => isArrayOfSymbol(p.tpe, StringClass) && restpe.typeSymbol == UnitClass
      case _                            => false
    })
    // The given class has a main method.
    def hasJavaMainMethod(sym: Symbol): Boolean =
      (sym.tpe member nme.main).alternatives exists isJavaMainMethod
    def hasJavaMainMethod(path: String): Boolean =
      hasJavaMainMethod(getModuleIfDefined(path))

    def isOptionType(tp: Type)  = tp.typeSymbol isSubClass OptionClass
    def isSomeType(tp: Type)    = tp.typeSymbol eq SomeClass
    def isNoneType(tp: Type)    = tp.typeSymbol eq NoneModule

    // Product, Tuple, Function, AbstractFunction
    private def mkArityArray(name: String, arity: Int, countFrom: Int = 1): Array[Symbol] = {
      val list = countFrom to arity map (i => getRequiredClass("scala." + name + i))
      if (countFrom == 0) list.toArray
      else (NoSymbol +: list).toArray
    }
    private def aritySpecificType(symbolArray: Array[Symbol], args: List[Type], others: Type*): Type = {
      val arity = args.length
      if (arity >= symbolArray.length) NoType
      else appliedType(symbolArray(arity), args ++ others: _*)
    }

    val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22
    lazy val ProductClass          = { val arr = mkArityArray("Product", MaxProductArity) ; arr(0) = UnitClass ; arr }
    lazy val TupleClass            = mkArityArray("Tuple", MaxTupleArity)
    lazy val FunctionClass         = mkArityArray("Function", MaxFunctionArity, 0)
    lazy val AbstractFunctionClass = mkArityArray("runtime.AbstractFunction", MaxFunctionArity, 0)

    /** Creators for TupleN, ProductN, FunctionN. */
    def tupleType(elems: List[Type])                            = aritySpecificType(TupleClass, elems)
    def productType(elems: List[Type])                          = aritySpecificType(ProductClass, elems)
    def functionType(formals: List[Type], restpe: Type)         = aritySpecificType(FunctionClass, formals, restpe)
    def abstractFunctionType(formals: List[Type], restpe: Type) = aritySpecificType(AbstractFunctionClass, formals, restpe)

    def wrapArrayMethodName(elemtp: Type): TermName = elemtp.typeSymbol match {
      case ByteClass    => nme.wrapByteArray
      case ShortClass   => nme.wrapShortArray
      case CharClass    => nme.wrapCharArray
      case IntClass     => nme.wrapIntArray
      case LongClass    => nme.wrapLongArray
      case FloatClass   => nme.wrapFloatArray
      case DoubleClass  => nme.wrapDoubleArray
      case BooleanClass => nme.wrapBooleanArray
      case UnitClass    => nme.wrapUnitArray
      case _        =>
        if ((elemtp <:< AnyRefClass.tpe) && !isPhantomClass(elemtp.typeSymbol)) nme.wrapRefArray
        else nme.genericWrapArray
    }

    @deprecated("Use isTupleType", "2.10.0")
    def isTupleTypeOrSubtype(tp: Type) = isTupleType(tp)

    def tupleField(n: Int, j: Int) = getMember(TupleClass(n), nme.productAccessorName(j))
    def isTupleSymbol(sym: Symbol) = TupleClass contains unspecializedSymbol(sym)
    def isProductNClass(sym: Symbol) = ProductClass contains sym

    def unspecializedSymbol(sym: Symbol): Symbol = {
      if (sym hasFlag SPECIALIZED) {
        // add initialization from its generic class constructor
        val genericName = nme.unspecializedName(sym.name)
        val member = sym.owner.info.decl(genericName.toTypeName)
        member
      }
      else sym
    }

    // Checks whether the given type is true for the given condition,
    // or if it is a specialized subtype of a type for which it is true.
    //
    // Origins notes:
    // An issue was introduced with specialization in that the implementation
    // of "isTupleType" in Definitions relied upon sym == TupleClass(elems.length).
    // This test is untrue for specialized tuples, causing mysterious behavior
    // because only some tuples are specialized.
    def isPossiblySpecializedType(tp: Type)(cond: Type => Boolean) = {
      cond(tp) || (tp match {
        case TypeRef(pre, sym, args) if sym hasFlag SPECIALIZED =>
          cond(tp baseType unspecializedSymbol(sym))
        case _ =>
          false
      })
    }
    // No normalization.
    def isTupleTypeDirect(tp: Type) = isPossiblySpecializedType(tp) {
      case TypeRef(_, sym, args) if args.nonEmpty =>
        val len = args.length
        len <= MaxTupleArity && sym == TupleClass(len)
      case _ => false
    }
    def isTupleType(tp: Type) = isTupleTypeDirect(tp.normalize)

    lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product]
      def Product_productArity          = getMemberMethod(ProductRootClass, nme.productArity)
      def Product_productElement        = getMemberMethod(ProductRootClass, nme.productElement)
      def Product_iterator              = getMemberMethod(ProductRootClass, nme.productIterator)
      def Product_productPrefix         = getMemberMethod(ProductRootClass, nme.productPrefix)
      def Product_canEqual              = getMemberMethod(ProductRootClass, nme.canEqual_)
      // def Product_productElementName = getMemberMethod(ProductRootClass, nme.productElementName)

      def productProj(z:Symbol, j: Int): Symbol = getMember(z, nme.productAccessorName(j))
      def productProj(n: Int,   j: Int): Symbol = productProj(ProductClass(n), j)

      /** returns true if this type is exactly ProductN[T1,...,Tn], not some subclass */
      def isExactProductType(tp: Type): Boolean = isProductNClass(tp.typeSymbol)

    /** if tpe <: ProductN[T1,...,TN], returns List(T1,...,TN) else Nil */
    def getProductArgs(tpe: Type): List[Type] = tpe.baseClasses find isProductNClass match {
      case Some(x)  => tpe.baseType(x).typeArgs
      case _        => Nil
    }

    def unapplyUnwrap(tpe:Type) = tpe.finalResultType.normalize match {
      case RefinedType(p :: _, _) => p.normalize
      case tp                     => tp
    }

    def functionApply(n: Int) = getMember(FunctionClass(n), nme.apply)

    def abstractFunctionForFunctionType(tp: Type) =
      if (isFunctionType(tp)) abstractFunctionType(tp.typeArgs.init, tp.typeArgs.last)
      else NoType

    def isFunctionType(tp: Type): Boolean = tp.normalize match {
      case TypeRef(_, sym, args) if args.nonEmpty =>
        val arity = args.length - 1   // -1 is the return type
        arity <= MaxFunctionArity && sym == FunctionClass(arity)
      case _ =>
        false
    }

    def isPartialFunctionType(tp: Type): Boolean = {
      val sym = tp.typeSymbol
      (sym eq PartialFunctionClass) || (sym eq AbstractPartialFunctionClass)
    }

    def isSeqType(tp: Type) = elementType(SeqClass, tp.normalize) != NoType

    def elementType(container: Symbol, tp: Type): Type = tp match {
      case TypeRef(_, `container`, arg :: Nil)  => arg
      case _                                    => NoType
    }

    def arrayType(arg: Type)         = appliedType(ArrayClass, arg)
    def byNameType(arg: Type)        = appliedType(ByNameParamClass, arg)
    def iteratorOfType(tp: Type)     = appliedType(IteratorClass, tp)
    def javaRepeatedType(arg: Type)  = appliedType(JavaRepeatedParamClass, arg)
    def optionType(tp: Type)         = appliedType(OptionClass, tp)
    def scalaRepeatedType(arg: Type) = appliedType(RepeatedParamClass, arg)
    def seqType(arg: Type)           = appliedType(SeqClass, arg)
    def someType(tp: Type)           = appliedType(SomeClass, tp)

    def StringArray   = arrayType(StringClass.tpe)
    lazy val ObjectArray   = arrayType(ObjectClass.tpe)

    def ClassType(arg: Type) =
      if (phase.erasedTypes || forMSIL) ClassClass.tpe
      else appliedType(ClassClass, arg)

    def vmClassType(arg: Type): Type = ClassType(arg)
    def vmSignature(sym: Symbol, info: Type): String = signature(info)    // !!!

    /** Given a class symbol C with type parameters T1, T2, ... Tn
     *  which have upper/lower bounds LB1/UB1, LB1/UB2, ..., LBn/UBn,
     *  returns an existential type of the form
     *
     *    C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... en >: LBn <: UBn }.
     */
    def classExistentialType(clazz: Symbol): Type =
      newExistentialType(clazz.typeParams, clazz.tpe)

    /** Given type U, creates a Type representing Class[_ <: U].
     */
    def boundedClassType(upperBound: Type) =
      appliedTypeAsUpperBounds(ClassClass.typeConstructor, List(upperBound))

    /** To avoid unchecked warnings on polymorphic classes, translate
     *  a Foo[T] into a Foo[_] for use in the pattern matcher.
     */
    @deprecated("Use classExistentialType", "2.10.0")
    def typeCaseType(clazz: Symbol): Type = classExistentialType(clazz)

    //
    // .NET backend
    //

    lazy val ComparatorClass = getRequiredClass("scala.runtime.Comparator")
    // System.ValueType
    lazy val ValueTypeClass: Symbol = getClass(sn.ValueType)
    // System.MulticastDelegate
    lazy val DelegateClass: Symbol = getClass(sn.Delegate)
    var Delegate_scalaCallers: List[Symbol] = List() // Syncnote: No protection necessary yet as only for .NET where reflection is not supported.
    // Symbol -> (Symbol, Type): scalaCaller -> (scalaMethodSym, DelegateType)
    // var Delegate_scalaCallerInfos: HashMap[Symbol, (Symbol, Type)] = _
    lazy val Delegate_scalaCallerTargets: mutable.HashMap[Symbol, Symbol] = mutable.HashMap()

    def isCorrespondingDelegate(delegateType: Type, functionType: Type): Boolean = {
      isSubType(delegateType, DelegateClass.tpe) &&
      (delegateType.member(nme.apply).tpe match {
      	case MethodType(delegateParams, delegateReturn) =>
      	  isFunctionType(functionType) &&
      	  (functionType.normalize match {
      	    case TypeRef(_, _, args) =>
      	      (delegateParams.map(pt => {
                      if (pt.tpe == AnyClass.tpe) definitions.ObjectClass.tpe else pt})
      	       ::: List(delegateReturn)) == args
      	    case _ => false
      	  })
        case _ => false
      })
    }

    // members of class scala.Any
    lazy val Any_==       = enterNewMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL)
    lazy val Any_!=       = enterNewMethod(AnyClass, nme.NE, anyparam, booltype, FINAL)
    lazy val Any_equals   = enterNewMethod(AnyClass, nme.equals_, anyparam, booltype)
    lazy val Any_hashCode = enterNewMethod(AnyClass, nme.hashCode_, Nil, inttype)
    lazy val Any_toString = enterNewMethod(AnyClass, nme.toString_, Nil, stringtype)
    lazy val Any_##       = enterNewMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL)

    // Any_getClass requires special handling.  The return type is determined on
    // a per-call-site basis as if the function being called were actually:
    //
    //    // Assuming `target.getClass()`
    //    def getClass[T](target: T): Class[_ <: T]
    //
    // Since getClass is not actually a polymorphic method, this requires compiler
    // participation.  At the "Any" level, the return type is Class[_] as it is in
    // java.lang.Object.  Java also special cases the return type.
    lazy val Any_getClass     = enterNewMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED)
    lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype)
    lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor)

  // A type function from T => Class[U], used to determine the return
    // type of getClass calls.  The returned type is:
    //
    //  1. If T is a value type, Class[T].
    //  2. If T is a phantom type (Any or AnyVal), Class[_].
    //  3. If T is a local class, Class[_ <: |T|].
    //  4. Otherwise, Class[_ <: T].
    //
    // Note: AnyVal cannot be Class[_ <: AnyVal] because if the static type of the
    // receiver is AnyVal, it implies the receiver is boxed, so the correct
    // class object is that of java.lang.Integer, not Int.
    //
    // TODO: If T is final, return type could be Class[T].  Should it?
    def getClassReturnType(tp: Type): Type = {
      val sym     = tp.typeSymbol

      if (phase.erasedTypes) ClassClass.tpe
      else if (isPrimitiveValueClass(sym)) ClassType(tp.widen)
      else {
        val eparams    = typeParamsToExistentials(ClassClass, ClassClass.typeParams)
        val upperBound = (
          if (isPhantomClass(sym)) AnyClass.tpe
          else if (sym.isLocalClass) erasure.intersectionDominator(tp.parents)
          else tp.widen
        )

        existentialAbstraction(
          eparams,
          ClassType(eparams.head setInfo TypeBounds.upper(upperBound) tpe)
        )
      }
    }

    /** Remove references to class Object (other than the head) in a list of parents */
    def removeLaterObjects(tps: List[Type]): List[Type] = tps match {
      case Nil      => Nil
      case x :: xs  => x :: xs.filterNot(_.typeSymbol == ObjectClass)
    }
    /** Remove all but one reference to class Object from a list of parents. */
    def removeRedundantObjects(tps: List[Type]): List[Type] = tps match {
      case Nil      => Nil
      case x :: xs  =>
        if (x.typeSymbol == ObjectClass)
          x :: xs.filterNot(_.typeSymbol == ObjectClass)
        else
          x :: removeRedundantObjects(xs)
    }
    /** Order a list of types with non-trait classes before others. */
    def classesFirst(tps: List[Type]): List[Type] = {
      val (classes, others) = tps partition (t => t.typeSymbol.isClass && !t.typeSymbol.isTrait)
      if (classes.isEmpty || others.isEmpty || (tps startsWith classes)) tps
      else classes ::: others
    }
    /** The following transformations applied to a list of parents.
     *  If any parent is a class/trait, all parents which normalize to
     *  Object are discarded.  Otherwise, all parents which normalize
     *  to Object except the first one found are discarded.
     */
    def normalizedParents(parents: List[Type]): List[Type] = {
      if (parents exists (t => (t.typeSymbol ne ObjectClass) && t.typeSymbol.isClass))
        parents filterNot (_.typeSymbol eq ObjectClass)
      else
        removeRedundantObjects(parents)
    }

    def typeStringNoPackage(tp: Type) =
      "" + tp stripPrefix tp.typeSymbol.enclosingPackage.fullName + "."

    def briefParentsString(parents: List[Type]) =
      normalizedParents(parents) map typeStringNoPackage mkString " with "

    def parentsString(parents: List[Type]) =
      normalizedParents(parents) mkString " with "

    def typeParamsString(tp: Type) = tp match {
      case PolyType(tparams, _) => tparams map (_.defString) mkString ("[", ",", "]")
      case _                    => ""
    }
    def valueParamsString(tp: Type) = tp match {
      case MethodType(params, _) => params map (_.defString) mkString ("(", ",", ")")
      case _                     => ""
    }

    // members of class java.lang.{ Object, String }
    lazy val Object_## = enterNewMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL)
    lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL)
    lazy val Object_!= = enterNewMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL)
    lazy val Object_eq = enterNewMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL)
    lazy val Object_ne = enterNewMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL)
    lazy val Object_isInstanceOf = newT1NoParamsMethod(ObjectClass, nme.isInstanceOf_Ob, FINAL | SYNTHETIC)(_ => booltype)
    lazy val Object_asInstanceOf = newT1NoParamsMethod(ObjectClass, nme.asInstanceOf_Ob, FINAL | SYNTHETIC)(_.typeConstructor)
    lazy val Object_synchronized = newPolyMethod(1, ObjectClass, nme.synchronized_, FINAL)(tps =>
      (Some(List(tps.head.typeConstructor)), tps.head.typeConstructor)
    )
    lazy val String_+ = enterNewMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL)

    def Object_getClass  = getMember(ObjectClass, nme.getClass_)
    def Object_clone     = getMember(ObjectClass, nme.clone_)
    def Object_finalize  = getMember(ObjectClass, nme.finalize_)
    def Object_notify    = getMember(ObjectClass, nme.notify_)
    def Object_notifyAll = getMember(ObjectClass, nme.notifyAll_)
    def Object_equals    = getMember(ObjectClass, nme.equals_)
    def Object_hashCode  = getMember(ObjectClass, nme.hashCode_)
    def Object_toString  = getMember(ObjectClass, nme.toString_)

    // boxed classes
    lazy val ObjectRefClass         = getRequiredClass("scala.runtime.ObjectRef")
    lazy val VolatileObjectRefClass = getRequiredClass("scala.runtime.VolatileObjectRef")
    lazy val BoxesRunTimeModule     = getRequiredModule("scala.runtime.BoxesRunTime")
    lazy val BoxesRunTimeClass      = BoxesRunTimeModule.moduleClass
    lazy val BoxedNumberClass       = getClass(sn.BoxedNumber)
    lazy val BoxedCharacterClass    = getClass(sn.BoxedCharacter)
    lazy val BoxedBooleanClass      = getClass(sn.BoxedBoolean)
    lazy val BoxedByteClass         = getRequiredClass("java.lang.Byte")
    lazy val BoxedShortClass        = getRequiredClass("java.lang.Short")
    lazy val BoxedIntClass          = getRequiredClass("java.lang.Integer")
    lazy val BoxedLongClass         = getRequiredClass("java.lang.Long")
    lazy val BoxedFloatClass        = getRequiredClass("java.lang.Float")
    lazy val BoxedDoubleClass       = getRequiredClass("java.lang.Double")

    lazy val Boxes_isNumberOrBool = getDecl(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean)
    lazy val Boxes_isNumber       = getDecl(BoxesRunTimeClass, nme.isBoxedNumber)

    lazy val BoxedUnitClass         = getRequiredClass("scala.runtime.BoxedUnit")
    lazy val BoxedUnitModule        = getRequiredModule("scala.runtime.BoxedUnit")
      def BoxedUnit_UNIT = getMember(BoxedUnitModule, nme.UNIT)
      def BoxedUnit_TYPE = getMember(BoxedUnitModule, nme.TYPE_)

    // Annotation base classes
    lazy val AnnotationClass            = getRequiredClass("scala.annotation.Annotation")
    lazy val ClassfileAnnotationClass   = getRequiredClass("scala.annotation.ClassfileAnnotation")
    lazy val StaticAnnotationClass      = getRequiredClass("scala.annotation.StaticAnnotation")

    // Annotations
    lazy val BridgeClass                = getRequiredClass("scala.annotation.bridge")
    lazy val ElidableMethodClass        = getRequiredClass("scala.annotation.elidable")
    lazy val ImplicitNotFoundClass      = getRequiredClass("scala.annotation.implicitNotFound")
    lazy val MigrationAnnotationClass   = getRequiredClass("scala.annotation.migration")
    lazy val ScalaStrictFPAttr          = getRequiredClass("scala.annotation.strictfp")
    lazy val SerializableAttr           = getRequiredClass("scala.annotation.serializable") // @serializable is deprecated
    lazy val SwitchClass                = getRequiredClass("scala.annotation.switch")
    lazy val TailrecClass               = getRequiredClass("scala.annotation.tailrec")
    lazy val VarargsClass               = getRequiredClass("scala.annotation.varargs")
    lazy val uncheckedStableClass       = getRequiredClass("scala.annotation.unchecked.uncheckedStable")
    lazy val uncheckedVarianceClass     = getRequiredClass("scala.annotation.unchecked.uncheckedVariance")

    lazy val BeanPropertyAttr           = getRequiredClass("scala.beans.BeanProperty")
    lazy val BooleanBeanPropertyAttr    = getRequiredClass("scala.beans.BooleanBeanProperty")
    lazy val CloneableAttr              = getRequiredClass("scala.cloneable")
    lazy val DeprecatedAttr             = getRequiredClass("scala.deprecated")
    lazy val DeprecatedNameAttr         = getRequiredClass("scala.deprecatedName")
    lazy val NativeAttr                 = getRequiredClass("scala.native")
    lazy val RemoteAttr                 = getRequiredClass("scala.remote")
    lazy val ScalaInlineClass           = getRequiredClass("scala.inline")
    lazy val ScalaNoInlineClass         = getRequiredClass("scala.noinline")
    lazy val SerialVersionUIDAttr       = getRequiredClass("scala.SerialVersionUID")
    lazy val SpecializedClass           = getRequiredClass("scala.specialized")
    lazy val ThrowsClass                = getRequiredClass("scala.throws")
    lazy val TransientAttr              = getRequiredClass("scala.transient")
    lazy val UncheckedClass             = getRequiredClass("scala.unchecked")
    lazy val VolatileAttr               = getRequiredClass("scala.volatile")

    // Meta-annotations
    lazy val BeanGetterTargetClass      = getMetaAnnotation("beanGetter")
    lazy val BeanSetterTargetClass      = getMetaAnnotation("beanSetter")
    lazy val FieldTargetClass           = getMetaAnnotation("field")
    lazy val GetterTargetClass          = getMetaAnnotation("getter")
    lazy val ParamTargetClass           = getMetaAnnotation("param")
    lazy val SetterTargetClass          = getMetaAnnotation("setter")
    lazy val ClassTargetClass           = getMetaAnnotation("companionClass")
    lazy val ObjectTargetClass          = getMetaAnnotation("companionObject")
    lazy val MethodTargetClass          = getMetaAnnotation("companionMethod")    // TODO: module, moduleClass? package, packageObject?
    lazy val LanguageFeatureAnnot       = getMetaAnnotation("languageFeature")

    // Language features
    lazy val languageFeatureModule      = getRequiredModule("scala.languageFeature")
    lazy val experimentalModule         = getMember(languageFeatureModule, newTermName("experimental"))
    lazy val MacrosFeature              = getLanguageFeature("macros", experimentalModule)
    lazy val DynamicsFeature            = getLanguageFeature("dynamics")
    lazy val PostfixOpsFeature          = getLanguageFeature("postfixOps")
    lazy val ReflectiveCallsFeature     = getLanguageFeature("reflectiveCalls")
    lazy val ImplicitConversionsFeature = getLanguageFeature("implicitConversions")
    lazy val HigherKindsFeature         = getLanguageFeature("higherKinds")
    lazy val ExistentialsFeature        = getLanguageFeature("existentials")

    private def getMetaAnnotation(name: String) = getRequiredClass("scala.annotation.meta." + name)
    def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || (
      // Trying to allow for deprecated locations
      sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol)
    )
    lazy val metaAnnotations = Set[Symbol](
      FieldTargetClass, ParamTargetClass,
      GetterTargetClass, SetterTargetClass,
      BeanGetterTargetClass, BeanSetterTargetClass
    )

    lazy val AnnotationDefaultAttr: Symbol = {
      val attr = enterNewClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.tpe))
      // This attribute needs a constructor so that modifiers in parsed Java code make sense
      attr.info.decls enter attr.newClassConstructor(NoPosition)
      attr
    }

    def getPackageObjectClass(fullname: String): Symbol =
      getPackageObject(fullname).companionClass

    def getPackageObject(fullname: String): Symbol =
      getModule(newTermName(fullname)).info member nme.PACKAGE

    def getModule(fullname: Name): ModuleSymbol =
      getModuleOrClass(fullname.toTermName) match {
        case x: ModuleSymbol => x
        case _               => MissingRequirementError.notFound("object " + fullname)
      }

    def getPackage(fullname: Name): PackageSymbol =
      getModuleOrClass(fullname.toTermName) match {
        case x: PackageSymbol => x
        case _                => MissingRequirementError.notFound("package " + fullname)
      }
    @inline private def wrapMissing(body: => Symbol): Symbol =
      try body
      catch { case _: MissingRequirementError => NoSymbol }

    private def fatalMissingSymbol(owner: Symbol, name: Name, what: String = "member") = {
      throw new FatalError(owner + " does not have a " + what + " " + name)
    }

    @deprecated("Use getClassByName", "2.10.0")
    def getClass(fullname: Name): Symbol = getClassByName(fullname)

    def getRequiredPackage(fullname: String): PackageSymbol =
      getPackage(newTermNameCached(fullname))

    def getRequiredModule(fullname: String): ModuleSymbol =
      getModule(newTermNameCached(fullname))

    def requiredClass[T: ClassTag] : ClassSymbol =
      getRequiredClass(classTag[T].erasure.getName)

    // TODO: What syntax do we think should work here? Say you have an object
    // like scala.Predef.  You can't say requiredModule[scala.Predef] since there's
    // no accompanying Predef class, and if you say requiredModule[scala.Predef.type]
    // the name found via the erasure is scala.Predef$.  For now I am
    // removing the trailing $, but I think that classTag should have
    // a method which returns a usable name, one which doesn't expose this
    // detail of the backend.
    def requiredModule[T: ClassTag] : ModuleSymbol =
      getRequiredModule(classTag[T].erasure.getName stripSuffix "$")

    def getRequiredClass(fullname: String): ClassSymbol =
      getClassByName(newTypeNameCached(fullname)) match {
        case x: ClassSymbol => x
        case _              => MissingRequirementError.notFound("class " + fullname)
      }

    def getClassIfDefined(fullname: String): Symbol =
      getClassIfDefined(newTypeName(fullname))

    def getClassIfDefined(fullname: Name): Symbol =
      wrapMissing(getClass(fullname.toTypeName))

    def getModuleIfDefined(fullname: String): Symbol =
      getModuleIfDefined(newTermName(fullname))

    def getModuleIfDefined(fullname: Name): Symbol =
      wrapMissing(getModule(fullname.toTermName))

    def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule) =
      getMember(owner, newTypeName(name))

    def termMember(owner: Symbol, name: String): Symbol = owner.info.member(newTermName(name))
    def typeMember(owner: Symbol, name: String): Symbol = owner.info.member(newTypeName(name))

    def findMemberFromRoot(fullName: Name): Symbol = {
      val segs = nme.segments(fullName.toString, fullName.isTermName)
      if (segs.isEmpty) NoSymbol
      else findNamedMember(segs.tail, definitions.RootClass.info member segs.head)
    }
    def findNamedMember(fullName: Name, root: Symbol): Symbol = {
      val segs = nme.segments(fullName.toString, fullName.isTermName)
      if (segs.isEmpty || segs.head != root.simpleName) NoSymbol
      else findNamedMember(segs.tail, root)
    }
    def findNamedMember(segs: List[Name], root: Symbol): Symbol =
      if (segs.isEmpty) root
      else findNamedMember(segs.tail, root.info member segs.head)

    def getMember(owner: Symbol, name: Name): Symbol = {
      getMemberIfDefined(owner, name) orElse {
        if (phase.flatClasses && name.isTypeName && !owner.isPackageObjectOrClass) {
          val pkg = owner.owner
          val flatname = nme.flattenedName(owner.name, name)
          getMember(pkg, flatname)
        }
        else fatalMissingSymbol(owner, name)
      }
    }
    def getMemberModule(owner: Symbol, name: Name): ModuleSymbol = {
      getMember(owner, name.toTermName) match {
        case x: ModuleSymbol => x
        case _               => fatalMissingSymbol(owner, name, "member object")
      }
    }
    def getMemberClass(owner: Symbol, name: Name): ClassSymbol = {
      getMember(owner, name.toTypeName) match {
        case x: ClassSymbol => x
        case _              => fatalMissingSymbol(owner, name, "member class")
      }
    }
    def getMemberMethod(owner: Symbol, name: Name): MethodSymbol = {
      getMember(owner, name.toTermName) match {
        case x: MethodSymbol => x
        case _               => fatalMissingSymbol(owner, name, "method")
      }
    }

    def getMemberIfDefined(owner: Symbol, name: Name): Symbol =
      owner.info.nonPrivateMember(name)

    /** Using getDecl rather than getMember may avoid issues with
     *  OverloadedTypes turning up when you don't want them, if you
     *  know the method in question is uniquely declared in the given owner.
     */
    def getDecl(owner: Symbol, name: Name): Symbol = {
      getDeclIfDefined(owner, name) orElse fatalMissingSymbol(owner, name, "decl")
    }
    def getDeclIfDefined(owner: Symbol, name: Name): Symbol =
      owner.info.nonPrivateDecl(name)

    def packageExists(packageName: String): Boolean =
      getModuleIfDefined(packageName).isPackage

    private def getModuleOrClass(path: Name, len: Int): Symbol = {
      val point = path lastPos('.', len - 1)
      val owner =
        if (point > 0) getModuleOrClass(path.toTermName, point)
        else RootClass
      val name = path subName (point + 1, len)
      val sym = owner.info member name
      val result = if (path.isTermName) sym.suchThat(_ hasFlag MODULE) else sym
      if (result != NoSymbol) result
      else {
        if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug
        missingHook(owner, name) orElse {
          MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path)
        }
      }
    }

    /** If you're looking for a class, pass a type name.
     *  If a module, a term name.
     */
    private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length)

    private def getClassByName(fullname: Name): Symbol = {
      var result = getModuleOrClass(fullname.toTypeName)
      while (result.isAliasType) result = result.info.typeSymbol
      result
    }

    private def newAlias(owner: Symbol, name: TypeName, alias: Type): AliasTypeSymbol =
      owner.newAliasType(name) setInfoAndEnter alias

    private def specialPolyClass(name: TypeName, flags: Long)(parentFn: Symbol => Type): ClassSymbol = {
      val clazz   = enterNewClass(ScalaPackageClass, name, Nil)
      val tparam  = clazz.newSyntheticTypeParam("T0", flags)
      val parents = List(AnyRefClass.tpe, parentFn(tparam))

      clazz setInfo GenPolyType(List(tparam), ClassInfoType(parents, newScope, clazz))
    }

    def newPolyMethod(typeParamCount: Int, owner: Symbol, name: TermName, flags: Long)(createFn: PolyMethodCreator): MethodSymbol = {
      val msym    = owner.newMethod(name.encode, NoPosition, flags)
      val tparams = msym.newSyntheticTypeParams(typeParamCount)
      val mtpe    = createFn(tparams) match {
        case (Some(formals), restpe) => MethodType(msym.newSyntheticValueParams(formals), restpe)
        case (_, restpe)             => NullaryMethodType(restpe)
      }

      msym setInfoAndEnter genPolyType(tparams, mtpe)
    }

    /** T1 means one type parameter.
     */
    def newT1NullaryMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): MethodSymbol = {
      newPolyMethod(1, owner, name, flags)(tparams => (None, createFn(tparams.head)))
    }
    def newT1NoParamsMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): MethodSymbol = {
      newPolyMethod(1, owner, name, flags)(tparams => (Some(Nil), createFn(tparams.head)))
    }

    lazy val boxedClassValues = boxedClass.values.toSet[Symbol]
    lazy val isUnbox = unboxMethod.values.toSet[Symbol]
    lazy val isBox = boxMethod.values.toSet[Symbol]

    /** Is symbol a phantom class for which no runtime representation exists? */
    lazy val isPhantomClass = Set[Symbol](AnyClass, AnyValClass, NullClass, NothingClass)

    /** Is the symbol that of a parent which is added during parsing? */
    lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass

    private lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass

    /** Is symbol a value class? */
    def isPrimitiveValueClass(sym: Symbol) = ScalaValueClasses contains sym
    def isNonUnitValueClass(sym: Symbol)   = isPrimitiveValueClass(sym) && (sym != UnitClass)
    def isSpecializableClass(sym: Symbol)  = isPrimitiveValueClass(sym) || (sym == AnyRefClass)
    def isScalaValueType(tp: Type)         = ScalaValueClasses contains tp.typeSymbol

    /** Is symbol a boxed value class, e.g. java.lang.Integer? */
    def isBoxedValueClass(sym: Symbol) = boxedValueClassesSet(sym)

    /** If symbol is a value class (boxed or not), return the unboxed
     *  value class.  Otherwise, NoSymbol.
     */
    def unboxedValueClass(sym: Symbol): Symbol =
      if (isPrimitiveValueClass(sym)) sym
      else if (sym == BoxedUnitClass) UnitClass
      else boxedClass.map(_.swap).getOrElse(sym, NoSymbol)

    /** Is type's symbol a numeric value class? */
    def isNumericValueType(tp: Type): Boolean = tp match {
      case TypeRef(_, sym, _) => isNumericValueClass(sym)
      case _ => false
    }

    // todo: reconcile with javaSignature!!!
    def signature(tp: Type): String = {
      def erasure(tp: Type): Type = tp match {
        case st: SubType => erasure(st.supertype)
        case RefinedType(parents, _) => erasure(parents.head)
        case _ => tp
      }
      def flatNameString(sym: Symbol, separator: Char): String =
        if (sym == NoSymbol) ""   // be more resistant to error conditions, e.g. neg/t3222.scala
        else if (sym.owner.isPackageClass) sym.javaClassName
        else flatNameString(sym.owner, separator) + nme.NAME_JOIN_STRING + sym.simpleName
      def signature1(etp: Type): String = {
        if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.normalize.typeArgs.head))
        else if (isPrimitiveValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString()
        else "L" + flatNameString(etp.typeSymbol, '/') + ";"
      }
      val etp = erasure(tp)
      if (etp.typeSymbol == ArrayClass) signature1(etp)
      else flatNameString(etp.typeSymbol, '.')
    }

    /** getModule2/getClass2 aren't needed at present but may be again,
     *  so for now they're mothballed.
     */
    // def getModule2(name1: Name, name2: Name) = {
    //   try getModuleOrClass(name1.toTermName)
    //   catch { case ex1: FatalError =>
    //     try getModuleOrClass(name2.toTermName)
    //     catch { case ex2: FatalError => throw ex1 }
    //   }
    // }
    // def getClass2(name1: Name, name2: Name) = {
    //   try {
    //     val result = getModuleOrClass(name1.toTypeName)
    //     if (result.isAliasType) getClass(name2) else result
    //   }
    //   catch { case ex1: FatalError =>
    //     try getModuleOrClass(name2.toTypeName)
    //     catch { case ex2: FatalError => throw ex1 }
    //   }
    // }

    /** Surgery on the value classes.  Without this, AnyVals defined in source
     *  files end up with an AnyRef parent.  It is likely there is a better way
     *  to evade that AnyRef.
     */
    private def setParents(sym: Symbol, parents: List[Type]): Symbol = sym.rawInfo match {
      case ClassInfoType(_, scope, clazz) =>
        sym setInfo ClassInfoType(parents, scope, clazz)
      case _ =>
        sym
    }

    def init() {
      if (isInitialized) return

      // Still fiddling with whether it's cleaner to do some of this setup here
      // or from constructors.  The latter approach tends to invite init order issues.
      EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass)
      EmptyPackage setInfo EmptyPackageClass.tpe

      connectModuleToClass(EmptyPackage, EmptyPackageClass)
      connectModuleToClass(RootPackage, RootClass)

      RootClass.info.decls enter EmptyPackage
      RootClass.info.decls enter RootPackage

      val forced = List( // force initialization of every symbol that is entered as a side effect
        AnnotationDefaultAttr, // #2264
        RepeatedParamClass,
        JavaRepeatedParamClass,
        ByNameParamClass,
        AnyClass,
        AnyRefClass,
        AnyValClass,
        NullClass,
        NothingClass,
        SingletonClass,
        EqualsPatternClass,
        Any_==,
        Any_!=,
        Any_equals,
        Any_hashCode,
        Any_toString,
        Any_getClass,
        Any_isInstanceOf,
        Any_asInstanceOf,
        Any_##,
        Object_eq,
        Object_ne,
        Object_==,
        Object_!=,
        Object_##,
        Object_synchronized,
        Object_isInstanceOf,
        Object_asInstanceOf,
        String_+,
        ComparableClass,
        JavaSerializableClass
      )

      isInitialized = true
    } //init

    var nbScalaCallers: Int = 0
    def newScalaCaller(delegateType: Type): Symbol = {
      assert(forMSIL, "scalaCallers can only be created if target is .NET")
      // object: reference to object on which to call (scala-)method
      val paramTypes: List[Type] = List(ObjectClass.tpe)
      val name = newTermName("$scalaCaller$$" + nbScalaCallers)
      // tparam => resultType, which is the resultType of PolyType, i.e. the result type after applying the
      // type parameter =-> a MethodType in this case
      // TODO: set type bounds manually (-> MulticastDelegate), see newTypeParam
      val newCaller = enterNewMethod(DelegateClass, name, paramTypes, delegateType, FINAL | STATIC)
      // val newCaller = newPolyMethod(DelegateClass, name,
      // tparam => MethodType(paramTypes, tparam.typeConstructor)) setFlag (FINAL | STATIC)
      Delegate_scalaCallers = Delegate_scalaCallers ::: List(newCaller)
      nbScalaCallers += 1
      newCaller
    }

    // def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol, delType: Type) {
    // assert(Delegate_scalaCallers contains scalaCaller)
    // Delegate_scalaCallerInfos += (scalaCaller -> (methSym, delType))
    // }

    def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol) {
      assert(Delegate_scalaCallers contains scalaCaller)
      Delegate_scalaCallerTargets += (scalaCaller -> methSym)
    }
  }
}