             element.selectedIndex = valueIndexOf options, newValue
         else
           element.value = newValue
-
-      bindObservable element, value, context, update
+        return
+
     else
       # Because firing twice with the same value is idempotent just binding both
       # oninput and onchange handles the widest range of inputs and browser
       # inconsistencies.
       element.oninput = element.onchange = ->
         value?(element.value)
+        return
 
       bindObservable element, value, context, (newValue) ->
         unless element.value is newValue
           element.value = newValue
+        return
 
   return
 

      append get item, context
    else
      element.appendChild document.createTextNode item

  update = (contents) ->
    # TODO: Zipper merge optimization to more efficiently modify the DOM
    empty element

    contents.forEach append

  bindObservable element, content, context, update

bufferTo = (context, collection) ->
  (content) ->

bindObservable = (element, value, context, update) ->
  observable = Observable ->
    update get value, context
    return

  attachCleaner element, observable.releaseDependencies
  return

bindEvent = (element, name, fn, context) ->
  element[name] = fn?.bind(context)
  return

id = (element, context, sources) ->
  lastId = ->
    [..., last] = splat sources, context
    return last

  bindObservable element, lastId, context, update = (newId) ->
    element.id = newId
    return

  return

classes = (element, context, sources) ->
  classNames = ->
    splat(sources, context).join(" ")

  bindObservable element, classNames, context, (classNames) ->
    element.className = classNames
    return

  return

observeContent = (element, context, contentFn) ->
  # TODO: Don't even try to observe contents for empty functions
