jQuery.fn.com_gorad_ui_multiselect = function(classPrefix) {
    classPrefix = typeof classPrefix == "undefined" ? "multiselect-" : classPrefix + "-multiselect-";

    return this.each(function() {
        var aid = this.id;
        var iid = this.id + "-inactive";
        var addId = this.id + "-add";
        var removeId = this.id + "-remove";
        var submitIdPrefix = this.id + "-submit-";
        var name = this.name;

        var opts = [];
        var optGroups = [];
        $.each($(this).children("optgroup"), function(i, v) {
            optGroups.push($(this).attr("label"));
            $(v).children("option").each(function() {
                opts.push({
                    "value" : $(this).val(),
                    "group" : i
                });
            });
        });

        // create inactive list and populate w/non-empty groups
        $('<select multiple="multiple"></select>')
            .attr("id", iid)
            .attr("class", classPrefix + "inactive")
            .append($(this).children('optgroup:parent'))
            .insertBefore(this);
        // prune remaining empty groups in active list
        $(this).children().remove();
        // fix up active list attributes
        $(this).attr("name", "").attr("class", classPrefix + "active");
        // move any pre-selected options to active list
        move(iid, aid, aid, opts, optGroups, name, submitIdPrefix);

        // create add/remove buttons
        var addremove = $("<span />").attr("class", classPrefix + "addremove");
        $("<span>Add</span>")
            .attr("id", addId)
            .attr("class", classPrefix + "add")
            .click(function() { move(iid, aid, aid, opts, optGroups, name, submitIdPrefix); })
            .appendTo(addremove);
        $("<span>Remove</span>")
            .attr("id", removeId)
            .attr("class", classPrefix + "remove")
            .click(function() { move(aid, iid, aid, opts, optGroups, name, submitIdPrefix); })
            .appendTo(addremove);
        addremove.insertBefore(this);

        // attach event handlers
        $('#'+iid).dblclick(function() { move(iid, aid, aid, opts, optGroups, name, submitIdPrefix); });
        $('#'+aid).dblclick(function() { move(aid, iid, aid, opts, optGroups, name, submitIdPrefix); });
    });

    function move(from, to, active, opts, optGroups, name, submitIdPrefix) {
        var dest = $("#"+to);

        // move selected options
        $('#'+from+" option:selected").each(function() {
            $(this).removeAttr("selected");
            if ($.browser.mozilla) {
                this.selected = false;
            }
            $(this).appendTo(dest);
        });

        // prune empty source groups
        $('#'+from).children("optgroup").each(function() {
            if (!$(this).children().length) {
                $(this).remove();
            }
        });

        // re-order options in destination
        $.each(opts, function(i, o) {
            var opt = $("#"+to+' option[value="'+o.value+'"]');
            if (opt.length) {
                var group = $('#'+to+' optgroup[label="'+optGroups[o.group]+'"]');
                if (!group.length) {
                    group = $("<optgroup>").attr("label", optGroups[o.group]);
                    group.appendTo(dest);
                }
                opt.appendTo(group);
            }
        });

        // re-order groups in destination
        $.each(optGroups, function(i, og) {
            var group = $("#"+to+' optgroup[label="'+og+'"]');
            if (group.length) {
                dest.append(group);
            }
        });

        // prune/add hidden controls
        $.each(opts, function(i, o) {
            $('#'+submitIdPrefix+i).remove();
            if ($("#"+active+' option[value="'+o.value+'"]').length) {
                $('<input type="hidden">')
                    .attr("id", submitIdPrefix + i)
                    .attr("name", name)
                    .attr("value", o.value)
                    .insertAfter(dest);
            }
        });

//        $('#'+to+"//option").add('#'+from+"//option").each(function() {
////            this.selected = false;
//            $(this).attr("selected", false)
//        });
    }
};
