           args = (attributes.args ? '').split()
           script = htmlDecode(child.innerHTML)
           type = attributes.type or defaulttype
-          classattributes.$methods[attributes.name] = [transformScript(script, type), args]
+          classattributes.$methods[attributes.name] = [compiler.transform(script, type), args]
           # console.log 'added method', attributes.name, script, classattributes
         when 'setter'
           args = (attributes.args ? '').split()
           script = htmlDecode(child.innerHTML)
           type = attributes.type or defaulttype
-          classattributes.$methods['set_' + attributes.name] = [transformScript(script, type), args]
+          classattributes.$methods['set_' + attributes.name] = [compiler.transform(script, type), args]
           # console.log 'added setter', 'set_' + attributes.name, args, classattributes.$methods
         when 'attribute'
           classattributes[attributes.name] = attributes.value

      # console.log 'new node', @, attributes
      @sendEvent('init', @)

    applyConstraint: (property, expression) ->
      @constraints ?= {}
      @constraints[property] = 
        expression: 'return ' + expression #compileScript('return ' + expression).bind(@)
      # console.log 'adding constraint', property, expression, @
        bindings: {}

      bindings = @constraints[property].bindings
      scopes = findPropertyBindings(expression)
      # console.log 'found scopes', scopes
      for scope in scopes
        bindexpression = scope.binding

      @


  compiler = do ->
    cacheKey = "compilecache"
    if cacheKey of localStorage
      compileCache = JSON.parse(localStorage[cacheKey])
      # console.log 'restored', compileCache
    else
      compileCache = 
        bindings: {}
        script: 
          coffee: {}

    $(window).on('unload', -> 
      localStorage[cacheKey] = JSON.stringify(compileCache) 
      # console.log 'onunload', localStorage[cacheKey]
    )

    findBindings = do ->
      bindingCache = compileCache.bindings
      scopes = null
      propertyBindings = 
        MemberExpression: (n) ->
          # grab the property name
          name = n.property.name

          # remove the property so we can compute the rest of the expression
          n = n.object

          # push the scope onto the list
          scopes.push({binding: acorn.stringify(n), property: name})
          # console.log 'MemberExpression', name, n, acorn.stringify n
          return true

      (expression) ->
        return bindingCache[expression] if expression of bindingCache
        ast = acorn.parse(expression)
        scopes = []
        acorn.walkDown(ast, propertyBindings)
        bindingCache[expression] = scopes
        # console.log compileCache.bindings
        # return scopes
      # propertyBindings.find = _.memoize(propertyBindings.find)

    # transforms a script to javascript using a runtime compiler
    transform = do ->    
      coffeeCache = compileCache.script.coffee
      compilers = 
        coffee: (script) ->
          if script of coffeeCache
            # console.log 'cache hit', script
            return coffeeCache[script]
          if not window.CoffeeScript
            console.warn 'missing coffee-script.js include'
            return
          # console.log 'compiling coffee-script', script
          coffeeCache[script] = CoffeeScript.compile(script, bare: true) if script
          # console.log 'compiled coffee-script', script
          # console.log coffeeCache
          # return coffeeCache[script]

      (script='', name) ->
        return script unless name of compilers
        compilers[name](script) 

    # cache compiled scripts to speed up instantiation
    scriptCache = {}
    # compile a string into a function
    compile = (script='', args=[]) ->
      key = script + args.join()
      return scriptCache[key] if key of scriptCache
      # console.log 'compile', compiler, args, script
      try 
        # console.log scriptCache
        scriptCache[key] = new Function(args, script)
      catch e
        console.error('failed to compile', args, script, e)

    exports = 
      compile: compile
      transform: transform
      findBindings: findBindings


  class Node extends Eventable
    matchConstraint = /\${(.+)}/

    constructor: (el, attributes = {}) ->
      @subnodes = []
