var events = require('events'),
    getByClass = require('get-by-class'),
    toString = require('to-string');

module.exports = function(list) {
    var item,
        text,
        columns,
        searchString,
        customSearch;

    var prepare = {
        resetList: function() {
            list.i = 1;
            list.templater.clear();
            customSearch = undefined;
        },
        setOptions: function(args) {
            if (args.length == 2 && args[1] instanceof Array) {
                columns = args[1];
            } else if (args.length == 2 && typeof(args[1]) == "function") {
                customSearch = args[1];
            } else if (args.length == 3) {
                columns = args[1];
                customSearch = args[2];
            }
        },
        setColumns: function() {
            columns = (columns === undefined) ? prepare.toArray(list.items[0].values()) : columns;
        },
        setSearchString: function(s) {
            s = toString(s).toLowerCase();
            s = s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); // Escape regular expression characters
            searchString = s;
        },
        toArray: function(values) {
            var tmpColumn = [];
            for (var name in values) {
                tmpColumn.push(name);
            }
            return tmpColumn;
        }
    };
    var search = {
        list: function() {
            for (var k = 0, kl = list.items.length; k < kl; k++) {
                search.item(list.items[k]);
            }
        },
        item: function(item) {
            item.found = false;
            for (var j = 0, jl = columns.length; j < jl; j++) {
                if (search.values(item.values(), columns[j])) {
                    item.found = true;
                    return;
                }
            }
        },
        values: function(values, column) {
            if (values.hasOwnProperty(column)) {
                text = toString(values[column]).toLowerCase();
                if ((searchString !== "") && (text.search(searchString) > -1)) {
                    return true;
                }
            }
            return false;
        },
        reset: function() {
            list.reset.search();
            list.searched = false;
        }
    };

    var searchMethod = function(str) {
        list.trigger('searchStart');

        prepare.resetList();
        prepare.setSearchString(str);
        prepare.setOptions(arguments); // str, cols|searchFunction, searchFunction
        prepare.setColumns();

        if (searchString === "" ) {
            search.reset();
        } else {
            list.searched = true;
            if (customSearch) {
                customSearch(searchString, columns);
            } else {
                search.list();
            }
        }

        list.update();
        list.trigger('searchComplete');
        return list.visibleItems;
    };

    list.handlers.searchStart = list.handlers.searchStart || [];
    list.handlers.searchComplete = list.handlers.searchComplete || [];

    events.bind(getByClass(list.listContainer, list.searchClass), 'keyup', function(e) {
        var target = e.target || e.srcElement; // IE have srcElement
        searchMethod(target.value);
    });

    return searchMethod;
};

@@ -1061,10 +1061,8 @@
 %5E$%7C#
-%5Cs
 %5D/g,

Fix regexp that adde "/" for each " "