Update xpath and scope property when refsDecl is updated

        :returns: Scope, Xpath
766523
def _parseXpathScope(self):
        
        rd = self.refsDecl
        matches = REFSDECL_SPLITTER.findall(rd)
        return REFSDECL_REPLACER.sub("?", "".join(matches[0:-1])), REFSDECL_REPLACER.sub("?", matches[-1])
278415
function(el, scope) {
    var tplScopeObject = {};

    $myelements.debug("Trying to update Element Scope without data from scope: %s", scope);
    // If no data is passed
    // we look up in localstorage
    $myelements.localDataForElement(el, scope, function onLocalDataForElement(err, data) {
      if (err) {
        // Maybe this is useless if there's no data to update.
        // If I don't do this, the element keeps its EJS tags untouched
        $myelements.debug("Updating element scope with empty object");
        // Default to [] because it's an object and its iterable. 
        // This way EJS templates cand use $().each to avoid 'undefined'errors
        data = [];
      }
      tplScopeObject[scope] = data;
      $myelements.doRender(el, tplScopeObject);
    });
  }
1317768
function (bindingDef, targetScope, attrKey, context) {
            var path = bindingDef.path;
            var pathElement = path[0];

            var scope;
            var searchScope = targetScope;
            if (pathElement.type != Binding.TYPE_FNC && attrKey == pathElement.name) {
                searchScope = searchScope.$parentScope;
            }

            if (pathElement.type == Binding.TYPE_FNC) {
                scope = searchScope.getScopeForFncName(pathElement.name);
            } else {
                scope = searchScope.getScopeForKey(pathElement.name);
            }

            if (scope) {
                if (bindingDef.type !== "static") {
                    var cb;
                    if (_.isFunction(attrKey)) {
                        cb = attrKey;
                    }

                    var twoWay = (bindingDef.type == Binding.TYPE_TWOWAY);

                    var options = {
                        scope: scope,
                        path: path,
                        parent: bindingDef.parent,
                        target: targetScope,
                        twoWay: twoWay,
                        context: context,
                        bindingCreator: this
                    };

                    if (twoWay) {
                        var fncName,
                            fncScope;
                        if (bindingDef.transform && bindingDef.transform.length) {
                            fncName = bindingDef.transform[0].name;
                            fncScope = searchScope.getScopeForFncName(fncName);
                            if (fncScope && fncScope[fncName] instanceof Function) {
                                options.transform = fncScope[fncName];
                                options.transformScope = fncScope;
                            }
                        }

                        if (bindingDef.transformBack && bindingDef.transformBack.length) {
                            fncName = bindingDef.transformBack[0].name;
                            fncScope = searchScope.getScopeForFncName(fncName);
                            if (fncScope && fncScope[fncName] instanceof Function) {
                                options.transformBack = fncScope[fncName];
                                options.transformBackScope = fncScope;
                            }
                        }
                    }

                    if (cb) {
                        options.callback = cb;
                    } else {
                        options.targetKey = attrKey;
                    }

                    return new Binding(options);
                } else {
                    var par,
                        newPath = [];

                    function resolvePath(scope, path) {
                        return scope.get(resolveParameter(path));
                    }

                    function resolveParameter(path) {
                        var pathElement,
                            first,
                            scope,
                            newPath = [],
                            parameter = [];
                        for (var i = 0; i < path.length; i++) {
                            pathElement = path[i];
                            if (_.isObject(pathElement)) {
                                if (pathElement.type === "fnc") {
                                    parameter = [];
                                    for (var j = 0; j < pathElement.parameter.length; j++) {
                                        par = pathElement.parameter[j];
                                        // if it's a path
                                        if (_.isArray(par)) {
                                            first = par[0];
                                            // TODO: check targetscope first
                                            if (first.type === "var") {
                                                scope = searchScope.getScopeForKey(first.name);
                                            } else if (first.type === "fnc") {
                                                scope = searchScope.getScopeForKey(first.name);
                                            }
                                            if (scope) {
                                                par = resolvePath(scope, par);
                                            }
                                        }
                                        parameter.push(par);
                                    }

                                }
                                newPath.push({
                                    index: pathElement.index,
                                    type: pathElement.type,
                                    name: pathElement.name,
                                    parameter: parameter
                                })
                            }
                        }

                        return newPath;
                    }

                    return scope.get(resolveParameter(bindingDef.path));
                }
            } else {
                throw new Error("Couldn't find scope for " + pathElement.name);
            }

        }
