docs: function(xmlElement, options, path) {
  	path = path || [];
  	options = options || {}
  	var parseTypes = options && 'parseTypes' in options ? options.parseTypes : true;
  	var childElements = xmlElement.find("./*");
  	// var typeHint = hintForPath(options.typeHints, path);
  	var typeHint = hintForElement(options.typeHints, xmlElement);
  
  	// if there are no children, parse the content
  	if (childElements.length === 0) {
  		// text() will give us a string even if the element has no text content, so check how many child nodes it has first
  		var value = (xmlElement.childNodes().length === 0) ? null : xmlElement.text();
  		return (parseTypes && value != null && value !== "") ? parseValue(value, typeHint) : value;
  	}
  	// otherwise create an object/array from the child elements
  	else {
  		// if there's 1 child, it's an array, otherwise we have to detect repeated element names
  		var elementIsList = typeHint !== "object" && (childElements.length === 1 || typeHint === "array");
  		var resultObject = elementIsList ? [] : {};
  
  		childElements.forEach(function(childElement, index) {
  			var prefix = childElement.namespace()
  				? (childElement.namespace().prefix() + ":")
  				: "";
  			var childName = prefix + childElement.name();
  
  			// if we're trying to overwrite the same name, switch to using an array
  			if (!elementIsList && typeHint !== "object" && resultObject.hasOwnProperty(childName)) {
  				elementIsList = true;
  				var newResultObject = [];
  				for (var key in resultObject) {
  					newResultObject.push(resultObject[key]);
  				}
  				resultObject = newResultObject;
  			}
  
  			var pathElement = elementIsList ? index.toString(10) : childElement.name()
  			var childObject = convertElementToObject(childElement, options, path.concat(pathElement));
  			if (elementIsList) {
  				resultObject.push(childObject);
  			}
  			else {
  				resultObject[childName] = childObject;
  			}
  		});
  
  		return resultObject;
  	}
  }