<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,12 +1,12 @@
 jQuery(function($){//on document ready
-	//autocomplete
-	$('input.autocomplete').each(function(){
+  //autocomplete
+  $('input.autocomplete').each(function(){
     var input = $(this);
-      input.autocomplete(input.attr('autocomplete_url'),{
+    input.autocomplete(input.attr('autocomplete_url'),{
       matchContains:1,//also match inside of strings when caching
-//    mustMatch:1,//allow only values from the list
-//    selectFirst:1,//select the first item on tab/enter
+      //    mustMatch:1,//allow only values from the list
+      //    selectFirst:1,//select the first item on tab/enter
       removeInitialValue:0//when first applying $.autocomplete
     });
-	}); 
+  }); 
 });
\ No newline at end of file</diff>
      <filename>example_js/javascripts/application.js</filename>
    </modified>
    <modified>
      <diff>@@ -13,752 +13,758 @@
 
 ;(function($) {
         
-$.fn.extend({
-        autocomplete: function(urlOrData, options) {
-                var isUrl = typeof urlOrData == &quot;string&quot;;
-                options = $.extend({}, $.Autocompleter.defaults, {
-                        url: isUrl ? urlOrData : null,
-                        data: isUrl ? null : urlOrData,
-                        delay: isUrl ? $.Autocompleter.defaults.delay : 10,
-                        max: options &amp;&amp; !options.scroll ? 10 : 150
-                }, options);
+  $.fn.extend({
+    autocomplete: function(urlOrData, options) {
+      var isUrl = typeof urlOrData == &quot;string&quot;;
+      options = $.extend({}, $.Autocompleter.defaults, {
+        url: isUrl ? urlOrData : null,
+        data: isUrl ? null : urlOrData,
+        delay: isUrl ? $.Autocompleter.defaults.delay : 10,
+        max: options &amp;&amp; !options.scroll ? 10 : 150
+      }, options);
                 
-                // if highlight is set to false, replace it with a do-nothing function
-                options.highlight = options.highlight || function(value) { return value; };
+      // if highlight is set to false, replace it with a do-nothing function
+      options.highlight = options.highlight || function(value) {
+        return value;
+      };
                 
-                // if the formatMatch option is not specified, then use formatItem for backwards compatibility
-                options.formatMatch = options.formatMatch || options.formatItem;
+      // if the formatMatch option is not specified, then use formatItem for backwards compatibility
+      options.formatMatch = options.formatMatch || options.formatItem;
                 
-                return this.each(function() {
-                        new $.Autocompleter(this, options);
-                });
-        },
-        result: function(handler) {
-                return this.bind(&quot;result&quot;, handler);
-        },
-        search: function(handler) {
-                return this.trigger(&quot;search&quot;, [handler]);
-        },
-        flushCache: function() {
-                return this.trigger(&quot;flushCache&quot;);
-        },
-        setOptions: function(options){
-                return this.trigger(&quot;setOptions&quot;, [options]);
-        },
-        unautocomplete: function() {
-                return this.trigger(&quot;unautocomplete&quot;);
-        }
-});
+      return this.each(function() {
+        new $.Autocompleter(this, options);
+      });
+    },
+    result: function(handler) {
+      return this.bind(&quot;result&quot;, handler);
+    },
+    search: function(handler) {
+      return this.trigger(&quot;search&quot;, [handler]);
+    },
+    flushCache: function() {
+      return this.trigger(&quot;flushCache&quot;);
+    },
+    setOptions: function(options){
+      return this.trigger(&quot;setOptions&quot;, [options]);
+    },
+    unautocomplete: function() {
+      return this.trigger(&quot;unautocomplete&quot;);
+    }
+  });
 
-$.Autocompleter = function(input, options) {
+  $.Autocompleter = function(input, options) {
 
-        var KEY = {
-                UP: 38,
-                DOWN: 40,
-                DEL: 46,
-                TAB: 9,
-                RETURN: 13,
-                ESC: 27,
-                COMMA: 188,
-                PAGEUP: 33,
-                PAGEDOWN: 34,
-                BACKSPACE: 8
-        };
+    var KEY = {
+      UP: 38,
+      DOWN: 40,
+      DEL: 46,
+      TAB: 9,
+      RETURN: 13,
+      ESC: 27,
+      COMMA: 188,
+      PAGEUP: 33,
+      PAGEDOWN: 34,
+      BACKSPACE: 8
+    };
 
-        // Create $ object for input element
-        var $input = $(input).attr(&quot;autocomplete&quot;, &quot;off&quot;).addClass(options.inputClass);
+    // Create $ object for input element
+    var $input = $(input).attr(&quot;autocomplete&quot;, &quot;off&quot;).addClass(options.inputClass);
 
-        var timeout;
-        var previousValue = &quot;&quot;;
-        var cache = $.Autocompleter.Cache(options);
-        var hasFocus = 0;
-        var lastKeyPressCode;
-        var config = {
-                mouseDownOnSelect: false
-        };
-        var select = $.Autocompleter.Select(options, input, selectCurrent, config);
+    var timeout;
+    var previousValue = &quot;&quot;;
+    var cache = $.Autocompleter.Cache(options);
+    var hasFocus = 0;
+    var lastKeyPressCode;
+    var config = {
+      mouseDownOnSelect: false
+    };
+    var select = $.Autocompleter.Select(options, input, selectCurrent, config);
         
-        var blockSubmit;
+    var blockSubmit;
         
-        // prevent form submit in opera when selecting with return key
-        $.browser.opera &amp;&amp; $(input.form).bind(&quot;submit.autocomplete&quot;, function() {
-                if (blockSubmit) {
-                        blockSubmit = false;
-                        return false;
-                }
-        });
+    // prevent form submit in opera when selecting with return key
+    $.browser.opera &amp;&amp; $(input.form).bind(&quot;submit.autocomplete&quot;, function() {
+      if (blockSubmit) {
+        blockSubmit = false;
+        return false;
+      }
+    });
         
-        // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
-        $input.bind(($.browser.opera ? &quot;keypress&quot; : &quot;keydown&quot;) + &quot;.autocomplete&quot;, function(event) {
-                // track last key pressed
-                lastKeyPressCode = event.keyCode;
-                switch(event.keyCode) {
+    // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
+    $input.bind(($.browser.opera ? &quot;keypress&quot; : &quot;keydown&quot;) + &quot;.autocomplete&quot;, function(event) {
+      // track last key pressed
+      lastKeyPressCode = event.keyCode;
+      switch(event.keyCode) {
                 
-                        case KEY.UP:
-                                event.preventDefault();
-                                if ( select.visible() ) {
-                                        select.prev();
-                                } else {
-                                        onChange(0, true);
-                                }
-                                break;
+        case KEY.UP:
+          event.preventDefault();
+          if ( select.visible() ) {
+            select.prev();
+          } else {
+            onChange(0, true);
+          }
+          break;
                                 
-                        case KEY.DOWN:
-                                event.preventDefault();
-                                if ( select.visible() ) {
-                                        select.next();
-                                } else {
-                                        onChange(0, true);
-                                }
-                                break;
+        case KEY.DOWN:
+          event.preventDefault();
+          if ( select.visible() ) {
+            select.next();
+          } else {
+            onChange(0, true);
+          }
+          break;
                                 
-                        case KEY.PAGEUP:
-                                event.preventDefault();
-                                if ( select.visible() ) {
-                                        select.pageUp();
-                                } else {
-                                        onChange(0, true);
-                                }
-                                break;
+        case KEY.PAGEUP:
+          event.preventDefault();
+          if ( select.visible() ) {
+            select.pageUp();
+          } else {
+            onChange(0, true);
+          }
+          break;
                                 
-                        case KEY.PAGEDOWN:
-                                event.preventDefault();
-                                if ( select.visible() ) {
-                                        select.pageDown();
-                                } else {
-                                        onChange(0, true);
-                                }
-                                break;
+        case KEY.PAGEDOWN:
+          event.preventDefault();
+          if ( select.visible() ) {
+            select.pageDown();
+          } else {
+            onChange(0, true);
+          }
+          break;
                         
-                        // matches also semicolon
-                        case options.multiple &amp;&amp; $.trim(options.multipleSeparator) == &quot;,&quot; &amp;&amp; KEY.COMMA:
-                        case KEY.TAB:
-                        case KEY.RETURN:
-                                if( selectCurrent() ) {
-                                        // stop default to prevent a form submit, Opera needs special handling
-                                        event.preventDefault();
-                                        blockSubmit = true;
-                                        return false;
-                                }
-                                break;
+        // matches also semicolon
+        case options.multiple &amp;&amp; $.trim(options.multipleSeparator) == &quot;,&quot; &amp;&amp; KEY.COMMA:
+        case KEY.TAB:
+        case KEY.RETURN:
+          if( selectCurrent() ) {
+            // stop default to prevent a form submit, Opera needs special handling
+            event.preventDefault();
+            blockSubmit = true;
+            return false;
+          }
+          break;
                                 
-                        case KEY.ESC:
-                                select.hide();
-                                break;
+        case KEY.ESC:
+          select.hide();
+          break;
                                 
-                        default:
-                                clearTimeout(timeout);
-                                timeout = setTimeout(onChange, options.delay);
-                                break;
-                }
-        }).focus(function(){
-                // track whether the field has focus, we shouldn't process any
-                // results if the field no longer has focus
-                hasFocus++;
-        }).blur(function() {
-                hasFocus = 0;
-                if (!config.mouseDownOnSelect) {
-                        hideResults();
-                }
-        }).click(function() {
-                // show select when clicking in a focused field
-                if ( hasFocus++ &gt; 1 &amp;&amp; !select.visible() ) {
-                        onChange(0, true);
-                }
-        }).bind(&quot;search&quot;, function() {
-                // TODO why not just specifying both arguments?
-                var fn = (arguments.length &gt; 1) ? arguments[1] : null;
-                function findValueCallback(q, data) {
-                        var result;
-                        if( data &amp;&amp; data.length ) {
-                                for (var i=0; i &lt; data.length; i++) {
-                                        if( data[i].result.toLowerCase() == q.toLowerCase() ) {
-                                                result = data[i];
-                                                break;
-                                        }
-                                }
-                        }
-                        if( typeof fn == &quot;function&quot; ) fn(result);
-                        else $input.trigger(&quot;result&quot;, result &amp;&amp; [result.data, result.value]);
-                }
-                $.each(trimWords($input.val()), function(i, value) {
-                        request(value, findValueCallback, findValueCallback);
-                });
-        }).bind(&quot;flushCache&quot;, function() {
-                cache.flush();
-        }).bind(&quot;setOptions&quot;, function() {
-                $.extend(options, arguments[1]);
-                // if we've updated the data, repopulate
-                if ( &quot;data&quot; in arguments[1] )
-                        cache.populate();
-        }).bind(&quot;unautocomplete&quot;, function() {
-                select.unbind();
-                $input.unbind();
-                $(input.form).unbind(&quot;.autocomplete&quot;);
-        });
+        default:
+          clearTimeout(timeout);
+          timeout = setTimeout(onChange, options.delay);
+          break;
+      }
+    }).focus(function(){
+      // track whether the field has focus, we shouldn't process any
+      // results if the field no longer has focus
+      hasFocus++;
+    }).blur(function() {
+      hasFocus = 0;
+      if (!config.mouseDownOnSelect) {
+        hideResults();
+      }
+    }).click(function() {
+      // show select when clicking in a focused field
+      if ( hasFocus++ &gt; 1 &amp;&amp; !select.visible() ) {
+        onChange(0, true);
+      }
+    }).bind(&quot;search&quot;, function() {
+      // TODO why not just specifying both arguments?
+      var fn = (arguments.length &gt; 1) ? arguments[1] : null;
+      function findValueCallback(q, data) {
+        var result;
+        if( data &amp;&amp; data.length ) {
+          for (var i=0; i &lt; data.length; i++) {
+            if( data[i].result.toLowerCase() == q.toLowerCase() ) {
+              result = data[i];
+              break;
+            }
+          }
+        }
+        if( typeof fn == &quot;function&quot; ) fn(result);
+        else $input.trigger(&quot;result&quot;, result &amp;&amp; [result.data, result.value]);
+      }
+      $.each(trimWords($input.val()), function(i, value) {
+        request(value, findValueCallback, findValueCallback);
+      });
+    }).bind(&quot;flushCache&quot;, function() {
+      cache.flush();
+    }).bind(&quot;setOptions&quot;, function() {
+      $.extend(options, arguments[1]);
+      // if we've updated the data, repopulate
+      if ( &quot;data&quot; in arguments[1] )
+        cache.populate();
+    }).bind(&quot;unautocomplete&quot;, function() {
+      select.unbind();
+      $input.unbind();
+      $(input.form).unbind(&quot;.autocomplete&quot;);
+    });
         
         
-        function selectCurrent() {
-                var selected = select.selected();
-                if( !selected )
-                        return false;
+    function selectCurrent() {
+      var selected = select.selected();
+      if( !selected )
+        return false;
                 
-                var v = selected.result;
-                previousValue = v;
+      var v = selected.result;
+      previousValue = v;
                 
-                if ( options.multiple ) {
-                        var words = trimWords($input.val());
-                        if ( words.length &gt; 1 ) {
-                                v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
-                        }
-                        v += options.multipleSeparator;
-                }
-                
-                $input.val(v);
-                hideResultsNow();
-                $input.trigger(&quot;result&quot;, [selected.data, selected.value]);
-                return true;
+      if ( options.multiple ) {
+        var words = trimWords($input.val());
+        if ( words.length &gt; 1 ) {
+          v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
         }
+        v += options.multipleSeparator;
+      }
+                
+      $input.val(v);
+      hideResultsNow();
+      $input.trigger(&quot;result&quot;, [selected.data, selected.value]);
+      return true;
+    }
         
-        function onChange(crap, skipPrevCheck) {
-                if( lastKeyPressCode == KEY.DEL ) {
-                        select.hide();
-                        return;
-                }
+    function onChange(crap, skipPrevCheck) {
+      if( lastKeyPressCode == KEY.DEL ) {
+        select.hide();
+        return;
+      }
                 
-                var currentValue = $input.val();
+      var currentValue = $input.val();
                 
-                if ( !skipPrevCheck &amp;&amp; currentValue == previousValue )
-                        return;
+      if ( !skipPrevCheck &amp;&amp; currentValue == previousValue )
+        return;
                 
-                previousValue = currentValue;
+      previousValue = currentValue;
                 
-                currentValue = lastWord(currentValue);
-                if ( currentValue.length &gt;= options.minChars) {
-                        $input.addClass(options.loadingClass);
-                        if (!options.matchCase)
-                                currentValue = currentValue.toLowerCase();
-                        request(currentValue, receiveData, hideResultsNow);
-                } else {
-                        stopLoading();
-                        select.hide();
-                }
-        };
+      currentValue = lastWord(currentValue);
+      if ( currentValue.length &gt;= options.minChars) {
+        $input.addClass(options.loadingClass);
+        if (!options.matchCase)
+          currentValue = currentValue.toLowerCase();
+        request(currentValue, receiveData, hideResultsNow);
+      } else {
+        stopLoading();
+        select.hide();
+      }
+    };
         
-        function trimWords(value) {
-                if ( !value ) {
-                        return [&quot;&quot;];
-                }
-                var words = value.split( options.multipleSeparator );
-                var result = [];
-                $.each(words, function(i, value) {
-                        if ( $.trim(value) )
-                                result[i] = $.trim(value);
-                });
-                return result;
-        }
+    function trimWords(value) {
+      if ( !value ) {
+        return [&quot;&quot;];
+      }
+      var words = value.split( options.multipleSeparator );
+      var result = [];
+      $.each(words, function(i, value) {
+        if ( $.trim(value) )
+          result[i] = $.trim(value);
+      });
+      return result;
+    }
         
-        function lastWord(value) {
-                if ( !options.multiple )
-                        return value;
-                var words = trimWords(value);
-                return words[words.length - 1];
-        }
+    function lastWord(value) {
+      if ( !options.multiple )
+        return value;
+      var words = trimWords(value);
+      return words[words.length - 1];
+    }
         
-        // fills in the input box w/the first match (assumed to be the best match)
-        // q: the term entered
-        // sValue: the first matching result
-        function autoFill(q, sValue){
-                // autofill in the complete box w/the first match as long as the user hasn't entered in more data
-                // if the last user key pressed was backspace, don't autofill
-                if( options.autoFill &amp;&amp; (lastWord($input.val()).toLowerCase() == q.toLowerCase()) &amp;&amp; lastKeyPressCode != KEY.BACKSPACE ) {
-                        // fill in the value (keep the case the user has typed)
-                        $input.val($input.val() + sValue.substring(lastWord(previousValue).length));
-                        // select the portion of the value not typed by the user (so the next character will erase)
-                        $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
-                }
-        };
+    // fills in the input box w/the first match (assumed to be the best match)
+    // q: the term entered
+    // sValue: the first matching result
+    function autoFill(q, sValue){
+      // autofill in the complete box w/the first match as long as the user hasn't entered in more data
+      // if the last user key pressed was backspace, don't autofill
+      if( options.autoFill &amp;&amp; (lastWord($input.val()).toLowerCase() == q.toLowerCase()) &amp;&amp; lastKeyPressCode != KEY.BACKSPACE ) {
+        // fill in the value (keep the case the user has typed)
+        $input.val($input.val() + sValue.substring(lastWord(previousValue).length));
+        // select the portion of the value not typed by the user (so the next character will erase)
+        $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
+      }
+    };
 
-        function hideResults() {
-                clearTimeout(timeout);
-                timeout = setTimeout(hideResultsNow, 200);
-        };
+    function hideResults() {
+      clearTimeout(timeout);
+      timeout = setTimeout(hideResultsNow, 200);
+    };
 
-        function hideResultsNow() {
-                var wasVisible = select.visible();
-                select.hide();
-                clearTimeout(timeout);
-                stopLoading();
-                if (options.mustMatch) {
-                        // call search and run callback
-                        $input.search(
-                                function (result){
-                                        // if no value found, clear the input box
-                                        if( !result ) {
-                                                if (options.multiple) {
-                                                        var words = trimWords($input.val()).slice(0, -1);
-                                                        $input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : &quot;&quot;) );
-                                                }
-                                                else
-                                                        $input.val( &quot;&quot; );
-                                        }
-                                }
-                        );
-                }
-                if (wasVisible)
-                        // position cursor at end of input field
-                        $.Autocompleter.Selection(input, input.value.length, input.value.length);
-        };
+    function hideResultsNow() {
+      var wasVisible = select.visible();
+      select.hide();
+      clearTimeout(timeout);
+      stopLoading();
+      if (options.mustMatch) {
+        // call search and run callback
+        $input.search(
+          function (result){
+            // if no value found, clear the input box
+            if( !result ) {
+              if (options.multiple) {
+                var words = trimWords($input.val()).slice(0, -1);
+                $input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : &quot;&quot;) );
+              }
+              else
+                $input.val( &quot;&quot; );
+            }
+          }
+          );
+      }
+      if (wasVisible)
+        // position cursor at end of input field
+        $.Autocompleter.Selection(input, input.value.length, input.value.length);
+    };
 
-        function receiveData(q, data) {
-                if ( data &amp;&amp; data.length &amp;&amp; hasFocus ) {
-                        stopLoading();
-                        select.display(data, q);
-                        autoFill(q, data[0].value);
-                        select.show();
-                } else {
-                        hideResultsNow();
-                }
-        };
+    function receiveData(q, data) {
+      if ( data &amp;&amp; data.length &amp;&amp; hasFocus ) {
+        stopLoading();
+        select.display(data, q);
+        autoFill(q, data[0].value);
+        select.show();
+      } else {
+        hideResultsNow();
+      }
+    };
 
-        function request(term, success, failure) {
-                if (!options.matchCase)
-                        term = term.toLowerCase();
-                var data = cache.load(term);
-                // recieve the cached data
-                if (data &amp;&amp; data.length) {
-                        success(term, data);
-                // if an AJAX url has been supplied, try loading the data now
-                } else if( (typeof options.url == &quot;string&quot;) &amp;&amp; (options.url.length &gt; 0) ){
-                        
-                        var extraParams = {
-                                timestamp: +new Date()
-                        };
-                        $.each(options.extraParams, function(key, param) {
-                                extraParams[key] = typeof param == &quot;function&quot; ? param() : param;
-                        });
+    function request(term, success, failure) {
+      if (!options.matchCase)
+        term = term.toLowerCase();
+      var data = cache.load(term);
+      // recieve the cached data
+      if (data &amp;&amp; data.length) {
+        success(term, data);
+      // if an AJAX url has been supplied, try loading the data now
+      } else if( (typeof options.url == &quot;string&quot;) &amp;&amp; (options.url.length &gt; 0) ){
                         
-                        $.ajax({
-                                // try to leverage ajaxQueue plugin to abort previous requests
-                                mode: &quot;abort&quot;,
-                                // limit abortion to this input
-                                port: &quot;autocomplete&quot; + input.name,
-                                dataType: options.dataType,
-                                url: options.url,
-                                data: $.extend({
-                                        q: lastWord(term),
-                                        limit: options.max
-                                }, extraParams),
-                                success: function(data) {
-                                        var parsed = options.parse &amp;&amp; options.parse(data) || parse(data);
-                                        cache.add(term, parsed);
-                                        success(term, parsed);
-                                }
-                        });
-                } else {
-                        // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
-                        select.emptyList();
-                        failure(term);
-                }
+        var extraParams = {
+          timestamp: +new Date()
         };
+        $.each(options.extraParams, function(key, param) {
+          extraParams[key] = typeof param == &quot;function&quot; ? param() : param;
+        });
+                        
+        $.ajax({
+          // try to leverage ajaxQueue plugin to abort previous requests
+          mode: &quot;abort&quot;,
+          // limit abortion to this input
+          port: &quot;autocomplete&quot; + input.name,
+          dataType: options.dataType,
+          url: options.url,
+          data: $.extend({
+            q: lastWord(term),
+            limit: options.max
+          }, extraParams),
+          success: function(data) {
+            var parsed = options.parse &amp;&amp; options.parse(data) || parse(data);
+            cache.add(term, parsed);
+            success(term, parsed);
+          }
+        });
+      } else {
+        // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
+        select.emptyList();
+        failure(term);
+      }
+    };
         
-        function parse(data) {
-                var parsed = [];
-                var rows = data.split(&quot;\n&quot;);
-                for (var i=0; i &lt; rows.length; i++) {
-                        var row = $.trim(rows[i]);
-                        if (row) {
-                                row = row.split(&quot;|&quot;);
-                                parsed[parsed.length] = {
-                                        data: row,
-                                        value: row[0],
-                                        result: options.formatResult &amp;&amp; options.formatResult(row, row[0]) || row[0]
-                                };
-                        }
-                }
-                return parsed;
-        };
+    function parse(data) {
+      var parsed = [];
+      var rows = data.split(&quot;\n&quot;);
+      for (var i=0; i &lt; rows.length; i++) {
+        var row = $.trim(rows[i]);
+        if (row) {
+          row = row.split(&quot;|&quot;);
+          parsed[parsed.length] = {
+            data: row,
+            value: row[0],
+            result: options.formatResult &amp;&amp; options.formatResult(row, row[0]) || row[0]
+          };
+        }
+      }
+      return parsed;
+    };
 
-        function stopLoading() {
-                $input.removeClass(options.loadingClass);
-        };
+    function stopLoading() {
+      $input.removeClass(options.loadingClass);
+    };
 
-};
+  };
 
-$.Autocompleter.defaults = {
-        inputClass: &quot;ac_input&quot;,
-        resultsClass: &quot;ac_results&quot;,
-        loadingClass: &quot;ac_loading&quot;,
-        minChars: 1,
-        delay: 400,
-        matchCase: false,
-        matchSubset: true,
-        matchContains: false,
-        cacheLength: 10,
-        max: 100,
-        mustMatch: false,
-        extraParams: {},
-        selectFirst: true,
-        formatItem: function(row) { return row[0]; },
-        formatMatch: null,
-        autoFill: false,
-        width: 0,
-        multiple: false,
-        multipleSeparator: &quot;, &quot;,
-        highlight: function(value, term) {
-                return value.replace(new RegExp(&quot;(?![^&amp;;]+;)(?!&lt;[^&lt;&gt;]*)(&quot; + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, &quot;\\$1&quot;) + &quot;)(?![^&lt;&gt;]*&gt;)(?![^&amp;;]+;)&quot;, &quot;gi&quot;), &quot;&lt;strong&gt;$1&lt;/strong&gt;&quot;);
-        },
+  $.Autocompleter.defaults = {
+    inputClass: &quot;ac_input&quot;,
+    resultsClass: &quot;ac_results&quot;,
+    loadingClass: &quot;ac_loading&quot;,
+    minChars: 1,
+    delay: 400,
+    matchCase: false,
+    matchSubset: true,
+    matchContains: false,
+    cacheLength: 10,
+    max: 100,
+    mustMatch: false,
+    extraParams: {},
+    selectFirst: true,
+    formatItem: function(row) {
+      return row[0];
+    },
+    formatMatch: null,
+    autoFill: false,
+    width: 0,
+    multiple: false,
+    multipleSeparator: &quot;, &quot;,
+    highlight: function(value, term) {
+      return value.replace(new RegExp(&quot;(?![^&amp;;]+;)(?!&lt;[^&lt;&gt;]*)(&quot; + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, &quot;\\$1&quot;) + &quot;)(?![^&lt;&gt;]*&gt;)(?![^&amp;;]+;)&quot;, &quot;gi&quot;), &quot;&lt;strong&gt;$1&lt;/strong&gt;&quot;);
+    },
     scroll: true,
     scrollHeight: 180
-};
+  };
 
