function addObserver(observerState, getter, handler) {
	  // use the passed in getter as the key so we can rely on a byreference call for unobserve
	  var getterKey = getter;
	  if ((0, _keyPath.isKeyPath)(getter)) {
	    getter = (0, _getter.fromKeyPath)(getter);
	  }

	  var currId = observerState.get('nextId');
	  var storeDeps = (0, _getter.getStoreDeps)(getter);
	  var entry = _immutable2['default'].Map({
	    id: currId,
	    storeDeps: storeDeps,
	    getterKey: getterKey,
	    getter: getter,
	    handler: handler
	  });

	  var updatedObserverState = undefined;
	  if (storeDeps.size === 0) {
	    // no storeDeps means the observer is dependent on any of the state changing
	    updatedObserverState = observerState.update('any', function (observerIds) {
	      return observerIds.add(currId);
	    });
	  } else {
	    updatedObserverState = observerState.withMutations(function (map) {
	      storeDeps.forEach(function (storeId) {
	        var path = ['stores', storeId];
	        if (!map.hasIn(path)) {
	          map.setIn(path, _immutable2['default'].Set());
	        }
	        map.updateIn(['stores', storeId], function (observerIds) {
	          return observerIds.add(currId);
	        });
	      });
	    });
	  }

	  updatedObserverState = updatedObserverState.set('nextId', currId + 1).setIn(['observersMap', currId], entry);

	  return {
	    observerState: updatedObserverState,
	    entry: entry
	  };
	}
Adds a change observer whenever a certain part of the reactor state changes

1. observe(handlerFn) - 1 argument, called anytime reactor.state changes
2. observe(keyPath, handlerFn) same as above
3. observe(getter, handlerFn) called whenever any getter dependencies change with
   the value of the getter

Adds a change handler whenever certain deps change
If only one argument is passed invoked the handler whenever
the reactor state changes

@param {ObserverState} observerState
@param {KeyPath|Getter} getter
@param {function} handler
@return {ObserveResult}