Index: /trunk/ProjectFortress/src/com/sun/fortress/scala_src/useful/STypesUtil.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/useful/STypesUtil.scala (revision 3905)
+++ /trunk/ProjectFortress/src/com/sun/fortress/scala_src/useful/STypesUtil.scala (revision 3915)
@@ -18,12 +18,8 @@
 package com.sun.fortress.scala_src.useful
 
+import _root_.java.util.ArrayList
 import com.sun.fortress.compiler.GlobalEnvironment
 import com.sun.fortress.compiler.Types
-import com.sun.fortress.compiler.index.CompilationUnitIndex
-import com.sun.fortress.compiler.index.DeclaredMethod
-import com.sun.fortress.compiler.index.FieldGetterMethod
-import com.sun.fortress.compiler.index.FieldSetterMethod
-import com.sun.fortress.compiler.index.Method
-import com.sun.fortress.compiler.index.TypeConsIndex
+import com.sun.fortress.compiler.index._
 import com.sun.fortress.compiler.typechecker.StaticTypeReplacer
 import com.sun.fortress.compiler.typechecker.TypeAnalyzer
@@ -32,6 +28,7 @@
 import com.sun.fortress.exceptions.TypeError
 import com.sun.fortress.nodes._
-import com.sun.fortress.nodes_util.NodeFactory
-import com.sun.fortress.nodes_util.NodeUtil
+import com.sun.fortress.nodes_util.ExprFactory
+import com.sun.fortress.nodes_util.{NodeFactory => NF}
+import com.sun.fortress.nodes_util.{NodeUtil => NU}
 import com.sun.fortress.scala_src.nodes._
 import com.sun.fortress.scala_src.useful.Lists._
