| Index: lib/compiler/implementation/typechecker.dart | 
| diff --git a/lib/compiler/implementation/typechecker.dart b/lib/compiler/implementation/typechecker.dart | 
| index 6f3dacc53efd2b0cb66bd92c10d575c63b3a8a22..1bc286096ee2caeb624ca49d4386761b80407b33 100644 | 
| --- a/lib/compiler/implementation/typechecker.dart | 
| +++ b/lib/compiler/implementation/typechecker.dart | 
| @@ -33,6 +33,8 @@ class TypeVariableType implements Type { | 
| final SourceString name; | 
| Element element; | 
| TypeVariableType(this.name, [this.element]); | 
| + | 
| +  toString() => name.toString(); | 
| } | 
|  | 
| /** | 
| @@ -58,12 +60,29 @@ class StatementType implements Type { | 
| String toString() => stringName; | 
| } | 
|  | 
| -class SimpleType implements Type { | 
| +class InterfaceType implements Type { | 
| final SourceString name; | 
| -  final Element element; | 
| +  final ClassElement element; | 
| +  final Link<Type> arguments; | 
|  | 
| -  const SimpleType(SourceString this.name, Element this.element); | 
| +  const InterfaceType(this.name, this.element, this.arguments); | 
| + | 
| +  toString() { | 
| +    StringBuffer sb = new StringBuffer(); | 
| +    sb.add(name.slowToString()); | 
| +    if (!arguments.isEmpty()) { | 
| +      sb.add('<'); | 
| +      arguments.printOn(sb); | 
| +      sb.add('>'); | 
| +    } | 
| +    return sb.toString(); | 
| +  } | 
| +} | 
|  | 
| +// TODO(karlklose): merge into InterfaceType as a named constructor. | 
| +class SimpleType extends InterfaceType { | 
| +  const SimpleType(SourceString name, Element element) | 
| +    : super(name, element, const EmptyLink<Type>()); | 
| String toString() => name.slowToString(); | 
| } | 
|  | 
| @@ -101,6 +120,7 @@ class Types { | 
| final SimpleType dynamicType; | 
|  | 
| Types() : this.with(new LibraryElement(new Script(null, null))); | 
| + | 
| Types.with(LibraryElement library) | 
| : voidType = new SimpleType(VOID, new ClassElement(VOID, library)), | 
| dynamicType = new SimpleType(DYNAMIC, new ClassElement(DYNAMIC, library)); | 
| @@ -172,9 +192,9 @@ Type lookupType(SourceString name, Compiler compiler, types) { | 
| class TypeCheckerVisitor implements Visitor<Type> { | 
| final Compiler compiler; | 
| final TreeElements elements; | 
| -  Node lastSeenNode; | 
| final Types types; | 
|  | 
| +  Node lastSeenNode; | 
| Type expectedReturnType; | 
| ClassElement currentClass; | 
|  | 
| @@ -187,8 +207,7 @@ class TypeCheckerVisitor implements Visitor<Type> { | 
| Type objectType; | 
| Type listType; | 
|  | 
| -  TypeCheckerVisitor(Compiler this.compiler, TreeElements this.elements, | 
| -                     Types this.types) { | 
| +  TypeCheckerVisitor(this.compiler, this.elements, this.types) { | 
| intType = lookupType(Types.INT, compiler, types); | 
| doubleType = lookupType(Types.DOUBLE, compiler, types); | 
| boolType = lookupType(Types.BOOL, compiler, types); | 
| @@ -456,19 +475,19 @@ class TypeCheckerVisitor implements Visitor<Type> { | 
| FunctionType computeFunType() { | 
| if (node.receiver !== null) { | 
| Type receiverType = analyze(node.receiver); | 
| -          if (receiverType === types.dynamicType) return null; | 
| -            if (receiverType === null) { | 
| -              fail(node.receiver, 'receivertype is null'); | 
| -            } | 
| -            if (receiverType.element.kind !== ElementKind.CLASS) { | 
| -              fail(node.receiver, 'receivertype is not a class'); | 
| -            } | 
| -            ClassElement classElement = receiverType.element; | 
| -            // TODO(karlklose): substitute type arguments. | 
| -            Type memberType = | 
| -              lookupMethodType(selector, classElement, selector.source); | 
| -            if (memberType === types.dynamicType) return null; | 
| -            return memberType; | 
| +          if (receiverType.element == compiler.dynamicClass) return null; | 
| +          if (receiverType === null) { | 
| +            fail(node.receiver, 'receivertype is null'); | 
| +          } | 
| +          if (receiverType.element.kind !== ElementKind.CLASS) { | 
| +            fail(node.receiver, 'receivertype is not a class'); | 
| +          } | 
| +          ClassElement classElement = receiverType.element; | 
| +          // TODO(karlklose): substitute type arguments. | 
| +          Type memberType = | 
| +            lookupMethodType(selector, classElement, selector.source); | 
| +          if (memberType.element === compiler.dynamicClass) return null; | 
| +          return memberType; | 
| } else { | 
| Element element = elements[node]; | 
| if (element === null) { | 
|  |