docs: function _handleAttributes(oldNode, newNode, rule, clearInternals) {
      var attributes          = {},                         // fresh new set of attributes to set on newNode
          setClass            = rule.set_class,             // classes to set
          addClass            = rule.add_class,             // add classes based on existing attributes
          addStyle            = rule.add_style,             // add styles based on existing attributes
          setAttributes       = rule.set_attributes,        // attributes to set on the current node
          allowedClasses      = currentRules.classes,
          i                   = 0,
          classes             = [],
          styles              = [],
          newClasses          = [],
          oldClasses          = [],
          classesLength,
          newClassesLength,
          currentClass,
          newClass,
          attributeName,
          method;
  
      if (setAttributes) {
        attributes = wysihtml5.lang.object(setAttributes).clone();
      }
  
      // check/convert values of attributes
      attributes = wysihtml5.lang.object(attributes).merge(_checkAttributes(oldNode,  rule.check_attributes)).get();
  
      if (setClass) {
        classes.push(setClass);
      }
  
      if (addClass) {
        for (attributeName in addClass) {
          method = addClassMethods[addClass[attributeName]];
          if (!method) {
            continue;
          }
          newClass = method(wysihtml5.dom.getAttribute(oldNode, attributeName));
          if (typeof(newClass) === "string") {
            classes.push(newClass);
          }
        }
      }
  
      if (addStyle) {
        for (attributeName in addStyle) {
          method = addStyleMethods[addStyle[attributeName]];
          if (!method) {
            continue;
          }
  
          newStyle = method(wysihtml5.dom.getAttribute(oldNode, attributeName));
          if (typeof(newStyle) === "string") {
            styles.push(newStyle);
          }
        }
      }
  
  
      if (typeof(allowedClasses) === "string" && allowedClasses === "any" && oldNode.getAttribute("class")) {
        if (currentRules.classes_blacklist) {
          oldClasses = oldNode.getAttribute("class");
          if (oldClasses) {
            classes = classes.concat(oldClasses.split(WHITE_SPACE_REG_EXP));
          }
  
          classesLength = classes.length;
          for (; i<classesLength; i++) {
            currentClass = classes[i];
            if (!currentRules.classes_blacklist[currentClass]) {
              newClasses.push(currentClass);
            }
          }
  
          if (newClasses.length) {
            attributes["class"] = wysihtml5.lang.array(newClasses).unique().join(" ");
          }
  
        } else {
          attributes["class"] = oldNode.getAttribute("class");
        }
      } else {
        // make sure that wysihtml5 temp class doesn't get stripped out
        if (!clearInternals) {
          allowedClasses["_wysihtml5-temp-placeholder"] = 1;
          allowedClasses["_rangySelectionBoundary"] = 1;
          allowedClasses["wysiwyg-tmp-selected-cell"] = 1;
        }
  
        // add old classes last
        oldClasses = oldNode.getAttribute("class");
        if (oldClasses) {
          classes = classes.concat(oldClasses.split(WHITE_SPACE_REG_EXP));
        }
        classesLength = classes.length;
        for (; i<classesLength; i++) {
          currentClass = classes[i];
          if (allowedClasses[currentClass]) {
            newClasses.push(currentClass);
          }
        }
  
        if (newClasses.length) {
          attributes["class"] = wysihtml5.lang.array(newClasses).unique().join(" ");
        }
      }
  
      // remove table selection class if present
      if (attributes["class"] && clearInternals) {
        attributes["class"] = attributes["class"].replace("wysiwyg-tmp-selected-cell", "");
        if ((/^\s*$/g).test(attributes["class"])) {
          delete attributes["class"];
        }
      }
  
      if (styles.length) {
        attributes["style"] = wysihtml5.lang.array(styles).unique().join(" ");
      }
  
      // set attributes on newNode
      for (attributeName in attributes) {
        // Setting attributes can cause a js error in IE under certain circumstances
        // eg. on a <img> under https when it's new attribute value is non-https
        // TODO: Investigate this further and check for smarter handling
        try {
          newNode.setAttribute(attributeName, attributes[attributeName]);
        } catch(e) {}
      }
  
      // IE8 sometimes loses the width/height attributes when those are set before the "src"
      // so we make sure to set them again
      if (attributes.src) {
        if (typeof(attributes.width) !== "undefined") {
          newNode.setAttribute("width", attributes.width);
        }
        if (typeof(attributes.height) !== "undefined") {
          newNode.setAttribute("height", attributes.height);
        }
      }
    }