
    function isClass (element, className) {
    	return element.className.match ('\\b' + className + '\\b');
    }

    function addClass (element, className) {
    	if (!element.className.match ('\\b' + className + '\\b'))
    		element.className += ' ' + className;
    }

    function removeClass (element, className) {
    	element.className = element.className.replace (new RegExp ('\\b' + className + '\\b', 'g'), '');
    }

    if (!document.getElementsByClassName) {
      document.getElementsByClassName = function (className, tag, onlydirect) {
        tag = tag || '*';
        onlydirect = onlydirect || false;
        var nodes = document.getElementsByTagName (tag);
        var result = [];
        var search = new RegExp ('\\b' + className + '\\b');
        for (var i = 0; i < nodes.length; i++) {
          if (nodes [i].className && search.test (nodes [i].className)) {
            result.push (nodes [i]);
          }
        }
        return result;
      }
    }

    function getDirectChilds (node, tag) {
      var results= [];
      var nodes  = node.childNodes;
      var l      = node.childNodes.length;
      for (var i = 0; i < l; i++) {
        if (nodes [i].tagName == tag) {
          results.push (nodes [i]);
        }
      }
      return results;
    }

    function addLoadEvent(func) {
      if (typeof window.onload != 'function') {
        window.onload = func;
      } else {
        var oldonload = window.onload;
        window.onload = function() {
          oldonload();
          func();
        }
      }
    }

    var liCount = 0;
    var cbCount = 0;
    function makeTreeSelect (id, title, tree, key, editable, submitClick) {
    
      /* find treeSelect */
      var ul = document.getElementById (id);

      ul.tsInit = function (toplist, title, tree, key) {

        this.tsToplist  = toplist;
        this.tsTitle    = title;
        this.tsTree     = tree;
        this.tsKey      = key;

        var lis, li, i, j, k, checkbox, label, sublist;

        /* get all lis and save list */
        lis = getDirectChilds (this, 'LI');
        this.tsLis = lis;


        /* uncheck all child checkboxes and hide all sublists */
        this.tsUncheckChilds = function () {
          for (var i = 0; i < this.tsLis.length; i++) {
            this.tsLis [i].tsUncheck (true);
          }
        }

        /* build string from list and sublists, sublists override list entry */
        this.toString = function () {
          var s, li;
          var results = [];

          /* loop over all lis of ul */
          for (var i = 0; i < this.tsLis.length; i++) {
            li = this.tsLis [i];
            /* not checked - no string */
            if (!li.tsCheckbox.checked) {
              continue;
            }
            /* checked and no sublist - got a string */
            if (!li.tsSublist) {
              s = li.tsLabel.innerHTML;
              if (s)
                results.push (s);
              continue;
            }
            /* get strings from sublist */
            s = li.tsSublist.toString ();
            if (s) {
              results.push (s);
              continue;
            }
            /* no string from sublist - get this label */
            s = li.tsLabel.innerHTML;
            if (s)
              results.push (s);
          }
          /* got nothing */
          if (!results.length)
            return '';

          /* return comma seperated list */
          return results.join (', ');
        }

        this.initLi = function (li) {
          var childs    = li.childNodes;
          var checkbox  = false;
          var label     = false;
          var sublist   = false;

          /* find essential childs */
          for (var j = 0; j < childs.length; j++) {
            node = childs [j];
            if (node.tagName == 'INPUT' && node.type == 'checkbox') {
              checkbox = node;
              continue;
            }
            if (node.tagName == 'LABEL') {
              label    = node;
              continue;
            }
            if (node.tagName == 'UL') {
              sublist  = node;
              continue;
            }
          }

          /* not found */
          if (!checkbox || !label)
            return;

          /* set li */
          li.tsToplist  = toplist;
          li.tsCheckbox = checkbox;
          li.tsLabel    = label;
          li.tsSublist  = sublist;
          if (sublist) {
            removeClass (li, 'nosub');
            addClass (li, 'sub');
          } else {
            removeClass (li, 'sub');
            addClass (li, 'nosub');
          }

          /* set label */
          if (editable) {
            li.tsLabel.title = "Klicken zum Ändern";
            li.tsLabel.onclick = function () {
              var nLi       = this.parentNode;
              var topList   = nLi.tsToplist;
              var h         = newCenteredWindow (
                'tsEdit.php'  +
                '?id='        + nLi.tsCheckbox.id.split ('-')[1] +
                '&domid='     + nLi.tsCheckbox.id +
                '&title='     + toplist.tsTitle +
                '&tree='      + toplist.tsTree +
                '&key='       + toplist.tsKey,
                toplist.tsTitle,
                winwidth,
                100,
                false
              );
              if (!h)
                return true;
              return false;
            }
          }

          /* select element */
          li.tsCheck = function () {
            cbCount++;
            this.tsCheckbox.checked = true;
            removeClass (this, 'unselected');
            addClass    (this, 'selected');
          }

          /* unselect element */
          li.tsUncheck = function (allChilds) {
            cbCount++;
            this.tsCheckbox.checked = false;
            removeClass (this, 'selected');
            addClass    (this, 'unselected');
            if (allChilds && this.tsSublist)
              this.tsSublist.tsUncheckChilds (true);
          }

          /* change text */
          li.tsChangeText = function (newText, newDesc) {
            this.tsLabel.innerHTML = newText;
            this.tsCheckbox.title  = newDesc;
          }

          /* delete element */
          li.tsDelete = function () {
            /* find in ul list */
            var nUl = this.parentNode;
            for (var i = 0; i < nUl.tsLis.length; i++) {
              if (nUl.tsLis [i] == this) {
                nUl.tsLis.splice (i, 1);
                break;
              }
            }
            nUl.removeChild (this);
            if (nUl.tsLis.length == 0) {
              var pLi = nUl.parentNode;
              pLi.removeChild (nUl);
              pLi.tsSublist = false;
              removeClass (pLi, 'sub');
              addClass    (pLi, 'nosub');
            }
          }

          /* add new last element */
          li.tsAppendLast = function (newId, newText, newDesc) {
            var nUl    = this.parentNode;

            /* create new li */
            var newLi  = this.cloneNode (false);

            /* create new checkbox and append to new li */
            var newInput      = this.tsCheckbox.cloneNode (false);
            newInput.id       = newInput.id.split ('-')[0] + '-' + newId;
            newInput.value    = newId;
            newInput.title    = newDesc;
            newLi.appendChild (newInput);
            newLi.appendChild (document.createTextNode(' '));

            /* create new label and append to new li */
            var newLabel  = this.tsLabel.cloneNode (false);
            newLabel.setAttribute ('for', newInput.id);
            newLabel.innerHTML = newText;
            newLi.appendChild (newLabel);
            newLi.appendChild (document.createTextNode(' '));

            /* add new last list item to parent ul */
            nUl.appendChild (newLi);
            nUl.tsLis.push (newLi);
            nUl.initLi (newLi);
            this.tsUncheck ();
            newLi.tsCheck ();
          }

          /* add child */
          li.tsAppendLastChild = function (newId, newText, newDesc) {
            var nUl    = this.parentNode;

            /* create new li */
            var newLi  = this.cloneNode (false);
            this.tsCheck ();

            /* create new checkbox and append to new li */
            var newInput      = this.tsCheckbox.cloneNode (false);
            newInput.id       = newInput.id.split ('-')[0] + '-' + newId;
            newInput.value    = newId;
            newInput.title    = newDesc;
            newLi.appendChild (newInput);
            newLi.appendChild (document.createTextNode(' '));

            /* create new label and append to new li */
            var newLabel  = this.tsLabel.cloneNode (false);
            newLabel.setAttribute ('for', newInput.id);
            newLabel.innerHTML = newText;
            newLi.appendChild (newLabel);
            newLi.appendChild (document.createTextNode(' '));

            /* create new ul */
            if (!this.tsSublist) {
              this.tsSublist    = nUl.cloneNode (false);
              this.appendChild (this.tsSublist);
              this.tsSublist.appendChild (newLi);
              this.tsSublist.tsInit = nUl.tsInit;
              this.tsSublist.tsInit (this.tsToplist);
              removeClass (this.tsSublist, 'treeSelect');
              removeClass (this, 'nosub');
              addClass    (this, 'sub');
            } else {
              /* add new last list item to existing ul */
              this.appendChild (this.tsSublist);
              this.tsSublist.appendChild (newLi);
              this.tsSublist.tsLis.push (newLi);
              this.tsSublist.initLi (newLi);
            }
            newLi.tsCheck ();
          }

          /* add event for show and hide subcheckBoxes */
          checkbox.tsLi = li;
          checkbox.onclick = function (e) {
//                alert ('click');
            if (this.checked) {
              this.tsLi.tsCheck ();
            } else {
              this.tsLi.tsUncheck (true);
            }
//                document.getElementById ('mats').innerHTML = this.tsLi.tsToplist.toString ();
            if (submitClick) {
              this.form.submit ();
            }
          }
          checkbox.onkeyup = checkbox.onclick;

          /* prepare sublists */
          if (sublist) {
            sublist.tsInit = this.tsInit;
            sublist.tsInit (toplist, toplist.tsTitle, toplist.tsTree, toplist.tsKey);
          }

          /* initialize li */
          if (checkbox.checked) {
            li.tsCheck ();
          } else {
            li.tsUncheck ();
          }
        }

        /* for all lis of ul */
        for (var i = 0; i < lis.length; i++) {
           /* find checkbox, label and sublist */
          this.initLi (lis [i]);
        }
      }

      ul.tsInit (ul, title, tree, key);
    }
