text: var parse = require('./parse'),
      render = require('dom-serializer'),
      assign = require('lodash/assign');
  
  /**
   * HTML Tags
   */
  
  var tags = { tag: true, script: true, style: true };
  
  /**
   * Check if the DOM element is a tag
   *
   * isTag(type) includes <script> and <style> tags
   */
  
  exports.isTag = function(type) {
    if (type.type) type = type.type;
    return tags[type] || false;
  };
  
  /**
   * Convert a string to camel case notation.
   * @param  {String} str String to be converted.
   * @return {String}     String in camel case notation.
   */
  
  exports.camelCase = function(str) {
    return str.replace(/[_.-](\w|$)/g, function(_, x) {
      return x.toUpperCase();
    });
  };
  
  /**
   * Convert a string from camel case to "CSS case", where word boundaries are
   * described by hyphens ("-") and all characters are lower-case.
   * @param  {String} str String to be converted.
   * @return {string}     String in "CSS case".
   */
  exports.cssCase = function(str) {
    return str.replace(/[A-Z]/g, '-$&').toLowerCase();
  };
  
  /**
   * Iterate over each DOM element without creating intermediary Cheerio instances.
   *
   * This is indented for use internally to avoid otherwise unnecessary memory pressure introduced
   * by _make.
   */
  
  exports.domEach = function(cheerio, fn) {
    var i = 0, len = cheerio.length;
    while (i < len && fn.call(cheerio, i, cheerio[i]) !== false) ++i;
    return cheerio;
  };
  
  /**
   * Create a deep copy of the given DOM structure by first rendering it to a
   * string and then parsing the resultant markup.
   *
   * @argument {Object} dom - The htmlparser2-compliant DOM structure
   * @argument {Object} options - The parsing/rendering options
   */
  exports.cloneDom = function(dom, options) {
    options = assign({}, options, { useHtmlParser2: true });
  
    return parse(render(dom, options), options, false).children;
  };
  
  /*
   * A simple way to check for HTML strings or ID strings
   */
  
  var quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
  
  /*
   * Check if string is HTML
   */
  exports.isHtml = function(str) {
    // Faster than running regex, if str starts with `<` and ends with `>`, assume it's HTML
    if (str.charAt(0) === '<' && str.charAt(str.length - 1) === '>' && str.length >= 3) return true;
  
    // Run the regex
    var match = quickExpr.exec(str);
    return !!(match && match[1]);
  };
  