@@ -48,39 +45,60 @@
 
   /**
-   * Return the arrow type of the given FnDecl.
-   */
-  def makeArrowFromFunction(f: FnDecl): ArrowType = {
-    val returnType = f.getHeader.getReturnType.get
-    val params = toList(f.getHeader.getParams).map(NodeUtil.getParamType)
+   * Return the arrow type of the given FnDecl node.
+   */
+  def makeArrowFromFnDecl(f: FnDecl): ArrowType = {
+    val returnType = f.getHeader.getReturnType.unwrap
+    val params = toList(f.getHeader.getParams).map(NU.getParamType)
     val argType = makeArgumentType(params)
     val sparams = f.getHeader.getStaticParams
     val where = f.getHeader.getWhereClause
     val throws = f.getHeader.getThrowsClause
-    NodeFactory.makeArrowType(NodeUtil.getSpan(f),
-                              false,
-                              argType,
-                              returnType,
-                              NodeFactory.makeEffect(throws),
-                              sparams,
-                              where)
-  }
-
+    NF.makeArrowType(NU.getSpan(f),
+                     false,
+                     argType,
+                     returnType,
+                     NF.makeEffect(throws),
+                     sparams,
+                     where)
+  }
+  
   /**
    * Return the arrow type of the given Method.
-   */
-  def makeArrowFromFunction(m: Method): ArrowType = {
-    val returnType = m.getReturnType
-    val params = toList(m.parameters).map(NodeUtil.getParamType)
-    val argType = makeArgumentType(params)
-    m match {
-      case m:DeclaredMethod => makeArrowFromFunction(m.ast)
-      case g:FieldGetterMethod =>
-        NodeFactory.makeArrowType(NodeUtil.getSpan(g.ast),
-                                  argType,
-                                  returnType)
-      case s:FieldSetterMethod =>
-        NodeFactory.makeArrowType(NodeUtil.getSpan(s.ast),
-                                  argType,
-                                  returnType)
+   * @TODO Make sure that the getReturnType method in these indices works
+   * as it should.
+   */
+  def makeArrowFromFunctional(f: Functional): ArrowType = f match {
+    case m:Method =>
+      val returnType = m.getReturnType.unwrap
+      val params = toList(m.parameters).map(NU.getParamType)
+      val argType = makeArgumentType(params)
+      m match {
+        case m:DeclaredMethod => makeArrowFromFnDecl(m.ast)
+        case g:FieldGetterMethod =>
+          NF.makeArrowType(NU.getSpan(g.ast),
+                           argType,
+                           returnType)
+        case s:FieldSetterMethod =>
+          NF.makeArrowType(NU.getSpan(s.ast),
+                           argType,
+                           returnType)
+      }
+    case f:Function => f match {
+      case f:DeclaredFunction => makeArrowFromFnDecl(f.ast)
+      case f:FunctionalMethod => makeArrowFromFnDecl(f.ast)
+      case f:Constructor =>
+        val argType =
+          makeArgumentType(toList(f.parameters).map(NU.getParamType))
+        val returnType = f.getReturnType.unwrap
+        val sparams = f.staticParameters
+        val where = f.where
+        val throws = f.thrownTypes
+        NF.makeArrowType(NF.typeSpan,
+                         false,
+                         argType,
+                         returnType,
+                         NF.makeEffect(throws),
+                         sparams,
+                         where)
     }
   }
@@ -93,7 +111,52 @@
     case t :: Nil => t
     case _ =>
-      val span1 = NodeUtil.getSpan(ts.head)
-      val span2 = NodeUtil.getSpan(ts.last)
-      NodeFactory.makeTupleType(NodeUtil.spanTwo(span1, span2), toJavaList(ts))
+      val span1 = NU.getSpan(ts.head)
+      val span2 = NU.getSpan(ts.last)
+      NF.makeTupleType(NU.spanTwo(span1, span2), toJavaList(ts))
+  }
+  
+  /**
+   * Make a domain type from a list of parameters, including varargs and
+   * keyword types. Ported from `TypeEnv.domainFromParams`.
+   */
+  def makeDomainType(ps: List[Param]): Type = {
+    val paramTypes = new ArrayList[Type](ps.length)
+    val keywordTypes = new ArrayList[KeywordType](ps.length)
+    var varargsType: Option[Type] = None
+    val span = ps match {
+      case Nil => NF.typeSpan
+      case _ => NU.spanTwo(NU.getSpan(ps.first), NU.getSpan(ps.last))
+    }
+    
+    // Extract out the appropriate parameter types.
+    ps.foreach(p => p match {
+      case SParam(_, _, _, _, _, Some(vaType)) => // Vararg
+        varargsType = Some(vaType)
+      case SParam(_, name, _, Some(idType), Some(expr), _) => // Keyword
+        keywordTypes.add(NF.makeKeywordType(name, idType))
+      case SParam(_, _, _, Some(idType), _, _) => // Normal
+        paramTypes.add(idType)
+      case _ => bug("Parameter missing type") 
+    })
+    NF.makeDomain(span, paramTypes, toJavaOption(varargsType), keywordTypes)
+  }
+  
+  /**
+   * Convert a static parameter to the corresponding static arg. Ported from
+   * `TypeEnv.staticParamsToArgs`.
+   */
+  def staticParamToArg(p: StaticParam): StaticArg = {
+    val span = NU.getSpan(p)
+    (p.getName, p.getKind) match {
+      case (id:Id, _:KindBool) => NF.makeBoolArg(span, NF.makeBoolRef(span, id))
+      case (id:Id, _:KindDim) => NF.makeDimArg(span, NF.makeDimRef(span, id))
+      case (id:Id, _:KindInt) => NF.makeIntArg(span, NF.makeIntRef(span, id))
+      case (id:Id, _:KindNat) => NF.makeIntArg(span, NF.makeIntRef(span, id))
+      case (id:Id, _:KindType) => NF.makeTypeArg(span, NF.makeVarType(span, id))
+      case (id:Id, _:KindUnit) =>
+        NF.makeUnitArg(span, NF.makeUnitRef(span, false, id))
+      case (op:Op, _:KindOp) => NF.makeOpArg(span, ExprFactory.makeOpRef(op))
+      case _ => bug("Unexpected static parameter kind")
+    }
   }
 
@@ -173,5 +236,5 @@
   def staticParamBoundType(sparam: StaticParam): Option[Type] =
     sparam.getKind match {
-      case SKindType(_) => Some(NodeFactory.makeIntersectionType(sparam.getExtendsClause))
+      case SKindType(_) => Some(NF.makeIntersectionType(sparam.getExtendsClause))
       case _ => None
     }
@@ -184,6 +247,6 @@
     case SKindType(_) => {
       // Create a new inference var type.
-      val t = NodeFactory.make_InferenceVarType(NodeUtil.getSpan(sparam))
-      NodeFactory.makeTypeArg(NodeFactory.makeSpan(t), t)
+      val t = NF.make_InferenceVarType(NU.getSpan(sparam))
+      NF.makeTypeArg(NF.makeSpan(t), t)
     }
     case SKindInt(_) => NI.nyi()
Index: /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala (revision 3877)
+++ /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/OverloadingChecker.scala (revision 3915)
@@ -117,5 +117,5 @@
                     if ( param.getIdType.isSome &&
                          ! typeAnalyzer.equivalent(param.getIdType.unwrap,
-                                                   getter.getReturnType).isTrue )
+                                                   getter.getReturnType.unwrap).isTrue )
                         error(span,
                               "The parameter type of a setter must be " +
@@ -144,5 +144,5 @@
         var signatures = List[((JavaList[StaticParam],Type,Type),Span)]()
         for ( f <- set ; if isDeclaredFunctional(f) ) {
-            val result = f.getReturnType
+            val result = f.getReturnType.unwrap
             val param = paramsToType(f.parameters, f.getSpan)
             val sparams = f.staticParameters
@@ -186,5 +186,5 @@
         subtype(paramsToType(g.parameters, g.getSpan),
                 paramsToType(f.parameters, f.getSpan)) &&
-        subtype(f.getReturnType, g.getReturnType)
+        subtype(f.getReturnType.unwrap, g.getReturnType.unwrap)
 
     private def subtype(sub_type: Type, super_type: Type): Boolean =
Index: /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/STypeEnv.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/STypeEnv.scala (revision 3915)
+++ /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/STypeEnv.scala (revision 3915)
@@ -0,0 +1,90 @@
+/*******************************************************************************
+    Copyright 2009 Sun Microsystems, Inc.,
+    4150 Network Circle, Santa Clara, California 95054, U.S.A.
+    All rights reserved.
+
+    U.S. Government Rights - Commercial software.
+    Government users are subject to the Sun Microsystems, Inc. standard
+    license agreement and applicable provisions of the FAR and its supplements.
+
+    Use is subject to license terms.
+
+    This distribution may include materials developed by third parties.
+
+    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
+    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
+ ******************************************************************************/
+
+package com.sun.fortress.scala_src.typechecker.staticenv
+
+import com.sun.fortress.nodes._
+import com.sun.fortress.nodes_util.Modifiers
+import scala.collection.immutable.EmptyMap
+
+/**
+ * Represents a list of variable name to type bindings for some context. All
+ * instances of this class should be created with `STypeEnv.make` or with the
+ * `extendWith` method.
+ */
+abstract sealed class STypeEnv extends StaticEnv[Type] {
+  
+  /** My type. */
+  type Env = STypeEnv
+  
+  /** My binding type. */
+  type EnvBinding = TypeBinding
+  
+  /** Extend me with the immediate bindings of the given node. */
+  def extendWith(node: Any): STypeEnv =
+    new NestedSTypeEnv(this, STypeEnv.extractEnvBindings(node))
+  
+  /** Same as `lookup`. */
+  def getType(x: Name): Option[Type] = lookup(x).map(_.value)
+}
+
+/** The single empty type environment. */
+object EmptySTypeEnv extends STypeEnv with EmptyStaticEnv[Type]
+
+/**
+ * A type environment with a parent and some explicit bindings.
+ * 
+ * @param parent A type environment that this one extends.
+ * @param _bindings A collection of all the bindings in this environment.
+ */
+class NestedSTypeEnv protected (protected val parent: STypeEnv,
+                                _bindings: Collection[TypeBinding])
+    extends STypeEnv with NestedStaticEnv[Type] {
+    
+  /** Internal representation of `bindings` is a map. */
+  protected val bindings: Map[Name, TypeBinding] =
+    new EmptyMap ++ _bindings.map(b => b.name -> b)
+}
+
+/** Companion module for STypeEnv. */
+object STypeEnv extends StaticEnvCompanion[Type] with STypeEnvExtraction {
+  
+  /** My type. */
+  type Env = STypeEnv
+  
+  /** My binding type. */
+  type EnvBinding = TypeBinding
+  
+  /** New type environment with empty parent and the node's bindings. */
+  def make(node: Any): STypeEnv =
+    new NestedSTypeEnv(EmptySTypeEnv, extractEnvBindings(node))
+}
+
+
+/**
+ * A binding for a type environment contains name to type pairs, along with some
+ * modifiers for the binding and whether or not the binding is mutable.
+ * 
+ * @param name The variable name for the binding.
+ * @param value The bound type for this variable name.
+ * @param mods Any modifiers for the binding.
+ * @param mutable Whether or not the binding is mutable.
+ */
+case class TypeBinding(override val name: Name,
+                       typ: Type,
+                       mods: Modifiers,
+                       mutable: Boolean) extends StaticBinding[Type](name, typ)
Index: /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/KindEnv.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/KindEnv.scala (revision 3915)
+++ /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/KindEnv.scala (revision 3915)
@@ -0,0 +1,98 @@
+/*******************************************************************************
+    Copyright 2009 Sun Microsystems, Inc.,
+    4150 Network Circle, Santa Clara, California 95054, U.S.A.
+    All rights reserved.
+
+    U.S. Government Rights - Commercial software.
+    Government users are subject to the Sun Microsystems, Inc. standard
+    license agreement and applicable provisions of the FAR and its supplements.
+
+    Use is subject to license terms.
+
+    This distribution may include materials developed by third parties.
+
+    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
+    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
+ ******************************************************************************/
+
+package com.sun.fortress.scala_src.typechecker.staticenv
+
+import com.sun.fortress.compiler.Types
+import com.sun.fortress.nodes._
+import scala.collection.immutable.EmptyMap
+
+/**
+ * Represents a list of variable name to static parameter bindings for some
+ * context. All instances of this class should be created with `KindEnv.make`
+ * or with the `extendWith` method.
+ */
+abstract sealed class KindEnv extends StaticEnv[StaticParam] {
+  
+  /** My type. */
+  type Env = KindEnv
+  
+  /** My binding type. */
+  type EnvBinding = KindBinding
+
+  /** Extend me with the immediate bindings of the given node. */
+  def extendWith(node: Any): KindEnv =
+    new NestedKindEnv(this, KindEnv.extractEnvBindings(node))
+
+  /**
+   * Get the type of the given variable name, if it is bound. The resulting
+   * type will only be defined if this name maps to a bool, int, or nat static
+   * parameter.
+   */
+  def getType(x: Name): Option[Type] = lookup(x).flatMap(b =>
+    b.value.getKind match {
+      case _:KindBool => Some(Types.BOOLEAN)
+      case _:KindInt => Some(Types.INT_LITERAL)
+      case _:KindNat => Some(Types.INT_LITERAL)
+      case _ => None
+    })
+}
+
+/** The single empty kind environment. */
+object EmptyKindEnv extends KindEnv with EmptyStaticEnv[StaticParam]
+
+/**
+ * A kind environment with a parent and some explicit bindings.
+ * 
+ * @param parent A kind environment that this one extends.
+ * @param _bindings A collection of all the bindings in this environment.
+ */
+class NestedKindEnv protected (protected val parent: KindEnv,
+                               _bindings: Collection[KindBinding])
+    extends KindEnv with NestedStaticEnv[StaticParam] {
+    
+  /** Internal representation of `bindings` is a map. */
+  protected val bindings: Map[Name, KindBinding] =
+    new EmptyMap ++ _bindings.map(b => b.name -> b)
+}
+
+/** Companion module for KindEnv; contains "static" members. */
+object KindEnv extends StaticEnvCompanion[StaticParam] {
+  
+  /** My type. */
+  type Env = KindEnv
+  
+  /** My binding type. */
+  type EnvBinding = KindBinding
+  
+  /** New kind environment with empty parent and the node's bindings. */
+  def make(node: Any): KindEnv =
+    new NestedKindEnv(EmptyKindEnv, extractEnvBindings(node))
+  
+  /** Extract out the bindings in node. */
+  protected def extractEnvBindings(node: Any) : Collection[KindBinding] = null
+}
+
+/**
+ * A binding for a kind environment contains name to static parameter pairs.
+ * 
+ * @param name The variable name for the binding.
+ * @param sparam The static parameter that this name is binding.
+ */
+case class KindBinding(override val name: Name,
+                       sparam: StaticParam)
+    extends StaticBinding[StaticParam](name, sparam)
Index: /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/STypeEnvExtraction.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/STypeEnvExtraction.scala (revision 3915)
+++ /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/STypeEnvExtraction.scala (revision 3915)
@@ -0,0 +1,125 @@
+/*******************************************************************************
+    Copyright 2009 Sun Microsystems, Inc.,
+    4150 Network Circle, Santa Clara, California 95054, U.S.A.
+    All rights reserved.
+
+    U.S. Government Rights - Commercial software.
+    Government users are subject to the Sun Microsystems, Inc. standard
+    license agreement and applicable provisions of the FAR and its supplements.
+
+    Use is subject to license terms.
+
+    This distribution may include materials developed by third parties.
+
+    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
+    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
+ ******************************************************************************/
+
+package com.sun.fortress.scala_src.typechecker.staticenv
+
+import _root_.java.util.{Map => JMap}
+import _root_.java.util.{Set => JSet}
+import com.sun.fortress.compiler.index._
+import com.sun.fortress.nodes._
+import com.sun.fortress.nodes_util.Modifiers
+import com.sun.fortress.nodes_util.{NodeFactory => NF}
+import com.sun.fortress.nodes_util.{NodeUtil => NU}
+import com.sun.fortress.scala_src.nodes._
+import com.sun.fortress.scala_src.useful.Lists._
+import com.sun.fortress.scala_src.useful.Options._
+import com.sun.fortress.scala_src.useful.Maps._
+import com.sun.fortress.scala_src.useful.Sets._
+import com.sun.fortress.scala_src.useful.STypesUtil
+import edu.rice.cs.plt.collect.Relation
+
+trait STypeEnvExtraction { self: STypeEnv.type =>
+  
+  /** Extract out the bindings in node. */
+  def extractEnvBindings(node: Any): Collection[TypeBinding] = {
+    def recur(node: Any) = extractEnvBindings(node)
+    (node match {
+      
+      case SBinding(_, name, mods, Some(typ)) =>
+        TypeBinding(name, typ, mods, false)
+      
+      case SParam(_, name, mods, _, _, Some(vaTyp)) =>
+        TypeBinding(name, vaTyp, mods, false)
+      case SParam(_, name, mods, Some(typ), _, _) =>
+        TypeBinding(name, typ, mods, false)
+      
+      case SLValue(_, name, mods, Some(typ), mutable) =>
+        TypeBinding(name, typ, mods, mutable)
+      
+      case SLocalVarDecl(_, _, lValues, _) => lValues.map(recur)
+      
+      case v:DeclaredVariable => recur(v.ast)
+      
+      // Type erasure makes us put all JMap cases in one.
+      case m:JMap[_, _] => toMap(m).flatMap(xv =>
+        xv match {
+          
+          // Match Map[Id, Variable]
+          case (x:Id, v:DeclaredVariable) => recur(v)
+          case (x:Id, v:SingletonVariable) =>
+            recur(NF.makeLValue(x, v.declaringTrait))
+          case (x:Id, v:ParamVariable) => recur(v.ast)
+          
+          // Bind object names to their types.
+          case (x:Id, v:ObjectTraitIndex) =>
+            val decl = v.ast
+            val params = toOption(NU.getParams(decl))
+            val sparams = NU.getStaticParams(decl)
+            val objType = params match {
+              case None if sparams.isEmpty =>
+                // Just a single trait type.
+                NF.makeTraitType(x)
+              case None =>
+                // A generic trait type.
+                NF.makeGenericSingletonType(x, sparams)
+              case Some(params) if sparams.isEmpty =>
+                // Arrow type for basic constructor.
+                NF.makeArrowType(NU.getSpan(x),
+                                 STypesUtil.makeDomainType(toList(params)),
+                                 NF.makeTraitType(x))
+              case Some(params) =>
+                // Generic arrow type for constructor.
+                val sargs = toList(sparams).map(STypesUtil.staticParamToArg)
+                NF.makeArrowType(NU.getSpan(decl),
+                                 false,
+                                 STypesUtil.makeDomainType(toList(params)),
+                                 NF.makeTraitType(x, toJavaList(sargs)),
+                                 NF.emptyEffect, // TODO: Change this?
+                                 sparams,
+                                 NU.getWhereClause(decl))
+            }
+            List(TypeBinding(x, objType, Modifiers.None, false))
+        })
+      
+      // Matches all, but must be [IdOrOpOrAnonymousName, ? <: Functional]
+      case r:Relation[IdOrOpOrAnonymousName, Functional] =>
+        val fnNames = toSet(r.firstSet)
+        
+        // For each name, intersect together all of its overloading types.
+        fnNames.flatMap(x => x match {
+          
+          // Make sure this is actually a name.
+          case x: IdOrOpOrAnonymousName => 
+            val fns: Set[Functional] = toSet(r.matchFirst(x).asInstanceOf[JSet[Functional]])
+            val oTypes =
+              fns.map(STypesUtil.makeArrowFromFunctional(_).asInstanceOf[Type])
+            val fnType = NF.makeIntersectionType(oTypes)
+            Some(TypeBinding(x, fnType, Modifiers.None, false))
+            
+//          case _ => None
+        })
+      
+      case xs:Iterable[_] => xs.flatMap(recur)
+      
+      case _ => Nil
+      
+    }) match { // Guarantee that a Collection is returned.
+      case bs:Collection[TypeBinding] => bs
+      case b:TypeBinding => List(b)
+    }
+  }
+}
Index: /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/StaticEnv.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/StaticEnv.scala (revision 3915)
+++ /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/staticenv/StaticEnv.scala (revision 3915)
@@ -0,0 +1,156 @@
+/*******************************************************************************
+    Copyright 2009 Sun Microsystems, Inc.,
+    4150 Network Circle, Santa Clara, California 95054, U.S.A.
+    All rights reserved.
+
+    U.S. Government Rights - Commercial software.
+    Government users are subject to the Sun Microsystems, Inc. standard
+    license agreement and applicable provisions of the FAR and its supplements.
+
+    Use is subject to license terms.
+
+    This distribution may include materials developed by third parties.
+
+    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
+    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
+ ******************************************************************************/
+
+package com.sun.fortress.scala_src.typechecker.staticenv
+
+import com.sun.fortress.nodes.Name
+import com.sun.fortress.nodes.Type
+
+/**
+ * Represents an environment that exists during static checking, mapping
+ * variable names to some value. Each static environment contains 
+ */
+trait StaticEnv[T] extends Collection[StaticBinding[T]] {
+  
+  /** Define Env as the type of the implementing class. */
+  type Env <: StaticEnv[T]
+  
+  /** Define EnvBinding as the type of the bindings. */
+  type EnvBinding <: StaticBinding[T]
+  
+  /**
+   * Extend this environment with the bindings immediately contained in the
+   * given node.
+   * 
+   * @param node A node or collection of nodes in which to find bindings.
+   * @return A new environment with the bindings of this one and those found in
+   *         `node` combined.
+   */
+  def extendWith(node: Any): Env
+  
+  /**
+   * Gets the value stored for the given variable name, if that binding exists.
+   *
+   * @param name The name to lookup.
+   * @return Some(T) if name:T is a binding. None otherwise.
+   */
+  def lookup(x: Name): Option[EnvBinding]
+  
+  /** Same as lookup when treating implementing object as a function. */
+  def apply(x: Name): Option[EnvBinding] = lookup(x)
+  
+  /**
+   * Gets the type stored for the given variable name, if that binding exists.
+   * 
+   * @param name The name to lookup.
+   * @return Some(T) if name:T is a binding. None otherwise.
+   */
+  def getType(x: Name): Option[Type]
+  
+  /** Make the type on `Collection.elements` more specific. */
+  def elements: Iterator[EnvBinding]
+}
+
+/**
+ * A single empty static environment. There are no bindings at all in this
+ * environemnt.
+ */
+trait EmptyStaticEnv[T] extends StaticEnv[T] {
+      
+  /** Every call to `lookup` fails. */
+  override def lookup(x: Name): Option[EnvBinding] = None
+      
+  /** Every call to `getType` fails. */
+  override def getType(x: Name): Option[Type] = None
+  
+  // Collection implementation
+  override def elements: Iterator[EnvBinding] = Iterator.empty
+  override def size: Int = 0
+}
+
+/**
+ * A nested static environment that contains all the bindings of some parent
+ * environment and additionally all the explicitly supplied bindings.
+ */
+trait NestedStaticEnv[T] extends StaticEnv[T] {
+    
+  /** A static environment that this one extends. */
+  protected val parent: Env {
+    // Require that the parent has the same binding type.
+    type EnvBinding = NestedStaticEnv.this.EnvBinding
+  }
+    
+  /** The bindings explicitly declared in this environment. */
+  protected val bindings: Map[Name, EnvBinding]
+  
+  /** Find it among `bindings` or else in `parent`. */
+  def lookup(x: Name): Option[EnvBinding] = bindings.get(x) match {
+    case Some(v) => Some(v)
+    case None => parent.lookup(x)
+  }
+  
+  // Collection implementation
+  def elements: Iterator[EnvBinding] = parent.elements ++ bindings.values
+  def size: Int = parent.size + bindings.size
+}
+
+/**
+ * Provides functionality for finding bindings in nodes and creating new
+ * instances of the environment.
+ */
+trait StaticEnvCompanion[T] {
+  
+  /** Define Env as the type of the implementing object's companion class. */
+  type Env <: StaticEnv[T]
+  
+  /** Define EnvBinding as the type of the bindings. */
+  type EnvBinding <: StaticBinding[T]
+  
+  /**
+   * Extracts all the _immediate_ bindings for this kind of environment from the
+   * given node. If `node` is a collection of nodes, then this method returns
+   * the concatenation of all bindings found therein. Any bindings located
+   * further inside the node will not be extracted.
+   * 
+   * @param node A node or collection of nodes in which to extract bindings.
+   * @return A collection of all the bindings extracted in the given node.
+   */
+  protected def extractEnvBindings(node: Any): Collection[EnvBinding]
+  
+  /**
+   * Creates a new instance of the environment containing all the bindings
+   * found in the given node.
+   * 
+   * @param node A node or collection of nodes in which to find bindings.
+   * @return A new instance of Env containing these bindings.
+   */
+  def make(node: Any): Env
+}
+
+
+/**
+ * A static environment binding of a variable name to some kind of value.
+ * 
+ * @param name The variable name for the binding.
+ * @param value The bound value for this binding.
+ */
+abstract class StaticBinding[T](val name: Name, val value: T)
+
+object StaticBinding {
+  def unapply[T](b: StaticBinding[T]): Option[(Name, T)] = Some(b.name, b.value)
+}
+
Index: /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/impls/Functionals.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/impls/Functionals.scala (revision 3905)
+++ /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/impls/Functionals.scala (revision 3915)
@@ -328,7 +328,7 @@
       val methods = findMethodsInTraitHierarchy(op.get, objType)
       val arrows =
-        if (sargs.isEmpty) methods.map(makeArrowFromFunction)
-        else methods.
-               flatMap(m => staticInstantiation(sargs, makeArrowFromFunction(m))).
+        if (sargs.isEmpty) methods.map(makeArrowFromFunctional)
+        else methods.flatMap(m =>
+               staticInstantiation(sargs, makeArrowFromFunctional(m))).
                map(_.asInstanceOf[ArrowType])
 
Index: /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/impls/Common.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/impls/Common.scala (revision 3902)
+++ /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/impls/Common.scala (revision 3915)
@@ -177,14 +177,14 @@
       val (arg, param) = argAndParam
       (arg, param.getKind) match {
-        case (STypeArg(_, argType), SKindType(_)) =>
+        case (STypeArg(_, argType), _:KindType) =>
             toList(param.getExtendsClause).forall((bound:Type) =>
               isSubtype(argType, bound, arg,
                         errorMsg(normalize(argType), " not a subtype of ", normalize(bound))))
-        case (SIntArg(_, _), SKindInt(_)) => true
-        case (SBoolArg(_, _), SKindBool(_)) => true
-        case (SDimArg(_, _), SKindDim(_)) => true
-        case (SOpArg(_, _), SKindOp(_)) => true
-        case (SUnitArg(_, _), SKindUnit(_)) => true
-        case (SIntArg(_, _), SKindNat(_)) => true
+        case (_:IntArg, _:KindInt) => true
+        case (_:BoolArg, _:KindBool) => true
+        case (_:DimArg, _:KindDim) => true
+        case (_:OpArg, _:KindOp) => true
+        case (_:UnitArg, _:KindUnit) => true
+        case (_:IntArg, _:KindNat) => true
         case (_, _) => false
       }
Index: /unk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/KindEnv.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/KindEnv.scala (revision 3905)
+++  (revision )
@@ -1,98 +1,0 @@
-/*******************************************************************************
-    Copyright 2009 Sun Microsystems, Inc.,
-    4150 Network Circle, Santa Clara, California 95054, U.S.A.
-    All rights reserved.
-
-    U.S. Government Rights - Commercial software.
-    Government users are subject to the Sun Microsystems, Inc. standard
-    license agreement and applicable provisions of the FAR and its supplements.
-
-    Use is subject to license terms.
-
-    This distribution may include materials developed by third parties.
-
-    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
-    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
- ******************************************************************************/
-
-package com.sun.fortress.scala_src.typechecker
-
-import com.sun.fortress.compiler.Types
-import com.sun.fortress.nodes._
-import scala.collection.immutable.EmptyMap
-
-/**
- * Represents a list of variable name to static parameter bindings for some
- * context. All instances of this class should be created with `KindEnv.make`
- * or with the `extendWith` method.
- */
-abstract sealed class KindEnv extends StaticEnv[StaticParam] {
-  
-  /** My type. */
-  type Env = KindEnv
-  
-  /** My binding type. */
-  type EnvBinding = KindBinding
-
-  /** Extend me with the immediate bindings of the given node. */
-  def extendWith(node: Any): KindEnv =
-    new NestedKindEnv(this, KindEnv.extractEnvBindings(node))
-
-  /**
-   * Get the type of the given variable name, if it is bound. The resulting
-   * type will only be defined if this name maps to a bool, int, or nat static
-   * parameter.
-   */
-  def getType(x: Name): Option[Type] = lookup(x).flatMap(b =>
-    b.value.getKind match {
-      case _:KindBool => Some(Types.BOOLEAN)
-      case _:KindInt => Some(Types.INT_LITERAL)
-      case _:KindNat => Some(Types.INT_LITERAL)
-      case _ => None
-    })
-}
-
-/** The single empty kind environment. */
-object EmptyKindEnv extends KindEnv with EmptyStaticEnv[StaticParam]
-
-/**
- * A kind environment with a parent and some explicit bindings.
- * 
- * @param parent A kind environment that this one extends.
- * @param _bindings A collection of all the bindings in this environment.
- */
-class NestedKindEnv protected (protected val parent: KindEnv,
-                               _bindings: Collection[KindBinding])
-    extends KindEnv with NestedStaticEnv[StaticParam] {
-    
-  /** Internal representation of `bindings` is a map. */
-  protected val bindings: Map[Name, KindBinding] =
-    new EmptyMap ++ _bindings.map(b => b.name -> b)
-}
-
-/** Companion module for KindEnv; contains "static" members. */
-object KindEnv extends StaticEnvCompanion[StaticParam] {
-  
-  /** My type. */
-  type Env = KindEnv
-  
-  /** My binding type. */
-  type EnvBinding = KindBinding
-  
-  /** New kind environment with empty parent and the node's bindings. */
-  def make(node: Any): KindEnv =
-    new NestedKindEnv(EmptyKindEnv, extractEnvBindings(node))
-  
-  /** Extract out the bindings in node. */
-  protected def extractEnvBindings(node: Any) : Collection[KindBinding] = null
-}
-
-/**
- * A binding for a kind environment contains name to static parameter pairs.
- * 
- * @param name The variable name for the binding.
- * @param sparam The static parameter that this name is binding.
- */
-case class KindBinding(override val name: Name,
-                       sparam: StaticParam)
-    extends StaticBinding[StaticParam](name, sparam)
Index: /unk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/StaticEnv.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/StaticEnv.scala (revision 3905)
+++  (revision )
@@ -1,157 +1,0 @@
-/*******************************************************************************
-    Copyright 2009 Sun Microsystems, Inc.,
-    4150 Network Circle, Santa Clara, California 95054, U.S.A.
-    All rights reserved.
-
-    U.S. Government Rights - Commercial software.
-    Government users are subject to the Sun Microsystems, Inc. standard
-    license agreement and applicable provisions of the FAR and its supplements.
-
-    Use is subject to license terms.
-
-    This distribution may include materials developed by third parties.
-
-    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
-    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
- ******************************************************************************/
-
-package com.sun.fortress.scala_src.typechecker
-
-import com.sun.fortress.nodes.Name
-import com.sun.fortress.nodes.Type
-import com.sun.fortress.nodes_util.Modifiers
-
-/**
- * Represents an environment that exists during static checking, mapping
- * variable names to some value. Each static environment contains 
- */
-trait StaticEnv[T] extends Collection[StaticBinding[T]] {
-  
-  /** Define Env as the type of the implementing class. */
-  type Env <: StaticEnv[T]
-  
-  /** Define EnvBinding as the type of the bindings. */
-  type EnvBinding <: StaticBinding[T]
-  
-  /**
-   * Extend this environment with the bindings immediately contained in the
-   * given node.
-   * 
-   * @param node A node or collection of nodes in which to find bindings.
-   * @return A new environment with the bindings of this one and those found in
-   *         `node` combined.
-   */
-  def extendWith(node: Any): Env
-  
-  /**
-   * Gets the value stored for the given variable name, if that binding exists.
-   *
-   * @param name The name to lookup.
-   * @return Some(T) if name:T is a binding. None otherwise.
-   */
-  def lookup(x: Name): Option[EnvBinding]
-  
-  /** Same as lookup when treating implementing object as a function. */
-  def apply(x: Name): Option[EnvBinding] = lookup(x)
-  
-  /**
-   * Gets the type stored for the given variable name, if that binding exists.
-   * 
-   * @param name The name to lookup.
-   * @return Some(T) if name:T is a binding. None otherwise.
-   */
-  def getType(x: Name): Option[Type]
-  
-  /** Make the type on `Collection.elements` more specific. */
-  def elements: Iterator[EnvBinding]
-}
-
-/**
- * A single empty static environment. There are no bindings at all in this
- * environemnt.
- */
-trait EmptyStaticEnv[T] extends StaticEnv[T] {
-      
-  /** Every call to `lookup` fails. */
-  override def lookup(x: Name): Option[EnvBinding] = None
-      
-  /** Every call to `getType` fails. */
-  override def getType(x: Name): Option[Type] = None
-  
-  // Collection implementation
-  override def elements: Iterator[EnvBinding] = Iterator.empty
-  override def size: Int = 0
-}
-
-/**
- * A nested static environment that contains all the bindings of some parent
- * environment and additionally all the explicitly supplied bindings.
- */
-trait NestedStaticEnv[T] extends StaticEnv[T] {
-    
-  /** A static environment that this one extends. */
-  protected val parent: Env {
-    // Require that the parent has the same binding type.
-    type EnvBinding = NestedStaticEnv.this.EnvBinding
-  }
-    
-  /** The bindings explicitly declared in this environment. */
-  protected val bindings: Map[Name, EnvBinding]
-  
-  /** Find it among `bindings` or else in `parent`. */
-  def lookup(x: Name): Option[EnvBinding] = bindings.get(x) match {
-    case Some(v) => Some(v)
-    case None => parent.lookup(x)
-  }
-  
-  // Collection implementation
-  def elements: Iterator[EnvBinding] = parent.elements ++ bindings.values
-  def size: Int = parent.size + bindings.size
-}
-
-/**
- * Provides functionality for finding bindings in nodes and creating new
- * instances of the environment.
- */
-trait StaticEnvCompanion[T] {
-  
-  /** Define Env as the type of the implementing object's companion class. */
-  type Env <: StaticEnv[T]
-  
-  /** Define EnvBinding as the type of the bindings. */
-  type EnvBinding <: StaticBinding[T]
-  
-  /**
-   * Extracts all the _immediate_ bindings for this kind of environment from the
-   * given node. If `node` is a collection of nodes, then this method returns
-   * the concatenation of all bindings found therein. Any bindings located
-   * further inside the node will not be extracted.
-   * 
-   * @param node A node or collection of nodes in which to extract bindings.
-   * @return A collection of all the bindings extracted in the given node.
-   */
-  protected def extractEnvBindings(node: Any): Collection[EnvBinding]
-  
-  /**
-   * Creates a new instance of the environment containing all the bindings
-   * found in the given node.
-   * 
-   * @param node A node or collection of nodes in which to find bindings.
-   * @return A new instance of Env containing these bindings.
-   */
-  def make(node: Any): Env
-}
-
-
-/**
- * A static environment binding of a variable name to some kind of value.
- * 
- * @param name The variable name for the binding.
- * @param value The bound value for this binding.
- */
-abstract class StaticBinding[T](val name: Name, val value: T)
-
-object StaticBinding {
-  def unapply[T](b: StaticBinding[T]): Option[(Name, T)] = Some(b.name, b.value)
-}
-
Index: /unk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/STypeEnv.scala
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/scala_src/typechecker/STypeEnv.scala (revision 3905)
+++  (revision )
@@ -1,171 +1,0 @@
-/*******************************************************************************
-    Copyright 2009 Sun Microsystems, Inc.,
-    4150 Network Circle, Santa Clara, California 95054, U.S.A.
-    All rights reserved.
-
-    U.S. Government Rights - Commercial software.
-    Government users are subject to the Sun Microsystems, Inc. standard
-    license agreement and applicable provisions of the FAR and its supplements.
-
-    Use is subject to license terms.
-
-    This distribution may include materials developed by third parties.
-
-    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
-    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
- ******************************************************************************/
-
-package com.sun.fortress.scala_src.typechecker
-
-import com.sun.fortress.exceptions.InterpreterBug.bug
-import com.sun.fortress.nodes._
-import com.sun.fortress.nodes_util.Modifiers
-import com.sun.fortress.scala_src.useful.SExprUtil
-import scala.collection.immutable.EmptyMap
-
-/**
- * Represents a list of variable name to type bindings for some context. All
- * instances of this class should be created with `STypeEnv.make` or with the
- * `extendWith` method.
- */
-abstract sealed class STypeEnv extends StaticEnv[Type] {
-  
-  /** My type. */
-  type Env = STypeEnv
-  
-  /** My binding type. */
-  type EnvBinding = TypeBinding
-  
-  /** Extend me with the immediate bindings of the given node. */
-  def extendWith(node: Any): STypeEnv =
-    new NestedSTypeEnv(this, STypeEnv.extractEnvBindings(node))
-  
-  /** Same as `lookup`. */
-  def getType(x: Name): Option[Type] = lookup(x).map(_.value)
-}
-
-/** The single empty type environment. */
-object EmptySTypeEnv extends STypeEnv with EmptyStaticEnv[Type]
-
-/**
- * A type environment with a parent and some explicit bindings.
- * 
- * @param parent A type environment that this one extends.
- * @param _bindings A collection of all the bindings in this environment.
- */
-class NestedSTypeEnv protected (protected val parent: STypeEnv,
-                                _bindings: Collection[TypeBinding])
-    extends STypeEnv with NestedStaticEnv[Type] {
-    
-  /** Internal representation of `bindings` is a map. */
-  protected val bindings: Map[Name, TypeBinding] =
-    new EmptyMap ++ _bindings.map(b => b.name -> b)
-}
-
-/** Companion module for STypeEnv. */
-object STypeEnv extends StaticEnvCompanion[Type] {
-  
-  /** My type. */
-  type Env = STypeEnv
-  
-  /** My binding type. */
-  type EnvBinding = TypeBinding
-  
-  /** New type environment with empty parent and the node's bindings. */
-  def make(node: Any): STypeEnv =
-    new NestedSTypeEnv(EmptySTypeEnv, extractEnvBindings(node))
-  
-  /** Extract out the bindings in node. */
-  protected def extractEnvBindings(node: Any): Collection[TypeBinding] = null
-//    node match {
-//      case SParam => 
-//    }
-  
-//  protected def extractFnDecls(node: Any): List[FnDecl] = null
-//  
-//  /**
-//   * A type environment that stores types of named functionals. Return types
-//   * might not always be given on functional declarations, so this type
-//   * environment will lazily evaluate those types as needed.
-//   * 
-//   * This class should only ever be instantiated by `STypeEnv`.
-//   * 
-//   * @param parent A static environment that this one extends.
-//   * @param fnDecls An immutable list of all the functional declarations in
-//   *                scope for this type environment.
-//   */
-//  protected class LazyFnTypeEnv(protected val parent: STypeEnv,
-//                                protected val fnDecls: List[FnDecl],
-//                                protected val initialChecker: STypeChecker)
-//      extends STypeEnv(parent, Nil) {
-//    
-//    import scala.collection.mutable.Map
-//    import scala.collection.mutable.Stack
-//    
-//    type TypeThunk = Function0[Option[Type]]
-//    type UnambiguousName = Name
-//    
-//    /**
-//     * Contains the function names that have been called thus far during the
-//     * type checking of function bodies in this environment.
-//     */
-//    protected var callStack: Stack[Name] = new Stack
-//    
-//    /** Maps unsolved overloadings to their thunks. */
-//    protected var unsolvedOverloadings: Map[UnambiguousName, TypeThunk] = Map.empty
-//    
-//    /** Maps solved overloadings to their thunks. */
-//    protected var solvedOverloadings: Map[UnambiguousName, Type] = Map.empty
-//    
-//    /**  */
-//    protected var solved: Map[Name, Type] = Map.empty
-//    
-//    protected def makeThunk(fnDecl: FnDecl): TypeThunk = {
-//      
-//      // If return type given, just thunk it.
-//      fnDecl.getHeader.getReturnType match {
-//        case Some(t) => return () => t
-//        case _ =>
-//      }
-//      
-//      // Get relevant parts out of the decl.
-//      val name = fnDecl.getHeader.getName
-//      val unambiguousName = fnDecl.getUnambiguousName
-//      val body = fnDecl.getBody.getOrElse(bug("No body on function."))
-//      
-//      // Capture the type checker at this point.
-//      val checker = this.initialChecker
-//      def thunk: Option[Type] = {
-//        
-//        // If we have already seen this name, then there is a cycle!
-//        if (callStack.contains(name)) {
-//          checker.signal(body, "Cyclical reference to function %s while checking body of function %s"
-//                                   .format(name, this.callStack.top))
-//        }
-//        
-//        // Add this name to the call stack.
-//        this.callStack += name
-//        
-//        // Extend the type checker with the params of this decl and check.
-//        val newChecker = checker.extend(fnDecl)
-//        SExprUtil.getType(newChecker.checkExpr(body))
-//      }
-//      thunk _
-//    }
-//  }
-}
-
-
-/**
- * A binding for a type environment contains name to type pairs, along with some
- * modifiers for the binding and whether or not the binding is mutable.
- * 
- * @param name The variable name for the binding.
- * @param value The bound type for this variable name.
- * @param mods Any modifiers for the binding.
- * @param mutable Whether or not the binding is mutable.
- */
-case class TypeBinding(override val name: Name,
-                       typ: Type,
-                       mods: Modifiers,
-                       mutable: Boolean) extends StaticBinding[Type](name, typ)
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/phases/OverloadSet.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/phases/OverloadSet.java (revision 3906)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/phases/OverloadSet.java (revision 3915)
@@ -87,5 +87,5 @@
         }
         public Type getReturnType() {
-            return tagF.getReturnType();
+            return tagF.getReturnType().unwrap();
         }
         public int hashCode() {
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/TypeChecker.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/TypeChecker.java (revision 3863)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/TypeChecker.java (revision 3915)
@@ -606,5 +606,5 @@
             if(getters.containsKey(thatFieldRef.getField())) {
                 Method field=(Method)getters.get(thatFieldRef.getField()).instantiate(trait_static_params, trait_static_args);
-                return Option.some(field.getReturnType());
+                return Option.some(field.getReturnType().unwrap());
             }
             else {
@@ -3472,5 +3472,5 @@
             List<Type> ranges = CollectUtil.makeList(IterUtil.map(candidates, new Lambda<Method,Type>(){
                 public Type value(Method arg0) {
-                    return arg0.getReturnType();
+                    return arg0.getReturnType().unwrap();
                 }}));
 
@@ -4878,5 +4878,5 @@
 
         List<Type> ranges = CollectUtil.makeList(IterUtil.map(candidates, new Lambda<Method,Type>(){
-            public Type value(Method arg0) { return arg0.getReturnType(); }}));
+            public Type value(Method arg0) { return arg0.getReturnType().unwrap(); }}));
 
         Type range = this.subtypeChecker.meet(ranges);
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/TypeEnv.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/TypeEnv.java (revision 3803)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/TypeEnv.java (revision 3915)
@@ -356,44 +356,46 @@
      * compiler to distinguish them from other variants with the same _erased_ signature.
      */