88615
def update_text(self, selector, new_value, by=By.CSS_SELECTOR,
                    timeout=settings.LARGE_TIMEOUT, retry=False):
        
        if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
            timeout = self.__get_new_timeout(timeout)
        if page_utils.is_xpath_selector(selector):
            by = By.XPATH
        self.update_text_value(selector, new_value, by=by,
                               timeout=timeout, retry=retry)
284005
def _update_dates(self, xpath_root=None, **update_props):
        

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = (update_props['values'] or {}).get(DATE_VALUES) or u''
        xpaths = self._data_structures[prop]

        if not self.dates:
            date_xpaths = xpath_root
        elif self.dates[DATE_TYPE] != DATE_TYPE_RANGE:
            date_xpaths = xpaths.get(self.dates[DATE_TYPE], u'')
        else:
            date_xpaths = [
                xpaths[DATE_TYPE_RANGE_BEGIN],
                xpaths[DATE_TYPE_RANGE_END]
            ]

        if xpath_root:
            remove_element(tree_to_update, xpath_root)

        return update_property(tree_to_update, xpath_root, date_xpaths, prop, values)
340345
def update(self):
        
        if self.instance is None:
            raise CQLEngineException("DML Query intance attribute is None")
        assert type(self.instance) == self.model
        null_clustering_key = False if len(self.instance._clustering_keys) == 0 else True
        static_changed_only = True
        statement = UpdateStatement(self.column_family_name, ttl=self._ttl,
                                    timestamp=self._timestamp, transactions=self._transaction)
        for name, col in self.instance._clustering_keys.items():
            null_clustering_key = null_clustering_key and col._val_is_null(getattr(self.instance, name, None))
        #get defined fields and their column names
        for name, col in self.model._columns.items():
            # if clustering key is null, don't include non static columns
            if null_clustering_key and not col.static and not col.partition_key:
                continue 
            if not col.is_primary_key:
                val = getattr(self.instance, name, None)
                val_mgr = self.instance._values[name]

                # don't update something that is null
                if val is None:
                    continue

                # don't update something if it hasn't changed
                if not val_mgr.changed and not isinstance(col, Counter):
                    continue
                
                static_changed_only = static_changed_only and col.static
                if isinstance(col, (BaseContainerColumn, Counter)):
                    # get appropriate clause
                    if isinstance(col, List): klass = ListUpdateClause
                    elif isinstance(col, Map): klass = MapUpdateClause
                    elif isinstance(col, Set): klass = SetUpdateClause
                    elif isinstance(col, Counter): klass = CounterUpdateClause
                    else: raise RuntimeError

                    # do the stuff
                    clause = klass(col.db_field_name, val,
                            previous=val_mgr.previous_value, column=col)
                    if clause.get_context_size() > 0:
                        statement.add_assignment_clause(clause)
                else:
                    statement.add_assignment_clause(AssignmentClause(
                        col.db_field_name,
                        col.to_database(val)
                    ))

        if statement.get_context_size() > 0 or self.instance._has_counter:
            for name, col in self.model._primary_keys.items():
                # only include clustering key if clustering key is not null, and non static columns are changed to avoid cql error
                if (null_clustering_key or static_changed_only) and (not col.partition_key):
                    continue
                statement.add_where_clause(WhereClause(
                    col.db_field_name,
                    EqualsOperator(),
                    col.to_database(getattr(self.instance, name))
                ))
            self._execute(statement)

        if not null_clustering_key:
            self._delete_null_columns()
526477
def update_from_element(self, elem):
        """"""
        self._elem = elem

        for attrname in self.attributes:
            try:
                delattr(self, attrname)
            except AttributeError:
                pass

        document_url = elem.attrib.get('href')
        if document_url is not None:
            self._url = document_url

        return self
1263002
def getElementDeclaration(self, attribute=None):
        
        if attribute:
            return XMLSchemaComponent.getElementDeclaration(self, attribute)
        return XMLSchemaComponent.getElementDeclaration(self, 'ref')
1108050
def _eval_xpath(self, xpath):
        
        if isinstance(xpath, etree.XPath):
            result = xpath(self._dataObject)
        else:
            result = self._dataObject.xpath(xpath,namespaces=self._namespaces)

        #print 'Xpath expression:', xpath
        #print etree.tostring(self._dataObject)
        #print 'Got Result: \n%s\n   End Result' % result

        return result
