diff --git a/karma-dart.conf.js b/karma-dart.conf.js
index 1ffe1b8257..1756386e65 100644
--- a/karma-dart.conf.js
+++ b/karma-dart.conf.js
@@ -8,6 +8,8 @@ module.exports = function(config) {
     frameworks: ['dart-unittest'],
 
     files: [
+      // Init and configure guiness.
+      {pattern: 'test-init.dart', included: true},
       // Unit test files needs to be included.
       // Karma-dart generates `__adapter_unittest.dart` that imports these files.
       {pattern: 'modules/*/test/**/*_spec.js', included: true},
diff --git a/modules/angular2/core.js b/modules/angular2/core.js
index cad9b91e40..3a6f970937 100644
--- a/modules/angular2/core.js
+++ b/modules/angular2/core.js
@@ -14,5 +14,5 @@ export * from './src/core/compiler/private_component_location';
 export * from './src/core/compiler/view';
 export * from './src/core/compiler/view_container';
 
-export * from './src/core/dom/element';
+export * from './src/core/compiler/ng_element';
 
diff --git a/modules/angular2/src/core/application.js b/modules/angular2/src/core/application.js
index 176689c50f..920b2f3cbf 100644
--- a/modules/angular2/src/core/application.js
+++ b/modules/angular2/src/core/application.js
@@ -9,12 +9,12 @@ import {ExceptionHandler} from './exception_handler';
 import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
 import {TemplateResolver} from './compiler/template_resolver';
 import {DirectiveMetadataReader} from './compiler/directive_metadata_reader';
-import {DirectiveBinding} from './compiler/element_injector';
 import {List, ListWrapper} from 'angular2/src/facade/collection';
 import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
 import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
 import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
-import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
+import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
+import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
 import {XHR} from 'angular2/src/services/xhr';
 import {XHRImpl} from 'angular2/src/services/xhr_impl';
 import {EventManager, DomEventsPlugin} from 'angular2/src/render/dom/events/event_manager';
@@ -27,6 +27,13 @@ import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
 import {Component} from 'angular2/src/core/annotations/annotations';
 import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
 import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
+import {ViewFactory, VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_factory';
+import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
+import {Renderer} from 'angular2/src/render/api';
+import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
+import * as rc from 'angular2/src/render/dom/compiler/compiler';
+import * as rvf from 'angular2/src/render/dom/view/view_factory';
+
 import {
   appViewToken,
   appChangeDetectorToken,
@@ -60,7 +67,7 @@ function _injectorBindings(appComponentType): List<Binding> {
         return element;
       }, [appComponentAnnotatedTypeToken, appDocumentToken]),
       bind(appViewToken).toAsyncFactory((changeDetection, compiler, injector, appElement,
-        appComponentAnnotatedType, strategy, eventManager, testability, registry) => {
+        appComponentAnnotatedType, testability, registry, viewFactory) => {
 
         // We need to do this here to ensure that we create Testability and
         // it's ready on the window for users.
@@ -73,18 +80,18 @@ function _injectorBindings(appComponentType): List<Binding> {
         }
         return compiler.compileRoot(
             appElement,
-            DirectiveBinding.createFromType(appComponentAnnotatedType.type, appComponentAnnotatedType.annotation)
+            appComponentAnnotatedType.type
           ).then(
             (appProtoView) => {
           // The light Dom of the app element is not considered part of
           // the angular application. Thus the context and lightDomInjector are
           // empty.
-          var view = appProtoView.instantiate(null, eventManager);
-          view.hydrate(injector, null, null, new Object(), null);
+          var view = viewFactory.getView(appProtoView);
+          view.hydrate(injector, null, new Object(), null);
           return view;
         });
       }, [ChangeDetection, Compiler, Injector, appElementToken, appComponentAnnotatedTypeToken,
-          ShadowDomStrategy, EventManager, Testability, TestabilityRegistry]),
+          Testability, TestabilityRegistry, ViewFactory]),
 
       bind(appChangeDetectorToken).toFactory((rootView) => rootView.changeDetector,
           [appViewToken]),
@@ -98,6 +105,23 @@ function _injectorBindings(appComponentType): List<Binding> {
       bind(ShadowDomStrategy).toFactory(
           (styleUrlResolver, doc) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, doc.head),
           [StyleUrlResolver, appDocumentToken]),
+      bind(Renderer).toClass(DirectDomRenderer),
+      bind(rc.Compiler).toClass(rc.DefaultCompiler),
+      // TODO(tbosch): We need an explicit factory here, as
+      // we are getting errors in dart2js with mirrors...
+      bind(rvf.ViewFactory).toFactory(
+        (capacity, eventManager, shadowDomStrategy) => new rvf.ViewFactory(capacity, eventManager, shadowDomStrategy),
+        [rvf.VIEW_POOL_CAPACITY, EventManager, ShadowDomStrategy]
+      ),
+      bind(rvf.VIEW_POOL_CAPACITY).toValue(100000),
+      ProtoViewFactory,
+      // TODO(tbosch): We need an explicit factory here, as
+      // we are getting errors in dart2js with mirrors...
+      bind(ViewFactory).toFactory(
+        (capacity) => new ViewFactory(capacity),
+        [VIEW_POOL_CAPACITY]
+      ),
+      bind(VIEW_POOL_CAPACITY).toValue(100000),
       Compiler,
       CompilerCache,
       TemplateResolver,
diff --git a/modules/angular2/src/core/compiler/compiler.js b/modules/angular2/src/core/compiler/compiler.js
index 6c382412e9..ed27b82e02 100644
--- a/modules/angular2/src/core/compiler/compiler.js
+++ b/modules/angular2/src/core/compiler/compiler.js
@@ -3,24 +3,16 @@ import {Type, isBlank, isPresent, BaseException, normalizeBlank, stringify} from
 import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
 import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection';
 
-import {ChangeDetection, Parser} from 'angular2/change_detection';
-
 import {DirectiveMetadataReader} from './directive_metadata_reader';
 import {Component, Viewport, DynamicComponent, Decorator} from '../annotations/annotations';
 import {ProtoView} from './view';
 import {DirectiveBinding} from './element_injector';
 import {TemplateResolver} from './template_resolver';
 import {Template} from '../annotations/template';
-import {ShadowDomStrategy} from './shadow_dom_strategy';
 import {ComponentUrlMapper} from './component_url_mapper';
 import {ProtoViewFactory} from './proto_view_factory';
 import {UrlResolver} from 'angular2/src/services/url_resolver';
 
-import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
-import {DefaultStepFactory} from 'angular2/src/render/dom/compiler/compile_step_factory';
-import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
-
-import * as rc from 'angular2/src/render/dom/compiler/compiler';
 import * as renderApi from 'angular2/src/render/api';
 
 /**
@@ -49,9 +41,7 @@ export class CompilerCache {
 }
 
 
-// TODO(tbosch): rename this class to Compiler
-// and remove the current Compiler when core uses the render views.
-export class NewCompiler {
+export class Compiler {
   _reader: DirectiveMetadataReader;
   _compilerCache:CompilerCache;
   _compiling:Map<Type, Promise>;
@@ -80,19 +70,19 @@ export class NewCompiler {
     this._protoViewFactory = protoViewFactory;
   }
 
-  _bindDirective(directive) {
-    var meta = this._reader.read(directive);
+  _bindDirective(directiveTypeOrBinding) {
+    if (directiveTypeOrBinding instanceof DirectiveBinding) {
+      return directiveTypeOrBinding;
+    }
+    var meta = this._reader.read(directiveTypeOrBinding);
     return DirectiveBinding.createFromType(meta.type, meta.annotation);
   }
 
   // Create a rootView as if the compiler encountered <rootcmp></rootcmp>.
   // Used for bootstrapping.
-  compileRoot(elementOrSelector, componentBinding:DirectiveBinding):Promise<ProtoView> {
+  compileRoot(elementOrSelector, componentTypeOrBinding:any):Promise<ProtoView> {
     return this._renderer.createRootProtoView(elementOrSelector, 'root').then( (rootRenderPv) => {
-      return this._compileNestedProtoViews(null, rootRenderPv, [componentBinding], true)
-    }).then( (rootProtoView) => {
-      rootProtoView.instantiateInPlace = true;
-      return rootProtoView;
+      return this._compileNestedProtoViews(null, rootRenderPv, [this._bindDirective(componentTypeOrBinding)], true);
     });
   }
 
@@ -266,40 +256,3 @@ export class NewCompiler {
   }
 
 }
-
-// TODO(tbosch): delete this class once we use the render views
-/**
- * The compiler loads and translates the html templates of components into
- * nested ProtoViews. To decompose its functionality it uses
- * the render compiler.
- *
- * @publicModule angular2/template
- */
-@Injectable()
-export class Compiler extends NewCompiler {
-  constructor(changeDetection:ChangeDetection,
-              templateLoader:TemplateLoader,
-              reader: DirectiveMetadataReader,
-              parser:Parser,
-              cache:CompilerCache,
-              shadowDomStrategy: ShadowDomStrategy,
-              templateResolver: TemplateResolver,
-              componentUrlMapper: ComponentUrlMapper,
-              urlResolver: UrlResolver) {
-    super(
-      reader,
-      cache,
-      templateResolver,
-      componentUrlMapper,
-      urlResolver,
-      new DirectDomRenderer(
-        new rc.Compiler(
-          new DefaultStepFactory(parser, shadowDomStrategy.render),
-          templateLoader
-        ),
-        null, shadowDomStrategy.render
-      ),
-      new ProtoViewFactory(changeDetection, shadowDomStrategy)
-    );
-  }
-}
diff --git a/modules/angular2/src/core/compiler/element_binder.js b/modules/angular2/src/core/compiler/element_binder.js
index 3c8e925cb6..dc82640c3f 100644
--- a/modules/angular2/src/core/compiler/element_binder.js
+++ b/modules/angular2/src/core/compiler/element_binder.js
@@ -8,11 +8,8 @@ export class ElementBinder {
   protoElementInjector:eiModule.ProtoElementInjector;
   componentDirective:DirectiveBinding;
   viewportDirective:DirectiveBinding;
-  textNodeIndices:List<int>;
-  hasElementPropertyBindings:boolean;
   nestedProtoView: viewModule.ProtoView;
   events:StringMap;
-  contentTagSelector:string;
   parent:ElementBinder;
   index:int;
   distanceToParent:int;
@@ -32,13 +29,7 @@ export class ElementBinder {
     this.distanceToParent = distanceToParent;
     // updated later when events are bound
     this.events = null;
-    // updated later when text nodes are bound
-    this.textNodeIndices = null;
-    // updated later when element properties are bound
-    this.hasElementPropertyBindings = false;
     // updated later, so we are able to resolve cycles
     this.nestedProtoView = null;
-    // updated later in the compilation pipeline
-    this.contentTagSelector = null;
   }
 }
diff --git a/modules/angular2/src/core/compiler/element_injector.js b/modules/angular2/src/core/compiler/element_injector.js
index 900728753f..1566d3a3cb 100644
--- a/modules/angular2/src/core/compiler/element_injector.js
+++ b/modules/angular2/src/core/compiler/element_injector.js
@@ -6,11 +6,10 @@ import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
 import {EventEmitter, PropertySetter, Attribute} from 'angular2/src/core/annotations/di';
 import * as viewModule from 'angular2/src/core/compiler/view';
 import {ViewContainer} from 'angular2/src/core/compiler/view_container';
-import {NgElement} from 'angular2/src/core/dom/element';
+import {NgElement} from 'angular2/src/core/compiler/ng_element';
 import {Directive, onChange, onDestroy, onAllChangesDone} from 'angular2/src/core/annotations/annotations';
 import {BindingPropagationConfig} from 'angular2/change_detection';
 import * as pclModule from 'angular2/src/core/compiler/private_component_location';
-import {setterFactory} from 'angular2/src/render/dom/view/property_setter_factory';
 
 var _MAX_DIRECTIVE_CONSTRUCTION_COUNTER = 10;
 
@@ -268,8 +267,8 @@ export class ProtoElementInjector  {
     }
   }
 
