         do @listen
         # prefill builder with state
         @make(@builder) # create a dom object
-        @builder._browser_done = deferred_callbacks()
-        do @builder._browser_done.callback() # builder is allways done
+        (@builder._browser ?= new BrowserState).done = deferred_callbacks()
+        do @builder._browser.done.callback() # builder is allways done
         # register ready handler
         @template.register 'ready', (tag, next) ->
+            tag._browser ?= new BrowserState
             # when tag is already in the dom its fine,
             #  else wait until it is inserted into dom
-            if tag._browser_ready is yes
+            if tag._browser.ready is yes
                 next(tag)
             else
-                tag._browser_ready = ->
-                    next(tag)
+                tag._browser.ready = next
         return this
 
     use: (plugin) ->

        return if removed el
        @make(el) # create a dom object
        that = this
        el._browser_manip    ?= cancelable_and_retrivable_callbacks()
        el._browser_done     ?= deferred_callbacks()
        parent._browser_done ?= deferred_callbacks()
        el._browser_manip.reset()
        while (cb = el._browser_manip.callbacks.shift())?
            @animation.push(cb)

        ecb = el._browser_done.callback()
        pcb = parent._browser_done.callback()
        if el is el.builder then ecb() else el.ready(ecb)
        if parent is parent.builder then pcb() else parent.ready(pcb)

        el._browser_insert ?= singlton_callback el, ->
            return if removed this
            that.insert_callback(this)
        el._browser_insert.replace?(el)

        el._browser_parent_done ?= singlton_callback el, ->
            return if removed this
            that.parent_done_callback(this)
        el._browser_parent_done.replace(el)
        parent._browser_done(el._browser_parent_done)

    onreplace: (oldtag, newtag) ->
        return if removed(oldtag) or removed(newtag)
        newtag._browser_parent_done ?= oldtag._browser_parent_done
        newtag._browser_insert      ?= oldtag._browser_insert
        newtag._browser_done        ?= oldtag._browser_done
        oldtag._browser_parent_done  = null
        oldtag._browser_insert       = null
        oldtag._browser_done         = null

        @onadd(oldtag.parent, newtag)

        oldtag._browser_manip?.cancel?()
        newtag._browser_manip.reset()
        # if manip left from last time run them
        while (cb = newtag._browser_manip.callbacks.shift())?
            @animation.push(cb)

        if newtag._browser_insert is true
            that = this
            newtag._browser_replace ?= oldtag._browser_replace
            oldreplacerequest = newtag._browser_replace?
            newtag._browser_replace ?= singlton_callback newtag, ->
                return if removed this
                that.replace_callback(oldtag, this)
            newtag._browser_replace.replace?(newtag)
            oldtag._browser_replace = null
            unless oldreplacerequest
                @animation.push(newtag._browser_replace)

    ontext: (el, text) ->
        el._browser_manip ?= cancelable_and_retrivable_callbacks(yes)
        @animation.push el._browser_manip =>
            @fn.text(el, text)

    onraw: (el, html) ->
        el._browser_manip ?= cancelable_and_retrivable_callbacks(yes)
        @animation.push el._browser_manip =>
            @fn.raw(el, html)

    onattr: (el, key, value) ->
        el._browser_manip ?= cancelable_and_retrivable_callbacks(yes)
        @animation.push el._browser_manip =>
            @fn.attr(el, key, value)

    onshow: (el) ->

defaultfn = {}
EVENTS.forEach (e) ->
    defaultfn[e] = -> throw new Error "no specific fn for #{e} defined" # dummy


class BrowserState
    initialize: (prev) ->
        @manip ?= cancelable_and_retrivable_callbacks()
        @done  ?= deferred_callbacks()
        @manip.reset()

    mergeInto: (state) ->
        for key in SHARED
            state[key] ?= this[key]
            this[key] = null
        state

    destroy: (opts) ->
        @manip?.cancel()
        @done?.reset()
        if opts.soft
            this[key] = null for key in SHARED
        else
            delete this[key] for key in SHARED
            delete manip
        this


class BrowserAdapter