340193
def apply_update(self, doc, update_spec):
        """"""

        # Helper to cast a key for a list or dict, or raise ValueError
        def _convert_or_raise(container, key):
            if isinstance(container, dict):
                return key
            elif isinstance(container, list):
                return int(key)
            else:
                raise ValueError

        # Helper to retrieve (and/or create)
        # a dot-separated path within a document.
        def _retrieve_path(container, path, create=False):
            looking_at = container
            for part in path:
                if isinstance(looking_at, dict):
                    if create and part not in looking_at:
                        looking_at[part] = {}
                    looking_at = looking_at[part]
                elif isinstance(looking_at, list):
                    index = int(part)
                    # Do we need to create additional space in the array?
                    if create and len(looking_at) <= index:
                        # Fill buckets with None up to the index we need.
                        looking_at.extend([None] * (index - len(looking_at)))
                        # Bucket we need gets the empty dictionary.
                        looking_at.append({})
                    looking_at = looking_at[index]
                else:
                    raise ValueError
            return looking_at

        def _set_field(doc, to_set, value):
            if "." in to_set:
                path = to_set.split(".")
                where = _retrieve_path(doc, path[:-1], create=True)
                index = _convert_or_raise(where, path[-1])
                wl = len(where)
                if isinstance(where, list) and index >= wl:
                    where.extend([None] * (index + 1 - wl))
                where[index] = value
            else:
                doc[to_set] = value

        def _unset_field(doc, to_unset):
            try:
                if "." in to_unset:
                    path = to_unset.split(".")
                    where = _retrieve_path(doc, path[:-1])
                    index_or_key = _convert_or_raise(where, path[-1])
                    if isinstance(where, list):
                        # Unset an array element sets it to null.
                        where[index_or_key] = None
                    else:
                        # Unset field removes it entirely.
                        del where[index_or_key]
                else:
                    del doc[to_unset]
            except (KeyError, IndexError, ValueError):
                source_version = get_mininum_mongodb_version()
                if source_version is None or source_version.at_least(2, 6):
                    raise
                # Ignore unset errors since MongoDB 2.4 records invalid
                # $unsets in the oplog.
                LOG.warning(
                    "Could not unset field %r from document %r. "
                    "This may be normal when replicating from "
                    "MongoDB 2.4 or the destination could be out of "
                    "sync." % (to_unset, doc)
                )

        # wholesale document replacement
        if "$set" not in update_spec and "$unset" not in update_spec:
            # update spec contains the new document in its entirety
            return update_spec
        else:
            try:
                # $set
                for to_set in update_spec.get("$set", []):
                    value = update_spec["$set"][to_set]
                    _set_field(doc, to_set, value)

                # $unset
                for to_unset in update_spec.get("$unset", []):
                    _unset_field(doc, to_unset)

            except (KeyError, ValueError, AttributeError, IndexError):
                exc_t, exc_v, exc_tb = sys.exc_info()
                msg = "Cannot apply update %r to %r" % (update_spec, doc)
                raise UpdateDoesNotApply(msg).with_traceback(exc_tb)
            return doc
476404
def _update_extent(self):
        """"""
        #For new instances, their length is being updated by the module
        #updater and will include *all* statements, so we don't want to
        #keep changing the endpoints.
        if self.bar_extent:
            return
            
        original = self.element.end
        if self.mode == "insert":
            #The end value needs to increase by the length of the current
            #statement being executed.
            self.element.end += self.curlength
        elif self.mode == "delete":
            #Reduce end by statement length
            self.element.end -= self.curlength
        elif self.mode == "replace":
            #Check whether we are currently doing the delete portion of the
            #replacement or the insert portion.
            if self.state[0] is None:
                self.element.end -= self.curlength
            else:
                self.element.end += self.curlength

        #Keep track of the total effect of all statements in this operation
        #so that it is easy to update the module once they are all done.
        self.length += self.element.end - original
