+    /*  In case users are impatient and want to skip ahead:
+     *  Capture <enter> key events and check if it's a unique hit.
+     *  If it is, go ahead and assume it was selected. If it wasn't don't do
+     *  anything so that autocompletion kicks in.  For <tab> don't prevent
+     *  propagation. It would be nice to catch it, but javascript is too stupid
+     *  to fire a tab event later on, so we'd have to reimplement the "find
+     *  next active element in tabindex order and focus it".
+     */
+    /* note:
+     *  event.which does not contain tab events in keypressed in firefox but will report 0
+     *  chrome does not fire keypressed at all on tab or escape
+     */
+    $dummy.keydown(function(event){
+      if (event.which == KEY.ENTER || event.which == KEY.TAB) {
+        // if string is empty assume they want to delete
+        if ($dummy.val() == '') {
+          set_item({});
+          return true;
+        } else if (state == STATES.PICKED) {
+          return true;
+        }
+        if (event.which == KEY.TAB) {
+          event.preventDefault();
+          handle_changed_text();
+        }
+        if (event.which == KEY.ENTER) {
+          handle_changed_text({
+            match_one:  function(){$('#update_button').click();},
+          });
+          return false;
+        }
+      } else {
+        state = STATES.UNDEFINED;
+      }
+    });
+
+    $dummy.on('paste', function(){
+      setTimeout(function() {
+        handle_changed_text();
+      }, 1);
+    });
+
+    $dummy.blur(function(){
+      window.clearTimeout(timer);
+      timer = window.setTimeout(annotate_state, 100);
+    });
+
+    // now add a picker div after the original input
+    var pp = {
+      real:           function() { return $real },
+      dummy:          function() { return $dummy },
+      type:           function() { return $type },
+      set_item:       set_item,
+      reset:          make_defined_state,
+      is_defined_state: function() { return state == STATES.PICKED },
+    }
+    $real.data('customer_vendor_picker', pp);
+    return pp;
+  }
+});
+
+$(function(){
+  $('input.customer_vendor_autocomplete').each(function(i,real){
+    kivi.CustomerVendorPicker($(real));
+  })