Simplify backend + create at right place
diff --git a/lib/src/codegen/backend/backend.dart b/lib/src/codegen/backend.dart
similarity index 81%
rename from lib/src/codegen/backend/backend.dart
rename to lib/src/codegen/backend.dart
index 29c3791..32bc255 100644
--- a/lib/src/codegen/backend/backend.dart
+++ b/lib/src/codegen/backend.dart
@@ -5,29 +5,47 @@
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
 
-import '../../js/js_ast.dart' as JS;
+import 'es6_backend.dart';
+import 'typescript_backend.dart';
+import 'module_builder.dart';
+
+import '../js/js_ast.dart' as JS;
+import '../options.dart';
+import '../utils.dart';
+import '../compiler.dart';
 
 abstract class Backend {
+  Backend.base();
+  factory Backend(AbstractCompiler compiler) {
+    moduleBuilderFactory() =>
+        new ModuleBuilder(compiler.options.codegenOptions.moduleFormat);
+
+    if (compiler.options.codegenOptions.closure) {
+      return new TypeScriptBackend(compiler, moduleBuilderFactory);
+    } else {
+      return new Es6Backend(compiler, moduleBuilderFactory);
+    }
+  }
+
   LibraryBuilder libraryBuilder(LibraryElement element);
   // JS.Expression buildTypeLiteral(JS.TypeRef typeRef);
 }
 
 abstract class LibraryBuilder {
+  String jsModuleValue;
   LibraryElement get element;
-  LibraryPartBuilder libraryPartBuilder(CompilationUnitElement element);
+  JS.Expression get exportsVar;
 
-  void build();
-}
-
-abstract class LibraryPartBuilder {
-  CompilationUnitElement get element;
   void buildTypedef(
       FunctionTypeAliasElement element,
       JS.TypeRef returnType, List<JS.TypeRef> paramTypes);
 
   ClassBuilder classBuilder(ClassElement element, ClassDeclaration node);
+
+  void build();
 }
 