16993
def _update(self, **kwargs):
        
        updated = False
        if 'proxy_server' in kwargs:
            proxy_server = kwargs.get('proxy_server')
            if not proxy_server and self._inspected_service_ref:
                self.protocol_agent_values.pop('inspected_service_ref', None)
                updated = True
            elif isinstance(proxy_server, ProxyServer):
                # Need the inspected service reference for the protocol
                enabled_services = {svc.name:svc.href for svc in proxy_server.inspected_services}
                
                if self.protocol_agent.name not in enabled_services:
                    raise MissingDependency('The specified ProxyServer %r does not enable '
                        'the required protocol %s' % (proxy_server.name, self.protocol_agent.name))
                
                if self._inspected_service_ref != enabled_services.get(self.protocol_agent.name):
                    self.protocol_agent_values['inspected_service_ref'] = enabled_services.get(
                        self.protocol_agent.name)
                    updated = True
        return updated
826256
def _update_from_globals(xtag, xmlglobals, container):
    
    #We also need to perform a globals update on each of the *original* child tags
    #in the current tag being updated.
    for child in list(xtag):
        _update_from_globals(child, xmlglobals, xtag)

    #If the tag doesn't have a value that is in the global defaults
    #then we automatically copy it over.
    if "defaults" in xmlglobals:
        #Iterate over the attributes that we have default values for.
        for key in xmlglobals["defaults"]:
            if key not in xtag.attrib:
                overwrite = True
                #If the key is a limited one, then it only gets copied to
                #tags that we know can actually use the attribute.
                if key in limited:
                    overwrite = (xtag.tag in monitored and key in monitored[xtag.tag])
                if overwrite:
                    xtag.attrib[key] = xmlglobals["defaults"][key]

    #For the global tags, we just want to update using the default values
    #They aren't allowed to reference other globals.
    if container is None:
        return                
                    
    def update_tag(xtag, gtag):
        """Updates the missing attributes in xtag with those from gtag."""
        for attr, value in gtag.attr.items():
            if attr not in xtag.attrib:
                xtag.attr[attr] = value
                
    def resolve_global(xtag, xmlglobals, xtagname, gtagname, attrib, container, op, gassumed):
        """Adds the child in xmlglobals with the relevant id to the tag.

        :arg xtag: the tag with the reference to a global tag.
        :arg xmlglobals: the dictionary of global tags extracted from <global>.
        :arg tagname: the name of the global tag to look for.
        :arg attrib: the name of the attribute in 'xtag' that references the
          global tag to process.
        :arg container: for "op"=="append", the XMLElement to append the global
          tag to as a subelement.
        :arg op: one of ["append", "update"]. For "append" the global tag is appended
          as a subelement to 'container'. For "update", the attributes of the global
          tag are copied to 'xtag'.
        :arg gassumed: when True, the 'attrib' being examined is assumed to reference
          only tags in <globals>, so no 'global:' prefix is required before attributes.
        """
        if attrib not in xtag.attrib:
            return False

        result = False
        if xtag.tag == xtagname and (gassumed or "global:" in xtag.attrib[attrib]):
            #We allow a ';'-separated list of global tag names, all of
            #which are appended to the child's subelements list.
            i = -1
            for sattr in xtag.attrib[attrib].split(";"):
                gid = sattr.strip().split(":")[1] if ":" in sattr else sattr.strip()
                #Since ordering matters, if the id starts with ^, we insert it at
                #the beginning of the subelements list instead of appending
                if gid[0] == '^':
                    insert = True
                    gid = gid[1::]
                    i += 1
                else:
                    insert = False
                    
                if gtagname in xmlglobals and gid.lower() in xmlglobals[gtagname]:
                    gtag = xmlglobals[gtagname][gid.lower()]
                    if op == "append":
                        if insert:
                            container.insert(i, gtag)
                        else:
                            container.append(gtag)
                    elif op == "update":
                        update_tag(xtag, gtag)
                    result = True
                else:
                    from fortpy.msg import warn
                    wstr = 'The global tag of type <{}> for <{} {}="{}"> does not exist.'
                    warn(wstr.format(gtagname, xtagname, attrib, xtag.attrib[attrib]))

            #Overwrite the name of the tag to not have the 'global:' in it anymore.
            xtag.attrib[attrib] = xtag.attrib[attrib].replace("global:", "")

        return result
                
    #Next, we just need to check the attributes of the tag that are allowed
    #to point to global tag children.
    i = 0
    #The order of these is xtagname, gtagname, xtagattrib, container, op, gassumed
    tags = [("assignment", "value", "value", xtag, "append", False),
            ("target", "output", "compareto", container, "append", False),
            ("test", "input", "inputs", xtag, "append", True),
            ("test", "global", "globals", xtag, "append", True),
            ("test", "assignment", "assignments", xtag, "append", True),
            ("test", "mapping", "mappings", xtag, "append", True),
            ("group", "input", "inputs", xtag, "append", True),
            ("group", "global", "globals", xtag, "append", True),
            ("group", "assignment", "assignments", xtag, "append", True),
            ("group", "mapping", "mappings", xtag, "append", True)]

    while i < len(tags):
        resolve_global(xtag, xmlglobals, *tags[i])
        i += 1

    if xtag.tag in ["test", "group"]:
        _handle_ignores(xtag)

    if xtag.tag == "auto":
        _expand_autotag(xtag, container)