+    // DONE
     public final TypeEnv extend(LValue... entries) {
         if (entries.length == 0) { return this; }
         else { return new LValueTypeEnv(entries, this); }
     }
-
+    // DONE
     public final TypeEnv extendWithLValues(List<LValue> entries) {
         if (entries.size() == 0) { return this; }
         else { return new LValueTypeEnv(entries, this); }
     }
-
+    // DONE
     public final TypeEnv extend(LocalVarDecl decl) {
         if (decl.getLhs().size() == 0) { return this; }
         else { return new LocalVarTypeEnv(decl, this); }
     }
-
+    // CALLED WITH CompilationUnitIndex.variables()
+    // DONE
     public final TypeEnv extend(Map<Id, Variable> vars) {
         if (vars.size() == 0) { return this; }
         else { return new VarTypeEnv(vars, this); }
     }
-
+    // DONE
     public final TypeEnv extendWithFunctions(Relation<IdOrOpOrAnonymousName, ? extends Function> fns) {
         if (fns.size() == 0) { return this; }
         else { return new FnTypeEnv(fns, this); }
     }
-
+    // UNNECESSARY
     public final TypeEnv extendWithFnDecls(Relation<IdOrOpOrAnonymousName, FnDecl> fns) {
         if (fns.size() == 0) { return this; }
         else { return new FnDeclTypeEnv(fns, this); }
     }
