Remove Compiler access from ResolutionEnqueuer

+ move CommonMasks into ClosedWorld
+ move OpenWorld into ResolutionWorldBuilder

Main changes in:
compiler.dart
enqueue.dart
world.dart
types/types.dart
universe/world_builder.dart

R=het@google.com

Review URL: https://codereview.chromium.org/2488353004 .
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index e0c6826..f9885ba 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -19,7 +19,6 @@
 import 'resolution/tree_elements.dart' show TreeElements;
 import 'tokens/token.dart' show Token;
 import 'tree/tree.dart';
-import 'universe/world_builder.dart' show CodegenWorldBuilder;
 import 'util/util.dart';
 
 class ClosureTask extends CompilerTask {
@@ -122,7 +121,7 @@
       throw new SpannableAssertionFailure(
           closure, 'Not a closure: $closure (${closure.runtimeType}).');
     }
-    compiler.enqueuer.codegen.forgetElement(cls);
+    compiler.enqueuer.codegen.forgetElement(cls, compiler);
   }
 }
 
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index ea4ae66..f58ef31 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -86,17 +86,17 @@
   void enqueueHelpers(ResolutionEnqueuer world);
 
   /// Creates an [Enqueuer] for code generation specific to this backend.
-  Enqueuer createCodegenEnqueuer(Compiler compiler);
+  Enqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler);
 
   WorldImpact codegen(CodegenWorkItem work);
 
   // The backend determines the native resolution enqueuer, with a no-op
   // default, so tools like dart2dart can ignore the native classes.