1246610
function() {
		var xPath = {};
		var mParserData = AnnotationParser._parserData;

		if (Device.browser.msie) {// old IE
			xPath = {
				setNameSpace : function(outNode) {
					outNode.setProperty("SelectionNamespaces",
							'xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" xmlns:d="http://docs.oasis-open.org/odata/ns/edm"');
					outNode.setProperty("SelectionLanguage", "XPath");
					return outNode;
				},
				selectNodes : function(xPath, inNode) {
					return inNode.selectNodes(xPath);
				},
				nextNode : function(node) {
					return node.nextNode();
				},
				getNodeText : function(node) {
					return node.text;
				}
			};
		} else {// Chrome, Firefox, Opera, etc.
			xPath = {
				setNameSpace : function(outNode) {
					return outNode;
				},
				nsResolver : function(prefix) {
					var ns = {
						"edmx" : "http://docs.oasis-open.org/odata/ns/edmx",
						"d" : "http://docs.oasis-open.org/odata/ns/edm"
					};
					return ns[prefix] || null;
				},
				selectNodes : function(sPath, inNode) {
					var xmlNodes = mParserData.xmlDocument.evaluate(sPath, inNode, this.nsResolver, /* ORDERED_NODE_SNAPSHOT_TYPE: */ 7, null);
					xmlNodes.length = xmlNodes.snapshotLength;
					return xmlNodes;
				},
				nextNode : function(node, item) {
					return node.snapshotItem(item);
				},
				getNodeText : function(node) {
					return node.textContent;
				}
			};
		}

		xPath.getPath = function(oNode) {
			var sPath = "";
			var sId = "getAttribute" in oNode ? oNode.getAttribute("id") : "";
			var sTagName = oNode.tagName ? oNode.tagName : "";

			if (sId) {
				// If node has an ID, use that
				sPath = 'id("' + sId + '")';
			} else if (oNode instanceof Document) {
				sPath = "/";
			} else if (sTagName.toLowerCase() === "body") {
				// If node is the body element, just return its tag name
				sPath = sTagName;
			} else if (oNode.parentNode) {
				// Count the position in the parent and get the path of the parent recursively

				var iPos = 1;
				for (var i = 0; i < oNode.parentNode.childNodes.length; ++i) {
					if (oNode.parentNode.childNodes[i] === oNode) {
						// Found the node inside its parent
						sPath = xPath.getPath(oNode.parentNode) +  "/" + sTagName + "[" + iPos + "]";
						break;
					} else if (oNode.parentNode.childNodes[i].nodeType === 1 && oNode.parentNode.childNodes[i].tagName === sTagName) {
						// In case there are other elements of the same kind, count them
						++iPos;
					}
				}
			} else {
				Log.error("Wrong Input node - cannot find XPath to it: " + sTagName);
			}

			return sPath;
		};

		return xPath;
	}
534233
def to_xml_updates
      doc = Nokogiri::XML::Document.new
      root = doc.create_element("Updates")
      self.class.elements.each do |name, field|
        value = read_attribute(name)
        # Create or update existing fields
        if changes.include?(name.to_s)
          field.to_xml_updates(value) do |field_uri_xml, element_xml|
            # Exchange does not like updating to nil, so delete those.
            if element_xml.text.present?
              set_item_field = doc.create_element("SetItemField")
              set_item_field << field_uri_xml
              element_wrapper = doc.create_element(tag_name)
              element_wrapper << element_xml
              set_item_field << element_wrapper
              root << set_item_field
            else
              delete_item_field = doc.create_element("DeleteItemField")
              delete_item_field << field_uri_xml
              root << delete_item_field
            end
          end
        end
        # Delete removed phone numbers, etc
        if changes.include?(name.to_s) && value.is_a?(Array)
          old_values, new_values = changes[name.to_s]
          deleted_values = old_values - new_values
          field.to_xml_updates(deleted_values) do |field_uri_xml, _|
            delete_item_field = doc.create_element("DeleteItemField")
            delete_item_field << field_uri_xml
            root << delete_item_field
          end
        end
      end
      root
    end
