function LinkScroller(id) {
  for(var i=0; window[this.name='__instance_LinkScroller_'+i]; i++);
  window[this.name]=this;

  this.getDescendantsByName=function(node, name, children) {
    if(!children) children=new Array();
    if( node.name==name || (node.attributes && node.attributes.name && node.attributes.name.nodeValue==name) )
      children.push(node);
    for(var child=node.firstChild; child; child=child.nextSibling)
      this.getDescendantsByName(child, name, children);
    return children;
  }

  this.getChildByName=function(node, name) {
    for(var child=node.firstChild; child; child=child.nextSibling)
      if(child.name==name) return child;
    return null;
  }

  this.scroller_onmouseover=function(e) {
    this.scroller_isMouseOver=true;
  }
  this.scroller_onmouseout=function(e) {
    this.scroller_isMouseOver=false;
  }

  this.regexp_activate=/( *active)|$/;
  this.replace_activate=' active';
  this.regexp_deactivate=/ *active/;
  this.replace_deactivate='';
  this.activateLink=function(link) {
    if(this.lastActive!=link) {
      var img;
      if(this.lastActive) {
        this.lastActive.className=this.lastActive.className.replace(this.regexp_deactivate, this.replace_deactivate);
        if( img=this.getChildByName(this.images, this.lastActive.name) ) {
          img.className=img.className.replace(this.regexp_deactivate, this.replace_deactivate);
          img.style.display='none';
        }
      }
      link.className=link.className.replace(this.regexp_activate, this.replace_activate);
      if( img=this.getChildByName(this.images, link.name) ) {
        img.className=img.className.replace(this.regexp_activate, this.replace_activate);
        img.style.display='inline';
      }
      this.lastActive=link;
    }
  }

  this.shiftLinks=function(n) {
    for(var l, i=Math.abs(n), links=this.links.childNodes; i>0; i--)
      if(n>0) {
        l=this.links.firstChild;
        this.links.removeChild(l);
        this.links.appendChild(l);
      } else {
        l=this.links.lastChild;
        this.links.removeChild(l);
        this.links.insertBefore(l, this.links.firstChild);
      }
  }

  this.pos=0;
  this.v=0;
  this.scrollBy=function(v) { this.v=v; }
  this.iterate=function() {
    this.v=Math.max(-4, Math.min(1.05*this.v, 4));
    this.pos+= this.v ? this.v : (this.scroller_isMouseOver?0:1) ;
    this.shiftLinks( Math.floor(this.pos/this.linkHeight) );
    this.pos%=this.linkHeight;
    if(this.pos<0) this.pos+=this.linkHeight;
    this.links.scrollTop=this.pos;
    if(!this.scroller_isMouseOver || this.v) this.activateLink(this.links.childNodes[this.linkActive]);
  }

  if( document.getElementById
      &&  (this.scroller=document.getElementById(id))
      &&  (this.links=this.getDescendantsByName(this.scroller, 'links')[0])
      &&  (this.images=this.getDescendantsByName(this.scroller, 'images')[0])
      &&  this.links.scrollHeight
  ) {
    this.scroller.style.overflow='hidden';
    eval(
      'this.scroller.onmouseover=function(e) { window["'+this.name+'"].scroller_onmouseover(e); };'
      +'this.scroller.onmouseout=function(e) { window["'+this.name+'"].scroller_onmouseout(e); };'
    );
    this.links.style.overflow='hidden';
    for(var i=this.links.childNodes.length-1, child; i>=0; i--)
      if(child=this.links.childNodes[i], child.nodeName=='A') {
        eval('child.onmouseover=function(e) { window["'+this.name+'"].activateLink(this); };');
        with(child.style) {
          display='block';
          whiteSpace='nowrap';
        }
      } else this.links.removeChild(child);
    for(var i=this.images.childNodes.length-1, child; i>=0; i--)
      if(child=this.images.childNodes[i], child.nodeName=='A') {
        if(i) child.style.display='none';
      } else this.images.removeChild(child);
    this.linkHeight=this.links.scrollHeight/this.links.childNodes.length;
    this.links.style.height=Math.min( parseInt(this.links.style.height) , Math.round( (this.links.childNodes.length-1)*this.linkHeight ) )+'px';
    this.linkActive= ( parseInt(this.links.style.height) / (this.linkHeight-1) ) >> 1 ;
    window.setInterval('window["'+this.name+'"].iterate()', 100);
  }

  return this;
}
