             if (listener = listeners[event])?
                 child.removeListener?(event, listener)
                 listeners[event] = undefined
-    remove = ->
-        dispose()
+    remove = (soft) ->
         if this is child
             parent.removeListener('removed', remove)
-        else
+            dispose()
+            parent.removeListener('replaced', replace)
+            child.removeListener('replaced', replace)
+        else unless soft
             child.removeListener('removed', remove)
-        parent.removeListener('replaced', replace)
-        child.removeListener('replaced', replace)
+            dispose()
+            parent.removeListener('replaced', replace)
+            child.removeListener('replaced', replace)
     replace = (tag) ->
         if this is child
             remove.call(parent)

        @emit 'replaced', tag # internal
        tag

    remove: () =>
        @closed = 'removed' unless @closed
        @emit 'remove', this
        @emit 'removed' # internal
        @removeAllListeners()
        this

    ready: (callback) =>


    TagInstance = @builder?.Tag ? Tag
    newtag = new TagInstance name, attrs, null, opts
    add_tag.call this, newtag, (tag) ->
        tag.children children, opts if children?
    return newtag # hopefully this is still the same after the approval
