docs: function(newnode, oldnode, lastnode, id, ids) {
  		var result = true;
  		var isSoftUpdate = false;
  		var isPluginUpdate = false; // TODO: plugins...
  		if ((newnode && !oldnode) || (!newnode && oldnode)) {
  			result = false;
  		} else if ((result = newnode.nodeType === oldnode.nodeType)) {
  			switch (oldnode.nodeType) {
  				case Node.TEXT_NODE:
  					if (newnode.data !== oldnode.data) {
  						result = false;
  					}
  					break;
  				case Node.ELEMENT_NODE:
  					if ((result = this._familiar(newnode, oldnode))) {
  						if ((result = this._checkatts(newnode, oldnode, ids))) {
  							if (this._maybesoft(newnode, oldnode)) {
  								if (this._confirmsoft(newnode, oldnode)) {
  									this._updatesoft(newnode, oldnode, ids);
  									isSoftUpdate = true; // prevents the replace update
  								}
  								result = false; // crawling continued in _updatesoft
  							} else {
  								if (oldnode.localName !== "textarea") { // TODO: better forms support!
  									result = newnode.childNodes.length === oldnode.childNodes.length;
  									if (!result && oldnode.id) {
  										lastnode = newnode;
  										id = oldnode.id;
  									}
  								}
  							}
  						}
  					}
  					break;
  			}
  		}
  		if (!result && !isSoftUpdate && !isPluginUpdate) {
  			this._updates.collect(new edbml.FunctionUpdate(this._doc).setup(id));
  			this._updates.collect(new edbml.HardUpdate(this._doc).setup(id, lastnode));
  		}
  		return result;
  	}