/**
 * Will pass the state of a store as properties to the nested components.
 * If there is more than one store, the stores themselves will be passed
 */
import React from 'react'

export default class AltContainer extends React.Component {

  constructor(props) {
    super(props)
    const { store, stores } = props;

    if (!stores && !store) {
      throw new Error('Must define either store or stores')
    }
    if (stores && store) {
      throw new Error('Cannot define both store and stores')
    }
    this.onStoreChange = this.onStoreChange.bind(this);
    this.state = this._reduceState();
    this.storeListeners = []
  }

  componentWillReceiveProps(nextProps) {
    this._destroySubscriptions()
    this.setState(this._reduceState(nextProps))
    this._registerStores(nextProps)
  }

  componentDidMount() {
    this._registerStores(this.props)
  }

  componentWillUnmount() {
    this._destroySubscriptions()
  }

  _reduceState() {
    const { store, stores, mergeFunc } = this.props;
    return store? store.getState() : mergeFunc(stores);
  }

  _registerStores({ store, stores }) {
    stores = stores || [ store ];
    stores.forEach(this._addSubscription.bind(this));
  }

  _destroySubscriptions() {
    this.storeListeners.forEach(storeListener => storeListener.dispose())
    this.storeListeners = []
  }

  _addSubscription(store) {
    this.storeListeners.push(store.subscribe(this.onStoreChange))
  }

  onStoreChange() {
    this.setState(this._reduceState(this.props))
  }

  render() {
    const { element, children, store, stores, mergeFunc, ...nodeProps } = this.props;
    return React.createElement(element, nodeProps, React.Children.map(children, child => {
      const childrenProps = Object.assign({}, this.state, child.props);
      return React.cloneElement(child, childrenProps);
    }))
  }

}

const PropTypes = React.PropTypes;
const storeShape = PropTypes.shape({
  getState: React.PropTypes.func.isRequired
});
AltContainer.propTypes = {

  // specify either store (a single store) or stores (array of stores)
  store: storeShape,
  stores: PropTypes.arrayOf(storeShape),

  // when specifying multiple stores, this is the function that will be called to merge the states of all stores.
  // By default, Object.assign() will be invoked with all the states.
  mergeFunc: PropTypes.func,

  // when rendering multiple children, a parent element will be created. Default is "div"
  element: PropTypes.string
}

AltContainer.defaultProps = {
  element: 'div',
  mergeFunc: function(stores) {
    return stores.reduce(function(state, store) {
      return Object.assign(state, store.getState());
    }, {});
  }
}

@@ -314,16 +314,67 @@
 props;%0A%0A
+    if (process.env.NODE_ENV !== 'production') %7B%0A  
     if (
@@ -392,32 +392,34 @@
 !store) %7B%0A      
+  
 throw new Error(
@@ -456,26 +456,30 @@
 tores')%0A    
-%7D%0A
+  %7D%0A  
     if (stor
@@ -489,24 +489,26 @@
 && store) %7B%0A
+  
       throw 
@@ -552,24 +552,32 @@
 nd stores')%0A
+      %7D%0A
     %7D%0A    th

Move validations to dev stage only