-  native.NativeEnqueuer nativeResolutionEnqueuer(world) {
+  native.NativeEnqueuer nativeResolutionEnqueuer() {
     return new native.NativeEnqueuer();
   }
 
-  native.NativeEnqueuer nativeCodegenEnqueuer(world) {
+  native.NativeEnqueuer nativeCodegenEnqueuer() {
     return new native.NativeEnqueuer();
   }
 
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 538692a..aeec588 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -158,6 +158,9 @@
   /// Resolve [element] if it has not already been resolved.
   void ensureResolved(Element element);
 
+  /// Ensure the resolution of all members of [element].
+  void ensureClassMembers(ClassElement element);
+
   /// Registers that [element] has a compile time error.
   ///
   /// The error itself is given in [message].
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index c2dad31..c2f91fe 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -77,7 +77,11 @@
     show ResolutionWorldBuilder, CodegenWorldBuilder;
 import 'universe/use.dart' show StaticUse;
 import 'universe/world_impact.dart'
-    show ImpactStrategy, WorldImpact, WorldImpactBuilderImpl;
+    show
+        ImpactStrategy,
+        WorldImpact,
+        WorldImpactBuilder,
+        WorldImpactBuilderImpl;
 import 'util/util.dart' show Link, Setlet;
 import 'world.dart' show ClosedWorld, ClosedWorldRefiner, OpenWorld, WorldImpl;
 
@@ -90,7 +94,7 @@
   Measurer get measurer;
 
   final IdGenerator idGenerator = new IdGenerator();
-  WorldImpl _world;
+  WorldImpl get _world => resolverWorld.openWorld;
   Types types;
   _CompilerCoreTypes _coreTypes;
   CompilerDiagnosticReporter _reporter;
@@ -140,7 +144,6 @@
   CommonElements get commonElements => _coreTypes;
   CoreClasses get coreClasses => _coreTypes;
   CoreTypes get coreTypes => _coreTypes;
-  CommonMasks get commonMasks => globalInference.masks;
   Resolution get resolution => _resolution;
   ParsingContext get parsingContext => _parsingContext;
 
@@ -185,10 +188,8 @@
   /// A customizable filter that is applied to enqueued work items.
   QueueFilter enqueuerFilter = new QueueFilter();
 
-  bool enabledRuntimeType = false;
-  bool enabledFunctionApply = false;
-  bool enabledInvokeOn = false;
-  bool hasIsolateSupport = false;
+  bool get hasFunctionApplySupport => resolverWorld.hasFunctionApplySupport;
+  bool get hasIsolateSupport => resolverWorld.hasIsolateSupport;
 
   bool get hasCrashed => _reporter.hasCrashed;
 
@@ -217,7 +218,6 @@
         this.userOutputProvider = outputProvider == null
             ? const NullCompilerOutput()
             : outputProvider {
-    _world = new WorldImpl(this);
     if (makeReporter != null) {
       _reporter = makeReporter(this, options);
     } else {
@@ -249,6 +249,7 @@
           useKernel: options.useKernel);
       backend = jsBackend;
     }
+    enqueuer = backend.makeEnqueuer();
 
     if (options.dumpInfo && options.useStartupEmitter) {
       throw new ArgumentError(
@@ -280,7 +281,9 @@
       constants = backend.constantCompilerTask,
       deferredLoadTask = new DeferredLoadTask(this),
       mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this),
-      enqueuer = backend.makeEnqueuer(),
+      // [enqueuer] is created earlier because it contains the resolution world
+      // objects needed by other tasks.
+      enqueuer,
       dumpInfoTask = new DumpInfoTask(this),
       selfTask = new GenericTask('self', measurer),
     ];
@@ -647,7 +650,7 @@
         // something to the resolution queue.  So we cannot wait with
         // this until after the resolution queue is processed.
         deferredLoadTask.beforeResolution(this);
-        impactStrategy = backend.createImpactStrategy(
+        ImpactStrategy impactStrategy = backend.createImpactStrategy(
             supportDeferredLoad: deferredLoadTask.isProgramSplit,
             supportDumpInfo: options.dumpInfo,
             supportSerialization: serialization.supportSerialization);
@@ -755,7 +758,7 @@
   void closeResolution() {
     phase = PHASE_DONE_RESOLVING;
 
-    openWorld.closeWorld();
+    openWorld.closeWorld(reporter);
     // Compute whole-program-knowledge that the backend needs. (This might
     // require the information computed in [world.closeWorld].)
     backend.onResolutionComplete();
@@ -827,28 +830,30 @@
   }
 
   /**
-   * Empty the [world] queue.
+   * Empty the [enqueuer] queue.
    */
-  void emptyQueue(Enqueuer world) =>
-      selfTask.measureSubtask("Compiler.emptyQueue", () {
-        world.forEach((WorkItem work) {
-          reporter.withCurrentElement(
-              work.element,
-              () => selfTask.measureSubtask("world.applyImpact", () {
-                    world.applyImpact(
-                        selfTask.measureSubtask(
-                            "work.run", () => work.run(this, world)),
-                        impactSource: work.element);
-                  }));
-        });
+  void emptyQueue(Enqueuer enqueuer) {
+    selfTask.measureSubtask("Compiler.emptyQueue", () {
+      enqueuer.forEach((WorkItem work) {
+        reporter.withCurrentElement(
+            work.element,
+            () => selfTask.measureSubtask("world.applyImpact", () {
+                  enqueuer.applyImpact(
+                      impactStrategy,
+                      selfTask.measureSubtask(
+                          "work.run", () => work.run(this, enqueuer)),
+                      impactSource: work.element);
+                }));
       });
+    });
+  }
 
   void processQueue(Enqueuer enqueuer, Element main) {
     selfTask.measureSubtask("Compiler.processQueue", () {
       WorldImpactBuilderImpl nativeImpact = new WorldImpactBuilderImpl();
       enqueuer.nativeEnqueuer
           .processNativeClasses(nativeImpact, libraryLoader.libraries);
-      enqueuer.applyImpact(nativeImpact);
+      enqueuer.applyImpact(impactStrategy, nativeImpact);
       if (main != null && !main.isMalformed) {
         FunctionElement mainMethod = main;
         mainMethod.computeType(resolution);
@@ -2039,6 +2044,13 @@
   }
 
   @override
+  void ensureClassMembers(ClassElement element) {
+    if (!compiler.serialization.isDeserialized(element)) {
+      compiler.resolver.checkClass(element);
+    }
+  }
+
+  @override
   void registerCompileTimeError(Element element, DiagnosticMessage message) =>
       compiler.registerCompileTimeError(element, message);
 
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index e1e39c8..db6a13a 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -420,7 +420,9 @@
 
   final Map<Element, Set<Element>> _dependencies = {};
   void registerDependency(Element source, Element target) {
-    _dependencies.putIfAbsent(source, () => new Set()).add(target);
+    if (compiler.options.dumpInfo) {
+      _dependencies.putIfAbsent(source, () => new Set()).add(target);
+    }
   }
 
   void registerImpact(Element element, WorldImpact impact) {
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 660e2e8..369c3ef 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -6,13 +6,17 @@
 
 import 'dart:collection' show Queue;
 
+import 'cache_strategy.dart';
+import 'common/backend_api.dart' show Backend;
 import 'common/names.dart' show Identifiers;
-import 'common/resolution.dart' show Resolution;
-import 'common/resolution.dart' show ResolutionWorkItem;
+import 'common/resolution.dart' show Resolution, ResolutionWorkItem;
+import 'common/registry.dart' show Registry;
 import 'common/tasks.dart' show CompilerTask;
 import 'common/work.dart' show WorkItem;
 import 'common.dart';
-import 'compiler.dart' show Compiler;
+import 'compiler.dart' show Compiler, GlobalDependencyRegistry;
+import 'core_types.dart' show CommonElements;
+import 'options.dart';
 import 'dart_types.dart' show DartType, InterfaceType;
 import 'elements/elements.dart'
     show
@@ -32,44 +36,49 @@
 import 'universe/use.dart'
     show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
 import 'universe/world_impact.dart'
-    show ImpactUseCase, WorldImpact, WorldImpactVisitor;
+    show ImpactStrategy, ImpactUseCase, WorldImpact, WorldImpactVisitor;
 import 'util/util.dart' show Setlet;
+import 'world.dart' show OpenWorld;
 
 class EnqueueTask extends CompilerTask {
-  final ResolutionEnqueuer resolution;
-  final Enqueuer codegen;
+  ResolutionEnqueuer _resolution;
+  Enqueuer _codegen;
   final Compiler compiler;
 
   String get name => 'Enqueue';
 
   EnqueueTask(Compiler compiler)
-      : compiler = compiler,
-        resolution = new ResolutionEnqueuer(
-            compiler,
-            compiler.options.analyzeOnly && compiler.options.analyzeMain
-                ? const EnqueuerStrategy()
-                : const TreeShakingEnqueuerStrategy()),
-        codegen = compiler.backend.createCodegenEnqueuer(compiler),
+      : this.compiler = compiler,
         super(compiler.measurer) {
-    codegen.task = this;
-    resolution.task = this;
-
-    codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen);
-    resolution.nativeEnqueuer =
-        compiler.backend.nativeResolutionEnqueuer(resolution);
+    _resolution = new ResolutionEnqueuer(
+        this,
+        compiler.options,
+        compiler.resolution,
+        compiler.enqueuerFilter,
+        compiler.options.analyzeOnly && compiler.options.analyzeMain
+            ? const EnqueuerStrategy()
+            : const TreeShakingEnqueuerStrategy(),
+        compiler.globalDependencies,
+        compiler.backend,
+        compiler.coreClasses,
+        compiler.cacheStrategy);
+    _codegen = compiler.backend.createCodegenEnqueuer(this, compiler);
   }
 
+  ResolutionEnqueuer get resolution => _resolution;
+  Enqueuer get codegen => _codegen;
+
   void forgetElement(Element element) {
-    resolution.forgetElement(element);
-    codegen.forgetElement(element);
+    resolution.forgetElement(element, compiler);
+    codegen.forgetElement(element, compiler);
   }
 }
 
 abstract class Enqueuer {
-  EnqueueTask task;
+  CompilerTask get task;
   WorldBuilder get universe;
-  native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
-  void forgetElement(Element element);
+  native.NativeEnqueuer get nativeEnqueuer;
+  void forgetElement(Element element, Compiler compiler);
   void processInstantiatedClassMembers(ClassElement cls);
   void processInstantiatedClassMember(ClassElement cls, Element member);
   void handleUnseenSelectorInternal(DynamicUse dynamicUse);
@@ -102,7 +111,8 @@
   /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provided
   /// the impact strategy will remove it from the element impact cache, if it is
   /// no longer needed.
-  void applyImpact(WorldImpact worldImpact, {Element impactSource});
+  void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact,
+      {Element impactSource});
   bool checkNoEnqueuedInvokedInstanceMethods();
   void logSummary(log(message));
 
@@ -116,8 +126,16 @@
 
 /// [Enqueuer] which is specific to resolution.
 class ResolutionEnqueuer extends Enqueuer {
+  final CompilerTask task;
   final String name;
-  final Compiler compiler; // TODO(ahe): Remove this dependency.
+  final Resolution resolution;
+  final QueueFilter filter;
+  final CompilerOptions options;
+  final Backend backend;
+  final GlobalDependencyRegistry globalDependencies;
+  final CommonElements commonElements;
+  final native.NativeEnqueuer nativeEnqueuer;
+
   final EnqueuerStrategy strategy;
   final Map<String, Set<Element>> instanceMembersByName =
       new Map<String, Set<Element>>();
@@ -125,31 +143,43 @@
       new Map<String, Set<Element>>();
   final Set<ClassElement> _processedClasses = new Set<ClassElement>();
   Set<ClassElement> recentClasses = new Setlet<ClassElement>();
-  final ResolutionWorldBuilderImpl _universe =
-      new ResolutionWorldBuilderImpl(const TypeMaskStrategy());
+  final ResolutionWorldBuilderImpl _universe;
 
   bool queueIsClosed = false;
 
   WorldImpactVisitor impactVisitor;
 
-  ResolutionEnqueuer(Compiler compiler, this.strategy)
+  ImpactStrategy impactStrategy;
+
+  ResolutionEnqueuer(
+      this.task,
+      this.options,
+      this.resolution,
+      this.filter,
+      this.strategy,
+      this.globalDependencies,
+      Backend backend,
+      CommonElements commonElements,
+      CacheStrategy cacheStrategy)
       : this.name = 'resolution enqueuer',
-        this.compiler = compiler,
+        this.backend = backend,
+        this.commonElements = commonElements,
+        this.nativeEnqueuer = backend.nativeResolutionEnqueuer(),
         processedElements = new Set<AstElement>(),
         queue = new Queue<ResolutionWorkItem>(),
-        deferredQueue = new Queue<_DeferredAction>() {
+        deferredQueue = new Queue<_DeferredAction>(),
+        _universe = new ResolutionWorldBuilderImpl(
+            backend, commonElements, cacheStrategy, const TypeMaskStrategy()) {
     impactVisitor = new _EnqueuerImpactVisitor(this);
   }
 
-  Resolution get resolution => compiler.resolution;
-
   ResolutionWorldBuilder get universe => _universe;
 
+  OpenWorld get openWorld => universe.openWorld;
+
   bool get queueIsEmpty => queue.isEmpty;
 
-  QueueFilter get filter => compiler.enqueuerFilter;
-
-  DiagnosticReporter get reporter => compiler.reporter;
+  DiagnosticReporter get reporter => resolution.reporter;
 
   bool isClassProcessed(ClassElement cls) => _processedClasses.contains(cls);
 
@@ -162,23 +192,19 @@
    */
   void addToWorkList(Element element) {
     assert(invariant(element, element.isDeclaration));
-    if (internalAddToWorkList(element) && compiler.options.dumpInfo) {
-      // TODO(sigmund): add other missing dependencies (internals, selectors
-      // enqueued after allocations), also enable only for the codegen enqueuer.
-      compiler.dumpInfoTask
-          .registerDependency(compiler.currentElement, element);
-    }
+    internalAddToWorkList(element);
+  }
+
+  void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact,
+      {Element impactSource}) {
+    impactStrategy.visitImpact(
+        impactSource, worldImpact, impactVisitor, impactUse);
   }
 
   void registerInstantiatedType(InterfaceType type) {
     _registerInstantiatedType(type, globalDependency: true);
   }
 
-  void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
-    compiler.impactStrategy
-        .visitImpact(impactSource, worldImpact, impactVisitor, impactUse);
-  }
-
   void _registerInstantiatedType(InterfaceType type,
       {bool mirrorUsage: false,
       bool nativeUsage: false,
@@ -186,19 +212,19 @@
     task.measure(() {
       ClassElement cls = type.element;
       cls.ensureResolved(resolution);
-      bool isNative = compiler.backend.isNative(cls);
+      bool isNative = backend.isNative(cls);
       _universe.registerTypeInstantiation(type,
           isNative: isNative,
           byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
-        compiler.backend.registerImplementedClass(cls, this);
+            backend.registerImplementedClass(cls, this);
       });
       if (globalDependency && !mirrorUsage) {
-        compiler.globalDependencies.registerDependency(type.element);
+        globalDependencies.registerDependency(type.element);
       }
       if (nativeUsage) {
         nativeEnqueuer.onInstantiatedType(type);
       }
-      compiler.backend.registerInstantiatedType(type);
+      backend.registerInstantiatedType(type);
       // TODO(johnniwinther): Share this reasoning with [Universe].
       if (!cls.isAbstract || isNative || mirrorUsage) {
         processInstantiatedClass(cls);
@@ -228,14 +254,14 @@
       // its metadata parsed and analyzed.
       // Note: this assumes that there are no non-native fields on native
       // classes, which may not be the case when a native class is subclassed.
-      if (compiler.backend.isNative(cls)) {
-        compiler.openWorld.registerUsedElement(member);
-        if (_universe.hasInvokedGetter(member, compiler.openWorld) ||
-            _universe.hasInvocation(member, compiler.openWorld)) {
+      if (backend.isNative(cls)) {
+        openWorld.registerUsedElement(member);
+        if (_universe.hasInvokedGetter(member, openWorld) ||
+            _universe.hasInvocation(member, openWorld)) {
           addToWorkList(member);
           return;
         }
-        if (_universe.hasInvokedSetter(member, compiler.openWorld)) {
+        if (_universe.hasInvokedSetter(member, openWorld)) {
           addToWorkList(member);
           return;
         }
@@ -259,7 +285,7 @@
       }
       // If there is a property access with the same name as a method we
       // need to emit the method.
-      if (_universe.hasInvokedGetter(function, compiler.openWorld)) {
+      if (_universe.hasInvokedGetter(function, openWorld)) {
         registerClosurizedMember(function);
         addToWorkList(function);
         return;
@@ -269,27 +295,27 @@
       instanceFunctionsByName
           .putIfAbsent(memberName, () => new Set<Element>())
           .add(member);
-      if (_universe.hasInvocation(function, compiler.openWorld)) {
+      if (_universe.hasInvocation(function, openWorld)) {
         addToWorkList(function);
         return;
       }
     } else if (member.isGetter) {
       FunctionElement getter = member;
       getter.computeType(resolution);
-      if (_universe.hasInvokedGetter(getter, compiler.openWorld)) {
+      if (_universe.hasInvokedGetter(getter, openWorld)) {
         addToWorkList(getter);
         return;
       }
       // We don't know what selectors the returned closure accepts. If
       // the set contains any selector we have to assume that it matches.
-      if (_universe.hasInvocation(getter, compiler.openWorld)) {
+      if (_universe.hasInvocation(getter, openWorld)) {
         addToWorkList(getter);
         return;
       }
     } else if (member.isSetter) {
       FunctionElement setter = member;
       setter.computeType(resolution);
-      if (_universe.hasInvokedSetter(setter, compiler.openWorld)) {
+      if (_universe.hasInvokedSetter(setter, openWorld)) {
         addToWorkList(setter);
         return;
       }
@@ -316,13 +342,11 @@
         recentClasses.add(superclass);
         superclass.ensureResolved(resolution);
         superclass.implementation.forEachMember(processInstantiatedClassMember);
-        if (!compiler.serialization.isDeserialized(superclass)) {
-          compiler.resolver.checkClass(superclass);
-        }
+        resolution.ensureClassMembers(superclass);
         // We only tell the backend once that [superclass] was instantiated, so
         // any additional dependencies must be treated as global
         // dependencies.
-        compiler.backend.registerInstantiatedClass(superclass, this);
+        backend.registerInstantiatedClass(superclass, this);
       }
 
       ClassElement superclass = cls;
@@ -372,7 +396,7 @@
     Selector selector = dynamicUse.selector;
     String methodName = selector.name;
     processInstanceMembers(methodName, (Element member) {
-      if (dynamicUse.appliesUnnamed(member, compiler.openWorld)) {
+      if (dynamicUse.appliesUnnamed(member, openWorld)) {
         if (member.isFunction && selector.isGetter) {
           registerClosurizedMember(member);
         }
@@ -383,7 +407,7 @@
     });
     if (selector.isGetter) {
       processInstanceFunctions(methodName, (Element member) {
-        if (dynamicUse.appliesUnnamed(member, compiler.openWorld)) {
+        if (dynamicUse.appliesUnnamed(member, openWorld)) {
           registerClosurizedMember(member);
           return true;
         }
@@ -406,11 +430,11 @@
     assert(invariant(element, element.isDeclaration,
         message: "Element ${element} is not the declaration."));
     _universe.registerStaticUse(staticUse);
-    compiler.backend.registerStaticUse(this, element);
+    backend.registerStaticUse(this, element);
     bool addElement = true;
     switch (staticUse.kind) {
       case StaticUseKind.STATIC_TEAR_OFF:
-        compiler.backend.registerGetOfStaticFunction(this);
+        backend.registerGetOfStaticFunction(this);
         break;
       case StaticUseKind.FIELD_GET:
       case StaticUseKind.FIELD_SET:
@@ -463,7 +487,7 @@
         _registerIsCheck(type);
         break;
       case TypeUseKind.CHECKED_MODE_CHECK:
-        if (compiler.options.enableTypeAssertions) {
+        if (options.enableTypeAssertions) {
           _registerIsCheck(type);
         }
         break;
@@ -473,7 +497,7 @@
   }
 
   void _registerIsCheck(DartType type) {
-    type = _universe.registerIsCheck(type, compiler);
+    type = _universe.registerIsCheck(type, resolution);
     // Even in checked mode, type annotations for return type and argument
     // types do not imply type checks, so there should never be a check
     // against the type variable of a typedef.
@@ -481,17 +505,17 @@
   }
 
   void registerCallMethodWithFreeTypeVariables(Element element) {
-    compiler.backend.registerCallMethodWithFreeTypeVariables(element, this);
+    backend.registerCallMethodWithFreeTypeVariables(element, this);
     _universe.callMethodsWithFreeTypeVariables.add(element);
   }
 
   void registerClosurizedMember(TypedElement element) {
     assert(element.isInstanceMember);
     if (element.computeType(resolution).containsTypeVariables) {
-      compiler.backend.registerClosureWithFreeTypeVariables(element, this);
+      backend.registerClosureWithFreeTypeVariables(element, this);
       _universe.closuresWithFreeTypeVariables.add(element);
     }
-    compiler.backend.registerBoundClosure(this);
+    backend.registerBoundClosure(this);
     _universe.closurizedMembers.add(element);
   }
 
@@ -542,7 +566,7 @@
   /// Registers [element] as processed by the resolution enqueuer.
   void registerProcessedElement(AstElement element) {
     processedElements.add(element);
-    compiler.backend.onElementResolved(element);
+    backend.onElementResolved(element);
   }
 
   /**
@@ -561,16 +585,16 @@
           element, "Resolution work list is closed. Trying to add $element.");
     }
 
-    compiler.openWorld.registerUsedElement(element);
+    openWorld.registerUsedElement(element);
 
-    ResolutionWorkItem workItem = compiler.resolution.createWorkItem(element);
+    ResolutionWorkItem workItem = resolution.createWorkItem(element);
     queue.add(workItem);
 
     // Enable isolate support if we start using something from the isolate
     // library, or timers for the async library.  We exclude constant fields,
     // which are ending here because their initializing expression is compiled.
     LibraryElement library = element.library;
-    if (!compiler.hasIsolateSupport && (!element.isField || !element.isConst)) {
+    if (!universe.hasIsolateSupport && (!element.isField || !element.isConst)) {
       String uri = library.canonicalUri.toString();
       if (uri == 'dart:isolate') {
         enableIsolateSupport();
@@ -589,23 +613,23 @@
       // We have to enable runtime type before hitting the codegen, so
       // that constructors know whether they need to generate code for
       // runtime type.
-      compiler.enabledRuntimeType = true;
+      _universe.hasRuntimeTypeSupport = true;
       // TODO(ahe): Record precise dependency here.
-      compiler.backend.registerRuntimeType(this);
-    } else if (compiler.commonElements.isFunctionApplyMethod(element)) {
-      compiler.enabledFunctionApply = true;
+      backend.registerRuntimeType(this);
+    } else if (commonElements.isFunctionApplyMethod(element)) {
+      _universe.hasFunctionApplySupport = true;
     }
 
     return true;
   }
 
   void registerNoSuchMethod(Element element) {
-    compiler.backend.registerNoSuchMethod(element);
+    backend.registerNoSuchMethod(element);
   }
 
   void enableIsolateSupport() {
-    compiler.hasIsolateSupport = true;
-    compiler.backend.enableIsolateSupport(this);
+    _universe.hasIsolateSupport = true;
+    backend.enableIsolateSupport(this);
   }
 
   /**
@@ -635,7 +659,7 @@
   bool onQueueEmpty(Iterable<ClassElement> recentClasses) {
     _emptyDeferredQueue();
 
-    return compiler.backend.onQueueEmpty(this, recentClasses);
+    return backend.onQueueEmpty(this, recentClasses);
   }
 
   void emptyDeferredQueueForTesting() => _emptyDeferredQueue();
@@ -647,7 +671,7 @@
     }
   }
 
-  void forgetElement(Element element) {
+  void forgetElement(Element element, Compiler compiler) {
     _universe.forgetElement(element, compiler);
     _processedClasses.remove(element);
     instanceMembersByName[element.name]?.remove(element);
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index ddca262..7e3bbd6 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -12,6 +12,7 @@
 import '../constants/values.dart';
 import '../dart_types.dart' show DartType, FunctionType, TypeKind;
 import '../elements/elements.dart';
+import '../js_backend/backend.dart';
 import '../tree/dartstring.dart' show DartString;
 import '../tree/tree.dart' as ast show Node, LiteralBool, Send;
 import '../types/masks.dart'
@@ -521,13 +522,13 @@
       return mask;
     }
     if (element.isField) {
-      return _narrowType(compiler, mask, element.type);
+      return _narrowType(compiler.closedWorld, mask, element.type);
     }
     assert(
         element.isFunction || element.isGetter || element.isFactoryConstructor);
 
     FunctionType type = element.type;
-    return _narrowType(compiler, mask, type.returnType);
+    return _narrowType(compiler.closedWorld, mask, type.returnType);
   }
 
   TypeMask computeType(TypeGraphInferrerEngine inferrer) {
@@ -668,7 +669,7 @@
     // ignore type annotations to ensure that the checks are actually inserted
     // into the function body and retained until runtime.
     assert(!compiler.options.enableTypeAssertions);
-    return _narrowType(compiler, mask, element.type);
+    return _narrowType(compiler.closedWorld, mask, element.type);
   }
 
   TypeMask computeType(TypeGraphInferrerEngine inferrer) {
@@ -970,9 +971,10 @@
     inferrer.updateSelectorInTree(caller, call, selector, typeMask);
 
     Compiler compiler = inferrer.compiler;
+    JavaScriptBackend backend = compiler.backend;
     TypeMask maskToUse =
         compiler.closedWorld.extendMaskIfReachesAll(selector, typeMask);
-    bool canReachAll = compiler.enabledInvokeOn && (maskToUse != typeMask);
+    bool canReachAll = backend.hasInvokeOnSupport && (maskToUse != typeMask);
 
     // If this call could potentially reach all methods that satisfy
     // the untyped selector (through noSuchMethod's `Invocation`
@@ -1724,24 +1726,24 @@
   T visitAwaitTypeInformation(AwaitTypeInformation info);
 }
 
-TypeMask _narrowType(Compiler compiler, TypeMask type, DartType annotation,
+TypeMask _narrowType(
+    ClosedWorld closedWorld, TypeMask type, DartType annotation,
     {bool isNullable: true}) {
   if (annotation.treatAsDynamic) return type;
   if (annotation.isObject) return type;
   TypeMask otherType;
   if (annotation.isTypedef || annotation.isFunctionType) {
-    otherType = compiler.commonMasks.functionType;
+    otherType = closedWorld.commonMasks.functionType;
   } else if (annotation.isTypeVariable) {
     // TODO(ngeoffray): Narrow to bound.
     return type;
   } else if (annotation.isVoid) {
-    otherType = compiler.commonMasks.nullType;
+    otherType = closedWorld.commonMasks.nullType;
   } else {
     assert(annotation.isInterfaceType);
-    otherType =
-        new TypeMask.nonNullSubtype(annotation.element, compiler.closedWorld);
+    otherType = new TypeMask.nonNullSubtype(annotation.element, closedWorld);
   }
   if (isNullable) otherType = otherType.nullable();
   if (type == null) return otherType;
-  return type.intersection(otherType, compiler.closedWorld);
+  return type.intersection(otherType, closedWorld);
 }
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 2fa0448..56e8e89 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -337,18 +337,19 @@
       TRACE_METHOD == 'post' || TRACE_METHOD == 'console';
   MethodElement traceHelper;
 
-  TypeMask get stringType => compiler.commonMasks.stringType;
-  TypeMask get doubleType => compiler.commonMasks.doubleType;
-  TypeMask get intType => compiler.commonMasks.intType;
-  TypeMask get uint32Type => compiler.commonMasks.uint32Type;
-  TypeMask get uint31Type => compiler.commonMasks.uint31Type;
-  TypeMask get positiveIntType => compiler.commonMasks.positiveIntType;
-  TypeMask get numType => compiler.commonMasks.numType;
-  TypeMask get boolType => compiler.commonMasks.boolType;
-  TypeMask get dynamicType => compiler.commonMasks.dynamicType;
-  TypeMask get nullType => compiler.commonMasks.nullType;
+  TypeMask get stringType => compiler.closedWorld.commonMasks.stringType;
+  TypeMask get doubleType => compiler.closedWorld.commonMasks.doubleType;
+  TypeMask get intType => compiler.closedWorld.commonMasks.intType;
+  TypeMask get uint32Type => compiler.closedWorld.commonMasks.uint32Type;
+  TypeMask get uint31Type => compiler.closedWorld.commonMasks.uint31Type;
+  TypeMask get positiveIntType =>
+      compiler.closedWorld.commonMasks.positiveIntType;
+  TypeMask get numType => compiler.closedWorld.commonMasks.numType;
+  TypeMask get boolType => compiler.closedWorld.commonMasks.boolType;
+  TypeMask get dynamicType => compiler.closedWorld.commonMasks.dynamicType;
+  TypeMask get nullType => compiler.closedWorld.commonMasks.nullType;
   TypeMask get emptyType => const TypeMask.nonNullEmpty();
-  TypeMask get nonNullType => compiler.commonMasks.nonNullType;
+  TypeMask get nonNullType => compiler.closedWorld.commonMasks.nonNullType;
 
   TypeMask _indexablePrimitiveTypeCache;
   TypeMask get indexablePrimitiveType {
@@ -519,6 +520,9 @@
   /// True when we enqueue the loadLibrary code.
   bool isLoadLibraryFunctionResolved = false;
 
+  /// `true` if access to [BackendHelpers.invokeOnMethod] is supported.
+  bool hasInvokeOnSupport = false;
+
   /// List of constants from metadata.  If metadata must be preserved,
   /// these constants must be registered.
   final List<Dependency> metadataConstants = <Dependency>[];
@@ -1489,13 +1493,13 @@
   }
 
   bool classNeedsRti(ClassElement cls) {
-    if (compiler.enabledRuntimeType) return true;
+    if (compiler.resolverWorld.hasRuntimeTypeSupport) return true;
     return rti.classesNeedingRti.contains(cls.declaration);
   }
 
   bool classNeedsRtiField(ClassElement cls) {
     if (cls.rawType.typeArguments.isEmpty) return false;
-    if (compiler.enabledRuntimeType) return true;
+    if (compiler.resolverWorld.hasRuntimeTypeSupport) return true;
     return rti.classesNeedingRti.contains(cls.declaration);
   }
 
@@ -1512,7 +1516,7 @@
 
   bool methodNeedsRti(FunctionElement function) {
     return rti.methodsNeedingRti.contains(function) ||
-        compiler.enabledRuntimeType;
+        compiler.resolverWorld.hasRuntimeTypeSupport;
   }
 
   /// Enqueue [e] in [enqueuer].
@@ -1571,8 +1575,9 @@
 
   CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen;
 
-  CodegenEnqueuer createCodegenEnqueuer(Compiler compiler) {
-    return new CodegenEnqueuer(compiler, const TreeShakingEnqueuerStrategy());
+  CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) {
+    return new CodegenEnqueuer(
+        task, compiler, const TreeShakingEnqueuerStrategy());
   }
 
   WorldImpact codegen(CodegenWorkItem work) {
@@ -1646,11 +1651,11 @@
     return worldImpact;
   }
 
-  native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
+  native.NativeEnqueuer nativeResolutionEnqueuer() {
     return new native.NativeResolutionEnqueuer(compiler);
   }
 
-  native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) {
+  native.NativeEnqueuer nativeCodegenEnqueuer() {
     return new native.NativeCodegenEnqueuer(compiler, emitter);
   }
 
@@ -2342,11 +2347,13 @@
     //
     // Return early if any elements are added to avoid counting the elements as
     // due to mirrors.
-    enqueuer.applyImpact(customElementsAnalysis.flush(
-        forResolution: enqueuer.isResolutionQueue));
     enqueuer.applyImpact(
+        compiler.impactStrategy,
+        customElementsAnalysis.flush(
+            forResolution: enqueuer.isResolutionQueue));
+    enqueuer.applyImpact(compiler.impactStrategy,
         lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue));
-    enqueuer.applyImpact(
+    enqueuer.applyImpact(compiler.impactStrategy,
         typeVariableHandler.flush(forResolution: enqueuer.isResolutionQueue));
 
     if (!enqueuer.queueIsEmpty) return false;
@@ -2420,7 +2427,7 @@
         }
         metadataConstants.clear();
       }
-      enqueuer.applyImpact(impactBuilder.flush());
+      enqueuer.applyImpact(compiler.impactStrategy, impactBuilder.flush());
     }
     return true;
   }
@@ -2545,7 +2552,7 @@
           "@NoSideEffects() should always be combined with @NoInline.");
     }
     if (element == helpers.invokeOnMethod) {
-      compiler.enabledInvokeOn = true;
+      hasInvokeOnSupport = true;
     }
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart
index 420dfab..c169537 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -10,6 +10,7 @@
 import '../common/codegen.dart' show CodegenWorkItem;
 import '../common/registry.dart' show Registry;
 import '../common/names.dart' show Identifiers;
+import '../common/tasks.dart' show CompilerTask;
 import '../common/work.dart' show WorkItem;
 import '../common.dart';
 import '../compiler.dart' show Compiler;
@@ -39,7 +40,7 @@
 import '../universe/use.dart'
     show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
 import '../universe/world_impact.dart'
-    show ImpactUseCase, WorldImpact, WorldImpactVisitor;
+    show ImpactUseCase, ImpactStrategy, WorldImpact, WorldImpactVisitor;
 import '../util/util.dart' show Setlet;
 import '../world.dart';
 
@@ -59,15 +60,16 @@
       new CodegenWorldBuilderImpl(const TypeMaskStrategy());
 
   bool queueIsClosed = false;
-  EnqueueTask task;
-  native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
+  final CompilerTask task;
+  final native.NativeEnqueuer nativeEnqueuer;
 
   WorldImpactVisitor impactVisitor;
 
-  CodegenEnqueuer(Compiler compiler, this.strategy)
+  CodegenEnqueuer(this.task, Compiler compiler, this.strategy)
       : queue = new Queue<CodegenWorkItem>(),
         newlyEnqueuedElements = compiler.cacheStrategy.newSet(),
         newlySeenSelectors = compiler.cacheStrategy.newSet(),
+        nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(),
         this.name = 'codegen enqueuer',
         this._compiler = compiler {
     impactVisitor = new _EnqueuerImpactVisitor(this);
@@ -117,17 +119,16 @@
           element, "Codegen work list is closed. Trying to add $element");
     }
     queue.add(new CodegenWorkItem(_compiler, element));
-    if (options.dumpInfo) {
-      // TODO(sigmund): add other missing dependencies (internals, selectors
-      // enqueued after allocations), also enable only for the codegen enqueuer.
-      _compiler.dumpInfoTask
-          .registerDependency(_compiler.currentElement, element);
-    }
+    // TODO(sigmund): add other missing dependencies (internals, selectors
+    // enqueued after allocations).
+    _compiler.dumpInfoTask
+        .registerDependency(_compiler.currentElement, element);
   }
 
-  void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
-    _compiler.impactStrategy
-        .visitImpact(impactSource, worldImpact, impactVisitor, impactUse);
+  void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact,
+      {Element impactSource}) {
+    impactStrategy.visitImpact(
+        impactSource, worldImpact, impactVisitor, impactUse);
   }
 
   void registerInstantiatedType(InterfaceType type) {
@@ -417,7 +418,7 @@
   }
 
   void _registerIsCheck(DartType type) {
-    type = _universe.registerIsCheck(type, _compiler);
+    type = _universe.registerIsCheck(type, _compiler.resolution);
     // Even in checked mode, type annotations for return type and argument
     // types do not imply type checks, so there should never be a check
     // against the type variable of a typedef.
@@ -500,7 +501,7 @@
     log('Compiled ${generatedCode.length} methods.');
   }
 
-  void forgetElement(Element element) {
+  void forgetElement(Element element, Compiler compiler) {
     _forgetElement(element);
     generatedCode.remove(element);
     if (element is MemberElement) {
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index d3adc4b..23740b3 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -181,7 +181,7 @@
         InterfaceType interface = type;
         do {
           for (DartType argument in interface.typeArguments) {
-            universe.registerIsCheck(argument, compiler);
+            universe.registerIsCheck(argument, compiler.resolution);
           }
           interface = interface.element.supertype;
         } while (interface != null && !instantiatedTypes.contains(interface));
@@ -204,7 +204,7 @@
             InterfaceType instance = current.asInstanceOf(cls);
             if (instance == null) break;
             for (DartType argument in instance.typeArguments) {
-              universe.registerIsCheck(argument, compiler);
+              universe.registerIsCheck(argument, compiler.resolution);
             }
             current = current.element.supertype;
           } while (current != null && !instantiatedTypes.contains(current));
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index 06f8203..a5e7b4c 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -1152,7 +1152,7 @@
         .add(new jsAst.FunctionDeclaration(constructorName, constructorAst));
 
     String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
-    bool hasIsolateSupport = compiler.hasIsolateSupport;
+    bool hasIsolateSupport = compiler.resolverWorld.hasIsolateSupport;
     jsAst.Node fieldNamesArray;
     if (hasIsolateSupport) {
       fieldNamesArray =
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
index 51f06f8..0da9ca3 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
@@ -76,7 +76,7 @@
     // We could also generate the list of intercepted names at
     // runtime, by running through the subclasses of Interceptor
     // (which can easily be identified).
-    if (!compiler.enabledInvokeOn) return null;
+    if (!backend.hasInvokeOnSupport) return null;
 
     Iterable<jsAst.Name> invocationNames = interceptorInvocationNames.toList()
       ..sort();
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
index 56b1e29..feaee8e 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
@@ -103,7 +103,7 @@
     'staticsPropertyNameString': js.quoteName(namer.staticsPropertyName),
     'typeInformation': typeInformationAccess,
     'globalFunctions': globalFunctionsAccess,
-    'enabledInvokeOn': compiler.enabledInvokeOn,
+    'enabledInvokeOn': backend.hasInvokeOnSupport,
     'interceptedNames': interceptedNamesAccess,
     'interceptedNamesSet': emitter.generateInterceptedNamesSet(),
     'notInCspMode': !compiler.options.useContentSecurityPolicy,
@@ -138,7 +138,7 @@
         js.quoteName(namer.runtimeTypeName(compiler.coreClasses.objectClass)),
     'needsStructuredMemberInfo': emitter.needsStructuredMemberInfo,
     'usesMangledNames': compiler.commonElements.mirrorsLibrary != null ||
-        compiler.enabledFunctionApply,
+        compiler.hasFunctionApplySupport,
     'tearOffCode': buildTearOffCode(backend),
     'nativeInfoHandler': nativeInfoHandler,
     'operatorIsPrefix': js.string(namer.operatorIsPrefix),
diff --git a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
index b38e403..55824e8 100644
--- a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
@@ -28,7 +28,7 @@
   jsAst.Statement generateInvokeMain() {
     Element main = compiler.mainFunction;
     jsAst.Expression mainCallClosure = null;
-    if (compiler.hasIsolateSupport) {
+    if (compiler.resolverWorld.hasIsolateSupport) {
       Element isolateMain =
           helpers.isolateHelperLibrary.find(BackendHelpers.START_ROOT_ISOLATE);
       mainCallClosure = _buildIsolateSetupClosure(main, isolateMain);
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 9c2971b..3fac271 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -675,7 +675,7 @@
   }
 
   bool _methodCanBeApplied(FunctionElement method) {
-    return _compiler.enabledFunctionApply &&
+    return _compiler.hasFunctionApplySupport &&
         _compiler.closedWorld.getMightBePassedToApply(method);
   }
 
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 14fd016..abf9afa 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -3161,7 +3161,7 @@
     if (!Selectors.noSuchMethod_.signatureApplies(element)) {
       element = coreClasses.objectClass.lookupMember(Identifiers.noSuchMethod_);
     }
-    if (compiler.enabledInvokeOn && !element.enclosingClass.isObject) {
+    if (backend.hasInvokeOnSupport && !element.enclosingClass.isObject) {
       // Register the call as dynamic if [noSuchMethod] on the super
       // class is _not_ the default implementation from [Object], in
       // case the [noSuchMethod] implementation calls
@@ -5512,7 +5512,7 @@
 
   _inferredTypeOfNewList(ast.Node node) =>
       _resultOf(sourceElement).typeOfNewList(node) ??
-      compiler.commonMasks.dynamicType;
+      compiler.closedWorld.commonMasks.dynamicType;
 
   visitConditional(ast.Conditional node) {
     SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node);
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
index 35ee527..1ba818c 100644
--- a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -179,7 +179,7 @@
 
   TypeMask typeOfNewList(Element owner, ir.ListLiteral listLiteral) {
     return _resultOf(owner).typeOfNewList(getNode(listLiteral)) ??
-        _compiler.commonMasks.dynamicType;
+        _compiler.closedWorld.commonMasks.dynamicType;
   }
 
   TypeMask typeOfIterator(ir.ForInStatement forInStatement) {
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index 0df5b81..f145aff 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -15,45 +15,45 @@
   static TypeMask inferredReturnTypeForElement(
       Element element, Compiler compiler) {
     return compiler.globalInference.results.resultOf(element).returnType ??
-        compiler.commonMasks.dynamicType;
+        compiler.closedWorld.commonMasks.dynamicType;
   }
 
   static TypeMask inferredTypeForElement(Element element, Compiler compiler) {
     return compiler.globalInference.results.resultOf(element).type ??
-        compiler.commonMasks.dynamicType;
+        compiler.closedWorld.commonMasks.dynamicType;
   }
 
   static TypeMask inferredTypeForSelector(
       Selector selector, TypeMask mask, Compiler compiler) {
     return compiler.globalInference.results.typeOfSelector(selector, mask) ??
-        compiler.commonMasks.dynamicType;
+        compiler.closedWorld.commonMasks.dynamicType;
   }
 
   static TypeMask fromNativeBehavior(
       native.NativeBehavior nativeBehavior, Compiler compiler) {
+    ClosedWorld closedWorld = compiler.closedWorld;
+    CommonMasks commonMasks = closedWorld.commonMasks;
     var typesReturned = nativeBehavior.typesReturned;
-    if (typesReturned.isEmpty) return compiler.commonMasks.dynamicType;
+    if (typesReturned.isEmpty) return commonMasks.dynamicType;
 
-    ClosedWorld world = compiler.closedWorld;
-    CommonMasks commonMasks = compiler.commonMasks;
-    CoreClasses coreClasses = compiler.coreClasses;
+    CoreClasses coreClasses = closedWorld.coreClasses;
 
     // [type] is either an instance of [DartType] or special objects
     // like [native.SpecialType.JsObject].
     TypeMask fromNativeType(dynamic type) {
       if (type == native.SpecialType.JsObject) {
-        return new TypeMask.nonNullExact(coreClasses.objectClass, world);
+        return new TypeMask.nonNullExact(coreClasses.objectClass, closedWorld);
       }
 
       if (type.isVoid) return commonMasks.nullType;
       if (type.element == coreClasses.nullClass) return commonMasks.nullType;
       if (type.treatAsDynamic) return commonMasks.dynamicType;
-      return new TypeMask.nonNullSubtype(type.element, world);
+      return new TypeMask.nonNullSubtype(type.element, closedWorld);
     }
 
     TypeMask result = typesReturned
         .map(fromNativeType)
-        .reduce((t1, t2) => t1.union(t2, compiler.closedWorld));
+        .reduce((t1, t2) => t1.union(t2, closedWorld));
     assert(!result.isEmpty);
     return result;
   }
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index 8c3f6b7..60dbd90 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -22,7 +22,7 @@
   TypeMask visitConstructed(
       ConstructedConstantValue constant, Compiler compiler) {
     if (compiler.backend.isInterceptorClass(constant.type.element)) {
-      return compiler.commonMasks.nonNullType;
+      return compiler.closedWorld.commonMasks.nonNullType;
     }
     return new TypeMask.nonNullExact(
         constant.type.element, compiler.closedWorld);
@@ -38,13 +38,13 @@
     // We have to recognize double constants that are 'is int'.
     if (compiler.backend.constantSystem.isInt(constant)) {
       if (constant.isMinusZero) {
-        return compiler.commonMasks.uint31Type;
+        return compiler.closedWorld.commonMasks.uint31Type;
       } else {
         assert(constant.isPositiveInfinity || constant.isNegativeInfinity);
-        return compiler.commonMasks.intType;
+        return compiler.closedWorld.commonMasks.intType;
       }
     }
-    return compiler.commonMasks.doubleType;
+    return compiler.closedWorld.commonMasks.doubleType;
   }
 
   @override
@@ -55,9 +55,9 @@
       case SyntheticConstantKind.EMPTY_VALUE:
         return constant.payload;
       case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
-        return compiler.commonMasks.intType;
+        return compiler.closedWorld.commonMasks.intType;
       case SyntheticConstantKind.NAME:
-        return compiler.commonMasks.stringType;
+        return compiler.closedWorld.commonMasks.stringType;
       default:
         DiagnosticReporter reporter = compiler.reporter;
         reporter.internalError(
@@ -68,55 +68,56 @@
 
   @override
   TypeMask visitBool(BoolConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.boolType;
+    return compiler.closedWorld.commonMasks.boolType;
   }
 
   @override
   TypeMask visitFunction(FunctionConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.functionType;
+    return compiler.closedWorld.commonMasks.functionType;
   }
 
   @override
   TypeMask visitInt(IntConstantValue constant, Compiler compiler) {
-    if (constant.isUInt31()) return compiler.commonMasks.uint31Type;
-    if (constant.isUInt32()) return compiler.commonMasks.uint32Type;
-    if (constant.isPositive()) return compiler.commonMasks.positiveIntType;
-    return compiler.commonMasks.intType;
+    if (constant.isUInt31()) return compiler.closedWorld.commonMasks.uint31Type;
+    if (constant.isUInt32()) return compiler.closedWorld.commonMasks.uint32Type;
+    if (constant.isPositive())
+      return compiler.closedWorld.commonMasks.positiveIntType;
+    return compiler.closedWorld.commonMasks.intType;
   }
 
   @override
   TypeMask visitInterceptor(
       InterceptorConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.nonNullType;
+    return compiler.closedWorld.commonMasks.nonNullType;
   }
 
   @override
   TypeMask visitList(ListConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.constListType;
+    return compiler.closedWorld.commonMasks.constListType;
   }
 
   @override
   TypeMask visitMap(MapConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.constMapType;
+    return compiler.closedWorld.commonMasks.constMapType;
   }
 
   @override
   TypeMask visitNull(NullConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.nullType;
+    return compiler.closedWorld.commonMasks.nullType;
   }
 
   @override
   TypeMask visitNonConstant(NonConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.nullType;
+    return compiler.closedWorld.commonMasks.nullType;
   }
 
   @override
   TypeMask visitString(StringConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.stringType;
+    return compiler.closedWorld.commonMasks.stringType;
   }
 
   @override
   TypeMask visitType(TypeConstantValue constant, Compiler compiler) {
-    return compiler.commonMasks.typeType;
+    return compiler.closedWorld.commonMasks.typeType;
   }
 }
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index ce6cd55..b93b1e6 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -573,10 +573,9 @@
             : (isSubclass ? ClassQuery.SUBCLASS : ClassQuery.SUBTYPE));
   }
 
-  Element locateSingleElement(Selector selector, Compiler compiler) {
+  Element locateSingleElement(Selector selector, ClosedWorld closedWorld) {
     if (isEmptyOrNull) return null;
-    Iterable<Element> targets =
-        compiler.closedWorld.allFunctions.filter(selector, this);
+    Iterable<Element> targets = closedWorld.allFunctions.filter(selector, this);
     if (targets.length != 1) return null;
     Element result = targets.first;
     ClassElement enclosing = result.enclosingClass.declaration;
@@ -584,7 +583,6 @@
     // all classes in the receiver type [this]. It could be found only in a
     // subclass or in an inheritance-wise unrelated class in case of subtype
     // selectors.
-    ClosedWorld closedWorld = compiler.closedWorld;
     if (isSubtype) {
       // if (closedWorld.isUsedAsMixin(enclosing)) {
       if (closedWorld.everySubtypeIsSubclassOfOrMixinUseOf(base, enclosing)) {
diff --git a/pkg/compiler/lib/src/types/forwarding_type_mask.dart b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
index f285a59..775fee0 100644
--- a/pkg/compiler/lib/src/types/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
@@ -101,8 +101,8 @@
     return forwardTo.canHit(element, selector, closedWorld);
   }
 
-  Element locateSingleElement(Selector selector, Compiler compiler) {
-    return forwardTo.locateSingleElement(selector, compiler);
+  Element locateSingleElement(Selector selector, ClosedWorld closedWorld) {
+    return forwardTo.locateSingleElement(selector, closedWorld);
   }
 
   bool equalsDisregardNull(other) {
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index 8577558..5cbc4c0 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -33,11 +33,9 @@
 class CommonMasks {
   // TODO(sigmund): once we split out the backend common elements, depend
   // directly on those instead.
-  final Compiler compiler;
+  final ClosedWorld closedWorld;
 
-  CommonMasks(this.compiler);
-
-  ClosedWorld get closedWorld => compiler.closedWorld;
+  CommonMasks(this.closedWorld);
 
   BackendClasses get backendClasses => closedWorld.backendClasses;
 
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index a3ba10d..c91fac6 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -356,5 +356,5 @@
    * on this mask. Returns null if there is none.
    */
   // TODO(johnniwinther): Move this method to [World].
-  Element locateSingleElement(Selector selector, Compiler compiler);
+  Element locateSingleElement(Selector selector, ClosedWorld closedWorld);
 }
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 82bed6f..c078298 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -233,24 +233,26 @@
   final String name = 'Type inference';
 
   final Compiler compiler;
-  TypeGraphInferrer typesInferrer;
-  CommonMasks masks;
+
+  /// The [TypeGraphInferrer] used by the global type inference. This should by
+  /// accessed from outside this class for testing only.
+  TypeGraphInferrer typesInferrerInternal;
+
   GlobalTypeInferenceResults results;
 
   GlobalTypeInferenceTask(Compiler compiler)
-      : masks = new CommonMasks(compiler),
-        compiler = compiler,
-        super(compiler.measurer) {
-    typesInferrer = new TypeGraphInferrer(compiler, masks);
-  }
+      : compiler = compiler,
+        super(compiler.measurer);
 
   /// Runs the global type-inference algorithm once.
   void runGlobalTypeInference(Element mainElement) {
     measure(() {
-      typesInferrer.analyzeMain(mainElement);
-      typesInferrer.clear();
+      CommonMasks masks = compiler.closedWorld.commonMasks;
+      typesInferrerInternal ??= new TypeGraphInferrer(compiler, masks);
+      typesInferrerInternal.analyzeMain(mainElement);
+      typesInferrerInternal.clear();
       results = new GlobalTypeInferenceResults(
-          typesInferrer, compiler, masks, typesInferrer.inferrer.types);
+          typesInferrerInternal, compiler, masks, typesInferrerInternal.inferrer.types);
     });
   }
 }
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 49f9b44..eada935 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -334,10 +334,10 @@
     return disjointMasks.any((e) => e.canHit(element, selector, closedWorld));
   }
 
-  Element locateSingleElement(Selector selector, Compiler compiler) {
+  Element locateSingleElement(Selector selector, ClosedWorld closedWorld) {
     Element candidate;
     for (FlatTypeMask mask in disjointMasks) {
-      Element current = mask.locateSingleElement(selector, compiler);
+      Element current = mask.locateSingleElement(selector, closedWorld);
       if (current == null) {
         return null;
       } else if (candidate == null) {
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index 677ffc5..0fb0018 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -17,11 +17,9 @@
 // too and stricly they aren't functions. Maybe this needs a better
 // name -- something like ElementSet seems a bit too generic.
 class FunctionSet {
-  final Compiler compiler;
+  final ClosedWorld closedWorld;
   final Map<String, FunctionSetNode> nodes = new Map<String, FunctionSetNode>();
-  FunctionSet(this.compiler);
-
-  ClosedWorld get closedWorld => compiler.closedWorld;
+  FunctionSet(this.closedWorld);
 
   FunctionSetNode newNode(String name) => new FunctionSetNode(name);
 
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index 470adf3..fa4108a 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -6,14 +6,19 @@
 
 import 'dart:collection';
 
+import '../cache_strategy.dart';
 import '../common.dart';
+import '../common/backend_api.dart' show Backend;
+import '../common/resolution.dart' show Resolution;
 import '../compiler.dart' show Compiler;
+import '../core_types.dart' show CoreClasses;
 import '../dart_types.dart';
 import '../elements/elements.dart';
+import '../types/masks.dart' show CommonMasks;
 import '../universe/class_set.dart' show Instantiation;
 import '../util/enumset.dart';
 import '../util/util.dart';
-import '../world.dart' show World, ClosedWorld, OpenWorld;
+import '../world.dart' show World, ClosedWorld, OpenWorld, WorldImpl;
 import 'selector.dart' show Selector;
 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;
 
@@ -120,7 +125,7 @@
 
   /// Registers that [type] is checked in this universe. The unaliased type is
   /// returned.
-  DartType registerIsCheck(DartType type, Compiler compiler);
+  DartType registerIsCheck(DartType type, Resolution resolution);
 
   /// All directly instantiated types, that is, the types of the directly
   /// instantiated classes.
@@ -162,6 +167,19 @@
   /// Call [f] for all directly or abstractly instantiated classes.
   void forEachInstantiatedClass(
       f(ClassElement cls, EnumSet<Instantiation> instantiations));
+
+  /// `true` of `Object.runtimeType` is supported.
+  bool get hasRuntimeTypeSupport;
+
+  /// `true` of use of the `dart:isolate` library is supported.
+  bool get hasIsolateSupport;
+
+  /// `true` of `Function.apply` is supported.
+  bool get hasFunctionApplySupport;
+
+  /// The [OpenWorld] being created by this world builder.
+  // TODO(johnniwinther): Merge this with [ResolutionWorldBuilder].
+  OpenWorld get openWorld;
 }
 
 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder {
@@ -236,7 +254,18 @@
 
   final SelectorConstraintsStrategy selectorConstraintsStrategy;
 
-  ResolutionWorldBuilderImpl(this.selectorConstraintsStrategy);
+  bool hasRuntimeTypeSupport = false;
+  bool hasIsolateSupport = false;
+  bool hasFunctionApplySupport = false;
+
+  OpenWorld _openWorld;
+
+  ResolutionWorldBuilderImpl(Backend backend, CoreClasses coreClasses,
+      CacheStrategy cacheStrategy, this.selectorConstraintsStrategy) {
+    _openWorld = new WorldImpl(this, backend, coreClasses, cacheStrategy);
+  }
+
+  OpenWorld get openWorld => _openWorld;
 
   /// All directly instantiated classes, that is, classes with a generative
   /// constructor that has been called directly and not only through a
@@ -365,8 +394,8 @@
     return constraints.addReceiverConstraint(mask);
   }
 
-  DartType registerIsCheck(DartType type, Compiler compiler) {
-    type.computeUnaliased(compiler.resolution);
+  DartType registerIsCheck(DartType type, Resolution resolution) {
+    type.computeUnaliased(resolution);
     type = type.unaliased;
     // Even in checked mode, type annotations for return type and argument
     // types do not imply type checks, so there should never be a check
@@ -644,8 +673,7 @@
     _invokedSetters.forEach(f);
   }
 
-  DartType registerIsCheck(DartType type, Compiler compiler) {
-    type.computeUnaliased(compiler.resolution);
+  DartType registerIsCheck(DartType type, Resolution resolution) {
     type = type.unaliased;
     // Even in checked mode, type annotations for return type and argument
     // types do not imply type checks, so there should never be a check
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 014b16e..dd786a4 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -4,10 +4,10 @@
 
 library dart2js.world;
 
+import 'cache_strategy.dart';
 import 'closure.dart' show SynthesizedCallMethodElementX;
 import 'common/backend_api.dart' show BackendClasses;
 import 'common.dart';
-import 'compiler.dart' show Compiler;
 import 'core_types.dart' show CoreClasses;
 import 'dart_types.dart';
 import 'elements/elements.dart'
@@ -25,6 +25,7 @@
 import 'universe/function_set.dart' show FunctionSet;
 import 'universe/selector.dart' show Selector;
 import 'universe/side_effects.dart' show SideEffects;
+import 'universe/world_builder.dart' show ResolutionWorldBuilder;
 import 'util/enumset.dart';
 import 'util/util.dart' show Link;
 
@@ -46,6 +47,8 @@
   /// Access to core classes used in the Dart language.
   CoreClasses get coreClasses;
 
+  CommonMasks get commonMasks;
+
   /// Returns `true` if [cls] is either directly or indirectly instantiated.
   bool isInstantiated(ClassElement cls);
 
@@ -334,7 +337,7 @@
   void registerUsedElement(Element element);
   void registerTypedef(TypedefElement typedef);
 
-  ClosedWorld closeWorld();
+  ClosedWorld closeWorld(DiagnosticReporter reporter);
 
   /// Returns an iterable over all mixin applications that mixin [cls].
   Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls);
@@ -437,7 +440,7 @@
   /// Returns `true` if [cls] is implemented by an instantiated class.
   bool isImplemented(ClassElement cls) {
     assert(isClosed);
-    return _compiler.resolverWorld.isImplemented(cls);
+    return resolverWorld.isImplemented(cls);
   }
 
   /// Returns an iterable over the directly instantiated classes that extend
@@ -836,11 +839,9 @@
     }
   }
 
-  final Compiler _compiler;
+  final JavaScriptBackend _backend;
   BackendClasses get backendClasses => _backend.backendClasses;
-  JavaScriptBackend get _backend => _compiler.backend;
-  CommonMasks get commonMasks => _compiler.commonMasks;
-  final FunctionSet allFunctions;
+  FunctionSet _allFunctions;
   final Set<Element> functionsCalledInLoop = new Set<Element>();
   final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>();
 
@@ -871,20 +872,33 @@
 
   final Set<Element> alreadyPopulated;
 
+  CommonMasks _commonMasks;
+
+  final CoreClasses coreClasses;
+
+  final CacheStrategy cacheStrategy;
+
+  final ResolutionWorldBuilder resolverWorld;
+
   bool get isClosed => _closed;
 
   Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) {
     return _typesImplementedBySubclasses[cls.declaration];
   }
 
-  WorldImpl(Compiler compiler)
-      : allFunctions = new FunctionSet(compiler),
-        this._compiler = compiler,
-        alreadyPopulated = compiler.cacheStrategy.newSet();
+  WorldImpl(this.resolverWorld, this._backend, this.coreClasses,
+      CacheStrategy cacheStrategy)
+      : this.cacheStrategy = cacheStrategy,
+        alreadyPopulated = cacheStrategy.newSet() {
+    _allFunctions = new FunctionSet(this);
+  }
 
-  CoreClasses get coreClasses => _compiler.coreClasses;
+  FunctionSet get allFunctions => _allFunctions;
 
-  DiagnosticReporter get reporter => _compiler.reporter;
+  CommonMasks get commonMasks {
+    assert(isClosed);
+    return _commonMasks;
+  }
 
   /// Called to add [cls] to the set of known classes.
   ///
@@ -979,7 +993,7 @@
 
   void _updateClassHierarchyNodeForClass(ClassElement cls,
       {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) {
-    ClassHierarchyNode node = getClassHierarchyNode(cls);
+    ClassHierarchyNode node = _ensureClassHierarchyNode(cls);
     _updateSuperClassHierarchyNodeForClass(node);
     if (directlyInstantiated) {
       node.isDirectlyInstantiated = true;
@@ -989,13 +1003,12 @@
     }
   }
 
-  ClosedWorld closeWorld() {
+  ClosedWorld closeWorld(DiagnosticReporter reporter) {
     /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
     /// properties of the [ClassHierarchyNode] for [cls].
 
     void addSubtypes(ClassElement cls, EnumSet<Instantiation> instantiations) {
-      if (_compiler.options.hasIncrementalSupport &&
-          !alreadyPopulated.add(cls)) {
+      if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) {
         return;
       }
       assert(cls.isDeclaration);
@@ -1027,9 +1040,10 @@
     // classes: if the superclass of these classes require RTI, then
     // they also need RTI, so that a constructor passes the type
     // variables to the super constructor.
-    _compiler.resolverWorld.forEachInstantiatedClass(addSubtypes);
+    resolverWorld.forEachInstantiatedClass(addSubtypes);
 
     _closed = true;
+    _commonMasks = new CommonMasks(this);
     return this;
   }
 
@@ -1072,14 +1086,16 @@
   }
 
   Element locateSingleElement(Selector selector, TypeMask mask) {
+    assert(isClosed);
     mask ??= commonMasks.dynamicType;
-    return mask.locateSingleElement(selector, _compiler);
+    return mask.locateSingleElement(selector, this);
   }
 
   TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
+    assert(isClosed);
     bool canReachAll = true;
     if (mask != null) {
-      canReachAll = _compiler.enabledInvokeOn &&
+      canReachAll = _backend.hasInvokeOnSupport &&
           mask.needsNoSuchMethodHandling(selector, this);
     }
     return canReachAll ? commonMasks.dynamicType : mask;
@@ -1107,8 +1123,8 @@
       return true;
     }
     if (element.isInstanceMember) {
-      return !_compiler.resolverWorld.hasInvokedSetter(element, this) &&
-          !_compiler.resolverWorld.fieldSetters.contains(element);
+      return !resolverWorld.hasInvokedSetter(element, this) &&
+          !resolverWorld.fieldSetters.contains(element);
     }
     return false;
   }
diff --git a/pkg/dart2js_incremental/lib/caching_compiler.dart b/pkg/dart2js_incremental/lib/caching_compiler.dart
index 8c6357f..34f67c64 100644
--- a/pkg/dart2js_incremental/lib/caching_compiler.dart
+++ b/pkg/dart2js_incremental/lib/caching_compiler.dart
@@ -84,7 +84,7 @@
       return compiler.libraryLoader.loadLibrary(core).then((_) {
         // Likewise, always be prepared for runtimeType support.
         // TODO(johnniwinther): Add global switch to force RTI.
-        compiler.enabledRuntimeType = true;
+        compiler.resolverWorld.hasRuntimeTypeSupport = true;
         backend.registerRuntimeType(compiler.enqueuer.resolution);
         return compiler;
       });
diff --git a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
index 8a6e86b..f12fe38 100644
--- a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
@@ -211,7 +211,7 @@
     var expectedTypes = f(compiler);
     var signature = element.functionSignature;
     int index = 0;
-    var inferrer = compiler.globalInference.typesInferrer;
+    var inferrer = compiler.globalInference.typesInferrerInternal;
     signature.forEachParameter((Element element) {
       Expect.equals(expectedTypes[index++],
           simplify(inferrer.getTypeOfElement(element), compiler), test);
@@ -230,31 +230,37 @@
 }
 
 void test() {
-  runTest(TEST_1, (compiler) => [compiler.commonMasks.stringType]);
-  runTest(TEST_2, (compiler) => [compiler.commonMasks.uint31Type]);
-  runTest(TEST_3, (compiler) => [compiler.commonMasks.intType]);
-  runTest(TEST_4, (compiler) => [compiler.commonMasks.numType]);
-  runTest(TEST_5, (compiler) => [compiler.commonMasks.numType]);
-  runTest(TEST_6, (compiler) => [compiler.commonMasks.numType]);
+  runTest(TEST_1, (compiler) => [compiler.closedWorld.commonMasks.stringType]);
+  runTest(TEST_2, (compiler) => [compiler.closedWorld.commonMasks.uint31Type]);
+  runTest(TEST_3, (compiler) => [compiler.closedWorld.commonMasks.intType]);
+  runTest(TEST_4, (compiler) => [compiler.closedWorld.commonMasks.numType]);
+  runTest(TEST_5, (compiler) => [compiler.closedWorld.commonMasks.numType]);
+  runTest(TEST_6, (compiler) => [compiler.closedWorld.commonMasks.numType]);
   runTest(TEST_7a, (compiler) => [subclassOfInterceptor(compiler)]);
   runTest(
-      TEST_7b, (compiler) => [compiler.commonMasks.dynamicType.nonNullable()]);
+      TEST_7b,
+      (compiler) =>
+          [compiler.closedWorld.commonMasks.dynamicType.nonNullable()]);
 
   runTest(
       TEST_8,
       (compiler) => [
-            compiler.commonMasks.uint31Type,
+            compiler.closedWorld.commonMasks.uint31Type,
             subclassOfInterceptor(compiler),
-            compiler.commonMasks.dynamicType.nonNullable()
+            compiler.closedWorld.commonMasks.dynamicType.nonNullable()
           ]);
   runTest(
       TEST_9,
-      (compiler) =>
-          [compiler.commonMasks.uint31Type, compiler.commonMasks.uint31Type]);
+      (compiler) => [
+            compiler.closedWorld.commonMasks.uint31Type,
+            compiler.closedWorld.commonMasks.uint31Type
+          ]);
   runTest(
       TEST_10,
-      (compiler) =>
-          [compiler.commonMasks.uint31Type, compiler.commonMasks.uint31Type]);
+      (compiler) => [
+            compiler.closedWorld.commonMasks.uint31Type,
+            compiler.closedWorld.commonMasks.uint31Type
+          ]);
   runTest(
       TEST_11,
       (compiler) =>
@@ -262,35 +268,41 @@
 
   runTest(
       TEST_12,
-      (compiler) =>
-          [compiler.commonMasks.stringType, compiler.commonMasks.uint31Type]);
+      (compiler) => [
+            compiler.closedWorld.commonMasks.stringType,
+            compiler.closedWorld.commonMasks.uint31Type
+          ]);
 
-  runTest(TEST_13, (compiler) => [compiler.commonMasks.numType]);
+  runTest(TEST_13, (compiler) => [compiler.closedWorld.commonMasks.numType]);
 
   runTest(
       TEST_14,
-      (compiler) =>
-          [compiler.commonMasks.uint31Type, compiler.commonMasks.stringType]);
+      (compiler) => [
+            compiler.closedWorld.commonMasks.uint31Type,
+            compiler.closedWorld.commonMasks.stringType
+          ]);
 
   runTest(
       TEST_15,
-      (compiler) =>
-          [compiler.commonMasks.stringType, compiler.commonMasks.boolType]);
+      (compiler) => [
+            compiler.closedWorld.commonMasks.stringType,
+            compiler.closedWorld.commonMasks.boolType
+          ]);
 
   runTest(
       TEST_16,
       (compiler) => [
-            compiler.commonMasks.uint31Type,
-            compiler.commonMasks.uint31Type,
-            compiler.commonMasks.stringType
+            compiler.closedWorld.commonMasks.uint31Type,
+            compiler.closedWorld.commonMasks.uint31Type,
+            compiler.closedWorld.commonMasks.stringType
           ]);
 
   runTest(
       TEST_17,
       (compiler) => [
-            compiler.commonMasks.uint31Type,
-            compiler.commonMasks.boolType,
-            compiler.commonMasks.doubleType
+            compiler.closedWorld.commonMasks.uint31Type,
+            compiler.closedWorld.commonMasks.boolType,
+            compiler.closedWorld.commonMasks.doubleType
           ]);
 
   runTest(
diff --git a/tests/compiler/dart2js/closure_tracer_test.dart b/tests/compiler/dart2js/closure_tracer_test.dart
index 110ccd4..f76bea1 100644
--- a/tests/compiler/dart2js/closure_tracer_test.dart
+++ b/tests/compiler/dart2js/closure_tracer_test.dart
@@ -154,8 +154,8 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkType(String name, type) {
           var element = findElement(compiler, name);
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index a81af12..eaa26df 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -74,7 +74,7 @@
     compiler.phase = Compiler.PHASE_RESOLVING;
     compiler.backend.enqueueHelpers(compiler.enqueuer.resolution);
     compiler.processQueue(compiler.enqueuer.resolution, element);
-    compiler.openWorld.closeWorld();
+    compiler.openWorld.closeWorld(compiler.reporter);
     compiler.backend.onResolutionComplete();
     ResolutionWorkItem resolutionWork = new ResolutionWorkItem(element);
     resolutionWork.run(compiler, compiler.enqueuer.resolution);
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 29317ae..ce5b556 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -41,23 +41,23 @@
 void testBasicTypes() {
   checkPrintType('true', (compiler, type) {
     if (type.isForwarding) type = type.forwardTo;
-    Expect.identical(compiler.commonMasks.boolType, type);
+    Expect.identical(compiler.closedWorld.commonMasks.boolType, type);
   });
   checkPrintType('1.5', (compiler, type) {
-    Expect.identical(compiler.commonMasks.doubleType, type);
+    Expect.identical(compiler.closedWorld.commonMasks.doubleType, type);
   });
   checkPrintType('1', (compiler, type) {
-    Expect.identical(compiler.commonMasks.uint31Type, type);
+    Expect.identical(compiler.closedWorld.commonMasks.uint31Type, type);
   });
   checkPrintType('[]', (compiler, type) {
     if (type.isForwarding) type = type.forwardTo;
-    Expect.identical(compiler.commonMasks.growableListType, type);
+    Expect.identical(compiler.closedWorld.commonMasks.growableListType, type);
   });
   checkPrintType('null', (compiler, type) {
-    Expect.identical(compiler.commonMasks.nullType, type);
+    Expect.identical(compiler.closedWorld.commonMasks.nullType, type);
   });
   checkPrintType('"foo"', (compiler, type) {
-    Expect.isTrue(compiler.commonMasks.stringType
+    Expect.isTrue(compiler.closedWorld.commonMasks.stringType
         .containsOnlyString(compiler.closedWorld));
   });
 }
@@ -68,7 +68,7 @@
     var firstParameter = fiskElement.functionSignature.requiredParameters[0];
     var secondParameter = fiskElement.functionSignature.optionalParameters[0];
     var thirdParameter = fiskElement.functionSignature.optionalParameters[1];
-    var commonMasks = compiler.commonMasks;
+    var commonMasks = compiler.closedWorld.commonMasks;
     Expect.identical(commonMasks.uint31Type, _typeOf(compiler, firstParameter));
     Expect.identical(commonMasks.nullType, _typeOf(compiler, secondParameter));
     Expect.identical(commonMasks.nullType, _typeOf(compiler, thirdParameter));
diff --git a/tests/compiler/dart2js/container_mask_equal_test.dart b/tests/compiler/dart2js/container_mask_equal_test.dart
index 21836b7..9f67840 100644
--- a/tests/compiler/dart2js/container_mask_equal_test.dart
+++ b/tests/compiler/dart2js/container_mask_equal_test.dart
@@ -30,7 +30,7 @@
   asyncTest(() async {
     var result = await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
     var compiler = result.compiler;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
     var element = compiler.mainApp.find('a');
     var mask1 = typesInferrer.getReturnTypeOfElement(element);
diff --git a/tests/compiler/dart2js/dictionary_types_test.dart b/tests/compiler/dart2js/dictionary_types_test.dart
index 0a169d6..15a4e57 100644
--- a/tests/compiler/dart2js/dictionary_types_test.dart
+++ b/tests/compiler/dart2js/dictionary_types_test.dart
@@ -141,8 +141,8 @@
         compiler.stopAfterTypeInference = !createCode;
       });
   var compiler = result.compiler;
-  var commonMasks = compiler.commonMasks;
-  var typesInferrer = compiler.globalInference.typesInferrer;
+  var commonMasks = compiler.closedWorld.commonMasks;
+  var typesInferrer = compiler.globalInference.typesInferrerInternal;
   getType(String name) {
     var element = findElement(compiler, name);
     return typesInferrer.getTypeOfElement(element);
diff --git a/tests/compiler/dart2js/expect_annotations_test.dart b/tests/compiler/dart2js/expect_annotations_test.dart
index 10ee78c..c9c47e0 100644
--- a/tests/compiler/dart2js/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/expect_annotations_test.dart
@@ -92,17 +92,18 @@
           expectAssumeDynamic,
           backend.annotations.assumeDynamic(method),
           "Unexpected annotation of @AssumeDynamic on '$method'.");
-      TypesInferrer inferrer = compiler.globalInference.typesInferrer;
+      TypesInferrer inferrer = compiler.globalInference.typesInferrerInternal;
       if (expectTrustTypeAnnotations && expectedParameterType != null) {
         testTypeMatch(
             method, expectedParameterType, expectedReturnType, inferrer);
       } else if (expectAssumeDynamic) {
-        testTypeMatch(method, compiler.commonMasks.dynamicType, null, inferrer);
+        testTypeMatch(method, compiler.closedWorld.commonMasks.dynamicType,
+            null, inferrer);
       }
     }
 
-    TypeMask jsStringType = compiler.commonMasks.stringType;
-    TypeMask jsIntType = compiler.commonMasks.intType;
+    TypeMask jsStringType = compiler.closedWorld.commonMasks.stringType;
+    TypeMask jsIntType = compiler.closedWorld.commonMasks.intType;
     TypeMask coreStringType = new TypeMask.subtype(
         compiler.coreClasses.stringClass, compiler.closedWorld);
 
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 03d7de3..0e930a0 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -5,6 +5,8 @@
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/types/types.dart' show TypeMask;
+import 'package:compiler/src/types/masks.dart' show CommonMasks;
+import 'package:compiler/src/compiler.dart' show Compiler;
 
 import 'compiler_helper.dart';
 import 'type_mask_test_helper.dart';
@@ -469,11 +471,14 @@
   }
 """;
 
-void doTest(String test, bool disableInlining, Map<String, Function> fields) {
-  fields.forEach((String name, Function f) {
+typedef TypeMask TestCallback(Compiler compiler, CommonMasks masks);
+
+void doTest(
+    String test, bool disableInlining, Map<String, TestCallback> fields) {
+  fields.forEach((String name, TestCallback f) {
     compileAndFind(test, 'A', name, disableInlining, (compiler, field) {
-      TypeMask type = f(compiler.commonMasks);
-      var inferrer = compiler.globalInference.typesInferrer;
+      TypeMask type = f(compiler, compiler.closedWorld.commonMasks);
+      var inferrer = compiler.globalInference.typesInferrerInternal;
       TypeMask inferredType =
           simplify(inferrer.getTypeOfElement(field), inferrer.compiler);
       Expect.equals(type, inferredType, test);
@@ -481,92 +486,120 @@
   });
 }
 
-void runTest(String test, Map<String, Function> fields) {
+void runTest(String test, Map<String, TestCallback> fields) {
   doTest(test, false, fields);
   doTest(test, true, fields);
 }
 
 void test() {
-  subclassOfInterceptor(types) =>
-      findTypeMask(types.compiler, 'Interceptor', 'nonNullSubclass');
+  TypeMask subclassOfInterceptor(Compiler compiler, CommonMasks types) =>
+      findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
 
-  runTest(TEST_1, {'f': (types) => types.nullType});
-  runTest(TEST_2,
-      {'f1': (types) => types.nullType, 'f2': (types) => types.uint31Type});
-  runTest(TEST_3, {
-    'f1': (types) => types.uint31Type,
-    'f2': (types) => types.uint31Type.nullable()
+  runTest(
+      TEST_1, <String, TestCallback>{'f': (compiler, types) => types.nullType});
+  runTest(TEST_2, <String, TestCallback>{
+    'f1': (compiler, types) => types.nullType,
+    'f2': (compiler, types) => types.uint31Type
   });
-  runTest(TEST_4, {
+  runTest(TEST_3, <String, TestCallback>{
+    'f1': (compiler, types) => types.uint31Type,
+    'f2': (compiler, types) => types.uint31Type.nullable()
+  });
+  runTest(TEST_4, <String, TestCallback>{
     'f1': subclassOfInterceptor,
-    'f2': (types) => types.stringType.nullable()
+    'f2': (compiler, types) => types.stringType.nullable()
   });
 
   // TODO(ngeoffray): We should try to infer that the initialization
   // code at the declaration site of the fields does not matter.
-  runTest(TEST_5, {'f1': subclassOfInterceptor, 'f2': subclassOfInterceptor});
-  runTest(TEST_6, {'f1': subclassOfInterceptor, 'f2': subclassOfInterceptor});
-  runTest(TEST_7, {'f1': subclassOfInterceptor, 'f2': subclassOfInterceptor});
+  runTest(TEST_5, <String, TestCallback>{
+    'f1': subclassOfInterceptor,
+    'f2': subclassOfInterceptor
+  });
+  runTest(TEST_6, <String, TestCallback>{
+    'f1': subclassOfInterceptor,
+    'f2': subclassOfInterceptor
+  });
+  runTest(TEST_7, <String, TestCallback>{
+    'f1': subclassOfInterceptor,
+    'f2': subclassOfInterceptor
+  });
 
-  runTest(TEST_8, {'f': (types) => types.stringType.nullable()});
-  runTest(TEST_9, {'f': (types) => types.stringType.nullable()});
-  runTest(TEST_10, {'f': (types) => types.uint31Type});
-  runTest(TEST_11, {'fs': (types) => types.uint31Type});
+  runTest(TEST_8, <String, TestCallback>{
+    'f': (compiler, types) => types.stringType.nullable()
+  });
+  runTest(TEST_9, <String, TestCallback>{
+    'f': (compiler, types) => types.stringType.nullable()
+  });
+  runTest(TEST_10,
+      <String, TestCallback>{'f': (compiler, types) => types.uint31Type});
+  runTest(TEST_11,
+      <String, TestCallback>{'fs': (compiler, types) => types.uint31Type});
 
   // TODO(ngeoffray): We should try to infer that the initialization
   // code at the declaration site of the fields does not matter.
-  runTest(TEST_12, {'fs': subclassOfInterceptor});
+  runTest(TEST_12, <String, TestCallback>{'fs': subclassOfInterceptor});
 
-  runTest(TEST_13, {'fs': (types) => types.uint31Type});
-  runTest(TEST_14, {'f': (types) => types.uint31Type});
-  runTest(TEST_15, {
-    'f': (types) {
-      ClassElement cls = types.compiler.backend.helpers.jsIndexableClass;
-      return new TypeMask.nonNullSubtype(cls, types.compiler.closedWorld);
+  runTest(TEST_13,
+      <String, TestCallback>{'fs': (compiler, types) => types.uint31Type});
+  runTest(TEST_14,
+      <String, TestCallback>{'f': (compiler, types) => types.uint31Type});
+  runTest(TEST_15, <String, TestCallback>{
+    'f': (compiler, types) {
+      ClassElement cls = compiler.backend.helpers.jsIndexableClass;
+      return new TypeMask.nonNullSubtype(cls, compiler.closedWorld);
     }
   });
-  runTest(TEST_16, {'f': subclassOfInterceptor});
-  runTest(TEST_17, {'f': (types) => types.uint31Type.nullable()});
-  runTest(TEST_18, {
-    'f1': (types) => types.uint31Type,
-    'f2': (types) => types.stringType,
-    'f3': (types) => types.dynamicType
+  runTest(TEST_16, <String, TestCallback>{'f': subclassOfInterceptor});
+  runTest(TEST_17, <String, TestCallback>{
+    'f': (compiler, types) => types.uint31Type.nullable()
   });
-  runTest(TEST_19, {
-    'f1': (types) => types.uint31Type,
-    'f2': (types) => types.stringType,
-    'f3': (types) => types.dynamicType
+  runTest(TEST_18, <String, TestCallback>{
+    'f1': (compiler, types) => types.uint31Type,
+    'f2': (compiler, types) => types.stringType,
+    'f3': (compiler, types) => types.dynamicType
   });
-  runTest(TEST_20, {'f': (types) => types.uint31Type.nullable()});
-  runTest(TEST_21, {'f': (types) => types.uint31Type.nullable()});
-
-  runTest(TEST_22, {
-    'f1': (types) => types.uint31Type,
-    'f2': (types) => types.uint31Type,
-    'f3': (types) => types.stringType.nullable()
+  runTest(TEST_19, <String, TestCallback>{
+    'f1': (compiler, types) => types.uint31Type,
+    'f2': (compiler, types) => types.stringType,
+    'f3': (compiler, types) => types.dynamicType
+  });
+  runTest(TEST_20, <String, TestCallback>{
+    'f': (compiler, types) => types.uint31Type.nullable()
+  });
+  runTest(TEST_21, <String, TestCallback>{
+    'f': (compiler, types) => types.uint31Type.nullable()
   });
 
-  runTest(TEST_23, {
-    'f1': (types) => types.uint31Type.nullable(),
-    'f2': (types) => types.uint31Type.nullable(),
-    'f3': (types) => types.uint31Type.nullable(),
-    'f4': (types) => types.uint31Type.nullable()
+  runTest(TEST_22, <String, TestCallback>{
+    'f1': (compiler, types) => types.uint31Type,
+    'f2': (compiler, types) => types.uint31Type,
+    'f3': (compiler, types) => types.stringType.nullable()
   });
 
-  runTest(TEST_24, {
-    'f1': (types) => types.positiveIntType,
-    'f2': (types) => types.positiveIntType,
-    'f3': (types) => types.uint31Type,
-    'f4': (types) => types.uint31Type,
-    'f5': (types) => types.numType.nullable(),
-    'f6': (types) => types.stringType.nullable()
+  runTest(TEST_23, <String, TestCallback>{
+    'f1': (compiler, types) => types.uint31Type.nullable(),
+    'f2': (compiler, types) => types.uint31Type.nullable(),
+    'f3': (compiler, types) => types.uint31Type.nullable(),
+    'f4': (compiler, types) => types.uint31Type.nullable()
   });
 
-  runTest(TEST_25, {'f1': (types) => types.uint31Type});
-  runTest(TEST_26, {'f1': (types) => types.positiveIntType});
-  runTest(TEST_27, {
-    'f1': (types) => types.uint31Type,
-    'f2': (types) => types.uint31Type.nullable()
+  runTest(TEST_24, <String, TestCallback>{
+    'f1': (compiler, types) => types.positiveIntType,
+    'f2': (compiler, types) => types.positiveIntType,
+    'f3': (compiler, types) => types.uint31Type,
+    'f4': (compiler, types) => types.uint31Type,
+    'f5': (compiler, types) => types.numType.nullable(),
+    'f6': (compiler, types) => types.stringType.nullable()
+  });
+
+  runTest(TEST_25,
+      <String, TestCallback>{'f1': (compiler, types) => types.uint31Type});
+  runTest(TEST_26,
+      <String, TestCallback>{'f1': (compiler, types) => types.positiveIntType});
+  runTest(TEST_27, <String, TestCallback>{
+    'f1': (compiler, types) => types.uint31Type,
+    'f2': (compiler, types) => types.uint31Type.nullable()
   });
 }
 
diff --git a/tests/compiler/dart2js/issue13354_test.dart b/tests/compiler/dart2js/issue13354_test.dart
index 32826cc..ecf8dba 100644
--- a/tests/compiler/dart2js/issue13354_test.dart
+++ b/tests/compiler/dart2js/issue13354_test.dart
@@ -29,8 +29,8 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturn(String name, type) {
           var element = findElement(compiler, name);
diff --git a/tests/compiler/dart2js/list_tracer2_test.dart b/tests/compiler/dart2js/list_tracer2_test.dart
index d03ab91..c0a5166 100644
--- a/tests/compiler/dart2js/list_tracer2_test.dart
+++ b/tests/compiler/dart2js/list_tracer2_test.dart
@@ -24,7 +24,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkType(String name, type) {
           var element = findElement(compiler, name);
@@ -32,6 +32,6 @@
           Expect.equals(type, simplify(mask.elementType, compiler), name);
         }
 
-        checkType('myList', compiler.commonMasks.uint31Type);
+        checkType('myList', compiler.closedWorld.commonMasks.uint31Type);
       }));
 }
diff --git a/tests/compiler/dart2js/list_tracer3_test.dart b/tests/compiler/dart2js/list_tracer3_test.dart
index cb1b936..1e61858 100644
--- a/tests/compiler/dart2js/list_tracer3_test.dart
+++ b/tests/compiler/dart2js/list_tracer3_test.dart
@@ -26,7 +26,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkType(String name, type) {
           var element = findElement(compiler, name);
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index fe1bd17..c407ce8 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -198,8 +198,8 @@
   var compiler = compilerFor(generateTest(allocation), uri,
       expectedErrors: 0, expectedWarnings: 1);
   asyncTest(() => compiler.run(uri).then((_) {
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkType(String name, type) {
           var element = findElement(compiler, name);
diff --git a/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart b/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart
index b0dc4fd..ee15963 100644
--- a/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart
+++ b/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart
@@ -29,7 +29,7 @@
   asyncTest(() async {
     CompilationResult result = await runCompiler(memorySourceFiles: TEST);
     Compiler compiler = result.compiler;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
     checkType(String name, type, length) {
       var element = findElement(compiler, name);
@@ -40,7 +40,7 @@
       Expect.equals(container.length, length);
     }
 
-    checkType('myList', compiler.commonMasks.numType, 42);
-    checkType('myOtherList', compiler.commonMasks.uint31Type, 32);
+    checkType('myList', compiler.closedWorld.commonMasks.numType, 42);
+    checkType('myOtherList', compiler.closedWorld.commonMasks.uint31Type, 32);
   });
 }
diff --git a/tests/compiler/dart2js/map_tracer_const_test.dart b/tests/compiler/dart2js/map_tracer_const_test.dart
index ee20f9f..69d9554 100644
--- a/tests/compiler/dart2js/map_tracer_const_test.dart
+++ b/tests/compiler/dart2js/map_tracer_const_test.dart
@@ -33,8 +33,8 @@
   var compiler = compilerFor(TEST, uri, expectedErrors: 0, expectedWarnings: 0);
   compiler.stopAfterTypeInference = true;
   asyncTest(() => compiler.run(uri).then((_) {
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
         var element = findElement(compiler, 'closure');
         var mask = typesInferrer.getReturnTypeOfElement(element);
         Expect.equals(commonMasks.numType, simplify(mask, compiler));
diff --git a/tests/compiler/dart2js/map_tracer_keys_test.dart b/tests/compiler/dart2js/map_tracer_keys_test.dart
index 4516fb3..4394879 100644
--- a/tests/compiler/dart2js/map_tracer_keys_test.dart
+++ b/tests/compiler/dart2js/map_tracer_keys_test.dart
@@ -57,8 +57,8 @@
   var compiler = compilerFor(generateTest(key, value, initial), uri,
       expectedErrors: 0, expectedWarnings: 0);
   asyncTest(() => compiler.run(uri).then((_) {
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
         var aDoubleType =
             typesInferrer.getTypeOfElement(findElement(compiler, 'aDouble'));
         var aListType =
diff --git a/tests/compiler/dart2js/map_tracer_test.dart b/tests/compiler/dart2js/map_tracer_test.dart
index 4399798..571450c 100644
--- a/tests/compiler/dart2js/map_tracer_test.dart
+++ b/tests/compiler/dart2js/map_tracer_test.dart
@@ -211,11 +211,11 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(generateTest(allocation), uri,
       expectedErrors: 0, expectedWarnings: 1);
-  var closedWorld = compiler.openWorld.closeWorld();
+  var closedWorld = compiler.openWorld.closeWorld(compiler.reporter);
   asyncTest(() => compiler.run(uri).then((_) {
         var keyType, valueType;
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
         var emptyType = new TypeMask.nonNullEmpty();
         var aKeyType =
             typesInferrer.getTypeOfElement(findElement(compiler, 'aKey'));
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
index 4f109a4..3d5ce6d 100644
--- a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
@@ -28,8 +28,8 @@
     var result = await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
     var compiler = result.compiler;
     var element = findElement(compiler, 'field');
-    var commonMasks = compiler.commonMasks;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var commonMasks = compiler.closedWorld.commonMasks;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     Expect.equals(commonMasks.uint31Type,
         simplify(typesInferrer.getTypeOfElement(element), compiler), 'field');
   });
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
index 31b555d..78ea487 100644
--- a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
@@ -28,8 +28,8 @@
     var result = await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
     var compiler = result.compiler;
     var element = findElement(compiler, 'field');
-    var commonMasks = compiler.commonMasks;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var commonMasks = compiler.closedWorld.commonMasks;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     Expect.equals(commonMasks.uint31Type,
         simplify(typesInferrer.getTypeOfElement(element), compiler), 'field');
   });
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index f12c2b2..f7b34dd 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -920,7 +920,7 @@
       """,
       runCompiler: true,
       analyzeOnly: true);
-  ClosedWorld world = compiler.openWorld.closeWorld();
+  ClosedWorld world = compiler.openWorld.closeWorld(compiler.reporter);
 
   ClassElement cls = ensure(
       compiler, "A", compiler.commonElements.coreLibrary.find,
diff --git a/tests/compiler/dart2js/related_types.dart b/tests/compiler/dart2js/related_types.dart
index 09b28ea..a2516f7 100644
--- a/tests/compiler/dart2js/related_types.dart
+++ b/tests/compiler/dart2js/related_types.dart
@@ -35,7 +35,7 @@
 
 /// Check all loaded libraries in [compiler] for unrelated types.
 void checkRelatedTypes(Compiler compiler) {
-  compiler.openWorld.closeWorld();
+  compiler.openWorld.closeWorld(compiler.reporter);
   for (LibraryElement library in compiler.libraryLoader.libraries) {
     checkLibraryElement(compiler, library);
   }
diff --git a/tests/compiler/dart2js/related_types_test.dart b/tests/compiler/dart2js/related_types_test.dart
index 38449bc..6711fb2 100644
--- a/tests/compiler/dart2js/related_types_test.dart
+++ b/tests/compiler/dart2js/related_types_test.dart
@@ -267,7 +267,7 @@
     Expect.isFalse(
         collector.hasRegularMessages, "Unexpected analysis messages.");
     Compiler compiler = result.compiler;
-    compiler.openWorld.closeWorld();
+    compiler.openWorld.closeWorld(compiler.reporter);
 
     void checkMember(MemberElement member) {
       if (!member.name.startsWith('test_')) return;
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
index cd6ecb2..7fab60f 100644
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ b/tests/compiler/dart2js/serialization/helper.dart
@@ -11,6 +11,7 @@
 import 'package:compiler/src/common/names.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/filenames.dart';
 
 import '../memory_compiler.dart';
 import 'test_data.dart';
@@ -71,6 +72,13 @@
         saveSerializedData: saveSerializedData);
   }
 
+  Uri get uri {
+    if (filename != null) {
+      return Uri.base.resolve(nativeToUriPath(filename));
+    }
+    return null;
+  }
+
   Future forEachTest(SerializedData serializedData, List<Test> tests,
       TestFunction testFunction) async {
     Uri entryPoint = Uri.parse('memory:main.dart');
diff --git a/tests/compiler/dart2js/serialization/model_test_helper.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart
index 9a4484a..8beea7d 100644
--- a/tests/compiler/dart2js/serialization/model_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/model_test_helper.dart
@@ -13,13 +13,16 @@
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/constants/values.dart';
 import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/dart_types.dart';
 import 'package:compiler/src/deferred_load.dart';
 import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/enqueue.dart';
 import 'package:compiler/src/filenames.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
 import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/tree/nodes.dart';
 import 'package:compiler/src/universe/class_set.dart';
+import 'package:compiler/src/world.dart' show ClosedWorld;
 import '../memory_compiler.dart';
 import 'helper.dart';
 import 'test_data.dart';
@@ -36,8 +39,8 @@
     Arguments arguments = new Arguments.from(args);
     SerializedData serializedData =
         await serializeDartCore(arguments: arguments);
-    if (arguments.filename != null) {
-      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
+    if (arguments.uri != null) {
+      Uri entryPoint = arguments.uri;
       SerializationResult result =
           await measure('${entryPoint}', 'serialize', () {
         return serialize(entryPoint,
@@ -90,97 +93,121 @@
 
   return measure(title, 'check models', () async {
     checkAllImpacts(compilerNormal, compilerDeserialized, verbose: verbose);
-
-    checkSets(
-        compilerNormal.resolverWorld.directlyInstantiatedClasses,
-        compilerDeserialized.resolverWorld.directlyInstantiatedClasses,
-        "Directly instantiated classes mismatch",
-        areElementsEquivalent,
+    checkResolutionEnqueuers(compilerNormal.enqueuer.resolution,
+        compilerDeserialized.enqueuer.resolution,
         verbose: verbose);
-
-    checkSets(
-        compilerNormal.resolverWorld.instantiatedTypes,
-        compilerDeserialized.resolverWorld.instantiatedTypes,
-        "Instantiated types mismatch",
-        areTypesEquivalent,
+    checkClosedWorlds(
+        compilerNormal.closedWorld, compilerDeserialized.closedWorld,
         verbose: verbose);
+    checkBackendInfo(compilerNormal, compilerDeserialized, verbose: verbose);
+  });
+}
 
-    checkSets(
-        compilerNormal.resolverWorld.isChecks,
-        compilerDeserialized.resolverWorld.isChecks,
-        "Is-check mismatch",
-        areTypesEquivalent,
-        verbose: verbose);
+void checkResolutionEnqueuers(
+    ResolutionEnqueuer enqueuer1, ResolutionEnqueuer enqueuer2,
+    {bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
+    bool elementFilter(Element element),
+    bool verbose: false}) {
+  Iterable<Element> processedElements1 = enqueuer1.processedElements;
+  Iterable<Element> processedElements2 = enqueuer2.processedElements;
+  if (elementFilter != null) {
+    processedElements1 = processedElements1.where(elementFilter);
+    processedElements2 = processedElements2.where(elementFilter);
+  }
 
-    checkSets(
-        compilerNormal.enqueuer.resolution.processedElements,
-        compilerDeserialized.enqueuer.resolution.processedElements,
-        "Processed element mismatch",
-        areElementsEquivalent, onSameElement: (a, b) {
-      checkElements(compilerNormal, compilerDeserialized, a, b,
-          verbose: verbose);
-    }, verbose: verbose);
+  checkSets(processedElements1, processedElements2,
+      "Processed element mismatch", areElementsEquivalent,
+      verbose: verbose);
 
-    checkClassHierarchyNodes(
-        compilerNormal,
-        compilerDeserialized,
-        compilerNormal.closedWorld
-            .getClassHierarchyNode(compilerNormal.coreClasses.objectClass),
-        compilerDeserialized.closedWorld.getClassHierarchyNode(
-            compilerDeserialized.coreClasses.objectClass),
-        verbose: verbose);
+  checkSets(
+      enqueuer1.universe.directlyInstantiatedClasses,
+      enqueuer2.universe.directlyInstantiatedClasses,
+      "Directly instantiated classes mismatch",
+      areElementsEquivalent,
+      verbose: verbose);
 
-    Expect.equals(
-        compilerNormal.enabledInvokeOn,
-        compilerDeserialized.enabledInvokeOn,
-        "Compiler.enabledInvokeOn mismatch");
-    Expect.equals(
-        compilerNormal.enabledFunctionApply,
-        compilerDeserialized.enabledFunctionApply,
-        "Compiler.enabledFunctionApply mismatch");
-    Expect.equals(
-        compilerNormal.enabledRuntimeType,
-        compilerDeserialized.enabledRuntimeType,
-        "Compiler.enabledRuntimeType mismatch");
-    Expect.equals(
-        compilerNormal.hasIsolateSupport,
-        compilerDeserialized.hasIsolateSupport,
-        "Compiler.hasIsolateSupport mismatch");
-    Expect.equals(
-        compilerNormal.deferredLoadTask.isProgramSplit,
-        compilerDeserialized.deferredLoadTask.isProgramSplit,
-        "isProgramSplit mismatch");
+  checkSets(
+      enqueuer1.universe.instantiatedTypes,
+      enqueuer2.universe.instantiatedTypes,
+      "Instantiated types mismatch",
+      typeEquivalence,
+      verbose: verbose);
 
-    Map<ConstantValue, OutputUnit> constants1 =
-        compilerNormal.deferredLoadTask.outputUnitForConstantsForTesting;
-    Map<ConstantValue, OutputUnit> constants2 =
-        compilerDeserialized.deferredLoadTask.outputUnitForConstantsForTesting;
-    checkSets(
-        constants1.keys,
-        constants2.keys,
-        'deferredLoadTask._outputUnitForConstants.keys',
-        areConstantValuesEquivalent,
-        failOnUnfound: false,
-        failOnExtra: false,
-        onSameElement: (ConstantValue value1, ConstantValue value2) {
-      OutputUnit outputUnit1 = constants1[value1];
-      OutputUnit outputUnit2 = constants2[value2];
-      checkOutputUnits(
-          outputUnit1,
-          outputUnit2,
-          'for ${value1.toStructuredText()} '
-          'vs ${value2.toStructuredText()}');
-    }, onUnfoundElement: (ConstantValue value1) {
-      OutputUnit outputUnit1 = constants1[value1];
-      Expect.isTrue(outputUnit1.isMainOutput,
-          "Missing deferred constant: ${value1.toStructuredText()}");
-    }, onExtraElement: (ConstantValue value2) {
-      OutputUnit outputUnit2 = constants2[value2];
-      Expect.isTrue(outputUnit2.isMainOutput,
-          "Extra deferred constant: ${value2.toStructuredText()}");
-    }, elementToString: (a) {
-      return '${a.toStructuredText()} -> ${constants1[a]}/${constants2[a]}';
-    });
+  checkSets(enqueuer1.universe.isChecks, enqueuer2.universe.isChecks,
+      "Is-check mismatch", typeEquivalence,
+      verbose: verbose);
+
+  JavaScriptBackend backend1 = enqueuer1.backend;
+  JavaScriptBackend backend2 = enqueuer2.backend;
+  Expect.equals(backend1.hasInvokeOnSupport,
+      backend2.hasInvokeOnSupport, "Compiler.enabledInvokeOn mismatch");
+  Expect.equals(
+      enqueuer1.universe.hasFunctionApplySupport,
+      enqueuer2.universe.hasFunctionApplySupport,
+      "ResolutionEnqueuer.universe.hasFunctionApplySupport mismatch");
+  Expect.equals(
+      enqueuer1.universe.hasRuntimeTypeSupport,
+      enqueuer2.universe.hasRuntimeTypeSupport,
+      "ResolutionEnqueuer.universe.hasRuntimeTypeSupport mismatch");
+  Expect.equals(
+      enqueuer1.universe.hasIsolateSupport,
+      enqueuer2.universe.hasIsolateSupport,
+      "ResolutionEnqueuer.universe.hasIsolateSupport mismatch");
+}
+
+void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2,
+    {bool verbose: false}) {
+  checkClassHierarchyNodes(
+      closedWorld1,
+      closedWorld2,
+      closedWorld1.getClassHierarchyNode(closedWorld1.coreClasses.objectClass),
+      closedWorld2.getClassHierarchyNode(closedWorld2.coreClasses.objectClass),
+      verbose: verbose);
+}
+
+void checkBackendInfo(Compiler compilerNormal, Compiler compilerDeserialized,
+    {bool verbose: false}) {
+  checkSets(
+      compilerNormal.enqueuer.resolution.processedElements,
+      compilerDeserialized.enqueuer.resolution.processedElements,
+      "Processed element mismatch",
+      areElementsEquivalent, onSameElement: (a, b) {
+    checkElements(compilerNormal, compilerDeserialized, a, b, verbose: verbose);
+  }, verbose: verbose);
+  Expect.equals(
+      compilerNormal.deferredLoadTask.isProgramSplit,
+      compilerDeserialized.deferredLoadTask.isProgramSplit,
+      "isProgramSplit mismatch");
+
+  Map<ConstantValue, OutputUnit> constants1 =
+      compilerNormal.deferredLoadTask.outputUnitForConstantsForTesting;
+  Map<ConstantValue, OutputUnit> constants2 =
+      compilerDeserialized.deferredLoadTask.outputUnitForConstantsForTesting;
+  checkSets(
+      constants1.keys,
+      constants2.keys,
+      'deferredLoadTask._outputUnitForConstants.keys',
+      areConstantValuesEquivalent,
+      failOnUnfound: false,
+      failOnExtra: false,
+      onSameElement: (ConstantValue value1, ConstantValue value2) {
+    OutputUnit outputUnit1 = constants1[value1];
+    OutputUnit outputUnit2 = constants2[value2];
+    checkOutputUnits(
+        outputUnit1,
+        outputUnit2,
+        'for ${value1.toStructuredText()} '
+        'vs ${value2.toStructuredText()}');
+  }, onUnfoundElement: (ConstantValue value1) {
+    OutputUnit outputUnit1 = constants1[value1];
+    Expect.isTrue(outputUnit1.isMainOutput,
+        "Missing deferred constant: ${value1.toStructuredText()}");
+  }, onExtraElement: (ConstantValue value2) {
+    OutputUnit outputUnit2 = constants2[value2];
+    Expect.isTrue(outputUnit2.isMainOutput,
+        "Extra deferred constant: ${value2.toStructuredText()}");
+  }, elementToString: (a) {
+    return '${a.toStructuredText()} -> ${constants1[a]}/${constants2[a]}';
   });
 }
 
@@ -260,19 +287,19 @@
   checkElementOutputUnits(compiler1, compiler2, element1, element2);
 }
 
-void checkMixinUses(Compiler compiler1, Compiler compiler2, ClassElement class1,
-    ClassElement class2,
+void checkMixinUses(ClosedWorld closedWorld1, ClosedWorld closedWorld2,
+    ClassElement class1, ClassElement class2,
     {bool verbose: false}) {
-  checkSets(
-      compiler1.closedWorld.mixinUsesOf(class1),
-      compiler2.closedWorld.mixinUsesOf(class2),
-      "Mixin uses of $class1 vs $class2",
-      areElementsEquivalent,
+  checkSets(closedWorld1.mixinUsesOf(class1), closedWorld2.mixinUsesOf(class2),
+      "Mixin uses of $class1 vs $class2", areElementsEquivalent,
       verbose: verbose);
 }
 
-void checkClassHierarchyNodes(Compiler compiler1, Compiler compiler2,
-    ClassHierarchyNode node1, ClassHierarchyNode node2,
+void checkClassHierarchyNodes(
+    ClosedWorld closedWorld1,
+    ClosedWorld closedWorld2,
+    ClassHierarchyNode node1,
+    ClassHierarchyNode node2,
     {bool verbose: false}) {
   if (verbose) {
     print('Checking $node1 vs $node2');
@@ -295,7 +322,7 @@
     bool found = false;
     for (ClassHierarchyNode other in node2.directSubclasses) {
       if (areElementsEquivalent(child.cls, other.cls)) {
-        checkClassHierarchyNodes(compiler1, compiler2, child, other,
+        checkClassHierarchyNodes(closedWorld1, closedWorld2, child, other,
             verbose: verbose);
         found = true;
         break;
@@ -305,10 +332,10 @@
       if (child.isInstantiated) {
         print('Missing subclass ${child.cls} of ${node1.cls} '
             'in ${node2.directSubclasses}');
-        print(compiler1.closedWorld
-            .dump(verbose ? compiler1.coreClasses.objectClass : node1.cls));
-        print(compiler2.closedWorld
-            .dump(verbose ? compiler2.coreClasses.objectClass : node2.cls));
+        print(closedWorld1
+            .dump(verbose ? closedWorld1.coreClasses.objectClass : node1.cls));
+        print(closedWorld2
+            .dump(verbose ? closedWorld2.coreClasses.objectClass : node2.cls));
       }
       Expect.isFalse(
           child.isInstantiated,
@@ -316,7 +343,8 @@
           '${node2.directSubclasses}');
     }
   }
-  checkMixinUses(compiler1, compiler2, node1.cls, node2.cls, verbose: verbose);
+  checkMixinUses(closedWorld1, closedWorld2, node1.cls, node2.cls,
+      verbose: verbose);
 }
 
 bool areLocalsEquivalent(Local a, Local b) {
diff --git a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
index ac2e682..2c81edc 100644
--- a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
@@ -96,7 +96,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturn(String name, type) {
           var element = findElement(compiler, name);
@@ -112,16 +112,17 @@
         checkReturn('returnDyn1', subclassOfInterceptor);
         checkReturn('returnDyn2', subclassOfInterceptor);
         checkReturn('returnDyn3', subclassOfInterceptor);
-        checkReturn(
-            'returnDyn4', compiler.commonMasks.dynamicType.nonNullable());
-        checkReturn(
-            'returnDyn5', compiler.commonMasks.dynamicType.nonNullable());
-        checkReturn(
-            'returnDyn6', compiler.commonMasks.dynamicType.nonNullable());
+        checkReturn('returnDyn4',
+            compiler.closedWorld.commonMasks.dynamicType.nonNullable());
+        checkReturn('returnDyn5',
+            compiler.closedWorld.commonMasks.dynamicType.nonNullable());
+        checkReturn('returnDyn6',
+            compiler.closedWorld.commonMasks.dynamicType.nonNullable());
         checkReturn('returnDyn7', subclassOfInterceptor);
         checkReturn('returnDyn7b', subclassOfInterceptor);
         checkReturn('returnDyn8', subclassOfInterceptor);
         checkReturn('returnDyn9', subclassOfInterceptor);
-        checkReturn('returnString', compiler.commonMasks.stringType);
+        checkReturn(
+            'returnString', compiler.closedWorld.commonMasks.stringType);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_callers_test.dart b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
index 85b537e..41b9457 100644
--- a/tests/compiler/dart2js/simple_inferrer_callers_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
@@ -35,10 +35,13 @@
 
 void main() {
   Uri uri = new Uri(scheme: 'source');
-  var compiler = compilerFor(TEST, uri);
-  var inferrer = new MyInferrer(compiler, compiler.commonMasks);
-  compiler.globalInference.typesInferrer = inferrer;
+  var compiler = compilerFor(TEST, uri, analyzeOnly: true);
   asyncTest(() => compiler.run(uri).then((_) {
+        compiler.closeResolution();
+        var inferrer =
+            new MyInferrer(compiler, compiler.closedWorld.commonMasks);
+        compiler.globalInference.typesInferrerInternal = inferrer;
+        compiler.globalInference.runGlobalTypeInference(compiler.mainFunction);
         var mainElement = findElement(compiler, 'main');
         var classA = findElement(compiler, 'A');
         var fieldA = classA.lookupLocalMember('field');
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index 5a12baa..109f197 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -118,7 +118,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturn(String name, type) {
           var element = findElement(compiler, name);
@@ -128,20 +128,20 @@
               name);
         }
 
-        checkReturn('returnInt1', compiler.commonMasks.uint31Type);
-        checkReturn('returnInt2', compiler.commonMasks.uint31Type);
-        checkReturn('returnInt3', compiler.commonMasks.uint31Type);
-        checkReturn('returnInt4', compiler.commonMasks.uint31Type);
-        checkReturn(
-            'returnIntOrNull', compiler.commonMasks.uint31Type.nullable());
+        checkReturn('returnInt1', compiler.closedWorld.commonMasks.uint31Type);
+        checkReturn('returnInt2', compiler.closedWorld.commonMasks.uint31Type);
+        checkReturn('returnInt3', compiler.closedWorld.commonMasks.uint31Type);
+        checkReturn('returnInt4', compiler.closedWorld.commonMasks.uint31Type);
+        checkReturn('returnIntOrNull',
+            compiler.closedWorld.commonMasks.uint31Type.nullable());
 
-        checkReturn(
-            'returnDyn1', compiler.commonMasks.dynamicType.nonNullable());
-        checkReturn(
-            'returnDyn2', compiler.commonMasks.dynamicType.nonNullable());
-        checkReturn(
-            'returnDyn3', compiler.commonMasks.dynamicType.nonNullable());
-        checkReturn('returnNum1', compiler.commonMasks.numType);
+        checkReturn('returnDyn1',
+            compiler.closedWorld.commonMasks.dynamicType.nonNullable());
+        checkReturn('returnDyn2',
+            compiler.closedWorld.commonMasks.dynamicType.nonNullable());
+        checkReturn('returnDyn3',
+            compiler.closedWorld.commonMasks.dynamicType.nonNullable());
+        checkReturn('returnNum1', compiler.closedWorld.commonMasks.numType);
 
         checkReturnInClass(String className, String methodName, type) {
           var cls = findElement(compiler, className);
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
index 175d716..2e59a21 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
@@ -28,7 +28,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturn(String name, type) {
           var element = findElement(compiler, name);
@@ -38,7 +38,7 @@
               name);
         }
 
-        checkReturn('method', compiler.commonMasks.numType);
-        checkReturn('returnNum', compiler.commonMasks.numType);
+        checkReturn('method', compiler.closedWorld.commonMasks.numType);
+        checkReturn('returnNum', compiler.closedWorld.commonMasks.numType);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
index 1a60bc8..a354985 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
@@ -28,7 +28,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkArgument(String functionName, type) {
           var functionElement = findElement(compiler, functionName);
@@ -40,6 +40,6 @@
               functionName);
         }
 
-        checkArgument('method', compiler.commonMasks.uint31Type);
+        checkArgument('method', compiler.closedWorld.commonMasks.uint31Type);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
index 40914d4..eeeeb02 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
@@ -29,7 +29,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkArgument(String functionName, type) {
           var functionElement = findElement(compiler, functionName);
@@ -41,7 +41,7 @@
               functionName);
         }
 
-        checkArgument('method', compiler.commonMasks.numType);
-        checkArgument('returnNum', compiler.commonMasks.numType);
+        checkArgument('method', compiler.closedWorld.commonMasks.numType);
+        checkArgument('returnNum', compiler.closedWorld.commonMasks.numType);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
index 413a385..a41c254 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
@@ -29,7 +29,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkArgument(String functionName, type) {
           var functionElement = findElement(compiler, functionName);
@@ -41,6 +41,6 @@
               functionName);
         }
 
-        checkArgument('method', compiler.commonMasks.numType);
+        checkArgument('method', compiler.closedWorld.commonMasks.numType);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
index 0a97f95..f2d38c6 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
@@ -42,7 +42,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkArgument(String functionName, type) {
           var functionElement = findElement(compiler, functionName);
@@ -66,41 +66,47 @@
               functionName);
         }
 
-        checkArgument('foo1', compiler.commonMasks.functionType);
+        checkArgument('foo1', compiler.closedWorld.commonMasks.functionType);
 
         /// 01: ok
-        checkArgument('foo2', compiler.commonMasks.functionType);
+        checkArgument('foo2', compiler.closedWorld.commonMasks.functionType);
 
         /// 02: ok
-        checkArgument('foo3', compiler.commonMasks.functionType);
+        checkArgument('foo3', compiler.closedWorld.commonMasks.functionType);
 
         /// 03: ok
-        checkArgument('foo4', compiler.commonMasks.functionType);
+        checkArgument('foo4', compiler.closedWorld.commonMasks.functionType);
 
         /// 04: ok
-        checkArgument('foo5', compiler.commonMasks.dynamicType);
+        checkArgument('foo5', compiler.closedWorld.commonMasks.dynamicType);
 
         /// 05: ok
-        checkArgument('foo6', compiler.commonMasks.dynamicType);
+        checkArgument('foo6', compiler.closedWorld.commonMasks.dynamicType);
 
         /// 06: ok
 
-        checkArgument('defaultFn1', compiler.commonMasks.uint31Type);
+        checkArgument(
+            'defaultFn1', compiler.closedWorld.commonMasks.uint31Type);
 
         /// 07: ok
-        checkArgument('defaultFn2', compiler.commonMasks.uint31Type);
+        checkArgument(
+            'defaultFn2', compiler.closedWorld.commonMasks.uint31Type);
 
         /// 08: ok
-        checkArgument('defaultFn3', compiler.commonMasks.uint31Type);
+        checkArgument(
+            'defaultFn3', compiler.closedWorld.commonMasks.uint31Type);
 
         /// 09: ok
-        checkArgument('defaultFn4', compiler.commonMasks.uint31Type);
+        checkArgument(
+            'defaultFn4', compiler.closedWorld.commonMasks.uint31Type);
 
         /// 10: ok
-        checkArgument('defaultFn5', compiler.commonMasks.uint31Type);
+        checkArgument(
+            'defaultFn5', compiler.closedWorld.commonMasks.uint31Type);
 
         /// 11: ok
-        checkArgument('defaultFn6', compiler.commonMasks.uint31Type);
+        checkArgument(
+            'defaultFn6', compiler.closedWorld.commonMasks.uint31Type);
 
         /// 12: ok
       }));
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
index bb5e17e..6dbd781 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
@@ -37,7 +37,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturn(String name, type) {
           var element = findElement(compiler, name);
@@ -47,10 +47,10 @@
               name);
         }
 
-        checkReturn('method1', compiler.commonMasks.uint31Type);
-        checkReturn('returnInt1', compiler.commonMasks.uint31Type);
+        checkReturn('method1', compiler.closedWorld.commonMasks.uint31Type);
+        checkReturn('returnInt1', compiler.closedWorld.commonMasks.uint31Type);
 
-        checkReturn('method2', compiler.commonMasks.uint31Type);
-        checkReturn('returnInt2', compiler.commonMasks.uint31Type);
+        checkReturn('method2', compiler.closedWorld.commonMasks.uint31Type);
+        checkReturn('returnInt2', compiler.closedWorld.commonMasks.uint31Type);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
index cc429df..2a31462 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
@@ -28,7 +28,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkFieldTypeInClass(String className, String fieldName, type) {
           var cls = findElement(compiler, className);
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
index caa821f..7eeefae 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
@@ -27,7 +27,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkFieldTypeInClass(String className, String fieldName, type) {
           var cls = findElement(compiler, className);
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
index d36ffa9..78b3ebc 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
@@ -31,7 +31,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkFieldTypeInClass(String className, String fieldName, type) {
           var cls = findElement(compiler, className);
@@ -40,12 +40,13 @@
               simplify(typesInferrer.getTypeOfElement(element), compiler));
         }
 
-        checkFieldTypeInClass('A', 'intField', compiler.commonMasks.uint31Type);
+        checkFieldTypeInClass(
+            'A', 'intField', compiler.closedWorld.commonMasks.uint31Type);
         checkFieldTypeInClass('A', 'giveUpField1',
             findTypeMask(compiler, 'Interceptor', 'nonNullSubclass'));
         checkFieldTypeInClass('A', 'giveUpField2',
-            compiler.commonMasks.dynamicType.nonNullable());
+            compiler.closedWorld.commonMasks.dynamicType.nonNullable());
         checkFieldTypeInClass(
-            'A', 'fieldParameter', compiler.commonMasks.uint31Type);
+            'A', 'fieldParameter', compiler.closedWorld.commonMasks.uint31Type);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
index c2e7492..01a896a 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
@@ -28,7 +28,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkArgument(String functionName, type) {
           var functionElement = findElement(compiler, functionName);
@@ -40,6 +40,6 @@
               functionName);
         }
 
-        checkArgument('method', compiler.commonMasks.uint31Type);
+        checkArgument('method', compiler.closedWorld.commonMasks.uint31Type);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
index eb486bc..f20912a 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
@@ -37,7 +37,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturn(String name, type) {
           var element = findElement(compiler, name);
@@ -47,10 +47,10 @@
               name);
         }
 
-        checkReturn('method1', compiler.commonMasks.uint31Type);
-        checkReturn('returnInt1', compiler.commonMasks.uint31Type);
+        checkReturn('method1', compiler.closedWorld.commonMasks.uint31Type);
+        checkReturn('returnInt1', compiler.closedWorld.commonMasks.uint31Type);
 
-        checkReturn('method2', compiler.commonMasks.uint31Type);
-        checkReturn('returnInt2', compiler.commonMasks.uint31Type);
+        checkReturn('method2', compiler.closedWorld.commonMasks.uint31Type);
+        checkReturn('returnInt2', compiler.closedWorld.commonMasks.uint31Type);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
index 96ede85..a68120c 100644
--- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
@@ -164,7 +164,7 @@
   Uri uri = new Uri(scheme: 'source');
 
   checkReturn(MockCompiler compiler, String name, type) {
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     var element = findElement(compiler, name);
     Expect.equals(
         type,
@@ -174,51 +174,74 @@
 
   var compiler1 = compilerFor(TEST1, uri);
   asyncTest(() => compiler1.run(uri).then((_) {
-        checkReturn(compiler1, 'test1', compiler1.commonMasks.uint31Type);
+        checkReturn(
+            compiler1, 'test1', compiler1.closedWorld.commonMasks.uint31Type);
         checkReturn(compiler1, 'test2',
-            compiler1.commonMasks.dynamicType.nonNullable());
-        checkReturn(compiler1, 'test3', compiler1.commonMasks.uint31Type);
-        checkReturn(compiler1, 'test4', compiler1.commonMasks.mapType);
+            compiler1.closedWorld.commonMasks.dynamicType.nonNullable());
+        checkReturn(
+            compiler1, 'test3', compiler1.closedWorld.commonMasks.uint31Type);
+        checkReturn(
+            compiler1, 'test4', compiler1.closedWorld.commonMasks.mapType);
         checkReturn(compiler1, 'test5',
-            compiler1.commonMasks.dynamicType.nonNullable());
+            compiler1.closedWorld.commonMasks.dynamicType.nonNullable());
         checkReturn(compiler1, 'test6',
-            compiler1.commonMasks.dynamicType.nonNullable());
+            compiler1.closedWorld.commonMasks.dynamicType.nonNullable());
       }));
 
   var compiler2 = compilerFor(TEST2, uri);
   asyncTest(() => compiler2.run(uri).then((_) {
+        checkReturn(compiler2, 'test1',
+            compiler2.closedWorld.commonMasks.mapType.nonNullable());
         checkReturn(
-            compiler2, 'test1', compiler2.commonMasks.mapType.nonNullable());
-        checkReturn(compiler2, 'test2', compiler2.commonMasks.mapType);
-        checkReturn(compiler2, 'test3', compiler2.commonMasks.mapType);
-        checkReturn(compiler2, 'test4', compiler2.commonMasks.mapType);
-        checkReturn(compiler2, 'test5', compiler2.commonMasks.mapType);
+            compiler2, 'test2', compiler2.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler2, 'test3', compiler2.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler2, 'test4', compiler2.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler2, 'test5', compiler2.closedWorld.commonMasks.mapType);
 
-        checkReturn(compiler2, 'test6', compiler2.commonMasks.numType);
-        checkReturn(compiler2, 'test7', compiler2.commonMasks.uint31Type);
-        checkReturn(compiler2, 'test8', compiler2.commonMasks.uint31Type);
-        checkReturn(compiler2, 'test9', compiler2.commonMasks.uint31Type);
-        checkReturn(compiler2, 'test10', compiler2.commonMasks.numType);
-        checkReturn(compiler2, 'test11', compiler2.commonMasks.doubleType);
+        checkReturn(
+            compiler2, 'test6', compiler2.closedWorld.commonMasks.numType);
+        checkReturn(
+            compiler2, 'test7', compiler2.closedWorld.commonMasks.uint31Type);
+        checkReturn(
+            compiler2, 'test8', compiler2.closedWorld.commonMasks.uint31Type);
+        checkReturn(
+            compiler2, 'test9', compiler2.closedWorld.commonMasks.uint31Type);
+        checkReturn(
+            compiler2, 'test10', compiler2.closedWorld.commonMasks.numType);
+        checkReturn(
+            compiler2, 'test11', compiler2.closedWorld.commonMasks.doubleType);
       }));
 
   var compiler3 = compilerFor(TEST3, uri);
   asyncTest(() => compiler3.run(uri).then((_) {
         checkReturn(compiler3, 'test1', const TypeMask.nonNullEmpty());
-        checkReturn(compiler3, 'test2', compiler3.commonMasks.mapType);
-        checkReturn(compiler3, 'test3', compiler3.commonMasks.mapType);
-        checkReturn(compiler3, 'test4', compiler3.commonMasks.mapType);
-        checkReturn(compiler3, 'test5', compiler3.commonMasks.mapType);
-        checkReturn(compiler3, 'test6', compiler3.commonMasks.mapType);
+        checkReturn(
+            compiler3, 'test2', compiler3.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler3, 'test3', compiler3.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler3, 'test4', compiler3.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler3, 'test5', compiler3.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler3, 'test6', compiler3.closedWorld.commonMasks.mapType);
       }));
 
   var compiler4 = compilerFor(TEST4, uri);
   asyncTest(() => compiler4.run(uri).then((_) {
         checkReturn(compiler4, 'test1', const TypeMask.nonNullEmpty());
-        checkReturn(compiler4, 'test2', compiler4.commonMasks.mapType);
-        checkReturn(compiler4, 'test3', compiler4.commonMasks.mapType);
-        checkReturn(compiler4, 'test4', compiler4.commonMasks.mapType);
-        checkReturn(compiler4, 'test5', compiler4.commonMasks.mapType);
-        checkReturn(compiler4, 'test6', compiler4.commonMasks.mapType);
+        checkReturn(
+            compiler4, 'test2', compiler4.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler4, 'test3', compiler4.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler4, 'test4', compiler4.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler4, 'test5', compiler4.closedWorld.commonMasks.mapType);
+        checkReturn(
+            compiler4, 'test6', compiler4.closedWorld.commonMasks.mapType);
       }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
index 3b308f0..3d37e58 100644
--- a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
@@ -66,8 +66,8 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturnInClass(String className, String methodName, type) {
           var cls = findElement(compiler, className);
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index ccb07a8..cf29a1a 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -727,8 +727,8 @@
   var compiler = compilerFor(TEST, uri);
   compiler.diagnosticHandler = createHandler(compiler, TEST);
   asyncTest(() => compiler.run(uri).then((_) {
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
         var world = compiler.closedWorld;
 
         checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index 28c8fde..207a861 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -167,8 +167,8 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var commonMasks = compiler.commonMasks;
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var commonMasks = compiler.closedWorld.commonMasks;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturn(String name, type) {
           var element = findElement(compiler, name);
diff --git a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
index 1253b83..f0be6f8 100644
--- a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
@@ -32,7 +32,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         checkReturnInClass(String className, String methodName, type) {
           var cls = findElement(compiler, className);
@@ -40,6 +40,7 @@
           Expect.equals(type, typesInferrer.getReturnTypeOfElement(element));
         }
 
-        checkReturnInClass('A', '+', compiler.commonMasks.uint31Type);
+        checkReturnInClass(
+            'A', '+', compiler.closedWorld.commonMasks.uint31Type);
       }));
 }
diff --git a/tests/compiler/dart2js/trust_type_annotations_test.dart b/tests/compiler/dart2js/trust_type_annotations_test.dart
index c140fed..764e5ef 100644
--- a/tests/compiler/dart2js/trust_type_annotations_test.dart
+++ b/tests/compiler/dart2js/trust_type_annotations_test.dart
@@ -50,7 +50,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri, trustTypeAnnotations: true);
   asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrer;
+        var typesInferrer = compiler.globalInference.typesInferrerInternal;
 
         ClassElement classA = findElement(compiler, "A");
 
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index 5ca7197..875f276 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -736,7 +736,7 @@
     """);
     JavaScriptBackend backend = compiler.backend;
     BackendHelpers helpers = backend.helpers;
-    ClosedWorld world = compiler.openWorld.closeWorld();
+    ClosedWorld world = compiler.openWorld.closeWorld(compiler.reporter);
     helpers.interceptorsLibrary.forEachLocalMember((element) {
       if (element.isClass) {
         element.ensureResolved(compiler.resolution);
@@ -752,7 +752,7 @@
         .registerInstantiatedType(compiler.coreTypes.functionType);
     compiler.enqueuer.resolution
         .registerInstantiatedType(patternImplClass.rawType);
-    compiler.openWorld.closeWorld();
+    compiler.openWorld.closeWorld(compiler.reporter);
 
     // Grab hold of a supertype for String so we can produce potential
     // string types.
diff --git a/tests/compiler/dart2js/type_inference6_test.dart b/tests/compiler/dart2js/type_inference6_test.dart
index 7eaf0a5..a9cdc0a 100644
--- a/tests/compiler/dart2js/type_inference6_test.dart
+++ b/tests/compiler/dart2js/type_inference6_test.dart
@@ -24,8 +24,8 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   return compiler.run(uri).then((_) {
-    var commonMasks = compiler.commonMasks;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var commonMasks = compiler.closedWorld.commonMasks;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     var element = findElement(compiler, "foo");
     var mask = typesInferrer.getReturnTypeOfElement(element);
     Expect.equals(commonMasks.uint31Type, simplify(mask, compiler));
diff --git a/tests/compiler/dart2js/type_inference7_test.dart b/tests/compiler/dart2js/type_inference7_test.dart
index 42b19b0..a8ebbb0 100644
--- a/tests/compiler/dart2js/type_inference7_test.dart
+++ b/tests/compiler/dart2js/type_inference7_test.dart
@@ -23,8 +23,8 @@
     // Assertions enabled:
     var compiler = compilerFor(TEST, uri, enableUserAssertions: true);
     await compiler.run(uri);
-    var commonMasks = compiler.commonMasks;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var commonMasks = compiler.closedWorld.commonMasks;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     var foo = findElement(compiler, "foo");
     // Return type is null|bool.
     var mask = typesInferrer.getReturnTypeOfElement(foo);
@@ -52,8 +52,8 @@
     // Assertions disabled:
     var compiler = compilerFor(TEST, uri, enableUserAssertions: false);
     await compiler.run(uri);
-    var commonMasks = compiler.commonMasks;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var commonMasks = compiler.closedWorld.commonMasks;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     var foo = findElement(compiler, "foo");
     // Return type is null.
     var mask = typesInferrer.getReturnTypeOfElement(foo);
diff --git a/tests/compiler/dart2js/type_inference8_test.dart b/tests/compiler/dart2js/type_inference8_test.dart
index bcae368..fb4717c 100644
--- a/tests/compiler/dart2js/type_inference8_test.dart
+++ b/tests/compiler/dart2js/type_inference8_test.dart
@@ -34,8 +34,8 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST1, uri);
   return compiler.run(uri).then((_) {
-    var commonMasks = compiler.commonMasks;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var commonMasks = compiler.closedWorld.commonMasks;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     var element = findElement(compiler, "foo");
     var mask = typesInferrer.getReturnTypeOfElement(element);
     var falseType =
@@ -77,8 +77,8 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST2, uri);
   return compiler.run(uri).then((_) {
-    var commonMasks = compiler.commonMasks;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var commonMasks = compiler.closedWorld.commonMasks;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     var element = findElement(compiler, "foo");
     var mask = typesInferrer.getReturnTypeOfElement(element);
     // Can't infer value for foo's return type, it could be either true or false
diff --git a/tests/compiler/dart2js/type_inference_switch_test.dart b/tests/compiler/dart2js/type_inference_switch_test.dart
index bac1abd..181fc41 100644
--- a/tests/compiler/dart2js/type_inference_switch_test.dart
+++ b/tests/compiler/dart2js/type_inference_switch_test.dart
@@ -135,15 +135,15 @@
   var compiler = compilerFor(test, uri);
 
   checkTypeOf(String name, TypeMask type) {
-    var commonMasks = compiler.commonMasks;
-    var typesInferrer = compiler.globalInference.typesInferrer;
+    var commonMasks = compiler.closedWorld.commonMasks;
+    var typesInferrer = compiler.globalInference.typesInferrerInternal;
     var element = findElement(compiler, name);
     var mask = typesInferrer.getReturnTypeOfElement(element);
     Expect.equals(type, simplify(mask, compiler));
   }
 
   return compiler.run(uri).then((_) {
-    checker(compiler.commonMasks, checkTypeOf);
+    checker(compiler.closedWorld.commonMasks, checkTypeOf);
   });
 }
 
diff --git a/tests/compiler/dart2js/type_mask_test.dart b/tests/compiler/dart2js/type_mask_test.dart
index fae28df..3cb01a0 100644
--- a/tests/compiler/dart2js/type_mask_test.dart
+++ b/tests/compiler/dart2js/type_mask_test.dart
@@ -21,7 +21,7 @@
 main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(CODE, uri);
-  var closedWorld = compiler.openWorld.closeWorld();
+  var closedWorld = compiler.openWorld.closeWorld(compiler.reporter);
 
   asyncTest(() => compiler.run(uri).then((_) {
         var classA = findElement(compiler, 'A');
diff --git a/tests/compiler/dart2js/union_type_test.dart b/tests/compiler/dart2js/union_type_test.dart
index 336ce10..65e6da6 100644
--- a/tests/compiler/dart2js/union_type_test.dart
+++ b/tests/compiler/dart2js/union_type_test.dart
@@ -22,7 +22,8 @@
       }
       """,
         useMockCompiler: false);
-    ClosedWorld world = env.compiler.openWorld.closeWorld();
+    ClosedWorld world =
+        env.compiler.openWorld.closeWorld(env.compiler.reporter);
     FlatTypeMask mask1 = new FlatTypeMask.exact(env.getElement('A'));
     FlatTypeMask mask2 = new FlatTypeMask.exact(env.getElement('B'));
     UnionTypeMask union1 = mask1.nonNullable().union(mask2, world);