Drop generic classes when --closure
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
index ea55316..a33a17c 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -531,7 +531,7 @@
     var genericName = '$name\$';
 
     JS.Statement genericDef = null;
-    if (type.typeParameters.isNotEmpty) {
+    if (type.typeParameters.isNotEmpty && genericClassesEnabled) {
       genericDef = _emitGenericClassDef(type, body);
     }
 
@@ -700,7 +700,8 @@
     body.add(new JS.ClassDeclaration(cls));
 
     // TODO(jmesserly): we should really just extend native Array.
-    if (jsPeerName != null && classElem.typeParameters.isNotEmpty) {
+    if (jsPeerName != null && classElem.typeParameters.isNotEmpty
+        && genericClassesEnabled) {
       body.add(js.statement('dart.setBaseClass(#, dart.global.#);',
           [classElem.name, _propertyName(jsPeerName)]));
     }
@@ -1600,12 +1601,16 @@
   /// the definitions for typedefs and generic types, respectively.
   JS.Expression _emitTypeName(DartType type,
       {bool lowerTypedef: false, bool lowerGeneric: false}) {
+
+    isSkippedTypeParameterType() =>
+        type is TypeParameterType && !genericClassesEnabled;
+    
     // The void and dynamic types are not defined in core.
     if (type.isVoid) {
       return js.call('dart.void');
     } else if (type.isDynamic) {
       return js.call('dart.dynamic');
-    } else if (type.isBottom) {
+    } else if (type.isBottom || isSkippedTypeParameterType()) {
       return js.call('dart.bottom');
     }
 
@@ -1625,7 +1630,7 @@
       return new JS.Identifier(name);
     }
 
-    if (type is ParameterizedType) {
+    if (type is ParameterizedType && genericClassesEnabled) {
       var args = type.typeArguments;
       var isCurrentClass =
           args.isNotEmpty && _loader.isCurrentElement(type.element);
@@ -3206,6 +3211,8 @@
     return id == null ? type.name : '${id.name}.${type.name}';
   }
 
+  bool get genericClassesEnabled => !options.closure;
+
   JS.Node annotate(JS.Node method, ExecutableElement e) =>
       options.closure && e != null
           ? method.withClosureAnnotation(
diff --git a/test/codegen/closure.dart b/test/codegen/closure.dart
index d40e8a7..4c873f2 100644
--- a/test/codegen/closure.dart
+++ b/test/codegen/closure.dart
@@ -1,7 +1,6 @@
 library test;
 import 'dart:js';
 
-
 typedef void Callback({int i});
 
 class Foo<T> {
@@ -46,13 +45,16 @@
   static String some_static_var = "abc";
 }
 
-class Bar {}
+class Bar<T> {}
 
-class Baz extends Foo<int> with Bar {
-  Baz(int i) : super(i, 123);
+class Baz<T> extends Foo<T> with Bar<T> {
+  Baz(int i, T v) : super(i, v);
 }
 
-void main(args) {}
+void main(args) {
+  print(new Bar());
+  print(new Bar<String>());
+}
 
 const String some_top_level_constant = "abc";
 final String some_top_level_final = "abc";
diff --git a/test/codegen/expect/closure.js b/test/codegen/expect/closure.js
index 0dbfa37..41d58c5 100644
--- a/test/codegen/expect/closure.js
+++ b/test/codegen/expect/closure.js
@@ -8,110 +8,106 @@
   let dartx = dart.dartx;
   /** @typedef {function({i: (?number|undefined)}=)} */
   let Callback = dart.typedef('Callback', () => dart.functionType(dart.void, [], {i: core.int}));
-  let Foo$ = dart.generic(function(T) {
-    class Foo extends core.Object {
-      /**
-       * @param {?number} i
-       * @param {?} v
-       */
-      Foo(i, v) {
-        this.i = i;
-        this.v = v;
-        this.b = null;
-        this.s = null;
-      }
-      /** @return {Foo} */
-      static build() {
-        return new (Foo$(T))(1, null);
-      }
-      /**
-       * @param {?} a
-       * @param {?} b
-       */
-      untyped_method(a, b) {}
-      /** @param {?} t */
-      pass(t) {
-        dart.as(t, T);
-        return t;
-      }
-      /**
-       * @param {Foo} foo
-       * @param {core.List} list
-       * @param {?number} i
-       * @param {?number} n
-       * @param {?number} d
-       * @param {?boolean} b
-       * @param {string} s
-       * @param {Array<?>} a
-       * @param {Object<*, *>} o
-       * @param {Function} f
-       * @return {string}
-       */
-      typed_method(foo, list, i, n, d, b, s, a, o, f) {
-        return '';
-      }
-      /**
-       * @param {?} a
-       * @param {?=} b
-       * @param {?=} c
-       */
-      optional_params(a, b, c) {
-        if (b === void 0)
-          b = null;
-        if (c === void 0)
-          c = null;
-      }
-      /**
-       * @param {?} a
-       * @param {{b: (?|undefined), c: (?|undefined)}=} opts
-       */
-      static named_params(a, opts) {
-        let b = opts && 'b' in opts ? opts.b : null;
-        let c = opts && 'c' in opts ? opts.c : null;
-      }
-      nullary_method() {}
-      /**
-       * @param {function(?, ?=):?number} f
-       * @param {function(?, {y: (string|undefined), z: (?|undefined)}=):?} g
-       * @param {Callback} cb
-       */
-      function_params(f, g, cb) {
-        dart.as(f, dart.functionType(core.int, [dart.dynamic], [dart.dynamic]));
-        dart.as(g, dart.functionType(dart.dynamic, [dart.dynamic], {y: core.String, z: dart.dynamic}));
-        cb({i: this.i});
-      }
-      /** @return {string} */
-      get prop() {
-        return null;
-      }
-      /** @param {string} value */
-      set prop(value) {}
-      /** @return {string} */
-      static get staticProp() {
-        return null;
-      }
-      /** @param {string} value */
-      static set staticProp(value) {}
+  class Foo extends core.Object {
+    /**
+     * @param {?number} i
+     * @param {?} v
+     */
+    Foo(i, v) {
+      this.i = i;
+      this.v = v;
+      this.b = null;
+      this.s = null;
     }
-    dart.setSignature(Foo, {
-      constructors: () => ({
-        Foo: [Foo$(T), [core.int, T]],
-        build: [Foo$(T), []]
-      }),
-      methods: () => ({
-        untyped_method: [dart.dynamic, [dart.dynamic, dart.dynamic]],
-        pass: [T, [T]],
-        typed_method: [core.String, [Foo$(), core.List, core.int, core.num, core.double, core.bool, core.String, js.JsArray, js.JsObject, js.JsFunction]],
-        optional_params: [dart.dynamic, [dart.dynamic], [dart.dynamic, dart.dynamic]],
-        nullary_method: [dart.dynamic, []],
-        function_params: [dart.dynamic, [dart.functionType(core.int, [dart.dynamic], [dart.dynamic]), dart.functionType(dart.dynamic, [dart.dynamic], {y: core.String, z: dart.dynamic}), Callback]]
-      }),
-      statics: () => ({named_params: [dart.dynamic, [dart.dynamic], {b: dart.dynamic, c: dart.dynamic}]}),
-      names: ['named_params']
-    });
-    return Foo;
+    /** @return {Foo} */
+    static build() {
+      return new Foo(1, null);
+    }
+    /**
+     * @param {?} a
+     * @param {?} b
+     */
+    untyped_method(a, b) {}
+    /** @param {?} t */
+    pass(t) {
+      dart.as(t, dart.bottom);
+      return t;
+    }
+    /**
+     * @param {Foo} foo
+     * @param {core.List} list
+     * @param {?number} i
+     * @param {?number} n
+     * @param {?number} d
+     * @param {?boolean} b
+     * @param {string} s
+     * @param {Array<?>} a
+     * @param {Object<*, *>} o
+     * @param {Function} f
+     * @return {string}
+     */
+    typed_method(foo, list, i, n, d, b, s, a, o, f) {
+      return '';
+    }
+    /**
+     * @param {?} a
+     * @param {?=} b
+     * @param {?=} c
+     */
+    optional_params(a, b, c) {
+      if (b === void 0)
+        b = null;
+      if (c === void 0)
+        c = null;
+    }
+    /**
+     * @param {?} a
+     * @param {{b: (?|undefined), c: (?|undefined)}=} opts
+     */
+    static named_params(a, opts) {
+      let b = opts && 'b' in opts ? opts.b : null;
+      let c = opts && 'c' in opts ? opts.c : null;
+    }
+    nullary_method() {}
+    /**
+     * @param {function(?, ?=):?number} f
+     * @param {function(?, {y: (string|undefined), z: (?|undefined)}=):?} g
+     * @param {Callback} cb
+     */
+    function_params(f, g, cb) {
+      dart.as(f, dart.functionType(core.int, [dart.dynamic], [dart.dynamic]));
+      dart.as(g, dart.functionType(dart.dynamic, [dart.dynamic], {y: core.String, z: dart.dynamic}));
+      cb({i: this.i});
+    }
+    /** @return {string} */
+    get prop() {
+      return null;
+    }
+    /** @param {string} value */
+    set prop(value) {}
+    /** @return {string} */
+    static get staticProp() {
+      return null;
+    }
+    /** @param {string} value */
+    static set staticProp(value) {}
+  }
+  dart.setSignature(Foo, {
+    constructors: () => ({
+      Foo: [Foo, [core.int, dart.bottom]],
+      build: [Foo, []]
+    }),
+    methods: () => ({
+      untyped_method: [dart.dynamic, [dart.dynamic, dart.dynamic]],
+      pass: [dart.bottom, [dart.bottom]],
+      typed_method: [core.String, [Foo, core.List, core.int, core.num, core.double, core.bool, core.String, js.JsArray, js.JsObject, js.JsFunction]],
+      optional_params: [dart.dynamic, [dart.dynamic], [dart.dynamic, dart.dynamic]],
+      nullary_method: [dart.dynamic, []],
+      function_params: [dart.dynamic, [dart.functionType(core.int, [dart.dynamic], [dart.dynamic]), dart.functionType(dart.dynamic, [dart.dynamic], {y: core.String, z: dart.dynamic}), Callback]]
+    }),
+    statics: () => ({named_params: [dart.dynamic, [dart.dynamic], {b: dart.dynamic, c: dart.dynamic}]}),
+    names: ['named_params']
   });
-  let Foo = Foo$();
   /** @final {string} */
   Foo.some_static_constant = "abc";
   /** @final {string} */
@@ -119,17 +115,22 @@
   /** @type {string} */
   Foo.some_static_var = "abc";
   class Bar extends core.Object {}
-  class Baz extends dart.mixin(Foo$(core.int), Bar) {
-    /** @param {?number} i */
-    Baz(i) {
-      super.Foo(i, 123);
+  class Baz extends dart.mixin(Foo, Bar) {
+    /**
+     * @param {?number} i
+     * @param {?} v
+     */
+    Baz(i, v) {
+      super.Foo(i, v);
     }
   }
   dart.setSignature(Baz, {
-    constructors: () => ({Baz: [Baz, [core.int]]})
+    constructors: () => ({Baz: [Baz, [core.int, dart.bottom]]})
   });
   /** @param {?} args */
   function main(args) {
+    core.print(new Bar());
+    core.print(new Bar());
   }
   dart.fn(main, dart.void, [dart.dynamic]);
   /** @final {string} */
@@ -140,7 +141,6 @@
   exports.some_top_level_var = "abc";
   // Exports:
   exports.Callback = Callback;
-  exports.Foo$ = Foo$;
   exports.Foo = Foo;
   exports.Bar = Bar;
   exports.Baz = Baz;
diff --git a/test/codegen/expect/html_input.html b/test/codegen/expect/html_input.html
index 96ed534..e04f195 100644
--- a/test/codegen/expect/html_input.html
+++ b/test/codegen/expect/html_input.html
@@ -27,10 +27,10 @@
 <script src="dev_compiler/runtime/dart/mirrors.js"></script>
 <script src="dev_compiler/runtime/dart/_js_mirrors.js"></script>
 <script src="dev_compiler/runtime/dart/js.js"></script>
-<script src="dir/html_input_d.js"></script>
-<script src="dir/html_input_b.js"></script>
 <script src="dir/html_input_e.js"></script>
 <script src="dir/html_input_c.js"></script>
+<script src="dir/html_input_d.js"></script>
+<script src="dir/html_input_b.js"></script>
 <script src="dir/html_input_a.js"></script>
 <script>dart_library.start('dir/html_input_a');</script>
 
diff --git a/test/codegen/expect/sunflower/sunflower.html b/test/codegen/expect/sunflower/sunflower.html
index aab058c..62c60f7 100644
--- a/test/codegen/expect/sunflower/sunflower.html
+++ b/test/codegen/expect/sunflower/sunflower.html
@@ -51,8 +51,8 @@
 <script src="../dev_compiler/runtime/dart/mirrors.js"></script>
 <script src="../dev_compiler/runtime/dart/_js_mirrors.js"></script>
 <script src="../dev_compiler/runtime/dart/js.js"></script>
-<script src="dom.js"></script>
 <script src="circle.js"></script>
+<script src="dom.js"></script>
 <script src="painter.js"></script>
 <script src="sunflower.js"></script>
 <script>dart_library.start('sunflower/sunflower');</script>