## mustacheCore.makeLiveBindingBranchRenderer Return a renderer function that evaluates the mustache expression and sets up live binding if a compute with dependencies is found. Otherwise, the element's value is set.  This function works by creating a `can.compute` from the mustache expression. If the compute has dependent observables, it passes the compute to `can.view.live`; otherwise, it updates the element's property based on the compute's value. 
@hide
Returns a renderer function that evaluates the mustache expression.
@param {String} mode
@param {can.stache.Expression} expression
@param {Object} state The html state of where the expression was found.
function(mode, expressionString, state){
		// Pre-process the expression.
		var exprData = core.expression.parse(expressionString);

		// A branching renderer takes truthy and falsey renderer.
		var branchRenderer = function branchRenderer(scope, parentSectionNodeList, truthyRenderer, falseyRenderer){
			// If this is within a tag, make sure we only get string values.
			var stringOnly = state.tag;
			//!steal-remove-start
			if (process.env.NODE_ENV !== 'production') {
				scope.set('scope.filename', state.filename);
				scope.set('scope.lineNumber', state.lineNo);
			}
			//!steal-remove-end
			var nodeList = [this];
			nodeList.expression = expressionString;
			// register this nodeList.
			// Register it with its parent ONLY if this is directly nested.  Otherwise, it's unnecessary.
			nodeLists.register(nodeList, null, parentSectionNodeList || true, state.directlyNested);

			// Get the evaluator. This does not need to be cached (probably) because if there
			// an observable value, it will be handled by `can.view.live`.
			var evaluator = makeEvaluator( scope, nodeList, mode, exprData, truthyRenderer, falseyRenderer, stringOnly );

			// Create a compute that can not be observed by other
			// computes. This is important because this renderer is likely called by
			// parent expressions.  If this value changes, the parent expressions should
			// not re-evaluate. We prevent that by making sure this compute is ignored by
			// everyone else.
			//var compute = can.compute(evaluator, null, false);
			var gotObservableValue = evaluator[canSymbol.for("can.onValue")];
			var observable;
			if(gotObservableValue) {
				observable = evaluator;
			} else {
				//!steal-remove-start
				if (process.env.NODE_ENV !== 'production') {
					Object.defineProperty(evaluator,"name",{
						value: "{{"+(mode || "")+expressionString+"}}"
					});
				}
				//!steal-remove-end
				observable = new Observation(evaluator,null,{isObservable: false});
			}

			if(canReflect.setPriority(observable, nodeList.nesting) === false) {
				throw new Error("can-stache unable to set priority on observable");
			}

			// Bind on the computeValue to set the cached value. This helps performance
			// so live binding can read a cached value instead of re-calculating.
			canReflect.onValue(observable, k);

			var value = canReflect.getValue(observable);

			// If value is a function and not a Lookup ({{foo}}),
			// it's a helper that returned a function and should be called.
			if(typeof value === "function" && !(exprData instanceof expression.Lookup)) {

				// A helper function should do it's own binding.  Similar to how
				// we prevented this function's compute from being noticed by parent expressions,
				// we hide any observables read in the function by saving any observables that
				// have been read and then setting them back which overwrites any `can.__observe` calls
				// performed in value.
				ObservationRecorder.ignore(value)(this);

			}
			// If the computeValue has observable dependencies, setup live binding.
			else if( canReflect.valueHasDependencies(observable) ) {
				// Depending on where the template is, setup live-binding differently.
				if(state.attr) {
					live.attr(this, state.attr, observable);
				}
				else if( state.tag )  {
					live.attrs( this, observable );
				}
				else if(state.text && !valueShouldBeInsertedAsHTML(value)) {
					//!steal-remove-start
					if (process.env.NODE_ENV !== 'production') {
						if(value !== null && typeof value === "object") {
							dev.warn("Previously, the result of "+
								expressionString+" in "+state.filename+":"+state.lineNo+
								", was being inserted as HTML instead of TEXT. Please use stache.safeString(obj) "+
								"if you would like the object to be treated as HTML.");
						}
					}
					//!steal-remove-end
					live.text(this, observable, this.parentNode, nodeList);
				} else {
					live.html(this, observable, this.parentNode, {
						nodeList: nodeList
					});
				}
			}
			// If the computeValue has no observable dependencies, just set the value on the element.
			else {

				if(state.attr) {
					domMutate.setAttribute(this, state.attr, value);
				}
				else if(state.tag) {
					live.attrs(this, value);
				}
				else if(state.text && !valueShouldBeInsertedAsHTML(value)) {
					this.nodeValue = live.makeString(value);
				}
				else if( value != null ){
					if (typeof value[viewInsertSymbol] === "function") {
						var insert = value[viewInsertSymbol]({
							nodeList: nodeList
						});
						var oldNodes = nodeLists.update(nodeList, [insert]);
						nodeLists.replace(oldNodes, insert);
					} else {
						nodeLists.replace([this], frag(value, this.ownerDocument));
					}
				}
			}
			// Unbind the compute.
			canReflect.offValue(observable, k);
		};

		branchRenderer.exprData = exprData;

		return branchRenderer;
	}