docs: function processElement( that, element, toBeRemoved, opts ) {
  		var status,
  			retVal = 0,
  			callbacksRetVal;
  
  		// Unprotect elements names previously protected by htmlDataProcessor
  		// (see protectElementNames and protectSelfClosingElements functions).
  		// Note: body, title, etc. are not protected by htmlDataP (or are protected and then unprotected).
  		if ( opts.toHtml )
  			element.name = element.name.replace( unprotectElementsNamesRegexp, '$1' );
  
  		// Execute element callbacks and return if one of them returned any value.
  		if ( opts.doCallbacks && that.elementCallbacks ) {
  			// For now we only support here FILTER_SKIP_TREE, so we can early return if retVal is truly value.
  			if ( ( callbacksRetVal = executeElementCallbacks( element, that.elementCallbacks ) ) )
  				return callbacksRetVal;
  		}
  
  		// If transformations are set apply all groups.
  		if ( opts.doTransform )
  			transformElement( that, element );
  
  		if ( opts.doFilter ) {
  			// Apply all filters.
  			status = filterElement( that, element, opts );
  
  			// Handle early return from filterElement.
  			if ( !status ) {
  				toBeRemoved.push( element );
  				return FILTER_ELEMENT_MODIFIED;
  			}
  
  			// Finally, if after running all filter rules it still hasn't been allowed - remove it.
  			if ( !status.valid ) {
  				toBeRemoved.push( element );
  				return FILTER_ELEMENT_MODIFIED;
  			}
  
  			// Update element's attributes based on status of filtering.
  			if ( updateElement( element, status ) )
  				retVal = FILTER_ELEMENT_MODIFIED;
  
  			if ( !opts.skipFinalValidation && !validateElement( element ) ) {
  				toBeRemoved.push( element );
  				return FILTER_ELEMENT_MODIFIED;
  			}
  		}
  
  		// Protect previously unprotected elements.
  		if ( opts.toHtml )
  			element.name = element.name.replace( protectElementsNamesRegexp, 'cke:$1' );
  
  		return retVal;
  	}