function custom_scroller_menu (selt, menuelt, debug) {
    function log () {
        if (!debug) return;
        console.log.apply(null, arguments);
        var msg = "";
        for (var i=0, l=arguments.length; i<l; i++) {
            msg += arguments[i] + " ";
        }
        debug.innerHTML += "\n"+ msg;
    }
    // console.log("selt", selt);
    // document.addEventListener("scroll", function (e) {
    //     var sm = selt.scrollHeight - selt.clientHeight;
    //     console.log("scroll", selt.scrollTop, sm, selt.scrollHeight);
    // })
    var dragging = false,
        drag_ref_y = 0,
        scroll_ref_y = 0,
        last_y = 0,
        starttime = null;

    var hc = menuelt;

    function touchstart (e) {
        if (dragging) { return; }
        var nn = e.target.nodeName.toLowerCase(),
            touch = e;
        if (e.touches) {
            if (e.touches.length != 1) { return; }
            touch = e.touches[0];
        }
        log("touchstart", nn);
        if (nn == "img" || nn == "input") {
            return;
        }
        if (nn !== "a") {
            e.preventDefault();
            e.stopPropagation();
            drag_ref_y = touch.screenY;
            last_y = touch.screenY;
            scroll_ref_y = selt.scrollTop;
            dragging = true;
            starttime = new Date().getTime();
            log("start drag", drag_ref_y, starttime);
        } else {
            log("headtouch", nn);
        }        
    }
    function touchmove (e) {
        if (dragging) {
            var touch = e;
            if (e.touches) {
                touch = e.touches[0];
            }
            last_y = touch.screenY;
            var dy = touch.screenY - drag_ref_y;
            selt.scrollTop = scroll_ref_y - dy;
        }
    }
    function touchend (e) {
        if (dragging) {
            log("touchend");
            dragging = false;
            var elapsed_time = new Date().getTime() - starttime;
            // log("end of drag", elapsed_time);
            if (elapsed_time <= 500) {
                var open = false,
                    scrollMax = selt.scrollHeight - selt.clientHeight;
                // do a snap / throw ... direction ??
                if (last_y == drag_ref_y) {
                    // console.log("no change, guessing state");
                    // toggle current state
                    var sp = selt.scrollTop;
                    log("guess", sp/scrollMax);
                    open = ((sp / scrollMax) < 0.5);
                } else {
                    log("end/drag", last_y, drag_ref_y);
                    open = (last_y < drag_ref_y);
                }
                log("THROW", open ? "open" : "closed");
                if (open) {
                    selt.scrollTop = scrollMax;
                } else {
                    selt.scrollTop = 0;
                }
            } else {
                log("long", elapsed_time);
            }            
        }
    }

    menuelt.addEventListener("touchstart", touchstart);
    menuelt.addEventListener("touchmove", touchmove);
    menuelt.addEventListener("touchend", touchend);
    menuelt.addEventListener("touchcancel", touchend);
    menuelt.addEventListener("mousedown", touchstart);
    menuelt.addEventListener("mousemove", touchmove);
    menuelt.addEventListener("mouseup", touchend);
    menuelt.addEventListener("mouseleave", touchend);

}
