docs: function dataBind(/*JsonML*/ node, /*object*/ data, /*int*/ index, /*int*/ count, /*object*/ args) {
  			try {
  				// recursively process each node
  				if (node) {
  					var output;
  
  					if ('function' === typeof node) {
  						output = callContext(self, data, index, count, args, node);
  
  						if (output instanceof JBST) {
  							// allow returned JBSTs to recursively bind
  							// useful for creating 'switcher' template methods
  							return output.dataBind(data, index, count, args);
  						}
  
  						// function result
  						return output;
  					}
  
  					if (node instanceof Array) {
  						var onBound = ('function' === typeof JsonML.BST.onbound) && JsonML.BST.onbound,
  							onAppend = ('function' === typeof JsonML.BST.onappend) && JsonML.BST.onappend,
  							appendCB = onAppend && function(parent, child) {
  								callContext(self, data, index, count, args, onAppend, [parent, child]);
  							};
  
  						// JsonML output
  						output = [];
  						for (var i=0; i<node.length; i++) {
  							var child = dataBind(node[i], data, index, count, args);
  							appendChild(output, child, appendCB);
  
  							if (!i && !output[0]) {
  								onAppend = appendCB = null;
  							}
  						}
  
  						if (output[0] && onBound) {
  							callContext(self, data, index, count, args, onBound, [output]);
  						}
  
  						// if output has attributes, check for JBST commands
  						if (JsonML.hasAttributes(output)) {
  							// visibility JBST command
  							var visible = output[1][SHOW];
  							if ('undefined' !== typeof visible) {
  								// cull any false-y values
  								if (!visible) {
  									// suppress rendering of entire subtree
  									return '';
  								}
  								// remove attribute
  								delete output[1][SHOW];
  							}
  
  							// jbst:oninit
  							ensureMethod(output[1], INIT);
  
  							// jbst:onload
  							ensureMethod(output[1], LOAD);
  						}
  
  						// JsonML element
  						return output;
  					}
  
  					if ('object' === typeof node) {
  						output = {};
  						// process each property in template node
  						for (var property in node) {
  							if (node.hasOwnProperty(property)) {
  								// evaluate property's value
  								var value = dataBind(node[property], data, index, count, args);
  								if ('undefined' !== typeof value && value !== null) {
  									output[property] = value;
  								}
  							}
  						}
  						// attributes object
  						return output;
  					}
  				}
  
  				// rest are simple value types, so return node directly
  				return node;
  			} catch (ex) {
  				try {
  					// handle error with complete context
  					var err = ('function' === typeof JsonML.BST.onerror) ? JsonML.BST.onerror : onError;
  					return callContext(self, data, index, count, args, err, [ex]);
  				} catch (ex2) {
  					return '['+ex2+']';
  				}
  			}
  		}