(function(wysihtml){

  wysihtml.commands.outdentList = {
    exec: function(composer, command, value) {
      var listEls = composer.selection.getSelectionParentsByTag('LI');
      if (listEls) {
        return this.tryToPullLiLevel(listEls, composer);
      }
      return false;
    },

    state: function(composer, command) {
        return false;
    },

    tryToPullLiLevel: function(liNodes, composer) {
      var listNode, outerListNode, outerLiNode, list, prevLi, liNode, afterList,
          found = false,
          that = this;

      composer.selection.executeAndRestoreRangy(function() {

        for (var i = liNodes.length; i--;) {
          liNode = liNodes[i];
          if (liNode.parentNode) {
            listNode = liNode.parentNode;

            if (listNode.tagName === 'OL' || listNode.tagName === 'UL') {
              found = true;

              outerListNode = wysihtml.dom.getParentElement(listNode.parentNode, { query: 'ol, ul' }, false, composer.element);
              outerLiNode = wysihtml.dom.getParentElement(listNode.parentNode, { query: 'li' }, false, composer.element);

              if (outerListNode && outerLiNode) {

                if (liNode.nextSibling) {
                  afterList = that.getAfterList(listNode, liNode);
                  liNode.appendChild(afterList);
                }
                outerListNode.insertBefore(liNode, outerLiNode.nextSibling);

              } else {

                if (liNode.nextSibling) {
                  afterList = that.getAfterList(listNode, liNode);
                  liNode.appendChild(afterList);
                }

                for (var j = liNode.childNodes.length; j--;) {
                  listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);
                }

                listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
                liNode.parentNode.removeChild(liNode);

              }

              // cleanup
              if (listNode.childNodes.length === 0) {
                  listNode.parentNode.removeChild(listNode);
              }
            }
          }
        }

      });
      return found;
    },

    getAfterList: function(listNode, liNode) {
      var nodeName = listNode.nodeName,
          newList = document.createElement(nodeName);

      while (liNode.nextSibling) {
        newList.appendChild(liNode.nextSibling);
      }
      return newList;
    }

  };
}(wysihtml));