-$.Autocompleter.Cache = function(options) {
+  $.Autocompleter.Cache = function(options) {
 
-        var data = {};
-        var length = 0;
+    var data = {};
+    var length = 0;
         
-        function matchSubset(s, sub) {
-                if (!options.matchCase) 
-                        s = s.toLowerCase();
-                var i = s.indexOf(sub);
-                if (i == -1) return false;
-                return i == 0 || options.matchContains;
-        };
+    function matchSubset(s, sub) {
+      if (!options.matchCase)
+        s = s.toLowerCase();
+      var i = s.indexOf(sub);
+      if (i == -1) return false;
+      return i == 0 || options.matchContains;
+    };
         
-        function add(q, value) {
-                if (length &gt; options.cacheLength){
-                        flush();
-                }
-                if (!data[q]){ 
-                        length++;
-                }
-                data[q] = value;
-        }
+    function add(q, value) {
+      if (length &gt; options.cacheLength){
+        flush();
+      }
+      if (!data[q]){
+        length++;
+      }
+      data[q] = value;
+    }
         
-        function populate(){
-                if( !options.data ) return false;
-                // track the matches
-                var stMatchSets = {},
-                        nullData = 0;
+    function populate(){
+      if( !options.data ) return false;
+      // track the matches
+      var stMatchSets = {},
+      nullData = 0;
 
-                // no url was specified, we need to adjust the cache length to make sure it fits the local data store
-                if( !options.url ) options.cacheLength = 1;
+      // no url was specified, we need to adjust the cache length to make sure it fits the local data store
+      if( !options.url ) options.cacheLength = 1;
                 
-                // track all options for minChars = 0
-                stMatchSets[&quot;&quot;] = [];
+      // track all options for minChars = 0
+      stMatchSets[&quot;&quot;] = [];
                 
-                // loop through the array and create a lookup structure
-                for ( var i = 0, ol = options.data.length; i &lt; ol; i++ ) {
-                        var rawValue = options.data[i];
-                        // if rawValue is a string, make an array otherwise just reference the array
-                        rawValue = (typeof rawValue == &quot;string&quot;) ? [rawValue] : rawValue;
+      // loop through the array and create a lookup structure
+      for ( var i = 0, ol = options.data.length; i &lt; ol; i++ ) {
+        var rawValue = options.data[i];
+        // if rawValue is a string, make an array otherwise just reference the array
+        rawValue = (typeof rawValue == &quot;string&quot;) ? [rawValue] : rawValue;
                         
-                        var value = options.formatMatch(rawValue, i+1, options.data.length);
-                        if ( value === false )
-                                continue;
+        var value = options.formatMatch(rawValue, i+1, options.data.length);
+        if ( value === false )
+          continue;
                                 
-                        var firstChar = value.charAt(0).toLowerCase();
-                        // if no lookup array for this character exists, look it up now
-                        if( !stMatchSets[firstChar] ) 
-                                stMatchSets[firstChar] = [];
+        var firstChar = value.charAt(0).toLowerCase();
+        // if no lookup array for this character exists, look it up now
+        if( !stMatchSets[firstChar] )
+          stMatchSets[firstChar] = [];
 
-                        // if the match is a string
-                        var row = {
-                                value: value,
-                                data: rawValue,
-                                result: options.formatResult &amp;&amp; options.formatResult(rawValue) || value
-                        };
+        // if the match is a string
+        var row = {
+          value: value,
+          data: rawValue,
+          result: options.formatResult &amp;&amp; options.formatResult(rawValue) || value
+        };
                         
-                        // push the current match into the set list
-                        stMatchSets[firstChar].push(row);
-
-                        // keep track of minChars zero items
-                        if ( nullData++ &lt; options.max ) {
-                                stMatchSets[&quot;&quot;].push(row);
-                        }
-                };
+        // push the current match into the set list
+        stMatchSets[firstChar].push(row);
 
-                // add the data items to the cache
-                $.each(stMatchSets, function(i, value) {
-                        // increase the cache size
-                        options.cacheLength++;
-                        // add to the cache
-                        add(i, value);
-                });
+        // keep track of minChars zero items
+        if ( nullData++ &lt; options.max ) {
+          stMatchSets[&quot;&quot;].push(row);
         }
+      };
+
+      // add the data items to the cache
+      $.each(stMatchSets, function(i, value) {
+        // increase the cache size
+        options.cacheLength++;
+        // add to the cache
+        add(i, value);
+      });
+    }
         
-        // populate any existing data
-        setTimeout(populate, 25);
+    // populate any existing data
+    setTimeout(populate, 25);
         
-        function flush(){
-                data = {};
-                length = 0;
-        }
+    function flush(){
+      data = {};
+      length = 0;
+    }
         
-        return {
-                flush: flush,
-                add: add,
-                populate: populate,
-                load: function(q) {
-                        if (!options.cacheLength || !length)
-                                return null;
-                        /* 
+    return {
+      flush: flush,
+      add: add,
+      populate: populate,
+      load: function(q) {
+        if (!options.cacheLength || !length)
+          return null;
+        /*
                          * if dealing w/local data and matchContains than we must make sure
                          * to loop through all the data collections looking for matches
                          */
-                        if( !options.url &amp;&amp; options.matchContains ){
-                                // track all matches
-                                var csub = [];
-                                // loop through all the data grids for matches
-                                for( var k in data ){
-                                        // don't search through the stMatchSets[&quot;&quot;] (minChars: 0) cache
-                                        // this prevents duplicates
-                                        if( k.length &gt; 0 ){
-                                                var c = data[k];
-                                                $.each(c, function(i, x) {
-                                                        // if we've got a match, add it to the array
-                                                        if (matchSubset(x.value, q)) {
-                                                                csub.push(x);
-                                                        }
-                                                });
-                                        }
-                                }                               
-                                return csub;
-                        } else 
-                        // if the exact item exists, use it
-                        if (data[q]){
-                                return data[q];
-                        } else
-                        if (options.matchSubset) {
-                                for (var i = q.length - 1; i &gt;= options.minChars; i--) {
-                                        var c = data[q.substr(0, i)];
-                                        if (c) {
-                                                var csub = [];
-                                                $.each(c, function(i, x) {
-                                                        if (matchSubset(x.value, q)) {
-                                                                csub[csub.length] = x;
-                                                        }
-                                                });
-                                                return csub;
-                                        }
-                                }
-                        }
-                        return null;
+        if( !options.url &amp;&amp; options.matchContains ){
+          // track all matches
+          var csub = [];
+          // loop through all the data grids for matches
+          for( var k in data ){
+            // don't search through the stMatchSets[&quot;&quot;] (minChars: 0) cache
+            // this prevents duplicates
+            if( k.length &gt; 0 ){
+              var c = data[k];
+              $.each(c, function(i, x) {
+                // if we've got a match, add it to the array
+                if (matchSubset(x.value, q)) {
+                  csub.push(x);
                 }
-        };
-};
+              });
+            }
+          }
+          return csub;
+        } else
+        // if the exact item exists, use it
+        if (data[q]){
+          return data[q];
+        } else
+        if (options.matchSubset) {
+          for (var i = q.length - 1; i &gt;= options.minChars; i--) {
+            var c = data[q.substr(0, i)];
+            if (c) {
+              var csub = [];
+              $.each(c, function(i, x) {
+                if (matchSubset(x.value, q)) {
+                  csub[csub.length] = x;
+                }
+              });
+              return csub;
+            }
+          }
+        }
+        return null;
+      }
+    };
+  };
 