-
+    // DERIVED
     public final TypeEnv extendWithMethods(Relation<IdOrOpOrAnonymousName, Method> methods) {
         if (methods.size() == 0) { return this; }
         else { return new MethodTypeEnv(methods, this); }
     }
-
+    // DERIVED
     public final TypeEnv extendWithParams(List<Param> params) {
         if (params.size() == 0) { return this; }
         else { return new ParamTypeEnv(params, this); }
     }
-
+    // DERIVED
     public final TypeEnv extendWithParams(scala.List<Param> params) {
     	return extendWithParams(toJavaList(params));
@@ -408,5 +410,5 @@
     	return extendWithStaticParams(toJavaList(params));
     }
-
+    // DONE
     public final TypeEnv extendWithTypeConses(Map<Id, TypeConsIndex> typeConses) {
         if (typeConses.isEmpty()) {
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/NamingCzar.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/NamingCzar.java (revision 3912)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/NamingCzar.java (revision 3915)
@@ -599,5 +599,5 @@
 
     public static String jvmSignatureFor(Function f, APIName ifNone) {
-        return jvmSignatureFor(f.parameters(), f.getReturnType(), ifNone);
+        return jvmSignatureFor(f.parameters(), f.getReturnType().unwrap(), ifNone);
     }
 
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FieldGetterMethod.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FieldGetterMethod.java (revision 3366)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FieldGetterMethod.java (revision 3915)
@@ -21,4 +21,5 @@
 import java.util.List;
 
+import com.sun.fortress.compiler.Types;
 import com.sun.fortress.nodes.ArrowType;
 import com.sun.fortress.nodes.BaseType;
@@ -35,4 +36,5 @@
 import com.sun.fortress.useful.NI;
 
+import edu.rice.cs.plt.lambda.SimpleBox;
 import edu.rice.cs.plt.tuple.Option;
 
@@ -45,4 +47,5 @@
         _ast = ast;
         _declaringTrait = declaringTrait;
+        putThunk(SimpleBox.make(_ast.getIdType()));
     }
 
@@ -78,9 +81,4 @@
 
 	@Override
-	public Type getReturnType() {
-		return _ast.getIdType().unwrap();
-	}
-
-	@Override
 	public Id getDeclaringTrait() {
 		return this._declaringTrait;
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Functional.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Functional.java (revision 3714)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Functional.java (revision 3915)
@@ -31,4 +31,6 @@
 import com.sun.fortress.nodes_util.Span;
 
+import edu.rice.cs.plt.lambda.LazyThunk;
+import edu.rice.cs.plt.lambda.Thunk;
 import edu.rice.cs.plt.tuple.Option;
 
@@ -46,6 +48,4 @@
     public abstract Span getSpan();
 
-    public abstract Type getReturnType();
-
     public abstract List<StaticParam> staticParameters();
 
@@ -57,3 +57,25 @@
 
     public abstract Functional acceptNodeUpdateVisitor(NodeUpdateVisitor visitor);
+    
+    // Lazy return type inference -----
+
+    /**
+     * Thunks are used to lazily get the return type of Functionals, as return
+     * types may not be available for functionals in the current program during
+     * type checking.
+     */
+    protected Option<Thunk<Option<Type>>> _thunk = Option.none();
+    
+    public void putThunk(Thunk<Option<Type>> thunk) {
+        _thunk = Option.<Thunk<Option<Type>>>some(LazyThunk.make(thunk));
+    }
+    
+    /**
+     * Evaluate the thunk to get a return type. Then replace the thunk with one
+     * that simply gets back the previously evaluated return type.
+     */
+    public Option<Type> getReturnType() {
+        if (_thunk.isNone()) return Option.none();
+        return _thunk.unwrap().value();
+    }
 }
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/ParametricOperator.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/ParametricOperator.java (revision 3518)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/ParametricOperator.java (revision 3915)
@@ -38,4 +38,5 @@
 import com.sun.fortress.useful.NI;
 
+import edu.rice.cs.plt.lambda.SimpleBox;
 import edu.rice.cs.plt.tuple.Option;
 
@@ -50,4 +51,5 @@
         super(ast, declaringTrait);
         _name = (Op)NodeUtil.getName(ast);
+        putThunk(SimpleBox.make(NodeUtil.getReturnType(_ast)));
     }
 
