       html.empty().append(newContents)
 
     html.text().substr(0, caretPos)
+
+  stripNbsp: (string) ->
+    string.replace(/&nbsp;/g, '')
+
+  fixWhitespace: ->
+    html = @stripNbsp(@input.html())
+    html = html.replace(/&nbsp;/g, ' ')
+    html = html.replace(/[\s]+/g, ' ')
+    @input.html(html)
+
+  showSuccess: ->
+    @element.removeClass "invalid"
+    @element.removeClass "maybevalid"
+    @element.addClass "valid"
+    @msg.html(@SUCCESS_MSG)
+    @msg.css('color', @SUCCESS_COLOR)
+
+  showError: ->
+    @element.removeClass "valid"
+    @element.removeClass "maybevalid"
+    @element.addClass "invalid"
+    @msg.html(@ERROR_MSG)
+    @msg.css('color', @ERROR_COLOR)
+
+  showChecking: ->
+    @element.removeClass "valid"
+    @element.removeClass "invalid"
+    @element.addClass "maybevalid"
+    @msg.html(@CHECKING_MSG)
+    @msg.css('color', @NEUTRAL_COLOR)
       
 $.fn.tokenTextArea = (options, args...) ->
   @each ->

  TOKEN_REGEX: /<span class="token" (contenteditable="false" data-id="[0-9]+"|data-id="[0-9]+" contenteditable="false")>[^<]+<\/span>/i
  ID_REGEX: /data-id="[0-9]+"/i
  WORD_REGEX: /[a-z]+$/i

  constructor: (@element, @options = {}) ->
    # Remove outline and return if readonly (display) mode.


      # Re-check validity of equation unless event is an arrow key.
      unless @isArrow(event.which)
        @showChecking()

        clearTimeout(@typingTimer) unless @typingTimer is null
        @typingTimer = setTimeout( =>
