                 attrs.json = @node.toJSON()
             return attrs
 
+        # Proxy methods
+        isEmpty: ->
+            @node.isEmpty()
+
+        isBranch: ->
+            @node.isBranch()
+
+        isCondition: ->
+            @node.isCondition()
+
+        isComposite: ->
+            @node.isComposite()
+
         cacheNode: (node) =>
             if node.id
                 if not (cache = @nodes[node.id])
                     cache = @nodes[node.id] = []
-                cache.push node
-
-        promote: (node, type, nodes...) ->
-            node.promote(type, nodes...)
+                # Don't add redundant cache
+                if cache.indexOf(node) is -1
+                    cache.push node
+
+        promote: (node, nodes...) ->
+            if node is null
+                @node.promote nodes...
+            else
+                node.promote nodes...
+            @set 'json', @node.toJSON()
 
         demote: (node) ->
             node.demote()
+            @set 'json', @node.toJSON()
 
         add: (node, nodes...) ->
-            node.add(nodes...)
+            if node is null
+                node = @node
+
+            if node.isEmpty()
+                node.set nodes[0].attributes or nodes[0]
+            else
+                node.add(nodes...)
+                @cacheNode node for node in node.get 'children'
+            @set 'json', @node.toJSON()
 
         remove: (node) ->
             node.remove()
-            # Unreference it
-            if (idx = (cache = @nodes[node.id]).indexOf(node)) >= 0
-                cache.splice(idx)
+            # Dereference it
+            if (cache = @nodes[node.id]) and (idx = cache.indexOf(node)) >= 0
+                cache.splice(idx, 1)
+            @set 'json', @node.toJSON()
 
 
     class DataContexts extends Backbone.Collection

            return @

        add: (nodes...) ->
            if @type isnt 'branch'
                throw new Error 'Node is not a branch. Use "promote" to convert it into one'
            @attributes.children.push.apply @attributes.children, _.map nodes, (attrs) =>
                DataContextNode.parseAttrs attrs, @

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

        parse: (response) =>
            if response
                @nodes = {}
                @node = DataContextNode.parseAttrs response.json, null, @cacheNode

            return response