@@ -99,9 +101,4 @@
 
 	@Override
-	public Type getReturnType() {
-		return NodeUtil.getReturnType(_ast).unwrap();
-	}
-
-	@Override
 	public Functional acceptNodeUpdateVisitor(NodeUpdateVisitor visitor) {
 		return new FunctionalMethod((FnDecl)this.ast().accept(visitor), this._declaringTrait);
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FunctionalMethod.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FunctionalMethod.java (revision 3764)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FunctionalMethod.java (revision 3915)
@@ -38,4 +38,5 @@
 import com.sun.fortress.useful.NI;
 
+import edu.rice.cs.plt.lambda.SimpleBox;
 import edu.rice.cs.plt.tuple.Option;
 
@@ -51,4 +52,5 @@
         _ast = ast;
         _declaringTrait = declaringTrait;
+        putThunk(SimpleBox.make(NodeUtil.getReturnType(_ast)));
     }
 
@@ -109,9 +111,4 @@
 
 	@Override
-	public Type getReturnType() {
-		return NodeUtil.getReturnType(_ast).unwrap();
-	}
-
-	@Override
 	public Functional acceptNodeUpdateVisitor(NodeUpdateVisitor visitor) {
 		return new FunctionalMethod((FnDecl)this.ast().accept(visitor), this._declaringTrait);
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/DeclaredMethod.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/DeclaredMethod.java (revision 3366)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/DeclaredMethod.java (revision 3915)
@@ -21,4 +21,5 @@
 import java.util.List;
 
+import com.sun.fortress.compiler.Types;
 import com.sun.fortress.compiler.typechecker.StaticTypeReplacer;
 import com.sun.fortress.nodes.BaseType;
@@ -36,4 +37,5 @@
 import com.sun.fortress.nodes_util.Span;
 
+import edu.rice.cs.plt.lambda.SimpleBox;
 import edu.rice.cs.plt.tuple.Option;
 
@@ -46,4 +48,5 @@
         _ast = ast;
         _declaringTrait = declaringTrait;
+        putThunk(SimpleBox.make(NodeUtil.getReturnType(_ast)));
     }
 