+
 abstract class ClassBuilder {
   ClassElement get element;
   ClassDeclaration get node;
diff --git a/lib/src/codegen/backend/es6_backend.dart b/lib/src/codegen/backend/es6_backend.dart
deleted file mode 100644
index 3a6db97..0000000
--- a/lib/src/codegen/backend/es6_backend.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
-
-import 'backend.dart';
-import '../../js/js_ast.dart' as JS;
-import '../module_builder.dart';
-import '../../utils.dart' show FileSystem;
-
-class Es6Backend extends Backend {
-  final ModuleBuilder _moduleBuilder;
-  final FileSystem _fileSystem;
-  Es6Backend(this._moduleBuilder, this._fileSystem);
-
-  LibraryBuilder libraryBuilder(LibraryElement element) =>
-      new Es6LibraryBuilder(this, element);
-}
-
-class Es6LibraryBuilder extends LibraryBuilder {
-  final Es6Backend _backend;
-  final LibraryElement element;
-  Es6LibraryBuilder(this._backend, this.element);
-
-  LibraryPartBuilder libraryPartBuilder(CompilationUnitElement element) =>
-      new Es6LibraryPartBuilder(_backend, element);
-
-  void build() {
-    // TODO(ochafik)
-  }
-}
-
-class Es6LibraryPartBuilder extends LibraryPartBuilder {
-  final Es6Backend _backend;
-  final CompilationUnitElement element;
-  Es6LibraryPartBuilder(this._backend, this.element);
-
-  void buildTypedef(
-      FunctionTypeAliasElement element,
-      JS.TypeRef returnType, List<JS.TypeRef> paramTypes) {
-    // TODO(ochafik)
-  }
-
-  ClassBuilder classBuilder(ClassElement element, ClassDeclaration node) =>
-      new Es6ClassBuilder(_backend, element, node);
-}
-
-class Es6ClassBuilder extends DefaultClassBuilder {
-  final Es6Backend _backend;
-  final ClassElement element;
-  final ClassDeclaration node;
-
-  Es6ClassBuilder(this._backend, this.element, this.node);
-
-  void build() {
-    // TODO(ochafik)
-  }
-}
diff --git a/lib/src/codegen/es6_backend.dart b/lib/src/codegen/es6_backend.dart
new file mode 100644
index 0000000..83f05b4
--- /dev/null
+++ b/lib/src/codegen/es6_backend.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
+
+import 'backend.dart';
+import 'module_builder.dart';
+import '../compiler.dart' show AbstractCompiler;
+import '../js/js_ast.dart' as JS;
+import 'js_names.dart' as JS;
+import 'js_metalet.dart' as JS;
+
+class Es6Backend extends Backend {
+  final AbstractCompiler compiler;
+  final ModuleBuilderFactory moduleBuilderFactory;
+  Es6Backend(this.compiler, this.moduleBuilderFactory) : super.base();
+
+  LibraryBuilder libraryBuilder(LibraryElement element) =>
+      new Es6LibraryBuilder(this, moduleBuilderFactory(), element);
+}
+
+class Es6LibraryBuilder extends LibraryBuilder {
+  final moduleItems = <JS.ModuleItem>[];
+  final Es6Backend _backend;
+  final LibraryElement element;
+  final ModuleBuilder moduleBuilder;
+  Es6LibraryBuilder(this._backend, this.moduleBuilder, this.element);
+  JS.Expression get exportsVar => moduleBuilder.exportsVar;
+
+  get compiler => _backend.compiler;
+
+  void buildTypedef(
+      FunctionTypeAliasElement element,
+      JS.TypeRef returnType, List<JS.TypeRef> paramTypes) {
+    // TODO(ochafik)
+    // moduleItems.add();
+  }
+
+  ClassBuilder classBuilder(ClassElement element, ClassDeclaration node) =>
+      new Es6ClassBuilder(moduleItems, element, node);
+
+  void build() {
+    var moduleBuilder = _backend.moduleBuilderFactory();
+    var module = moduleBuilder.build(
+        _backend.compiler.getModuleName(element.source.uri),
+        jsModuleValue,
+        moduleItems);
+
+    // TODO(ochafik).
+    // var out = _backend.compiler.getOutputPath(element.source.uri);
+    // var flags = compiler.options;
+    // var serverUri = flags.serverMode
+    //     ? Uri.parse('http://${flags.host}:${flags.port}/')
+    //     : null;
+    // return writeJsLibrary(module, out, compiler.inputBaseDir, serverUri,
+    //     emitSourceMaps: _backend.compiler.options.codegenOptions.emitSourceMaps);
+    // TODO(ochafik)
+  }
+}
+
+class Es6ClassBuilder extends DefaultClassBuilder {
+  final List<JS.ModuleItem> out;
+  final ClassElement element;
+  final ClassDeclaration node;
+
+  Es6ClassBuilder(this.out, this.element, this.node);
+
+  void build() {
+    // TODO(ochafik)
+  }
+}
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
index 2b3fddf..f59b0c0 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -29,6 +29,7 @@
 import '../options.dart' show CodegenOptions;
 import '../utils.dart';
 
+import 'backend.dart';
 import 'code_generator.dart';
 import 'js_field_storage.dart';
 import 'js_interop.dart';
@@ -56,7 +57,8 @@
 class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
   final AbstractCompiler compiler;
   final CodegenOptions options;
-  final LibraryElement currentLibrary;
+  final LibraryBuilder libraryBuilder;
+  LibraryElement get currentLibrary => libraryBuilder.element;
   final StrongTypeSystemImpl rules;
 
   /// The global extension type table.
@@ -90,7 +92,7 @@
   /// The name for the library's exports inside itself.
   /// `exports` was chosen as the most similar to ES module patterns.
   final _dartxVar = new JS.Identifier('dartx');
-  final _exportsVar = new JS.TemporaryId('exports');
+  JS.Expression get _exportsVar => libraryBuilder.exportsVar;
   final _runtimeLibVar = new JS.Identifier('dart');
   final _namedArgTemp = new JS.TemporaryId('opts');
 
@@ -108,7 +110,7 @@
 
   bool _isDartRuntime;
 
-  JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary,
+  JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.libraryBuilder,
       this._extensionTypes, this._fieldsNeedingStorage)
       : compiler = compiler,
         options = compiler.options.codegenOptions,
@@ -213,7 +215,6 @@
     return moduleBuilder.build(
         compiler.getModuleName(currentLibrary.source.uri),
         _jsModuleValue,
-        _exportsVar,
         items);
   }
 