418517
function(el, hookupOptions) {
                    // Setup values passed to component
                    var initalScopeData = {},
                        component = this,
                        twoWayBindings = {},
                        // what scope property is currently updating
                        scopePropertyUpdating,
                        // the object added to the scope
                        componentScope,
                        frag;

                    // ## Scope

                    // Add scope prototype properties marked with an "@" to the `initialScopeData` object
                    can.each(this.constructor.attributeScopeMappings, function(val, prop) {
                        initalScopeData[prop] = el.getAttribute(can.hyphenate(val));
                    });

                    // Get the value in the scope for each attribute
                    // the hookup should probably happen after?
                    can.each(can.makeArray(el.attributes), function(node, index) {
                        var name = can.camelize(node.nodeName.toLowerCase()),
                            value = node.value;



                        // Ignore attributes already present in the ScopeMappings.
                        if (component.constructor.attributeScopeMappings[name] || ignoreAttributesRegExp.test(name) || viewCallbacks.attr(node.nodeName)) {
                            return;
                        }
                        // Only setup bindings if attribute looks like `foo="{bar}"`
                        if (value[0] === "{" && value[value.length - 1] === "}") {
                            value = value.substr(1, value.length - 2);
                        } else {
                            // Legacy template types will crossbind "foo=bar"
                            if (hookupOptions.templateType !== "legacy") {
                                initalScopeData[name] = value;
                                return;
                            }
                        }
                        // Cross-bind the value in the scope to this 
                        // component's scope
                        var computeData = hookupOptions.scope.computeData(value, {
                                args: []
                            }),
                            compute = computeData.compute;

                        // bind on this, check it's value, if it has dependencies
                        var handler = function(ev, newVal) {
                            scopePropertyUpdating = name;
                            componentScope.attr(name, newVal);
                            scopePropertyUpdating = null;
                        };

                        // Compute only returned if bindable
                        compute.bind("change", handler);

                        // Set the value to be added to the scope
                        initalScopeData[name] = compute();

                        // We don't need to listen to the compute `change` if it doesn't have any dependencies
                        if (!compute.hasDependencies) {
                            compute.unbind("change", handler);
                        } else {
                            // Make sure we unbind (there's faster ways of doing this)
                            can.bind.call(el, "removed", function() {
                                compute.unbind("change", handler);
                            });
                            // Setup the two-way binding
                            twoWayBindings[name] = computeData;
                        }

                    });
                    if (this.constructor.Map) {
                        // If `Map` property is set on the constructor use it to wrap the `initialScopeData`
                        componentScope = new this.constructor.Map(initalScopeData);
                    } else if (this.scope instanceof can.Map) {
                        // If `this.scope` is instance of `can.Map` assign it to the `componentScope`
                        componentScope = this.scope;
                    } else if (can.isFunction(this.scope)) {
                        // If `this.scope` is a function, call the function and 
                        var scopeResult = this.scope(initalScopeData, hookupOptions.scope, el);

                        if (scopeResult instanceof can.Map) {
                            // If the function returns a can.Map, use that as the scope
                            componentScope = scopeResult;
                        } else if (scopeResult.prototype instanceof can.Map) {
                            // If `scopeResult` is of a `can.Map` type, use it to wrap the `initialScopeData`
                            componentScope = new scopeResult(initalScopeData);
                        } else {
                            // Otherwise extend `can.Map` with the `scopeResult` and initialize it with the `initialScopeData`
                            componentScope = new(can.Map.extend(scopeResult))(initalScopeData);
                        }

                    }

                    // ## Two way bindings

                    // Object to hold the bind handlers so we can tear them down
                    var handlers = {};
                    // Setup reverse bindings
                    can.each(twoWayBindings, function(computeData, prop) {
                        handlers[prop] = function(ev, newVal) {
                            // Check that this property is not being changed because
                            // it's source value just changed
                            if (scopePropertyUpdating !== prop) {
                                computeData.compute(newVal);
                            }
                        };
                        componentScope.bind(prop, handlers[prop]);
                    });
                    // Teardown reverse bindings when the element is removed
                    can.bind.call(el, "removed", function() {
                        can.each(handlers, function(handler, prop) {
                            componentScope.unbind(prop, handlers[prop]);
                        });
                    });
                    // Setup the attributes bindings
                    if (!can.isEmptyObject(this.constructor.attributeScopeMappings) || hookupOptions.templateType !== "legacy") {
                        // Bind on the `attributes` event and update the scope.
                        can.bind.call(el, "attributes", function(ev) {
                            // Convert attribute name from the `attribute-name` to the `attributeName` format.
                            var camelized = can.camelize(ev.attributeName);
                            if (!twoWayBindings[camelized]) {
                                // If there is a mapping for this attribute, update the `componentScope` attribute
                                componentScope.attr(camelized, el.getAttribute(ev.attributeName));
                            }
                        });

                    }

                    // Set `componentScope` to `this.scope` and set it to the element's `data` object as a `scope` property
                    this.scope = componentScope;
                    can.data(can.$(el), "scope", this.scope);

                    // Create a real Scope object out of the scope property
                    var renderedScope = hookupOptions.scope.add(this.scope),
                        options = {
                            helpers: {}
                        };

                    // ## Helpers

                    // Setup helpers to callback with `this` as the component
                    can.each(this.helpers || {}, function(val, prop) {
                        if (can.isFunction(val)) {
                            options.helpers[prop] = function() {
                                return val.apply(componentScope, arguments);
                            };
                        }
                    });

                    // ## `events` control

                    // Create a control to listen to events
                    this._control = new this.constructor.Control(el, {
                            // Pass the scope to the control so we can listen to it's changes from the controller.
                            scope: this.scope
                        });

                    // ## Rendering

                    // If this component has a template (that we've already converted to a renderer)
                    if (this.constructor.renderer) {
                        // If `options.tags` doesn't exist set it to an empty object.
                        if (!options.tags) {
                            options.tags = {};
                        }

                        // We need be alerted to when a <content> element is rendered so we can put the original contents of the widget in its place
                        options.tags.content = function contentHookup(el, rendererOptions) {
                            // First check if there was content within the custom tag
                            // otherwise, render what was within <content>, the default code
                            var subtemplate = hookupOptions.subtemplate || rendererOptions.subtemplate;

                            if (subtemplate) {

                                // `rendererOptions.options` is a scope of helpers where `<content>` was found, so
                                // the right helpers should already be available.
                                // However, `_tags.content` is going to point to this current content callback.  We need to 
                                // remove that so it will walk up the chain

                                delete options.tags.content;

                                can.view.live.replace([el], subtemplate(
                                        // This is the context of where `<content>` was found
                                        // which will have the the component's context
                                        rendererOptions.scope,

                                        rendererOptions.options));

                                // Restore the content tag so it could potentially be used again (as in lists)
                                options.tags.content = contentHookup;
                            }
                        };
                        // Render the component's template
                        frag = this.constructor.renderer(renderedScope, hookupOptions.options.add(options));
                    } else {
                        // Otherwise render the contents between the 
                        if (hookupOptions.templateType === "legacy") {
                            frag = can.view.frag(hookupOptions.subtemplate ? hookupOptions.subtemplate(renderedScope, hookupOptions.options.add(options)) : "");
                        } else {
                            frag = hookupOptions.subtemplate ? hookupOptions.subtemplate(renderedScope, hookupOptions.options.add(options)) : document.createDocumentFragment();
                        }

                    }
                    // Append the resulting document fragment to the element
                    can.appendChild(el, frag);
                }
361771
def update(cls, spec, updates, upsert=False):
        '''
        
        '''
        if 'key' in spec:
            previous = cls.get(spec['key'])
        else:
            previous = None
        if previous:
            # Update existing data.
            current = cls(**previous.__dict__)
        elif upsert:
            # Create new data.
            current = cls(**spec)
        else:
            current = None
        # XXX Should there be any error thrown if this is a noop?
        if current:
            current.__dict__.update(updates)
            current.save()
        return current