docs: function (parent, reads, options) {
  		options = options || {};
  		var state = {
  			foundObservable: false
  		};
  		var getObserves;
  		if(options.foundObservable) {
  			getObserves = ObservationRecorder.trap();
  		}
  
  		// `cur` is the current value.
  		var cur = readValue(parent, 0, reads, options, state),
  			type,
  			// `prev` is the object we are reading from.
  			prev,
  			// `foundObs` did we find an observable.
  			readLength = reads.length,
  			i = 0,
  			last,
  			parentHasKey;
  
  		checkForObservableAndNotify(options, state, getObserves, parent, 0);
  
  		while( i < readLength ) {
  			prev = cur;
  			// try to read the property
  			for(var r=0, readersLength = observeReader.propertyReaders.length; r < readersLength; r++) {
  				var reader = observeReader.propertyReaders[r];
  				if(reader.test(cur)) {
  					cur = reader.read(cur, reads[i], i, options, state);
  					break; // there can be only one reading of a property
  				}
  			}
  			checkForObservableAndNotify(options, state, getObserves, prev, i);
  			last = cur;
  			i = i+1;
  			// read the value if it is a compute or function
  			cur = readValue(cur, i, reads, options, state, prev);
  
  			checkForObservableAndNotify(options, state, getObserves, prev, i-1);
  
  			type = typeof cur;
  			// early exit if need be
  			if (i < reads.length && (cur === null || cur === undefined )) {
  				parentHasKey = objHasKeyAtIndex(prev, reads, i - 1);
  				if (options.earlyExit && !parentHasKey) {
  					options.earlyExit(prev, i - 1, cur);
  				}
  				// return undefined so we know this isn't the right value
  				return {
  					value: undefined,
  					parent: prev,
  					parentHasKey: parentHasKey,
  					foundLastParent: false
  				};
  			}
  
  		}
  
  		parentHasKey = objHasKeyAtIndex(prev, reads, reads.length - 1);
  		// if we don't have a value, exit early.
  		if (cur === undefined && !parentHasKey) {
  			if (options.earlyExit) {
  				options.earlyExit(prev, i - 1);
  			}
  		}
  		return {
  			value: cur,
  			parent: prev,
  			parentHasKey: parentHasKey,
  			foundLastParent: true
  		};
  	}