     DataContextNode.parseAttrs = (attrs, parent, callback) ->
         if not attrs
             node = new DataContextNode
-        # Existing node. Note this assumes
+        # Existing node
         else if attrs instanceof DataContextNode
             node = attrs
         # Branch
-        else if attrs.type is 'and' or attrs.type is 'or' and attrs.children?.length >= 2
+        else if isBranch attrs
             node = new DataContextNode type: attrs.type
-            children = _.map attrs.children, (_attrs) -> DataContextNode.parseAttrs _attrs, node
+            children = _.map attrs.children, (_attrs) -> DataContextNode.parseAttrs _attrs, node, callback
             node.set children: children
-            node.type = 'branch'
         # Condition
-        else if attrs.operator and attrs.id and attrs.value isnt undefined
+        else if isCondition attrs
             node = new DataContextNode attrs
-            node.type = 'condition'
         # Composite
-        else if attrs.composite is true and attrs.id
+        else if isComposite attrs
             node = new DataContextNode attrs
-            node.type = 'composite'
         else
             throw new Error 'Unknown node type'
 

            if @isNew() then super else @get 'url'

        parse: (response) =>
            @nodes = {}

            if response
                @node = DataContextNode.parseAttrs response.json, null, @cacheNode

            return response

        siblings: ->
            if @root then false else _.without @parent.get('children'), @

        # Proxy methods
        isEmpty: ->
            _.isEmpty @attributes

        isBranch: ->
            isBranch @attributes

        isCondition: ->
            isCondition @attributes

        isComposite: ->
            isComposite @attributes

        # Creates a new branch and adds this node along with one or more other
        # nodes to the branch
        promote: (nodes...) ->
            if _.isString nodes[0]
                type = nodes[0]
                if type isnt 'and' and type isnt 'or'
                    throw new Error 'Type must be "and" or "or"'
                nodes.splice 0, 1
            else
                type = 'and'

            if nodes.length is 0
                throw new Error 'At least one other node must be supplied'

            children = _.map [@toJSON(), nodes...], (attrs) =>
                DataContextNode.parseAttrs attrs, @

            @clear slient: true
            @set type: type, children: children
            return @
