docs: function XML2Object(node, mapping){  // require for refactoring
      var nodeType = node.nodeType;
      var attributes = node.attributes;
      var firstChild = node.firstChild;
  
      if (!firstChild)
      {
        var firstAttr = attributes && attributes[0];
        if (nodeType == ELEMENT_NODE)
        {
          if (!firstAttr)
            return '';
  
          // test for <node xsi:nil="true"/>
          if (attributes.length == 1 &&
              (firstAttr.baseName || firstAttr.localName) == XSI_NIL_LOCALPART &&
              firstAttr.namespaceURI == XSI_NAMESPACE)
            return null;
        }
        else
        {
          if (!firstAttr)
            return null;
        }
      }
      else
      {
        // single child node and not an element -> return child nodeValue
        if (firstChild.nodeType != ELEMENT_NODE && firstChild === node.lastChild)
          return firstChild.nodeValue;
        else
          if (firstChild !== node.lastChild && firstChild.nodeType == TEXT_NODE)
          {
            var isSeparatedTextNode = true;
            var result = '';
            var cursor = firstChild;
            do
            {
              if (cursor.nodeType !== TEXT_NODE)
              {
                isSeparatedTextNode = false;
                break;
              }
              result += cursor.nodeValue;
            }
            while (cursor = cursor.nextSibling);
  
            if (isSeparatedTextNode)
              return result;
          }
      }
  
      var result = {};
      var nodes = [];
      var childNodesCount = 0;
      var value;
      var cursor;
      var object;
      var name;
      var isElement;
      var map;
  
      if (cursor = firstChild)
      {
        do
        {
          childNodesCount = nodes.push(cursor);
        }
        while (cursor = cursor.nextSibling);
      }
  
      if (attributes)
        for (var i = 0, attr; attr = attributes[i]; i++)
          nodes.push(attr);
  
      if (!mapping)
        mapping = {};
  
      for (var i = 0, child; child = nodes[i]; i++)
      {
        name = child.nodeName;
        isElement = i < childNodesCount;
        map = mapping[name];
  
        // fetch value
        if (isElement)
        {
          value = XML2Object(child, mapping);
        }
        else
        {
          if (name == 'xmlns')
            continue;
  
          value = child.nodeValue;
        }
  
        // mapping keys
        while (map)
        {
          if (map.storeName)
            value[map.storeName] = name;
  
          if (map.rename)
          {
            name = map.rename;
            map = mapping[name];
          }
          else
          {
            if (map.format)
              value = map.format(value);
  
            if (!result[name] && map.forceArray)
              value = [value];
  
            break;
          }
        }
  
        // store result
        if (name in result)
        {
          if ((object = result[name]) && object.push)
            object.push(value);
          else
            result[name] = [object, value];
        }
        else
          result[name] = value;
      }
  
      return result;
    }