-  instantiate(parent:ElementInjector, host:ElementInjector):ElementInjector {
-    return new ElementInjector(this, parent, host);
+  instantiate(parent:ElementInjector):ElementInjector {
+    return new ElementInjector(this, parent);
   }
 
   directParent(): ProtoElementInjector {
@@ -339,21 +338,12 @@ export class ElementInjector extends TreeNode {
   _privateComponent;
   _privateComponentBinding:DirectiveBinding;
 
-  constructor(proto:ProtoElementInjector, parent:ElementInjector, host:ElementInjector) {
+  constructor(proto:ProtoElementInjector, parent:ElementInjector) {
     super(parent);
-    if (isPresent(parent) && isPresent(host)) {
-      throw new BaseException('Only either parent or host is allowed');
-    }
-    this._host = null; // needed to satisfy Dart
-    if (isPresent(parent)) {
-      this._host = parent._host;
-    } else {
-      this._host = host;
-    }
-
     this._proto = proto;
 
     //we cannot call clearDirectives because fields won't be detected
+    this._host = null;
     this._preBuiltObjects = null;
     this._lightDomAppInjector = null;
     this._shadowDomAppInjector = null;
@@ -371,6 +361,7 @@ export class ElementInjector extends TreeNode {
   }
 
   clearDirectives() {
+    this._host = null;
     this._preBuiltObjects = null;
     this._lightDomAppInjector = null;
     this._shadowDomAppInjector = null;
@@ -406,7 +397,8 @@ export class ElementInjector extends TreeNode {
     this._constructionCounter = 0;
   }
 
-  instantiateDirectives(lightDomAppInjector:Injector, shadowDomAppInjector:Injector, preBuiltObjects:PreBuiltObjects) {
+  instantiateDirectives(lightDomAppInjector:Injector, host:ElementInjector, shadowDomAppInjector:Injector, preBuiltObjects:PreBuiltObjects) {
+    this._host = host;
     this._checkShadowDomAppInjector(shadowDomAppInjector);
 
     this._preBuiltObjects = preBuiltObjects;
@@ -456,10 +448,6 @@ export class ElementInjector extends TreeNode {
     return pb !== _undefined && isPresent(pb);
   }
 
-  forElement(el):boolean {
-    return this._preBuiltObjects.element.domElement === el;
-  }
-
   /** Gets the NgElement associated with this ElementInjector */
   getNgElement() {
     return this._preBuiltObjects.element;
@@ -538,6 +526,10 @@ export class ElementInjector extends TreeNode {
     return obj;
   }
 
+  getBoundElementIndex() {
+    return this._proto.index;
+  }
+
   _getByDependency(dep:DirectiveDependency, requestor:Key) {
     if (isPresent(dep.eventEmitterName)) return this._buildEventEmitter(dep);
     if (isPresent(dep.propSetterName)) return this._buildPropSetter(dep);
@@ -553,10 +545,12 @@ export class ElementInjector extends TreeNode {
   }
 
   _buildPropSetter(dep) {
-    var ngElement = this._getPreBuiltObjectByKeyId(StaticKeys.instance().ngElementId);
-    var domElement = ngElement.domElement;
-    var setter = setterFactory(dep.propSetterName);
-    return function(v) { setter(domElement, v) };
+    var view = this._getPreBuiltObjectByKeyId(StaticKeys.instance().viewId);
+    var renderer = view.proto.renderer;
+    var index = this._proto.index;
+    return function(v) {
+      renderer.setElementProperty(view.render, index, dep.propSetterName, v);
+    };
   }
 
   _buildAttribute(dep): string {
@@ -582,7 +576,6 @@ export class ElementInjector extends TreeNode {
    */
   _getByKey(key:Key, depth:number, optional:boolean, requestor:Key) {
     var ei = this;
-
     if (! this._shouldIncludeSelf(depth)) {
       depth -= ei._proto.distanceToParent;
       ei = ei._parent;
@@ -631,7 +624,7 @@ export class ElementInjector extends TreeNode {
     if (keyId === staticKeys.bindingPropagationConfigId) return this._preBuiltObjects.bindingPropagationConfig;
 
     if (keyId === staticKeys.privateComponentLocationId) {
-      return new pclModule.PrivateComponentLocation(this, this._preBuiltObjects.element, this._preBuiltObjects.view);
+      return new pclModule.PrivateComponentLocation(this, this._preBuiltObjects.view);
     }
 
     //TODO add other objects as needed
diff --git a/modules/angular2/src/core/compiler/ng_element.js b/modules/angular2/src/core/compiler/ng_element.js
new file mode 100644
index 0000000000..af496c0d26
--- /dev/null
+++ b/modules/angular2/src/core/compiler/ng_element.js
@@ -0,0 +1,34 @@
+import {DOM} from 'angular2/src/dom/dom_adapter';
+import {normalizeBlank} from 'angular2/src/facade/lang';
+import * as viewModule from '../compiler/view';
+import {DirectDomViewRef} from 'angular2/src/render/dom/direct_dom_renderer';
+
+/**
+ * Allows direct access to the underlying DOM element.
+ *
+ * Attention: NgElement will be replaced by a different concept
+ * for accessing an element in a way that is compatible with the render layer.
+ *
+ * @publicModule angular2/angular2
+ */
+export class NgElement {
+  _view:viewModule.View;
+  _boundElementIndex:number;
+
+  constructor(view, boundElementIndex) {
+    this._view = view;
+    this._boundElementIndex = boundElementIndex;
+  }
+
+  // TODO(tbosch): Here we expose the real DOM element.
+  // We need a more general way to read/write to the DOM element
+  // via a proper abstraction in the render layer
+  get domElement() {
+    var domViewRef:DirectDomViewRef = this._view.render;
+    return domViewRef.delegate.boundElements[this._boundElementIndex];
+  }
+
+  getAttribute(name:string) {
+    return normalizeBlank(DOM.getAttribute(this.domElement, name));
+  }
+}
\ No newline at end of file
diff --git a/modules/angular2/src/core/compiler/private_component_loader.js b/modules/angular2/src/core/compiler/private_component_loader.js
index 7bb69157ab..49da82bd18 100644
--- a/modules/angular2/src/core/compiler/private_component_loader.js
+++ b/modules/angular2/src/core/compiler/private_component_loader.js
@@ -1,7 +1,6 @@
 import {Compiler} from './compiler';
-import {ShadowDomStrategy} from './shadow_dom_strategy';
+import {ViewFactory} from './view_factory';
 import {Injectable} from 'angular2/di';
-import {EventManager} from 'angular2/src/render/dom/events/event_manager';
 import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
 import {Component} from 'angular2/src/core/annotations/annotations';
 import {PrivateComponentLocation} from './private_component_location';
@@ -11,17 +10,14 @@ import {Type, stringify, BaseException} from 'angular2/src/facade/lang';
 @Injectable()
 export class PrivateComponentLoader {
   compiler:Compiler;
-  shadowDomStrategy:ShadowDomStrategy;
-  eventManager:EventManager;
   directiveMetadataReader:DirectiveMetadataReader;
+  viewFactory:ViewFactory;
 
-  constructor(compiler:Compiler, shadowDomStrategy:ShadowDomStrategy,
-              eventManager:EventManager, directiveMetadataReader:DirectiveMetadataReader) {
+  constructor(compiler:Compiler, directiveMetadataReader:DirectiveMetadataReader, viewFactory:ViewFactory) {
 
     this.compiler = compiler;
-    this.shadowDomStrategy = shadowDomStrategy;
-    this.eventManager = eventManager;
     this.directiveMetadataReader = directiveMetadataReader;
+    this.viewFactory = viewFactory;
   }
 
   load(type:Type, location:PrivateComponentLocation) {
@@ -33,10 +29,10 @@ export class PrivateComponentLoader {
 
     return this.compiler.compile(type).then((componentProtoView) => {
       location.createComponent(
+        this.viewFactory,
         type, annotation,
-        componentProtoView,
-        this.eventManager,
-        this.shadowDomStrategy);
+        componentProtoView
+      );
     });
   }
 }
diff --git a/modules/angular2/src/core/compiler/private_component_location.js b/modules/angular2/src/core/compiler/private_component_location.js
index 86b7c01ff6..e8282be9da 100644
--- a/modules/angular2/src/core/compiler/private_component_location.js
+++ b/modules/angular2/src/core/compiler/private_component_location.js
@@ -1,33 +1,28 @@
 import {Directive} from 'angular2/src/core/annotations/annotations'
-import {NgElement} from 'angular2/src/core/dom/element';
 import * as viewModule from './view';
 import * as eiModule from './element_injector';
-import {ShadowDomStrategy} from './shadow_dom_strategy';
-import {EventManager} from 'angular2/src/render/dom/events/event_manager';
 import {ListWrapper} from 'angular2/src/facade/collection';
 import {Type} from 'angular2/src/facade/lang';
-
+import * as vfModule from './view_factory';
 
 export class PrivateComponentLocation {
   _elementInjector:eiModule.ElementInjector;
-  _elt:NgElement;
   _view:viewModule.View;
 
-  constructor(elementInjector:eiModule.ElementInjector, elt:NgElement, view:viewModule.View){
+  constructor(elementInjector:eiModule.ElementInjector, view:viewModule.View){
     this._elementInjector = elementInjector;
-    this._elt = elt;
     this._view = view;
   }
 
-  createComponent(type:Type, annotation:Directive, componentProtoView:viewModule.ProtoView,
-                  eventManager:EventManager, shadowDomStrategy:ShadowDomStrategy) {
+  createComponent(viewFactory: vfModule.ViewFactory, type:Type, annotation:Directive, componentProtoView:viewModule.ProtoView) {
     var context = this._elementInjector.createPrivateComponent(type, annotation);
 
-    var view = componentProtoView.instantiate(this._elementInjector, eventManager);
-    view.hydrate(this._elementInjector.getShadowDomAppInjector(), this._elementInjector, null, context, null);
-
-    shadowDomStrategy.attachTemplate(this._elt.domElement, view);
+    var view = viewFactory.getView(componentProtoView);
+    view.hydrate(this._elementInjector.getShadowDomAppInjector(), this._elementInjector, context, null);
 
+    this._view.proto.renderer.setDynamicComponentView(
+      this._view.render, this._elementInjector.getBoundElementIndex(), view.render
+    );
     ListWrapper.push(this._view.componentChildViews, view);
     this._view.changeDetector.addChild(view.changeDetector);
   }
diff --git a/modules/angular2/src/core/compiler/proto_view_factory.js b/modules/angular2/src/core/compiler/proto_view_factory.js
index 9a843ff7d0..a7a4a3ecdc 100644
--- a/modules/angular2/src/core/compiler/proto_view_factory.js
+++ b/modules/angular2/src/core/compiler/proto_view_factory.js
@@ -1,23 +1,23 @@
+import {Injectable} from 'angular2/di';
 import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
 import {isPresent, isBlank} from 'angular2/src/facade/lang';
 import {reflector} from 'angular2/src/reflection/reflection';
 
 import {ChangeDetection} from 'angular2/change_detection';
-import {ShadowDomStrategy} from './shadow_dom_strategy';
 import {Component, Viewport, DynamicComponent} from '../annotations/annotations';
 
 import * as renderApi from 'angular2/src/render/api';
-import {DirectDomProtoViewRef} from 'angular2/src/render/dom/direct_dom_renderer';
 import {ProtoView} from './view';
 import {ProtoElementInjector, DirectiveBinding} from './element_injector';
 
+@Injectable()
 export class ProtoViewFactory {
   _changeDetection:ChangeDetection;
-  _shadowDomStrategy:ShadowDomStrategy;
+  _renderer:renderApi.Renderer;
 
-  constructor(changeDetection, shadowDomStrategy) {
+  constructor(changeDetection:ChangeDetection, renderer:renderApi.Renderer) {
     this._changeDetection = changeDetection;
-    this._shadowDomStrategy = shadowDomStrategy;
+    this._renderer = renderer;
   }
 
   createProtoView(componentBinding:DirectiveBinding, renderProtoView: renderApi.ProtoView, directives:List<DirectiveBinding>):ProtoView {
@@ -30,13 +30,10 @@ export class ProtoViewFactory {
         'dummy', componentAnnotation.changeDetection
       );
     }
-    var domProtoView = this._getDomProtoView(renderProtoView.render);
-    var protoView = new ProtoView(renderProtoView.render, domProtoView.element, protoChangeDetector,
-        this._shadowDomStrategy, null);
+    var protoView = new ProtoView(this._renderer, renderProtoView.render, protoChangeDetector);
 
     for (var i=0; i<renderProtoView.elementBinders.length; i++) {
       var renderElementBinder = renderProtoView.elementBinders[i];
-      var domElementBinder = domProtoView.elementBinders[i];
       var sortedDirectives = new SortedDirectives(renderElementBinder.directives, directives);
       var parentPeiWithDistance = this._findParentProtoElementInjectorWithDistance(
         i, protoView.elementBinders, renderProtoView.elementBinders
@@ -46,7 +43,7 @@ export class ProtoViewFactory {
         sortedDirectives, renderElementBinder
       );
       this._createElementBinder(
-        protoView, renderElementBinder, domElementBinder, protoElementInjector, sortedDirectives
+        protoView, renderElementBinder, protoElementInjector, sortedDirectives
       );
       this._createDirectiveBinders(protoView, sortedDirectives);
     }
@@ -56,11 +53,6 @@ export class ProtoViewFactory {
     return protoView;
   }
 
-  // This method is needed to make DartAnalyzer happy
-  _getDomProtoView(protoViewRef: DirectDomProtoViewRef) {
-    return protoViewRef.delegate;
-  }
-
   _findParentProtoElementInjectorWithDistance(binderIndex, elementBinders, renderElementBinders) {
     var distance = 0;
     do {
@@ -105,7 +97,7 @@ export class ProtoViewFactory {
     return protoElementInjector;
   }
 
-  _createElementBinder(protoView, renderElementBinder, domElementBinder, protoElementInjector, sortedDirectives) {
+  _createElementBinder(protoView, renderElementBinder, protoElementInjector, sortedDirectives) {
     var parent = null;
     if (renderElementBinder.parentIndex !== -1) {
       parent = protoView.elementBinders[renderElementBinder.parentIndex];
@@ -117,14 +109,13 @@ export class ProtoViewFactory {
       sortedDirectives.componentDirective,
       sortedDirectives.viewportDirective
     );
-    elBinder.contentTagSelector = domElementBinder.contentTagSelector;
     // text nodes
     for (var i=0; i<renderElementBinder.textBindings.length; i++) {
-      protoView.bindTextNode(domElementBinder.textNodeIndices[i], renderElementBinder.textBindings[i].ast);
+      protoView.bindTextNode(renderElementBinder.textBindings[i].ast);
     }
     // element properties
     MapWrapper.forEach(renderElementBinder.propertyBindings, (astWithSource, propertyName) => {
-      protoView.bindElementProperty(astWithSource.ast, propertyName, MapWrapper.get(domElementBinder.propertySetters, propertyName));
+      protoView.bindElementProperty(astWithSource.ast, propertyName);
     });
     // events
     MapWrapper.forEach(renderElementBinder.eventBindings, (astWithSource, eventName) => {
diff --git a/modules/angular2/src/core/compiler/shadow_dom_emulation/content_tag.js b/modules/angular2/src/core/compiler/shadow_dom_emulation/content_tag.js
deleted file mode 100644
index 0cb1210176..0000000000
--- a/modules/angular2/src/core/compiler/shadow_dom_emulation/content_tag.js
+++ /dev/null
@@ -1,88 +0,0 @@
-import * as ldModule from './light_dom';
-import {Inject, Injectable} from 'angular2/di';
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {isPresent} from 'angular2/src/facade/lang';
-import {List, ListWrapper} from 'angular2/src/facade/collection';
-
-class ContentStrategy {
-  nodes:List;
-  insert(nodes:List){}
-}
-
-/**
- * An implementation of the content tag that is used by transcluding components.
- * It is used when the content tag is not a direct child of another component,
- * and thus does not affect redistribution.
- */
-@Injectable()
-class RenderedContent extends ContentStrategy {
-  beginScript;
-  endScript;
-
-  constructor(contentEl) {
-    super();
-    this.beginScript = contentEl;
-    this.endScript = DOM.nextSibling(this.beginScript);
-    this.nodes = [];
-  }
-
-  // Inserts the nodes in between the start and end scripts.
-  // Previous content is removed.
-  insert(nodes:List) {
-    this.nodes = nodes;
-    DOM.insertAllBefore(this.endScript, nodes);
-    this._removeNodesUntil(ListWrapper.isEmpty(nodes) ? this.endScript : nodes[0]);
-  }
-
-  _removeNodesUntil(node) {
-    var p = DOM.parentElement(this.beginScript);
-    for (var next = DOM.nextSibling(this.beginScript);
-         next !== node;
-         next = DOM.nextSibling(this.beginScript)) {
-      DOM.removeChild(p, next);
-    }
-  }
-}
-
-/**
- * An implementation of the content tag that is used by transcluding components.
- * It is used when the content tag is a direct child of another component,
- * and thus does not get rendered but only affect the distribution of its parent component.
- */
-class IntermediateContent extends ContentStrategy {
-  destinationLightDom:ldModule.LightDom;
-
-  constructor(destinationLightDom:ldModule.LightDom) {
-    super();
-    this.destinationLightDom = destinationLightDom;
-    this.nodes = [];
-  }
-
-  insert(nodes:List) {
-    this.nodes = nodes;
-    this.destinationLightDom.redistribute();
-  }
-}
-
-
-export class Content {
-  select:string;
-  _strategy:ContentStrategy;
-  contentStartElement;
-
-  constructor(destinationLightDom:ldModule.LightDom, contentStartEl, selector:string) {
-    this.select = selector;
-    this.contentStartElement = contentStartEl;
-    this._strategy = isPresent(destinationLightDom) ?
-      new IntermediateContent(destinationLightDom) :
-      new RenderedContent(contentStartEl);
-  }
-
-  nodes():List {
-    return this._strategy.nodes;
-  }
-
-  insert(nodes:List) {
-    this._strategy.insert(nodes);
-  }
-}
diff --git a/modules/angular2/src/core/compiler/shadow_dom_emulation/light_dom.js b/modules/angular2/src/core/compiler/shadow_dom_emulation/light_dom.js
deleted file mode 100644
index 82a915ae4e..0000000000
--- a/modules/angular2/src/core/compiler/shadow_dom_emulation/light_dom.js
+++ /dev/null
@@ -1,140 +0,0 @@
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {List, ListWrapper} from 'angular2/src/facade/collection';
-import {isBlank, isPresent} from 'angular2/src/facade/lang';
-
-import * as viewModule from '../view';
-import {Content} from './content_tag';
-
-export class DestinationLightDom {}
-
-
-class _Root {
-  node;
-  viewContainer;
-  content;
-
-  constructor(node, viewContainer, content) {
-    this.node = node;
-    this.viewContainer = viewContainer;
-    this.content = content;
-  }
-}
-
-// TODO: LightDom should implement DestinationLightDom
-// once interfaces are supported
-export class LightDom {
-  // The light DOM of the element is enclosed inside the lightDomView
-  lightDomView:viewModule.View;
-  // The shadow DOM
-  shadowDomView:viewModule.View;
-  // The nodes of the light DOM
-  nodes:List;
-  roots:List<_Root>;
-
-  constructor(lightDomView:viewModule.View, shadowDomView:viewModule.View, element) {
-    this.lightDomView = lightDomView;
-    this.shadowDomView = shadowDomView;
-    this.nodes = DOM.childNodesAsList(element);
-
-    this.roots = null;
-  }
-
-  redistribute() {
-    var tags = this.contentTags();
-    if (tags.length > 0) {
-      redistributeNodes(tags, this.expandedDomNodes());
-    }
-  }
-
-  contentTags(): List<Content> {
-    return this._collectAllContentTags(this.shadowDomView, []);
-  }
-
-  // Collects the Content directives from the view and all its child views
-  _collectAllContentTags(view: viewModule.View, acc:List<Content>):List<Content> {
-    var contentTags = view.contentTags;
-    var vcs = view.viewContainers;
-    for (var i=0; i<vcs.length; i++) {
-      var vc = vcs[i];
-      var contentTag = contentTags[i];
-      if (isPresent(contentTag)) {
-        ListWrapper.push(acc, contentTag);  
-      }
-      if (isPresent(vc)) {
-        ListWrapper.forEach(vc.contentTagContainers(), (view) => {
-          this._collectAllContentTags(view, acc);
-        });              
-      }
-    }
-    return acc;
-  }
-
-  // Collects the nodes of the light DOM by merging:
-  // - nodes from enclosed ViewContainers,
-  // - nodes from enclosed content tags,
-  // - plain DOM nodes
-  expandedDomNodes():List {
-    var res = [];
-    
-    var roots = this._roots();
-    for (var i = 0; i < roots.length; ++i) {
-
-      var root = roots[i];
-
-      if (isPresent(root.viewContainer)) {
-        res = ListWrapper.concat(res, root.viewContainer.nodes());
-      } else if (isPresent(root.content)) {
-        res = ListWrapper.concat(res, root.content.nodes());
-      } else {
-        ListWrapper.push(res, root.node);
-      }
-    }
-    return res;
-  }
-
-  // Returns a list of Roots for all the nodes of the light DOM.
-  // The Root object contains the DOM node and its corresponding injector (could be null).
-  _roots() {
-    if (isPresent(this.roots)) return this.roots;
-
-    var viewContainers = this.lightDomView.viewContainers;
-    var contentTags = this.lightDomView.contentTags;
-
-    this.roots = ListWrapper.map(this.nodes, (n) => {
-      var foundVc = null;
-      var foundContentTag = null;
-      for (var i=0; i<viewContainers.length; i++) {
-        var vc = viewContainers[i];
-        var contentTag = contentTags[i];
-        if (isPresent(vc) && vc.templateElement === n) {
-          foundVc = vc;
-        }
-        if (isPresent(contentTag) && contentTag.contentStartElement === n) {
-          foundContentTag = contentTag;
-        }
-      }
-      return new _Root(n, foundVc, foundContentTag);
-    });
-
-    return this.roots;
-  }
-}
-
-// Projects the light DOM into the shadow DOM
-function redistributeNodes(contents:List<Content>, nodes:List) {
-  for (var i = 0; i < contents.length; ++i) {
-    var content = contents[i];
-    var select = content.select;
-    var matchSelector = (n) => DOM.elementMatches(n, select);
-
-    // Empty selector is identical to <content/>
-    if (select.length === 0) {
-      content.insert(nodes);
-      ListWrapper.clear(nodes);
-    } else {
-      var matchingNodes = ListWrapper.filter(nodes, matchSelector);
-      content.insert(matchingNodes);
-      ListWrapper.removeAll(nodes, matchingNodes);
-    }
-  }
-}
diff --git a/modules/angular2/src/core/compiler/shadow_dom_strategy.js b/modules/angular2/src/core/compiler/shadow_dom_strategy.js
deleted file mode 100644
index 72cca0a9a6..0000000000
--- a/modules/angular2/src/core/compiler/shadow_dom_strategy.js
+++ /dev/null
@@ -1,114 +0,0 @@
-import {Injectable} from 'angular2/di';
-
-import {stringify} from 'angular2/src/facade/lang';
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import * as viewModule from './view';
-import {LightDom} from './shadow_dom_emulation/light_dom';
-import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
-import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
-
-// temporal import while we migrated the views over
-import * as sds from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
-import * as nsds from 'angular2/src/render/dom/shadow_dom/native_shadow_dom_strategy';
-import * as eusds from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
-import * as essds from 'angular2/src/render/dom/shadow_dom/emulated_scoped_shadow_dom_strategy';
-
-/**
- * @publicModule angular2/template
- */
-export class ShadowDomStrategy {
-  render: sds.ShadowDomStrategy;
-
-  attachTemplate(el, view:viewModule.View) {}
-  constructLightDom(lightDomView:viewModule.View, shadowDomView:viewModule.View, el): LightDom { return null; }
-
-  shimAppElement(componentType, insertionElement) {
-    this.render.processElement(null, stringify(componentType), insertionElement);
-  }
-}
-
-/**
- * This strategy emulates the Shadow DOM for the templates, styles **excluded**:
- * - components templates are added as children of their component element,
- * - styles are moved from the templates to the styleHost (i.e. the document head).
- *
- * Notes:
- * - styles are **not** scoped to their component and will apply to the whole document,
- * - you can **not** use shadow DOM specific selectors in the styles
- *
- * @publicModule angular2/template
- */
-@Injectable()
-export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
-
-  constructor(styleUrlResolver: StyleUrlResolver, styleHost) {
-    super();
-    this.render = new eusds.EmulatedUnscopedShadowDomStrategy(styleUrlResolver, styleHost);
-  }
-
-  attachTemplate(el, view:viewModule.View) {
-    DOM.clearNodes(el);
-    _moveViewNodesIntoParent(el, view);
-  }
-
-  constructLightDom(lightDomView:viewModule.View, shadowDomView:viewModule.View, el): LightDom {
-    return new LightDom(lightDomView, shadowDomView, el);
-  }
-}
-
-/**
- * This strategy emulates the Shadow DOM for the templates, styles **included**:
- * - components templates are added as children of their component element,
- * - both the template and the styles are modified so that styles are scoped to the component
- *   they belong to,
- * - styles are moved from the templates to the styleHost (i.e. the document head).
- *
- * Notes:
- * - styles are scoped to their component and will apply only to it,
- * - a common subset of shadow DOM selectors are supported,
- * - see `ShadowCss` for more information and limitations.
- *
- * @publicModule angular2/template
- */
-@Injectable()
-export class EmulatedScopedShadowDomStrategy extends ShadowDomStrategy {
-
-  constructor(styleInliner: StyleInliner, styleUrlResolver: StyleUrlResolver, styleHost) {
-    super();
-    this.render = new essds.EmulatedScopedShadowDomStrategy(styleInliner, styleUrlResolver, styleHost);
-  }
-
-  attachTemplate(el, view:viewModule.View) {
-    DOM.clearNodes(el);
-    _moveViewNodesIntoParent(el, view);
-  }
-
-  constructLightDom(lightDomView:viewModule.View, shadowDomView:viewModule.View, el): LightDom {
-    return new LightDom(lightDomView, shadowDomView, el);
-  }
-}
-
-/**
- * This strategies uses the native Shadow DOM support.
- *
- * The templates for the component are inserted in a Shadow Root created on the component element.
- * Hence they are strictly isolated.
- */
-@Injectable()
-export class NativeShadowDomStrategy extends ShadowDomStrategy {
-
-  constructor(styleUrlResolver: StyleUrlResolver) {
-    super();
-    this.render = new nsds.NativeShadowDomStrategy(styleUrlResolver);
-  }
-
-  attachTemplate(el, view:viewModule.View){
-    _moveViewNodesIntoParent(DOM.createShadowRoot(el), view);
-  }
-}
-
-function _moveViewNodesIntoParent(parent, view) {
-  for (var i = 0; i < view.nodes.length; ++i) {
-    DOM.appendChild(parent, view.nodes[i]);
-  }
-}
diff --git a/modules/angular2/src/core/compiler/view.js b/modules/angular2/src/core/compiler/view.js
index 436d0e1941..daefe68cee 100644
--- a/modules/angular2/src/core/compiler/view.js
+++ b/modules/angular2/src/core/compiler/view.js
@@ -1,5 +1,3 @@
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {Promise} from 'angular2/src/facade/async';
 import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
 import {AST, Locals, ChangeDispatcher, ProtoChangeDetector, ChangeDetector,
   ChangeRecord, BindingRecord, BindingPropagationConfig, uninitialized} from 'angular2/change_detection';
@@ -9,76 +7,51 @@ import {ElementBinder} from './element_binder';
 import {SetterFn} from 'angular2/src/reflection/types';
 import {IMPLEMENTS, int, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
 import {Injector} from 'angular2/di';
-import {NgElement} from 'angular2/src/core/dom/element';
 import {ViewContainer} from './view_container';
-import {LightDom} from './shadow_dom_emulation/light_dom';
-import {Content} from './shadow_dom_emulation/content_tag';
-import {ShadowDomStrategy} from './shadow_dom_strategy';
-import {ViewPool} from './view_pool';
-import {EventManager} from 'angular2/src/render/dom/events/event_manager';
 import * as renderApi from 'angular2/src/render/api';
 
-const NG_BINDING_CLASS = 'ng-binding';
-const NG_BINDING_CLASS_SELECTOR = '.ng-binding';
-
-// TODO(rado): make this configurable/smarter.
-var VIEW_POOL_CAPACITY = 10000;
-var VIEW_POOL_PREFILL = 0;
-
 /**
  * Const of making objects: http://jsperf.com/instantiate-size-of-object
  *
  * @publicModule angular2/template
  */
 @IMPLEMENTS(ChangeDispatcher)
+// TODO(tbosch): this is not supported in dart2js (no '.' is allowed)
+// @IMPLEMENTS(renderApi.EventDispatcher)
 export class View {
+  render:renderApi.ViewRef;
   /// This list matches the _nodes list. It is sparse, since only Elements have ElementInjector
   rootElementInjectors:List<ElementInjector>;
   elementInjectors:List<ElementInjector>;
-  bindElements:List;
-  textNodes:List;
   changeDetector:ChangeDetector;
-  /// When the view is part of render tree, the DocumentFragment is empty, which is why we need
-  /// to keep track of the nodes.
-  nodes:List;
   componentChildViews: List<View>;
   viewContainers: List<ViewContainer>;
-  contentTags: List<Content>;
   preBuiltObjects: List<PreBuiltObjects>;
-  lightDoms: List<LightDom>;
   proto: ProtoView;
   context: any;
   locals:Locals;
 
-  constructor(proto:ProtoView, nodes:List, protoLocals:Map) {
+  constructor(proto:ProtoView, protoLocals:Map) {
+    this.render = null;
     this.proto = proto;
-    this.nodes = nodes;
     this.changeDetector = null;
     this.elementInjectors = null;
     this.rootElementInjectors = null;
-    this.textNodes = null;
-    this.bindElements = null;
     this.componentChildViews = null;
     this.viewContainers = null;
-    this.contentTags = null;
     this.preBuiltObjects = null;
-    this.lightDoms = null;
     this.context = null;
     this.locals = new Locals(null, MapWrapper.clone(protoLocals)); //TODO optimize this
   }
 
-  init(changeDetector:ChangeDetector, elementInjectors:List, rootElementInjectors:List, textNodes: List, bindElements:List,
-    viewContainers:List, contentTags:List, preBuiltObjects:List, componentChildViews:List, lightDoms:List<LightDom>) {
+  init(changeDetector:ChangeDetector, elementInjectors:List, rootElementInjectors:List,
+      viewContainers:List, preBuiltObjects:List, componentChildViews:List) {
     this.changeDetector = changeDetector;
     this.elementInjectors = elementInjectors;
     this.rootElementInjectors = rootElementInjectors;
-    this.textNodes = textNodes;
-    this.bindElements = bindElements;
     this.viewContainers = viewContainers;
-    this.contentTags = contentTags;
     this.preBuiltObjects = preBuiltObjects;
     this.componentChildViews = componentChildViews;
-    this.lightDoms = lightDoms;
   }
 
   setLocal(contextName: string, value) {
@@ -124,16 +97,33 @@ export class View {
    * A call to hydrate/dehydrate does not attach/detach the view from the view
    * tree.
    */
-  hydrate(appInjector: Injector, hostElementInjector: ElementInjector, hostLightDom: LightDom,
+  hydrate(appInjector: Injector, hostElementInjector: ElementInjector,
       context: Object, locals:Locals) {
+    var renderComponentViewRefs = this.proto.renderer.createView(this.proto.render);
+    this.internalHydrateRecurse(renderComponentViewRefs, 0, appInjector, hostElementInjector, context, locals);
+  }
+
+  dehydrate() {
+    var render = this.render;
+    this.internalDehydrateRecurse();
+    this.proto.renderer.destroyView(render);
+  }
+
+  internalHydrateRecurse(
+      renderComponentViewRefs:List<renderApi.ViewRef>,
+      renderComponentIndex:number,
+      appInjector: Injector, hostElementInjector: ElementInjector,
+      context: Object, locals:Locals):number {
     if (this.hydrated()) throw new BaseException('The view is already hydrated.');
+
+    this.render = renderComponentViewRefs[renderComponentIndex++];
     this._hydrateContext(context, locals);
 
     // viewContainers
     for (var i = 0; i < this.viewContainers.length; i++) {
       var vc = this.viewContainers[i];
       if (isPresent(vc)) {
-        vc.hydrate(appInjector, hostElementInjector, hostLightDom);
+        vc.internalHydrateRecurse(new renderApi.ViewContainerRef(this.render, i), appInjector, hostElementInjector);
       }
     }
 
@@ -158,7 +148,7 @@ export class View {
       // elementInjectors
       var elementInjector = this.elementInjectors[i];
       if (isPresent(elementInjector)) {
-        elementInjector.instantiateDirectives(appInjector, shadowDomAppInjector, this.preBuiltObjects[i]);
+        elementInjector.instantiateDirectives(appInjector, hostElementInjector, shadowDomAppInjector, this.preBuiltObjects[i]);
 
         // The exporting of $implicit is a special case. Since multiple elements will all export
         // the different values as $implicit, directly assign $implicit bindings to the variable
@@ -167,30 +157,32 @@ export class View {
         if (elementInjector.isExportingComponent()) {
           this.locals.set(exportImplicitName, elementInjector.getComponent());
         } else if (elementInjector.isExportingElement()) {
-          this.locals.set(exportImplicitName, elementInjector.getNgElement().domElement);
+          this.locals.set(exportImplicitName, elementInjector.getNgElement());
         }
       }
 
       if (isPresent(binders[i].nestedProtoView) && isPresent(componentDirective)) {
-        this.componentChildViews[componentChildViewIndex++].hydrate(shadowDomAppInjector,
-          elementInjector, this.lightDoms[i], elementInjector.getComponent(), null);
-      }
-    }
-
-    for (var i = 0; i < this.lightDoms.length; ++i) {
-      var lightDom = this.lightDoms[i];
-      if (isPresent(lightDom)) {
-        lightDom.redistribute();
+        renderComponentIndex = this.componentChildViews[componentChildViewIndex].internalHydrateRecurse(
+          renderComponentViewRefs,
+          renderComponentIndex,
+          shadowDomAppInjector,
+          elementInjector,
+          elementInjector.getComponent(),
+          null
+        );
+        componentChildViewIndex++;
       }
     }
+    this.proto.renderer.setEventDispatcher(this.render, this);
+    return renderComponentIndex;
   }
 
-  dehydrate() {
+  internalDehydrateRecurse() {
     // Note: preserve the opposite order of the hydration process.
 
     // componentChildViews
     for (var i = 0; i < this.componentChildViews.length; i++) {
-      this.componentChildViews[i].dehydrate();
+      this.componentChildViews[i].internalDehydrateRecurse();
     }
 
     // elementInjectors
@@ -205,11 +197,13 @@ export class View {
       for (var i = 0; i < this.viewContainers.length; i++) {
         var vc = this.viewContainers[i];
         if (isPresent(vc)) {
-          vc.dehydrate();
+          vc.internalDehydrateRecurse();
         }
       }
     }
 
+    this.render = null;
+
     this._dehydrateContext();
   }
 
@@ -223,11 +217,9 @@ export class View {
    * @param {int} binderIndex
    */
   triggerEventHandlers(eventName: string, eventObj, binderIndex: int) {
-    var handlers = this.proto.eventHandlers[binderIndex];
-    if (isBlank(handlers)) return;
-    var handler = StringMapWrapper.get(handlers, eventName);
-    if (isBlank(handler)) return;
-    handler(eventObj, this);
+    var locals = MapWrapper.create();
+    MapWrapper.set(locals, '$event', eventObj);
+    this.dispatchEvent(binderIndex, eventName, locals);
   }
 
   onAllChangesDone(directiveMemento:DirectiveMemento) {
@@ -245,15 +237,39 @@ export class View {
     if (memento instanceof DirectiveBindingMemento) {
       var directiveMemento:DirectiveBindingMemento = memento;
       directiveMemento.invoke(currentValue, this.elementInjectors);
-
     } else if (memento instanceof ElementBindingMemento) {
       var elementMemento:ElementBindingMemento = memento;
-      elementMemento.invoke(currentValue, this.bindElements);
-
+      this.proto.renderer.setElementProperty(
+        this.render, elementMemento.elementIndex, elementMemento.propertyName, currentValue
+      );
     } else {
       // we know it refers to _textNodes.
       var textNodeIndex:number = memento;
-      DOM.setText(this.textNodes[textNodeIndex], currentValue);
+      this.proto.renderer.setText(this.render, textNodeIndex, currentValue);
+    }
+  }
+
+  // implementation of EventDispatcher#dispatchEvent
+  dispatchEvent(
+    elementIndex:number, eventName:string, locals:Map<string, any>
+  ):void {
+    // Most of the time the event will be fired only when the view is in the live document.
+    // However, in a rare circumstance the view might get dehydrated, in between the event
+    // queuing up and firing.
+    if (this.hydrated()) {
+      var elBinder = this.proto.elementBinders[elementIndex];
+      if (isBlank(elBinder.events)) return;
+      var eventMap = elBinder.events[eventName];
+      if (isBlank(eventName)) return;
+      MapWrapper.forEach(eventMap, (expr, directiveIndex) => {
+        var context;
+        if (directiveIndex === -1) {
+          context = this.context;
+        } else {
+          context = this.elementInjectors[elementIndex].getDirectiveAtIndex(directiveIndex);
+        }
+        expr.eval(context, new Locals(this.locals, locals));
+      });
     }
   }
 }
@@ -263,21 +279,11 @@ export class View {
  * @publicModule angular2/template
  */
 export class ProtoView {
-  element;
   elementBinders:List<ElementBinder>;
   protoChangeDetector:ProtoChangeDetector;
   variableBindings: Map;
   protoLocals:Map;
   textNodesWithBindingCount:int;
-  elementsWithBindingCount:int;
-  instantiateInPlace:boolean;
-  rootBindingOffset:int;
-  isTemplateElement:boolean;
-  shadowDomStrategy: ShadowDomStrategy;
-  _viewPool: ViewPool;
-  stylePromises: List<Promise>;
-  // List<Map<eventName, handler>>, indexed by binder index
-  eventHandlers:List;
   bindingRecords:List;
   parentProtoView:ProtoView;
   _variableBindings:List;
@@ -285,58 +291,36 @@ export class ProtoView {
   _directiveMementosMap:Map;
   _directiveMementos:List;
   render:renderApi.ProtoViewRef;
+  renderer:renderApi.Renderer;
 
   constructor(
+      renderer:renderApi.Renderer,
       render:renderApi.ProtoViewRef,
-      template,
-      protoChangeDetector:ProtoChangeDetector,
-      shadowDomStrategy:ShadowDomStrategy, parentProtoView:ProtoView = null) {
+      protoChangeDetector:ProtoChangeDetector) {
+    this.renderer = renderer;
     this.render = render;
-    this.element = template;
     this.elementBinders = [];
     this.variableBindings = MapWrapper.create();
     this.protoLocals = MapWrapper.create();
     this.protoChangeDetector = protoChangeDetector;
-    this.parentProtoView = parentProtoView;
+    this.parentProtoView = null;
     this.textNodesWithBindingCount = 0;
-    this.elementsWithBindingCount = 0;
-    this.instantiateInPlace = false;
-    this.rootBindingOffset = (isPresent(this.element) && DOM.hasClass(this.element, NG_BINDING_CLASS))
-      ? 1 : 0;
-    this.isTemplateElement = DOM.isTemplateElement(this.element);
-    this.shadowDomStrategy = shadowDomStrategy;
-    this._viewPool = new ViewPool(VIEW_POOL_CAPACITY);
-    this.stylePromises = [];
-    this.eventHandlers = [];
     this.bindingRecords = [];
     this._directiveMementosMap = MapWrapper.create();
     this._variableBindings = null;
     this._directiveMementos = null;
   }
 
-  // TODO(rado): hostElementInjector should be moved to hydrate phase.
-  instantiate(hostElementInjector: ElementInjector, eventManager: EventManager):View {
-    if (this._viewPool.length() == 0) this._preFillPool(hostElementInjector, eventManager);
-    var view = this._viewPool.pop();
-    return isPresent(view) ? view : this._instantiate(hostElementInjector, eventManager);
-  }
-
-  _preFillPool(hostElementInjector: ElementInjector, eventManager: EventManager) {
-    for (var i = 0; i < VIEW_POOL_PREFILL; i++) {
-      this._viewPool.push(this._instantiate(hostElementInjector, eventManager));
-    }
-  }
-
   //TODO: Tobias or Victor. Moving it into the constructor.
   // this work should be done the constructor of ProtoView once we separate
   // ProtoView and ProtoViewBuilder
-  _getVariableBindings() {
+  getVariableBindings() {
     if (isPresent(this._variableBindings)) {
       return this._variableBindings;
     }
 
     this._variableBindings = isPresent(this.parentProtoView) ?
-      ListWrapper.clone(this.parentProtoView._getVariableBindings()) : [];
+      ListWrapper.clone(this.parentProtoView.getVariableBindings()) : [];
 
     MapWrapper.forEach(this.protoLocals, (v, local) => {
       ListWrapper.push(this._variableBindings, local);
@@ -348,7 +332,7 @@ export class ProtoView {
   //TODO: Tobias or Victor. Moving it into the constructor.
   // this work should be done the constructor of ProtoView once we separate
   // ProtoView and ProtoViewBuilder
-  _getDirectiveMementos() {
+  getDirectiveMementos() {
     if (isPresent(this._directiveMementos)) {
       return this._directiveMementos;
     }
@@ -367,185 +351,6 @@ export class ProtoView {
     return this._directiveMementos;
   }
 
-  _instantiate(hostElementInjector: ElementInjector, eventManager: EventManager): View {
-    var rootElementClone = this.instantiateInPlace ? this.element : DOM.importIntoDoc(this.element);
-    var elementsWithBindingsDynamic;
-    if (this.isTemplateElement) {
-      elementsWithBindingsDynamic = DOM.querySelectorAll(DOM.content(rootElementClone), NG_BINDING_CLASS_SELECTOR);
-    } else {
-      elementsWithBindingsDynamic= DOM.getElementsByClassName(rootElementClone, NG_BINDING_CLASS);
-    }
-
-    var elementsWithBindings = ListWrapper.createFixedSize(elementsWithBindingsDynamic.length);
-    for (var binderIdx = 0; binderIdx < elementsWithBindingsDynamic.length; ++binderIdx) {
-      elementsWithBindings[binderIdx] = elementsWithBindingsDynamic[binderIdx];
-    }
-
-    var viewNodes;
-    if (this.isTemplateElement) {
-      var childNode = DOM.firstChild(DOM.content(rootElementClone));
-      viewNodes = []; // TODO(perf): Should be fixed size, since we could pre-compute in in ProtoView
-      // Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
-      while(childNode != null) {
-        ListWrapper.push(viewNodes, childNode);
-        childNode = DOM.nextSibling(childNode);
-      }
-    } else {
-      viewNodes = [rootElementClone];
-    }
-
-    var view = new View(this, viewNodes, this.protoLocals);
-    var changeDetector = this.protoChangeDetector.instantiate(view, this.bindingRecords,
-      this._getVariableBindings(), this._getDirectiveMementos());
-
-    var binders = this.elementBinders;
-    var elementInjectors = ListWrapper.createFixedSize(binders.length);
-    var eventHandlers = ListWrapper.createFixedSize(binders.length);
-    var rootElementInjectors = [];
-    var textNodes = [];
-    var elementsWithPropertyBindings = [];
-    var preBuiltObjects = ListWrapper.createFixedSize(binders.length);
-    var viewContainers = ListWrapper.createFixedSize(binders.length);
-    var contentTags = ListWrapper.createFixedSize(binders.length);
-    var componentChildViews = [];
-    var lightDoms = ListWrapper.createFixedSize(binders.length);
-
-    for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
-      var binder = binders[binderIdx];
-      var element;
-      if (binderIdx === 0 && this.rootBindingOffset === 1) {
-        element = rootElementClone;
-      } else {
-        element = elementsWithBindings[binderIdx - this.rootBindingOffset];
-      }
-      var elementInjector = null;
-
-      // elementInjectors and rootElementInjectors
-      var protoElementInjector = binder.protoElementInjector;
-      if (isPresent(protoElementInjector)) {
-        if (isPresent(protoElementInjector.parent)) {
-          var parentElementInjector = elementInjectors[protoElementInjector.parent.index];
-          elementInjector = protoElementInjector.instantiate(parentElementInjector, null);
-        } else {
-          elementInjector = protoElementInjector.instantiate(null, hostElementInjector);
-          ListWrapper.push(rootElementInjectors, elementInjector);
-        }
-      }
-      elementInjectors[binderIdx] = elementInjector;
-
-      if (binder.hasElementPropertyBindings) {
-        ListWrapper.push(elementsWithPropertyBindings, element);
-      }
-
-      // textNodes
-      var textNodeIndices = binder.textNodeIndices;
-      if (isPresent(textNodeIndices)) {
-        var childNode = DOM.firstChild(DOM.templateAwareRoot(element));
-        for (var j = 0, k = 0; j < textNodeIndices.length; j++) {
-          for(var index = textNodeIndices[j]; k < index; k++) {
-            childNode = DOM.nextSibling(childNode);
-          }
-          ListWrapper.push(textNodes, childNode);
-        }
-      }
-
-      // componentChildViews
-      var lightDom = null;
-      var bindingPropagationConfig = null;
-      if (isPresent(binder.nestedProtoView) && isPresent(binder.componentDirective)) {
-        var strategy = this.shadowDomStrategy;
-        var childView = binder.nestedProtoView.instantiate(elementInjector, eventManager);
-        changeDetector.addChild(childView.changeDetector);
-
-        lightDom = strategy.constructLightDom(view, childView, element);
-        strategy.attachTemplate(element, childView);
-
-        bindingPropagationConfig = new BindingPropagationConfig(childView.changeDetector);
-
-        ListWrapper.push(componentChildViews, childView);
-      }
-      lightDoms[binderIdx] = lightDom;
-
-      var destLightDom = null;
-      if (isPresent(binder.parent) && binder.distanceToParent === 1) {
-        destLightDom = lightDoms[binder.parent.index];
-      }
-
-      // viewContainers
-      var viewContainer = null;
-      if (isPresent(binder.viewportDirective)) {
-        viewContainer = new ViewContainer(view, element, binder.nestedProtoView, elementInjector,
-          eventManager, destLightDom);
-      }
-      viewContainers[binderIdx] = viewContainer;
-
-      // contentTags
-      var contentTag = null;
-      if (isPresent(binder.contentTagSelector)) {
-        contentTag = new Content(destLightDom, element, binder.contentTagSelector);
-      }
-      contentTags[binderIdx] = contentTag;
-
-      // preBuiltObjects
-      if (isPresent(elementInjector)) {
-        preBuiltObjects[binderIdx] = new PreBuiltObjects(view, new NgElement(element), viewContainer,
-          bindingPropagationConfig);
-      }
-
-      // events
-      if (isPresent(binder.events)) {
-        eventHandlers[binderIdx] = StringMapWrapper.create();
-        StringMapWrapper.forEach(binder.events, (eventMap, eventName) => {
-          var handler = ProtoView.buildEventHandler(eventMap, binderIdx);
-          StringMapWrapper.set(eventHandlers[binderIdx], eventName, handler);
-          if (isBlank(elementInjector) || !elementInjector.hasEventEmitter(eventName)) {
-            eventManager.addEventListener(element, eventName,
-              (event) => { handler(event, view); });
-          }
-        });
-      }
-    }
-
-    this.eventHandlers = eventHandlers;
-
-    view.init(changeDetector, elementInjectors, rootElementInjectors, textNodes, elementsWithPropertyBindings,
-      viewContainers, contentTags, preBuiltObjects, componentChildViews, lightDoms);
-
-    return view;
-  }
-
-  returnToPool(view: View) {
-    this._viewPool.push(view);
-  }
-
-  /**
-   * Creates an event handler.
-   *
-   * @param {Map} eventMap Map directiveIndexes to expressions
-   * @param {int} injectorIdx
-   * @returns {Function}
-   */
-  static buildEventHandler(eventMap: Map, injectorIdx: int) {
-    var locals = MapWrapper.create();
-    return (event, view) => {
-      // Most of the time the event will be fired only when the view is in the live document.
-      // However, in a rare circumstance the view might get dehydrated, in between the event
-      // queuing up and firing.
-      if (view.hydrated()) {
-        MapWrapper.set(locals, '$event', event);
-        MapWrapper.forEach(eventMap, (expr, directiveIndex) => {
-          var context;
-          if (directiveIndex === -1) {
-            context = view.context;
-          } else {
-            context = view.elementInjectors[injectorIdx].getDirectiveAtIndex(directiveIndex);
-          }
-          expr.eval(context, new Locals(view.locals, locals));
-        });
-      }
-    }
-  }
-
   bindVariable(contextName:string, templateName:string) {
     MapWrapper.set(this.variableBindings, contextName, templateName);
     MapWrapper.set(this.protoLocals, templateName, null);
@@ -562,12 +367,7 @@ export class ProtoView {
   /**
    * Adds a text node binding for the last created ElementBinder via bindElement
    */
-  bindTextNode(indexInParent:int, expression:AST) {
-    var elBinder = this.elementBinders[this.elementBinders.length-1];
-    if (isBlank(elBinder.textNodeIndices)) {
-      elBinder.textNodeIndices = ListWrapper.create();
-    }
-    ListWrapper.push(elBinder.textNodeIndices, indexInParent);
+  bindTextNode(expression:AST) {
     var memento = this.textNodesWithBindingCount++;
     ListWrapper.push(this.bindingRecords, new BindingRecord(expression, memento, null));
   }
@@ -575,13 +375,8 @@ export class ProtoView {
   /**
    * Adds an element property binding for the last created ElementBinder via bindElement
    */
-  bindElementProperty(expression:AST, setterName:string, setter:SetterFn) {
-    var elBinder = this.elementBinders[this.elementBinders.length-1];
-    if (!elBinder.hasElementPropertyBindings) {
-      elBinder.hasElementPropertyBindings = true;
-      this.elementsWithBindingCount++;
-    }
-    var memento = new ElementBindingMemento(this.elementsWithBindingCount-1, setter);
+  bindElementProperty(expression:AST, setterName:string) {
+    var memento = new ElementBindingMemento(this.elementBinders.length-1, setterName);
     ListWrapper.push(this.bindingRecords, new BindingRecord(expression, memento, null));
   }
 
@@ -651,16 +446,12 @@ export class ProtoView {
 /**
  */
 export class ElementBindingMemento {
-  _elementIndex:int;
-  _setter:SetterFn;
-  constructor(elementIndex:int, setter:SetterFn) {
-    this._elementIndex = elementIndex;
-    this._setter = setter;
-  }
+  elementIndex:int;
+  propertyName:string;
 
-  invoke(currentValue:any, bindElements:List) {
-    var element = bindElements[this._elementIndex];
-    this._setter(element, currentValue);
+  constructor(elementIndex:int, propertyName:string) {
+    this.elementIndex = elementIndex;
+    this.propertyName = propertyName;
   }
 }
 
diff --git a/modules/angular2/src/core/compiler/view_container.js b/modules/angular2/src/core/compiler/view_container.js
index 3d49624973..3d11a85c7f 100644
--- a/modules/angular2/src/core/compiler/view_container.js
+++ b/modules/angular2/src/core/compiler/view_container.js
@@ -1,59 +1,64 @@
-import * as viewModule from './view';
-import {DOM} from 'angular2/src/dom/dom_adapter';
 import {ListWrapper, MapWrapper, List} from 'angular2/src/facade/collection';
 import {BaseException} from 'angular2/src/facade/lang';
 import {Injector} from 'angular2/di';
 import * as eiModule from 'angular2/src/core/compiler/element_injector';
 import {isPresent, isBlank} from 'angular2/src/facade/lang';
-import {EventManager} from 'angular2/src/render/dom/events/event_manager';
-import {LightDom} from './shadow_dom_emulation/light_dom';
+
+import * as renderApi from 'angular2/src/render/api';
+import * as viewModule from './view';
+import * as vfModule from './view_factory';
 
 /**
  * @publicModule angular2/template
  */
 export class ViewContainer {
+  render:renderApi.ViewContainerRef;
+  viewFactory: vfModule.ViewFactory;
   parentView: viewModule.View;
-  templateElement;
   defaultProtoView: viewModule.ProtoView;
   _views: List<viewModule.View>;
-  _lightDom: LightDom;
-  _eventManager: EventManager;
   elementInjector: eiModule.ElementInjector;
   appInjector: Injector;
   hostElementInjector: eiModule.ElementInjector;
-  hostLightDom: LightDom;
 
-  constructor(parentView: viewModule.View,
-              templateElement,
+  constructor(viewFactory:vfModule.ViewFactory,
+              parentView: viewModule.View,
               defaultProtoView: viewModule.ProtoView,
-              elementInjector: eiModule.ElementInjector,
-              eventManager: EventManager,
-              lightDom = null) {
+              elementInjector: eiModule.ElementInjector) {
+    this.viewFactory = viewFactory;
+    this.render = null;
     this.parentView = parentView;
-    this.templateElement = templateElement;
     this.defaultProtoView = defaultProtoView;
     this.elementInjector = elementInjector;
-    this._lightDom = lightDom;
 
     // The order in this list matches the DOM order.
     this._views = [];
     this.appInjector = null;
     this.hostElementInjector = null;
-    this.hostLightDom = null;
-    this._eventManager = eventManager;
   }
 
-  hydrate(appInjector: Injector, hostElementInjector: eiModule.ElementInjector, hostLightDom: LightDom) {
+  internalHydrateRecurse(render:renderApi.ViewContainerRef, appInjector: Injector, hostElementInjector: eiModule.ElementInjector) {
+    this.render = render;
     this.appInjector = appInjector;
     this.hostElementInjector = hostElementInjector;
-    this.hostLightDom = hostLightDom;
   }
 
-  dehydrate() {
+  internalDehydrateRecurse() {
     this.appInjector = null;
     this.hostElementInjector = null;
-    this.hostLightDom = null;
-    this.clear();
+    this.render = null;
+    // Note: We don't call clear here,
+    // as we don't want to change the render side
+    // (i.e. don't deattach views on the render side),
+    // as the render side does its own recursion.
+    for (var i = this._views.length - 1; i >= 0; i--) {
+      var view = this._views[i];
+      view.changeDetector.remove();
+      this._unlinkElementInjectors(view);
+      view.internalDehydrateRecurse();
+      this.viewFactory.returnView(view);
+    }
+    this._views = [];
   }
 
   clear() {
@@ -70,11 +75,6 @@ export class ViewContainer {
     return this._views.length;
   }
 
-  _siblingToInsertAfter(index: number) {
-    if (index == 0) return this.templateElement;
-    return ListWrapper.last(this._views[index - 1].nodes);
-  }
-
   hydrated() {
     return isPresent(this.appInjector);
   }
@@ -84,28 +84,27 @@ export class ViewContainer {
   create(atIndex=-1): viewModule.View {
     if (!this.hydrated()) throw new BaseException(
         'Cannot create views on a dehydrated ViewContainer');
-    // TODO(rado): replace with viewFactory.
-    var newView = this.defaultProtoView.instantiate(this.hostElementInjector, this._eventManager);
+    var newView = this.viewFactory.getView(this.defaultProtoView);
     // insertion must come before hydration so that element injector trees are attached.
-    this.insert(newView, atIndex);
-    newView.hydrate(this.appInjector, this.hostElementInjector, this.hostLightDom,
+    this._insertWithoutRender(newView, atIndex);
+    // hydration must come before changing the render side,
+    // as it acquires the render views.
+    newView.hydrate(this.appInjector, this.hostElementInjector,
       this.parentView.context, this.parentView.locals);
+    this.defaultProtoView.renderer.insertViewIntoContainer(this.render, newView.render, atIndex);
 
-    // new content tags might have appeared, we need to redistrubute.
-    if (isPresent(this.hostLightDom)) {
-      this.hostLightDom.redistribute();
-    }
     return newView;
   }
 
   insert(view, atIndex=-1): viewModule.View {
+    this._insertWithoutRender(view, atIndex);
+    this.defaultProtoView.renderer.insertViewIntoContainer(this.render, view.render, atIndex);
+    return view;
+  }
+
+  _insertWithoutRender(view, atIndex=-1): viewModule.View {
     if (atIndex == -1) atIndex = this._views.length;
     ListWrapper.insert(this._views, atIndex, view);
-    if (isBlank(this._lightDom)) {
-      ViewContainer.moveViewNodesAfterSibling(this._siblingToInsertAfter(atIndex), view);
-    } else {
-      this._lightDom.redistribute();
-    }
     this.parentView.changeDetector.addChild(view.changeDetector);
     this._linkElementInjectors(view);
 
@@ -116,8 +115,7 @@ export class ViewContainer {
     if (atIndex == -1) atIndex = this._views.length - 1;
     var view = this.detach(atIndex);
     view.dehydrate();
-    // TODO(rado): this needs to be delayed until after any pending animations.
-    this.defaultProtoView.returnToPool(view);
+    this.viewFactory.returnView(view);
     // view is intentionally not returned to the client.
   }
 
@@ -129,32 +127,12 @@ export class ViewContainer {
     if (atIndex == -1) atIndex = this._views.length - 1;
     var detachedView = this.get(atIndex);
     ListWrapper.removeAt(this._views, atIndex);
-    if (isBlank(this._lightDom)) {
-      ViewContainer.removeViewNodes(detachedView);
-    } else {
-      this._lightDom.redistribute();
-    }
-    // content tags might have disappeared we need to do redistribution.
-    if (isPresent(this.hostLightDom)) {
-      this.hostLightDom.redistribute();
-    }
+    this.defaultProtoView.renderer.detachViewFromContainer(this.render, atIndex);
     detachedView.changeDetector.remove();
     this._unlinkElementInjectors(detachedView);
     return detachedView;
   }
 
-  contentTagContainers() {
-    return this._views;
-  }
-
-  nodes():List {
-    var r = [];
-    for (var i = 0; i < this._views.length; ++i) {
-      r = ListWrapper.concat(r, this._views[i].nodes);
-    }
-    return r;
-  }
-
   _linkElementInjectors(view) {
     for (var i = 0; i < view.rootElementInjectors.length; ++i) {
       view.rootElementInjectors[i].parent = this.elementInjector;
@@ -166,19 +144,4 @@ export class ViewContainer {
       view.rootElementInjectors[i].parent = null;
     }
   }
-
-  static moveViewNodesAfterSibling(sibling, view) {
-    for (var i = view.nodes.length - 1; i >= 0; --i) {
-      DOM.insertAfter(sibling, view.nodes[i]);
-    }
-  }
-
-  static removeViewNodes(view) {
-    var len = view.nodes.length;
-    if (len == 0) return;
-    var parent = view.nodes[0].parentNode;
-    for (var i = len - 1; i >= 0; --i) {
-      DOM.removeChild(parent, view.nodes[i]);
-    }
-  }
 }
diff --git a/modules/angular2/src/core/compiler/view_factory.js b/modules/angular2/src/core/compiler/view_factory.js
new file mode 100644
index 0000000000..083d7b02b8
--- /dev/null
+++ b/modules/angular2/src/core/compiler/view_factory.js
@@ -0,0 +1,109 @@
+import {Injectable, Inject, OpaqueToken} from 'angular2/di';
+import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
+import * as eli from './element_injector';
+import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
+import {NgElement} from 'angular2/src/core/compiler/ng_element';
+import * as vcModule from './view_container';
+import * as viewModule from './view';
+import {BindingPropagationConfig} from 'angular2/change_detection';
+
+// TODO(tbosch): Make this an OpaqueToken as soon as our transpiler supports this!
+export const VIEW_POOL_CAPACITY = 'ViewFactory.viewPoolCapacity';
+
+@Injectable()
+export class ViewFactory {
+  _poolCapacity:number;
+  _pooledViews:List<viewModule.View>;
+
+  constructor(@Inject(VIEW_POOL_CAPACITY) capacity) {
+    this._poolCapacity = capacity;
+    this._pooledViews = ListWrapper.create();
+  }
+
+  getView(protoView:viewModule.ProtoView):viewModule.View {
+    // TODO(tbosch): benchmark this scanning of views and maybe
+    // replace it with a fancy LRU Map/List combination...
+    var view;
+    for (var i=this._pooledViews.length-1; i>=0; i--) {
+      var pooledView = this._pooledViews[i];
+      if (pooledView.proto === protoView) {
+        view = ListWrapper.removeAt(this._pooledViews, i);
+      }
+    }
+    if (isBlank(view)) {
+      view = this._createView(protoView);
+    }
+    return view;
+  }
+
+  returnView(view:viewModule.View) {
+    if (view.hydrated()) {
+      throw new BaseException('Only dehydrated Views can be put back into the pool!');
+    }
+    ListWrapper.push(this._pooledViews, view);
+    while (this._pooledViews.length > this._poolCapacity) {
+      ListWrapper.removeAt(this._pooledViews, 0);
+    }
+  }
+
+  _createView(protoView:viewModule.ProtoView): viewModule.View {
+    var view = new viewModule.View(protoView, protoView.protoLocals);
+    var changeDetector = protoView.protoChangeDetector.instantiate(view, protoView.bindingRecords,
+      protoView.getVariableBindings(), protoView.getDirectiveMementos());
+
+    var binders = protoView.elementBinders;
+    var elementInjectors = ListWrapper.createFixedSize(binders.length);
+    var rootElementInjectors = [];
+    var preBuiltObjects = ListWrapper.createFixedSize(binders.length);
+    var viewContainers = ListWrapper.createFixedSize(binders.length);
+    var componentChildViews = [];
+
+    for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
+      var binder = binders[binderIdx];
+      var elementInjector = null;
+
+      // elementInjectors and rootElementInjectors
+      var protoElementInjector = binder.protoElementInjector;
+      if (isPresent(protoElementInjector)) {
+        if (isPresent(protoElementInjector.parent)) {
+          var parentElementInjector = elementInjectors[protoElementInjector.parent.index];
+          elementInjector = protoElementInjector.instantiate(parentElementInjector);
+        } else {
+          elementInjector = protoElementInjector.instantiate(null);
+          ListWrapper.push(rootElementInjectors, elementInjector);
+        }
+      }
+      elementInjectors[binderIdx] = elementInjector;
+
+      // componentChildViews
+      var bindingPropagationConfig = null;
+      if (isPresent(binder.nestedProtoView) && isPresent(binder.componentDirective)) {
+        var childView = this._createView(binder.nestedProtoView);
+        changeDetector.addChild(childView.changeDetector);
+
+        bindingPropagationConfig = new BindingPropagationConfig(childView.changeDetector);
+
+        ListWrapper.push(componentChildViews, childView);
+      }
+
+      // viewContainers
+      var viewContainer = null;
+      if (isPresent(binder.viewportDirective)) {
+        viewContainer = new vcModule.ViewContainer(this, view, binder.nestedProtoView, elementInjector);
+      }
+      viewContainers[binderIdx] = viewContainer;
+
+      // preBuiltObjects
+      if (isPresent(elementInjector)) {
+        preBuiltObjects[binderIdx] = new eli.PreBuiltObjects(view, new NgElement(view, binderIdx), viewContainer,
+          bindingPropagationConfig);
+      }
+    }
+
+    view.init(changeDetector, elementInjectors, rootElementInjectors,
+      viewContainers, preBuiltObjects, componentChildViews);
+
+    return view;
+  }
+
+}
\ No newline at end of file
diff --git a/modules/angular2/src/core/compiler/view_pool.js b/modules/angular2/src/core/compiler/view_pool.js
deleted file mode 100644
index ef6d42d67e..0000000000
--- a/modules/angular2/src/core/compiler/view_pool.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import {ListWrapper, MapWrapper, StringMapWrapper, List} from 'angular2/src/facade/collection';
-import * as viewModule from './view';
-
-export class ViewPool {
-  _views: List<viewModule.View>;
-  _capacity: number;
-  constructor(capacity: number) {
-    this._views = [];
-    this._capacity = capacity;
-  }
-
-  pop(): viewModule.View {
-    return ListWrapper.isEmpty(this._views) ? null : ListWrapper.removeLast(this._views);
-  }
-
-  push(view: viewModule.View) {
-    if (this._views.length < this._capacity) {
-      ListWrapper.push(this._views, view);
-    }
-  }
-
-  length() {
-    return this._views.length;
-  }
-}
-
diff --git a/modules/angular2/src/core/dom/element.js b/modules/angular2/src/core/dom/element.js
deleted file mode 100644
index bb9c98fb6b..0000000000
--- a/modules/angular2/src/core/dom/element.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {normalizeBlank} from 'angular2/src/facade/lang';
-
-/**
- * @publicModule angular2/angular2
- */
-export class NgElement {
-  domElement;
-  constructor(domElement) {
-    this.domElement = domElement;
-  }
-
-  getAttribute(name:string) {
-    return normalizeBlank(DOM.getAttribute(this.domElement, name));
-  }
-}
\ No newline at end of file
diff --git a/modules/angular2/src/directives/class.js b/modules/angular2/src/directives/class.js
index 69d8375cac..9a986ae904 100644
--- a/modules/angular2/src/directives/class.js
+++ b/modules/angular2/src/directives/class.js
@@ -1,7 +1,7 @@
 import {Decorator} from 'angular2/src/core/annotations/annotations';
 import {isPresent} from 'angular2/src/facade/lang';
 import {DOM} from 'angular2/src/dom/dom_adapter';
-import {NgElement} from 'angular2/src/core/dom/element';
+import {NgElement} from 'angular2/src/core/compiler/ng_element';
 
 @Decorator({
   selector: '[class]',
diff --git a/modules/angular2/src/directives/switch.js b/modules/angular2/src/directives/switch.js
index b71d163c1e..56fdca4850 100644
--- a/modules/angular2/src/directives/switch.js
+++ b/modules/angular2/src/directives/switch.js
@@ -1,6 +1,5 @@
 import {Decorator, Viewport} from 'angular2/src/core/annotations/annotations';
 import {ViewContainer} from 'angular2/src/core/compiler/view_container';
-import {NgElement} from 'angular2/src/core/dom/element';
 import {isPresent, isBlank, normalizeBlank} from 'angular2/src/facade/lang';
 import {ListWrapper, List, MapWrapper, Map} from 'angular2/src/facade/collection';
 import {Parent} from 'angular2/src/core/annotations/visibility';
@@ -156,7 +155,7 @@ export class SwitchWhen {
   _switch: Switch;
   _viewContainer: ViewContainer;
 
-  constructor(el: NgElement, viewContainer: ViewContainer, @Parent() sswitch: Switch) {
+  constructor(viewContainer: ViewContainer, @Parent() sswitch: Switch) {
     // `_whenDefault` is used as a marker for a not yet initialized value
     this._value = _whenDefault;
     this._switch = sswitch;
diff --git a/modules/angular2/src/render/api.js b/modules/angular2/src/render/api.js
index 2315bb5dcb..03e556d98c 100644
--- a/modules/angular2/src/render/api.js
+++ b/modules/angular2/src/render/api.js
@@ -203,7 +203,7 @@ export class Renderer {
    * Sets the dispatcher for all events that have been defined in the template or in directives
    * in the given view.
    */
-  setEventDispatcher(viewRef:ViewRef, dispatcher:EventDispatcher):void {}
+  setEventDispatcher(viewRef:ViewRef, dispatcher:any/*EventDispatcher*/):void {}
 
   /**
    * To be called at the end of the VmTurn so the API can buffer calls
@@ -218,10 +218,10 @@ export class Renderer {
 export class EventDispatcher {
   /**
    * Called when an event was triggered for a on-* attribute on an element.
-   * @param {List<any>} locals Locals to be used to evaluate the
+   * @param {Map<string, any>} locals Locals to be used to evaluate the
    *   event expressions
    */
   dispatchEvent(
-    elementIndex:number, eventName:string, locals:List<any>
+    elementIndex:number, eventName:string, locals:Map<string, any>
   ):void {}
 }
diff --git a/modules/angular2/src/render/dom/compiler/compiler.js b/modules/angular2/src/render/dom/compiler/compiler.js
index 628c7a30ce..5d33843351 100644
--- a/modules/angular2/src/render/dom/compiler/compiler.js
+++ b/modules/angular2/src/render/dom/compiler/compiler.js
@@ -1,10 +1,14 @@
+import {Injectable} from 'angular2/di';
+
 import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
 import {BaseException} from 'angular2/src/facade/lang';
 
 import {Template, ProtoView} from '../../api';
 import {CompilePipeline} from './compile_pipeline';
 import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
-import {CompileStepFactory} from './compile_step_factory';
+import {CompileStepFactory, DefaultStepFactory} from './compile_step_factory';
+import {Parser} from 'angular2/change_detection';
+import {ShadowDomStrategy} from '../shadow_dom/shadow_dom_strategy';
 
 /**
  * The compiler loads and translates the html templates of components into
@@ -43,4 +47,11 @@ export class Compiler {
       return PromiseWrapper.resolve(protoView);
     }
   }
+}
+
+@Injectable()
+export class DefaultCompiler extends Compiler {
+  constructor(parser:Parser, shadowDomStrategy:ShadowDomStrategy, templateLoader: TemplateLoader) {
+    super(new DefaultStepFactory(parser, shadowDomStrategy), templateLoader);
+  }
 }
\ No newline at end of file
diff --git a/modules/angular2/src/render/dom/direct_dom_renderer.js b/modules/angular2/src/render/dom/direct_dom_renderer.js
index fe2dbe8f84..4f0c963626 100644
--- a/modules/angular2/src/render/dom/direct_dom_renderer.js
+++ b/modules/angular2/src/render/dom/direct_dom_renderer.js
@@ -1,3 +1,4 @@
+import {Injectable} from 'angular2/di';
 import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
 import {List, ListWrapper} from 'angular2/src/facade/collection';
 import {isBlank, isPresent} from 'angular2/src/facade/lang';
@@ -14,7 +15,7 @@ function _resolveViewContainer(vc:api.ViewContainerRef) {
   return _resolveView(vc.view).viewContainers[vc.elementIndex];
 }
 
-function _resolveView(viewRef:_DirectDomViewRef) {
+function _resolveView(viewRef:DirectDomViewRef) {
   return isPresent(viewRef) ? viewRef.delegate : null;
 }
 
@@ -23,7 +24,7 @@ function _resolveProtoView(protoViewRef:DirectDomProtoViewRef) {
 }
 
 function _wrapView(view:View) {
-  return new _DirectDomViewRef(view);
+  return new DirectDomViewRef(view);
 }
 
 function _collectComponentChildViewRefs(view, target = null) {
@@ -51,7 +52,7 @@ export class DirectDomProtoViewRef extends api.ProtoViewRef {
   }
 }
 
-class _DirectDomViewRef extends api.ViewRef {
+export class DirectDomViewRef extends api.ViewRef {
   delegate:View;
 
   constructor(delegate:View) {
@@ -60,6 +61,7 @@ class _DirectDomViewRef extends api.ViewRef {
   }
 }
 
+@Injectable()
 export class DirectDomRenderer extends api.Renderer {
   _compiler: Compiler;
   _viewFactory: ViewFactory;
@@ -131,7 +133,7 @@ export class DirectDomRenderer extends api.Renderer {
     _resolveView(viewRef).setText(textNodeIndex, text);
   }
 
-  setEventDispatcher(viewRef:api.ViewRef, dispatcher:api.EventDispatcher) {
+  setEventDispatcher(viewRef:api.ViewRef, dispatcher:any/*api.EventDispatcher*/):void {
     _resolveView(viewRef).setEventDispatcher(dispatcher);
   }
 }
diff --git a/modules/angular2/src/render/dom/view/proto_view_builder.js b/modules/angular2/src/render/dom/view/proto_view_builder.js
index 37fa03ddd0..7e3e20810a 100644
--- a/modules/angular2/src/render/dom/view/proto_view_builder.js
+++ b/modules/angular2/src/render/dom/view/proto_view_builder.js
@@ -242,19 +242,19 @@ export class EventLocalsAstSplitter extends AstTransformer {
   }
 
   splitEventAstIntoLocals(eventBindings:Map<string, ASTWithSource>):Map<string, ASTWithSource> {
-    // TODO(tbosch): reenable this when we are using
-    // the render views
-    return eventBindings;
-    // if (isPresent(eventBindings)) {
-    //   var result = MapWrapper.create();
-    //   MapWrapper.forEach(eventBindings, (astWithSource, eventName) => {
-    //     var adjustedAst = astWithSource.ast.visit(this);
-    //     MapWrapper.set(result, eventName, new ASTWithSource(adjustedAst, astWithSource.source, ''));
-    //     ListWrapper.push(this.eventNames, eventName);
-    //   });
-    //   return result;
-    // }
-    // return null;
+    if (isPresent(eventBindings)) {
+      var result = MapWrapper.create();
+      MapWrapper.forEach(eventBindings, (astWithSource, eventName) => {
+        // TODO(tbosch): reenable this when we are parsing element properties
+        // out of action expressions
+        // var adjustedAst = astWithSource.ast.visit(this);
+        var adjustedAst = astWithSource.ast;
+        MapWrapper.set(result, eventName, new ASTWithSource(adjustedAst, astWithSource.source, ''));
+        ListWrapper.push(this.eventNames, eventName);
+      });
+      return result;
+    }
+    return null;
   }
 
   visitAccessMember(ast:AccessMember) {
diff --git a/modules/angular2/src/render/dom/view/view.js b/modules/angular2/src/render/dom/view/view.js
index b486332840..4e8a2a435e 100644
--- a/modules/angular2/src/render/dom/view/view.js
+++ b/modules/angular2/src/render/dom/view/view.js
@@ -1,7 +1,6 @@
 import {DOM} from 'angular2/src/dom/dom_adapter';
 import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
 import {int, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
-import {Locals} from 'angular2/change_detection';
 
 import {ViewContainer} from './view_container';
 import {ProtoView} from './proto_view';
@@ -10,7 +9,7 @@ import {Content} from '../shadow_dom/content_tag';
 
 import {ShadowDomStrategy} from '../shadow_dom/shadow_dom_strategy';
 
-import {EventDispatcher} from '../../api';
+// import {EventDispatcher} from '../../api';
 
 const NG_BINDING_CLASS = 'ng-binding';
 
@@ -31,7 +30,7 @@ export class View {
   lightDoms: List<LightDom>;
   proto: ProtoView;
   _hydrated: boolean;
-  _eventDispatcher: EventDispatcher;
+  _eventDispatcher: any/*EventDispatcher*/;
 
   constructor(
       proto:ProtoView, rootNodes:List,
@@ -43,6 +42,7 @@ export class View {
     this.viewContainers = viewContainers;
     this.contentTags = contentTags;
     this.lightDoms = ListWrapper.createFixedSize(boundElements.length);
+    ListWrapper.fill(this.lightDoms, null);
     this.componentChildViews = ListWrapper.createFixedSize(boundElements.length);
     this._hydrated = false;
   }
@@ -134,7 +134,10 @@ export class View {
 
     // componentChildViews
     for (var i = 0; i < this.componentChildViews.length; i++) {
-      this.componentChildViews[i].dehydrate();
+      var cv = this.componentChildViews[i];
+      if (isPresent(cv)) {
+        cv.dehydrate();
+      }
     }
 
     // viewContainers and content tags
@@ -150,10 +153,11 @@ export class View {
         }
       }
     }
+    this._eventDispatcher = null;
     this._hydrated = false;
   }
 
-  setEventDispatcher(dispatcher:EventDispatcher) {
+  setEventDispatcher(dispatcher:any/*EventDispatcher*/) {
     this._eventDispatcher = dispatcher;
   }
 
@@ -161,8 +165,11 @@ export class View {
     if (isPresent(this._eventDispatcher)) {
       var evalLocals = MapWrapper.create();
       MapWrapper.set(evalLocals, '$event', event);
-      var localValues = this.proto.elementBinders[elementIndex].eventLocals.eval(null, new Locals(null, evalLocals));
-      this._eventDispatcher.dispatchEvent(elementIndex, eventName, localValues);
+      // TODO(tbosch): reenable this when we are parsing element properties
+      // out of action expressions
+      // var localValues = this.proto.elementBinders[elementIndex].eventLocals.eval(null, new Locals(null, evalLocals));
+      // this._eventDispatcher.dispatchEvent(elementIndex, eventName, localValues);
+      this._eventDispatcher.dispatchEvent(elementIndex, eventName, evalLocals);
     }
   }
 }
diff --git a/modules/angular2/src/render/dom/view/view_container.js b/modules/angular2/src/render/dom/view/view_container.js
index 4df3216085..570fceb1c2 100644
--- a/modules/angular2/src/render/dom/view/view_container.js
+++ b/modules/angular2/src/render/dom/view/view_container.js
@@ -35,7 +35,7 @@ export class ViewContainer {
     if (isBlank(this._lightDom)) {
       for (var i = this._views.length - 1; i >= 0; i--) {
         var view = this._views[i];
-        ViewContainer.removeViewNodesFromParent(this.templateElement.parentNode, view);
+        ViewContainer.removeViewNodes(view);
         this._viewFactory.returnView(view);
       }
       this._views = [];
@@ -72,12 +72,11 @@ export class ViewContainer {
   }
 
   insert(view, atIndex=-1): viewModule.View {
-    this._checkHydrated();
-    if (atIndex == -1) atIndex = this._views.length;
-    ListWrapper.insert(this._views, atIndex, view);
     if (!view.hydrated()) {
       view.hydrate(this._hostLightDom);
     }
+    if (atIndex == -1) atIndex = this._views.length;
+    ListWrapper.insert(this._views, atIndex, view);
 
     if (isBlank(this._lightDom)) {
       ViewContainer.moveViewNodesAfterSibling(this._siblingToInsertAfter(atIndex), view);
@@ -100,7 +99,7 @@ export class ViewContainer {
     var detachedView = this.get(atIndex);
     ListWrapper.removeAt(this._views, atIndex);
     if (isBlank(this._lightDom)) {
-      ViewContainer.removeViewNodesFromParent(this.templateElement.parentNode, detachedView);
+      ViewContainer.removeViewNodes(detachedView);
     } else {
       this._lightDom.redistribute();
     }
@@ -129,8 +128,11 @@ export class ViewContainer {
     }
   }
 
-  static removeViewNodesFromParent(parent, view) {
-    for (var i = view.rootNodes.length - 1; i >= 0; --i) {
+  static removeViewNodes(view) {
+    var len = view.rootNodes.length;
+    if (len == 0) return;
+    var parent = view.rootNodes[0].parentNode;
+    for (var i = len - 1; i >= 0; --i) {
       DOM.removeChild(parent, view.rootNodes[i]);
     }
   }
diff --git a/modules/angular2/src/render/dom/view/view_factory.js b/modules/angular2/src/render/dom/view/view_factory.js
index 077bd7e624..2883dedd0a 100644
--- a/modules/angular2/src/render/dom/view/view_factory.js
+++ b/modules/angular2/src/render/dom/view/view_factory.js
@@ -1,4 +1,4 @@
-import {OpaqueToken} from 'angular2/di';
+import {OpaqueToken, Inject, Injectable} from 'angular2/di';
 import {int, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
 import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
 
@@ -8,32 +8,33 @@ import {Content} from '../shadow_dom/content_tag';
 import {ShadowDomStrategy} from '../shadow_dom/shadow_dom_strategy';
 import {EventManager} from 'angular2/src/render/dom/events/event_manager';
 
-import {ViewContainer} from './view_container';
-import {ProtoView} from './proto_view';
-import {View} from './view';
+import * as vcModule from './view_container';
+import * as pvModule from './proto_view';
+import * as viewModule from './view';
 import {NG_BINDING_CLASS_SELECTOR, NG_BINDING_CLASS} from '../util';
 
-export var VIEW_POOL_CAPACITY = new OpaqueToken('ViewFactory.viewPoolCapacity');
-
+// TODO(tbosch): Make this an OpaqueToken as soon as our transpiler supports this!
+export const VIEW_POOL_CAPACITY = 'render.ViewFactory.viewPoolCapacity';
 
+@Injectable()
 export class ViewFactory {
   _poolCapacity:number;
-  _pooledViews:List<View>;
+  _pooledViews:List<viewModule.View>;
   _eventManager:EventManager;
   _shadowDomStrategy:ShadowDomStrategy;
 
-  constructor(capacity, eventManager, shadowDomStrategy) {
+  constructor(@Inject(VIEW_POOL_CAPACITY) capacity, eventManager:EventManager, shadowDomStrategy:ShadowDomStrategy) {
     this._poolCapacity = capacity;
     this._pooledViews = ListWrapper.create();
     this._eventManager = eventManager;
     this._shadowDomStrategy = shadowDomStrategy;
   }
 
-  getView(protoView:ProtoView):View {
+  getView(protoView:pvModule.ProtoView):viewModule.View {
     // TODO(tbosch): benchmark this scanning of views and maybe
     // replace it with a fancy LRU Map/List combination...
     var view;
-    for (var i=0; i<this._pooledViews.length; i++) {
+    for (var i=this._pooledViews.length-1; i>=0; i--) {
       var pooledView = this._pooledViews[i];
       if (pooledView.proto === protoView) {
         view = ListWrapper.removeAt(this._pooledViews, i);
@@ -45,7 +46,7 @@ export class ViewFactory {
     return view;
   }
 
-  returnView(view:View) {
+  returnView(view:viewModule.View) {
     if (view.hydrated()) {
       view.dehydrate();
     }
@@ -55,7 +56,7 @@ export class ViewFactory {
     }
   }
 
-  _createView(protoView:ProtoView): View {
+  _createView(protoView:pvModule.ProtoView): viewModule.View {
     var rootElementClone = protoView.isRootView ? protoView.element : DOM.importIntoDoc(protoView.element);
     var elementsWithBindingsDynamic;
     if (protoView.isTemplateElement) {
@@ -72,7 +73,7 @@ export class ViewFactory {
     var viewRootNodes;
     if (protoView.isTemplateElement) {
       var childNode = DOM.firstChild(DOM.content(rootElementClone));
-      viewRootNodes = []; // TODO(perf): Should be fixed size, since we could pre-compute in in ProtoView
+      viewRootNodes = []; // TODO(perf): Should be fixed size, since we could pre-compute in in pvModule.ProtoView
       // Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
       while(childNode != null) {
         ListWrapper.push(viewRootNodes, childNode);
@@ -108,7 +109,7 @@ export class ViewFactory {
       // viewContainers
       var viewContainer = null;
       if (isBlank(binder.componentId) && isPresent(binder.nestedProtoView)) {
-        viewContainer = new ViewContainer(this, element);
+        viewContainer = new vcModule.ViewContainer(this, element);
       }
       viewContainers[binderIdx] = viewContainer;
 
@@ -120,7 +121,7 @@ export class ViewFactory {
       contentTags[binderIdx] = contentTag;
     }
 
-    var view = new View(
+    var view = new viewModule.View(
       protoView, viewRootNodes,
       boundTextNodes, boundElements, viewContainers, contentTags
     );
diff --git a/modules/angular2/src/services/ruler.js b/modules/angular2/src/services/ruler.js
index 8d14b4f175..40136dee25 100644
--- a/modules/angular2/src/services/ruler.js
+++ b/modules/angular2/src/services/ruler.js
@@ -1,6 +1,6 @@
 import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
 import {DomAdapter} from 'angular2/src/dom/dom_adapter';
-import {NgElement} from 'angular2/src/core/dom/element';
+import {NgElement} from 'angular2/src/core/compiler/ng_element';
 
 export class Rectangle {
   left;
diff --git a/modules/angular2/src/test_lib/test_bed.js b/modules/angular2/src/test_lib/test_bed.js
index 7de912ebcc..f8024a1b73 100644
--- a/modules/angular2/src/test_lib/test_bed.js
+++ b/modules/angular2/src/test_lib/test_bed.js
@@ -1,4 +1,4 @@
-import {Injector} from 'angular2/di';
+import {Injector, bind} from 'angular2/di';
 
 import {Type, isPresent, BaseException} from 'angular2/src/facade/lang';
 import {Promise} from 'angular2/src/facade/async';
@@ -10,12 +10,15 @@ import {Template} from 'angular2/src/core/annotations/template';
 import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
 import {Compiler} from 'angular2/src/core/compiler/compiler';
 import {View} from 'angular2/src/core/compiler/view';
+import {ViewFactory} from 'angular2/src/core/compiler/view_factory';
 
-import {EventManager} from 'angular2/src/render/dom/events/event_manager';
+import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
+import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
 
-import {queryView} from './utils';
+import {queryView, viewRootNodes, el} from './utils';
 import {instantiateType, getTypeOf} from './lang_utils';
 
+
 export class TestBed {
   _injector: Injector;
 
@@ -85,11 +88,17 @@ export class TestBed {
       this.setInlineTemplate(component, html);
     }
 
-    return this._injector.get(Compiler).compile(component).then((pv) => {
-      var eventManager = this._injector.get(EventManager);
-      var view = pv.instantiate(null, eventManager);
-      view.hydrate(this._injector, null, null, context, null);
-      return new ViewProxy(view);
+    var rootEl = el('<div></div>');
+    var metadataReader = this._injector.get(DirectiveMetadataReader);
+    var componentBinding = DirectiveBinding.createFromBinding(
+      bind(component).toValue(context),
+      metadataReader.read(component).annotation
+    );
+    return this._injector.get(Compiler).compileRoot(rootEl, componentBinding).then((pv) => {
+      var viewFactory = this._injector.get(ViewFactory);
+      var view = viewFactory.getView(pv);
+      view.hydrate(this._injector, null, context, null);
+      return new ViewProxy(view.componentChildViews[0]);
     });
   }
 }
@@ -108,8 +117,8 @@ export class ViewProxy {
     return this._view.context;
   }
 
-  get nodes(): List {
-    return this._view.nodes;
+  get rootNodes(): List {
+    return viewRootNodes(this._view);
   }
 
   detectChanges(): void {
diff --git a/modules/angular2/src/test_lib/test_injector.js b/modules/angular2/src/test_lib/test_injector.js
index 92236aae1d..feef7d75e2 100644
--- a/modules/angular2/src/test_lib/test_injector.js
+++ b/modules/angular2/src/test_lib/test_injector.js
@@ -7,13 +7,15 @@ import {ExceptionHandler} from 'angular2/src/core/exception_handler';
 import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
 import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
 import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
-import {ShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
+import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
+import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
 import {XHR} from 'angular2/src/services/xhr';
 import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
 import {UrlResolver} from 'angular2/src/services/url_resolver';
 import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
 import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
 import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
+import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
 
 import {DOM} from 'angular2/src/dom/dom_adapter';
 
@@ -32,6 +34,13 @@ import {Injector} from 'angular2/di';
 import {List, ListWrapper} from 'angular2/src/facade/collection';
 import {FunctionWrapper} from 'angular2/src/facade/lang';
 
+import {ViewFactory, VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_factory';
+import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
+import {Renderer} from 'angular2/src/render/api';
+import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
+import * as rc from 'angular2/src/render/dom/compiler/compiler';
+import * as rvf from 'angular2/src/render/dom/view/view_factory';
+
 /**
  * Returns the root injector bindings.
  *
@@ -67,11 +76,19 @@ function _getAppBindings() {
     bind(ShadowDomStrategy).toFactory(
         (styleUrlResolver, doc) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, doc.head),
         [StyleUrlResolver, appDocumentToken]),
+    bind(Renderer).toClass(DirectDomRenderer),
+    bind(rc.Compiler).toClass(rc.DefaultCompiler),
+    rvf.ViewFactory,
+    bind(rvf.VIEW_POOL_CAPACITY).toValue(500),
+    ProtoViewFactory,
+    ViewFactory,
+    bind(VIEW_POOL_CAPACITY).toValue(500),
     Compiler,
     CompilerCache,
     bind(TemplateResolver).toClass(MockTemplateResolver),
     bind(ChangeDetection).toValue(dynamicChangeDetection),
     TemplateLoader,
+    PrivateComponentLoader,
     DirectiveMetadataReader,
     Parser,
     Lexer,
diff --git a/modules/angular2/src/test_lib/utils.js b/modules/angular2/src/test_lib/utils.js
index a436d03998..89e968d0e0 100644
--- a/modules/angular2/src/test_lib/utils.js
+++ b/modules/angular2/src/test_lib/utils.js
@@ -24,9 +24,14 @@ export class Log {
   }
 }
 
+export function viewRootNodes(view) {
+  return view.render.delegate.rootNodes;
+}
+
 export function queryView(view, selector) {
-  for (var i = 0; i < view.nodes.length; ++i) {
-    var res = DOM.querySelector(view.nodes[i], selector);
+  var rootNodes = viewRootNodes(view);
+  for (var i = 0; i < rootNodes.length; ++i) {
+    var res = DOM.querySelector(rootNodes[i], selector);
     if (isPresent(res)) {
       return res;
     }
diff --git a/modules/angular2/test/core/compiler/compiler_spec.js b/modules/angular2/test/core/compiler/compiler_spec.js
index 94cd8e7994..e1640ee0b7 100644
--- a/modules/angular2/test/core/compiler/compiler_spec.js
+++ b/modules/angular2/test/core/compiler/compiler_spec.js
@@ -16,7 +16,7 @@ import {List, ListWrapper, Map, MapWrapper, StringMapWrapper} from 'angular2/src
 import {Type, isBlank, stringify, isPresent} from 'angular2/src/facade/lang';
 import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
 
-import {NewCompiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
+import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
 import {ProtoView} from 'angular2/src/core/compiler/view';
 import {ElementBinder} from 'angular2/src/core/compiler/element_binder';
 import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
@@ -45,7 +45,7 @@ export function main() {
       var urlResolver = new FakeUrlResolver();
       renderer = new FakeRenderer(renderCompileResults);
       protoViewFactory = new FakeProtoViewFactory(protoViewFactoryResults)
-      return new NewCompiler(
+      return new Compiler(
         reader,
         new CompilerCache(),
         tplResolver,
@@ -373,7 +373,7 @@ export function main() {
         ],
         [rootProtoView, mainProtoView]
       );
-      compiler.compileRoot(null, createDirectiveBinding(reader, MainComponent)).then( (protoView) => {
+      compiler.compileRoot(null, MainComponent).then( (protoView) => {
         expect(protoView).toBe(rootProtoView);
         expect(rootProtoView.elementBinders[0].nestedProtoView).toBe(mainProtoView);
         async.done();
@@ -388,7 +388,7 @@ function createDirectiveBinding(reader, type) {
 }
 
 function createProtoView(elementBinders = null) {
-  var pv = new ProtoView(null, null, null, null, null);
+  var pv = new ProtoView(null, null, null);
   if (isBlank(elementBinders)) {
     elementBinders = [];
   }
diff --git a/modules/angular2/test/core/compiler/element_injector_spec.js b/modules/angular2/test/core/compiler/element_injector_spec.js
index 30378450e6..8c9f918733 100644
--- a/modules/angular2/test/core/compiler/element_injector_spec.js
+++ b/modules/angular2/test/core/compiler/element_injector_spec.js
@@ -1,7 +1,6 @@
 import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, SpyObject, proxy, el} from 'angular2/test_lib';
 import {isBlank, isPresent, IMPLEMENTS} from 'angular2/src/facade/lang';
 import {ListWrapper, MapWrapper, List, StringMapWrapper} from 'angular2/src/facade/collection';
-import {DOM} from 'angular2/src/dom/dom_adapter';
 import {ProtoElementInjector, PreBuiltObjects, DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
 import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
 import {EventEmitter, PropertySetter, Attribute} from 'angular2/src/core/annotations/di';
@@ -9,10 +8,11 @@ import {onDestroy} from 'angular2/src/core/annotations/annotations';
 import {Optional, Injector, Inject, bind} from 'angular2/di';
 import {ProtoView, View} from 'angular2/src/core/compiler/view';
 import {ViewContainer} from 'angular2/src/core/compiler/view_container';
-import {NgElement} from 'angular2/src/core/dom/element';
-import {LightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
+import {NgElement} from 'angular2/src/core/compiler/ng_element';
 import {Directive} from 'angular2/src/core/annotations/annotations';
-import {BindingPropagationConfig} from 'angular2/change_detection';
+import {BindingPropagationConfig, Parser, Lexer} from 'angular2/change_detection';
+
+import {ViewRef, Renderer} from 'angular2/src/render/api';
 
 class DummyDirective extends Directive {
   constructor({lifecycle} = {}) { super({lifecycle: lifecycle}); }
@@ -22,10 +22,6 @@ class DummyDirective extends Directive {
 @IMPLEMENTS(View)
 class DummyView extends SpyObject {noSuchMethod(m){super.noSuchMethod(m)}}
 
-@proxy
-@IMPLEMENTS(LightDom)
-class DummyLightDom extends SpyObject {noSuchMethod(m){super.noSuchMethod(m)}}
-
 
 class SimpleDirective {
 }
@@ -198,10 +194,10 @@ export function main() {
 
     var proto = new ProtoElementInjector(null, 0, bindings, isPresent(shadowDomAppInjector));
     proto.attributes = attributes;
-    var inj = proto.instantiate(null, null);
+    var inj = proto.instantiate(null);
     var preBuilt = isPresent(preBuiltObjects) ? preBuiltObjects : defaultPreBuiltObjects;
 
-    inj.instantiateDirectives(lightDomAppInjector, shadowDomAppInjector, preBuilt);
+    inj.instantiateDirectives(lightDomAppInjector, null, shadowDomAppInjector, preBuilt);
     return inj;
   }
 
@@ -211,13 +207,13 @@ export function main() {
     var inj = new Injector([]);
 
     var protoParent = new ProtoElementInjector(null, 0, parentBindings);
-    var parent = protoParent.instantiate(null, null);
+    var parent = protoParent.instantiate(null);
 
-    parent.instantiateDirectives(inj, null, parentPreBuildObjects);
+    parent.instantiateDirectives(inj, null, null, parentPreBuildObjects);
 
     var protoChild = new ProtoElementInjector(protoParent, 1, childBindings, false, 1);
-    var child = protoChild.instantiate(parent, null);
-    child.instantiateDirectives(inj, null, defaultPreBuiltObjects);
+    var child = protoChild.instantiate(parent);
+    child.instantiateDirectives(inj, null, null, defaultPreBuiltObjects);
 
     return child;
   }
@@ -229,12 +225,12 @@ export function main() {
     var shadowInj = inj.createChild([]);
 
     var protoParent = new ProtoElementInjector(null, 0, hostBindings, true);
-    var host = protoParent.instantiate(null, null);
-    host.instantiateDirectives(inj, shadowInj, hostPreBuildObjects);
+    var host = protoParent.instantiate(null);
+    host.instantiateDirectives(inj, null, shadowInj, hostPreBuildObjects);
 
     var protoChild = new ProtoElementInjector(protoParent, 0, shadowBindings, false, 1);
-    var shadow = protoChild.instantiate(null, host);
-    shadow.instantiateDirectives(shadowInj, null, null);
+    var shadow = protoChild.instantiate(null);
+    shadow.instantiateDirectives(shadowInj, host, null, null);
 
     return shadow;
   }
@@ -278,9 +274,9 @@ export function main() {
         var protoChild1 = new ProtoElementInjector(protoParent, 1, []);
         var protoChild2 = new ProtoElementInjector(protoParent, 2, []);
 
-        var p = protoParent.instantiate(null, null);
-        var c1 = protoChild1.instantiate(p, null);
-        var c2 = protoChild2.instantiate(p, null);
+        var p = protoParent.instantiate(null);
+        var c1 = protoChild1.instantiate(p);
+        var c2 = protoChild2.instantiate(p);
 
         expect(humanize(p, [
           [p, 'parent'],
@@ -295,8 +291,8 @@ export function main() {
           var protoParent = new ProtoElementInjector(null, 0, []);
           var protoChild = new ProtoElementInjector(protoParent, 1, [], false, distance);
 
-          var p = protoParent.instantiate(null, null);
-          var c = protoChild.instantiate(p, null);
+          var p = protoParent.instantiate(null);
+          var c = protoChild.instantiate(p);
 
           expect(c.directParent()).toEqual(p);
         });
@@ -306,8 +302,8 @@ export function main() {
           var protoParent = new ProtoElementInjector(null, 0, []);
           var protoChild = new ProtoElementInjector(protoParent, 1, [], false, distance);
 
-          var p = protoParent.instantiate(null, null);
-          var c = protoChild.instantiate(p, null);
+          var p = protoParent.instantiate(null);
+          var c = protoChild.instantiate(p);
 
           expect(c.directParent()).toEqual(null);
         });
@@ -496,14 +492,14 @@ export function main() {
       });
 
       it("should return element", function () {
-        var element = new NgElement(null);
+        var element = new NgElement(null, null);
         var inj = injector([], null, null, new PreBuiltObjects(null, element, null, null));
 
         expect(inj.get(NgElement)).toEqual(element);
       });
 
       it('should return viewContainer', function () {
-        var viewContainer = new ViewContainer(null, null, null, null, null);
+        var viewContainer = new ViewContainer(null, null, null, null);
         var inj = injector([], null, null, new PreBuiltObjects(null, null, viewContainer, null));
 
         expect(inj.get(ViewContainer)).toEqual(viewContainer);
@@ -536,9 +532,9 @@ export function main() {
         injWithPrivateComponent.createPrivateComponent(SomeOtherDirective, null);
 
         var shadowDomProtoInjector = new ProtoElementInjector(null, 0, [NeedDirectiveFromAncestor], false);
-        var shadowDomInj = shadowDomProtoInjector.instantiate(null, injWithPrivateComponent);
+        var shadowDomInj = shadowDomProtoInjector.instantiate(null);
 
-        expect(() => shadowDomInj.instantiateDirectives(appInjector, null, defaultPreBuiltObjects)).
+        expect(() => shadowDomInj.instantiateDirectives(appInjector, injWithPrivateComponent, null, defaultPreBuiltObjects)).
           toThrowError(new RegExp("No provider for SimpleDirective"));
       });
 
@@ -547,8 +543,8 @@ export function main() {
         injWithPrivateComponent.createPrivateComponent(SimpleDirective, null);
 
         var shadowDomProtoInjector = new ProtoElementInjector(null, 0, [NeedDirectiveFromAncestor], false);
-        var shadowDomInjector = shadowDomProtoInjector.instantiate(null, injWithPrivateComponent);
-        shadowDomInjector.instantiateDirectives(appInjector, null, defaultPreBuiltObjects);
+        var shadowDomInjector = shadowDomProtoInjector.instantiate(null);
+        shadowDomInjector.instantiateDirectives(appInjector, injWithPrivateComponent, null, defaultPreBuiltObjects);
 
         expect(shadowDomInjector.get(NeedDirectiveFromAncestor)).toBeAnInstanceOf(NeedDirectiveFromAncestor);
         expect(shadowDomInjector.get(NeedDirectiveFromAncestor).dependency).toBeAnInstanceOf(SimpleDirective);
@@ -566,7 +562,7 @@ export function main() {
         expect(inj.getPrivateComponent()).toBe(null);
         expect(dir.onDestroyCounter).toBe(1);
 
-        inj.instantiateDirectives(null, null, null);
+        inj.instantiateDirectives(null, null, null, null);
 
         expect(inj.getPrivateComponent()).not.toBe(null);
       });
@@ -577,15 +573,18 @@ export function main() {
       function createpreBuildObject(eventName, eventHandler) {
         var handlers = StringMapWrapper.create();
         StringMapWrapper.set(handlers, eventName, eventHandler);
-        var pv = new ProtoView(null, null, null, null);
-        pv.eventHandlers = [handlers];
-        var view = new View(pv, null, MapWrapper.create());
+        var pv = new ProtoView(null, null, null);
+        pv.bindElement(null, 0, null, null, null);
+        pv.bindEvent(eventName, new Parser(new Lexer()).parseAction('handler()', ''));
+
+        var view = new View(pv, MapWrapper.create());
+        view.context = new ContextWithHandler(eventHandler);
         return new PreBuiltObjects(view, null, null, null);
       }
 
       it('should be injectable and callable', () => {
         var called = false;
-        var preBuildObject = createpreBuildObject('click', (e, view) => { called = true;});
+        var preBuildObject = createpreBuildObject('click', () => { called = true;});
         var inj = injector([NeedsEventEmitter], null, null, preBuildObject);
         inj.get(NeedsEventEmitter).click();
         expect(called).toEqual(true);
@@ -593,7 +592,7 @@ export function main() {
 
       it('should be injectable and callable without specifying param type annotation', () => {
         var called = false;
-        var preBuildObject = createpreBuildObject('click', (e, view) => { called = true;});
+        var preBuildObject = createpreBuildObject('click', () => { called = true;});
         var inj = injector([NeedsEventEmitterNoType], null, null, preBuildObject);
         inj.get(NeedsEventEmitterNoType).click();
         expect(called).toEqual(true);
@@ -613,11 +612,17 @@ export function main() {
     });
 
     describe('property setter', () => {
-      it('should be injectable and callable', () => {
-        var div = el('<div></div>');
-        var ngElement = new NgElement(div);
+      var renderer, view;
 
-        var preBuildObject = new PreBuiltObjects(null, ngElement, null, null);
+      beforeEach( () => {
+        renderer = new FakeRenderer();
+        var protoView = new ProtoView(renderer, null, null);
+        view = new View(protoView, MapWrapper.create());
+        view.render = new ViewRef();
+      });
+
+      it('should be injectable and callable', () => {
+        var preBuildObject = new PreBuiltObjects(view, null, null, null);
         var inj = injector([NeedsPropertySetter], null, null, preBuildObject);
         var component = inj.get(NeedsPropertySetter);
         component.setProp('foobar');
@@ -627,22 +632,21 @@ export function main() {
         component.setStyle('40px');
         component.setStyleWithUnit(50);
 
-        expect(div.title).toEqual('foobar');
-        expect(DOM.getAttribute(div, 'role')).toEqual('button');
-        expect(DOM.hasClass(div, 'active')).toEqual(true);
-        expect(DOM.hasClass(div, 'foo-bar')).toEqual(true);
-        expect(DOM.getStyle(div, 'width')).toEqual('40px');
-        expect(DOM.getStyle(div, 'height')).toEqual('50px');
+        expect(renderer.log[0]).toEqual([view.render, 0, 'title', 'foobar']);
+        expect(renderer.log[1]).toEqual([view.render, 0, 'attr.role', 'button']);
+        expect(renderer.log[2]).toEqual([view.render, 0, 'class.active', true]);
+        expect(renderer.log[3]).toEqual([view.render, 0, 'class.foo-bar', true]);
+        expect(renderer.log[4]).toEqual([view.render, 0, 'style.width', '40px']);
+        expect(renderer.log[5]).toEqual([view.render, 0, 'style.height.px', 50]);
       });
 
       it('should be injectable and callable without specifying param type annotation', () => {
-        var div = el('<div></div>');
-        var preBuildObject = new PreBuiltObjects(null, new NgElement(div), null, null);
+        var preBuildObject = new PreBuiltObjects(view, null, null, null);
         var inj = injector([NeedsPropertySetterNoType], null, null, preBuildObject);
         var component = inj.get(NeedsPropertySetterNoType);
         component.setProp('foobar');
 
-        expect(div.title).toEqual('foobar');
+        expect(renderer.log[0]).toEqual([view.render, 0, 'title', 'foobar']);
       });
     });
 
@@ -673,3 +677,22 @@ export function main() {
 
   });
 }
+
+class ContextWithHandler {
+  handler;
+  constructor(handler) {
+    this.handler = handler;
+  }
+}
+
+class FakeRenderer extends Renderer {
+  log:List;
+  constructor() {
+    super();
+    this.log = [];
+  }
+  setElementProperty(viewRef, elementIndex, propertyName, value) {
+    ListWrapper.push(this.log, [viewRef, elementIndex, propertyName, value]);
+  }
+
+}
\ No newline at end of file
diff --git a/modules/angular2/test/core/compiler/integration_spec.js b/modules/angular2/test/core/compiler/integration_spec.js
index 2d8a265369..917d78aaa1 100644
--- a/modules/angular2/test/core/compiler/integration_spec.js
+++ b/modules/angular2/test/core/compiler/integration_spec.js
@@ -5,32 +5,27 @@ import {
   xdescribe,
   describe,
   el,
+  dispatchEvent,
   expect,
   iit,
   inject,
+  beforeEachBindings,
   it,
-  xit,
+  xit
 } from 'angular2/test_lib';
 
+import {TestBed} from 'angular2/src/test_lib/test_bed';
+
 import {DOM} from 'angular2/src/dom/dom_adapter';
 import {Type, isPresent, BaseException, assertionsEnabled, isJsObject} from 'angular2/src/facade/lang';
 import {PromiseWrapper} from 'angular2/src/facade/async';
 
 import {Injector, bind} from 'angular2/di';
-import {Lexer, Parser, dynamicChangeDetection,
-  DynamicChangeDetection, Pipe, PipeRegistry, BindingPropagationConfig, ON_PUSH} from 'angular2/change_detection';
+import {dynamicChangeDetection,
+  ChangeDetection, DynamicChangeDetection, Pipe, PipeRegistry, BindingPropagationConfig, ON_PUSH} from 'angular2/change_detection';
 
-import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
-import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
-import {ShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
 import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location';
 import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
-import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
-import {MockTemplateResolver} from 'angular2/src/mock/template_resolver_mock';
-import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
-import {UrlResolver} from 'angular2/src/services/url_resolver';
-import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
-import {EventManager} from 'angular2/src/render/dom/events/event_manager';
 
 import {Decorator, Component, Viewport, DynamicComponent} from 'angular2/src/core/annotations/annotations';
 import {Template} from 'angular2/src/core/annotations/template';
@@ -43,161 +38,117 @@ import {ViewContainer} from 'angular2/src/core/compiler/view_container';
 
 export function main() {
   describe('integration tests', function() {
-    var directiveMetadataReader, shadowDomStrategy, compiler, tplResolver;
-
-    function createCompiler(tplResolver, changedDetection) {
-      var urlResolver = new UrlResolver();
-      return new Compiler(changedDetection,
-        new TemplateLoader(null, null),
-        directiveMetadataReader,
-        new Parser(new Lexer()),
-        new CompilerCache(),
-        shadowDomStrategy,
-        tplResolver,
-        new ComponentUrlMapper(),
-        urlResolver
-      );
-    }
+    var ctx;
 
     beforeEach( () => {
-      tplResolver = new MockTemplateResolver();
-
-      directiveMetadataReader = new DirectiveMetadataReader();
-
-      var urlResolver = new UrlResolver();
-      shadowDomStrategy = new EmulatedUnscopedShadowDomStrategy(new StyleUrlResolver(urlResolver), null);
-
-      compiler = createCompiler(tplResolver, dynamicChangeDetection);
+      ctx = new MyComp();
     });
 
     describe('react to record changes', function() {
-      var view, ctx, cd;
-      function createView(pv) {
-        ctx = new MyComp();
-        view = pv.instantiate(null, null);
-
-        view.hydrate(new Injector([
-          bind(Compiler).toValue(compiler),
-          bind(DirectiveMetadataReader).toValue(directiveMetadataReader),
-          bind(ShadowDomStrategy).toValue(shadowDomStrategy),
-          bind(EventManager).toValue(null),
-          PrivateComponentLoader
-        ]), null, null, ctx, null);
-
-        cd = view.changeDetector;
-      }
-
-      it('should consume text node changes', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({inline: '<div>{{ctxProp}}</div>'}));
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+      it('should consume text node changes', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({inline: '<div>{{ctxProp}}</div>'}));
+        tb.createView(MyComp, {context: ctx}).then((view) => {
           ctx.ctxProp = 'Hello World!';
 
-          cd.detectChanges();
-          expect(DOM.getInnerHTML(view.nodes[0])).toEqual('Hello World!');
+          view.detectChanges();
+          expect(DOM.getInnerHTML(view.rootNodes[0])).toEqual('Hello World!');
           async.done();
         });
       }));
 
-      it('should consume element binding changes', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({inline: '<div [id]="ctxProp"></div>'}));
+      it('should consume element binding changes', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({inline: '<div [id]="ctxProp"></div>'}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
           ctx.ctxProp = 'Hello World!';
-          cd.detectChanges();
+          view.detectChanges();
 
-          expect(view.nodes[0].id).toEqual('Hello World!');
+          expect(view.rootNodes[0].id).toEqual('Hello World!');
           async.done();
         });
       }));
 
-      it('should consume binding to aria-* attributes', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({inline: '<div [attr.aria-label]="ctxProp"></div>'}));
+      it('should consume binding to aria-* attributes', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({inline: '<div [attr.aria-label]="ctxProp"></div>'}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
           ctx.ctxProp = 'Initial aria label';
-          cd.detectChanges();
-          expect(DOM.getAttribute(view.nodes[0], 'aria-label')).toEqual('Initial aria label');
+          view.detectChanges();
+          expect(DOM.getAttribute(view.rootNodes[0], 'aria-label')).toEqual('Initial aria label');
 
           ctx.ctxProp = 'Changed aria label';
-          cd.detectChanges();
-          expect(DOM.getAttribute(view.nodes[0], 'aria-label')).toEqual('Changed aria label');
+          view.detectChanges();
+          expect(DOM.getAttribute(view.rootNodes[0], 'aria-label')).toEqual('Changed aria label');
 
           async.done();
         });
       }));
 
-      it('should consume binding to property names where attr name and property name do not match', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({inline: '<div [tabindex]="ctxNumProp"></div>'}));
+      it('should consume binding to property names where attr name and property name do not match', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({inline: '<div [tabindex]="ctxNumProp"></div>'}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          cd.detectChanges();
-          expect(view.nodes[0].tabIndex).toEqual(0);
+          view.detectChanges();
+          expect(view.rootNodes[0].tabIndex).toEqual(0);
 
           ctx.ctxNumProp = 5;
-          cd.detectChanges();
-          expect(view.nodes[0].tabIndex).toEqual(5);
+          view.detectChanges();
+          expect(view.rootNodes[0].tabIndex).toEqual(5);
 
           async.done();
         });
       }));
 
-      it('should consume binding to camel-cased properties using dash-cased syntax in templates', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({inline: '<input [read-only]="ctxBoolProp">'}));
+      it('should consume binding to camel-cased properties using dash-cased syntax in templates', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({inline: '<input [read-only]="ctxBoolProp">'}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          cd.detectChanges();
-          expect(view.nodes[0].readOnly).toBeFalsy();
+          view.detectChanges();
+          expect(view.rootNodes[0].readOnly).toBeFalsy();
 
           ctx.ctxBoolProp = true;
-          cd.detectChanges();
-          expect(view.nodes[0].readOnly).toBeTruthy();
+          view.detectChanges();
+          expect(view.rootNodes[0].readOnly).toBeTruthy();
 
           async.done();
         });
       }));
 
-      it('should consume binding to inner-html', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({inline: '<div inner-html="{{ctxProp}}"></div>'}));
+      it('should consume binding to inner-html', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({inline: '<div inner-html="{{ctxProp}}"></div>'}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
           ctx.ctxProp = 'Some <span>HTML</span>';
-          cd.detectChanges();
-          expect(DOM.getInnerHTML(view.nodes[0])).toEqual('Some <span>HTML</span>');
+          view.detectChanges();
+          expect(DOM.getInnerHTML(view.rootNodes[0])).toEqual('Some <span>HTML</span>');
 
           ctx.ctxProp = 'Some other <div>HTML</div>';
-          cd.detectChanges();
-          expect(DOM.getInnerHTML(view.nodes[0])).toEqual('Some other <div>HTML</div>');
+          view.detectChanges();
+          expect(DOM.getInnerHTML(view.rootNodes[0])).toEqual('Some other <div>HTML</div>');
 
           async.done();
         });
       }));
 
-      it('should ignore bindings to unknown properties', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({inline: '<div unknown="{{ctxProp}}"></div>'}));
+      it('should ignore bindings to unknown properties', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({inline: '<div unknown="{{ctxProp}}"></div>'}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
           ctx.ctxProp = 'Some value';
-          cd.detectChanges();
-          expect(DOM.hasProperty(view.nodes[0], 'unknown')).toBeFalsy();
+          view.detectChanges();
+          expect(DOM.hasProperty(view.rootNodes[0], 'unknown')).toBeFalsy();
 
           async.done();
         });
       }));
 
-      it('should consume directive watch expression change.', inject([AsyncTestCompleter], (async) => {
+      it('should consume directive watch expression change.', inject([TestBed, AsyncTestCompleter], (tb, async) => {
         var tpl =
           '<div>' +
             '<div my-dir [elprop]="ctxProp"></div>' +
@@ -205,80 +156,81 @@ export function main() {
             '<div my-dir elprop="Hi {{\'there!\'}}"></div>' +
             '<div my-dir elprop="One more {{ctxProp}}"></div>' +
           '</div>'
-        tplResolver.setTemplate(MyComp, new Template({inline: tpl, directives: [MyDir]}));
+        tb.overrideTemplate(MyComp, new Template({inline: tpl, directives: [MyDir]}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
           ctx.ctxProp = 'Hello World!';
-          cd.detectChanges();
+          view.detectChanges();
 
-          expect(view.elementInjectors[0].get(MyDir).dirProp).toEqual('Hello World!');
-          expect(view.elementInjectors[1].get(MyDir).dirProp).toEqual('Hi there!');
-          expect(view.elementInjectors[2].get(MyDir).dirProp).toEqual('Hi there!');
-          expect(view.elementInjectors[3].get(MyDir).dirProp).toEqual('One more Hello World!');
+          expect(view.rawView.elementInjectors[0].get(MyDir).dirProp).toEqual('Hello World!');
+          expect(view.rawView.elementInjectors[1].get(MyDir).dirProp).toEqual('Hi there!');
+          expect(view.rawView.elementInjectors[2].get(MyDir).dirProp).toEqual('Hi there!');
+          expect(view.rawView.elementInjectors[3].get(MyDir).dirProp).toEqual('One more Hello World!');
           async.done();
         });
       }));
 
-      it("should support pipes in bindings and bind config", inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp,
-          new Template({
-            inline: '<component-with-pipes #comp [prop]="ctxProp | double"></component-with-pipes>',
-            directives: [ComponentWithPipes]
-          }));
-
-
-        var registry = new PipeRegistry({
-          "double" : [new DoublePipeFactory()]
+      describe('pipes', () => {
+        beforeEachBindings(() => {
+          return [bind(ChangeDetection).toFactory(
+            () => new DynamicChangeDetection(new PipeRegistry({
+                "double" : [new DoublePipeFactory()]
+              })),
+            []
+          )];
         });
-        var changeDetection = new DynamicChangeDetection(registry);
-        var compiler = createCompiler(tplResolver, changeDetection);
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
 
-          ctx.ctxProp = 'a';
-          cd.detectChanges();
+        it("should support pipes in bindings and bind config", inject([TestBed, AsyncTestCompleter], (tb, async) => {
+          tb.overrideTemplate(MyComp,
+            new Template({
+              inline: '<component-with-pipes #comp [prop]="ctxProp | double"></component-with-pipes>',
+              directives: [ComponentWithPipes]
+            }));
 
-          var comp = view.locals.get("comp");
+          tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          // it is doubled twice: once in the binding, second time in the bind config
-          expect(comp.prop).toEqual('aaaa');
-          async.done();
-        });
-      }));
+            ctx.ctxProp = 'a';
+            view.detectChanges();
 
-      it('should support nested components.', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+            var comp = view.rawView.locals.get("comp");
+
+            // it is doubled twice: once in the binding, second time in the bind config
+            expect(comp.prop).toEqual('aaaa');
+            async.done();
+          });
+        }));
+      });
+
+      it('should support nested components.', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<child-cmp></child-cmp>',
           directives: [ChildComp]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          cd.detectChanges();
+          view.detectChanges();
 
-          expect(view.nodes).toHaveText('hello');
+          expect(view.rootNodes).toHaveText('hello');
           async.done();
         });
       }));
 
       // GH issue 328 - https://github.com/angular/angular/issues/328
-      it('should support different directive types on a single node', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp,
+      it('should support different directive types on a single node', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp,
           new Template({
             inline: '<child-cmp my-dir [elprop]="ctxProp"></child-cmp>',
             directives: [MyDir, ChildComp]
           }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
           ctx.ctxProp = 'Hello World!';
-          cd.detectChanges();
+          view.detectChanges();
 
-          var elInj = view.elementInjectors[0];
+          var elInj = view.rawView.elementInjectors[0];
           expect(elInj.get(MyDir).dirProp).toEqual('Hello World!');
           expect(elInj.get(ChildComp).dirProp).toEqual(null);
 
@@ -286,57 +238,54 @@ export function main() {
         });
       }));
 
-      it('should support directives where a binding attribute is not given', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp,
+      it('should support directives where a binding attribute is not given', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp,
           new Template({
             // No attribute "el-prop" specified.
             inline: '<p my-dir></p>',
             directives: [MyDir]
           }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
           async.done();
         });
       }));
 
-      it('should support directives where a selector matches property binding', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp,
+      it('should support directives where a selector matches property binding', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp,
           new Template({
             inline: '<p [id]="ctxProp"></p>',
             directives: [IdComponent]
           }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
           ctx.ctxProp = 'some_id';
-          cd.detectChanges();
-          expect(view.nodes[0].id).toEqual('some_id');
-          expect(view.nodes).toHaveText('Matched on id with some_id');
+          view.detectChanges();
+          expect(view.rootNodes[0].id).toEqual('some_id');
+          expect(view.rootNodes).toHaveText('Matched on id with some_id');
 
           ctx.ctxProp = 'other_id';
-          cd.detectChanges();
-          expect(view.nodes[0].id).toEqual('other_id');
-          expect(view.nodes).toHaveText('Matched on id with other_id');
+          view.detectChanges();
+          expect(view.rootNodes[0].id).toEqual('other_id');
+          expect(view.rootNodes).toHaveText('Matched on id with other_id');
 
           async.done();
         });
       }));
 
-      it('should support template directives via `<template>` elements.', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp,
+      it('should support template directives via `<template>` elements.', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp,
           new Template({
             inline: '<div><template some-viewport var-greeting="some-tmpl"><copy-me>{{greeting}}</copy-me></template></div>',
             directives: [SomeViewport]
           }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          cd.detectChanges();
+          view.detectChanges();
 
-          var childNodesOfWrapper = view.nodes[0].childNodes;
+          var childNodesOfWrapper = view.rootNodes[0].childNodes;
           // 1 template + 2 copies.
           expect(childNodesOfWrapper.length).toBe(3);
           expect(childNodesOfWrapper[1].childNodes[0].nodeValue).toEqual('hello');
@@ -345,18 +294,17 @@ export function main() {
         });
       }));
 
-      it('should support template directives via `template` attribute.', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should support template directives via `template` attribute.', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<div><copy-me template="some-viewport: var greeting=some-tmpl">{{greeting}}</copy-me></div>',
           directives: [SomeViewport]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          cd.detectChanges();
+          view.detectChanges();
 
-          var childNodesOfWrapper = view.nodes[0].childNodes;
+          var childNodesOfWrapper = view.rootNodes[0].childNodes;
           // 1 template + 2 copies.
           expect(childNodesOfWrapper.length).toBe(3);
           expect(childNodesOfWrapper[1].childNodes[0].nodeValue).toEqual('hello');
@@ -365,84 +313,79 @@ export function main() {
         });
       }));
 
-      it('should assign the component instance to a var-', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should assign the component instance to a var-', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<p><child-cmp var-alice></child-cmp></p>',
           directives: [ChildComp]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          expect(view.locals).not.toBe(null);
-          expect(view.locals.get('alice')).toBeAnInstanceOf(ChildComp);
+          expect(view.rawView.locals).not.toBe(null);
+          expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
 
           async.done();
         })
       }));
 
-      it('should assign two component instances each with a var-', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should assign two component instances each with a var-', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<p><child-cmp var-alice></child-cmp><child-cmp var-bob></p>',
           directives: [ChildComp]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          expect(view.locals).not.toBe(null);
-          expect(view.locals.get('alice')).toBeAnInstanceOf(ChildComp);
-          expect(view.locals.get('bob')).toBeAnInstanceOf(ChildComp);
-          expect(view.locals.get('alice')).not.toBe(view.locals.get('bob'));
+          expect(view.rawView.locals).not.toBe(null);
+          expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
+          expect(view.rawView.locals.get('bob')).toBeAnInstanceOf(ChildComp);
+          expect(view.rawView.locals.get('alice')).not.toBe(view.rawView.locals.get('bob'));
 
           async.done();
         })
       }));
 
-      it('should assign the component instance to a var- with shorthand syntax', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should assign the component instance to a var- with shorthand syntax', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<child-cmp #alice></child-cmp>',
           directives: [ChildComp]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          expect(view.locals).not.toBe(null);
-          expect(view.locals.get('alice')).toBeAnInstanceOf(ChildComp);
+          expect(view.rawView.locals).not.toBe(null);
+          expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
 
           async.done();
         })
       }));
 
-      it('should assign the element instance to a user-defined variable', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp,
+      it('should assign the element instance to a user-defined variable', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp,
           new Template({inline: '<p><div var-alice><i>Hello</i></div></p>'}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
-          expect(view.locals).not.toBe(null);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
+          expect(view.rawView.locals).not.toBe(null);
 
-          var value = view.locals.get('alice');
+          var value = view.rawView.locals.get('alice');
           expect(value).not.toBe(null);
-          expect(value.tagName.toLowerCase()).toEqual('div');
+          expect(value.domElement.tagName.toLowerCase()).toEqual('div');
 
           async.done();
         })
       }));
 
 
-      it('should assign the element instance to a user-defined variable with camelCase using dash-case', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp,
+      it('should assign the element instance to a user-defined variable with camelCase using dash-case', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp,
           new Template({inline: '<p><div var-super-alice><i>Hello</i></div></p>'}));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
-          expect(view.locals).not.toBe(null);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
+          expect(view.rawView.locals).not.toBe(null);
 
-          var value = view.locals.get('superAlice');
+          var value = view.rawView.locals.get('superAlice');
           expect(value).not.toBe(null);
-          expect(value.tagName.toLowerCase()).toEqual('div');
+          expect(value.domElement.tagName.toLowerCase()).toEqual('div');
 
           async.done();
         })
@@ -450,49 +393,47 @@ export function main() {
 
       describe("BindingPropagationConfig", () => {
         it("can be used to disable the change detection of the component's template",
-          inject([AsyncTestCompleter], (async) => {
+          inject([TestBed, AsyncTestCompleter], (tb, async) => {
 
-          tplResolver.setTemplate(MyComp, new Template({
+          tb.overrideTemplate(MyComp, new Template({
             inline: '<push-cmp #cmp></push-cmp>',
             directives: [[[PushBasedComp]]]
           }));
 
-          compiler.compile(MyComp).then((pv) => {
-            createView(pv);
+          tb.createView(MyComp, {context: ctx}).then((view) => {
 
-            var cmp = view.locals.get('cmp');
+            var cmp = view.rawView.locals.get('cmp');
 
-            cd.detectChanges();
+            view.detectChanges();
             expect(cmp.numberOfChecks).toEqual(1);
 
-            cd.detectChanges();
+            view.detectChanges();
             expect(cmp.numberOfChecks).toEqual(1);
 
             cmp.propagate();
 
-            cd.detectChanges();
+            view.detectChanges();
             expect(cmp.numberOfChecks).toEqual(2);
             async.done();
           })
         }));
 
-        it('should not affect updating properties on the component', inject([AsyncTestCompleter], (async) => {
-          tplResolver.setTemplate(MyComp, new Template({
+        it('should not affect updating properties on the component', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+          tb.overrideTemplate(MyComp, new Template({
             inline: '<push-cmp [prop]="ctxProp" #cmp></push-cmp>',
             directives: [[[PushBasedComp]]]
           }));
 
-          compiler.compile(MyComp).then((pv) => {
-            createView(pv);
+          tb.createView(MyComp, {context: ctx}).then((view) => {
 
-            var cmp = view.locals.get('cmp');
+            var cmp = view.rawView.locals.get('cmp');
 
             ctx.ctxProp = "one";
-            cd.detectChanges();
+            view.detectChanges();
             expect(cmp.prop).toEqual("one");
 
             ctx.ctxProp = "two";
-            cd.detectChanges();
+            view.detectChanges();
             expect(cmp.prop).toEqual("two");
 
             async.done();
@@ -500,24 +441,23 @@ export function main() {
         }));
       });
 
-      it('should create a component that injects a @Parent', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should create a component that injects a @Parent', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<some-directive><cmp-with-parent #child></cmp-with-parent></some-directive>',
           directives: [SomeDirective, CompWithParent]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          var childComponent = view.locals.get('child');
+          var childComponent = view.rawView.locals.get('child');
           expect(childComponent.myParent).toBeAnInstanceOf(SomeDirective);
 
           async.done();
         })
       }));
 
-      it('should create a component that injects an @Ancestor', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should create a component that injects an @Ancestor', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: `
             <some-directive>
               <p>
@@ -527,18 +467,17 @@ export function main() {
           directives: [SomeDirective, CompWithAncestor]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          var childComponent = view.locals.get('child');
+          var childComponent = view.rawView.locals.get('child');
           expect(childComponent.myAncestor).toBeAnInstanceOf(SomeDirective);
 
           async.done();
         })
       }));
 
-      it('should create a component that injects an @Ancestor through viewport directive', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should create a component that injects an @Ancestor through viewport directive', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: `
             <some-directive>
               <p *if="true">
@@ -548,11 +487,10 @@ export function main() {
           directives: [SomeDirective, CompWithAncestor, If]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
-          cd.detectChanges();
+        tb.createView(MyComp, {context: ctx}).then((view) => {
+          view.detectChanges();
 
-          var subview = view.viewContainers[1].get(0);
+          var subview = view.rawView.viewContainers[1].get(0);
           var childComponent = subview.locals.get('child');
           expect(childComponent.myAncestor).toBeAnInstanceOf(SomeDirective);
 
@@ -560,16 +498,15 @@ export function main() {
         });
       }));
 
-      it('should support events', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should support events via EventEmitter', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<div emitter listener></div>',
           directives: [DecoratorEmitingEvent, DecoratorListeningEvent]
         }));
 
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          var injector = view.elementInjectors[0];
+          var injector = view.rawView.elementInjectors[0];
 
           var emitter = injector.get(DecoratorEmitingEvent);
           var listener = injector.get(DecoratorListeningEvent);
@@ -585,34 +522,54 @@ export function main() {
         });
       }));
 
-      it('should support dynamic components', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      if (DOM.supportsDOMEvents()) {
+        it('should support render events', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+          tb.overrideTemplate(MyComp, new Template({
+            inline: '<div listener></div>',
+            directives: [DecoratorListeningDomEvent]
+          }));
+
+          tb.createView(MyComp, {context: ctx}).then((view) => {
+
+            var injector = view.rawView.elementInjectors[0];
+
+            var listener = injector.get(DecoratorListeningDomEvent);
+
+            dispatchEvent(view.rootNodes[0], 'domEvent');
+
+            expect(listener.eventType).toEqual('domEvent');
+
+            async.done();
+          });
+        }));
+      }
+
+      it('should support dynamic components', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<dynamic-comp #dynamic></dynamic-comp>',
           directives: [DynamicComp]
         }));
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          var dynamicComponent = view.locals.get("dynamic");
+          var dynamicComponent = view.rawView.locals.get("dynamic");
           expect(dynamicComponent).toBeAnInstanceOf(DynamicComp);
 
           dynamicComponent.done.then((_) => {
-            cd.detectChanges();
-            expect(view.nodes).toHaveText('hello');
+            view.detectChanges();
+            expect(view.rootNodes).toHaveText('hello');
             async.done();
           });
         });
       }));
 
-      it('should support static attributes', inject([AsyncTestCompleter], (async) => {
-        tplResolver.setTemplate(MyComp, new Template({
+      it('should support static attributes', inject([TestBed, AsyncTestCompleter], (tb, async) => {
+        tb.overrideTemplate(MyComp, new Template({
           inline: '<input static type="text" title></input>',
           directives: [NeedsAttribute]
         }));
-        compiler.compile(MyComp).then((pv) => {
-          createView(pv);
+        tb.createView(MyComp, {context: ctx}).then((view) => {
 
-          var injector = view.elementInjectors[0];
+          var injector = view.rawView.elementInjectors[0];
           var needsAttribute = injector.get(NeedsAttribute);
           expect(needsAttribute.typeAttribute).toEqual('text');
           expect(needsAttribute.titleAttribute).toEqual('');
@@ -632,9 +589,9 @@ export function main() {
 
       if (assertionsEnabled()) {
 
-        function expectCompileError(inlineTpl, errMessage, done) {
-          tplResolver.setTemplate(MyComp, new Template({inline: inlineTpl}));
-          PromiseWrapper.then(compiler.compile(MyComp),
+        function expectCompileError(tb, inlineTpl, errMessage, done) {
+          tb.overrideTemplate(MyComp, new Template({inline: inlineTpl}));
+          PromiseWrapper.then(tb.createView(MyComp),
             (value) => {
               throw new BaseException("Test failure: should not have come here as an exception was expected");
             },
@@ -645,32 +602,36 @@ export function main() {
           );
         }
 
-        it('should raise an error if no directive is registered for a template with template bindings', inject([AsyncTestCompleter], (async) => {
+        it('should raise an error if no directive is registered for a template with template bindings', inject([TestBed, AsyncTestCompleter], (tb, async) => {
           expectCompileError(
+            tb,
             '<div><div template="if: foo"></div></div>',
             'Missing directive to handle \'if\' in <div template="if: foo">',
             () => async.done()
           );
         }));
 
-        it('should raise an error for missing template directive (1)', inject([AsyncTestCompleter], (async) => {
+        it('should raise an error for missing template directive (1)', inject([TestBed, AsyncTestCompleter], (tb, async) => {
           expectCompileError(
+            tb,
             '<div><template foo></template></div>',
             'Missing directive to handle: <template foo>',
             () => async.done()
           );
         }));
 
-        it('should raise an error for missing template directive (2)', inject([AsyncTestCompleter], (async) => {
+        it('should raise an error for missing template directive (2)', inject([TestBed, AsyncTestCompleter], (tb, async) => {
           expectCompileError(
+            tb,
             '<div><template *if="condition"></template></div>',
             'Missing directive to handle: <template *if="condition">',
             () => async.done()
           );
         }));
 
-        it('should raise an error for missing template directive (3)', inject([AsyncTestCompleter], (async) => {
+        it('should raise an error for missing template directive (3)', inject([TestBed, AsyncTestCompleter], (tb, async) => {
           expectCompileError(
+            tb,
             '<div *if="condition"></div>',
             'Missing directive to handle \'if\' in MyComp: <div *if="condition">',
             () => async.done()
@@ -746,6 +707,8 @@ class PushBasedComp {
 }
 
 @Component()
+@Template({directives: [
+]})
 class MyComp {
   ctxProp:string;
   ctxNumProp;
@@ -909,6 +872,22 @@ class DecoratorListeningEvent {
   }
 }
 
+@Decorator({
+  selector: '[listener]',
+  events: {'domEvent': 'onEvent($event.type)'}
+})
+class DecoratorListeningDomEvent {
+  eventType: string;
+
+  constructor() {
+    this.eventType = '';
+  }
+
+  onEvent(eventType: string) {
+    this.eventType = eventType;
+  }
+}
+
 @Component({
   selector: '[id]',
   bind: {'id': 'id'}
diff --git a/modules/angular2/test/core/compiler/private_component_loader_spec.js b/modules/angular2/test/core/compiler/private_component_loader_spec.js
index e9da39f6da..4c4245b1cf 100644
--- a/modules/angular2/test/core/compiler/private_component_loader_spec.js
+++ b/modules/angular2/test/core/compiler/private_component_loader_spec.js
@@ -14,7 +14,7 @@ export function main() {
     var loader;
 
     beforeEach(() => {
-      loader = new PrivateComponentLoader(null, null, null,  new DirectiveMetadataReader());
+      loader = new PrivateComponentLoader(null, new DirectiveMetadataReader(), null);
     });
 
     describe('Load errors', () => {
diff --git a/modules/angular2/test/core/compiler/shadow_dom/content_tag_spec.js b/modules/angular2/test/core/compiler/shadow_dom/content_tag_spec.js
deleted file mode 100644
index 298f05d9bb..0000000000
--- a/modules/angular2/test/core/compiler/shadow_dom/content_tag_spec.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import {describe, beforeEach, it, expect, ddescribe, iit, SpyObject, el, proxy} from 'angular2/test_lib';
-import {IMPLEMENTS} from 'angular2/src/facade/lang';
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
-import {LightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
-
-@proxy
-@IMPLEMENTS(LightDom)
-class DummyLightDom extends SpyObject {noSuchMethod(m){super.noSuchMethod(m)}}
-
-var _scriptStart = `<script start=""></script>`;
-var _scriptEnd = `<script end=""></script>`;
-
-export function main() {
-  describe('Content', function() {
-    var parent;
-    var content;
-
-    beforeEach(() => {
-      parent = el(`<div>${_scriptStart}${_scriptEnd}`);
-      content = DOM.firstChild(parent);
-    });
-
-    it("should insert the nodes", () => {
-      var c = new Content(null, content, '');
-      c.insert([el("<a></a>"), el("<b></b>")])
-
-      expect(DOM.getInnerHTML(parent)).toEqual(`${_scriptStart}<a></a><b></b>${_scriptEnd}`);
-    });
-
-    it("should remove the nodes from the previous insertion", () => {
-      var c = new Content(null, content, '');
-      c.insert([el("<a></a>")]);
-      c.insert([el("<b></b>")]);
-
-      expect(DOM.getInnerHTML(parent)).toEqual(`${_scriptStart}<b></b>${_scriptEnd}`);
-    });
-
-    it("should insert empty list", () => {
-      var c = new Content(null, content, '');
-      c.insert([el("<a></a>")]);
-      c.insert([]);
-
-      expect(DOM.getInnerHTML(parent)).toEqual(`${_scriptStart}${_scriptEnd}`);
-    });
-  });
-}
diff --git a/modules/angular2/test/core/compiler/shadow_dom/light_dom_spec.js b/modules/angular2/test/core/compiler/shadow_dom/light_dom_spec.js
deleted file mode 100644
index a017a7d19d..0000000000
--- a/modules/angular2/test/core/compiler/shadow_dom/light_dom_spec.js
+++ /dev/null
@@ -1,219 +0,0 @@
-import {describe, beforeEach, it, expect, ddescribe, iit, SpyObject, el, proxy} from 'angular2/test_lib';
-import {IMPLEMENTS, isBlank, isPresent} from 'angular2/src/facade/lang';
-import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
-import {LightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
-import {View} from 'angular2/src/core/compiler/view';
-import {ViewContainer} from 'angular2/src/core/compiler/view_container';
-
-@proxy
-@IMPLEMENTS(View)
-class FakeView {
-  contentTags;
-  viewContainers;
-
-  constructor(containers = null) {
-    this.contentTags = [];
-    this.viewContainers = [];
-    if (isPresent(containers)) {
-      ListWrapper.forEach(containers, (c) => {
-        if (c instanceof FakeContentTag) {
-          ListWrapper.push(this.contentTags, c);
-        } else {
-          ListWrapper.push(this.contentTags, null);
-        }
-        if (c instanceof FakeViewContainer) {
-          ListWrapper.push(this.viewContainers, c);
-        } else {
-          ListWrapper.push(this.viewContainers, null);
-        }
-      });
-    }
-  }
-
-  noSuchMethod(i) {
-    super.noSuchMethod(i);
-  }
-}
-
-@proxy
-@IMPLEMENTS(ViewContainer)
-class FakeViewContainer {
-  templateElement;
-  _nodes;
-  _contentTagContainers;
-
-  constructor(templateEl, nodes = null, views = null) {
-    this.templateElement = templateEl;
-    this._nodes = nodes;
-    this._contentTagContainers = views;
-  }
-
-  nodes(){
-    return this._nodes;
-  }
-
-  contentTagContainers(){
-    return this._contentTagContainers;
-  }
-
-  noSuchMethod(i) {
-    super.noSuchMethod(i);
-  }
-}
-
-
-@proxy
-@IMPLEMENTS(Content)
-class FakeContentTag {
-  select;
-  _nodes;
-  contentStartElement;
-
-  constructor(contentEl, select = '', nodes = null) {
-    this.contentStartElement = contentEl;
-    this.select = select;
-    this._nodes = nodes;
-  }
-
-  insert(nodes){
-    this._nodes = ListWrapper.clone(nodes);
-  }
-
-  nodes() {
-    return this._nodes;
-  }
-
-  noSuchMethod(i) {
-    super.noSuchMethod(i);
-  }
-}
-
-
-export function main() {
-  describe('LightDom', function() {
-    var lightDomView;
-
-    beforeEach(() => {
-      lightDomView = new FakeView();
-    });
-
-    describe("contentTags", () => {
-      it("should collect content tags from element injectors", () => {
-        var tag = new FakeContentTag(el('<script></script>'));
-        var shadowDomView = new FakeView([tag]);
-
-        var lightDom = new LightDom(lightDomView, shadowDomView,
-            el("<div></div>"));
-
-        expect(lightDom.contentTags()).toEqual([tag]);
-      });
-
-      it("should collect content tags from ViewContainers", () => {
-        var tag = new FakeContentTag(el('<script></script>'));
-        var vc = new FakeViewContainer(null, null, [
-          new FakeView([tag])
-        ]);
-        var shadowDomView = new FakeView([vc]);
-        var lightDom = new LightDom(lightDomView, shadowDomView,
-            el("<div></div>"));
-
-        expect(lightDom.contentTags()).toEqual([tag]);
-      });
-    });
-
-    describe("expandedDomNodes", () => {
-      it("should contain root nodes", () => {
-        var lightDomEl = el("<div><a></a></div>")
-        var lightDom = new LightDom(lightDomView, new FakeView(), lightDomEl);
-        expect(toHtml(lightDom.expandedDomNodes())).toEqual(["<a></a>"]);
-      });
-
-      it("should include view container nodes", () => {
-        var lightDomEl = el("<div><template></template></div>");
-        var lightDom = new LightDom(
-          new FakeView([
-            new FakeViewContainer(
-              DOM.firstChild(lightDomEl),  // template element
-              [el('<a></a>')]              // light DOM nodes of view container
-            )
-          ]),
-          null,
-          lightDomEl);
-
-        expect(toHtml(lightDom.expandedDomNodes())).toEqual(["<a></a>"]);
-      });
-
-      it("should include content nodes", () => {
-        var lightDomEl = el("<div><content></content></div>");
-        var lightDom = new LightDom(
-          new FakeView([
-            new FakeContentTag(
-              DOM.firstChild(lightDomEl),  // content element
-              '',                          // selector
-              [el('<a></a>')]              // light DOM nodes of content tag
-            )
-          ]),
-          null,
-          lightDomEl);
-
-        expect(toHtml(lightDom.expandedDomNodes())).toEqual(["<a></a>"]);
-      });
-
-      it("should work when the element injector array contains nulls", () => {
-        var lightDomEl = el("<div><a></a></div>")
-
-        var lightDomView = new FakeView();
-
-        var lightDom = new LightDom(
-          lightDomView,
-          new FakeView(),
-          lightDomEl);
-
-        expect(toHtml(lightDom.expandedDomNodes())).toEqual(["<a></a>"]);
-      });
-    });
-
-    describe("redistribute", () => {
-      it("should redistribute nodes between content tags with select property set", () => {
-        var contentA = new FakeContentTag(null, "a");
-        var contentB = new FakeContentTag(null, "b");
-
-        var lightDomEl = el("<div><a>1</a><b>2</b><a>3</a></div>")
-
-        var lightDom = new LightDom(lightDomView, new FakeView([
-          contentA,
-          contentB
-        ]), lightDomEl);
-
-        lightDom.redistribute();
-
-        expect(toHtml(contentA.nodes())).toEqual(["<a>1</a>", "<a>3</a>"]);
-        expect(toHtml(contentB.nodes())).toEqual(["<b>2</b>"]);
-      });
-
-      it("should support wildcard content tags", () => {
-        var wildcard = new FakeContentTag(null, '');
-        var contentB = new FakeContentTag(null, "b");
-
-        var lightDomEl = el("<div><a>1</a><b>2</b><a>3</a></div>")
-
-        var lightDom = new LightDom(lightDomView, new FakeView([
-          wildcard,
-          contentB
-        ]), lightDomEl);
-
-        lightDom.redistribute();
-
-        expect(toHtml(wildcard.nodes())).toEqual(["<a>1</a>", "<b>2</b>", "<a>3</a>"]);
-        expect(toHtml(contentB.nodes())).toEqual([]);
-      });
-    });
-  });
-}
-
-function toHtml(nodes) {
-  if (isBlank(nodes)) return [];
-  return ListWrapper.map(nodes, DOM.getOuterHTML);
-}
diff --git a/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js b/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js
deleted file mode 100644
index e28404a8b9..0000000000
--- a/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js
+++ /dev/null
@@ -1,384 +0,0 @@
-import {
-  AsyncTestCompleter,
-  beforeEach,
-  ddescribe,
-  describe,
-  el,
-  expect,
-  iit,
-  inject,
-  it,
-  xit,
-} from 'angular2/test_lib';
-
-import {StringMapWrapper, List} from 'angular2/src/facade/collection';
-import {Type} from 'angular2/src/facade/lang';
-import {DOM} from 'angular2/src/dom/dom_adapter';
-
-import {Injector} from 'angular2/di';
-import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection';
-import {ExceptionHandler} from 'angular2/src/core/exception_handler';
-
-import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
-import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
-import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
-import {ShadowDomStrategy,
-        NativeShadowDomStrategy,
-        EmulatedScopedShadowDomStrategy,
-        EmulatedUnscopedShadowDomStrategy,
-} from 'angular2/src/core/compiler/shadow_dom_strategy';
-import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
-import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
-import {UrlResolver} from 'angular2/src/services/url_resolver';
-import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
-import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
-
-import {MockTemplateResolver} from 'angular2/src/mock/template_resolver_mock';
-
-import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
-import {Template} from 'angular2/src/core/annotations/template';
-
-import {ViewContainer} from 'angular2/src/core/compiler/view_container';
-
-import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
-
-export function main() {
-  BrowserDomAdapter.makeCurrent();
-  describe('integration tests', function() {
-    var urlResolver;
-    var styleUrlResolver;
-    var styleInliner;
-    var strategies = {
-      "scoped" : () => new EmulatedScopedShadowDomStrategy(styleInliner, styleUrlResolver, DOM.createElement('div')),
-      "unscoped" : () => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, DOM.createElement('div'))
-    }
-    if (DOM.supportsNativeShadowDOM()) {
-      StringMapWrapper.set(strategies, "native", () => new NativeShadowDomStrategy(styleUrlResolver));
-    }
-
-    StringMapWrapper.forEach(strategies,
-      (strategyFactory, name) => {
-
-      describe(`${name} shadow dom strategy`, () => {
-        var compiler, tplResolver;
-
-        beforeEach(() => {
-          urlResolver = new UrlResolver();
-          styleUrlResolver = new StyleUrlResolver(urlResolver);
-          styleInliner = new StyleInliner(null, styleUrlResolver, urlResolver);
-          tplResolver = new MockTemplateResolver();
-          compiler = new Compiler(dynamicChangeDetection,
-            new TemplateLoader(null, null),
-            new DirectiveMetadataReader(),
-            new Parser(new Lexer()),
-            new CompilerCache(),
-            strategyFactory(),
-            tplResolver,
-            new ComponentUrlMapper(),
-            urlResolver
-          );
-        });
-
-        function compile(template, directives: List<Type>, assertions) {
-          tplResolver.setTemplate(MyComp, new Template({
-            inline: template,
-            directives: directives
-          }));
-          compiler.compile(MyComp)
-            .then(createView)
-            .then((view) => {
-              var lc = new LifeCycle(new ExceptionHandler(), view.changeDetector, false);
-              assertions(view, lc);
-            });
-        }
-
-        it('should support simple components', inject([AsyncTestCompleter], (async) => {
-          var temp = '<simple>' +
-            '<div>A</div>' +
-            '</simple>';
-
-          compile(temp, [Simple], (view, lc) => {
-            expect(view.nodes).toHaveText('SIMPLE(A)');
-
-            async.done();
-          });
-        }));
-
-        it('should support multiple content tags', inject([AsyncTestCompleter], (async) => {
-          var temp = '<multiple-content-tags>' +
-            '<div>B</div>' +
-            '<div>C</div>' +
-            '<div class="left">A</div>' +
-          '</multiple-content-tags>';
-
-          compile(temp, [MultipleContentTagsComponent], (view, lc) => {
-            expect(view.nodes).toHaveText('(A, BC)');
-            async.done();
-          });
-        }));
-
-        it('should redistribute only direct children', inject([AsyncTestCompleter], (async) => {
-          var temp = '<multiple-content-tags>' +
-            '<div>B<div class="left">A</div></div>' +
-            '<div>C</div>' +
-            '</multiple-content-tags>';
-
-          compile(temp, [MultipleContentTagsComponent], (view, lc) => {
-            expect(view.nodes).toHaveText('(, BAC)');
-            async.done();
-          });
-        }));
-
-        it("should redistribute direct child viewcontainers when the light dom changes", inject([AsyncTestCompleter], (async) => {
-          var temp = '<multiple-content-tags>' +
-            '<div><div template="manual" class="left">A</div></div>' +
-            '<div>B</div>' +
-            '</multiple-content-tags>';
-
-          compile(temp, [MultipleContentTagsComponent, ManualViewportDirective], (view, lc) => {
-            var dir = view.elementInjectors[1].get(ManualViewportDirective);
-
-            expect(view.nodes).toHaveText('(, B)');
-
-            dir.show();
-            lc.tick();
-
-            expect(view.nodes).toHaveText('(, AB)');
-
-            dir.hide();
-            lc.tick();
-
-            expect(view.nodes).toHaveText('(, B)');
-
-            async.done();
-          });
-        }));
-
-        it("should redistribute when the light dom changes", inject([AsyncTestCompleter], (async) => {
-          var temp = '<multiple-content-tags>' +
-            '<div template="manual" class="left">A</div>' +
-            '<div>B</div>' +
-            '</multiple-content-tags>';
-
-          compile(temp, [MultipleContentTagsComponent, ManualViewportDirective], (view, lc) => {
-            var dir = view.elementInjectors[1].get(ManualViewportDirective);
-
-            expect(view.nodes).toHaveText('(, B)');
-
-            dir.show();
-            lc.tick();
-
-            expect(view.nodes).toHaveText('(A, B)');
-
-            dir.hide();
-            lc.tick();
-
-            expect(view.nodes).toHaveText('(, B)');
-
-            async.done();
-          });
-        }));
-
-        it("should support nested components", inject([AsyncTestCompleter], (async) => {
-          var temp = '<outer-with-indirect-nested>' +
-            '<div>A</div>' +
-            '<div>B</div>' +
-            '</outer-with-indirect-nested>';
-
-          compile(temp, [OuterWithIndirectNestedComponent], (view, lc) => {
-            expect(view.nodes).toHaveText('OUTER(SIMPLE(AB))');
-
-            async.done();
-          });
-        }));
-
-        it("should support nesting with content being direct child of a nested component", inject([AsyncTestCompleter], (async) => {
-          var temp = '<outer>' +
-            '<div template="manual" class="left">A</div>' +
-            '<div>B</div>' +
-            '<div>C</div>' +
-            '</outer>';
-
-          compile(temp, [OuterComponent, ManualViewportDirective], (view, lc) => {
-            var dir = view.elementInjectors[1].get(ManualViewportDirective);
-
-            expect(view.nodes).toHaveText('OUTER(INNER(INNERINNER(,BC)))');
-
-            dir.show();
-            lc.tick();
-
-            expect(view.nodes).toHaveText('OUTER(INNER(INNERINNER(A,BC)))');
-            async.done();
-          });
-        }));
-
-        it('should redistribute when the shadow dom changes', inject([AsyncTestCompleter], (async) => {
-          var temp = '<conditional-content>' +
-            '<div class="left">A</div>' +
-            '<div>B</div>' +
-            '<div>C</div>' +
-            '</conditional-content>';
-
-
-          compile(temp, [ConditionalContentComponent, AutoViewportDirective], (view, lc) => {
-            var cmp = view.elementInjectors[0].get(ConditionalContentComponent);
-
-            expect(view.nodes).toHaveText('(, ABC)');
-
-            cmp.showLeft();
-            lc.tick();
-
-            expect(view.nodes).toHaveText('(A, BC)');
-
-            cmp.hideLeft();
-            lc.tick();
-
-            expect(view.nodes).toHaveText('(, ABC)');
-
-            async.done();
-          });
-        }));
-
-        //Implement once NgElement support changing a class
-        //it("should redistribute when a class has been added or removed");
-        //it('should not lose focus', () => {
-        //  var temp = `<simple>aaa<input type="text" id="focused-input" ng-class="{'aClass' : showClass}"> bbb</simple>`;
-        //
-        //  compile(temp, (view, lc) => {
-        //    var input = view.nodes[1];
-        //    input.focus();
-        //
-        //    expect(document.activeElement.id).toEqual("focused-input");
-        //
-        //    // update class of input
-        //
-        //    expect(document.activeElement.id).toEqual("focused-input");
-        //  });
-        //});
-      });
-    });
-
-  });
-}
-
-class TestDirectiveMetadataReader extends DirectiveMetadataReader {
-  shadowDomStrategy;
-
-  constructor(shadowDomStrategy) {
-    super();
-    this.shadowDomStrategy = shadowDomStrategy;
-  }
-
-  parseShadowDomStrategy(annotation:Component):ShadowDomStrategy{
-    return this.shadowDomStrategy;
-  }
-}
-
-@Viewport({
-  selector: '[manual]'
-})
-class ManualViewportDirective {
-  viewContainer;
-  constructor(viewContainer:ViewContainer) {
-    this.viewContainer = viewContainer;
-  }
-
-  show() { this.viewContainer.create(); }
-  hide() { this.viewContainer.remove(0); }
-}
-
-@Viewport({
-  selector: '[auto]',
-  bind: {
-    'auto': 'auto'
-  }
-})
-class AutoViewportDirective {
-  viewContainer;
-  constructor(viewContainer:ViewContainer) {
-    this.viewContainer = viewContainer;
-  }
-
-  set auto(newValue:boolean) {
-    if (newValue) {
-      this.viewContainer.create();
-    } else {
-      this.viewContainer.remove(0);
-    }
-  }
-}
-
-@Component({selector: 'simple'})
-@Template({inline: 'SIMPLE(<content></content>)'})
-class Simple {
-}
-
-@Component({selector: 'multiple-content-tags'})
-@Template({
-  inline: '(<content select=".left"></content>, <content></content>)'
-})
-class MultipleContentTagsComponent {
-}
-
-
-@Component({selector: 'conditional-content'})
-@Template({
-  inline: '<div>(<div *auto="cond"><content select=".left"></content></div>, <content></content>)</div>',
-  directives: [AutoViewportDirective]
-})
-class ConditionalContentComponent  {
-  cond:boolean;
-
-  constructor() {
-    this.cond = false;
-  }
-
-  showLeft() { this.cond = true; }
-  hideLeft() { this.cond = false; }
-}
-
-@Component({selector: 'outer-with-indirect-nested'})
-@Template({
-  inline: 'OUTER(<simple><div><content></content></div></simple>)',
-  directives: [Simple]
-})
-class OuterWithIndirectNestedComponent  {
-}
-
-@Component({selector: 'outer'})
-@Template({
-  inline: 'OUTER(<inner><content></content></inner>)',
-  directives: [InnerComponent]
-})
-class OuterComponent {
-}
-
-@Component({selector: 'inner'})
-@Template({
-  inline: 'INNER(<innerinner><content></content></innerinner>)',
-  directives: [InnerInnerComponent]
-})
-class InnerComponent {
-}
-
-@Component({selector: 'innerinner'})
-@Template({
-  inline: 'INNERINNER(<content select=".left"></content>,<content></content>)'
-})
-class InnerInnerComponent {
-}
-
-
-@Component({selector: 'my-comp'})
-@Template({
-  directives: [MultipleContentTagsComponent, ManualViewportDirective,
-    ConditionalContentComponent, OuterWithIndirectNestedComponent, OuterComponent]
-})
-class MyComp {
-}
-
-function createView(pv) {
-  var view = pv.instantiate(null, null);
-  view.hydrate(new Injector([]), null, null, {}, null);
-  return view;
-}
diff --git a/modules/angular2/test/core/compiler/shadow_dom_strategy_spec.js b/modules/angular2/test/core/compiler/shadow_dom_strategy_spec.js
deleted file mode 100644
index 7638a58d45..0000000000
--- a/modules/angular2/test/core/compiler/shadow_dom_strategy_spec.js
+++ /dev/null
@@ -1,130 +0,0 @@
-import {
-  AsyncTestCompleter,
-  beforeEach,
-  ddescribe,
-  describe,
-  el,
-  expect,
-  iit,
-  inject,
-  it,
-  SpyObject,
-} from 'angular2/test_lib';
-
-import {
-  NativeShadowDomStrategy,
-  EmulatedScopedShadowDomStrategy,
-  EmulatedUnscopedShadowDomStrategy
-} from 'angular2/src/core/compiler/shadow_dom_strategy';
-import {UrlResolver} from 'angular2/src/services/url_resolver';
-import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
-import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
-import {ProtoView} from 'angular2/src/core/compiler/view';
-
-import {XHR} from 'angular2/src/services/xhr';
-
-import {isPresent, isBlank} from 'angular2/src/facade/lang';
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {Map, MapWrapper} from 'angular2/src/facade/collection';
-import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
-
-import {DynamicProtoChangeDetector} from 'angular2/change_detection';
-
-export function main() {
-  var strategy;
-
-  describe('NativeShadowDomStratgey', () => {
-    beforeEach(() => {
-      var urlResolver = new UrlResolver();
-      var styleUrlResolver = new StyleUrlResolver(urlResolver);
-      strategy = new NativeShadowDomStrategy(styleUrlResolver);
-    });
-
-    it('should attach the view nodes to the shadow root', () => {
-      var host = el('<div></div>');
-      var nodes = el('<div>view</div>');
-      var pv = new ProtoView(null, nodes, new DynamicProtoChangeDetector(null, null), null);
-      var view = pv.instantiate(null, null);
-
-      strategy.attachTemplate(host, view);
-      var shadowRoot = DOM.getShadowRoot(host);
-      expect(isPresent(shadowRoot)).toBeTruthy();
-      expect(shadowRoot).toHaveText('view');
-    });
-  });
-
-  describe('EmulatedScopedShadowDomStratgey', () => {
-    var xhr, styleHost;
-
-    beforeEach(() => {
-      var urlResolver = new UrlResolver();
-      var styleUrlResolver = new StyleUrlResolver(urlResolver);
-      xhr = new FakeXHR();
-      var styleInliner = new StyleInliner(xhr, styleUrlResolver, urlResolver);
-      styleHost = el('<div></div>');
-      strategy = new EmulatedScopedShadowDomStrategy(styleInliner, styleUrlResolver, styleHost);
-    });
-
-    it('should attach the view nodes as child of the host element', () => {
-      var host = el('<div><span>original content</span></div>');
-      var nodes = el('<div>view</div>');
-      var pv = new ProtoView(null, nodes, new DynamicProtoChangeDetector(null, null), null);
-      var view = pv.instantiate(null, null);
-
-      strategy.attachTemplate(host, view);
-      var firstChild = DOM.firstChild(host);
-      expect(DOM.tagName(firstChild).toLowerCase()).toEqual('div');
-      expect(firstChild).toHaveText('view');
-      expect(host).toHaveText('view');
-    });
-  });
-
-  describe('EmulatedUnscopedShadowDomStratgey', () => {
-    var styleHost;
-
-    beforeEach(() => {
-      var urlResolver = new UrlResolver();
-      var styleUrlResolver = new StyleUrlResolver(urlResolver);
-      styleHost = el('<div></div>');
-      strategy = new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, styleHost);
-    });
-
-    it('should attach the view nodes as child of the host element', () => {
-      var host = el('<div><span>original content</span></div>');
-      var nodes = el('<div>view</div>');
-      var pv = new ProtoView(null, nodes, new DynamicProtoChangeDetector(null, null), null);
-      var view = pv.instantiate(null, null);
-
-      strategy.attachTemplate(host, view);
-      var firstChild = DOM.firstChild(host);
-      expect(DOM.tagName(firstChild).toLowerCase()).toEqual('div');
-      expect(firstChild).toHaveText('view');
-      expect(host).toHaveText('view');
-    });
-  });
-}
-
-class FakeXHR extends XHR {
-  _responses: Map;
-
-  constructor() {
-    super();
-    this._responses = MapWrapper.create();
-  }
-
-  get(url: string): Promise<string> {
-    var response = MapWrapper.get(this._responses, url);
-    if (isBlank(response)) {
-      return PromiseWrapper.reject('xhr error');
-    }
-
-    return PromiseWrapper.resolve(response);
-  }
-
-  reply(url: string, response: string) {
-    MapWrapper.set(this._responses, url, response);
-  }
-}
-
-class SomeComponent {}
-class SomeOtherComponent {}
diff --git a/modules/angular2/test/core/compiler/view_container_spec.js b/modules/angular2/test/core/compiler/view_container_spec.js
deleted file mode 100644
index ee8b88980c..0000000000
--- a/modules/angular2/test/core/compiler/view_container_spec.js
+++ /dev/null
@@ -1,251 +0,0 @@
-import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, proxy} from 'angular2/test_lib';
-import {View, ProtoView} from 'angular2/src/core/compiler/view';
-import {ViewContainer} from 'angular2/src/core/compiler/view_container';
-import {IMPLEMENTS} from 'angular2/src/facade/lang';
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
-import {Injector} from 'angular2/di';
-import {ProtoElementInjector, ElementInjector} from 'angular2/src/core/compiler/element_injector';
-import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
-import {DynamicProtoChangeDetector, ChangeDetector, Lexer, Parser} from 'angular2/change_detection';
-
-function createView(nodes) {
-  var view = new View(null, nodes, MapWrapper.create());
-  var cd = new DynamicProtoChangeDetector(null, null).instantiate(view, [], null, []);
-  view.init(cd, [], [], [], [], [], [], [], [], []);
-  return view;
-}
-
-@proxy
-@IMPLEMENTS(ChangeDetector)
-class AttachableChangeDetector {
-  parent;
-  constructor() {
-  }
-  remove() {
-    this.parent = null;
-  }
-  noSuchMethod(i) {
-    super.noSuchMethod(i);
-  }
-}
-
-@proxy
-@IMPLEMENTS(View)
-class HydrateAwareFakeView {
-  isHydrated: boolean;
-  nodes: List;
-  changeDetector: ChangeDetector;
-  rootElementInjectors;
-  constructor(isHydrated) {
-    this.isHydrated = isHydrated;
-    this.nodes = [DOM.createElement('div')];
-    this.rootElementInjectors = [];
-    this.changeDetector = new AttachableChangeDetector();
-  }
-
-  hydrated() {
-    return this.isHydrated;
-  }
-
-
-  hydrate(_, __, ___, ____, _____) {
-    this.isHydrated = true;
-  }
-
-  dehydrate() {
-    this.isHydrated = false;
-  }
-
-  noSuchMethod(i) {
-    super.noSuchMethod(i);
-  }
-}
-
-export function main() {
-  describe('ViewContainer', () => {
-    var viewContainer, parentView, protoView, dom, customViewWithOneNode,
-        customViewWithTwoNodes, elementInjector;
-
-    beforeEach(() => {
-      dom = el(`<div><stuff></stuff><div insert-after-me></div><stuff></stuff></div>`);
-      var insertionElement = dom.childNodes[1];
-      parentView = createView([dom.childNodes[0]]);
-      protoView = new ProtoView(null, el('<div>hi</div>'), new DynamicProtoChangeDetector(null, null),
-        new NativeShadowDomStrategy(null));
-      elementInjector = new ElementInjector(null, null, null);
-      viewContainer = new ViewContainer(parentView, insertionElement, protoView, elementInjector,
-        null);
-      customViewWithOneNode = createView([el('<div>single</div>')]);
-      customViewWithTwoNodes = createView([el('<div>one</div>'), el('<div>two</div>')]);
-    });
-
-    describe('when dehydrated', () => {
-      it('should throw if create is called', () => {
-        expect(() => viewContainer.create()).toThrowError();
-      });
-    });
-
-    describe('when hydrated', () => {
-      function textInViewContainer() {
-        var out = '';
-        // skipping starting filler, insert-me and final filler.
-        for (var i = 2; i < dom.childNodes.length - 1; i++) {
-          if (i != 2) out += ' ';
-          out += DOM.getInnerHTML(dom.childNodes[i]);
-        }
-        return out;
-      }
-
-      beforeEach(() => {
-        viewContainer.hydrate(new Injector([]), null, null);
-        var fillerView = createView([el('<filler>filler</filler>')]);
-        viewContainer.insert(fillerView);
-      });
-
-      it('should create new views from protoView', () => {
-        viewContainer.create();
-        expect(textInViewContainer()).toEqual('filler hi');
-        expect(viewContainer.length).toBe(2);
-      });
-
-      it('should create new views from protoView at index', () => {
-        viewContainer.create(0);
-        expect(textInViewContainer()).toEqual('hi filler');
-        expect(viewContainer.length).toBe(2);
-      });
-
-      it('should insert new views at the end by default', () => {
-        viewContainer.insert(customViewWithOneNode);
-        expect(textInViewContainer()).toEqual('filler single');
-        expect(viewContainer.get(1)).toBe(customViewWithOneNode);
-        expect(viewContainer.length).toBe(2);
-      });
-
-      it('should insert new views at the given index', () => {
-        viewContainer.insert(customViewWithOneNode, 0);
-        expect(textInViewContainer()).toEqual('single filler');
-        expect(viewContainer.get(0)).toBe(customViewWithOneNode);
-        expect(viewContainer.length).toBe(2);
-      });
-
-      it('should remove the last view by default', () => {
-        viewContainer.insert(customViewWithOneNode);
-
-        viewContainer.remove();
-
-        expect(textInViewContainer()).toEqual('filler');
-        expect(viewContainer.length).toBe(1);
-      });
-
-      it('should remove the view at a given index', () => {
-        viewContainer.insert(customViewWithOneNode);
-        viewContainer.insert(customViewWithTwoNodes);
-
-        viewContainer.remove(1);
-
-        expect(textInViewContainer()).toEqual('filler one two');
-        expect(viewContainer.get(1)).toBe(customViewWithTwoNodes);
-        expect(viewContainer.length).toBe(2);
-      });
-
-      it('should detach the last view by default', () => {
-        viewContainer.insert(customViewWithOneNode);
-        expect(viewContainer.length).toBe(2);
-
-        var detachedView = viewContainer.detach();
-
-        expect(detachedView).toBe(customViewWithOneNode);
-        expect(textInViewContainer()).toEqual('filler');
-        expect(viewContainer.length).toBe(1);
-      });
-
-      it('should detach the view at a given index', () => {
-        viewContainer.insert(customViewWithOneNode);
-        viewContainer.insert(customViewWithTwoNodes);
-        expect(viewContainer.length).toBe(3);
-
-        var detachedView = viewContainer.detach(1);
-        expect(detachedView).toBe(customViewWithOneNode);
-        expect(textInViewContainer()).toEqual('filler one two');
-        expect(viewContainer.length).toBe(2);
-      });
-
-      it('should keep views hydration state during insert', () => {
-        var hydratedView = new HydrateAwareFakeView(true);
-        var dehydratedView = new HydrateAwareFakeView(false);
-        viewContainer.insert(hydratedView);
-        viewContainer.insert(dehydratedView);
-
-        expect(hydratedView.hydrated()).toBe(true);
-        expect(dehydratedView.hydrated()).toBe(false);
-      });
-
-      it('should dehydrate on remove', () => {
-        var hydratedView = new HydrateAwareFakeView(true);
-        viewContainer.insert(hydratedView);
-        viewContainer.remove();
-
-        expect(hydratedView.hydrated()).toBe(false);
-      });
-
-      it('should keep views hydration state during detach', () => {
-        var hydratedView = new HydrateAwareFakeView(true);
-        var dehydratedView = new HydrateAwareFakeView(false);
-        viewContainer.insert(hydratedView);
-        viewContainer.insert(dehydratedView);
-
-        expect(viewContainer.detach().hydrated()).toBe(false);
-        expect(viewContainer.detach().hydrated()).toBe(true);
-      });
-
-      it('should support adding/removing views with more than one node', () => {
-        viewContainer.insert(customViewWithTwoNodes);
-        viewContainer.insert(customViewWithOneNode);
-
-        expect(textInViewContainer()).toEqual('filler one two single');
-
-        viewContainer.remove(1);
-        expect(textInViewContainer()).toEqual('filler single');
-      });
-    });
-
-    describe('should update injectors and parent views.', () => {
-      var fancyView;
-      beforeEach(() => {
-        var parser = new Parser(new Lexer());
-        viewContainer.hydrate(new Injector([]), null, null);
-
-        var pv = new ProtoView(null, el('<div class="ng-binding">{{}}</div>'),
-          new DynamicProtoChangeDetector(null, null), new NativeShadowDomStrategy(null));
-        pv.bindElement(null, 0, new ProtoElementInjector(null, 1, [SomeDirective]));
-        pv.bindTextNode(0, parser.parseBinding('foo', null));
-        fancyView = pv.instantiate(null, null);
-      });
-
-      it('hydrating should update rootElementInjectors and parent change detector', () => {
-        viewContainer.insert(fancyView);
-        ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
-            expect(inj.parent).toBe(elementInjector));
-
-        expect(parentView.changeDetector.lightDomChildren.length).toBe(1);
-      });
-
-      it('dehydrating should update rootElementInjectors and parent change detector', () => {
-        viewContainer.insert(fancyView);
-        viewContainer.remove();
-        ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
-            expect(inj.parent).toBe(null));
-        expect(parentView.changeDetector.lightDomChildren.length).toBe(0);
-        expect(viewContainer.length).toBe(0);
-      });
-    });
-  });
-}
-
-class SomeDirective {
-  prop;
-  constructor() {
-    this.prop = 'foo';
-  }
-}
diff --git a/modules/angular2/test/core/compiler/view_pool_spec.js b/modules/angular2/test/core/compiler/view_pool_spec.js
deleted file mode 100644
index 3146233244..0000000000
--- a/modules/angular2/test/core/compiler/view_pool_spec.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, proxy} from 'angular2/test_lib';
-
-import {View} from 'angular2/src/core/compiler/view';
-import {ViewPool} from 'angular2/src/core/compiler/view_pool';
-import {IMPLEMENTS} from 'angular2/src/facade/lang';
-
-@proxy
-@IMPLEMENTS(View)
-class FakeView {
-  noSuchMethod(i) {
-    super.noSuchMethod(i);
-  }
-}
-
-export function main() {
-  describe('ViewPool', () => {
-    var viewPool, capacity = 3;
-    beforeEach(() => {
-      viewPool = new ViewPool(capacity);
-    })
-
-    it('should return null when there are no views', () => {
-      expect(viewPool.pop()).toBeNull();
-      expect(viewPool.length()).toBe(0);
-    })
-
-    it('should support storing and retrieving a view', () => {
-      var view = new FakeView();
-      viewPool.push(view);
-      expect(viewPool.length()).toBe(1);
-
-      expect(viewPool.pop()).toBe(view);
-      expect(viewPool.length()).toBe(0);
-    })
-
-    it('should not store more views that its capacity', () => {
-      for (var i = 0; i < capacity * 2; i++) viewPool.push(new FakeView());
-      expect(viewPool.length()).toBe(capacity);
-
-      for (var i = 0; i < capacity; i++) {
-        expect(viewPool.pop()).not.toBe(null);
-      }
-      expect(viewPool.pop()).toBeNull();
-    })
-  })
-}
diff --git a/modules/angular2/test/core/compiler/view_spec.js b/modules/angular2/test/core/compiler/view_spec.js
deleted file mode 100644
index b8c523fa66..0000000000
--- a/modules/angular2/test/core/compiler/view_spec.js
+++ /dev/null
@@ -1,787 +0,0 @@
-import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, proxy} from 'angular2/test_lib';
-import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'angular2/src/core/compiler/view';
-import {ProtoElementInjector, ElementInjector, DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
-import {EmulatedScopedShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
-import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
-import {Component, Decorator, Viewport, Directive, onChange, onAllChangesDone} from 'angular2/src/core/annotations/annotations';
-import {Lexer, Parser, DynamicProtoChangeDetector,
-  ChangeDetector} from 'angular2/change_detection';
-import {EventEmitter} from 'angular2/src/core/annotations/di';
-import {List, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
-import {DOM} from 'angular2/src/dom/dom_adapter';
-import {int, IMPLEMENTS} from 'angular2/src/facade/lang';
-import {Injector} from 'angular2/di';
-import {View} from 'angular2/src/core/compiler/view';
-import {ViewContainer} from 'angular2/src/core/compiler/view_container';
-import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
-import {EventManager, DomEventsPlugin} from 'angular2/src/render/dom/events/event_manager';
-import {reflector} from 'angular2/src/reflection/reflection';
-
-class DummyDirective extends Directive {
-  constructor({lifecycle} = {}) { super({lifecycle: lifecycle}); }
-}
-
-@proxy
-@IMPLEMENTS(ViewContainer)
-class FakeViewContainer {
-  templateElement;
-
-  constructor(templateElement) {
-    this.templateElement = templateElement;
-  }
-
-  noSuchMethod(i) {
-    super.noSuchMethod(i);
-  }
-}
-
-@proxy
-@IMPLEMENTS(View)
-class FakeView {
-  noSuchMethod(i) {
-    super.noSuchMethod(i);
-  }
-}
-
-export function main() {
-  describe('view', function() {
-    var parser, someComponentDirective, someViewportDirective;
-
-    function createView(protoView, eventManager: EventManager = null) {
-      var ctx = new MyEvaluationContext();
-      var view = protoView.instantiate(null, eventManager);
-      view.hydrate(null, null, null, ctx, null);
-      return view;
-    }
-
-    beforeEach(() => {
-      parser = new Parser(new Lexer());
-      someComponentDirective = readDirectiveBinding(SomeComponent);
-      someViewportDirective = readDirectiveBinding(SomeViewport);
-    });
-
-    describe('instantiated from protoView', () => {
-      var view;
-      beforeEach(() => {
-        var pv = new ProtoView(null, el('<div id="1"></div>'), new DynamicProtoChangeDetector(null, null), null);
-        view = pv.instantiate(null, null);
-      });
-
-      it('should be dehydrated by default', () => {
-        expect(view.hydrated()).toBe(false);
-      });
-
-      it('should be able to be hydrated and dehydrated', () => {
-        var ctx = new Object();
-        view.hydrate(null, null, null, ctx, null);
-        expect(view.hydrated()).toBe(true);
-
-        view.dehydrate();
-        expect(view.hydrated()).toBe(false);
-      });
-
-      it('should hydrate and dehydrate the change detector', () => {
-        var ctx = new Object();
-        view.hydrate(null, null, null, ctx, null);
-        expect(view.changeDetector.hydrated()).toBe(true);
-
-        view.dehydrate();
-        expect(view.changeDetector.hydrated()).toBe(false);
-      });
-
-      it('should use the view pool to reuse views', () => {
-        var pv = new ProtoView(null, el('<div id="1"></div>'), new DynamicProtoChangeDetector(null, null), null);
-        var fakeView = new FakeView();
-        pv.returnToPool(fakeView);
-
-        expect(pv.instantiate(null, null)).toBe(fakeView);
-      });
-    });
-
-    describe('with locals', function() {
-      var view;
-      beforeEach(() => {
-        var pv = new ProtoView(null, el('<div id="1"></div>'), new DynamicProtoChangeDetector(null, null), null);
-        pv.bindVariable('context-foo', 'template-foo');
-        view = createView(pv);
-      });
-
-      it('should support setting of declared locals', () => {
-        view.setLocal('context-foo', 'bar');
-        expect(view.locals.get('template-foo')).toBe('bar');
-      });
-
-      it('should not throw on undeclared locals', () => {
-        expect(() => view.setLocal('setMePlease', 'bar')).not.toThrow();
-      });
-
-      it('when dehydrated should set locals to null', () => {
-        view.setLocal('context-foo', 'bar');
-        view.dehydrate();
-        view.hydrate(null, null, null, new Object(), null);
-        expect(view.locals.get('template-foo')).toBe(null);
-      });
-
-      it('should throw when trying to set on dehydrated view', () => {
-        view.dehydrate();
-        expect(() => view.setLocal('context-foo', 'bar')).toThrowError();
-      });
-    });
-
-    describe('instantiated and hydrated', function() {
-
-      function createCollectDomNodesTestCases(useTemplateElement:boolean) {
-
-        function templateAwareCreateElement(html) {
-          return el(useTemplateElement ? `<template>${html}</template>` : html);
-        }
-
-        it('should collect the root node in the ProtoView element', () => {
-          var pv = new ProtoView(null, templateAwareCreateElement('<div id="1"></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          var view = pv.instantiate(null, null);
-          view.hydrate(null, null, null, null, null);
-          expect(view.nodes.length).toBe(1);
-          expect(DOM.getAttribute(view.nodes[0], 'id')).toEqual('1');
-        });
-
-        describe('collect elements with property bindings', () => {
-
-          it('should collect property bindings on the root element if it has the ng-binding class', () => {
-            var pv = new ProtoView(null, templateAwareCreateElement('<div [prop]="a" class="ng-binding"></div>'),
-              new DynamicProtoChangeDetector(null, null), null);
-            pv.bindElement(null, 0, null);
-            pv.bindElementProperty(parser.parseBinding('a', null), 'prop', reflector.setter('prop'));
-
-            var view = pv.instantiate(null, null);
-            view.hydrate(null, null, null, null, null);
-            expect(view.bindElements.length).toEqual(1);
-            expect(view.bindElements[0]).toBe(view.nodes[0]);
-          });
-
-          it('should collect property bindings on child elements with ng-binding class', () => {
-            var pv = new ProtoView(null, templateAwareCreateElement('<div><span></span><span class="ng-binding"></span></div>'),
-              new DynamicProtoChangeDetector(null, null), null);
-            pv.bindElement(null, 0, null);
-            pv.bindElementProperty(parser.parseBinding('b', null), 'a', reflector.setter('a'));
-
-            var view = pv.instantiate(null, null);
-            view.hydrate(null, null, null, null, null);
-            expect(view.bindElements.length).toEqual(1);
-            expect(view.bindElements[0]).toBe(view.nodes[0].childNodes[1]);
-          });
-
-        });
-
-        describe('collect text nodes with bindings', () => {
-
-          it('should collect text nodes under the root element', () => {
-            var pv = new ProtoView(null, templateAwareCreateElement('<div class="ng-binding">{{}}<span></span>{{}}</div>'),
-              new DynamicProtoChangeDetector(null, null), null);
-            pv.bindElement(null, 0, null);
-            pv.bindTextNode(0, parser.parseBinding('a', null));
-            pv.bindTextNode(2, parser.parseBinding('b', null));
-
-            var view = pv.instantiate(null, null);
-            view.hydrate(null, null, null, null, null);
-            expect(view.textNodes.length).toEqual(2);
-            expect(view.textNodes[0]).toBe(view.nodes[0].childNodes[0]);
-            expect(view.textNodes[1]).toBe(view.nodes[0].childNodes[2]);
-          });
-
-          it('should collect text nodes with bindings on child elements with ng-binding class', () => {
-            var pv = new ProtoView(null, templateAwareCreateElement('<div><span> </span><span class="ng-binding">{{}}</span></div>'),
-              new DynamicProtoChangeDetector(null, null), null);
-            pv.bindElement(null, 0, null);
-            pv.bindTextNode(0, parser.parseBinding('b', null));
-
-            var view = pv.instantiate(null, null);
-            view.hydrate(null, null, null, null, null);
-            expect(view.textNodes.length).toEqual(1);
-            expect(view.textNodes[0]).toBe(view.nodes[0].childNodes[1].childNodes[0]);
-          });
-
-        });
-      }
-
-      describe('inplace instantiation', () => {
-        it('should be supported.', () => {
-          var template = el('<div></div>');
-          var pv = new ProtoView(null, template, new DynamicProtoChangeDetector(null, null),
-            new NativeShadowDomStrategy(null));
-          pv.instantiateInPlace = true;
-          var view = pv.instantiate(null, null);
-          view.hydrate(null, null, null, null, null);
-          expect(view.nodes[0]).toBe(template);
-        });
-
-        it('should be off by default.', () => {
-          var template = el('<div></div>')
-          var pv = new ProtoView(null, template, new DynamicProtoChangeDetector(null, null),
-            new NativeShadowDomStrategy(null))
-          var view = pv.instantiate(null, null);
-          view.hydrate(null, null, null, null, null);
-          expect(view.nodes[0]).not.toBe(template);
-        });
-      });
-
-      describe('collect dom nodes with a regular element as root', () => {
-        createCollectDomNodesTestCases(false);
-      });
-
-      describe('collect dom nodes with a template element as root', () => {
-        createCollectDomNodesTestCases(true);
-      });
-
-      describe('create ElementInjectors', () => {
-        it('should use the directives of the ProtoElementInjector', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          pv.bindElement(null, 0, new ProtoElementInjector(null, 1, [SomeDirective]));
-
-          var view = pv.instantiate(null, null);
-          view.hydrate(null, null, null, null, null);
-          expect(view.elementInjectors.length).toBe(1);
-          expect(view.elementInjectors[0].get(SomeDirective) instanceof SomeDirective).toBe(true);
-        });
-
-        it('should use the correct parent', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"><span class="ng-binding"></span></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          var protoParent = new ProtoElementInjector(null, 0, [SomeDirective]);
-          pv.bindElement(null, 0, protoParent);
-          pv.bindElement(null, 0, new ProtoElementInjector(protoParent, 1, [AnotherDirective]));
-
-          var view = pv.instantiate(null, null);
-          view.hydrate(null, null, null, null, null);
-          expect(view.elementInjectors.length).toBe(2);
-          expect(view.elementInjectors[0].get(SomeDirective) instanceof SomeDirective).toBe(true);
-          expect(view.elementInjectors[1].parent).toBe(view.elementInjectors[0]);
-        });
-
-        it('should not pass the host injector when a parent injector exists', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"><span class="ng-binding"></span></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          var protoParent = new ProtoElementInjector(null, 0, [SomeDirective]);
-          pv.bindElement(null, 0, protoParent);
-          var testProtoElementInjector = new TestProtoElementInjector(protoParent, 1, [AnotherDirective]);
-          pv.bindElement(null, 0, testProtoElementInjector);
-
-          var hostProtoInjector = new ProtoElementInjector(null, 0, []);
-          var hostInjector = hostProtoInjector.instantiate(null, null);
-          var view;
-          expect(() => view = pv.instantiate(hostInjector, null)).not.toThrow();
-          expect(testProtoElementInjector.parentElementInjector).toBe(view.elementInjectors[0]);
-          expect(testProtoElementInjector.hostElementInjector).toBeNull();
-        });
-
-        it('should pass the host injector when there is no parent injector', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"><span class="ng-binding"></span></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [SomeDirective]));
-          var testProtoElementInjector = new TestProtoElementInjector(null, 1, [AnotherDirective]);
-          pv.bindElement(null, 0, testProtoElementInjector);
-
-          var hostProtoInjector = new ProtoElementInjector(null, 0, []);
-          var hostInjector = hostProtoInjector.instantiate(null, null);
-          expect(() => pv.instantiate(hostInjector, null)).not.toThrow();
-          expect(testProtoElementInjector.parentElementInjector).toBeNull();
-          expect(testProtoElementInjector.hostElementInjector).toBe(hostInjector);
-        });
-      });
-
-      describe('collect root element injectors', () => {
-
-        it('should collect a single root element injector', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"><span class="ng-binding"></span></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          var protoParent = new ProtoElementInjector(null, 0, [SomeDirective]);
-          pv.bindElement(null, 0, protoParent);
-          pv.bindElement(null, 0, new ProtoElementInjector(protoParent, 1, [AnotherDirective]));
-
-          var view = pv.instantiate(null, null);
-          view.hydrate(null, null, null, null, null);
-          expect(view.rootElementInjectors.length).toBe(1);
-          expect(view.rootElementInjectors[0].get(SomeDirective) instanceof SomeDirective).toBe(true);
-        });
-
-        it('should collect multiple root element injectors', () => {
-          var pv = new ProtoView(null, el('<div><span class="ng-binding"></span><span class="ng-binding"></span></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          pv.bindElement(null, 0, new ProtoElementInjector(null, 1, [SomeDirective]));
-          pv.bindElement(null, 0, new ProtoElementInjector(null, 2, [AnotherDirective]));
-
-          var view = pv.instantiate(null, null);
-          view.hydrate(null, null, null, null, null);
-          expect(view.rootElementInjectors.length).toBe(2)
-          expect(view.rootElementInjectors[0].get(SomeDirective) instanceof SomeDirective).toBe(true);
-          expect(view.rootElementInjectors[1].get(AnotherDirective) instanceof AnotherDirective).toBe(true);
-        });
-
-      });
-
-      describe('with component views', () => {
-        var ctx;
-
-        function createComponentWithSubPV(subProtoView) {
-          var pv = new ProtoView(null, el('<cmp class="ng-binding"></cmp>'),
-            new DynamicProtoChangeDetector(null, null), new NativeShadowDomStrategy(null));
-          var binder = pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [SomeComponent], true));
-          binder.componentDirective = someComponentDirective;
-          binder.nestedProtoView = subProtoView;
-          return pv;
-        }
-
-        function createNestedView(protoView) {
-          ctx = new MyEvaluationContext();
-          var view = protoView.instantiate(null, null);
-          view.hydrate(new Injector([]), null, null, ctx, null);
-          return view;
-        }
-
-        it('should expose component services to the component', () => {
-          var subpv = new ProtoView(null, el('<span></span>'), new DynamicProtoChangeDetector(null, null), null);
-          var pv = createComponentWithSubPV(subpv);
-
-          var view = createNestedView(pv);
-
-          var comp = view.rootElementInjectors[0].get(SomeComponent);
-          expect(comp.service).toBeAnInstanceOf(SomeService);
-        });
-
-        it('should expose component services and component instance to directives in the shadow Dom',
-          () => {
-            var subpv = new ProtoView(null,
-              el('<div dec class="ng-binding">hello shadow dom</div>'),
-              new DynamicProtoChangeDetector(null, null),
-              null);
-            subpv.bindElement(null, 0,
-              new ProtoElementInjector(null, 0, [ServiceDependentDecorator]));
-            var pv = createComponentWithSubPV(subpv);
-
-            var view = createNestedView(pv);
-
-            var subView = view.componentChildViews[0];
-            var subInj = subView.rootElementInjectors[0];
-            var subDecorator = subInj.get(ServiceDependentDecorator);
-            var comp = view.rootElementInjectors[0].get(SomeComponent);
-
-            expect(subDecorator).toBeAnInstanceOf(ServiceDependentDecorator);
-            expect(subDecorator.service).toBe(comp.service);
-            expect(subDecorator.component).toBe(comp);
-          });
-
-        function expectViewHasNoDirectiveInstances(view) {
-          view.elementInjectors.forEach((inj) => expect(inj.hasInstances()).toBe(false));
-        }
-
-        it('dehydration should dehydrate child component views too', () => {
-          var subpv = new ProtoView(null,
-            el('<div dec class="ng-binding">hello shadow dom</div>'),
-            new DynamicProtoChangeDetector(null, null),
-            null);
-          subpv.bindElement(null, 0,
-            new ProtoElementInjector(null, 0, [ServiceDependentDecorator]));
-          var pv = createComponentWithSubPV(subpv);
-
-          var view = createNestedView(pv);
-          view.dehydrate();
-
-          expect(view.hydrated()).toBe(false);
-          expectViewHasNoDirectiveInstances(view);
-          view.componentChildViews.forEach(
-            (view) => expectViewHasNoDirectiveInstances(view));
-        });
-
-        it('should create shadow dom (Native Strategy)', () => {
-          var subpv = new ProtoView(null, el('<span>hello shadow dom</span>'),
-            new DynamicProtoChangeDetector(null, null),
-            null);
-          var pv = createComponentWithSubPV(subpv);
-
-          var view = createNestedView(pv);
-
-          expect(view.nodes[0].shadowRoot.childNodes[0].childNodes[0].nodeValue).toEqual('hello shadow dom');
-        });
-
-        it('should emulate shadow dom (Emulated Strategy)', () => {
-          var subpv = new ProtoView(null, el('<span>hello shadow dom</span>'),
-            new DynamicProtoChangeDetector(null, null), null);
-
-          var pv = new ProtoView(null, el('<cmp class="ng-binding"></cmp>'),
-            new DynamicProtoChangeDetector(null, null), new EmulatedScopedShadowDomStrategy(null, null, null));
-          var binder = pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [SomeComponent], true));
-          binder.componentDirective = readDirectiveBinding(SomeComponent);
-          binder.nestedProtoView = subpv;
-
-          var view = createNestedView(pv);
-          expect(view.nodes[0].childNodes[0].childNodes[0].nodeValue).toEqual('hello shadow dom');
-        });
-
-      });
-
-      describe('with template views', () => {
-        function createViewWithViewport() {
-          var templateProtoView = new ProtoView(null,
-            el('<div id="1"></div>'), new DynamicProtoChangeDetector(null, null), null);
-          var pv = new ProtoView(null, el('<someTmpl class="ng-binding"></someTmpl>'),
-            new DynamicProtoChangeDetector(null, null), new NativeShadowDomStrategy(null));
-          var binder = pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [SomeViewport]));
-          binder.viewportDirective = someViewportDirective;
-          binder.nestedProtoView = templateProtoView;
-
-          return createView(pv);
-        }
-
-        it('should create a ViewContainer for the Viewport directive', () => {
-          var view = createViewWithViewport();
-
-          var tmplComp = view.rootElementInjectors[0].get(SomeViewport);
-          expect(tmplComp.viewContainer).not.toBe(null);
-        });
-
-        it('dehydration should dehydrate viewcontainers', () => {
-          var view = createViewWithViewport();
-
-          var tmplComp = view.rootElementInjectors[0].get(SomeViewport);
-          expect(tmplComp.viewContainer.hydrated()).toBe(false);
-        });
-      });
-
-      if (DOM.supportsDOMEvents()) {
-        describe('event handlers', () => {
-          var view, ctx, called, receivedEvent, dispatchedEvent;
-
-          function createViewAndContext(protoView) {
-            view = createView(protoView,
-                new EventManager([new DomEventsPlugin()], new FakeVmTurnZone()));
-            ctx = view.context;
-            called = 0;
-            receivedEvent = null;
-            ctx.callMe = (event) => {
-              called += 1;
-              receivedEvent = event;
-            }
-          }
-
-          function dispatchClick(el) {
-            dispatchedEvent = DOM.createMouseEvent('click');
-            DOM.dispatchEvent(el, dispatchedEvent);
-          }
-
-          function createProtoView() {
-            var pv = new ProtoView(null, el('<div class="ng-binding"><div></div></div>'),
-              new DynamicProtoChangeDetector(null, null), null);
-            pv.bindElement(null, 0, new TestProtoElementInjector(null, 0, []));
-            pv.bindEvent('click', parser.parseBinding('callMe($event)', null));
-            return pv;
-          }
-
-          it('should fire on non-bubbling native events', () => {
-            createViewAndContext(createProtoView());
-
-            dispatchClick(view.nodes[0]);
-
-            expect(called).toEqual(1);
-            expect(receivedEvent).toBe(dispatchedEvent);
-          });
-
-          it('should not fire on a bubbled native events', () => {
-            createViewAndContext(createProtoView());
-
-            dispatchClick(view.nodes[0].firstChild);
-
-            // This test passes trivially on webkit browsers due to
-            // https://bugs.webkit.org/show_bug.cgi?id=122755
-            expect(called).toEqual(0);
-          });
-
-          it('should not throw if the view is dehydrated', () => {
-            createViewAndContext(createProtoView());
-
-            view.dehydrate();
-            expect(() => dispatchClick(view.nodes[0])).not.toThrow();
-            expect(called).toEqual(0);
-          });
-
-          it('should support custom event emitters', () => {
-            var pv = new ProtoView(null, el('<div class="ng-binding"><div></div></div>'),
-              new DynamicProtoChangeDetector(null, null), null);
-            pv.bindElement(null, 0, new TestProtoElementInjector(null, 0, [EventEmitterDirective]));
-            pv.bindEvent('click', parser.parseBinding('callMe($event)', null));
-
-            createViewAndContext(pv);
-            var dir = view.elementInjectors[0].get(EventEmitterDirective);
-
-            var dispatchedEvent = new Object();
-
-            dir.click(dispatchedEvent);
-            expect(receivedEvent).toBe(dispatchedEvent);
-            expect(called).toEqual(1);
-
-            // Should not eval the binding, because custom emitter takes over.
-            dispatchClick(view.nodes[0]);
-
-            expect(called).toEqual(1);
-          });
-
-          it('should bind to directive events', () => {
-            var pv = new ProtoView(null, el('<div class="ng-binding"></div>'),
-              new DynamicProtoChangeDetector(null, null), null);
-            pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [SomeDirectiveWithEventHandler]));
-            pv.bindEvent('click', parser.parseAction('onEvent($event)', null), 0);
-            view = createView(pv, new EventManager([new DomEventsPlugin()], new FakeVmTurnZone()));
-
-            var directive = view.elementInjectors[0].get(SomeDirectiveWithEventHandler);
-            expect(directive.event).toEqual(null);
-
-            dispatchClick(view.nodes[0]);
-            expect(directive.event).toBe(dispatchedEvent);
-          });
-        });
-      }
-
-      describe('react to record changes', () => {
-        var view, cd, ctx;
-
-        function createViewAndChangeDetector(protoView) {
-          view = createView(protoView);
-          ctx = view.context;
-          cd = view.changeDetector;
-        }
-
-        it('should consume text node changes', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding">{{}}</div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          pv.bindElement(null, 0, null);
-          pv.bindTextNode(0, parser.parseBinding('foo', null));
-          createViewAndChangeDetector(pv);
-
-          ctx.foo = 'buz';
-          cd.detectChanges();
-          expect(view.textNodes[0].nodeValue).toEqual('buz');
-        });
-
-        it('should consume element binding changes', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          pv.bindElement(null, 0, null);
-          pv.bindElementProperty(parser.parseBinding('foo', null), 'id', reflector.setter('id'));
-          createViewAndChangeDetector(pv);
-
-          ctx.foo = 'buz';
-          cd.detectChanges();
-          expect(view.bindElements[0].id).toEqual('buz');
-        });
-
-        it('should consume directive watch expression change', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-          pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [SomeDirective]));
-          pv.bindDirectiveProperty(0, parser.parseBinding('foo', null), 'prop', reflector.setter('prop'));
-          createViewAndChangeDetector(pv);
-
-          ctx.foo = 'buz';
-          cd.detectChanges();
-          expect(view.elementInjectors[0].get(SomeDirective).prop).toEqual('buz');
-        });
-
-        it('should notify a directive about changes after all its properties have been set', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-
-          pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [
-            DirectiveBinding.createFromType(DirectiveImplementingOnChange,
-                new DummyDirective({lifecycle: [onChange]}))
-          ]));
-          pv.bindDirectiveProperty( 0, parser.parseBinding('a', null), 'a', reflector.setter('a'));
-          pv.bindDirectiveProperty( 0, parser.parseBinding('b', null), 'b', reflector.setter('b'));
-          createViewAndChangeDetector(pv);
-
-          ctx.a = 100;
-          ctx.b = 200;
-          cd.detectChanges();
-
-          var directive = view.elementInjectors[0].get(DirectiveImplementingOnChange);
-          expect(directive.c).toEqual(300);
-        });
-
-        it('should provide a map of updated properties using onChange callback', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-
-          pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [
-            DirectiveBinding.createFromType(DirectiveImplementingOnChange,
-                new DummyDirective({lifecycle: [onChange]}))
-          ]));
-          pv.bindDirectiveProperty( 0, parser.parseBinding('a', null), 'a', reflector.setter('a'));
-          pv.bindDirectiveProperty( 0, parser.parseBinding('b', null), 'b', reflector.setter('b'));
-          createViewAndChangeDetector(pv);
-
-          var directive = view.elementInjectors[0].get(DirectiveImplementingOnChange);
-
-          ctx.a = 0;
-          ctx.b = 0;
-          cd.detectChanges();
-
-          expect(directive.changes["a"].currentValue).toEqual(0);
-          expect(directive.changes["b"].currentValue).toEqual(0);
-
-          ctx.a = 100;
-          cd.detectChanges();
-          expect(directive.changes["a"].currentValue).toEqual(100);
-          expect(StringMapWrapper.contains(directive.changes, "b")).toBe(false);
-        });
-
-        it('should invoke the onAllChangesDone callback', () => {
-          var pv = new ProtoView(null, el('<div class="ng-binding"></div>'),
-            new DynamicProtoChangeDetector(null, null), null);
-
-          pv.bindElement(null, 0, new ProtoElementInjector(null, 0, [
-            DirectiveBinding.createFromType(DirectiveImplementingOnAllChangesDone,
-                new DummyDirective({lifecycle: [onAllChangesDone]}))
-          ]));
-
-          createViewAndChangeDetector(pv);
-          cd.detectChanges();
-
-          var directive = view.elementInjectors[0].get(DirectiveImplementingOnAllChangesDone);
-          expect(directive.onAllChangesDoneCalled).toBe(true);
-        });
-      });
-    });
-
-  });
-}
-
-function readDirectiveBinding(type) {
-  var meta = new DirectiveMetadataReader().read(type);
-  return DirectiveBinding.createFromType(type, meta.annotation);
-}
-
-class SomeDirective {
-  prop;
-  constructor() {
-    this.prop = 'foo';
-  }
-}
-
-class DirectiveImplementingOnChange {
-  a;
-  b;
-  c;
-  changes;
-
-  onChange(changes) {
-    this.c = this.a + this.b;
-    this.changes = changes;
-  }
-}
-
-class DirectiveImplementingOnAllChangesDone {
-  onAllChangesDoneCalled;
-
-  onAllChangesDone() {
-    this.onAllChangesDoneCalled = true;
-  }
-}
-
-class SomeService {}
-
-@Component({services: [SomeService]})
-class SomeComponent {
-  service: SomeService;
-  constructor(service: SomeService) {
-    this.service = service;
-  }
-}
-
-@Decorator({
-  selector: '[dec]'
-})
-class ServiceDependentDecorator {
-  component: SomeComponent;
-  service: SomeService;
-  constructor(component: SomeComponent, service: SomeService) {
-    this.component = component;
-    this.service = service;
-  }
-}
-
-@Viewport({
-  selector: 'someTmpl'
-})
-class SomeViewport {
-  viewContainer: ViewContainer;
-  constructor(viewContainer: ViewContainer) {
-    this.viewContainer = viewContainer;
-  }
-}
-
-class AnotherDirective {
-  prop:string;
-  constructor() {
-    this.prop = 'anotherFoo';
-  }
-}
-
-class EventEmitterDirective {
-  _clicker:Function;
-  constructor(@EventEmitter('click') clicker:Function) {
-    this._clicker = clicker;
-  }
-  click(eventData) {
-    this._clicker(eventData);
-  }
-}
-
-class SomeDirectiveWithEventHandler {
-  event;
-
-  constructor() {
-    this.event = null;
-  }
-
-  onEvent(event) {
-    this.event = event;
-  }
-}
-
-class MyEvaluationContext {
-  foo:string;
-  a;
-  b;
-  callMe;
-  constructor() {
-    this.foo = 'bar';
-  };
-}
-
-class TestProtoElementInjector extends ProtoElementInjector {
-  parentElementInjector: ElementInjector;
-  hostElementInjector: ElementInjector;
-
-  constructor(parent:ProtoElementInjector, index:int, bindings:List, firstBindingIsComponent:boolean = false) {
-    super(parent, index, bindings, firstBindingIsComponent);
-  }
-
-  instantiate(parent:ElementInjector, host:ElementInjector):ElementInjector {
-    this.parentElementInjector = parent;
-    this.hostElementInjector = host;
-    return super.instantiate(parent, host);
-  }
-}
-
-class FakeVmTurnZone extends VmTurnZone {
-  constructor() {
-    super({enableLongStackTrace: false});
-  }
-
-  run(fn) {
-    fn();
-  }
-
-  runOutsideAngular(fn) {
-    fn();
-  }
-}
diff --git a/modules/angular2/test/directives/class_spec.js b/modules/angular2/test/directives/class_spec.js
index f05988a525..26e1b4ccbb 100644
--- a/modules/angular2/test/directives/class_spec.js
+++ b/modules/angular2/test/directives/class_spec.js
@@ -31,7 +31,7 @@ export function main() {
 
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding foo');
+        expect(view.rootNodes[0].className).toEqual('ng-binding foo');
 
         async.done();
       });
@@ -43,11 +43,11 @@ export function main() {
 
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding foo');
+        expect(view.rootNodes[0].className).toEqual('ng-binding foo');
 
         view.context.condition = false;
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding bar');
+        expect(view.rootNodes[0].className).toEqual('ng-binding bar');
 
         async.done();
       });
@@ -59,19 +59,19 @@ export function main() {
 
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding foo');
+        expect(view.rootNodes[0].className).toEqual('ng-binding foo');
 
         StringMapWrapper.set(view.context.expr, 'bar', true);
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding foo bar');
+        expect(view.rootNodes[0].className).toEqual('ng-binding foo bar');
 
         StringMapWrapper.set(view.context.expr, 'baz', true);
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding foo bar baz');
+        expect(view.rootNodes[0].className).toEqual('ng-binding foo bar baz');
 
         StringMapWrapper.delete(view.context.expr, 'bar');
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding foo baz');
+        expect(view.rootNodes[0].className).toEqual('ng-binding foo baz');
 
         async.done();
       });
@@ -83,15 +83,15 @@ export function main() {
 
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding foo');
+        expect(view.rootNodes[0].className).toEqual('ng-binding foo');
 
         view.context.expr = null;
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding foo');
+        expect(view.rootNodes[0].className).toEqual('ng-binding foo');
 
         view.context.expr = {'foo': false, 'bar': true};
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('ng-binding bar');
+        expect(view.rootNodes[0].className).toEqual('ng-binding bar');
 
         async.done();
       });
@@ -104,11 +104,11 @@ export function main() {
       tb.createView(TestComponent, {html: template}).then((view) => {
         StringMapWrapper.set(view.context.expr, 'bar', true);
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('init foo ng-binding bar');
+        expect(view.rootNodes[0].className).toEqual('init foo ng-binding bar');
 
         StringMapWrapper.set(view.context.expr, 'foo', false);
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('init ng-binding bar');
+        expect(view.rootNodes[0].className).toEqual('init ng-binding bar');
 
         async.done();
       });
@@ -120,19 +120,19 @@ export function main() {
 
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('init foo ng-binding baz');
+        expect(view.rootNodes[0].className).toEqual('init foo ng-binding baz');
 
         StringMapWrapper.set(view.context.expr, 'bar', true);
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('init foo ng-binding baz bar');
+        expect(view.rootNodes[0].className).toEqual('init foo ng-binding baz bar');
 
         StringMapWrapper.set(view.context.expr, 'foo', false);
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('init ng-binding baz bar');
+        expect(view.rootNodes[0].className).toEqual('init ng-binding baz bar');
 
         view.context.condition = false;
         view.detectChanges();
-        expect(view.nodes[0].className).toEqual('init ng-binding bar');
+        expect(view.rootNodes[0].className).toEqual('init ng-binding bar');
 
         async.done();
       });
diff --git a/modules/angular2/test/directives/for_spec.js b/modules/angular2/test/directives/for_spec.js
index 143ca97d85..cfdb958cd9 100644
--- a/modules/angular2/test/directives/for_spec.js
+++ b/modules/angular2/test/directives/for_spec.js
@@ -30,7 +30,7 @@ export function main() {
     it('should reflect initial elements', inject([TestBed, AsyncTestCompleter], (tb, async) => {
       tb.createView(TestComponent, {html: TEMPLATE}).then((view) => {
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('1;2;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('1;2;');
         async.done();
       });
     }));
@@ -42,7 +42,7 @@ export function main() {
         ListWrapper.push(view.context.items, 3);
         view.detectChanges();
 
-        expect(DOM.getText(view.nodes[0])).toEqual('1;2;3;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('1;2;3;');
         async.done();
       });
     }));
@@ -54,7 +54,7 @@ export function main() {
         ListWrapper.removeAt(view.context.items, 1);
         view.detectChanges();
 
-        expect(DOM.getText(view.nodes[0])).toEqual('1;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('1;');
         async.done();
       });
     }));
@@ -67,7 +67,7 @@ export function main() {
         ListWrapper.push(view.context.items, 1);
         view.detectChanges();
 
-        expect(DOM.getText(view.nodes[0])).toEqual('2;1;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('2;1;');
         async.done();
       });
     }));
@@ -81,7 +81,7 @@ export function main() {
         view.context.items = [6, 2, 7, 0, 4, 8];
         view.detectChanges();
 
-        expect(DOM.getText(view.nodes[0])).toEqual('6;2;7;0;4;8;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('6;2;7;0;4;8;');
         async.done();
       });
     }));
@@ -94,20 +94,20 @@ export function main() {
         // INIT
         view.context.items = [{'name': 'misko'}, {'name':'shyam'}];
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('misko;shyam;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('misko;shyam;');
 
         // GROW
         ListWrapper.push(view.context.items, {'name': 'adam'});
         view.detectChanges();
 
-        expect(DOM.getText(view.nodes[0])).toEqual('misko;shyam;adam;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('misko;shyam;adam;');
 
         // SHRINK
         ListWrapper.removeAt(view.context.items, 2);
         ListWrapper.removeAt(view.context.items, 0);
         view.detectChanges();
 
-        expect(DOM.getText(view.nodes[0])).toEqual('shyam;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('shyam;');
         async.done();
       });
     }));
@@ -116,7 +116,7 @@ export function main() {
       var template = '<ul><li template="for #item of null">{{item}};</li></ul>';
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('');
         async.done();
       });
     }));
@@ -125,15 +125,15 @@ export function main() {
       inject([TestBed, AsyncTestCompleter], (tb, async) => {
       tb.createView(TestComponent, {html: TEMPLATE}).then((view) => {
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('1;2;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('1;2;');
 
         view.context.items = null;
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('');
 
         view.context.items = [1, 2, 3];
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('1;2;3;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('1;2;3;');
         async.done();
       });
     }));
@@ -141,7 +141,7 @@ export function main() {
     it('should throw on ref changing to string', inject([TestBed, AsyncTestCompleter], (tb, async) => {
       tb.createView(TestComponent, {html: TEMPLATE}).then((view) => {
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('1;2;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('1;2;');
 
         view.context.items = 'whaaa';
         expect(() => view.detectChanges()).toThrowError();
@@ -154,7 +154,7 @@ export function main() {
         var a = new Foo();
         view.context.items = [a, a];
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('foo;foo;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('foo;foo;');
         async.done();
       });
     }));
@@ -174,11 +174,11 @@ export function main() {
         view.detectChanges();
         view.detectChanges();
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('a-2;b-2;|c-1;|');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('a-2;b-2;|c-1;|');
 
         view.context.items = [['e'], ['f', 'g']];
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('e-1;|f-2;g-2;|');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('e-1;|f-2;g-2;|');
 
         async.done();
       });
@@ -195,11 +195,11 @@ export function main() {
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.context.items = [['a', 'b'], ['c']];
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('a-2;b-2;c-1;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('a-2;b-2;c-1;');
 
         view.context.items = [['e'], ['f', 'g']];
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('e-1;f-2;g-2;');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('e-1;f-2;g-2;');
         async.done();
       });
     }));
@@ -212,11 +212,11 @@ export function main() {
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.context.items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('0123456789');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('0123456789');
 
         view.context.items = [1, 2, 6, 7, 4, 3, 5, 8, 9, 0];
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('0123456789');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('0123456789');
         async.done();
       });
     }));
diff --git a/modules/angular2/test/directives/if_spec.js b/modules/angular2/test/directives/if_spec.js
index 60d7dbdd39..059e858db7 100644
--- a/modules/angular2/test/directives/if_spec.js
+++ b/modules/angular2/test/directives/if_spec.js
@@ -28,8 +28,8 @@ export function main() {
 
       tb.createView(TestComponent, {html: html}).then((view) => {
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-        expect(DOM.getText(view.nodes[0])).toEqual('hello');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('hello');
         async.done();
       });
     }));
@@ -39,8 +39,8 @@ export function main() {
 
       tb.createView(TestComponent, {html: html}).then((view) => {
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-        expect(DOM.getText(view.nodes[0])).toEqual('hello2');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('hello2');
         async.done();
       });
     }));
@@ -51,18 +51,18 @@ export function main() {
       tb.createView(TestComponent, {html: html}).then((view) => {
         view.context.booleanCondition = false;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(0);
-        expect(DOM.getText(view.nodes[0])).toEqual('');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(0);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('');
 
         view.context.booleanCondition = true;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-        expect(DOM.getText(view.nodes[0])).toEqual('hello');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('hello');
 
         view.context.booleanCondition = false;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(0);
-        expect(DOM.getText(view.nodes[0])).toEqual('');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(0);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('');
 
         async.done();
       });
@@ -74,28 +74,28 @@ export function main() {
       tb.createView(TestComponent, {html: html}).then((view) => {
         view.context.booleanCondition = false;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(0);
-        expect(DOM.getText(view.nodes[0])).toEqual('');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(0);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('');
 
         view.context.booleanCondition = true;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-        expect(DOM.getText(view.nodes[0])).toEqual('hello');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('hello');
 
         view.context.nestedBooleanCondition = false;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(0);
-        expect(DOM.getText(view.nodes[0])).toEqual('');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(0);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('');
 
         view.context.nestedBooleanCondition = true;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-        expect(DOM.getText(view.nodes[0])).toEqual('hello');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('hello');
 
         view.context.booleanCondition = false;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(0);
-        expect(DOM.getText(view.nodes[0])).toEqual('');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(0);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('');
 
         async.done();
       });
@@ -111,19 +111,19 @@ export function main() {
 
       tb.createView(TestComponent, {html: html}).then((view) => {
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(3);
-        expect(DOM.getText(view.nodes[0])).toEqual('helloNumberhelloStringhelloFunction');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(3);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('helloNumberhelloStringhelloFunction');
 
         view.context.numberCondition = 0;
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-        expect(DOM.getText(view.nodes[0])).toEqual('helloString');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('helloString');
 
         view.context.numberCondition = 1;
         view.context.stringCondition = "bar";
         view.detectChanges();
-        expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-        expect(DOM.getText(view.nodes[0])).toEqual('helloNumber');
+        expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+        expect(DOM.getText(view.rootNodes[0])).toEqual('helloNumber');
         async.done();
       });
     }));
@@ -136,13 +136,13 @@ export function main() {
 
         tb.createView(TestComponent, {html: html}).then((view) => {
           view.detectChanges();
-          expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-          expect(DOM.getText(view.nodes[0])).toEqual('hello');
+          expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+          expect(DOM.getText(view.rootNodes[0])).toEqual('hello');
 
           view.context.numberCondition = 2;
           view.detectChanges();
-          expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(1);
-          expect(DOM.getText(view.nodes[0])).toEqual('hello');
+          expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(1);
+          expect(DOM.getText(view.rootNodes[0])).toEqual('hello');
 
           async.done();
         });
@@ -154,11 +154,11 @@ export function main() {
 
           tb.createView(TestComponent, {html: html}).then((view) => {
             view.detectChanges();
-            DOM.addClass(view.nodes[0].childNodes[1], "foo");
+            DOM.addClass(view.rootNodes[0].childNodes[1], "foo");
 
             view.context.numberCondition = 2;
             view.detectChanges();
-            expect(DOM.hasClass(view.nodes[0].childNodes[1], "foo")).toBe(true);
+            expect(DOM.hasClass(view.rootNodes[0].childNodes[1], "foo")).toBe(true);
 
             async.done();
           });
@@ -172,8 +172,8 @@ export function main() {
 
           tb.createView(TestComponent, {html: html}).then((view) => {
             expect(() => view.detectChanges()).toThrowError();
-            expect(DOM.querySelectorAll(view.nodes[0], 'copy-me').length).toEqual(0);
-            expect(DOM.getText(view.nodes[0])).toEqual('');
+            expect(DOM.querySelectorAll(view.rootNodes[0], 'copy-me').length).toEqual(0);
+            expect(DOM.getText(view.rootNodes[0])).toEqual('');
             async.done();
           });
       }));
diff --git a/modules/angular2/test/directives/non_bindable_spec.js b/modules/angular2/test/directives/non_bindable_spec.js
index 5974725deb..6842301fdc 100644
--- a/modules/angular2/test/directives/non_bindable_spec.js
+++ b/modules/angular2/test/directives/non_bindable_spec.js
@@ -15,7 +15,7 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
 import {Decorator, Component} from 'angular2/src/core/annotations/annotations';
 import {Template} from 'angular2/src/core/annotations/template';
 
-import {NgElement} from 'angular2/src/core/dom/element';
+import {NgElement} from 'angular2/src/core/compiler/ng_element';
 
 import {NonBindable} from 'angular2/src/directives/non_bindable';
 
@@ -27,7 +27,7 @@ export function main() {
       var template = '<div>{{text}}<span non-bindable>{{text}}</span></div>';
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        expect(DOM.getText(view.nodes[0])).toEqual('foo{{text}}');
+        expect(DOM.getText(view.rootNodes[0])).toEqual('foo{{text}}');
         async.done();
       });
     }));
@@ -36,7 +36,7 @@ export function main() {
       var template = '<div non-bindable><span id=child test-dec>{{text}}</span></div>';
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        var span = DOM.querySelector(view.nodes[0], '#child');
+        var span = DOM.querySelector(view.rootNodes[0], '#child');
         expect(DOM.hasClass(span, 'compiled')).toBeFalsy();
         async.done();
       });
@@ -46,7 +46,7 @@ export function main() {
       var template = '<div><span id=child non-bindable test-dec>{{text}}</span></div>';
       tb.createView(TestComponent, {html: template}).then((view) => {
         view.detectChanges();
-        var span = DOM.querySelector(view.nodes[0], '#child');
+        var span = DOM.querySelector(view.rootNodes[0], '#child');
         expect(DOM.hasClass(span, 'compiled')).toBeTruthy();
         async.done();
       });
diff --git a/modules/angular2/test/directives/switch_spec.js b/modules/angular2/test/directives/switch_spec.js
index be45000238..1bbf4630bd 100644
--- a/modules/angular2/test/directives/switch_spec.js
+++ b/modules/angular2/test/directives/switch_spec.js
@@ -31,15 +31,15 @@ export function main() {
 
         tb.createView(TestComponent, {html: template}).then((view) => {
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('');
 
           view.context.switchValue = 'a';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when a');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when a');
 
           view.context.switchValue = 'b';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when b');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when b');
 
           async.done();
         });
@@ -55,15 +55,15 @@ export function main() {
 
         tb.createView(TestComponent, {html: template}).then((view) => {
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when default');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when default');
 
           view.context.switchValue = 'a';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when a');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when a');
 
           view.context.switchValue = 'b';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when default');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when default');
 
           async.done();
         });
@@ -83,15 +83,15 @@ export function main() {
 
         tb.createView(TestComponent, {html: template}).then((view) => {
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when default1;when default2;');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when default1;when default2;');
 
           view.context.switchValue = 'a';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when a1;when a2;');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when a1;when a2;');
 
           view.context.switchValue = 'b';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when b1;when b2;');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when b1;when b2;');
 
           async.done();
         });
@@ -113,23 +113,23 @@ export function main() {
           view.context.when2 = 'b';
           view.context.switchValue = 'a';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when 1;');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when 1;');
 
           view.context.switchValue = 'b';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when 2;');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when 2;');
 
           view.context.switchValue = 'c';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when default;');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when default;');
 
           view.context.when1 = 'c';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when 1;');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when 1;');
 
           view.context.when1 = 'd';
           view.detectChanges();
-          expect(DOM.getText(view.nodes[0])).toEqual('when default;');
+          expect(DOM.getText(view.rootNodes[0])).toEqual('when default;');
 
           async.done();
         });
diff --git a/modules/angular2/test/forms/integration_spec.js b/modules/angular2/test/forms/integration_spec.js
index 720fd4e5c0..0755498eea 100644
--- a/modules/angular2/test/forms/integration_spec.js
+++ b/modules/angular2/test/forms/integration_spec.js
@@ -25,8 +25,8 @@ import {ControlGroupDirective, ControlDirective, Control, ControlGroup, Optional
   DefaultValueAccessor, Validators} from 'angular2/forms';
 
 export function main() {
-  if (DOM.supportsDOMEvents()) {
-    describe("integration tests", () => {
+  describe("integration tests", () => {
+    if (DOM.supportsDOMEvents()) {
       it("should initialize DOM elements with the given form object",
         inject([TestBed, AsyncTestCompleter], (tb, async) => {
         var ctx = new MyComp(new ControlGroup({
@@ -362,8 +362,8 @@ export function main() {
           });
         }));
       });
-    });
-  }
+    }
+  });
 }
 
 @Component({selector: "my-comp"})
diff --git a/modules/angular2/test/render/dom/integration_testbed.js b/modules/angular2/test/render/dom/integration_testbed.js
index eb34d2e042..d1d5565b09 100644
--- a/modules/angular2/test/render/dom/integration_testbed.js
+++ b/modules/angular2/test/render/dom/integration_testbed.js
@@ -1,5 +1,5 @@
 import {isBlank, isPresent, BaseException} from 'angular2/src/facade/lang';
-import {MapWrapper, ListWrapper, List} from 'angular2/src/facade/collection';
+import {MapWrapper, ListWrapper, List, Map} from 'angular2/src/facade/collection';
 import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
 import {DOM} from 'angular2/src/dom/dom_adapter';
 
@@ -177,7 +177,7 @@ export class LoggingEventDispatcher extends EventDispatcher {
     this.log = [];
   }
   dispatchEvent(
-    elementIndex:number, eventName:string, locals:List<any>
+    elementIndex:number, eventName:string, locals:Map<string, any>
   ) {
     ListWrapper.push(this.log, [elementIndex, eventName, locals]);
   }
diff --git a/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.js b/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.js
index fe57ce4e3a..3dea0d8870 100644
--- a/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.js
+++ b/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.js
@@ -279,7 +279,7 @@ export function main() {
         //  var temp = `<simple>aaa<input type="text" id="focused-input" ng-class="{'aClass' : showClass}"> bbb</simple>`;
         //
         //  compile(temp, (view, lc) => {
-        //    var input = view.nodes[1];
+        //    var input = view.rootNodes[1];
         //    input.focus();
         //
         //    expect(document.activeElement.id).toEqual("focused-input");
diff --git a/modules/angular2/test/services/ruler_spec.js b/modules/angular2/test/services/ruler_spec.js
index ffb62efb67..c4c44cede4 100644
--- a/modules/angular2/test/services/ruler_spec.js
+++ b/modules/angular2/test/services/ruler_spec.js
@@ -1,7 +1,7 @@
 import {AsyncTestCompleter, inject, ddescribe, describe, it, iit, xit, expect, SpyObject} from 'angular2/test_lib';
 
 import {DOM, DomAdapter} from 'angular2/src/dom/dom_adapter';
-import {NgElement} from 'angular2/src/core/dom/element';
+import {NgElement} from 'angular2/src/core/compiler/ng_element';
 
 import {Ruler, Rectangle} from 'angular2/src/services/ruler';
 import {createRectangle} from './rectangle_mock';
@@ -35,7 +35,7 @@ export function main() {
       inject([AsyncTestCompleter], (async) => {
         var ruler = new Ruler(new DomAdapterMock(createRectangle(10, 20, 200, 100)));
 
-        ruler.measure(new NgElement(null)).then((rect) => {
+        ruler.measure(new FakeNgElement(null)).then((rect) => {
           assertDimensions(rect, 10, 210, 20, 120, 200, 100);
           async.done();
         });
@@ -46,7 +46,7 @@ export function main() {
       inject([AsyncTestCompleter], (async) => {
         var ruler = new Ruler(DOM);
 
-        ruler.measure(new NgElement(DOM.createElement('div'))).then((rect) => {
+        ruler.measure(new FakeNgElement(DOM.createElement('div'))).then((rect) => {
           //here we are using an element created in a doc fragment so all the measures will come back as 0
           assertDimensions(rect, 0, 0, 0, 0, 0, 0);
           async.done();
@@ -55,3 +55,16 @@ export function main() {
 
   });
 }
+
+class FakeNgElement extends NgElement {
+  _domElement;
+
+  constructor(domElement) {
+    super(null, null);
+    this._domElement = domElement;
+  }
+
+  get domElement() {
+    return this._domElement;
+  }
+}
\ No newline at end of file
diff --git a/modules/benchmarks/src/change_detection/change_detection_benchmark.js b/modules/benchmarks/src/change_detection/change_detection_benchmark.js
index 48696d81bd..ad37f23afb 100644
--- a/modules/benchmarks/src/change_detection/change_detection_benchmark.js
+++ b/modules/benchmarks/src/change_detection/change_detection_benchmark.js
@@ -185,11 +185,11 @@ function setUpChangeDetection(changeDetection:ChangeDetection, iterations, objec
   var dispatcher = new DummyDispatcher();
   var parser = new Parser(new Lexer());
 
-  var parentProto = changeDetection.createProtoChangeDetector('parent');
+  var parentProto = changeDetection.createProtoChangeDetector('parent', null);
   var parentCd = parentProto.instantiate(dispatcher, [], [], []);
 
   var targetObj = new Obj();
-  var proto = changeDetection.createProtoChangeDetector("proto");
+  var proto = changeDetection.createProtoChangeDetector("proto", null);
   var bindingRecords = [
     new BindingRecord(parser.parseBinding('field0', null), new FakeBindingMemento(targetObj, reflector.setter("field0")), null),
     new BindingRecord(parser.parseBinding('field1', null), new FakeBindingMemento(targetObj, reflector.setter("field1")), null),
@@ -240,7 +240,7 @@ export function main () {
 
   // -- BASELINE
   var baselineHead = setUpBaseline(numberOfDetectors, object);
-  
+
   runBaselineReads(baselineHead, 1); //warmup
 
   bindAction(
diff --git a/modules/benchmarks/src/compiler/compiler_benchmark.js b/modules/benchmarks/src/compiler/compiler_benchmark.js
index c16b935e2a..2487017d8b 100644
--- a/modules/benchmarks/src/compiler/compiler_benchmark.js
+++ b/modules/benchmarks/src/compiler/compiler_benchmark.js
@@ -4,7 +4,7 @@ import {isBlank, Type} from 'angular2/src/facade/lang';
 import {document} from 'angular2/src/facade/browser';
 import {MapWrapper} from 'angular2/src/facade/collection';
 import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
-import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
+import {NativeShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/native_shadow_dom_strategy';
 
 import {Parser, Lexer, ProtoRecordRange, dynamicChangeDetection} from 'angular2/change_detection';
 
@@ -23,6 +23,11 @@ import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mappe
 import {reflector} from 'angular2/src/reflection/reflection';
 import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
 
+import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
+import {Renderer} from 'angular2/src/render/api';
+import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
+import * as rc from 'angular2/src/render/dom/compiler/compiler';
+
 function setupReflector() {
   reflector.registerType(BenchmarkComponent, {
     "factory": () => new BenchmarkComponent(),
@@ -94,16 +99,22 @@ export function main() {
   var templateResolver = new FakeTemplateResolver();
   var urlResolver = new UrlResolver();
   var styleUrlResolver = new StyleUrlResolver(urlResolver);
+  var shadowDomStrategy = new NativeShadowDomStrategy(styleUrlResolver);
+  var renderer = new DirectDomRenderer(
+    new rc.DefaultCompiler(
+      new Parser(new Lexer()), shadowDomStrategy, new TemplateLoader(null, urlResolver)
+    ),
+    null,
+    shadowDomStrategy
+  );
   var compiler = new Compiler(
-    dynamicChangeDetection,
-    new TemplateLoader(null, urlResolver),
     reader,
-    new Parser(new Lexer()),
     cache,
-    new NativeShadowDomStrategy(styleUrlResolver),
     templateResolver,
     new ComponentUrlMapper(),
-    urlResolver
+    urlResolver,
+    renderer,
+    new ProtoViewFactory(dynamicChangeDetection, renderer)
   );
   var templateNoBindings = createTemplateHtml('templateNoBindings', count);
   var templateWithBindings = createTemplateHtml('templateWithBindings', count);
diff --git a/modules/benchmarks/src/element_injector/element_injector_benchmark.js b/modules/benchmarks/src/element_injector/element_injector_benchmark.js
index fc68b1d24a..60e2e65bde 100644
--- a/modules/benchmarks/src/element_injector/element_injector_benchmark.js
+++ b/modules/benchmarks/src/element_injector/element_injector_benchmark.js
@@ -33,19 +33,19 @@ export function main() {
 
   var bindings = [A, B, C];
   var proto = new ProtoElementInjector(null, 0, bindings);
-  var elementInjector = proto.instantiate(null, null);
+  var elementInjector = proto.instantiate(null);
 
   function instantiate () {
     for (var i = 0; i < iterations; ++i) {
-      var ei = proto.instantiate(null, null);
-      ei.instantiateDirectives(appInjector, null, null);
+      var ei = proto.instantiate(null);
+      ei.instantiateDirectives(appInjector, null, null, null);
     }
   }
 
   function instantiateDirectives () {
     for (var i = 0; i < iterations; ++i) {
       elementInjector.clearDirectives();
-      elementInjector.instantiateDirectives(appInjector, null, null);
+      elementInjector.instantiateDirectives(appInjector, null, null, null);
     }
   }
 
diff --git a/modules/benchmarks/src/largetable/largetable_benchmark.js b/modules/benchmarks/src/largetable/largetable_benchmark.js
index 44383bca1d..da04ff8165 100644
--- a/modules/benchmarks/src/largetable/largetable_benchmark.js
+++ b/modules/benchmarks/src/largetable/largetable_benchmark.js
@@ -8,9 +8,9 @@ import {CompilerCache} from 'angular2/src/core/compiler/compiler';
 import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
 import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
 import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
-import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
-import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
-import {DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
+import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
+import {NativeShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/native_shadow_dom_strategy';
+import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
 import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
 import {UrlResolver} from 'angular2/src/services/url_resolver';
 import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
@@ -36,6 +36,14 @@ import {EventManager} from 'angular2/src/render/dom/events/event_manager';
 import {ListWrapper} from 'angular2/src/facade/collection';
 import {Parent} from 'angular2/src/core/annotations/visibility';
 
+import {ViewFactory, VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_factory';
+import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
+import {Renderer} from 'angular2/src/render/api';
+import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
+import * as rc from 'angular2/src/render/dom/compiler/compiler';
+import * as rvf from 'angular2/src/render/dom/view/view_factory';
+import {Inject} from 'angular2/di';
+
 var BASELINE_LARGETABLE_TEMPLATE;
 
 function setupReflector() {
@@ -139,8 +147,8 @@ function setupReflector() {
   });
 
   reflector.registerType(SwitchWhen, {
-    'factory': (el, vc, ss) => new SwitchWhen(el, vc, ss),
-    'parameters': [[NgElement],[ViewContainer],[Switch, new Parent()]],
+    'factory': (vc, ss) => new SwitchWhen(vc, ss),
+    'parameters': [[ViewContainer],[Switch, new Parent()]],
     'annotations' : [new Viewport({
         selector: '[switch-when]',
         bind: {
@@ -158,14 +166,13 @@ function setupReflector() {
   });
 
   reflector.registerType(Compiler, {
-    'factory': (cd, templateLoader, reader, parser, compilerCache, strategy, tplResolver,
-      cmpUrlMapper, urlResolver) =>
-      new Compiler(cd, templateLoader, reader, parser, compilerCache, strategy, tplResolver,
-        cmpUrlMapper, urlResolver),
-    'parameters': [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader],
-                   [Parser], [CompilerCache], [ShadowDomStrategy], [TemplateResolver],
-                   [ComponentUrlMapper], [UrlResolver]],
-    'annotations': []
+    "factory": (reader, compilerCache, tplResolver, cmpUrlMapper, urlResolver, renderer,
+                protoViewFactory) =>
+      new Compiler(reader, compilerCache, tplResolver, cmpUrlMapper, urlResolver, renderer,
+                protoViewFactory),
+    "parameters": [[DirectiveMetadataReader], [CompilerCache], [TemplateResolver], [ComponentUrlMapper],
+                   [UrlResolver], [Renderer], [ProtoViewFactory]],
+    "annotations": []
   });
 
   reflector.registerType(CompilerCache, {
@@ -240,12 +247,6 @@ function setupReflector() {
     "annotations": []
   });
 
-  reflector.registerType(Content, {
-    "factory": (lightDom, el) => new Content(lightDom, el),
-    "parameters": [[DestinationLightDom], [NgElement]],
-    "annotations" : [new Decorator({selector: '[content]'})]
-  });
-
   reflector.registerType(UrlResolver, {
     "factory": () => new UrlResolver(),
     "parameters": [],
@@ -290,12 +291,58 @@ function setupReflector() {
   });
 
   reflector.registerType(PrivateComponentLoader, {
-    "factory": (compiler, strategy, eventMgr, reader) =>
-      new PrivateComponentLoader(compiler, strategy, eventMgr, reader),
-    "parameters": [[Compiler], [ShadowDomStrategy], [EventManager], [DirectiveMetadataReader]],
+    "factory": (compiler, reader, viewFactory) =>
+      new PrivateComponentLoader(compiler, reader, viewFactory),
+    "parameters": [[Compiler], [DirectiveMetadataReader], [ViewFactory]],
     "annotations": []
   });
 
+  reflector.registerType(DirectDomRenderer, {
+    "factory": (renderCompiler, renderViewFactory, shadowDomStrategy) =>
+      new DirectDomRenderer(renderCompiler, renderViewFactory, shadowDomStrategy),
+    "parameters": [[rc.Compiler], [rvf.ViewFactory], [ShadowDomStrategy]],
+    "annotations": []
+  });
+
+  reflector.registerType(rc.DefaultCompiler, {
+    "factory": (parser, shadowDomStrategy, templateLoader) =>
+      new rc.DefaultCompiler(parser, shadowDomStrategy, templateLoader),
+    "parameters": [[Parser], [ShadowDomStrategy], [TemplateLoader]],
+    "annotations": []
+  });
+
+  reflector.registerType(rvf.ViewFactory, {
+    "factory": (capacity, eventManager, shadowDomStrategy) =>
+      new rvf.ViewFactory(capacity, eventManager, shadowDomStrategy),
+    "parameters": [[new Inject(rvf.VIEW_POOL_CAPACITY)], [EventManager], [ShadowDomStrategy]],
+    "annotations": []
+  });
+
+  reflector.registerType(rvf.VIEW_POOL_CAPACITY, {
+    "factory": () => 100000,
+    "parameters": [],
+    "annotations": []
+  });
+
+  reflector.registerType(ProtoViewFactory, {
+    "factory": (changeDetection, renderer) =>
+      new ProtoViewFactory(changeDetection, renderer),
+    "parameters": [[ChangeDetection], [Renderer]],
+    "annotations": []
+  });
+
+  reflector.registerType(ViewFactory, {
+    "factory": (capacity) =>
+      new ViewFactory(capacity),
+    "parameters": [[new Inject(VIEW_POOL_CAPACITY)]],
+    "annotations": []
+  });
+
+  reflector.registerType(VIEW_POOL_CAPACITY, {
+    "factory": () => 100000,
+    "parameters": [],
+    "annotations": []
+  });
 
   reflector.registerGetters({
     'data': (a) => a.data,
diff --git a/modules/benchmarks/src/naive_infinite_scroll/index.js b/modules/benchmarks/src/naive_infinite_scroll/index.js
index a1e57ae0c3..4d12abbe16 100644
--- a/modules/benchmarks/src/naive_infinite_scroll/index.js
+++ b/modules/benchmarks/src/naive_infinite_scroll/index.js
@@ -11,9 +11,9 @@ import {
 import {reflector} from 'angular2/src/reflection/reflection';
 import {CompilerCache} from 'angular2/src/core/compiler/compiler';
 import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
-import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
-import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
-import {DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
+import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
+import {NativeShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/native_shadow_dom_strategy';
+import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
 import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
 import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
 import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
@@ -36,6 +36,13 @@ import {CompanyNameComponent, OpportunityNameComponent, OfferingNameComponent,
         from './cells';
 
 import {EventManager} from 'angular2/src/render/dom/events/event_manager';
+import {ViewFactory, VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_factory';
+import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
+import {Renderer} from 'angular2/src/render/api';
+import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
+import * as rc from 'angular2/src/render/dom/compiler/compiler';
+import * as rvf from 'angular2/src/render/dom/view/view_factory';
+import {Inject} from 'angular2/di';
 
 export function main() {
   setupReflector();
@@ -188,13 +195,12 @@ export function setupReflectorForAngular() {
   });
 
   reflector.registerType(Compiler, {
-    "factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
-      tplResolver, cmpUrlMapper, urlResolver) =>
-      new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
-        tplResolver, cmpUrlMapper, urlResolver),
-    "parameters": [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader], [Parser],
-                   [CompilerCache], [ShadowDomStrategy], [TemplateResolver], [ComponentUrlMapper],
-                   [UrlResolver]],
+    "factory": (reader, compilerCache, tplResolver, cmpUrlMapper, urlResolver, renderer,
+                protoViewFactory) =>
+      new Compiler(reader, compilerCache, tplResolver, cmpUrlMapper, urlResolver, renderer,
+                protoViewFactory),
+    "parameters": [[DirectiveMetadataReader], [CompilerCache], [TemplateResolver], [ComponentUrlMapper],
+                   [UrlResolver], [Renderer], [ProtoViewFactory]],
     "annotations": []
   });
 
@@ -288,12 +294,6 @@ export function setupReflectorForAngular() {
     "annotations": []
   });
 
-  reflector.registerType(Content, {
-    "factory": (lightDom, el) => new Content(lightDom, el),
-    "parameters": [[DestinationLightDom], [NgElement]],
-    "annotations" : [new Decorator({selector: '[content]'})]
-  });
-
   reflector.registerType(TestabilityRegistry, {
     "factory": () => new TestabilityRegistry(),
     "parameters": [],
@@ -320,9 +320,56 @@ export function setupReflectorForAngular() {
   });
 
   reflector.registerType(PrivateComponentLoader, {
-    "factory": (compiler, strategy, eventMgr, reader) =>
-      new PrivateComponentLoader(compiler, strategy, eventMgr, reader),
-    "parameters": [[Compiler], [ShadowDomStrategy], [EventManager], [DirectiveMetadataReader]],
+    "factory": (compiler, reader, viewFactory) =>
+      new PrivateComponentLoader(compiler, reader, viewFactory),
+    "parameters": [[Compiler], [DirectiveMetadataReader], [ViewFactory]],
+    "annotations": []
+  });
+
+  reflector.registerType(DirectDomRenderer, {
+    "factory": (renderCompiler, renderViewFactory, shadowDomStrategy) =>
+      new DirectDomRenderer(renderCompiler, renderViewFactory, shadowDomStrategy),
+    "parameters": [[rc.Compiler], [rvf.ViewFactory], [ShadowDomStrategy]],
+    "annotations": []
+  });
+
+  reflector.registerType(rc.DefaultCompiler, {
+    "factory": (parser, shadowDomStrategy, templateLoader) =>
+      new rc.DefaultCompiler(parser, shadowDomStrategy, templateLoader),
+    "parameters": [[Parser], [ShadowDomStrategy], [TemplateLoader]],
+    "annotations": []
+  });
+
+  reflector.registerType(rvf.ViewFactory, {
+    "factory": (capacity, eventManager, shadowDomStrategy) =>
+      new rvf.ViewFactory(capacity, eventManager, shadowDomStrategy),
+    "parameters": [[new Inject(rvf.VIEW_POOL_CAPACITY)], [EventManager], [ShadowDomStrategy]],
+    "annotations": []
+  });
+
+  reflector.registerType(rvf.VIEW_POOL_CAPACITY, {
+    "factory": () => 100000,
+    "parameters": [],
+    "annotations": []
+  });
+
+  reflector.registerType(ProtoViewFactory, {
+    "factory": (changeDetection, renderer) =>
+      new ProtoViewFactory(changeDetection, renderer),
+    "parameters": [[ChangeDetection], [Renderer]],
+    "annotations": []
+  });
+
+  reflector.registerType(ViewFactory, {
+    "factory": (capacity) =>
+      new ViewFactory(capacity),
+    "parameters": [[new Inject(VIEW_POOL_CAPACITY)]],
+    "annotations": []
+  });
+
+  reflector.registerType(VIEW_POOL_CAPACITY, {
+    "factory": () => 100000,
+    "parameters": [],
     "annotations": []
   });
 }
diff --git a/modules/benchmarks/src/tree/tree_benchmark.js b/modules/benchmarks/src/tree/tree_benchmark.js
index 1e2546e28a..4336fd6fd4 100644
--- a/modules/benchmarks/src/tree/tree_benchmark.js
+++ b/modules/benchmarks/src/tree/tree_benchmark.js
@@ -8,9 +8,9 @@ import {CompilerCache} from 'angular2/src/core/compiler/compiler';
 import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
 import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
 import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
-import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
-import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
-import {DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
+import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
+import {NativeShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/native_shadow_dom_strategy';
+import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
 import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
 import {UrlResolver} from 'angular2/src/services/url_resolver';
 import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
@@ -32,6 +32,13 @@ import {If} from 'angular2/directives';
 import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
 
 import {EventManager} from 'angular2/src/render/dom/events/event_manager';
+import {ViewFactory, VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_factory';
+import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
+import {Renderer} from 'angular2/src/render/api';
+import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
+import * as rc from 'angular2/src/render/dom/compiler/compiler';
+import * as rvf from 'angular2/src/render/dom/view/view_factory';
+import {Inject} from 'angular2/di';
 
 function setupReflector() {
   // TODO: Put the general calls to reflector.register... in a shared file
@@ -74,14 +81,13 @@ function setupReflector() {
   });
 
   reflector.registerType(Compiler, {
-    'factory': (cd, templateLoader, reader, parser, compilerCache, strategy, tplResolver,
-      cmpUrlMapper, urlResolver) =>
-      new Compiler(cd, templateLoader, reader, parser, compilerCache, strategy, tplResolver,
-        cmpUrlMapper, urlResolver),
-    'parameters': [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader],
-                   [Parser], [CompilerCache], [ShadowDomStrategy], [TemplateResolver],
-                   [ComponentUrlMapper], [UrlResolver]],
-    'annotations': []
+    "factory": (reader, compilerCache, tplResolver, cmpUrlMapper, urlResolver, renderer,
+                protoViewFactory) =>
+      new Compiler(reader, compilerCache, tplResolver, cmpUrlMapper, urlResolver, renderer,
+                protoViewFactory),
+    "parameters": [[DirectiveMetadataReader], [CompilerCache], [TemplateResolver], [ComponentUrlMapper],
+                   [UrlResolver], [Renderer], [ProtoViewFactory]],
+    "annotations": []
   });
 
   reflector.registerType(CompilerCache, {
@@ -156,12 +162,6 @@ function setupReflector() {
     "annotations": []
   });
 
-  reflector.registerType(Content, {
-    "factory": (lightDom, el) => new Content(lightDom, el),
-    "parameters": [[DestinationLightDom], [NgElement]],
-    "annotations" : [new Decorator({selector: '[content]'})]
-  });
-
   reflector.registerType(UrlResolver, {
     "factory": () => new UrlResolver(),
     "parameters": [],
@@ -206,9 +206,56 @@ function setupReflector() {
   });
 
   reflector.registerType(PrivateComponentLoader, {
-    "factory": (compiler, strategy, eventMgr, reader) =>
-      new PrivateComponentLoader(compiler, strategy, eventMgr, reader),
-    "parameters": [[Compiler], [ShadowDomStrategy], [EventManager], [DirectiveMetadataReader]],
+    "factory": (compiler, reader, viewFactory) =>
+      new PrivateComponentLoader(compiler, reader, viewFactory),
+    "parameters": [[Compiler], [DirectiveMetadataReader], [ViewFactory]],
+    "annotations": []
+  });
+
+  reflector.registerType(DirectDomRenderer, {
+    "factory": (renderCompiler, renderViewFactory, shadowDomStrategy) =>
+      new DirectDomRenderer(renderCompiler, renderViewFactory, shadowDomStrategy),
+    "parameters": [[rc.Compiler], [rvf.ViewFactory], [ShadowDomStrategy]],
+    "annotations": []
+  });
+
+  reflector.registerType(rc.DefaultCompiler, {
+    "factory": (parser, shadowDomStrategy, templateLoader) =>
+      new rc.DefaultCompiler(parser, shadowDomStrategy, templateLoader),
+    "parameters": [[Parser], [ShadowDomStrategy], [TemplateLoader]],
+    "annotations": []
+  });
+
+  reflector.registerType(rvf.ViewFactory, {
+    "factory": (capacity, eventManager, shadowDomStrategy) =>
+      new rvf.ViewFactory(capacity, eventManager, shadowDomStrategy),
+    "parameters": [[new Inject(rvf.VIEW_POOL_CAPACITY)], [EventManager], [ShadowDomStrategy]],
+    "annotations": []
+  });
+
+  reflector.registerType(rvf.VIEW_POOL_CAPACITY, {
+    "factory": () => 100000,
+    "parameters": [],
+    "annotations": []
+  });
+
+  reflector.registerType(ProtoViewFactory, {
+    "factory": (changeDetection, renderer) =>
+      new ProtoViewFactory(changeDetection, renderer),
+    "parameters": [[ChangeDetection], [Renderer]],
+    "annotations": []
+  });
+
+  reflector.registerType(ViewFactory, {
+    "factory": (capacity) =>
+      new ViewFactory(capacity),
+    "parameters": [[new Inject(VIEW_POOL_CAPACITY)]],
+    "annotations": []
+  });
+
+  reflector.registerType(VIEW_POOL_CAPACITY, {
+    "factory": () => 100000,
+    "parameters": [],
     "annotations": []
   });
 
diff --git a/modules/examples/src/hello_world/index_static.js b/modules/examples/src/hello_world/index_static.js
index e6d043224b..e1dcc52e74 100644
--- a/modules/examples/src/hello_world/index_static.js
+++ b/modules/examples/src/hello_world/index_static.js
@@ -7,9 +7,9 @@ import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
 
 import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
 import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
-import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
-import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
-import {DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
+import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
+import {NativeShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/native_shadow_dom_strategy';
+import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
 import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
 import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
 import {XHR} from 'angular2/src/services/xhr';
@@ -24,6 +24,14 @@ import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/te
 
 import {reflector} from 'angular2/src/reflection/reflection';
 
+import {ViewFactory, VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_factory';
+import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
+import {Renderer} from 'angular2/src/render/api';
+import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
+import * as rc from 'angular2/src/render/dom/compiler/compiler';
+import * as rvf from 'angular2/src/render/dom/view/view_factory';
+import {Inject} from 'angular2/di';
+
 function setup() {
   reflector.registerType(app.HelloCmp, {
     "factory": (service) => new app.HelloCmp(service),
@@ -53,13 +61,12 @@ function setup() {
   });
 
   reflector.registerType(Compiler, {
-    "factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
-                tplResolver, cmpUrlMapper, urlResolver) =>
-      new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
-        tplResolver, cmpUrlMapper, urlResolver),
-    "parameters": [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader], [Parser],
-                   [CompilerCache], [ShadowDomStrategy], [TemplateResolver], [ComponentUrlMapper],
-                   [UrlResolver]],
+    "factory": (reader, compilerCache, tplResolver, cmpUrlMapper, urlResolver, renderer,
+                protoViewFactory) =>
+      new Compiler(reader, compilerCache, tplResolver, cmpUrlMapper, urlResolver, renderer,
+                protoViewFactory),
+    "parameters": [[DirectiveMetadataReader], [CompilerCache], [TemplateResolver], [ComponentUrlMapper],
+                   [UrlResolver], [Renderer], [ProtoViewFactory]],
     "annotations": []
   });
 
@@ -153,12 +160,6 @@ function setup() {
     "annotations": []
   });
 
-  reflector.registerType(Content, {
-    "factory": (lightDom, el, selector) => new Content(lightDom, el, selector),
-    "parameters": [[DestinationLightDom], [NgElement], [String]],
-    "annotations" : []
-  });
-
   reflector.registerType(StyleInliner, {
     "factory": (xhr, styleUrlResolver, urlResolver) =>
       new StyleInliner(xhr, styleUrlResolver, urlResolver),
@@ -173,9 +174,9 @@ function setup() {
   });
 
   reflector.registerType(PrivateComponentLoader, {
-    "factory": (compiler, strategy, eventMgr, reader) =>
-      new PrivateComponentLoader(compiler, strategy, eventMgr, reader),
-    "parameters": [[Compiler], [ShadowDomStrategy], [EventManager], [DirectiveMetadataReader]],
+    "factory": (compiler, reader, viewFactory) =>
+      new PrivateComponentLoader(compiler, reader, viewFactory),
+    "parameters": [[Compiler], [DirectiveMetadataReader], [ViewFactory]],
     "annotations": []
   });
 
@@ -191,6 +192,53 @@ function setup() {
     "annotations": []
   });
 
+  reflector.registerType(DirectDomRenderer, {
+    "factory": (renderCompiler, renderViewFactory, shadowDomStrategy) =>
+      new DirectDomRenderer(renderCompiler, renderViewFactory, shadowDomStrategy),
+    "parameters": [[rc.Compiler], [rvf.ViewFactory], [ShadowDomStrategy]],
+    "annotations": []
+  });
+
+  reflector.registerType(rc.DefaultCompiler, {
+    "factory": (parser, shadowDomStrategy, templateLoader) =>
+      new rc.DefaultCompiler(parser, shadowDomStrategy, templateLoader),
+    "parameters": [[Parser], [ShadowDomStrategy], [TemplateLoader]],
+    "annotations": []
+  });
+
+  reflector.registerType(rvf.ViewFactory, {
+    "factory": (capacity, eventManager, shadowDomStrategy) =>
+      new rvf.ViewFactory(capacity, eventManager, shadowDomStrategy),
+    "parameters": [[new Inject(rvf.VIEW_POOL_CAPACITY)], [EventManager], [ShadowDomStrategy]],
+    "annotations": []
+  });
+
+  reflector.registerType(rvf.VIEW_POOL_CAPACITY, {
+    "factory": () => 100000,
+    "parameters": [],
+    "annotations": []
+  });
+
+  reflector.registerType(ProtoViewFactory, {
+    "factory": (changeDetection, renderer) =>
+      new ProtoViewFactory(changeDetection, renderer),
+    "parameters": [[ChangeDetection], [Renderer]],
+    "annotations": []
+  });
+
+  reflector.registerType(ViewFactory, {
+    "factory": (capacity) =>
+      new ViewFactory(capacity),
+    "parameters": [[new Inject(VIEW_POOL_CAPACITY)]],
+    "annotations": []
+  });
+
+  reflector.registerType(VIEW_POOL_CAPACITY, {
+    "factory": () => 100000,
+    "parameters": [],
+    "annotations": []
+  });
+
   reflector.registerGetters({
     "greeting": (a) => a.greeting
   });
diff --git a/test-init.dart b/test-init.dart
new file mode 100644
index 0000000000..7e1096de8f
--- /dev/null
+++ b/test-init.dart
@@ -0,0 +1,5 @@
+import 'package:angular2/src/dom/browser_adapter.dart';
+
+main() {
+  BrowserDomAdapter.makeCurrent();
+}
diff --git a/test-main.dart b/test-main.dart
index 82e616960d..0726d474bb 100644
--- a/test-main.dart
+++ b/test-main.dart
@@ -1,11 +1,9 @@
 import 'package:guinness/guinness.dart';
 import 'package:unittest/unittest.dart' as unit;
-import 'package:angular2/src/dom/browser_adapter.dart';
 
 import 'package:angular2/src/test_lib/test_lib.dart' show testSetup;
 
 main() {
-  BrowserDomAdapter.makeCurrent();
   unit.filterStacks = true;
   unit.formatStacks = false;
   unit.unittestConfiguration.timeout = new Duration(milliseconds: 100);