-$.Autocompleter.Select = function (options, input, select, config) {
-        var CLASSES = {
-                ACTIVE: &quot;ac_over&quot;
-        };
+  $.Autocompleter.Select = function (options, input, select, config) {
+    var CLASSES = {
+      ACTIVE: &quot;ac_over&quot;
+    };
         
-        var listItems,
-                active = -1,
-                data,
-                term = &quot;&quot;,
-                needsInit = true,
-                element,
-                list;
+    var listItems,
+    active = -1,
+    data,
+    term = &quot;&quot;,
+    needsInit = true,
+    element,
+    list;
         
-        // Create results
-        function init() {
-                if (!needsInit)
-                        return;
-                element = $(&quot;&lt;div/&gt;&quot;)
-                .hide()
-                .addClass(options.resultsClass)
-                .css(&quot;position&quot;, &quot;absolute&quot;)
-                .appendTo(document.body);
+    // Create results
+    function init() {
+      if (!needsInit)
+        return;
+      element = $(&quot;&lt;div/&gt;&quot;)
+      .hide()
+      .addClass(options.resultsClass)
+      .css(&quot;position&quot;, &quot;absolute&quot;)
+      .appendTo(document.body);
         
-                list = $(&quot;&lt;ul/&gt;&quot;).appendTo(element).mouseover( function(event) {
-                        if(target(event).nodeName &amp;&amp; target(event).nodeName.toUpperCase() == 'LI') {
-                    active = $(&quot;li&quot;, list).removeClass(CLASSES.ACTIVE).index(target(event));
-                            $(target(event)).addClass(CLASSES.ACTIVE);            
-                }
-                }).click(function(event) {
-                        $(target(event)).addClass(CLASSES.ACTIVE);
-                        select();
-                        // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
-                        input.focus();
-                        return false;
-                }).mousedown(function() {
-                        config.mouseDownOnSelect = true;
-                }).mouseup(function() {
-                        config.mouseDownOnSelect = false;
-                });
+      list = $(&quot;&lt;ul/&gt;&quot;).appendTo(element).mouseover( function(event) {
+        if(target(event).nodeName &amp;&amp; target(event).nodeName.toUpperCase() == 'LI') {
+          active = $(&quot;li&quot;, list).removeClass(CLASSES.ACTIVE).index(target(event));
+          $(target(event)).addClass(CLASSES.ACTIVE);
+        }
+      }).click(function(event) {
+        $(target(event)).addClass(CLASSES.ACTIVE);
+        select();
+        // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
+        input.focus();
+        return false;
+      }).mousedown(function() {
+        config.mouseDownOnSelect = true;
+      }).mouseup(function() {
+        config.mouseDownOnSelect = false;
+      });
                 
-                if( options.width &gt; 0 )
-                        element.css(&quot;width&quot;, options.width);
+      if( options.width &gt; 0 )
+        element.css(&quot;width&quot;, options.width);
                         
-                needsInit = false;
-        } 
+      needsInit = false;
+    }
         
-        function target(event) {
-                var element = event.target;
-                while(element &amp;&amp; element.tagName != &quot;LI&quot;)
-                        element = element.parentNode;
-                // more fun with IE, sometimes event.target is empty, just ignore it then
-                if(!element)
-                        return [];
-                return element;
-        }
+    function target(event) {
+      var element = event.target;
+      while(element &amp;&amp; element.tagName != &quot;LI&quot;)
+        element = element.parentNode;
+      // more fun with IE, sometimes event.target is empty, just ignore it then
+      if(!element)
+        return [];
+      return element;
+    }
 
-        function moveSelect(step) {
-                listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
-                movePosition(step);
-        var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
-        if(options.scroll) {
-            var offset = 0;
-            listItems.slice(0, active).each(function() {
-                                offset += this.offsetHeight;
-                        });
-            if((offset + activeItem[0].offsetHeight - list.scrollTop()) &gt; list[0].clientHeight) {
-                list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
-            } else if(offset &lt; list.scrollTop()) {
-                list.scrollTop(offset);
-            }
+    function moveSelect(step) {
+      listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
+      movePosition(step);
+      var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
+      if(options.scroll) {
+        var offset = 0;
+        listItems.slice(0, active).each(function() {
+          offset += this.offsetHeight;
+        });
+        if((offset + activeItem[0].offsetHeight - list.scrollTop()) &gt; list[0].clientHeight) {
+          list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
+        } else if(offset &lt; list.scrollTop()) {
+          list.scrollTop(offset);
         }
-        };
+      }
+    };
         
-        function movePosition(step) {
-                active += step;
-                if (active &lt; 0) {
-                        active = listItems.size() - 1;
-                } else if (active &gt;= listItems.size()) {
-                        active = 0;
-                }
-        }
+    function movePosition(step) {
+      active += step;
+      if (active &lt; 0) {
+        active = listItems.size() - 1;
+      } else if (active &gt;= listItems.size()) {
+        active = 0;
+      }
+    }
         
-        function limitNumberOfItems(available) {
-                return options.max &amp;&amp; options.max &lt; available
-                        ? options.max
-                        : available;
-        }
+    function limitNumberOfItems(available) {
+      return options.max &amp;&amp; options.max &lt; available
+      ? options.max
+      : available;
+    }
         
-        function fillList() {
-                list.empty();
-                var max = limitNumberOfItems(data.length);
-                for (var i=0; i &lt; max; i++) {
-                        if (!data[i])
-                                continue;
-                        var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
-                        if ( formatted === false )
-                                continue;
-                        var li = $(&quot;&lt;li/&gt;&quot;).html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? &quot;ac_even&quot; : &quot;ac_odd&quot;).appendTo(list)[0];
-                        $.data(li, &quot;ac_data&quot;, data[i]);
-                }
-                listItems = list.find(&quot;li&quot;);
-                if ( options.selectFirst ) {
-                        listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
-                        active = 0;
-                }
-                // apply bgiframe if available
-                if ( $.fn.bgiframe )
-                        list.bgiframe();
-        }
+    function fillList() {
+      list.empty();
+      var max = limitNumberOfItems(data.length);
+      for (var i=0; i &lt; max; i++) {
+        if (!data[i])
+          continue;
+        var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
+        if ( formatted === false )
+          continue;
+        var li = $(&quot;&lt;li/&gt;&quot;).html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? &quot;ac_even&quot; : &quot;ac_odd&quot;).appendTo(list)[0];
+        $.data(li, &quot;ac_data&quot;, data[i]);
+      }
+      listItems = list.find(&quot;li&quot;);
+      if ( options.selectFirst ) {
+        listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
+        active = 0;
+      }
+      // apply bgiframe if available
+      if ( $.fn.bgiframe )
+        list.bgiframe();
+    }
         
-        return {
-                display: function(d, q) {
-                        init();
-                        data = d;
-                        term = q;
-                        fillList();
-                },
-                next: function() {
-                        moveSelect(1);
-                },
-                prev: function() {
-                        moveSelect(-1);
-                },
-                pageUp: function() {
-                        if (active != 0 &amp;&amp; active - 8 &lt; 0) {
-                                moveSelect( -active );
-                        } else {
-                                moveSelect(-8);
-                        }
-                },
-                pageDown: function() {
-                        if (active != listItems.size() - 1 &amp;&amp; active + 8 &gt; listItems.size()) {
-                                moveSelect( listItems.size() - 1 - active );
-                        } else {
-                                moveSelect(8);
-                        }
-                },
-                hide: function() {
-                        element &amp;&amp; element.hide();
-                        listItems &amp;&amp; listItems.removeClass(CLASSES.ACTIVE);
-                        active = -1;
-                },
-                visible : function() {
-                        return element &amp;&amp; element.is(&quot;:visible&quot;);
-                },
-                current: function() {
-                        return this.visible() &amp;&amp; (listItems.filter(&quot;.&quot; + CLASSES.ACTIVE)[0] || options.selectFirst &amp;&amp; listItems[0]);
-                },
-                show: function() {
-                  var offset = $(input).offset();
-                  var results_top = offset.top + input.offsetHeight;
-                  element.css({
-                    width: typeof options.width == &quot;string&quot; || options.width &gt; 0 ? options.width : $(input).width(),
-                    top: results_top,
-                    left: offset.left
-                  }).show();
-                  if(options.scroll) {
-                    list.scrollTop(0);
-                    list.css({
-                      maxHeight: options.scrollHeight,
-                      overflow: 'auto'
-                    });
-                    
-                    if($.browser.msie &amp;&amp; typeof document.body.style.maxHeight === &quot;undefined&quot;) {
-                      var listHeight = 0;
-                      listItems.each(function() {
-                        listHeight += this.offsetHeight;
-                      });
-                      var scrollbarsVisible = listHeight &gt; options.scrollHeight;
-                      list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
-                      if (!scrollbarsVisible) {
-                        // IE doesn't recalculate width when scrollbar disappears
-                        listItems.width( list.width() - parseInt(listItems.css(&quot;padding-left&quot;)) - parseInt(listItems.css(&quot;padding-right&quot;)) );
-                      }
-                    }
-                  }
-                  var element_height = parseInt(element.css(&quot;height&quot;));
-                  if (results_top + element_height &gt; $(window).height()) {
-                    results_top = offset.top - element_height;
-                  }
-                  element.css({top: results_top}).show();
-                },
-                selected: function() {
-                        var selected = listItems &amp;&amp; listItems.filter(&quot;.&quot; + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
-                        return selected &amp;&amp; selected.length &amp;&amp; $.data(selected[0], &quot;ac_data&quot;);
-                },
-                emptyList: function (){
-                        list &amp;&amp; list.empty();
-                },
-                unbind: function() {
-                        element &amp;&amp; element.remove();
-                }
-        };
-};
-
-$.Autocompleter.Selection = function(field, start, end) {
-        if( field.createTextRange ){
-                var selRange = field.createTextRange();
-                selRange.collapse(true);
-                selRange.moveStart(&quot;character&quot;, start);
-                selRange.moveEnd(&quot;character&quot;, end);
-                selRange.select();
-        } else if( field.setSelectionRange ){
-                field.setSelectionRange(start, end);
+    return {
+      display: function(d, q) {
+        init();
+        data = d;
+        term = q;
+        fillList();
+      },
+      next: function() {
+        moveSelect(1);
+      },
+      prev: function() {
+        moveSelect(-1);
+      },
+      pageUp: function() {
+        if (active != 0 &amp;&amp; active - 8 &lt; 0) {
+          moveSelect( -active );
         } else {
-                if( field.selectionStart ){
-                        field.selectionStart = start;
-                        field.selectionEnd = end;
-                }
+          moveSelect(-8);
+        }
+      },
+      pageDown: function() {
+        if (active != listItems.size() - 1 &amp;&amp; active + 8 &gt; listItems.size()) {
+          moveSelect( listItems.size() - 1 - active );
+        } else {
+          moveSelect(8);
         }
-        field.focus();
-};
+      },
+      hide: function() {
+        element &amp;&amp; element.hide();
+        listItems &amp;&amp; listItems.removeClass(CLASSES.ACTIVE);
+        active = -1;
+      },
+      visible : function() {
+        return element &amp;&amp; element.is(&quot;:visible&quot;);
+      },
+      current: function() {
+        return this.visible() &amp;&amp; (listItems.filter(&quot;.&quot; + CLASSES.ACTIVE)[0] || options.selectFirst &amp;&amp; listItems[0]);
+      },
+      show: function() {
+        var offset = $(input).offset();
+        var results_top = offset.top + input.offsetHeight;
+        element.css({
+          width: typeof options.width == &quot;string&quot; || options.width &gt; 0 ? options.width : $(input).width(),
+          top: results_top,
+          left: offset.left
+        }).show();
+        if(options.scroll) {
+          list.scrollTop(0);
+          list.css({
+            maxHeight: options.scrollHeight,
+            overflow: 'auto'
+          });
+                    
+          if($.browser.msie &amp;&amp; typeof document.body.style.maxHeight === &quot;undefined&quot;) {
+            var listHeight = 0;
+            listItems.each(function() {
+              listHeight += this.offsetHeight;
+            });
+            var scrollbarsVisible = listHeight &gt; options.scrollHeight;
+            list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
+            if (!scrollbarsVisible) {
+              // IE doesn't recalculate width when scrollbar disappears
+              listItems.width( list.width() - parseInt(listItems.css(&quot;padding-left&quot;)) - parseInt(listItems.css(&quot;padding-right&quot;)) );
+            }
+          }
+        }
+        var element_height = parseInt(element.css(&quot;height&quot;));
+        if (results_top + element_height &gt; $(window).height()) {
+          results_top = offset.top - element_height;
+        }
+        element.css({
+          top: results_top
+        }).show();
+      },
+      selected: function() {
+        var selected = listItems &amp;&amp; listItems.filter(&quot;.&quot; + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
+        return selected &amp;&amp; selected.length &amp;&amp; $.data(selected[0], &quot;ac_data&quot;);
+      },
+      emptyList: function (){
+        list &amp;&amp; list.empty();
+      },
+      unbind: function() {
+        element &amp;&amp; element.remove();
+      }
+    };
+  };
+
+  $.Autocompleter.Selection = function(field, start, end) {
+    if( field.createTextRange ){
+      var selRange = field.createTextRange();
+      selRange.collapse(true);
+      selRange.moveStart(&quot;character&quot;, start);
+      selRange.moveEnd(&quot;character&quot;, end);
+      selRange.select();
+    } else if( field.setSelectionRange ){
+      field.setSelectionRange(start, end);
+    } else {
+      if( field.selectionStart ){
+        field.selectionStart = start;
+        field.selectionEnd = end;
+      }
+    }
+    field.focus();
+  };
 
 })(jQuery);
\ No newline at end of file</diff>
      <filename>example_js/javascripts/jquery.autocomplete.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>9868750ba21c0298df1d8eeb9e1d089e9cea66e8</id>
    </parent>
  </parents>
  <author>
    <name>grosser</name>
    <email>grosser.michael@gmail.com</email>
  </author>
  <url>http://github.com/grosser/simple_auto_complete/commit/82e2cebeb8af0173e2fa63301258a9fc874eca95</url>
  <id>82e2cebeb8af0173e2fa63301258a9fc874eca95</id>
  <committed-date>2009-08-15T07:12:46-07:00</committed-date>
  <authored-date>2009-08-15T07:12:46-07:00</authored-date>
  <message>reformatting for viewing pleasure</message>
  <tree>d50f987d2158723aaa8777b0369d13ad98ca36e7</tree>
  <committer>
    <name>grosser</name>
    <email>grosser.michael@gmail.com</email>
  </committer>
</commit>