@@ -93,9 +96,4 @@
 
 	@Override
-	public Type getReturnType() {
-		return NodeUtil.getReturnType(_ast).unwrap();
-	}
-
-	@Override
 	public Id getDeclaringTrait() {
 		return this._declaringTrait;
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/DeclaredFunction.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/DeclaredFunction.java (revision 3764)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/DeclaredFunction.java (revision 3915)
@@ -37,4 +37,5 @@
 import com.sun.fortress.useful.NI;
 
+import edu.rice.cs.plt.lambda.SimpleBox;
 import edu.rice.cs.plt.tuple.Option;
 
@@ -42,5 +43,8 @@
     private final FnDecl _ast;
 
-    public DeclaredFunction(FnDecl ast) { _ast = ast; }
+    public DeclaredFunction(FnDecl ast) {
+      _ast = ast;
+      putThunk(SimpleBox.make(NodeUtil.getReturnType(_ast)));
+    }
 
     public FnDecl ast() { return _ast; }
@@ -98,9 +102,4 @@
 
 	@Override
-	public Type getReturnType() {
-		return NodeUtil.getReturnType(_ast).unwrap();
-	}
-
-	@Override
 	public Functional acceptNodeUpdateVisitor(NodeUpdateVisitor visitor) {
 		return new DeclaredFunction((FnDecl)this._ast.accept(visitor));
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FieldSetterMethod.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FieldSetterMethod.java (revision 3366)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/FieldSetterMethod.java (revision 3915)
@@ -38,4 +38,5 @@
 import com.sun.fortress.useful.NI;
 
+import edu.rice.cs.plt.lambda.SimpleBox;
 import edu.rice.cs.plt.tuple.Option;
 
@@ -48,4 +49,5 @@
         _ast = ast;
         _declaringTrait = declaringTrait;
+        putThunk(SimpleBox.make(Option.<Type>some(Types.VOID)));
     }
 
@@ -86,9 +88,4 @@
 
 	@Override
-	public Type getReturnType() {
-		return Types.VOID;
-	}
-
-	@Override
 	public Id getDeclaringTrait() {
 		return this._declaringTrait;
Index: /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Constructor.java
===================================================================
--- /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Constructor.java (revision 3764)
+++ /trunk/ProjectFortress/src/com/sun/fortress/compiler/index/Constructor.java (revision 3915)
@@ -39,4 +39,5 @@
 import edu.rice.cs.plt.iter.IterUtil;
 import edu.rice.cs.plt.lambda.Lambda;
+import edu.rice.cs.plt.lambda.Thunk;
 import edu.rice.cs.plt.tuple.Option;
 
@@ -60,4 +61,9 @@
         _throwsClause = throwsClause;
         _where = where;
+        putThunk(new Thunk<Option<Type>>() {
+          @Override public Option<Type> value() {
+            return NI.nyi();
+          }
+        });
     }
 
@@ -117,10 +123,4 @@
 
 	@Override
-	public Type getReturnType() {
-		// TODO Auto-generated method stub
-		return NI.nyi();
-	}
-
-	@Override
 	public Functional acceptNodeUpdateVisitor(final NodeUpdateVisitor v) {
 