@@ -3546,8 +3547,10 @@
 class JSGenerator extends CodeGenerator {
   final _extensionTypes = new HashSet<ClassElement>();
   final TypeProvider _types;
+  final Backend _backend;
   JSGenerator(AbstractCompiler compiler)
       : _types = compiler.context.typeProvider,
+        _backend = new Backend(compiler),
         super(compiler) {
     // TODO(jacobr): determine the the set of types with extension methods from
     // the annotations rather than hard coding the list once the analyzer
@@ -3580,8 +3583,11 @@
     var library = unit.library.element.library;
     var fields = findFieldsNeedingStorage(unit, _extensionTypes);
     var rules = new StrongTypeSystemImpl();
+    var libraryBuilder = _backend.libraryBuilder(library);
     var codegen =
-        new JSCodegenVisitor(compiler, rules, library, _extensionTypes, fields);
+        new JSCodegenVisitor(compiler, rules, libraryBuilder, _extensionTypes, fields);
+    libraryBuilder.build();
+    // TODO(ochafik): Move the following lines to [LibraryBuilder.build]:
     var module = codegen.emitLibrary(unit);
     var out = compiler.getOutputPath(library.source.uri);
     var flags = compiler.options;
diff --git a/lib/src/codegen/module_builder.dart b/lib/src/codegen/module_builder.dart
index 22cc871..de65a18 100644
--- a/lib/src/codegen/module_builder.dart
+++ b/lib/src/codegen/module_builder.dart
@@ -6,8 +6,12 @@
 
 import '../js/js_ast.dart' as JS;
 import '../js/js_ast.dart' show js;
+import 'js_names.dart' as JS;
+import 'js_metalet.dart' as JS;
 import '../options.dart' show ModuleFormat;
 
+typedef ModuleBuilder ModuleBuilderFactory();
+
 /// Helper that builds JS modules in a given [ModuleFormat].
 abstract class ModuleBuilder {
   final _exports = <String, String>{};
@@ -15,13 +19,15 @@
 
   ModuleBuilder._();
 
+  /// Name of the object on which items are exported.
+  /// Lazy variables and constants are assumed to be declared on this instance.
+  JS.Expression get exportsVar;
+
   /// Returns a [format]-specific [ModuleBuilder].
   /// - [jsPath] is the path of the module being built.
   /// - [jsModuleValue] is the default value to use for the library, in case of
   ///   js interop (comes from the @js.JS(jsModuleValue) annotation on the
   ///   library directive). It is null in any other case.
-  /// - [exportsVar] is the name of the object on which items are exported. Lazy
-  ///   variables and constants are assumed to be declared on this instance.
   factory ModuleBuilder(ModuleFormat format) {
     switch (format) {
       case ModuleFormat.legacy:
@@ -49,7 +55,7 @@
 
   /// Builds a program out of menu items.
   JS.Program build(String jsPath, String jsModuleValue,
-      JS.Identifier exportsVar, Iterable<JS.ModuleItem> moduleItems);
+      Iterable<JS.ModuleItem> moduleItems);
 }
 
 class _ModuleImport {
@@ -65,9 +71,10 @@
 /// Generates modules for with DDC's `dart_library.js` loading mechanism.
 class LegacyModuleBuilder extends ModuleBuilder {
   LegacyModuleBuilder() : super._();
+  final exportsVar = new JS.TemporaryId('exports');
 
   JS.Program build(String jsPath, String jsModuleValue,
-      JS.Identifier exportsVar, Iterable<JS.ModuleItem> moduleItems) {
+      Iterable<JS.ModuleItem> moduleItems) {
     // TODO(jmesserly): it would be great to run the renamer on the body,
     // then figure out if we really need each of these parameters.
     // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34
@@ -123,9 +130,10 @@
 // TODO(ochafik): Break strong dep cycles to accommodate the Closure Compiler.
 class ES6ModuleBuilder extends ModuleBuilder {
   ES6ModuleBuilder() : super._();
+  final exportsVar = new JS.TemporaryId('exports');
 
   JS.Program build(String jsPath, String jsModuleValue,
-      JS.Identifier exportsVar, Iterable<JS.ModuleItem> moduleItems) {
+      Iterable<JS.ModuleItem> moduleItems) {
     var moduleStatements = <JS.ModuleItem>[
       js.statement("const # = {};", [exportsVar])
     ];
@@ -165,9 +173,11 @@
 /// Generates node modules.
 class NodeModuleBuilder extends ModuleBuilder {
   NodeModuleBuilder() : super._();
+  /// This is *not* a [JS.TemporaryId].
+  final exportsVar = new JS.Identifier('exports');
 
   JS.Program build(String jsPath, String jsModuleValue,
-      JS.Identifier exportsVar, Iterable<JS.ModuleItem> moduleItems) {
+      Iterable<JS.ModuleItem> moduleItems) {
     var moduleStatements = <JS.ModuleItem>[js.statement("'use strict';"),];
 
     for (var i in _imports) {
diff --git a/lib/src/codegen/typescript_backend.dart b/lib/src/codegen/typescript_backend.dart
new file mode 100644
index 0000000..fc59c86
--- /dev/null
+++ b/lib/src/codegen/typescript_backend.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'es6_backend.dart';
+import 'module_builder.dart';
+import '../utils.dart';
+import '../compiler.dart';
+
+class TypeScriptBackend extends Es6Backend {
+  TypeScriptBackend(
+      AbstractCompiler compiler, ModuleBuilderFactory moduleBuilderFactory)
+          : super(compiler, moduleBuilderFactory);
+}
diff --git a/lib/src/compiler.dart b/lib/src/compiler.dart
index 097a2dc..aabff36 100644
--- a/lib/src/compiler.dart
+++ b/lib/src/compiler.dart
@@ -32,7 +32,7 @@
 import 'options.dart';
 import 'report.dart';
 import 'report/html_reporter.dart';
-import 'utils.dart' show isStrongModeError;
+import 'utils.dart' show FileSystem, isStrongModeError;
 
 /// Sets up the type checker logger to print a span that highlights error
 /// messages.
@@ -358,6 +358,9 @@
   final AnalysisContext context;
   final AnalysisErrorListener reporter;
 
+  // TODO(ochafik): Update transformer CL.
+  FileSystem fileSystem;
+
   AbstractCompiler(this.context, this.options, [AnalysisErrorListener listener])
       : reporter = listener ?? AnalysisErrorListener.NULL_LISTENER;