/**
@module ember
@submodule ember-htmlbars
*/

import merge from "ember-metal/merge";
import ComponentNode from "ember-htmlbars/system/component-node";

import topLevelViewTemplate from "ember-htmlbars/templates/top-level-view";
topLevelViewTemplate.revision = 'Ember@VERSION_STRING_PLACEHOLDER';

export default {
  willRender: function(renderNode, env) {
    env.view.ownerView._outlets.push(renderNode);
  },

  setupState: function(state, env, scope, params, hash) {
    var outletState = env.outletState;
    var read = env.hooks.getValue;

    var outletName = read(params[0]) || 'main';
    var selectedOutletState = outletState[outletName];

    var toRender = selectedOutletState && selectedOutletState.render;
    if (toRender && !toRender.template && !toRender.ViewClass) {
      toRender.template = topLevelViewTemplate;
    }

    return { outletState: selectedOutletState };
  },

  updateEnv: function(state, env) {
    var outletState = state.outletState;
    var newEnv = merge({ outletState: null }, env);

    newEnv.outletState = outletState && outletState.outlets;
    return newEnv;
  },

  isStable: function(state, env, scope, params, hash) {
    return isStable(state.lastOutletState, state.outletState);
  },

  isEmpty: function(state) {
    return isEmpty(state.outletState);
  },

  rerender: function(morph, env, scope, params, hash, template, inverse, visitor) {
    var newEnv = env;
    if (morph.emberView) {
      newEnv = merge({}, env);
      newEnv.view = morph.emberView;
    }
  },

  render: function(renderNode, env, scope, params, hash, template, inverse, visitor) {
    var state = renderNode.state;
    var parentView = env.view;
    var outletState = state.outletState;
    var toRender = outletState.render;

    var ViewClass = outletState.render.ViewClass;

    var options = {
      component: ViewClass,
      layout: toRender.template,
      self: toRender.controller,
      isOutlet: true
    };

    var componentNode = ComponentNode.create(renderNode, env, {}, options, parentView, null, null, template);
    state.componentNode = componentNode;

    componentNode.render(env, hash, visitor);
  }
};

function isEmpty(outletState) {
  return !outletState || (!outletState.render.ViewClass && !outletState.render.template);
}

function isStable(a, b) {
  if (!a && !b) {
    return true;
  }
  if (!a || !b) {
    return false;
  }
  a = a.render;
  b = b.render;
  for (var key in a) {
    if (a.hasOwnProperty(key)) {
      // name is only here for logging & debugging. If two different
      // names result in otherwise identical states, they're still
      // identical.
      if (a[key] !== b[key] && key !== 'name') {
        return false;
      }
    }
  }
  return true;
}

@@ -895,14 +895,13 @@
 %0A%0A  
-update
+child
 Env:
@@ -915,29 +915,24 @@
 on(state
-, env
 ) %7B%0A    
 var outl
@@ -927,236 +927,127 @@
     
-var outletState = state.outletState;%0A    var newEnv = merge(%7B outletState: null %7D, env);%0A%0A    newEnv.outletState = outletState && outletState.outlets;%0A    return newEnv;%0A  %7D,%0A%0A  isStable: function(state, env, scope, params, hash
+return %7B outletState: state.outletState && state.outletState.outlets %7D;%0A  %7D,%0A%0A  isStable: function(lastState, nextState
 ) %7B%0A
@@ -1070,19 +1070,19 @@
 ble(
-state.lastO
+lastState.o
 utle
@@ -1089,17 +1089,21 @@
 tState, 
-s
+nextS
 tate.out

Use improved child env support