function com_genesisuk_collapsibleList(strContainerName, fMutex, fTitleExpands, xEventCallback, xExpanderClickCallback)
{
  this.strListContainerName = strContainerName;
  this.fMutexMode = fMutex;
  this.fTitleExpands = fTitleExpands;
  this.xEventCallback = xEventCallback;
  this.xExpanderClickCallback = xExpanderClickCallback;
  this._lastSelectedDIV = null;
  this.aSubItems = [];
  
  this.SetActiveListContainerName = function(strName) {
    this.strListContainerName = strName;
  };
  
  this.SetMutexMode = function(fEnabled) {
    this.fMutexMode = fEnabled;
  };

  this.SetTitleExpandMode = function(fEnabled) {
    this.fTitleExpands = fEnabled;
  };

  this.SetEventCallbackFunction = function(func) {
    this.xEventCallback = func;
  };

  this.SetExpanderClickCallback = function(func) {
    this.xExpanderClickCallback = func;
  };

  this.ClearListContainer = function() {
    ClearContainerByName(this.strListContainerName);
  }

  this.AddListItem = function(strTitle, strURL, fJSURL) {
    var cont = GetDOMObject(this.strListContainerName);
    if (!cont)
      return null;
    var newItemDiv = document.createElement("div");

    //Create the expander
    var expander    = document.createElement("span");
    var expanderImg = document.createElement("img");
    expander._class    = this;
    expanderImg._class = this;
    expander.setAttribute("class", "listItem_expander");
    expander.className = "listItem_expander";
    expander.style.cursor = "default";
    expander.onclick = this._expander_toggleItems;
    expanderImg.setAttribute("src", "/i/plus.gif");
    expander.appendChild(expanderImg);
  
    //Create the item title
    var titleDiv  = document.createElement("div");
    var titleLink = document.createElement("a");
    titleDiv._class  = this;
    titleLink._class = this;
    titleDiv.setAttribute("class", "listItem_title");
    titleDiv.className = "listItem_title";
    titleDiv.appendChild(expander);
    if (fJSURL)
    {
      if (fTitleExpands)
      {
        titleLink.onclick  = function() {
          var func = this._class._title_expandItems;
          func.apply(this);
          eval(strURL);
        };
      }
      else
        titleLink.onclick = new Function(strURL);
      titleLink.setAttribute("href", "javascript:;");
    }
    else
    {
      if (fTitleExpands)
        titleLink.onclick = this._title_expandItems;
      titleLink.setAttribute("href", strURL);
    }
    titleLink.appendChild(document.createTextNode(strTitle));
    titleDiv.appendChild(titleLink);
  
    //Create the subitem container
    var itemsDiv = document.createElement("div");
    itemsDiv._class = this;
    itemsDiv.setAttribute("name",  "listItem_subItemsList");
    itemsDiv.setAttribute("id",    "listItem_subItemsList");
    itemsDiv.setAttribute("class", "listItem_subItemsList");
    itemsDiv.className = "listItem_subItemsList";
    itemsDiv.style.display = "none";
  
    //Add the elements to the new item
    newItemDiv.appendChild(titleDiv);
    newItemDiv.appendChild(itemsDiv);
  
    //Add the new item to the list
    cont.appendChild(newItemDiv);
  
    if (this.xEventCallback)
      this.xEventCallback("ADD_ITEM", newItemDiv);
      
    return newItemDiv;
  };

  this.AddSubItem = function(itemNode, uniqueID, itemName, itemURL, fJSURL) {
    var cont = GetDOMObject(this.strListContainerName);
    if (!cont || !itemNode)
      return;
    var itemsCont = GetDOMObject("listItem_subItemsList", itemNode);
    if (!itemsCont)
      return;
    var newLink = document.createElement("a");
    newLink._class = this;
    if (fJSURL)
    {
      newLink.onclick = new Function(itemURL);
      newLink.setAttribute("href", "javascript:;");
    }
    else
      newLink.setAttribute("href", itemURL);
    newLink.appendChild(document.createTextNode(itemName));
    //var div = CreateNamedElement("div", uniqueID);
    var div = document.createElement("div");
    div.appendChild(newLink);
    itemsCont.appendChild(div);
    //itemsCont.appendChild(newLink);
    //itemsCont.appendChild(document.createElement("br"));
  
    //Add the DIV to the internal list
    var objItemRef = new Object();
    objItemRef._div    = div;
    objItemRef._uid    = uniqueID;
    objItemRef._parent = itemNode;
    this.aSubItems.push(objItemRef);
    
    if (this.xEventCallback)
      this.xEventCallback("ADD_SUBITEM", itemName);
  };

  this.AddSubItemByName = function(uniqueID, strListItemName, strSubItemTitle, strSubItemURL, fJSURL) {
    var item = GetItemByName(this.strListItemName);
    if (item)
      this.AddSubItem(item, uniqueID, strSubItemTitle, strSubItemURL, fJSURL);
  };

  this.ExpandItem = function(itemNode) {
    if (!itemNode)
      return;
    var itemsCont = GetDOMObject("listItem_subItemsList", itemNode);
    if (!itemsCont)
      return;
    if (itemsCont.style.display != "block")
    {
      itemsCont.style.display = "block";
      var expanderImg = itemNode.firstChild.firstChild.firstChild;
      if (expanderImg)
        expanderImg.setAttribute("src", "/i/minus.gif");
      if (this.xEventCallback)
        this.xEventCallback("EXPAND", itemNode);
      if (this.fMutexMode)
        this._collapseOtherItems(itemNode);
    }
  };

  this.ExpandItemByName = function(strItemName) {
    var item = GetItemByName(strItemName);
    if (item)
      this.ExpandItem(item);
  };

  this.CollapseItem = function(itemNode) {
    if (!itemNode)
      return;
    var itemsCont = GetDOMObject("listItem_subItemsList", itemNode);
    if (!itemsCont)
      return;
    if (itemsCont.style.display != "none")
    {
      itemsCont.style.display = "none";
      var expanderImg = itemNode.firstChild.firstChild.firstChild;
      if (expanderImg)
        expanderImg.setAttribute("src", "/i/plus.gif");
      if (this.xEventCallback)
        this.xEventCallback("COLLAPSE", itemNode);
    }
  };

  this.CollapseItemByName = function(strItemName) {
    var item = GetItemByName(strItemName);
    if (item)
      this.CollapseItem(item);
  };

  this.GetItemByName = function(strName) {
    var cont = GetDOMObject(this.strListContainerName);
    if (!cont)
      return null;
    for (var i = 0; i < cont.childNodes.length; i++)
    {
      var anchorTag = cont.childNodes[i].firstChild.childNodes[1];
      for (var j = 0; j < anchorTag.childNodes.length; j++)
      {
        if ((anchorTag.childNodes[j].nodeType == 3) && (anchorTag.childNodes[j].nodeValue.toUpperCase() == strName.toUpperCase()))
          return cont.childNodes[i];
      }
    }
    return null;
  };
  
  this.SelectItemByUID = function(strUID, fExpandParent) {
    var div        = null;
    var parentNode = null;
    for (var i = 0; i < this.aSubItems.length; i++)
    {
      if (this.aSubItems[i]._uid.toUpperCase() == strUID.toUpperCase())
      {
        div        = this.aSubItems[i]._div;
        parentNode = this.aSubItems[i]._parent;
        break;
      }
    }
    if (div)
    {
      if (this._lastSelectedDIV)
        this._lastSelectedDIV.className = "";
      div.className = "selected";
      this._lastSelectedDIV = div;
      if (fExpandParent)
        this.ExpandItem(parentNode);
      return true;
    }
    else
      return false;
  };
  
  this.DeselectAllItems = function() {
    for (var i = 0; i < this.aSubItems.length; i++)
      this.aSubItems[i]._div.className = "";
  };

  this.GetItemStates = function() {
    var cont = GetDOMObject(this.strListContainerName);
    if (!cont)
      return null;
    var itemStates = "";
    for (var i = 0; i < cont.childNodes.length; i++)
      itemStates += (cont.childNodes[i].childNodes[1].style.display == "block") ? "1" : "0";
    return itemStates;
  };

  this.SetItemStates = function(itemStates) {
    var cont = GetDOMObject(this.strListContainerName);
    if (!cont)
      return;
    if (itemStates.length != cont.childNodes.length)
      return;
    for (var i = 0; i < itemStates.length; i++)
    {
      if (itemStates.substring(i, i + 1) == "1")
        this.ExpandItem(cont.childNodes[i]);
      else
        this.CollapseItem(cont.childNodes[i]);
    }
  };

  this._expander_toggleItems = function() {
    var itemsDiv = GetDOMObject("listItem_subItemsList", this.parentNode.parentNode);
    if (!itemsDiv)
      return;
    var displayValue = itemsDiv.style.display;
    if (!displayValue)
      displayValue = "block";
    itemsDiv.style.display = (displayValue == "block") ? "none" : "block";
    var expanderImg = this.firstChild;
    if (expanderImg)
      expanderImg.setAttribute("src", (displayValue == "block") ? "/i/plus.gif" : "/i/minus.gif");
    if (this._class.xExpanderClickCallback)
      this._class.xExpanderClickCallback((displayValue == "block") ? "COLLAPSE" : "EXPAND", itemsDiv.parentNode);
    if (this._class.xEventCallback)
      this._class.xEventCallback((displayValue == "block") ? "COLLAPSE" : "EXPAND", itemsDiv.parentNode);
    if (this._class.fMutexMode)
      this._class._collapseOtherItems(itemsDiv.parentNode);
  };

  this._title_expandItems = function() {
    var itemsDiv = GetDOMObject("listItem_subItemsList", this.parentNode.parentNode);
    if (!itemsDiv)
      return;
    itemsDiv.style.display = "block";
    var expanderImg = this.parentNode.firstChild.firstChild;
    if (expanderImg)
      expanderImg.setAttribute("src", "/i/minus.gif");
    if (this._class.xExpanderClickCallback)
      this._class.xExpanderClickCallback("COLLAPSE", itemsDiv.parentNode);
    if (this._class.xEventCallback)
      this._class.xEventCallback("COLLAPSE", itemsDiv.parentNode);
    if (this._class.fMutexMode)
      this._class._collapseOtherItems(itemsDiv.parentNode);
  };

  this._collapseOtherItems = function(expandedItem) {
    var cont = GetDOMObject(this.strListContainerName);
    if (!cont)
      return;
    for (var i = 0; i < cont.childNodes.length; i++)
    {
      if (cont.childNodes[i] != expandedItem)
      {
        var subItemsDiv = cont.childNodes[i].childNodes[1];
        var expanderImg = cont.childNodes[i].firstChild.firstChild.firstChild;
        if (subItemsDiv && expanderImg)
        {
          if (subItemsDiv.style.display != "none")
          {
            subItemsDiv.style.display = "none";
            expanderImg.setAttribute("src", "/i/plus.gif");
            if (this.xEventCallback)
              this.xEventCallback("COLLAPSE", cont.childNodes[i]);
          }
        }
      }
    }
  };
}
