[evolution/wip/webkit2] Commit the word before sync with master



commit f966e1e0f6365074406ca1fb7bbd6f3fffb639d2
Author: Tomas Popela <tpopela redhat com>
Date:   Thu Nov 27 16:10:30 2014 +0100

    Commit the word before sync with master

 e-util/e-dom-utils.c                               |   14 +-
 e-util/e-html-editor-selection-dom-functions.c     |  441 +-
 e-util/e-html-editor-selection-dom-functions.h     |   66 +-
 e-util/e-html-editor-selection.c                   |   14 +-
 e-util/e-html-editor-view-dom-functions.c          | 4934 ++++++++++++++++++
 e-util/e-html-editor-view-dom-functions.h          |   16 +
 e-util/e-html-editor-view.c                        | 5244 ++------------------
 e-util/e-html-editor.c                             |   12 +-
 e-util/e-html-editor.h                             |    2 +-
 e-util/web-extensions/Makefile.am                  |    3 +-
 .../e-html-editor-web-extension-main.c             |   51 +
 .../e-html-editor-web-extension-names.h            |   14 +-
 .../web-extensions/e-html-editor-web-extension.c   |  625 ++-
 .../web-extensions/e-html-editor-web-extension.h   |  104 +-
 .../module-itip-formatter-web-extension.c          |    8 +-
 .../mail/web-extension/module-mail-web-extension.c |    4 +-
 .../module-prefer-plain-web-extension.c            |    4 +-
 .../module-text-highlight-web-extension.c          |    4 +-
 web-extensions/Makefile.am                         |    5 +-
 web-extensions/e-web-extension-main.c              |   51 +
 ...evolution-web-extension.c => e-web-extension.c} |  564 ++-
 web-extensions/e-web-extension.h                   |   76 +
 22 files changed, 6664 insertions(+), 5592 deletions(-)
---
diff --git a/e-util/e-dom-utils.c b/e-util/e-dom-utils.c
index 6981d05..871aab5 100644
--- a/e-util/e-dom-utils.c
+++ b/e-util/e-dom-utils.c
@@ -23,7 +23,7 @@
 #include <webkitdom/WebKitDOMDOMWindowUnstable.h>
 #include <webkitdom/WebKitDOMHTMLElementUnstable.h>
 
-#include "../web-extensions/evolution-web-extension.h"
+#include "../web-extensions/e-web-extension.h"
 
 #include "e-misc-utils.h"
 
@@ -626,8 +626,8 @@ toggle_address_visibility (WebKitDOMElement *button,
        g_dbus_connection_emit_signal (
                connection,
                NULL,
-               EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
-               EVOLUTION_WEB_EXTENSION_INTERFACE,
+               E_WEB_EXTENSION_OBJECT_PATH,
+               E_WEB_EXTENSION_INTERFACE,
                "HeadersCollapsed",
                g_variant_new ("(b)", expanded),
                &error);
@@ -1190,8 +1190,8 @@ display_mode_toggle_button_cb (WebKitDOMElement *button,
        g_dbus_connection_emit_signal (
                connection,
                NULL,
-               EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
-               EVOLUTION_WEB_EXTENSION_INTERFACE,
+               E_WEB_EXTENSION_OBJECT_PATH,
+               E_WEB_EXTENSION_INTERFACE,
                "VCardInlineDisplayModeToggled",
                g_variant_new ("(s)", element_id),
                &error);
@@ -1218,8 +1218,8 @@ save_vcard_button_cb (WebKitDOMElement *button,
        g_dbus_connection_emit_signal (
                connection,
                NULL,
-               EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
-               EVOLUTION_WEB_EXTENSION_INTERFACE,
+               E_WEB_EXTENSION_OBJECT_PATH,
+               E_WEB_EXTENSION_INTERFACE,
                "VCardInlineSaveButtonPressed",
                g_variant_new ("(s)", button_value),
                &error);
diff --git a/e-util/e-html-editor-selection-dom-functions.c b/e-util/e-html-editor-selection-dom-functions.c
index 13359f9..d08f4c8 100644
--- a/e-util/e-html-editor-selection-dom-functions.c
+++ b/e-util/e-html-editor-selection-dom-functions.c
@@ -37,7 +37,6 @@
 #define SPACES_PER_INDENTATION 4
 #define SPACES_PER_LIST_LEVEL 8
 #define MINIMAL_PARAGRAPH_WIDTH 5
-#define WORD_WRAP_LENGTH 71
 
 static const GdkRGBA black = { 0, 0, 0, 1 };
 
@@ -131,17 +130,16 @@ dom_get_current_range (WebKitDOMDocument *document)
  * #EHTMLEditorSelection and should not be free'd.
  */
 gchar *
-dom_selection_get_string (WebKitDOMDocument *document)
+dom_selection_get_string (WebKitDOMDocument *document,
+                          EHTMLEditorWebExtension *extension)
 {
+       gchar *text;
        WebKitDOMRange *range;
 
        range = dom_get_current_range (document);
        if (!range)
                return NULL;
-/* FIXME WK2
-       g_free (selection->priv->text);
-       selection->priv->text = webkit_dom_range_get_text (range);
-*/
+
        return webkit_dom_range_get_text (range);
 }
 
@@ -496,32 +494,6 @@ get_list_format_from_node (WebKitDOMNode *node)
 }
 
 static gboolean
-is_in_html_mode (WebKitDOMDocument *document)
-{
-       WebKitDOMElement *document_element;
-
-       document_element = webkit_dom_document_get_document_element (document);
-
-       return webkit_dom_element_has_attribute (document_element, "data-html-mode");
-
-       /* FIXME WK2 we have to probably add a body attribute that shows,
-        * whether the composer is in HTML mode */
-       /*
-       EHTMLEditorView *view = e_html_editor_selection_ref_html_editor_view (selection);
-       gboolean ret_val;
-
-       g_return_val_if_fail (view != NULL, FALSE);
-
-       ret_val = e_html_editor_view_get_html_mode (view);
-
-       g_object_unref (view);
-
-       return ret_val;
-       */
-       return FALSE;
-}
-
-static gboolean
 node_is_list_or_item (WebKitDOMNode *node)
 {
        return node && (
@@ -631,8 +603,17 @@ dom_get_alignment (WebKitDOMDocument *document)
        return alignment;
 }
 
+static gint
+set_word_wrap_length (EHTMLEditorWebExtension *extension,
+                      gint user_word_wrap_length)
+{
+       return (user_word_wrap_length == -1) ?
+               e_html_editor_web_extension_get_word_wrap_length (extension) : user_word_wrap_length;
+}
+
 static void
-dom_set_paragraph_style (WebKitDOMDocument *document,
+dom_set_paragraph_style (EHTMLEditorWebExtension *extension,
+                         WebKitDOMDocument *document,
                          WebKitDOMElement *element,
                          gint width,
                          gint offset,
@@ -640,13 +621,13 @@ dom_set_paragraph_style (WebKitDOMDocument *document,
 {
        EHTMLEditorSelectionAlignment alignment;
        char *style = NULL;
-       gint word_wrap_length = (width == -1) ? WORD_WRAP_LENGTH : width;
+       gint word_wrap_length = set_word_wrap_length (extension, width);
 
        alignment = dom_get_alignment (document);
 
        element_add_class (element, "-x-evo-paragraph");
        element_add_class (element, get_css_alignment_value_class (alignment));
-       if (!is_in_html_mode (document)) {
+       if (!e_html_editor_web_extension_get_html_mode (extension)) {
                style = g_strdup_printf (
                        "width: %dch; word-wrap: normal; %s",
                        (word_wrap_length + offset), style_to_add);
@@ -661,7 +642,8 @@ dom_set_paragraph_style (WebKitDOMDocument *document,
 }
 
 static WebKitDOMElement *
-create_list_element (WebKitDOMDocument *document,
+create_list_element (EHTMLEditorWebExtension *extension,
+                     WebKitDOMDocument *document,
                      EHTMLEditorSelectionBlockFormat format,
                     gint level,
                      gboolean html_mode)
@@ -680,8 +662,7 @@ create_list_element (WebKitDOMDocument *document,
                offset = (level + 1) * -SPACES_PER_LIST_LEVEL;
 
        if (!html_mode)
-               dom_set_paragraph_style (
-                       document, list, -1, offset, "");
+               dom_set_paragraph_style (extension, document, list, -1, offset, "");
 
        return list;
 }
@@ -751,7 +732,8 @@ merge_lists_if_possible (WebKitDOMNode *list)
 }
 
 static void
-indent_list (WebKitDOMDocument *document)
+indent_list (EHTMLEditorWebExtension *extension,
+             WebKitDOMDocument *document)
 {
        WebKitDOMElement *selection_start_marker, *selection_end_marker;
        WebKitDOMNode *item, *next_item;
@@ -767,7 +749,7 @@ indent_list (WebKitDOMDocument *document)
                WEBKIT_DOM_NODE (selection_start_marker));
 
        if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (item)) {
-               gboolean html_mode = is_in_html_mode (document);
+               gboolean html_mode = e_html_editor_web_extension_get_html_mode (extension);
                WebKitDOMElement *list;
                WebKitDOMNode *source_list = webkit_dom_node_get_parent_node (item);
                EHTMLEditorSelectionBlockFormat format;
@@ -775,7 +757,7 @@ indent_list (WebKitDOMDocument *document)
                format = get_list_format_from_node (source_list);
 
                list = create_list_element (
-                       document, format, get_list_level (item), html_mode);
+                       extension, document, format, get_list_level (item), html_mode);
 
                element_add_class (list, "-x-evo-indented");
 
@@ -799,16 +781,17 @@ indent_list (WebKitDOMDocument *document)
 }
 
 static void
-dom_set_indented_style (WebKitDOMDocument *document,
+dom_set_indented_style (EHTMLEditorWebExtension *extension,
+                        WebKitDOMDocument *document,
                         WebKitDOMElement *element,
                         gint width)
 {
        gchar *style;
-       gint word_wrap_length = (width == -1) ? WORD_WRAP_LENGTH : width;
+       gint word_wrap_length = set_word_wrap_length (extension, width);
 
        webkit_dom_element_set_class_name (element, "-x-evo-indented");
 
-       if (is_in_html_mode (document))
+       if (e_html_editor_web_extension_get_html_mode (extension))
                style = g_strdup_printf ("margin-left: %dch;", SPACES_PER_INDENTATION);
        else
                style = g_strdup_printf (
@@ -820,25 +803,27 @@ dom_set_indented_style (WebKitDOMDocument *document,
 }
 
 static WebKitDOMElement *
-dom_get_indented_element (WebKitDOMDocument *document,
+dom_get_indented_element (EHTMLEditorWebExtension *extension,
+                          WebKitDOMDocument *document,
                           gint width)
 {
        WebKitDOMElement *element;
 
        element = webkit_dom_document_create_element (document, "DIV", NULL);
-       dom_set_indented_style (document, element, width);
+       dom_set_indented_style (extension, document, element, width);
 
        return element;
 }
 
 static void
-indent_block (WebKitDOMDocument *document,
+indent_block (EHTMLEditorWebExtension *extension,
+              WebKitDOMDocument *document,
               WebKitDOMNode *block,
               gint width)
 {
        WebKitDOMElement *element;
 
-       element = dom_get_indented_element (document, width);
+       element = dom_get_indented_element (extension, document, width);
 
        webkit_dom_node_insert_before (
                webkit_dom_node_get_parent_node (block),
@@ -991,7 +976,8 @@ add_selection_markers_into_element_start (WebKitDOMDocument *document,
  * Indents current paragraph by one level.
  */
 static void
-dom_indent (WebKitDOMDocument *document)
+dom_indent (EHTMLEditorWebExtension *extension,
+            WebKitDOMDocument *document)
 {
        gboolean after_selection_start = FALSE, after_selection_end = FALSE;
        WebKitDOMElement *selection_start_marker, *selection_end_marker;
@@ -1027,11 +1013,12 @@ dom_indent (WebKitDOMDocument *document)
                        WEBKIT_DOM_NODE (selection_start_marker));
 
        while (block && !after_selection_end) {
-               gint ii, length, level, final_width = 0;
-               gint word_wrap_length = WORD_WRAP_LENGTH;
+               gint ii, length, level, word_wrap_length, final_width = 0;
                WebKitDOMNode *next_block;
                WebKitDOMNodeList *list;
 
+               word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
+
                next_block = webkit_dom_node_get_next_sibling (block);
 
                list = webkit_dom_element_query_selector_all (
@@ -1044,7 +1031,7 @@ dom_indent (WebKitDOMDocument *document)
 
                length = webkit_dom_node_list_get_length (list);
                if (length == 0 && node_is_list_or_item (block)) {
-                       indent_list (document);
+                       indent_list (extension, document);
                        goto next;
                }
 
@@ -1060,10 +1047,10 @@ dom_indent (WebKitDOMDocument *document)
 
                        final_width = word_wrap_length - SPACES_PER_INDENTATION * (level + 1);
                        if (final_width < MINIMAL_PARAGRAPH_WIDTH &&
-                           !is_in_html_mode (document))
+                           !e_html_editor_web_extension_get_html_mode (extension))
                                goto next;
 
-                       indent_block (document, block, final_width);
+                       indent_block (extension, document, block, final_width);
 
                        if (after_selection_end)
                                goto next;
@@ -1090,10 +1077,10 @@ dom_indent (WebKitDOMDocument *document)
 
                        final_width = word_wrap_length - SPACES_PER_INDENTATION * (level + 1);
                        if (final_width < MINIMAL_PARAGRAPH_WIDTH &&
-                           !is_in_html_mode (document))
+                           !e_html_editor_web_extension_get_html_mode (extension))
                                continue;
 
-                       indent_block (document, block_to_process, final_width);
+                       indent_block (extension, document, block_to_process, final_width);
 
                        if (after_selection_end)
                                break;
@@ -1107,9 +1094,9 @@ dom_indent (WebKitDOMDocument *document)
        }
 
        dom_selection_restore (document);
-       /* FIXME WK2
-       e_html_editor_view_force_spell_check_for_current_paragraph (view);
+       dom_force_spell_check_for_current_paragraph (document);
 
+       /* FIXME WK2
        g_object_notify (G_OBJECT (selection), "indented"); */
 }
 
@@ -1183,12 +1170,12 @@ unindent_list (WebKitDOMDocument *document)
 }
 
 static void
-unindent_block (WebKitDOMDocument *document,
+unindent_block (EHTMLEditorWebExtension *extension,
+                WebKitDOMDocument *document,
                 WebKitDOMNode *block)
 {
        gboolean before_node = TRUE;
-       gint word_wrap_length = WORD_WRAP_LENGTH;
-       gint level, width;
+       gint word_wrap_length, level, width;
        EHTMLEditorSelectionAlignment alignment;
        WebKitDOMElement *element;
        WebKitDOMElement *prev_blockquote = NULL, *next_blockquote = NULL;
@@ -1207,19 +1194,18 @@ unindent_block (WebKitDOMDocument *document,
        element_add_class (WEBKIT_DOM_ELEMENT (block_to_process), "-x-evo-to-unindent");
 
        level = get_indentation_level (element);
+       word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
        width = word_wrap_length - SPACES_PER_INDENTATION * level;
 
        /* Look if we have previous siblings, if so, we have to
         * create new blockquote that will include them */
        if (webkit_dom_node_get_previous_sibling (block_to_process))
-               prev_blockquote = dom_get_indented_element (
-                       document, width);
+               prev_blockquote = dom_get_indented_element (extension, document, width);
 
        /* Look if we have next siblings, if so, we have to
         * create new blockquote that will include them */
        if (webkit_dom_node_get_next_sibling (block_to_process))
-               next_blockquote = dom_get_indented_element (
-                       document, width);
+               next_blockquote = dom_get_indented_element (extension, document, width);
 
        /* Copy nodes that are before / after the element that we want to unindent */
        while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)))) {
@@ -1253,7 +1239,7 @@ unindent_block (WebKitDOMDocument *document,
 
        if (level == 1 && element_has_class (WEBKIT_DOM_ELEMENT (node_clone), "-x-evo-paragraph")) {
                dom_set_paragraph_style (
-                       document, WEBKIT_DOM_ELEMENT (node_clone), word_wrap_length, 0, "");
+                       extension, document, WEBKIT_DOM_ELEMENT (node_clone), word_wrap_length, 0, "");
                element_add_class (
                        WEBKIT_DOM_ELEMENT (node_clone),
                        get_css_alignment_value_class (alignment));
@@ -1288,7 +1274,8 @@ unindent_block (WebKitDOMDocument *document,
  * Unindents current paragraph by one level.
  */
 static void
-dom_unindent (WebKitDOMDocument *document)
+dom_unindent (EHTMLEditorWebExtension *extension,
+              WebKitDOMDocument *document)
 {
        gboolean after_selection_start = FALSE, after_selection_end = FALSE;
        WebKitDOMElement *selection_start_marker, *selection_end_marker;
@@ -1365,7 +1352,7 @@ dom_unindent (WebKitDOMDocument *document)
                                        goto next;
                        }
 
-                       unindent_block (document, block);
+                       unindent_block (extension, document, block);
 
                        if (after_selection_end)
                                goto next;
@@ -1388,7 +1375,7 @@ dom_unindent (WebKitDOMDocument *document)
                                        continue;
                        }
 
-                       unindent_block (document, block_to_process);
+                       unindent_block (extension, document, block_to_process);
 
                        if (after_selection_end)
                                break;
@@ -1399,10 +1386,11 @@ dom_unindent (WebKitDOMDocument *document)
        }
 
        dom_selection_restore (document);
-/* FIXME WK2
-       e_html_editor_view_force_spell_check_for_current_paragraph (view);
 
-       g_object_notify (G_OBJECT (selection), "indented"); */
+       dom_force_spell_check_for_current_paragraph (document);
+
+       /* FIXME XXX - Check if the block is still indented */
+       set_dbus_property_boolean (extension, "Indented", TRUE);
 }
 
 static WebKitDOMNode *
@@ -1909,30 +1897,28 @@ dom_scroll_to_caret (WebKitDOMDocument *document)
  * is selected, it will be replaced by @html_text.
  */
 static void
-dom_insert_html (WebKitDOMDocument *document,
+dom_insert_html (EHTMLEditorWebExtension *extension,
+                 WebKitDOMDocument *document,
                  const gchar *html_text)
 {
        g_return_if_fail (html_text != NULL);
 
-       if (is_in_html_mode (document)) {
+       if (e_html_editor_web_extension_get_html_mode (extension)) {
                dom_exec_command (
                        document, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, html_text);
 /* FIXME WK2
                e_html_editor_view_check_magic_links (view, FALSE);
-               e_html_editor_view_force_spell_check (view);
 */
+               dom_force_spell_check (document);
                dom_scroll_to_caret (document);
-       }
-/* FIXME WK2
-       else
-               e_html_editor_view_convert_and_insert_html_to_plain_text (
-                       view, html_text);
-*/
+       } else
+               dom_convert_and_insert_html_into_selection (document, extension, html_text, TRUE);
 }
 
 static WebKitDOMElement *
-wrap_lines (WebKitDOMNode *paragraph,
-           WebKitDOMDocument *document,
+wrap_lines (EHTMLEditorWebExtension *extension,
+            WebKitDOMDocument *document,
+            WebKitDOMNode *paragraph,
            gboolean remove_all_br,
            gint word_wrap_length)
 {
@@ -1950,11 +1936,10 @@ wrap_lines (WebKitDOMNode *paragraph,
        has_selection = !dom_selection_is_collapsed (document);
 
        if (has_selection) {
-               gchar *text_content;
+               const gchar *selection_content;
 
-               text_content = dom_selection_get_string (document);
-               paragraph_char_count = g_utf8_strlen (text_content, -1);
-               g_free (text_content);
+               selection_content = e_html_editor_web_extension_get_selection_text (extension);
+               paragraph_char_count = g_utf8_strlen (selection_content, -1);
 
                fragment = webkit_dom_range_clone_contents (
                        dom_get_current_range (document), NULL);
@@ -2303,7 +2288,7 @@ wrap_lines (WebKitDOMNode *paragraph,
                html = webkit_dom_html_element_get_inner_html (WEBKIT_DOM_HTML_ELEMENT (element));
 
                /* Overwrite the current selection be the processed content */
-               dom_insert_html (document, html);
+               dom_insert_html (extension, document, html);
 
                g_free (html);
 
@@ -2323,20 +2308,22 @@ wrap_lines (WebKitDOMNode *paragraph,
 }
 
 static WebKitDOMElement *
-dom_get_paragraph_element (WebKitDOMDocument *document,
+dom_get_paragraph_element (EHTMLEditorWebExtension *extension,
+                           WebKitDOMDocument *document,
                            gint width,
                            gint offset)
 {
        WebKitDOMElement *element;
 
        element = webkit_dom_document_create_element (document, "DIV", NULL);
-       dom_set_paragraph_style (document, element, width, offset, "");
+       dom_set_paragraph_style (extension, document, element, width, offset, "");
 
        return element;
 }
 
 static WebKitDOMElement *
-dom_put_node_into_paragraph (WebKitDOMDocument *document,
+dom_put_node_into_paragraph (EHTMLEditorWebExtension *extension,
+                             WebKitDOMDocument *document,
                              WebKitDOMNode *node,
                              WebKitDOMNode *caret_position)
 {
@@ -2344,7 +2331,7 @@ dom_put_node_into_paragraph (WebKitDOMDocument *document,
        WebKitDOMElement *container;
 
        range = webkit_dom_document_create_range (document);
-       container = dom_get_paragraph_element (document, -1, 0);
+       container = dom_get_paragraph_element (extension, document, -1, 0);
        webkit_dom_range_select_node (range, node, NULL);
        webkit_dom_range_surround_contents (range, WEBKIT_DOM_NODE (container), NULL);
        /* We have to move caret position inside this container */
@@ -2359,13 +2346,17 @@ dom_put_node_into_paragraph (WebKitDOMDocument *document,
  *
  * Wraps all lines in current selection to be 71 characters long.
  */
-#if 0
-void
-dom_wrap_lines (WebKitDOMDocument *document)
+
+static void
+dom_wrap_lines (EHTMLEditorWebExtension *extension,
+                WebKitDOMDocument *document)
 {
+       gint word_wrap_length;
        WebKitDOMRange *range;
        WebKitDOMElement *active_paragraph, *caret;
 
+       word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
+
        caret = dom_save_caret_position (document);
        if (dom_selection_is_collapsed (document)) {
                WebKitDOMNode *end_container;
@@ -2408,7 +2399,9 @@ dom_wrap_lines (WebKitDOMDocument *document)
                                        if (WEBKIT_DOM_IS_TEXT (paragraph))
                                                paragraph = WEBKIT_DOM_NODE (
                                                        dom_put_node_into_paragraph (
-                                                               selection, document, paragraph,
+                                                               extension,
+                                                               document,
+                                                               paragraph,
                                                                WEBKIT_DOM_NODE (caret)));
                                } else {
                                        /* When some weird element is selected, return */
@@ -2455,16 +2448,13 @@ dom_wrap_lines (WebKitDOMDocument *document)
                g_free (text_content);
 
                wrap_lines (
-                       NULL, paragraph, document, FALSE,
-                       selection->priv->word_wrap_length);
+                       extension, document, paragraph, FALSE, word_wrap_length);
 
        } else {
                dom_save_caret_position (document);
                /* If we have selection -> wrap it */
                wrap_lines (
-                       selection, NULL, document, FALSE,
-                       selection->priv->word_wrap_length);
-       }
+                       extension, document, NULL, FALSE, word_wrap_length); }
 
        active_paragraph = webkit_dom_document_get_element_by_id (
                document, "-x-evo-active-paragraph");
@@ -2476,16 +2466,17 @@ dom_wrap_lines (WebKitDOMDocument *document)
                webkit_dom_element_remove_attribute (
                        WEBKIT_DOM_ELEMENT (active_paragraph), "id");
 }
-#endif
+
 static WebKitDOMElement *
-dom_wrap_paragraph_length (WebKitDOMDocument *document,
+dom_wrap_paragraph_length (EHTMLEditorWebExtension *extension,
+                           WebKitDOMDocument *document,
                            WebKitDOMElement *paragraph,
                            gint length)
 {
        g_return_val_if_fail (WEBKIT_DOM_IS_ELEMENT (paragraph), NULL);
        g_return_val_if_fail (length >= MINIMAL_PARAGRAPH_WIDTH, NULL);
 
-       return wrap_lines (WEBKIT_DOM_NODE (paragraph), document, FALSE, length);
+       return wrap_lines (extension, document, WEBKIT_DOM_NODE (paragraph), FALSE, length);
 }
 
 static gint
@@ -2506,7 +2497,8 @@ get_citation_level (WebKitDOMNode *node)
 }
 
 static void
-dom_wrap_paragraphs_in_document (WebKitDOMDocument *document)
+dom_wrap_paragraphs_in_document (EHTMLEditorWebExtension *extension,
+                                 WebKitDOMDocument *document)
 {
        WebKitDOMNodeList *list;
        gint ii, length;
@@ -2517,34 +2509,36 @@ dom_wrap_paragraphs_in_document (WebKitDOMDocument *document)
        length = webkit_dom_node_list_get_length (list);
 
        for (ii = 0; ii < length; ii++) {
-               gint quote, citation_level;
+               gint word_wrap_length, quote, citation_level;
                WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
 
                citation_level = get_citation_level (node);
                quote = citation_level ? citation_level * 2 : 0;
+               word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
 
                if (node_is_list (node)) {
                        WebKitDOMNode *item = webkit_dom_node_get_first_child (node);
 
                        while (item && WEBKIT_DOM_IS_HTML_LI_ELEMENT (item)) {
                                dom_wrap_paragraph_length (
-                                       document, WEBKIT_DOM_ELEMENT (item), WORD_WRAP_LENGTH - quote);
+                                       extension, document, WEBKIT_DOM_ELEMENT (item), word_wrap_length - 
quote);
                                item = webkit_dom_node_get_next_sibling (item);
                        }
                } else {
                        dom_wrap_paragraph_length (
-                               document, WEBKIT_DOM_ELEMENT (node), WORD_WRAP_LENGTH - quote);
+                               extension, document, WEBKIT_DOM_ELEMENT (node), word_wrap_length - quote);
                }
        }
        g_object_unref (list);
 }
 
 static WebKitDOMElement *
-dom_wrap_paragraph (WebKitDOMDocument *document,
+dom_wrap_paragraph (EHTMLEditorWebExtension *extension,
+                    WebKitDOMDocument *document,
                     WebKitDOMElement *paragraph)
 {
        gint indentation_level, citation_level, quote;
-       gint final_width, offset = 0;
+       gint word_wrap_length, final_width, offset = 0;
 
        g_return_val_if_fail (WEBKIT_DOM_IS_ELEMENT (paragraph), NULL);
 
@@ -2563,11 +2557,12 @@ dom_wrap_paragraph (WebKitDOMDocument *document,
 
        quote = citation_level ? citation_level * 2 : 0;
 
-       final_width = WORD_WRAP_LENGTH - quote + offset;
+       word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
+       final_width = word_wrap_length - quote + offset;
        final_width -= SPACES_PER_INDENTATION * indentation_level;
 
        return dom_wrap_paragraph_length (
-               document, WEBKIT_DOM_ELEMENT (paragraph), final_width);
+               extension, document, WEBKIT_DOM_ELEMENT (paragraph), final_width);
 }
 
 static void
@@ -2676,7 +2671,8 @@ get_has_style (WebKitDOMDocument *document,
  * Returns @TRUE when selection is underlined, @FALSE otherwise.
  */
 gboolean
-dom_selection_is_underline (WebKitDOMDocument *document)
+dom_selection_is_underline (WebKitDOMDocument *document,
+                            EHTMLEditorWebExtension *extension)
 {
        gboolean ret_val;
        gchar *value, *text_content;
@@ -2698,9 +2694,7 @@ dom_selection_is_underline (WebKitDOMDocument *document)
        text_content = webkit_dom_node_get_text_content (node);
        if (g_strcmp0 (text_content, "") == 0) {
                g_free (text_content);
-               return FALSE;
-/* FIXME WK2
-               return selection->priv->is_underline;*/
+               return e_html_editor_web_extension_get_underline (extension);
        }
        g_free (text_content);
 
@@ -2731,17 +2725,15 @@ dom_selection_is_underline (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_underline (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension,
                              gboolean underline)
 {
-       if (dom_selection_is_underline (document) == underline)
+       if (dom_selection_is_underline (document, extension) == underline)
                return;
 
-//     selection->priv->is_underline = underline;
-
        dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_UNDERLINE, NULL);
 
-/* FIXME WK2
-       g_object_notify (G_OBJECT (selection), "underline"); */
+       set_dbus_property_boolean (extension, "Underline", underline);
 }
 
 /**
@@ -2754,7 +2746,8 @@ dom_selection_set_underline (WebKitDOMDocument *document,
  * Returns @TRUE when selection is in subscript, @FALSE otherwise.
  */
 gboolean
-dom_selection_is_subscript (WebKitDOMDocument *document)
+dom_selection_is_subscript (WebKitDOMDocument *document,
+                            EHTMLEditorWebExtension *extension)
 {
        WebKitDOMNode *node;
        WebKitDOMRange *range;
@@ -2789,9 +2782,10 @@ dom_selection_is_subscript (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_subscript (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension,
                              gboolean subscript)
 {
-       if (dom_selection_is_subscript (document) == subscript)
+       if (dom_selection_is_subscript (document, extension) == subscript)
                return;
 
        dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_SUBSCRIPT, NULL);
@@ -2811,7 +2805,8 @@ dom_selection_set_subscript (WebKitDOMDocument *document,
  * Returns @TRUE when selection is in superscript, @FALSE otherwise.
  */
 gboolean
-dom_selection_is_superscript (WebKitDOMDocument *document)
+dom_selection_is_superscript (WebKitDOMDocument *document,
+                              EHTMLEditorWebExtension *extension)
 {
        WebKitDOMNode *node;
        WebKitDOMRange *range;
@@ -2846,9 +2841,10 @@ dom_selection_is_superscript (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_superscript (WebKitDOMDocument *document,
+                               EHTMLEditorWebExtension *extension,
                                gboolean superscript)
 {
-       if (dom_selection_is_superscript (document) == superscript)
+       if (dom_selection_is_superscript (document, extension) == superscript)
                return;
 
        dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_SUPERSCRIPT, NULL);
@@ -2868,7 +2864,8 @@ dom_selection_set_superscript (WebKitDOMDocument *document,
  * Returns @TRUE when selection is striked through, @FALSE otherwise.
  */
 gboolean
-dom_selection_is_strikethrough (WebKitDOMDocument *document)
+dom_selection_is_strikethrough (WebKitDOMDocument *document,
+                                EHTMLEditorWebExtension *extension)
 {
        gboolean ret_val;
        gchar *value, *text_content;
@@ -2889,9 +2886,7 @@ dom_selection_is_strikethrough (WebKitDOMDocument *document)
        text_content = webkit_dom_node_get_text_content (node);
        if (g_strcmp0 (text_content, "") == 0) {
                g_free (text_content);
-               return FALSE;
-/* FIXME WK2
-               return selection->priv->is_strikethrough; */
+               return e_html_editor_web_extension_get_strikethrough (extension);
        }
        g_free (text_content);
 
@@ -2922,9 +2917,10 @@ dom_selection_is_strikethrough (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_strikethrough (WebKitDOMDocument *document,
+                                 EHTMLEditorWebExtension *extension,
                                  gboolean strikethrough)
 {
-       if (dom_selection_is_strikethrough (document) == strikethrough)
+       if (dom_selection_is_strikethrough (document, extension) == strikethrough)
                return;
 /* FIXME WK2
        selection->priv->is_strikethrough = strikethrough;
@@ -2968,7 +2964,8 @@ is_monospaced_element (WebKitDOMElement *element)
  * Returns @TRUE when selection is monospaced, @FALSE otherwise.
  */
 gboolean
-dom_selection_is_monospaced (WebKitDOMDocument *document)
+dom_selection_is_monospaced (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension)
 {
        gboolean ret_val;
        gchar *value, *text_content;
@@ -3022,13 +3019,15 @@ dom_selection_is_monospaced (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_monospaced (WebKitDOMDocument *document,
+                              EHTMLEditorWebExtension *extension,
                               gboolean monospaced)
 {
+       guint font_size = 0;
        WebKitDOMRange *range;
        WebKitDOMDOMWindow *window;
        WebKitDOMDOMSelection *window_selection;
 
-       if (dom_selection_is_monospaced (document) == monospaced)
+       if (dom_selection_is_monospaced (document, extension) == monospaced)
                return;
 /* FIXME WK2
        selection->priv->is_monospaced = monospaced;
@@ -3037,22 +3036,21 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
        if (!range)
                return;
 
+       font_size = e_html_editor_web_extension_get_font_size (extension);
+       if (font_size == 0)
+               font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+
        window = webkit_dom_document_get_default_view (document);
        window_selection = webkit_dom_dom_window_get_selection (window);
 
        if (monospaced) {
                gchar *font_size_str;
-               guint font_size = 0;
                WebKitDOMElement *monospace;
 
                monospace = webkit_dom_document_create_element (
                        document, "font", NULL);
                webkit_dom_element_set_attribute (
                        monospace, "face", "monospace", NULL);
-/* FIXME WK2
-               font_size = selection->priv->font_size; */
-               if (font_size == 0)
-                       font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
                font_size_str = g_strdup_printf ("%d", font_size);
                webkit_dom_element_set_attribute (
                        monospace, "size", font_size_str, NULL);
@@ -3078,7 +3076,7 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
                                "<span id=\"-x-evo-selection-end-marker\"></span>",
                                NULL),
 
-                       dom_insert_html (document, html);
+                       dom_insert_html (extension, document, html);
 
                        dom_selection_restore (document);
 
@@ -3114,14 +3112,10 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
                }
 
                /* Save current formatting */
-/* FIXME WK2
-               is_bold = selection->priv->is_bold;
-               is_italic = selection->priv->is_italic;
-               is_underline = selection->priv->is_underline;
-               is_strikethrough = selection->priv->is_strikethrough;
-               font_size = selection->priv->font_size;*/
-               if (font_size == 0)
-                       font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+               is_bold = e_html_editor_web_extension_get_bold (extension);
+               is_italic = e_html_editor_web_extension_get_italic (extension);
+               is_underline = e_html_editor_web_extension_get_underline (extension);
+               is_strikethrough = e_html_editor_web_extension_get_strikethrough (extension);
 
                if (!dom_selection_is_collapsed (document)) {
                        gchar *html, *outer_html, *inner_html, *beginning, *end;
@@ -3221,22 +3215,21 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
 
                        g_free (outer_html);
                        g_free (tmp);
-/* FIXME WK2
-                       e_html_editor_view_force_spell_check_for_current_paragraph (
-                               view);*/
+
+                       dom_force_spell_check_for_current_paragraph (document);
                }
 
                /* Re-set formatting */
                if (is_bold)
-                       dom_selection_set_bold (document, TRUE);
+                       dom_selection_set_bold (document, extension, TRUE);
                if (is_italic)
-                       dom_selection_set_italic (document, TRUE);
+                       dom_selection_set_italic (document, extension, TRUE);
                if (is_underline)
-                       dom_selection_set_underline (document, TRUE);
+                       dom_selection_set_underline (document, extension, TRUE);
                if (is_strikethrough)
-                       dom_selection_set_strikethrough (document, TRUE);
+                       dom_selection_set_strikethrough (document, extension, TRUE);
 
-               dom_selection_set_font_size (document, font_size);
+               dom_selection_set_font_size (document, extension, font_size);
        }
 /* FIXME WK2
        g_object_notify (G_OBJECT (selection), "monospaced");*/
@@ -3252,7 +3245,8 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
  * Returns @TRUE when selection is bold, @FALSE otherwise.
  */
 gboolean
-dom_selection_is_bold (WebKitDOMDocument *document)
+dom_selection_is_bold (WebKitDOMDocument *document,
+                       EHTMLEditorWebExtension *extension)
 {
        gboolean ret_val;
        gchar *value, *text_content;
@@ -3274,9 +3268,7 @@ dom_selection_is_bold (WebKitDOMDocument *document)
        text_content = webkit_dom_node_get_text_content (node);
        if (g_strcmp0 (text_content, "") == 0) {
                g_free (text_content);
-               return FALSE;
-/* FIXME WK2
-               return selection->priv->is_bold;*/
+               return e_html_editor_web_extension_get_bold (extension);
        }
        g_free (text_content);
 
@@ -3307,9 +3299,10 @@ dom_selection_is_bold (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_bold (WebKitDOMDocument *document,
+                        EHTMLEditorWebExtension *extension,
                         gboolean bold)
 {
-       if (dom_selection_is_bold (document) == bold)
+       if (dom_selection_is_bold (document, extension) == bold)
                return;
 /* FIXME WK2
        selection->priv->is_bold = bold; */
@@ -3329,7 +3322,8 @@ dom_selection_set_bold (WebKitDOMDocument *document,
  * Returns @TRUE when selection is italic, @FALSE otherwise.
  */
 gboolean
-dom_selection_is_italic (WebKitDOMDocument *document)
+dom_selection_is_italic (WebKitDOMDocument *document,
+                         EHTMLEditorWebExtension *extension)
 {
        gboolean ret_val;
        gchar *value, *text_content;
@@ -3351,9 +3345,7 @@ dom_selection_is_italic (WebKitDOMDocument *document)
        text_content = webkit_dom_node_get_text_content (node);
        if (g_strcmp0 (text_content, "") == 0) {
                g_free (text_content);
-               return FALSE;
-/* FIXME WK2
-               return selection->priv->is_italic;*/
+               return e_html_editor_web_extension_get_italic (extension);
        }
        g_free (text_content);
 
@@ -3384,9 +3376,10 @@ dom_selection_is_italic (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_italic (WebKitDOMDocument *document,
+                          EHTMLEditorWebExtension *extension,
                           gboolean italic)
 {
-       if (dom_selection_is_italic (document) == italic)
+       if (dom_selection_is_italic (document, extension) == italic)
                return;
 /* FIXME WK2
        selection->priv->is_italic = italic;*/
@@ -3520,8 +3513,9 @@ get_font_property (WebKitDOMDocument *document,
  *
  * Returns point size of current selection or of letter at current cursor position.
  */
- guint
-dom_selection_get_font_size (WebKitDOMDocument *document)
+guint
+dom_selection_get_font_size (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension)
 {
        gchar *size;
        guint size_int;
@@ -3549,6 +3543,7 @@ dom_selection_get_font_size (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_font_size (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension,
                              guint font_size)
 {
        gchar *size_str;
@@ -3572,6 +3567,7 @@ dom_selection_set_font_size (WebKitDOMDocument *document,
  */
 void
 dom_selection_set_font_name (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension,
                              const gchar *font_name)
 {
        dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_FONT_NAME, font_name);
@@ -3589,7 +3585,8 @@ dom_selection_set_font_name (WebKitDOMDocument *document,
  * Returns: A string with font name. [transfer-none]
  */
 gchar *
-dom_selection_get_font_name (WebKitDOMDocument *document)
+dom_selection_get_font_name (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension)
 {
        WebKitDOMNode *node;
        WebKitDOMRange *range;
@@ -3618,6 +3615,7 @@ dom_selection_get_font_name (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_font_color (WebKitDOMDocument *document,
+                              EHTMLEditorWebExtension *extension,
                               const gchar *color)
 {
 /* FIXME WK2
@@ -3637,7 +3635,8 @@ dom_selection_set_font_color (WebKitDOMDocument *document,
  * cursor position.
  */
 gchar *
-dom_selection_get_font_color (WebKitDOMDocument *document)
+dom_selection_get_font_color (WebKitDOMDocument *document,
+                              EHTMLEditorWebExtension *extension)
 {
        gchar *color;
 
@@ -3673,7 +3672,8 @@ get_block_node (WebKitDOMRange *range)
  * Returns: #EHTMLEditorSelectionBlockFormat
  */
 EHTMLEditorSelectionBlockFormat
-dom_selection_get_block_format (WebKitDOMDocument *document)
+dom_selection_get_block_format (WebKitDOMDocument *document,
+                                EHTMLEditorWebExtension *extension)
 {
        WebKitDOMNode *node;
        WebKitDOMRange *range;
@@ -3814,6 +3814,7 @@ is_citation_node (WebKitDOMNode *node)
 
 static gboolean
 process_block_to_block (WebKitDOMDocument *document,
+                        EHTMLEditorWebExtension *extension,
                         EHTMLEditorSelectionBlockFormat format,
                        const gchar *value,
                         WebKitDOMNode *block,
@@ -3836,6 +3837,7 @@ process_block_to_block (WebKitDOMDocument *document,
                        next_block = webkit_dom_node_get_next_sibling (block);
                        finished = process_block_to_block (
                                document,
+                               extension,
                                format,
                                value,
                                webkit_dom_node_get_first_child (block),
@@ -3864,7 +3866,7 @@ process_block_to_block (WebKitDOMDocument *document,
                next_block = webkit_dom_node_get_next_sibling (block);
 
                if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH)
-                       element = dom_get_paragraph_element (document, -1, 0);
+                       element = dom_get_paragraph_element (extension, document, -1, 0);
                else
                        element = webkit_dom_document_create_element (
                                document, value, NULL);
@@ -3913,18 +3915,25 @@ process_block_to_block (WebKitDOMDocument *document,
                block = next_block;
 
                if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH && !html_mode) {
-                       gint citation_level, quote;
+                       gint citation_level;
 
                        citation_level = get_citation_level (WEBKIT_DOM_NODE (element));
-                       quote = citation_level ? citation_level * 2 : 0;
 
-                       if (citation_level > 0)
+                       if (citation_level > 0) {
+                               gint quote, word_wrap_length;
+
+                               word_wrap_length =
+                                       e_html_editor_web_extension_get_word_wrap_length (extension);
+                               quote = citation_level ? citation_level * 2 : 0;
+
                                element = dom_wrap_paragraph_length (
-                                       document, element, WORD_WRAP_LENGTH - quote);
+                                       extension, document, element, word_wrap_length - quote);
+
+                       }
                }
-/* FIXME WK2
+
                if (quoted)
-                       e_html_editor_view_quote_plain_text_element (view, element);*/
+                       dom_quote_plain_text_element (document, element);
        }
 
        return after_selection_end;
@@ -3932,6 +3941,7 @@ process_block_to_block (WebKitDOMDocument *document,
 
 static void
 format_change_block_to_block (WebKitDOMDocument *document,
+                              EHTMLEditorWebExtension *extension,
                               EHTMLEditorSelectionBlockFormat format,
                               const gchar *value)
 {
@@ -3966,18 +3976,18 @@ format_change_block_to_block (WebKitDOMDocument *document,
        end_block = get_parent_block_node_from_child (
                WEBKIT_DOM_NODE (selection_end_marker));
 
-/* FIXME WK2
-       html_mode = e_html_editor_view_get_html_mode (view);
-*/
+       html_mode = e_html_editor_web_extension_get_html_mode (extension);
+
        /* Process all blocks that are in the selection one by one */
        process_block_to_block (
-               document, format, value, block, end_block, html_mode);
+               document, extension, format, value, block, end_block, html_mode);
 
        dom_selection_restore (document);
 }
 
 static void
 format_change_block_to_list (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension,
                              EHTMLEditorSelectionBlockFormat format)
 {
        gboolean after_selection_end = FALSE, in_quote = FALSE;
@@ -4012,7 +4022,7 @@ format_change_block_to_list (WebKitDOMDocument *document,
        block = get_parent_block_node_from_child (
                WEBKIT_DOM_NODE (selection_start_marker));
 
-       list = create_list_element (document, format, 0, html_mode);
+       list = create_list_element (extension, document, format, 0, html_mode);
 
        if (webkit_dom_element_query_selector (
                WEBKIT_DOM_ELEMENT (block), "span.-x-evo-quoted", NULL)) {
@@ -4139,6 +4149,7 @@ get_list_node_from_child (WebKitDOMNode *child)
 
 static void
 format_change_list_from_list (WebKitDOMDocument *document,
+                              EHTMLEditorWebExtension *extension,
                               EHTMLEditorSelectionBlockFormat to,
                               gboolean html_mode)
 {
@@ -4154,7 +4165,7 @@ format_change_list_from_list (WebKitDOMDocument *document,
        if (!selection_start_marker || !selection_end_marker)
                return;
 
-       new_list = create_list_element (document, to, 0, html_mode);
+       new_list = create_list_element (extension, document, to, 0, html_mode);
 
        /* Copy elements from previous block to list */
        item = get_list_item_node_from_child (
@@ -4208,6 +4219,7 @@ format_change_list_from_list (WebKitDOMDocument *document,
 
 static void
 format_change_list_to_list (WebKitDOMDocument *document,
+                            EHTMLEditorWebExtension *extension,
                             EHTMLEditorSelectionBlockFormat format,
                             gboolean html_mode)
 {
@@ -4246,7 +4258,7 @@ format_change_list_to_list (WebKitDOMDocument *document,
        indented = element_has_class (WEBKIT_DOM_ELEMENT (current_list), "-x-evo-indented");
 
        if (!prev_list || !next_list || indented) {
-               format_change_list_from_list (document, format, html_mode);
+               format_change_list_from_list (document, extension, format, html_mode);
                goto out;
        }
 
@@ -4260,7 +4272,7 @@ format_change_list_to_list (WebKitDOMDocument *document,
                                webkit_dom_node_get_parent_node (
                                        WEBKIT_DOM_NODE (selection_end_marker))));
                if (!prev_list || !next_list) {
-                       format_change_list_from_list (document, format, html_mode);
+                       format_change_list_from_list (document, extension, format, html_mode);
                        goto out;
                }
        }
@@ -4285,13 +4297,14 @@ format_change_list_to_list (WebKitDOMDocument *document,
        if (done)
                goto out;
 
-       format_change_list_from_list (document, format, html_mode);
+       format_change_list_from_list (document, extension, format, html_mode);
 out:
        dom_selection_restore (document);
 }
 
 static void
 format_change_list_to_block (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension,
                              EHTMLEditorSelectionBlockFormat format,
                              const gchar *value)
 {
@@ -4327,7 +4340,7 @@ format_change_list_to_block (WebKitDOMDocument *document,
 
                if (!after_end) {
                        if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH)
-                               element = dom_get_paragraph_element (document, -1, 0);
+                               element = dom_get_paragraph_element (extension, document, -1, 0);
                        else
                                element = webkit_dom_document_create_element (
                                        document, value, NULL);
@@ -4373,6 +4386,7 @@ format_change_list_to_block (WebKitDOMDocument *document,
  */
 void
 dom_selection_set_block_format (WebKitDOMDocument *document,
+                                EHTMLEditorWebExtension *extension,
                                 EHTMLEditorSelectionBlockFormat format)
 {
        EHTMLEditorSelectionBlockFormat current_format;
@@ -4380,7 +4394,7 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
        gboolean from_list = FALSE, to_list = FALSE, html_mode = FALSE;
        WebKitDOMRange *range;
 
-       current_format = dom_selection_get_block_format (document);
+       current_format = dom_selection_get_block_format (document, extension);
        if (current_format == format) {
                return;
        }
@@ -4433,12 +4447,11 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
        }
 
        /* H1 - H6 have bold font by default */
-/* FIXME WK2
        if (format >= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H1 &&
            format <= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H6)
-               selection->priv->is_bold = TRUE;*/
-/* FIXME WK2
-       html_mode = e_html_editor_view_get_html_mode (view);*/
+               set_dbus_property_boolean (extension, "Bold", TRUE);
+
+       html_mode = e_html_editor_web_extension_get_html_mode (extension);
 
        from_list =
                current_format >= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST;
@@ -4448,26 +4461,25 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
                return;
 
        if (from_list && to_list)
-               format_change_list_to_list (document, format, html_mode);
+               format_change_list_to_list (document, extension, format, html_mode);
 
        if (!from_list && !to_list)
-               format_change_block_to_block (document, format, value);
+               format_change_block_to_block (document, extension, format, value);
 
        if (from_list && !to_list)
-               format_change_list_to_block (document, format, value);
+               format_change_list_to_block (document, extension, format, value);
 
        if (!from_list && to_list)
-               format_change_block_to_list (document, format);
-/* FIXME WK2
-       e_html_editor_view_force_spell_check_for_current_paragraph (view);
-*/
+               format_change_block_to_list (document, extension, format);
 
-       /* When changing the format we need to re-set the alignment */
-/* FIXME WK2
-       dom_selection_set_alignment (document, selection->priv->alignment);
+       dom_force_spell_check_for_current_paragraph (document);
 
-       e_html_editor_view_set_changed (view, TRUE);
+       /* When changing the format we need to re-set the alignment */
+       dom_selection_set_alignment (
+               document, extension, e_html_editor_web_extension_get_alignment (extension));
 
+       e_html_editor_web_extension_set_content_changed (extension);
+/*
        g_object_notify (G_OBJECT (selection), "block-format");*/
 }
 
@@ -4481,7 +4493,8 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
  * Returns: A string with code of current background color.
  */
 gchar *
-dom_selection_get_background_color (WebKitDOMDocument *document)
+dom_selection_get_background_color (WebKitDOMDocument *document,
+                                    EHTMLEditorWebExtension *extension)
 {
        WebKitDOMNode *ancestor;
        WebKitDOMRange *range;
@@ -4511,6 +4524,7 @@ dom_selection_get_background_color (WebKitDOMDocument *document)
  */
 void
 dom_selection_set_background_color (WebKitDOMDocument *document,
+                                    EHTMLEditorWebExtension *extension,
                                     const gchar *color)
 {
        dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_BACKGROUND_COLOR, color);
@@ -4527,7 +4541,8 @@ dom_selection_set_background_color (WebKitDOMDocument *document,
  * Returns: #EHTMLEditorSelectionAlignment
  */
 EHTMLEditorSelectionAlignment
-dom_selection_get_alignment (WebKitDOMDocument *document)
+dom_selection_get_alignment (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension)
 {
        EHTMLEditorSelectionAlignment alignment;
        gchar *value;
@@ -4597,6 +4612,7 @@ set_block_alignment (WebKitDOMElement *element,
  */
 void
 dom_selection_set_alignment (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension,
                              EHTMLEditorSelectionAlignment alignment)
 {
        gboolean after_selection_end = FALSE;
@@ -4604,7 +4620,7 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
        WebKitDOMElement *selection_start_marker, *selection_end_marker;
        WebKitDOMNode *block;
 
-       if (dom_selection_get_alignment (document) == alignment)
+       if (dom_selection_get_alignment (document, extension) == alignment)
                return;
 
        switch (alignment) {
@@ -4695,9 +4711,10 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
        }
 
        dom_selection_restore (document);
-/* FIXME WK2
-       e_html_editor_view_force_spell_check_for_current_paragraph (view);
 
+       dom_force_spell_check_for_current_paragraph (document);
+
+/* FIXME WK2
        g_object_notify (G_OBJECT (selection), "alignment");*/
 }
 
@@ -4709,9 +4726,11 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
  * Replaces currently selected text with @replacement.
  */
 void
-dom_selection_replace (WebKitDOMDocument *document,
+dom_selection_replace (EHTMLEditorWebExtension *extension,
+                       WebKitDOMDocument *document,
                        const gchar *replacement)
 {
+       e_html_editor_web_extension_set_content_changed (extension);
        dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT, replacement);
 }
 
@@ -4723,7 +4742,8 @@ dom_selection_replace (WebKitDOMDocument *document,
  * Replaces current word under cursor with @replacement.
  */
 void
-dom_replace_caret_word (WebKitDOMDocument *document,
+dom_replace_caret_word (EHTMLEditorWebExtension *extension,
+                        WebKitDOMDocument *document,
                         const gchar *replacement)
 {
        WebKitDOMDOMWindow *window;
@@ -4733,11 +4753,12 @@ dom_replace_caret_word (WebKitDOMDocument *document,
        window = webkit_dom_document_get_default_view (document);
        dom_selection = webkit_dom_dom_window_get_selection (window);
 
+       e_html_editor_web_extension_set_content_changed (extension);
        range = dom_get_current_range (document);
        webkit_dom_range_expand (range, "word", NULL);
        webkit_dom_dom_selection_add_range (dom_selection, range);
 
-       dom_insert_html (document, replacement);
+       dom_insert_html (extension, document, replacement);
 }
 
 /**
diff --git a/e-util/e-html-editor-selection-dom-functions.h b/e-util/e-html-editor-selection-dom-functions.h
index 945f20b..b513f92 100644
--- a/e-util/e-html-editor-selection-dom-functions.h
+++ b/e-util/e-html-editor-selection-dom-functions.h
@@ -21,6 +21,8 @@
 
 #include <webkitdom/webkitdom.h>
 
+#include "web-extensions/e-html-editor-web-extension.h"
+
 #include "e-util-enums.h"
 
 G_BEGIN_DECLS
@@ -31,8 +33,7 @@ void          dom_replace_base64_image_src    (WebKitDOMDocument *document,
                                                 const gchar *filename,
                                                 const gchar *uri);
 
-void           dom_clear_caret_position_marker
-                                               (WebKitDOMDocument *document);
+void           dom_clear_caret_position_marker (WebKitDOMDocument *document);
 
 WebKitDOMNode *
                dom_create_caret_position_node  (WebKitDOMDocument *document);
@@ -40,7 +41,8 @@ WebKitDOMNode *
 WebKitDOMRange *
                dom_get_current_range           (WebKitDOMDocument *document);
 */
-gchar *                dom_selection_get_string        (WebKitDOMDocument *document);
+gchar *                dom_selection_get_string        (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 WebKitDOMElement *
                dom_save_caret_position         (WebKitDOMDocument *document);
@@ -59,83 +61,111 @@ void               dom_selection_save              (WebKitDOMDocument *document);
 
 void           dom_selection_restore           (WebKitDOMDocument *document);
 
-gboolean       dom_selection_is_underline      (WebKitDOMDocument *document);
+gboolean       dom_selection_is_underline      (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_underline     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 gboolean underline);
 
-gboolean       dom_selection_is_subscript      (WebKitDOMDocument *document);
+gboolean       dom_selection_is_subscript      (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_subscript     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 gboolean subscript);
 
-gboolean       dom_selection_is_superscript    (WebKitDOMDocument *document);
+gboolean       dom_selection_is_superscript    (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_superscript   (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 gboolean superscript);
 
-gboolean       dom_selection_is_strikethrough  (WebKitDOMDocument *document);
+gboolean       dom_selection_is_strikethrough  (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_strikethrough (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 gboolean strikethrough);
 
-gboolean       dom_selection_is_monospaced     (WebKitDOMDocument *document);
+gboolean       dom_selection_is_monospaced     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_monospaced    (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 gboolean monospaced);
 
-gboolean       dom_selection_is_bold           (WebKitDOMDocument *document);
+gboolean       dom_selection_is_bold           (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_bold          (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 gboolean bold);
 
-gboolean       dom_selection_is_italic         (WebKitDOMDocument *document);
+gboolean       dom_selection_is_italic         (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_italic        (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 gboolean italic);
 
 gboolean       dom_selection_is_indented       (WebKitDOMDocument *document);
 
 gboolean       dom_selection_is_citation       (WebKitDOMDocument *document);
 
-guint          dom_selection_get_font_size     (WebKitDOMDocument *document);
+guint          dom_selection_get_font_size     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_font_size     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 guint font_size);
 
-gchar *                dom_selection_get_font_name     (WebKitDOMDocument *document);
+gchar *                dom_selection_get_font_name     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_font_name     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 const gchar *font_size);
 
-gchar *                dom_selection_get_font_color    (WebKitDOMDocument *document);
+gchar *                dom_selection_get_font_color    (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_font_color    (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 const gchar *font_color);
 
 gchar *                dom_selection_get_background_color
-                                               (WebKitDOMDocument *document);
+                                               (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_background_color
                                                (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 const gchar *font_color);
 
 EHTMLEditorSelectionBlockFormat
-               dom_selection_get_block_format  (WebKitDOMDocument *document);
+               dom_selection_get_block_format  (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_block_format  (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 EHTMLEditorSelectionBlockFormat format);
 
 EHTMLEditorSelectionAlignment
-               dom_selection_get_alignment     (WebKitDOMDocument *document);
+               dom_selection_get_alignment     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_alignment     (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 EHTMLEditorSelectionAlignment alignment);
 
-void           dom_selection_replace           (WebKitDOMDocument *document,
+void           dom_selection_replace           (EHTMLEditorWebExtension *extension,
+                                                WebKitDOMDocument *document,
                                                 const gchar *replacement);
 
-void           dom_replace_caret_word          (WebKitDOMDocument *document,
+void           dom_replace_caret_word          (EHTMLEditorWebExtension *extension,
+                                                WebKitDOMDocument *document,
                                                 const gchar *replacement);
 
 gchar *                dom_get_caret_word              (WebKitDOMDocument *document);
diff --git a/e-util/e-html-editor-selection.c b/e-util/e-html-editor-selection.c
index b5f9250..d9bb798 100644
--- a/e-util/e-html-editor-selection.c
+++ b/e-util/e-html-editor-selection.c
@@ -718,14 +718,6 @@ e_html_editor_selection_init (EHTMLEditorSelection *selection)
        g_object_unref (g_settings);
 }
 
-gint
-e_html_editor_selection_get_word_wrap_length (EHTMLEditorSelection *selection)
-{
-       g_return_val_if_fail (E_IS_HTML_EDITOR_SELECTION (selection), 72);
-
-       return selection->priv->word_wrap_length;
-}
-
 /**
  * e_html_editor_selection_ref_html_editor_view:
  * @selection: an #EHTMLEditorSelection
@@ -854,7 +846,6 @@ e_html_editor_selection_replace_caret_word (EHTMLEditorSelection *selection,
        view = e_html_editor_selection_ref_html_editor_view (selection);
        g_return_if_fail (view != NULL);
 
-       e_html_editor_view_set_changed (view, TRUE);
        web_extension = e_html_editor_view_get_web_extension_proxy (view);
        if (!web_extension)
                goto out;
@@ -894,7 +885,6 @@ e_html_editor_selection_replace (EHTMLEditorSelection *selection,
        view = e_html_editor_selection_ref_html_editor_view (selection);
        g_return_if_fail (view != NULL);
 
-       e_html_editor_view_set_changed (view, TRUE);
        web_extension = e_html_editor_view_get_web_extension_proxy (view);
        if (!web_extension)
                goto out;
@@ -1261,7 +1251,7 @@ e_html_editor_selection_get_background_color (EHTMLEditorSelection *selection)
 
        g_free (selection->priv->background_color);
        selection->priv->background_color = g_strdup (
-               (html_editor_selection_get_format_string (selection, "font-family"));
+               html_editor_selection_get_format_string (selection, "font-family"));
 
        return selection->priv->background_color;
 }
@@ -1305,7 +1295,7 @@ e_html_editor_selection_get_font_name (EHTMLEditorSelection *selection)
 
        g_free (selection->priv->font_name);
        selection->priv->font_name = g_strdup (
-               html_editor_selection_get_format_string (selection, "font-family")_;
+               html_editor_selection_get_format_string (selection, "font-family"));
 
        return selection->priv->font_name;
 }
diff --git a/e-util/e-html-editor-view-dom-functions.c b/e-util/e-html-editor-view-dom-functions.c
index 4fcb4ad..f164c80 100644
--- a/e-util/e-html-editor-view-dom-functions.c
+++ b/e-util/e-html-editor-view-dom-functions.c
@@ -18,6 +18,9 @@
 
 #include "e-html-editor-view-dom-functions.h"
 
+#include "e-dom-utils.h"
+#include "e-html-editor-selection-dom-functions.h"
+
 /**
  * e_html_editor_view_dom_exec_command:
  * @document: a #WebKitDOMDocument
@@ -101,3 +104,4934 @@ dom_exec_command (WebKitDOMDocument *document,
        return webkit_dom_document_exec_command (
                document, cmd_str, FALSE, has_value ? value : "" );
 }
+
+static WebKitDOMElement *
+get_parent_block_element (WebKitDOMNode *node)
+{
+       WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
+
+       while (parent &&
+              !WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_HEADING_ELEMENT (parent) &&
+              !element_has_tag (parent, "address")) {
+               parent = webkit_dom_node_get_parent_element (
+                       WEBKIT_DOM_NODE (parent));
+       }
+
+       return parent;
+}
+
+void
+dom_force_spell_check_for_current_paragraph (WebKitDOMDocument *document)
+{
+       WebKitDOMDOMSelection *dom_selection;
+       WebKitDOMDOMWindow *window;
+       WebKitDOMElement *selection_start_marker, *selection_end_marker;
+       WebKitDOMElement *parent, *element;
+       WebKitDOMRange *end_range, *actual;
+       WebKitDOMText *text;
+
+       window = webkit_dom_document_get_default_view (document);
+       dom_selection = webkit_dom_dom_window_get_selection (window);
+
+       element = webkit_dom_document_query_selector (
+               document, "body[spellcheck=true]", NULL);
+
+       if (!element)
+               return;
+
+       dom_selection_save (document);
+
+       selection_start_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-start-marker", NULL);
+       selection_end_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-end-marker", NULL);
+
+       if (!selection_start_marker || !selection_end_marker)
+               return;
+
+       /* Block callbacks of selection-changed signal as we don't want to
+        * recount all the block format things in EHTMLEditorSelection and here as well
+        * when we are moving with caret */
+/* FIXME WK2
+       g_signal_handlers_block_by_func (
+               view, html_editor_view_selection_changed_cb, NULL);
+       e_html_editor_selection_block_selection_changed (selection);
+*/
+       parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_end_marker));
+
+       /* Append some text on the end of the element */
+       text = webkit_dom_document_create_text_node (document, "-x-evo-end");
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (parent),
+               WEBKIT_DOM_NODE (text),
+               NULL);
+
+       parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_start_marker));
+
+       /* Create range that's pointing on the end of this text */
+       end_range = webkit_dom_document_create_range (document);
+       webkit_dom_range_select_node_contents (
+               end_range, WEBKIT_DOM_NODE (text), NULL);
+       webkit_dom_range_collapse (end_range, FALSE, NULL);
+
+       /* Move on the beginning of the paragraph */
+       actual = webkit_dom_document_create_range (document);
+       webkit_dom_range_select_node_contents (
+               actual, WEBKIT_DOM_NODE (parent), NULL);
+       webkit_dom_range_collapse (actual, TRUE, NULL);
+       webkit_dom_dom_selection_remove_all_ranges (dom_selection);
+       webkit_dom_dom_selection_add_range (dom_selection, actual);
+
+       /* Go through all words to spellcheck them. To avoid this we have to wait for
+        * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
+       actual = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+       /* We are moving forward word by word until we hit the text on the end of
+        * the paragraph that we previously inserted there */
+       while (actual && webkit_dom_range_compare_boundary_points (end_range, 2, actual, NULL) != 0) {
+               webkit_dom_dom_selection_modify (
+                       dom_selection, "move", "forward", "word");
+               actual = webkit_dom_dom_selection_get_range_at (
+                       dom_selection, 0, NULL);
+       }
+
+       /* Remove the text that we inserted on the end of the paragraph */
+       remove_node (WEBKIT_DOM_NODE (text));
+
+       /* Unblock the callbacks */
+/* FIXME WK2
+       g_signal_handlers_unblock_by_func (
+               view, html_editor_view_selection_changed_cb, NULL);
+       e_html_editor_selection_unblock_selection_changed (selection);
+*/
+       do_selection_restore (document);
+}
+
+static WebKitDOMElement *
+create_selection_marker (WebKitDOMDocument *document,
+                         gboolean start)
+{
+       WebKitDOMElement *element;
+
+       element = webkit_dom_document_create_element (
+               document, "SPAN", NULL);
+       webkit_dom_element_set_id (
+               element,
+               start ? "-x-evo-selection-start-marker" :
+                       "-x-evo-selection-end-marker");
+
+       return element;
+}
+
+static void
+add_selection_markers_into_element_start (WebKitDOMDocument *document,
+                                          WebKitDOMElement *element,
+                                          WebKitDOMElement **selection_start_marker,
+                                          WebKitDOMElement **selection_end_marker)
+{
+       WebKitDOMElement *marker;
+
+       marker = create_selection_marker (document, FALSE);
+       webkit_dom_node_insert_before (
+               WEBKIT_DOM_NODE (element),
+               WEBKIT_DOM_NODE (marker),
+               webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
+               NULL);
+       if (selection_end_marker)
+               *selection_end_marker = marker;
+
+       marker = create_selection_marker (document, TRUE);
+       webkit_dom_node_insert_before (
+               WEBKIT_DOM_NODE (element),
+               WEBKIT_DOM_NODE (marker),
+               webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
+               NULL);
+       if (selection_start_marker)
+               *selection_start_marker = marker;
+}
+
+static void
+add_selection_markers_into_element_end (WebKitDOMDocument *document,
+                                        WebKitDOMElement *element,
+                                        WebKitDOMElement **selection_start_marker,
+                                        WebKitDOMElement **selection_end_marker)
+{
+       WebKitDOMElement *marker;
+
+       marker = create_selection_marker (document, TRUE);
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
+       if (selection_start_marker)
+               *selection_start_marker = marker;
+
+       marker = create_selection_marker (document, FALSE);
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
+       if (selection_end_marker)
+               *selection_end_marker = marker;
+}
+
+static void
+refresh_spell_check (WebKitDOMDocument *document,
+                     gboolean enable_spell_check)
+{
+       WebKitDOMDOMSelection *dom_selection;
+       WebKitDOMDOMWindow *window;
+       WebKitDOMElement *selection_start_marker, *selection_end_marker;
+       WebKitDOMHTMLElement *body;
+       WebKitDOMRange *end_range, *actual;
+       WebKitDOMText *text;
+
+       window = webkit_dom_document_get_default_view (document);
+       dom_selection = webkit_dom_dom_window_get_selection (window);
+
+       /* Enable/Disable spellcheck in composer */
+       body = webkit_dom_document_get_body (document);
+       webkit_dom_element_set_attribute (
+               WEBKIT_DOM_ELEMENT (body),
+               "spellcheck",
+               enable_spell_check ? "true" : "false",
+               NULL);
+
+       dom_selection_save (document);
+
+       selection_start_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-start-marker", NULL);
+       selection_end_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-end-marker", NULL);
+
+       /* Sometimes the web view is not focused, so we have to save the selection
+        * manually into the body */
+       if (!selection_start_marker || !selection_end_marker) {
+               WebKitDOMNode *child;
+
+               child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+               if (!child)
+                       return;
+
+               add_selection_markers_into_element_start (
+                       document,
+                       WEBKIT_DOM_ELEMENT (child),
+                       &selection_start_marker,
+                       &selection_end_marker);
+       }
+
+       /* Block callbacks of selection-changed signal as we don't want to
+        * recount all the block format things in EHTMLEditorSelection and here as well
+        * when we are moving with caret */
+/* FIXME WK2
+       g_signal_handlers_block_by_func (
+               view, html_editor_view_selection_changed_cb, NULL);
+       e_html_editor_selection_block_selection_changed (selection);
+*/
+       /* Append some text on the end of the body */
+       text = webkit_dom_document_create_text_node (document, "-x-evo-end");
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (text), NULL);
+
+       /* Create range that's pointing on the end of this text */
+       end_range = webkit_dom_document_create_range (document);
+       webkit_dom_range_select_node_contents (
+               end_range, WEBKIT_DOM_NODE (text), NULL);
+       webkit_dom_range_collapse (end_range, FALSE, NULL);
+
+       /* Move on the beginning of the document */
+       webkit_dom_dom_selection_modify (
+               dom_selection, "move", "backward", "documentboundary");
+
+       /* Go through all words to spellcheck them. To avoid this we have to wait for
+        * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
+       actual = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+       /* We are moving forward word by word until we hit the text on the end of
+        * the body that we previously inserted there */
+       while (actual && webkit_dom_range_compare_boundary_points (end_range, 2, actual, NULL) != 0) {
+               webkit_dom_dom_selection_modify (
+                       dom_selection, "move", "forward", "word");
+               actual = webkit_dom_dom_selection_get_range_at (
+                       dom_selection, 0, NULL);
+       }
+
+       /* Remove the text that we inserted on the end of the body */
+       remove_node (WEBKIT_DOM_NODE (text));
+
+       /* Unblock the callbacks */
+/* FIXME WK2
+       g_signal_handlers_unblock_by_func (
+               view, html_editor_view_selection_changed_cb, NULL);
+       e_html_editor_selection_unblock_selection_changed (selection);
+*/
+       dom_selection_restore (document);
+}
+
+void
+dom_turn_spell_check_off (WebKitDOMDocument *document)
+{
+       refresh_spell_check (document, FALSE);
+}
+
+void
+dom_force_spell_check (EHTMLEditorWebExtension *extension,
+                       WebKitDOMDocument *document)
+{
+       if (extension->priv->inline_spelling)
+               refresh_spell_check (document, TRUE);
+}
+
+static gint
+get_citation_level (WebKitDOMNode *node,
+                    gboolean set_plaintext_quoted)
+{
+       WebKitDOMNode *parent = node;
+       gint level = 0;
+
+       while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+               if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
+                   webkit_dom_element_has_attribute (WEBKIT_DOM_ELEMENT (parent), "type")) {
+                       level++;
+
+                       if (set_plaintext_quoted) {
+                               element_add_class (
+                                       WEBKIT_DOM_ELEMENT (parent),
+                                       "-x-evo-plaintext-quoted");
+                       }
+               }
+
+               parent = webkit_dom_node_get_parent_node (parent);
+       }
+
+       return level;
+}
+
+static gchar *
+get_quotation_for_level (gint quote_level)
+{
+       gint ii;
+       GString *output = g_string_new ("");
+
+       for (ii = 0; ii < quote_level; ii++) {
+               g_string_append (output, "<span class=\"-x-evo-quote-character\">");
+               g_string_append (output, QUOTE_SYMBOL);
+               g_string_append (output, " ");
+               g_string_append (output, "</span>");
+       }
+
+       return g_string_free (output, FALSE);
+}
+
+static void
+quote_plain_text_element_after_wrapping (WebKitDOMDocument *document,
+                                         WebKitDOMElement *element,
+                                         gint quote_level)
+{
+       WebKitDOMNodeList *list;
+       WebKitDOMNode *quoted_node;
+       gint length, ii;
+       gchar *quotation;
+
+       quoted_node = WEBKIT_DOM_NODE (
+               webkit_dom_document_create_element (document, "SPAN", NULL));
+       webkit_dom_element_set_class_name (
+               WEBKIT_DOM_ELEMENT (quoted_node), "-x-evo-quoted");
+       quotation = get_quotation_for_level (quote_level);
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (quoted_node), quotation, NULL);
+
+       list = webkit_dom_element_query_selector_all (
+               element, "br.-x-evo-wrap-br", NULL);
+       webkit_dom_node_insert_before (
+               WEBKIT_DOM_NODE (element),
+               quoted_node,
+               webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
+               NULL);
+
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *br = webkit_dom_node_list_item (list, ii);
+
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_parent_node (br),
+                       webkit_dom_node_clone_node (quoted_node, TRUE),
+                       webkit_dom_node_get_next_sibling (br),
+                       NULL);
+       }
+
+       g_object_unref (list);
+       g_free (quotation);
+}
+
+static gboolean
+is_citation_node (WebKitDOMNode *node)
+{
+       char *value;
+
+       if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))
+               return FALSE;
+
+       value = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "type");
+
+       /* citation == <blockquote type='cite'> */
+       if (g_strcmp0 (value, "cite") == 0) {
+               g_free (value);
+               return TRUE;
+       } else {
+               g_free (value);
+               return FALSE;
+       }
+}
+
+static gboolean
+return_pressed_in_empty_line (WebKitDOMDocument *document)
+{
+       WebKitDOMNode *node;
+       WebKitDOMRange *range;
+
+       range = dom_get_current_range (document);
+       if (!range)
+               return FALSE;
+
+       node = webkit_dom_range_get_start_container (range, NULL);
+       if (!WEBKIT_DOM_IS_TEXT (node)) {
+               WebKitDOMNode *first_child;
+
+               first_child = webkit_dom_node_get_first_child (node);
+               if (first_child && WEBKIT_DOM_IS_ELEMENT (first_child) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (first_child), "-x-evo-quoted")) {
+                       WebKitDOMNode *prev_sibling;
+
+                       prev_sibling = webkit_dom_node_get_previous_sibling (node);
+                       if (!prev_sibling)
+                               return webkit_dom_range_get_collapsed (range, NULL);
+               }
+       }
+
+       return FALSE;
+}
+
+static WebKitDOMNode *
+get_parent_block_node_from_child (WebKitDOMNode *node)
+{
+       WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
+
+       if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-temp-text-wrapper") ||
+           WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) ||
+           element_has_tag (WEBKIT_DOM_ELEMENT (parent), "b") ||
+           element_has_tag (WEBKIT_DOM_ELEMENT (parent), "i") ||
+           element_has_tag (WEBKIT_DOM_ELEMENT (parent), "u"))
+               parent = webkit_dom_node_get_parent_node (parent);
+
+       return parent;
+}
+
+static WebKitDOMElement *
+prepare_paragraph (WebKitDOMDocument *document,
+                   gboolean with_selection)
+{
+       WebKitDOMElement *element, *paragraph;
+
+       paragraph = dom_get_paragraph_element (document, -1, 0);
+
+       if (with_selection)
+               add_selection_markers_into_element_start (
+                       document, paragraph, NULL, NULL);
+
+       element = webkit_dom_document_create_element (document, "BR", NULL);
+
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (paragraph), WEBKIT_DOM_NODE (element), NULL);
+
+       return paragraph;
+}
+
+static WebKitDOMElement *
+insert_new_line_into_citation (EHTMLEditorWebExtension *extension,
+                               WebKitDOMDocument *document,
+                               const gchar *html_to_insert)
+{
+       gboolean html_mode = FALSE, ret_val, avoid_editor_call;
+       WebKitDOMElement *element, *paragraph = NULL;
+
+       html_mode = is_in_html_mode (extension);
+
+       avoid_editor_call = return_pressed_in_empty_line (document);
+
+       if (avoid_editor_call) {
+               WebKitDOMElement *selection_start_marker;
+               WebKitDOMNode *current_block, *parent, *parent_block, *block_clone;
+
+               dom_selection_save (document);
+
+               selection_start_marker = webkit_dom_document_get_element_by_id (
+                       document, "-x-evo-selection-start-marker");
+
+               current_block = get_parent_block_node_from_child (
+                       WEBKIT_DOM_NODE (selection_start_marker));
+
+               block_clone = webkit_dom_node_clone_node (current_block, TRUE);
+               /* Find selection start marker and restore it after the new line
+                * is inserted */
+               selection_start_marker = webkit_dom_element_query_selector (
+                       WEBKIT_DOM_ELEMENT (block_clone), "#-x-evo-selection-start-marker", NULL);
+
+               /* Find parent node that is immediate child of the BODY */
+               /* Build the same structure of parent nodes of the current block */
+               parent_block = current_block;
+               parent = webkit_dom_node_get_parent_node (parent_block);
+               while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+                       WebKitDOMNode *node;
+
+                       parent_block = parent;
+                       node = webkit_dom_node_clone_node (parent_block, FALSE);
+                       webkit_dom_node_append_child (node, block_clone, NULL);
+                       block_clone = node;
+                       parent = webkit_dom_node_get_parent_node (parent_block);
+               }
+
+               paragraph = dom_get_paragraph_element (document, -1, 0);
+
+               webkit_dom_node_append_child (
+                       WEBKIT_DOM_NODE (paragraph),
+                       WEBKIT_DOM_NODE (
+                               webkit_dom_document_create_element (document, "BR", NULL)),
+                       NULL);
+
+               /* Insert the selection markers to right place */
+               webkit_dom_node_insert_before (
+                       WEBKIT_DOM_NODE (paragraph),
+                       webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (selection_start_marker)),
+                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (paragraph)),
+                       NULL);
+               webkit_dom_node_insert_before (
+                       WEBKIT_DOM_NODE (paragraph),
+                       WEBKIT_DOM_NODE (selection_start_marker),
+                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (paragraph)),
+                       NULL);
+
+               /* Insert the cloned nodes before the BODY parent node */
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_parent_node (parent_block),
+                       block_clone,
+                       parent_block,
+                       NULL);
+
+               /* Insert the new empty paragraph before the BODY parent node */
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_parent_node (parent_block),
+                       WEBKIT_DOM_NODE (paragraph),
+                       parent_block,
+                       NULL);
+
+               /* Remove the old block (its copy was moved to the right place) */
+               remove_node (current_block);
+
+               dom_selection_restore (document);
+
+               return NULL;
+       } else {
+               ret_val = dom_exec_command (
+                       document, E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, NULL);
+
+               if (!ret_val)
+                       return NULL;
+
+               element = webkit_dom_document_query_selector (
+                       document, "body>br", NULL);
+
+               if (!element)
+                       return NULL;
+       }
+
+       if (!html_mode) {
+               WebKitDOMNode *next_sibling;
+
+               next_sibling = webkit_dom_node_get_next_sibling (
+                       WEBKIT_DOM_NODE (element));
+
+               if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (next_sibling)) {
+                       gint citation_level, length;
+                       gint word_wrap_length = extension->priv->word_wrap_length;
+                       WebKitDOMNode *node;
+
+                       node = webkit_dom_node_get_first_child (next_sibling);
+                       while (node && is_citation_node (node))
+                               node = webkit_dom_node_get_first_child (node);
+
+                       citation_level = get_citation_level (node, FALSE);
+                       length = word_wrap_length - 2 * citation_level;
+
+                       /* Rewrap and requote first block after the newly inserted line */
+                       if (node && WEBKIT_DOM_IS_ELEMENT (node)) {
+                               remove_quoting_from_element (WEBKIT_DOM_ELEMENT (node));
+                               remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (node));
+                               node = WEBKIT_DOM_NODE (dom_wrap_paragraph_length (
+                                       document, WEBKIT_DOM_ELEMENT (node), length));
+                               quote_plain_text_element_after_wrapping (
+                                       document, WEBKIT_DOM_ELEMENT (node), citation_level);
+                       }
+
+                       dom_force_spell_check (document);
+               }
+       }
+
+       if (html_to_insert && *html_to_insert) {
+               paragraph = prepare_paragraph (document, FALSE);
+               webkit_dom_html_element_set_inner_html (
+                       WEBKIT_DOM_HTML_ELEMENT (paragraph),
+                       html_to_insert,
+                       NULL);
+               add_selection_markers_into_element_end (
+                       document, paragraph, NULL, NULL);
+       } else
+               paragraph = prepare_paragraph (document, TRUE);
+
+       webkit_dom_node_insert_before (
+               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+               WEBKIT_DOM_NODE (paragraph),
+               WEBKIT_DOM_NODE (element),
+               NULL);
+
+       remove_node (WEBKIT_DOM_NODE (element));
+
+       dom_selection_restore (document);
+
+       return paragraph;
+}
+
+/* For purpose of this function see e-mail-formatter-quote.c */
+static void
+put_body_in_citation (WebKitDOMDocument *document)
+{
+       WebKitDOMElement *cite_body = webkit_dom_document_query_selector (
+               document, "span.-x-evo-cite-body", NULL);
+
+       if (cite_body) {
+               WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
+               WebKitDOMNode *citation;
+               WebKitDOMNode *sibling;
+
+               citation = WEBKIT_DOM_NODE (
+                       webkit_dom_document_create_element (document, "blockquote", NULL));
+               webkit_dom_element_set_id (WEBKIT_DOM_ELEMENT (citation), "-x-evo-main-cite");
+               webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (citation), "type", "cite", NULL);
+
+               webkit_dom_node_insert_before (
+                       WEBKIT_DOM_NODE (body),
+                       citation,
+                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
+                       NULL);
+
+               while ((sibling = webkit_dom_node_get_next_sibling (citation)))
+                       webkit_dom_node_append_child (citation, sibling, NULL);
+       }
+}
+
+/* For purpose of this function see e-mail-formatter-quote.c */
+static void
+move_elements_to_body (WebKitDOMDocument *document)
+{
+       WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
+       WebKitDOMNodeList *list;
+       gint ii;
+
+       list = webkit_dom_document_query_selector_all (
+               document, "span.-x-evo-to-body[data-headers]", NULL);
+       for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
+               WebKitDOMNode *child;
+               WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
+
+               while ((child = webkit_dom_node_get_first_child (node))) {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (body),
+                               child,
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (body)),
+                               NULL);
+               }
+
+               remove_node (node);
+       }
+       g_object_unref (list);
+
+       list = webkit_dom_document_query_selector_all (
+               document, "span.-x-evo-to-body[data-credits]", NULL);
+       for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
+               WebKitDOMNode *child;
+               WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
+
+               while ((child = webkit_dom_node_get_first_child (node))) {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (body),
+                               child,
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (body)),
+                               NULL);
+               }
+
+               remove_node (node);
+       }
+       g_object_unref (list);
+}
+
+static void
+repair_gmail_blockquotes (WebKitDOMDocument *document)
+{
+       WebKitDOMNodeList *list;
+       gint ii, length;
+
+       list = webkit_dom_document_query_selector_all (
+               document, "blockquote.gmail_quote", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
+
+               webkit_dom_element_remove_attribute (WEBKIT_DOM_ELEMENT (node), "class");
+               webkit_dom_element_remove_attribute (WEBKIT_DOM_ELEMENT (node), "style");
+               webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (node), "type", "cite", NULL);
+       }
+       g_object_unref (list);
+}
+
+/* FIXME WK2 */
+static void
+dom_check_magic_links (WebKitDOMDocument *document,
+                       WebKitDOMRange *range,
+                       gboolean include_space_by_user,
+                      gboolean return_pressed,
+                      gboolean space_pressed)
+{
+       gchar *node_text;
+       gchar **urls;
+       GRegex *regex = NULL;
+       GMatchInfo *match_info;
+       gint start_pos_url, end_pos_url;
+       WebKitDOMNode *node;
+       gboolean include_space = FALSE;
+       gboolean return_pressed = FALSE;
+
+       if (event != NULL) {
+               return_pressed = is_return_key (event);
+               include_space = (event->keyval == GDK_KEY_space);
+       } else {
+               include_space = include_space_by_user;
+       }
+
+       node = webkit_dom_range_get_end_container (range, NULL);
+
+       if (return_pressed)
+               node = webkit_dom_node_get_previous_sibling (node);
+
+       if (!node)
+               return;
+
+       if (!WEBKIT_DOM_IS_TEXT (node)) {
+               if (webkit_dom_node_has_child_nodes (node))
+                       node = webkit_dom_node_get_first_child (node);
+               if (!WEBKIT_DOM_IS_TEXT (node))
+                       return;
+       }
+
+       node_text = webkit_dom_text_get_whole_text (WEBKIT_DOM_TEXT (node));
+       if (!node_text || !(*node_text) || !g_utf8_validate (node_text, -1, NULL))
+               return;
+
+       regex = g_regex_new (include_space ? URL_PATTERN_SPACE : URL_PATTERN, 0, 0, NULL);
+
+       if (!regex) {
+               g_free (node_text);
+               return;
+       }
+
+       g_regex_match_all (regex, node_text, G_REGEX_MATCH_NOTEMPTY, &match_info);
+       urls = g_match_info_fetch_all (match_info);
+
+       if (urls) {
+               gchar *final_url, *url_end_raw;
+               glong url_start, url_end, url_length;
+               WebKitDOMNode *url_text_node_clone;
+               WebKitDOMText *url_text_node;
+               WebKitDOMElement *anchor;
+               const gchar* url_text;
+
+               if (!return_pressed)
+                       dom_save_caret_position (document);
+
+               g_match_info_fetch_pos (match_info, 0, &start_pos_url, &end_pos_url);
+
+               /* Get start and end position of url in node's text because positions
+                * that we get from g_match_info_fetch_pos are not UTF-8 aware */
+               url_end_raw = g_strndup(node_text, end_pos_url);
+               url_end = g_utf8_strlen (url_end_raw, -1);
+
+               url_length = g_utf8_strlen (urls[0], -1);
+               url_start = url_end - url_length;
+
+               webkit_dom_text_split_text (
+                       WEBKIT_DOM_TEXT (node),
+                       include_space ? url_end - 1 : url_end,
+                       NULL);
+
+               url_text_node = webkit_dom_text_split_text (
+                       WEBKIT_DOM_TEXT (node), url_start, NULL);
+               url_text_node_clone = webkit_dom_node_clone_node (
+                       WEBKIT_DOM_NODE (url_text_node), TRUE);
+               url_text = webkit_dom_text_get_whole_text (
+                       WEBKIT_DOM_TEXT (url_text_node_clone));
+
+               final_url = g_strconcat (
+                       g_str_has_prefix (url_text, "www") ? "http://"; : "", url_text, NULL);
+
+               /* Create and prepare new anchor element */
+               anchor = webkit_dom_document_create_element (document, "A", NULL);
+
+               webkit_dom_html_element_set_inner_html (
+                       WEBKIT_DOM_HTML_ELEMENT (anchor),
+                       url_text,
+                       NULL);
+
+               webkit_dom_html_anchor_element_set_href (
+                       WEBKIT_DOM_HTML_ANCHOR_ELEMENT (anchor),
+                       final_url);
+
+               /* Insert new anchor element into document */
+               webkit_dom_node_replace_child (
+                       webkit_dom_node_get_parent_node (node),
+                       WEBKIT_DOM_NODE (anchor),
+                       WEBKIT_DOM_NODE (url_text_node),
+                       NULL);
+
+               if (!return_pressed)
+                       dom_restore_caret_position (document);
+
+               g_free (url_end_raw);
+               g_free (final_url);
+       } else {
+               WebKitDOMElement *parent;
+               WebKitDOMNode *prev_sibling;
+               gchar *href, *text, *url;
+               gint diff;
+               const char* text_to_append;
+               gboolean appending_to_link = FALSE;
+
+               parent = webkit_dom_node_get_parent_element (node);
+               prev_sibling = webkit_dom_node_get_previous_sibling (node);
+
+               /* If previous sibling is ANCHOR and actual text node is not beginning with
+                * space => we're appending to link */
+               if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling)) {
+                       text_to_append = webkit_dom_node_get_text_content (node);
+                       if (g_strcmp0 (text_to_append, "") != 0 &&
+                               !g_unichar_isspace (g_utf8_get_char (text_to_append))) {
+
+                               appending_to_link = TRUE;
+                               parent = WEBKIT_DOM_ELEMENT (prev_sibling);
+                       }
+               }
+
+               /* If parent is ANCHOR => we're editing the link */
+               if (!WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) && !appending_to_link) {
+                       g_match_info_free (match_info);
+                       g_regex_unref (regex);
+                       g_free (node_text);
+                       return;
+               }
+
+               /* edit only if href and description are the same */
+               href = webkit_dom_html_anchor_element_get_href (
+                       WEBKIT_DOM_HTML_ANCHOR_ELEMENT (parent));
+
+               if (appending_to_link) {
+                       gchar *inner_text;
+
+                       inner_text =
+                               webkit_dom_html_element_get_inner_text (
+                                       WEBKIT_DOM_HTML_ELEMENT (parent)),
+
+                       text = g_strconcat (inner_text, text_to_append, NULL);
+                       g_free (inner_text);
+               } else
+                       text = webkit_dom_html_element_get_inner_text (
+                                       WEBKIT_DOM_HTML_ELEMENT (parent));
+
+               if (strstr (href, "://") && !strstr (text, "://")) {
+                       url = strstr (href, "://") + 3;
+                       diff = strlen (text) - strlen (url);
+
+                       if (text [strlen (text) - 1] != '/')
+                               diff++;
+
+                       if ((g_strcmp0 (url, text) != 0 && ABS (diff) == 1) || appending_to_link) {
+                               gchar *inner_html, *protocol, *new_href;
+
+                               protocol = g_strndup (href, strstr (href, "://") - href + 3);
+                               inner_html = webkit_dom_html_element_get_inner_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (parent));
+                               new_href = g_strconcat (
+                                       protocol, inner_html, appending_to_link ? text_to_append : "", NULL);
+
+                               webkit_dom_html_anchor_element_set_href (
+                                       WEBKIT_DOM_HTML_ANCHOR_ELEMENT (parent),
+                                       new_href);
+
+                               if (appending_to_link) {
+                                       gchar *tmp;
+
+                                       tmp = g_strconcat (inner_html, text_to_append, NULL);
+                                       webkit_dom_html_element_set_inner_html (
+                                               WEBKIT_DOM_HTML_ELEMENT (parent),
+                                               tmp,
+                                               NULL);
+
+                                       remove_node (node);
+
+                                       g_free (tmp);
+                               }
+
+                               g_free (new_href);
+                               g_free (protocol);
+                               g_free (inner_html);
+                       }
+               } else {
+                       diff = strlen (text) - strlen (href);
+                       if (text [strlen (text) - 1] != '/')
+                               diff++;
+
+                       if ((g_strcmp0 (href, text) != 0 && ABS (diff) == 1) || appending_to_link) {
+                               gchar *inner_html;
+                               gchar *new_href;
+
+                               inner_html = webkit_dom_html_element_get_inner_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (parent));
+                               new_href = g_strconcat (
+                                               inner_html,
+                                               appending_to_link ? text_to_append : "",
+                                               NULL);
+
+                               webkit_dom_html_anchor_element_set_href (
+                                       WEBKIT_DOM_HTML_ANCHOR_ELEMENT (parent),
+                                       new_href);
+
+                               if (appending_to_link) {
+                                       gchar *tmp;
+
+                                       tmp = g_strconcat (inner_html, text_to_append, NULL);
+                                       webkit_dom_html_element_set_inner_html (
+                                               WEBKIT_DOM_HTML_ELEMENT (parent),
+                                               tmp,
+                                               NULL);
+
+                                       remove_node (node);
+
+                                       g_free (tmp);
+                               }
+
+                               g_free (new_href);
+                               g_free (inner_html);
+                       }
+
+               }
+               g_free (text);
+               g_free (href);
+       }
+
+       g_match_info_free (match_info);
+       g_regex_unref (regex);
+       g_free (node_text);
+}
+
+void
+dom_embed_style_sheet (WebKitDOMDocument *document,
+                       const gchar *style_sheet_content)
+{
+       WebKitDOMElement *sheet;
+
+       e_web_view_create_and_add_css_style_sheet (document, "-x-evo-composer-sheet");
+
+       sheet = webkit_dom_document_get_element_by_id (document, "-x-evo-composer-sheet");
+       webkit_dom_element_set_attribute (
+               sheet,
+               "type",
+               "text/css",
+               NULL);
+
+       webkit_dom_html_element_set_inner_html (WEBKIT_DOM_HTML_ELEMENT (sheet), stylesheet_content, NULL);
+}
+
+void
+dom_remove_embed_style_sheet (WebKitDOMDocument *document)
+{
+       WebKitDOMElement *sheet;
+
+       sheet = webkit_dom_document_get_element_by_id (
+               document, "-x-evo-composer-sheet");
+
+       remove_node (WEBKIT_DOM_NODE (sheet));
+}
+
+void
+dom_set_links_active (WebKitDOMDocument *document,
+                      gboolean active)
+{
+       WebKitDOMElement *style;
+
+       if (active) {
+               style = webkit_dom_document_get_element_by_id (
+                               document, "--evolution-editor-style-a");
+               if (style)
+                       remove_node (WEBKIT_DOM_NODE (style));
+       } else {
+               WebKitDOMHTMLHeadElement *head;
+               head = webkit_dom_document_get_head (document);
+
+               style = webkit_dom_document_create_element (document, "STYLE", NULL);
+               webkit_dom_element_set_id (style, "--evolution-editor-style-a");
+               webkit_dom_html_element_set_inner_text (
+                       WEBKIT_DOM_HTML_ELEMENT (style), "a { cursor: text; }", NULL);
+
+               webkit_dom_node_append_child (
+                       WEBKIT_DOM_NODE (head), WEBKIT_DOM_NODE (style), NULL);
+       }
+}
+
+static void
+fix_paragraph_structure_after_pressing_enter_after_smiley (WebKitDOMDocument *document)
+{
+       WebKitDOMElement *element;
+
+       element = webkit_dom_document_query_selector (
+               document, "span.-x-evo-smiley-wrapper > br", NULL);
+
+       if (element) {
+               WebKitDOMNode *parent;
+
+               parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element));
+               webkit_dom_html_element_set_inner_html (
+                       WEBKIT_DOM_HTML_ELEMENT (
+                               webkit_dom_node_get_parent_node (parent)),
+                       UNICODE_ZERO_WIDTH_SPACE,
+                       NULL);
+       }
+}
+
+static void
+mark_node_as_paragraph_after_ending_list (WebKitDOMDocument *document)
+{
+       gint ii, length;
+       WebKitDOMNodeList *list;
+
+       /* When pressing Enter on empty line in the list WebKit will end that
+        * list and inserts <div><br></div> so mark it for wrapping */
+       list = webkit_dom_document_query_selector_all (
+               document, "body > div:not(.-x-evo-paragraph) > br", NULL);
+
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *node = webkit_dom_node_get_parent_node (
+                       webkit_dom_node_list_item (list, ii));
+
+               dom_set_paragraph_style (WEBKIT_DOM_ELEMENT (node), -1, 0, "");
+       }
+       g_object_unref (list);
+}
+
+static gboolean
+surround_text_with_paragraph_if_needed (WebKitDOMDocument *document,
+                                        WebKitDOMNode *node)
+{
+       WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
+       WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (node);
+       WebKitDOMElement *element;
+
+       /* All text in composer has to be written in div elements, so if
+        * we are writing something straight to the body, surround it with
+        * paragraph */
+       if (WEBKIT_DOM_IS_TEXT (node) &&
+           WEBKIT_DOM_IS_HTML_BODY_ELEMENT (webkit_dom_node_get_parent_node (node))) {
+               element = dom_put_node_into_paragraph (
+                       document, node, dom_caret_position_node (document));
+
+               if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (next_sibling))
+                       remove_node (next_sibling);
+
+               /* Tab character */
+               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "Apple-tab-span")) {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (element),
+                               prev_sibling,
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (element)),
+                               NULL);
+               }
+
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static void
+body_input_event_cb (WebKitDOMElement *element,
+                     WebKitDOMEvent *event,
+                     EHTMLEditorWebExtension *extension)
+{
+       gboolean html_mode;
+       WebKitDOMDocument *document;
+       WebKitDOMNode *node;
+       WebKitDOMRange *range;
+
+       document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
+       range = dom_get_range (document);
+
+       html_mode = is_in_html_mode (extension)
+       set_content_changed (extension);
+
+       if (extension->priv->magic_smileys && html_mode)
+               html_editor_view_check_magic_smileys (view, range);
+
+       if (is_return_key (key_event) || (key_event->keyval == GDK_KEY_space)) {
+               html_editor_view_check_magic_links (view, range, FALSE, key_event);
+               mark_node_as_paragraph_after_ending_list (document);
+               if (html_mode)
+                       fix_paragraph_structure_after_pressing_enter_after_smiley (document);
+       } else {
+               WebKitDOMNode *node;
+
+               node = webkit_dom_range_get_end_container (range, NULL);
+
+               if (surround_text_with_paragraph_if_needed (document, node)) {
+                       dom_restore_caret_position (document);
+                       node = webkit_dom_range_get_end_container (range, NULL);
+                       range = dom_get_range (document);
+               }
+
+               if (WEBKIT_DOM_IS_TEXT (node)) {
+                       gchar *text;
+
+                       text = webkit_dom_node_get_text_content (node);
+
+                       if (g_strcmp0 (text, "") != 0 && !g_unichar_isspace (g_utf8_get_char (text))) {
+                               WebKitDOMNode *prev_sibling;
+
+                               prev_sibling = webkit_dom_node_get_previous_sibling (node);
+
+                               if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling))
+                                       html_editor_view_check_magic_links (view, range, FALSE, key_event);
+                       }
+                       g_free (text);
+               }
+       }
+
+       node = webkit_dom_range_get_end_container (range, NULL);
+
+       /* After toggling monospaced format, we are using UNICODE_ZERO_WIDTH_SPACE
+        * to move caret into right space. When this callback is called it is not
+        * necassary anymore so remove it */
+       if (html_mode) {
+               WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
+
+               if (parent) {
+                       WebKitDOMNode *prev_sibling;
+
+                       prev_sibling = webkit_dom_node_get_previous_sibling (
+                               WEBKIT_DOM_NODE (parent));
+
+                       if (prev_sibling && WEBKIT_DOM_IS_TEXT (prev_sibling)) {
+                               gchar *text = webkit_dom_node_get_text_content (
+                                       prev_sibling);
+
+                               if (g_strcmp0 (text, UNICODE_ZERO_WIDTH_SPACE) == 0)
+                                       remove_node (prev_sibling);
+
+                               g_free (text);
+                       }
+
+               }
+       }
+
+       /* If text before caret includes UNICODE_ZERO_WIDTH_SPACE character, remove it */
+       if (WEBKIT_DOM_IS_TEXT (node)) {
+               gchar *text = webkit_dom_character_data_get_data (WEBKIT_DOM_CHARACTER_DATA (node));
+               glong length = g_utf8_strlen (text, -1);
+               WebKitDOMNode *parent;
+
+               /* We have to preserve empty paragraphs with just UNICODE_ZERO_WIDTH_SPACE
+                * character as when we will remove it it will collapse */
+               if (length > 1) {
+                       if (g_str_has_prefix (text, UNICODE_ZERO_WIDTH_SPACE))
+                               webkit_dom_character_data_replace_data (
+                                       WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
+                       else if (g_str_has_suffix (text, UNICODE_ZERO_WIDTH_SPACE))
+                               webkit_dom_character_data_replace_data (
+                                       WEBKIT_DOM_CHARACTER_DATA (node), length - 1, 1, "", NULL);
+               }
+               g_free (text);
+
+               parent = webkit_dom_node_get_parent_node (node);
+               if ((WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (parent) ||
+                   WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent)) &&
+                   !element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph")) {
+                       if (html_mode)
+                               element_add_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph");
+                       else
+                               dom_set_paragraph_style (
+                                       selection, WEBKIT_DOM_ELEMENT (parent), -1, 0, "");
+               }
+
+               /* When new smiley is added we have to use UNICODE_HIDDEN_SPACE to set the
+                * caret position to right place. It is removed when user starts typing. But
+                * when the user will press left arrow he will move the caret into
+                * smiley wrapper. If he will start to write there we have to move the written
+                * text out of the wrapper and move caret to right place */
+               if (WEBKIT_DOM_IS_ELEMENT (parent) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-smiley-wrapper")) {
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (parent),
+                               dom_crate_caret_position_node (document),
+                               webkit_dom_node_get_next_sibling (parent),
+                               NULL);
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (parent),
+                               node,
+                               webkit_dom_node_get_next_sibling (parent),
+                               NULL);
+                       dom_restore_caret_position (document);
+               }
+       }
+
+       /* Writing into quoted content */
+       if (html_mode) {
+               gint citation_level;
+               WebKitDOMElement *selection_start_marker, *selection_end_marker;
+               WebKitDOMNode *node, *parent;
+               WebKitDOMRange *range;
+
+               range = dom_get_range (document);
+               node = webkit_dom_range_get_end_container (range, NULL);
+
+               citation_level = get_citation_level (node, FALSE);
+               if (citation_level == 0)
+                       return;
+
+               selection_start_marker = webkit_dom_document_query_selector (
+                       document, "span#-x-evo-selection-start-marker", NULL);
+               if (selection_start_marker)
+                       return;
+
+               dom_selection_save (document);
+
+               selection_start_marker = webkit_dom_document_query_selector (
+                       document, "span#-x-evo-selection-start-marker", NULL);
+               selection_end_marker = webkit_dom_document_query_selector (
+                       document, "span#-x-evo-selection-end-marker", NULL);
+               /* If the selection was not saved, move it into the first child of body */
+               if (!selection_start_marker || !selection_end_marker) {
+                       WebKitDOMHTMLElement *body;
+                       WebKitDOMNode *child;
+
+                       body = webkit_dom_document_get_body (document);
+                       child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+
+                       add_selection_markers_into_element_start (
+                               document,
+                               WEBKIT_DOM_ELEMENT (child),
+                               &selection_start_marker,
+                               &selection_end_marker);
+               }
+
+               /* We have to process elements only inside normal block */
+               parent = WEBKIT_DOM_NODE (get_parent_block_element (
+                       WEBKIT_DOM_NODE (selection_start_marker)));
+               if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent)) {
+                       dom_selection_restore (document);
+                       return;
+               }
+
+               if (selection_start_marker) {
+                       gchar *content;
+                       gint text_length, word_wrap_length, length;
+                       WebKitDOMElement *block;
+                       gboolean remove_quoting = FALSE;
+
+                       word_wrap_length = extension->priv->word_wrap_length;
+                       length = word_wrap_length - 2 * citation_level;
+
+                       block = WEBKIT_DOM_ELEMENT (parent);
+                       if (webkit_dom_element_query_selector (
+                               WEBKIT_DOM_ELEMENT (block), ".-x-evo-quoted", NULL)) {
+                               WebKitDOMNode *prev_sibling;
+
+                               prev_sibling = webkit_dom_node_get_previous_sibling (
+                                       WEBKIT_DOM_NODE (selection_end_marker));
+
+                               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling))
+                                       remove_quoting = element_has_class (
+                                               WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-quoted");
+                       }
+
+                       content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (block));
+                       text_length = g_utf8_strlen (content, -1);
+                       g_free (content);
+
+                       /* Wrap and quote the line */
+                       if (!remove_quoting && text_length >= word_wrap_length) {
+                               remove_quoting_from_element (block);
+
+                               block = dom_wrap_paragraph_length (document, block, length);
+                               webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
+                               quote_plain_text_element_after_wrapping (
+                                       document, WEBKIT_DOM_ELEMENT (block), citation_level);
+                               selection_start_marker = webkit_dom_document_query_selector (
+                                       document, "span#-x-evo-selection-start-marker", NULL);
+                               if (!selection_start_marker)
+                                       add_selection_markers_into_element_end (
+                                               document,
+                                               WEBKIT_DOM_ELEMENT (block),
+                                               NULL,
+                                               NULL);
+
+                               dom_selection_restore (document);
+                               dom_force_spell_check_for_current_paragraph (document);
+                               return;
+                       }
+               }
+               dom_selection_restore (document);
+       }
+}
+
+static void
+remove_input_event_listener_from_body (EHTMLEditorWebExtension *extension,
+                                       WebKitDOMDocument *document)
+{
+       if (!extension->priv->body_input_event_removed) {
+               webkit_dom_event_target_remove_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (
+                               webkit_dom_document_get_body (document)),
+                       "input",
+                       G_CALLBACK (body_input_event_cb),
+                       FALSE);
+
+               extension->priv->body_input_event_removed = TRUE;
+       }
+}
+
+static void
+register_input_event_listener_on_body (EHTMLEditorWebExtension *extension,
+                                       WebKitDOMDocument *document)
+{
+       if (extension->priv->body_input_event_removed) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (
+                               webkit_dom_document_get_body (document)),
+                       "input",
+                       G_CALLBACK (body_input_event_cb),
+                       FALSE,
+                       extension);
+
+               extension->priv->body_input_event_removed = FALSE;
+       }
+}
+
+static void
+fix_structure_after_pasting_multiline_content (WebKitDOMNode *node)
+{
+       WebKitDOMNode *first_child, *parent;
+
+       /* When pasting content that does not contain just the
+        * one line text WebKit inserts all the content after the
+        * first line into one element. So we have to take it out
+        * of this element and insert it after that element. */
+       parent = webkit_dom_node_get_parent_node (node);
+       if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent))
+               return;
+       first_child = webkit_dom_node_get_first_child (parent);
+       while (first_child) {
+               WebKitDOMNode *next_child =
+                       webkit_dom_node_get_next_sibling  (first_child);
+               if (webkit_dom_node_has_child_nodes (first_child))
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (parent),
+                               first_child,
+                               parent,
+                               NULL);
+               first_child = next_child;
+       }
+       remove_node (parent);
+}
+
+static void
+dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
+                                            EHTMLEditorWebExtension *extension,
+                                            const gchar *html,
+                                            gboolean is_html)
+{
+       gboolean has_selection;
+       gchar *inner_html;
+       gint citation_level;
+       WebKitDOMElement *element;
+       WebKitDOMNode *node;
+       WebKitDOMRange *range;
+
+       remove_input_event_listener_from_body (document);
+
+       element = webkit_dom_document_create_element (document, "div", NULL);
+       if (is_html) {
+               gchar *inner_text;
+
+               webkit_dom_html_element_set_inner_html (
+                       WEBKIT_DOM_HTML_ELEMENT (element), html, NULL);
+               inner_text = webkit_dom_html_element_get_inner_text (
+                       WEBKIT_DOM_HTML_ELEMENT (element));
+               webkit_dom_html_element_set_inner_text (
+                       WEBKIT_DOM_HTML_ELEMENT (element), inner_text, NULL);
+
+               g_free (inner_text);
+       } else
+               webkit_dom_html_element_set_inner_text (
+                       WEBKIT_DOM_HTML_ELEMENT (element), html, NULL);
+
+       inner_html = webkit_dom_html_element_get_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (element));
+       parse_html_into_paragraphs (document, element, inner_html);
+
+       g_free (inner_html);
+
+       has_selection = !dom_selection_is_collapsed (document);
+
+       range = dom_get_range (document);
+       node = webkit_dom_range_get_end_container (range, NULL);
+       citation_level = get_citation_level (node, FALSE);
+       /* Pasting into the citation */
+       if (citation_level > 0) {
+               gint length;
+               gint word_wrap_length = extension->priv->word_wrap_length;
+               WebKitDOMElement *selection_start_marker, *selection_end_marker;
+               WebKitDOMElement *br;
+               WebKitDOMNode *first_paragraph, *last_paragraph;
+               WebKitDOMNode *child, *parent;
+
+               dom_selection_save (selection);
+               selection_start_marker = webkit_dom_document_get_element_by_id (
+                       document, "-x-evo-selection-start-marker");
+               selection_end_marker = webkit_dom_document_get_element_by_id (
+                       document, "-x-evo-selection-end-marker");
+
+               first_paragraph = webkit_dom_node_get_first_child (
+                       WEBKIT_DOM_NODE (element));
+               last_paragraph = webkit_dom_node_get_last_child (
+                       WEBKIT_DOM_NODE (element));
+
+               length = word_wrap_length - 2 * citation_level;
+
+               /* Pasting text that was parsed just into one paragraph */
+               if (webkit_dom_node_is_same_node (first_paragraph, last_paragraph)) {
+                       WebKitDOMNode *child, *parent;
+
+                       parent = get_parent_block_node_from_child (
+                               WEBKIT_DOM_NODE (selection_start_marker));
+
+                       remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
+                       remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
+
+                       while ((child = webkit_dom_node_get_first_child (first_paragraph)))
+                               webkit_dom_node_insert_before (
+                                       parent,
+                                       child,
+                                       WEBKIT_DOM_NODE (selection_start_marker),
+                                       NULL);
+
+                       parent = WEBKIT_DOM_NODE (
+                               dom_wrap_paragraph_length (
+                                       document, WEBKIT_DOM_ELEMENT (parent), length));
+                       webkit_dom_node_normalize (parent);
+                       quote_plain_text_element_after_wrapping (
+                               document, WEBKIT_DOM_ELEMENT (parent), citation_level);
+
+                       goto delete;
+               }
+
+               /* Pasting content parsed into the multiple paragraphs */
+               parent = get_parent_block_node_from_child (
+                       WEBKIT_DOM_NODE (selection_start_marker));
+
+               remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
+               remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
+
+               /* Move the elements from the first paragraph before the selection start element */
+               while ((child = webkit_dom_node_get_first_child (first_paragraph)))
+                       webkit_dom_node_insert_before (
+                               parent,
+                               child,
+                               WEBKIT_DOM_NODE (selection_start_marker),
+                               NULL);
+
+               remove_node (first_paragraph);
+
+               /* If the BR element is on the last position, remove it as we don't need it */
+               child = webkit_dom_node_get_last_child (parent);
+               if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (child))
+                       remove_node (child);
+
+               parent = get_parent_block_node_from_child (
+                       WEBKIT_DOM_NODE (selection_end_marker)),
+
+               child = webkit_dom_node_get_next_sibling (
+                       WEBKIT_DOM_NODE (selection_end_marker));
+               /* Move the elements that are in the same paragraph as the selection end
+                * on the end of pasted text, but avoid BR on the end of paragraph */
+               while (child) {
+                       WebKitDOMNode *next_child =
+                               webkit_dom_node_get_next_sibling  (child);
+                       if (!(!next_child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)))
+                               webkit_dom_node_append_child (last_paragraph, child, NULL);
+                       child = next_child;
+               }
+
+               /* Caret will be restored on the end of pasted text */
+               webkit_dom_node_append_child (
+                       last_paragraph,
+                       dom_create_caret_position_node (document),
+                       NULL);
+
+               /* Insert the paragraph with the end of the pasted text after
+                * the paragraph that contains the selection end */
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_parent_node (parent),
+                       last_paragraph,
+                       webkit_dom_node_get_next_sibling (parent),
+                       NULL);
+
+               /* Wrap, quote and move all paragraphs from pasted text into the body */
+               while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)))) {
+                       child = WEBKIT_DOM_NODE (dom_wrap_paragraph_length (
+                               document, WEBKIT_DOM_ELEMENT (child), length));
+                       quote_plain_text_element_after_wrapping (
+                               document, WEBKIT_DOM_ELEMENT (child), citation_level);
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (last_paragraph),
+                               child,
+                               last_paragraph,
+                               NULL);
+               }
+
+               webkit_dom_node_normalize (last_paragraph);
+
+               last_paragraph = WEBKIT_DOM_NODE (
+                       dom_wrap_paragraph_length (
+                               document, WEBKIT_DOM_ELEMENT (last_paragraph), length));
+               quote_plain_text_element_after_wrapping (
+                       document, WEBKIT_DOM_ELEMENT (last_paragraph), citation_level);
+
+               remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
+               remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
+
+               parent = get_parent_block_node_from_child (
+                       WEBKIT_DOM_NODE (selection_start_marker));
+               parent = WEBKIT_DOM_NODE (dom_wrap_paragraph_length (
+                       document, WEBKIT_DOM_ELEMENT (parent), length));
+               quote_plain_text_element_after_wrapping (
+                       document, WEBKIT_DOM_ELEMENT (parent), citation_level);
+
+               /* If the pasted text begun or ended with a new line we have to
+                * quote these paragraphs as well */
+               br = webkit_dom_element_query_selector (
+                       WEBKIT_DOM_ELEMENT (last_paragraph), "br.-x-evo-last-br", NULL);
+               if (br) {
+                       WebKitDOMNode *parent;
+
+                       parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (br));
+                       quote_plain_text_recursive (document, parent, parent, citation_level);
+                       webkit_dom_element_remove_attribute (br, "class");
+               }
+
+               br = webkit_dom_document_query_selector (
+                       document, "* > br.-x-evo-first-br", NULL);
+               if (br) {
+                       WebKitDOMNode *parent;
+
+                       parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (br));
+                       quote_plain_text_recursive (document, parent, parent, citation_level);
+                       webkit_dom_element_remove_attribute (br, "class");
+               }
+ delete:
+               dom_selection_restore (document);
+               /* Remove the text that was meant to be replaced by the pasted text */
+               if (has_selection)
+                       dom_exec_command (
+                               document, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+
+               dom_restore_caret_position (document);
+               goto out;
+       }
+
+       inner_html = webkit_dom_html_element_get_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (element));
+       dom_exec_command (
+               document, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, inner_html);
+       g_free (inner_html);
+
+       dom_selection_save (document);
+
+       element = webkit_dom_document_query_selector (
+               document, "* > br.-x-evo-first-br", NULL);
+       if (element) {
+               WebKitDOMNode *next_sibling;
+               WebKitDOMNode *parent;
+
+               parent = webkit_dom_node_get_parent_node (
+                       WEBKIT_DOM_NODE (element));
+
+               next_sibling = webkit_dom_node_get_next_sibling (parent);
+               if (next_sibling)
+                       remove_node (WEBKIT_DOM_NODE (parent));
+               else
+                       webkit_dom_element_remove_attribute (element, "class");
+       }
+
+       element = webkit_dom_document_query_selector (
+               document, "* > br.-x-evo-last-br", NULL);
+       if (element) {
+               WebKitDOMNode *parent;
+               WebKitDOMNode *child;
+               WebKitDOMElement *selection_marker;
+
+               parent = webkit_dom_node_get_parent_node (
+                       WEBKIT_DOM_NODE (element));
+
+               node = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent));
+               if (node) {
+                       node = webkit_dom_node_get_first_child (node);
+                       if (node) {
+                               inner_html = webkit_dom_node_get_text_content (node);
+                               if (g_str_has_prefix (inner_html, UNICODE_NBSP))
+                                       webkit_dom_character_data_replace_data (
+                                               WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
+                               g_free (inner_html);
+                       }
+               }
+
+               selection_marker = webkit_dom_document_get_element_by_id (
+                       document, "-x-evo-selection-end-marker");
+
+               if (has_selection) {
+                       /* Everything after the selection end marker have to be in separate
+                        * paragraph */
+                       child = webkit_dom_node_get_next_sibling (
+                               WEBKIT_DOM_NODE (selection_marker));
+                       /* Move the elements that are in the same paragraph as the selection end
+                        * on the end of pasted text, but avoid BR on the end of paragraph */
+                       while (child) {
+                               WebKitDOMNode *next_child =
+                                       webkit_dom_node_get_next_sibling  (child);
+                               if (!(!next_child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)))
+                                       webkit_dom_node_append_child (parent, child, NULL);
+                               child = next_child;
+                       }
+
+                       remove_node (WEBKIT_DOM_NODE (element));
+
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (
+                                       webkit_dom_node_get_parent_node (
+                                               WEBKIT_DOM_NODE (selection_marker))),
+                               parent,
+                               webkit_dom_node_get_next_sibling (
+                                       webkit_dom_node_get_parent_node (
+                                               WEBKIT_DOM_NODE (selection_marker))),
+                               NULL);
+                       node = parent;
+               } else {
+                       node = webkit_dom_node_get_next_sibling (parent);
+                       if (!node)
+                               fix_structure_after_pasting_multiline_content (parent);
+               }
+
+               if (node) {
+                       /* Restore caret on the end of pasted text */
+                       webkit_dom_node_insert_before (
+                               node,
+                               WEBKIT_DOM_NODE (selection_marker),
+                               webkit_dom_node_get_first_child (node),
+                               NULL);
+
+                       selection_marker = webkit_dom_document_get_element_by_id (
+                               document, "-x-evo-selection-start-marker");
+                       webkit_dom_node_insert_before (
+                               node,
+                               WEBKIT_DOM_NODE (selection_marker),
+                               webkit_dom_node_get_first_child (node),
+                               NULL);
+               }
+
+               if (element)
+                       webkit_dom_element_remove_attribute (element, "class");
+
+               if (webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent)) && !has_selection)
+                       remove_node (parent);
+       } else {
+               /* When pasting the content that was copied from the composer, WebKit
+                * restores the selection wrongly, thus is saved wrongly and we have
+                * to fix it */
+               WebKitDOMElement *selection_start_marker, *selection_end_marker;
+               WebKitDOMNode *paragraph, *parent;
+
+               selection_start_marker = webkit_dom_document_get_element_by_id (
+                       document, "-x-evo-selection-start-marker");
+               selection_end_marker = webkit_dom_document_get_element_by_id (
+                       document, "-x-evo-selection-end-marker");
+
+               paragraph = get_parent_block_node_from_child (
+                       WEBKIT_DOM_NODE (selection_start_marker));
+               parent = webkit_dom_node_get_parent_node (paragraph);
+               if (element_has_class (WEBKIT_DOM_ELEMENT (paragraph), "-x-evo-paragraph") &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph"))
+                       fix_structure_after_pasting_multiline_content (paragraph);
+
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_parent_node (
+                               WEBKIT_DOM_NODE (selection_start_marker)),
+                       WEBKIT_DOM_NODE (selection_end_marker),
+                       webkit_dom_node_get_next_sibling (
+                               WEBKIT_DOM_NODE (selection_start_marker)),
+                       NULL);
+       }
+
+       dom_selection_restore (document);
+ out:
+       dom_force_spell_check (document);
+       dom_scroll_to_caret (document);
+
+       register_input_event_listener_on_body (document);
+}
+
+void
+dom_quote_and_insert_text_into_selection (EHTMLEditorWebExtension *extension,
+                                          WebKitDOMDocument *document,
+                                          const gchar *text)
+{
+       gchar *escaped_text;
+       WebKitDOMElement *blockquote, *element;
+       WebKitDOMNode *node;
+       WebKitDOMRange *range;
+
+       if (!text || !*text)
+               return;
+
+       /* This is a trick to escape any HTML characters (like <, > or &).
+        * <textarea> automatically replaces all these unsafe characters
+        * by &lt;, &gt; etc. */
+       element = webkit_dom_document_create_element (document, "textarea", NULL);
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (element), text, NULL);
+       escaped_text = webkit_dom_html_element_get_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (element));
+
+       element = webkit_dom_document_create_element (document, "pre", NULL);
+
+       webkit_dom_html_element_set_inner_text (
+               WEBKIT_DOM_HTML_ELEMENT (element), escaped_text, NULL);
+
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (element),
+               dom_create_caret_position_node (document),
+               NULL);
+
+       blockquote = webkit_dom_document_create_element (document, "blockquote", NULL);
+       webkit_dom_element_set_attribute (blockquote, "type", "cite", NULL);
+
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (blockquote), WEBKIT_DOM_NODE (element), NULL);
+
+       if (!is_in_html_mode (extension))
+               dom_quote_plain_text_element (document, element);
+
+       range = dom_get_range (document);
+       node = webkit_dom_range_get_end_container (range, NULL);
+
+       webkit_dom_node_append_child (
+               webkit_dom_node_get_parent_node (node),
+               WEBKIT_DOM_NODE (blockquote),
+               NULL);
+
+       dom_restore_caret_position (document);
+
+       dom_force_spell_check_for_current_paragraph (document);
+
+       g_free (escaped_text);
+}
+
+gboolean
+dom_change_quoted_block_to_normal (EHTMLEditorWebExtension *extension,
+                                   WebKitDOMDocument *document)
+{
+       gboolean html_mode;
+       gint citation_level, success = FALSE;
+       WebKitDOMElement *selection_start_marker, *selection_end_marker, *block;
+
+       html_mode = is_in_html_mode (extension);
+
+       selection_start_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-start-marker", NULL);
+       selection_end_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-end-marker", NULL);
+
+       if (!selection_start_marker || !selection_end_marker)
+               return FALSE;
+
+       block = WEBKIT_DOM_ELEMENT (get_parent_block_node_from_child (
+               WEBKIT_DOM_NODE (selection_start_marker)));
+
+       citation_level = get_citation_level (
+               WEBKIT_DOM_NODE (selection_start_marker), FALSE);
+
+       if (selection_start_marker && citation_level > 0) {
+               if (webkit_dom_element_query_selector (
+                       WEBKIT_DOM_ELEMENT (block), ".-x-evo-quoted", NULL)) {
+
+                       WebKitDOMNode *prev_sibling;
+
+                       webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
+
+                       prev_sibling = webkit_dom_node_get_previous_sibling (
+                               WEBKIT_DOM_NODE (selection_start_marker));
+
+                       if (WEBKIT_DOM_IS_ELEMENT (prev_sibling))
+                               success = element_has_class (
+                                       WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-quoted");
+                       /* We really have to be in the beginning of paragraph and
+                        * not on the beginning of some line in the paragraph */
+                       if (success && webkit_dom_node_get_previous_sibling (prev_sibling))
+                               success = FALSE;
+               }
+
+               if (html_mode)
+                       success = WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (
+                               webkit_dom_node_get_parent_element (
+                                       WEBKIT_DOM_NODE (block)));
+       }
+
+       if (!success)
+               return FALSE;
+
+       if (citation_level == 1) {
+               gchar *inner_html;
+               WebKitDOMElement *paragraph;
+
+               inner_html = webkit_dom_html_element_get_inner_html (
+                       WEBKIT_DOM_HTML_ELEMENT (block));
+               webkit_dom_element_set_id (
+                       WEBKIT_DOM_ELEMENT (block), "-x-evo-to-remove");
+
+               paragraph = insert_new_line_into_citation (document, inner_html);
+               g_free (inner_html);
+
+               if (paragraph) {
+                       if (html_mode) {
+                               webkit_dom_node_insert_before (
+                                       WEBKIT_DOM_NODE (paragraph),
+                                       WEBKIT_DOM_NODE (selection_start_marker),
+                                       webkit_dom_node_get_first_child (
+                                               WEBKIT_DOM_NODE (paragraph)),
+                                       NULL);
+                               webkit_dom_node_insert_before (
+                                       WEBKIT_DOM_NODE (paragraph),
+                                       WEBKIT_DOM_NODE (selection_end_marker),
+                                       webkit_dom_node_get_first_child (
+                                               WEBKIT_DOM_NODE (paragraph)),
+                                       NULL);
+
+                       }
+
+                       remove_quoting_from_element (paragraph);
+                       remove_wrapping_from_element (paragraph);
+               }
+
+               if (block)
+                       remove_node (WEBKIT_DOM_NODE (block));
+               block = webkit_dom_document_get_element_by_id (
+                       document, "-x-evo-to-remove");
+               if (block)
+                       remove_node (WEBKIT_DOM_NODE (block));
+
+               if (paragraph)
+                       remove_node_if_empty (
+                               webkit_dom_node_get_next_sibling (
+                                       WEBKIT_DOM_NODE (paragraph)));
+       }
+
+       if (citation_level > 1) {
+               gint length, word_wrap_length;
+               WebKitDOMNode *parent;
+
+               word_wrap_length = extension->priv->word_wrap_length;
+               length =  word_wrap_length - 2 * (citation_level - 1);
+
+               if (html_mode) {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (block),
+                               WEBKIT_DOM_NODE (selection_start_marker),
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (block)),
+                               NULL);
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (block),
+                               WEBKIT_DOM_NODE (selection_end_marker),
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (block)),
+                               NULL);
+
+               }
+
+               remove_quoting_from_element (block);
+               remove_wrapping_from_element (block);
+
+               block = dom_wrap_paragraph_length (document, block, length);
+               webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
+               quote_plain_text_element_after_wrapping (document, block, citation_level - 1);
+
+               parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (block));
+
+               if (!webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (block))) {
+                       /* Currect block is in the beginning of citation, just move it
+                        * before the citation where already is */
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (parent),
+                               WEBKIT_DOM_NODE (block),
+                               parent,
+                               NULL);
+               } else if (!webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (block))) {
+                       /* Currect block is at the end of the citation, just move it
+                        * after the citation where already is */
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (parent),
+                               WEBKIT_DOM_NODE (block),
+                               webkit_dom_node_get_next_sibling (parent),
+                               NULL);
+               } else {
+                       /* Current block is somewhere in the middle of the citation
+                        * so we need to split the citation and insert the block into
+                        * the citation that is one level lower */
+                       WebKitDOMNode *clone, *child;
+
+                       clone = webkit_dom_node_clone_node (parent, FALSE);
+
+                       /* Move nodes that are after the currect block into the
+                        * new blockquote */
+                       child = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (block));
+                       while (child) {
+                               WebKitDOMNode *next = webkit_dom_node_get_next_sibling (child);
+                               webkit_dom_node_append_child (clone, child, NULL);
+                               child = next;
+                       }
+
+                       clone = webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (parent),
+                               clone,
+                               webkit_dom_node_get_next_sibling (parent),
+                               NULL);
+
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (parent),
+                               WEBKIT_DOM_NODE (block),
+                               clone,
+                               NULL);
+               }
+       }
+
+       return success;
+}
+
+static gboolean
+prevent_from_deleting_last_element_in_body (WebKitDOMDocument *document)
+{
+       gboolean ret_val = FALSE;
+       WebKitDOMHTMLElement *body;
+       WebKitDOMNodeList *list;
+
+       body = webkit_dom_document_get_body (document);
+
+       list = webkit_dom_node_get_child_nodes (WEBKIT_DOM_NODE (body));
+
+       if (webkit_dom_node_list_get_length (list) <= 1) {
+               gchar *content;
+
+               content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (body));
+
+               if (!*content)
+                       ret_val = TRUE;
+
+               g_free (content);
+
+               if (webkit_dom_element_query_selector (WEBKIT_DOM_ELEMENT (body), "img", NULL))
+                       ret_val = FALSE;
+       }
+       g_object_unref (list);
+
+       return ret_val;
+}
+
+static void
+insert_quote_symbols (WebKitDOMHTMLElement *element,
+                      gint quote_level,
+                      gboolean skip_first,
+                      gboolean insert_newline)
+{
+       gchar *text;
+       gint ii;
+       GString *output;
+       gchar *quotation;
+
+       if (!WEBKIT_DOM_IS_HTML_ELEMENT (element))
+               return;
+
+       text = webkit_dom_html_element_get_inner_html (element);
+       output = g_string_new ("");
+       quotation = get_quotation_for_level (quote_level);
+
+       if (g_strcmp0 (text, "\n") == 0) {
+               g_string_append (output, "<span class=\"-x-evo-quoted\">");
+               g_string_append (output, quotation);
+               g_string_append (output, "</span>");
+               g_string_append (output, "\n");
+       } else {
+               gchar **lines;
+
+               lines = g_strsplit (text, "\n", 0);
+
+               for (ii = 0; lines[ii]; ii++) {
+                       if (ii == 0 && skip_first) {
+                               if (g_strv_length (lines) == 1) {
+                                       g_strfreev (lines);
+                                       goto exit;
+                               }
+                               g_string_append (output, lines[ii]);
+                               g_string_append (output, "\n");
+                       }
+
+                       g_string_append (output, "<span class=\"-x-evo-quoted\">");
+                       g_string_append (output, quotation);
+                       g_string_append (output, "</span>");
+
+                       /* Insert line of text */
+                       g_string_append (output, lines[ii]);
+                       if ((ii == g_strv_length (lines) - 1) &&
+                           !g_str_has_suffix (text, "\n") && !insert_newline) {
+                               /* If we are on last line and node's text doesn't
+                                * end with \n, don't insert it */
+                               break;
+                       }
+                       g_string_append (output, "\n");
+               }
+
+               g_strfreev (lines);
+       }
+
+       webkit_dom_html_element_set_inner_html (element, output->str, NULL);
+ exit:
+       g_free (quotation);
+       g_free (text);
+       g_string_free (output, TRUE);
+}
+
+static void
+quote_node (WebKitDOMDocument *document,
+           WebKitDOMNode *node,
+           gint quote_level)
+{
+       gboolean skip_first = FALSE;
+       gboolean insert_newline = FALSE;
+       gboolean is_html_node = FALSE;
+       WebKitDOMElement *wrapper;
+       WebKitDOMNode *node_clone, *prev_sibling, *next_sibling;
+
+       /* Don't quote when we are not in citation */
+       if (quote_level == 0)
+               return;
+
+       if (WEBKIT_DOM_IS_COMMENT (node))
+               return;
+
+       if (WEBKIT_DOM_IS_HTML_ELEMENT (node)) {
+               insert_quote_symbols (
+                       WEBKIT_DOM_HTML_ELEMENT (node), quote_level, FALSE, FALSE);
+               return;
+       }
+
+       prev_sibling = webkit_dom_node_get_previous_sibling (node);
+       next_sibling = webkit_dom_node_get_next_sibling (node);
+
+       is_html_node =
+               !WEBKIT_DOM_IS_TEXT (prev_sibling) &&
+               !WEBKIT_DOM_IS_COMMENT (prev_sibling) && (
+               WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling) ||
+               element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "b") ||
+               element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "i") ||
+               element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "u"));
+
+       if (prev_sibling && is_html_node)
+               skip_first = TRUE;
+
+       /* Skip the BR between first blockquote and pre */
+       if (quote_level == 1 && next_sibling && WEBKIT_DOM_IS_HTML_PRE_ELEMENT (next_sibling))
+               return;
+
+       /* Do temporary wrapper */
+       wrapper = webkit_dom_document_create_element (document, "SPAN", NULL);
+       webkit_dom_element_set_class_name (wrapper, "-x-evo-temp-text-wrapper");
+
+       node_clone = webkit_dom_node_clone_node (node, TRUE);
+
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (wrapper),
+               node_clone,
+               NULL);
+
+       insert_quote_symbols (
+               WEBKIT_DOM_HTML_ELEMENT (wrapper),
+               quote_level,
+               skip_first,
+               insert_newline);
+
+       webkit_dom_node_replace_child (
+               webkit_dom_node_get_parent_node (node),
+               WEBKIT_DOM_NODE (wrapper),
+               node,
+               NULL);
+}
+
+static void
+insert_quote_symbols_before_node (WebKitDOMDocument *document,
+                                  WebKitDOMNode *node,
+                                  gint quote_level,
+                                  gboolean is_html_node)
+{
+       gboolean skip, wrap_br;
+       gchar *quotation;
+       WebKitDOMElement *element;
+
+       quotation = get_quotation_for_level (quote_level);
+       element = webkit_dom_document_create_element (document, "SPAN", NULL);
+       element_add_class (element, "-x-evo-quoted");
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (element), quotation, NULL);
+
+       /* Don't insert temporary BR before BR that is used for wrapping */
+       skip = WEBKIT_DOM_IS_HTML_BR_ELEMENT (node);
+       wrap_br = element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-wrap-br");
+       skip = skip && wrap_br;
+
+       if (is_html_node && !skip) {
+               WebKitDOMElement *new_br;
+
+               new_br = webkit_dom_document_create_element (document, "br", NULL);
+               element_add_class (new_br, "-x-evo-temp-br");
+
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_parent_node (node),
+                       WEBKIT_DOM_NODE (new_br),
+                       node,
+                       NULL);
+       }
+
+       webkit_dom_node_insert_before (
+               webkit_dom_node_get_parent_node (node),
+               WEBKIT_DOM_NODE (element),
+               node,
+               NULL);
+
+       if (is_html_node && !wrap_br)
+               remove_node (node);
+
+       g_free (quotation);
+}
+
+static gboolean
+element_is_selection_marker (WebKitDOMElement *element)
+{
+       gboolean is_marker = FALSE;
+
+       is_marker =
+               element_has_id (element, "-x-evo-selection-start-marker") ||
+               element_has_id (element, "-x-evo-selection-end-marker");
+
+       return is_marker;
+}
+
+static gboolean
+check_if_suppress_next_node (WebKitDOMNode *node)
+{
+       if (!node)
+               return FALSE;
+
+       if (node && WEBKIT_DOM_IS_ELEMENT (node))
+               if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node)))
+                       if (!webkit_dom_node_get_previous_sibling (node))
+                               return FALSE;
+
+       return TRUE;
+}
+
+static void
+quote_br_node (WebKitDOMNode *node,
+               gint quote_level)
+{
+       gchar *quotation, *content;
+
+       quotation = get_quotation_for_level (quote_level);
+
+       content = g_strconcat (
+               "<span class=\"-x-evo-quoted\">",
+               quotation,
+               "</span><br class=\"-x-evo-temp-br\">",
+               NULL);
+
+       webkit_dom_html_element_set_outer_html (
+               WEBKIT_DOM_HTML_ELEMENT (node),
+               content,
+               NULL);
+
+       g_free (content);
+       g_free (quotation);
+}
+
+static void
+quote_plain_text_recursive (WebKitDOMDocument *document,
+                           WebKitDOMNode *node,
+                           WebKitDOMNode *start_node,
+                           gint quote_level)
+{
+       gboolean skip_node = FALSE;
+       gboolean move_next = FALSE;
+       gboolean suppress_next = FALSE;
+       gboolean is_html_node = FALSE;
+       gboolean next = FALSE;
+       WebKitDOMNode *next_sibling, *prev_sibling;
+
+       node = webkit_dom_node_get_first_child (node);
+
+       while (node) {
+               gchar *text_content;
+
+               skip_node = FALSE;
+               move_next = FALSE;
+               is_html_node = FALSE;
+
+               if (WEBKIT_DOM_IS_COMMENT (node) ||
+                   WEBKIT_DOM_IS_HTML_META_ELEMENT (node) ||
+                   WEBKIT_DOM_IS_HTML_STYLE_ELEMENT (node) ||
+                   WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (node)) {
+
+                       move_next = TRUE;
+                       goto next_node;
+               }
+
+               prev_sibling = webkit_dom_node_get_previous_sibling (node);
+               next_sibling = webkit_dom_node_get_next_sibling (node);
+
+               if (WEBKIT_DOM_IS_TEXT (node)) {
+                       /* Start quoting after we are in blockquote */
+                       if (quote_level > 0 && !suppress_next) {
+                               /* When quoting text node, we are wrappering it and
+                                * afterwards replacing it with that wrapper, thus asking
+                                * for next_sibling after quoting will return NULL bacause
+                                * that node don't exist anymore */
+                               quote_node (document, node, quote_level);
+                               node = next_sibling;
+                               skip_node = TRUE;
+                       }
+
+                       goto next_node;
+               }
+
+               if (!(WEBKIT_DOM_IS_ELEMENT (node) || WEBKIT_DOM_IS_HTML_ELEMENT (node)))
+                       goto next_node;
+
+               if (element_has_id (WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-position")) {
+                       if (quote_level > 0)
+                               element_add_class (
+                                       WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-quoting");
+
+                       move_next = TRUE;
+                       suppress_next = TRUE;
+                       next = FALSE;
+                       goto next_node;
+               }
+
+               if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node))) {
+                       /* If there is collapsed selection in the beginning of line
+                        * we cannot suppress first text that is after the end of
+                        * selection */
+                       suppress_next = check_if_suppress_next_node (prev_sibling);
+                       if (suppress_next)
+                               next = FALSE;
+                       move_next = TRUE;
+                       goto next_node;
+               }
+
+               if (!WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) &&
+                   webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (node)) != 0)
+                       goto with_children;
+
+               /* Even in plain text mode we can have some basic html element
+                * like anchor and others. When Forwaring e-mail as Quoted EMFormat
+                * generates header that contatains <b> tags (bold font).
+                * We have to treat these elements separately to avoid
+                * modifications of theirs inner texts */
+               is_html_node =
+                       WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) ||
+                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "b") ||
+                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "i") ||
+                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "u");
+
+               if (is_html_node) {
+                       gboolean wrap_br;
+
+                       wrap_br =
+                               prev_sibling &&
+                               WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling) &&
+                               element_has_class (
+                                       WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-wrap-br");
+
+                       if (!prev_sibling || wrap_br)
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+
+                       if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling) && !wrap_br)
+                               insert_quote_symbols_before_node (
+                                       document, prev_sibling, quote_level, TRUE);
+
+                       move_next = TRUE;
+                       goto next_node;
+               }
+
+               /* If element doesn't have children, we can quote it */
+               if (is_citation_node (node)) {
+                       /* Citation with just text inside */
+                       quote_node (document, node, quote_level + 1);
+                       /* Set citation as quoted */
+                       element_add_class (
+                               WEBKIT_DOM_ELEMENT (node),
+                               "-x-evo-plaintext-quoted");
+
+                       move_next = TRUE;
+                       goto next_node;
+               }
+
+               if (!WEBKIT_DOM_IS_HTML_BR_ELEMENT (node)) {
+                       if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling)) {
+                               move_next = TRUE;
+                               goto next_node;
+                       }
+                       goto not_br;
+               } else if (element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-first-br") ||
+                          element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-last-br")) {
+                       quote_br_node (node, quote_level);
+                       node = next_sibling;
+                       skip_node = TRUE;
+                       goto next_node;
+               }
+
+               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+                   WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (next_sibling) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
+                       /* Situation when anchors are alone on line */
+                       text_content = webkit_dom_node_get_text_content (prev_sibling);
+
+                       if (g_str_has_suffix (text_content, "\n")) {
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+                               remove_node (node);
+                               g_free (text_content);
+                               node = next_sibling;
+                               skip_node = TRUE;
+                               goto next_node;
+                       }
+                       g_free (text_content);
+               }
+
+               if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling)) {
+                       quote_br_node (prev_sibling, quote_level);
+                       node = next_sibling;
+                       skip_node = TRUE;
+                       goto next_node;
+               }
+
+               if (!prev_sibling && !next_sibling) {
+                       WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
+
+                       if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) ||
+                           WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) ||
+                           (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
+                            !is_citation_node (parent))) {
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+
+                               goto next_node;
+                       }
+               }
+
+               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
+                       text_content = webkit_dom_node_get_text_content (prev_sibling);
+                       if (text_content && !*text_content) {
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+
+                               g_free (text_content);
+                               goto next_node;
+
+                       }
+
+                       g_free (text_content);
+               }
+
+               if (is_citation_node (prev_sibling)) {
+                       insert_quote_symbols_before_node (
+                               document, node, quote_level, FALSE);
+                       goto next_node;
+               }
+
+               if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (node) &&
+                   !next_sibling &&
+                   element_is_selection_marker (WEBKIT_DOM_ELEMENT (prev_sibling))) {
+                       insert_quote_symbols_before_node (
+                               document, node, quote_level, FALSE);
+                       goto next_node;
+               }
+
+               if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (node)) {
+                       move_next = TRUE;
+                       goto next_node;
+               }
+
+ not_br:
+               text_content = webkit_dom_node_get_text_content (node);
+               if (text_content && !*text_content) {
+                       g_free (text_content);
+                       move_next = TRUE;
+                       goto next_node;
+               }
+               g_free (text_content);
+
+               quote_node (document, node, quote_level);
+
+               move_next = TRUE;
+               goto next_node;
+
+ with_children:
+               if (is_citation_node (node)) {
+                       /* Go deeper and increase level */
+                       quote_plain_text_recursive (
+                               document, node, start_node, quote_level + 1);
+                       /* set citation as quoted */
+                       element_add_class (
+                               WEBKIT_DOM_ELEMENT (node),
+                               "-x-evo-plaintext-quoted");
+                       move_next = TRUE;
+               } else {
+                       quote_plain_text_recursive (
+                               document, node, start_node, quote_level);
+                       move_next = TRUE;
+               }
+ next_node:
+               if (next) {
+                       suppress_next = FALSE;
+                       next = FALSE;
+               }
+
+               if (suppress_next)
+                       next = TRUE;
+
+               if (!skip_node) {
+                       /* Move to next node */
+                       if (!move_next && webkit_dom_node_has_child_nodes (node)) {
+                               node = webkit_dom_node_get_first_child (node);
+                       } else if (webkit_dom_node_get_next_sibling (node)) {
+                               node = webkit_dom_node_get_next_sibling (node);
+                       } else {
+                               return;
+                       }
+               }
+       }
+}
+
+WebKitDOMElement *
+dom_quote_plain_text_element (WebKitDOMDocument *document,
+                              WebKitDOMElement *element)
+{
+       WebKitDOMNode *element_clone;
+       WebKitDOMNodeList *list;
+       gint ii, length, level;
+
+       element_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (element), TRUE);
+       level = get_citation_level (WEBKIT_DOM_NODE (element), TRUE);
+
+       /* Remove old quote characters if the exists */
+       list = webkit_dom_element_query_selector_all (
+               WEBKIT_DOM_ELEMENT (element_clone), "span.-x-evo-quoted", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for  (ii = 0; ii < length; ii++)
+               remove_node (webkit_dom_node_list_item (list, ii));
+
+       webkit_dom_node_normalize (element_clone);
+       quote_plain_text_recursive (
+               document, element_clone, element_clone, level);
+
+       /* Set citation as quoted */
+       if (is_citation_node (element_clone))
+               element_add_class (
+                       WEBKIT_DOM_ELEMENT (element_clone),
+                       "-x-evo-plaintext-quoted");
+
+       /* Replace old element with one, that is quoted */
+       webkit_dom_node_replace_child (
+               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+               element_clone,
+               WEBKIT_DOM_NODE (element),
+               NULL);
+
+       g_object_unref (list);
+       return WEBKIT_DOM_ELEMENT (element_clone);
+}
+
+/**
+ * e_html_editor_view_quote_plain_text:
+ * @view: an #EHTMLEditorView
+ *
+ * Quote text inside citation blockquotes in plain text mode.
+ *
+ * As this function is cloning and replacing all citation blockquotes keep on
+ * mind that any pointers to nodes inside these blockquotes will be invalidated.
+ */
+WebKitDOMElement *
+dom_quote_plain_text (WebKitDOMDocument *document)
+{
+       WebKitDOMHTMLElement *body;
+       WebKitDOMNode *body_clone;
+       WebKitDOMNamedNodeMap *attributes;
+       WebKitDOMNodeList *list;
+       WebKitDOMElement *element;
+       gint ii, length;
+       gulong attributes_length;
+
+       /* Check if the document is already quoted */
+       element = webkit_dom_document_query_selector (
+               document, ".-x-evo-plaintext-quoted", NULL);
+       if (element)
+               return NULL;
+
+       body = webkit_dom_document_get_body (document);
+       body_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
+
+       /* Clean unwanted spaces before and after blockquotes */
+       list = webkit_dom_element_query_selector_all (
+               WEBKIT_DOM_ELEMENT (body_clone), "blockquote[type|=cite]", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *blockquote = webkit_dom_node_list_item (list, ii);
+               WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (blockquote);
+               WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (blockquote);
+
+               if (prev_sibling && WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling))
+                       remove_node (prev_sibling);
+
+               if (next_sibling && WEBKIT_DOM_IS_HTML_BR_ELEMENT (next_sibling))
+                       remove_node (next_sibling);
+
+               if (webkit_dom_node_has_child_nodes (blockquote)) {
+                       WebKitDOMNode *child = webkit_dom_node_get_first_child (blockquote);
+                       if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (child))
+                               remove_node (child);
+               }
+       }
+       g_object_unref (list);
+
+       webkit_dom_node_normalize (body_clone);
+       quote_plain_text_recursive (document, body_clone, body_clone, 0);
+
+       /* Copy attributes */
+       attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
+       attributes_length = webkit_dom_named_node_map_get_length (attributes);
+       for (ii = 0; ii < attributes_length; ii++) {
+               gchar *name, *value;
+               WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
+
+               name = webkit_dom_node_get_local_name (node);
+               value = webkit_dom_node_get_node_value (node);
+
+               webkit_dom_element_set_attribute (
+                       WEBKIT_DOM_ELEMENT (body_clone), name, value, NULL);
+
+               g_free (name);
+               g_free (value);
+       }
+       g_object_unref (attributes);
+
+       /* Replace old BODY with one, that is quoted */
+       webkit_dom_node_replace_child (
+               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
+               body_clone,
+               WEBKIT_DOM_NODE (body),
+               NULL);
+
+       return WEBKIT_DOM_ELEMENT (body_clone);
+}
+
+/**
+ * e_html_editor_view_dequote_plain_text:
+ * @view: an #EHTMLEditorView
+ *
+ * Dequote already quoted plain text in editor.
+ * Editor have to be quoted with e_html_editor_view_quote_plain_text otherwise
+ * it's not working.
+ */
+void
+dom_dequote_plain_text (WebKitDOMDocument *document)
+{
+       WebKitDOMNodeList *paragraphs;
+       gint length, ii;
+
+       paragraphs = webkit_dom_document_query_selector_all (
+               document, "blockquote.-x-evo-plaintext-quoted", NULL);
+       length = webkit_dom_node_list_get_length (paragraphs);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMElement *element;
+
+               element = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (paragraphs, ii));
+
+               if (is_citation_node (WEBKIT_DOM_NODE (element))) {
+                       element_remove_class (element, "-x-evo-plaintext-quoted");
+                       remove_quoting_from_element (element);
+               }
+       }
+       g_object_unref (paragraphs);
+}
+
+static gboolean
+create_anchor_for_link (const GMatchInfo *info,
+                        GString *res,
+                        gpointer data)
+{
+       gint offset = 0;
+       gchar *match;
+       gboolean address_surrounded;
+
+       match = g_match_info_fetch (info, 0);
+
+       address_surrounded =
+               strstr (match, "@") &&
+               g_str_has_prefix (match, "&lt;") &&
+               g_str_has_suffix (match, "&gt;");
+
+       if (address_surrounded)
+               offset += 4;
+
+       if (g_str_has_prefix (match, "&nbsp;"))
+               offset += 6;
+
+       if (address_surrounded)
+               g_string_append (res, "&lt;");
+
+       g_string_append (res, "<a href=\"");
+       if (strstr (match, "@")) {
+               g_string_append (res, "mailto:";);
+               g_string_append (res, match + offset);
+               if (address_surrounded)
+                       g_string_truncate (res, res->len - 4);
+
+               g_string_append (res, "\">");
+               g_string_append (res, match + offset);
+               if (address_surrounded)
+                       g_string_truncate (res, res->len - 4);
+       } else {
+               g_string_append (res, match + offset);
+               g_string_append (res, "\">");
+               g_string_append (res, match + offset);
+       }
+       g_string_append (res, "</a>");
+
+       if (address_surrounded)
+               g_string_append (res, "&gt;");
+
+       g_free (match);
+
+       return FALSE;
+}
+
+static gboolean
+replace_to_nbsp (const GMatchInfo *info,
+                 GString *res,
+                 gboolean use_nbsp)
+{
+       gchar *match;
+       const gchar *string, *previous_tab;
+       gint ii, length = 0, start = 0;
+
+       match = g_match_info_fetch (info, 0);
+       g_match_info_fetch_pos (info, 0, &start, NULL);
+       string = g_match_info_get_string (info);
+
+       if (start > 0) {
+               previous_tab = g_strrstr_len (string, start, "\x9");
+               if (previous_tab && *previous_tab) {
+                       const char *act_tab = NULL;
+                       act_tab = strstr (previous_tab + 1, "\x9");
+
+                       if (act_tab && *act_tab) {
+                               length = act_tab - previous_tab - 1;
+                               length = TAB_LENGTH - length;
+                       }
+               }
+       }
+
+       if (length == 0) {
+               if (strstr (match, "\x9")) {
+                       gint tab_count = strlen (match);
+                       length = TAB_LENGTH - (start %  TAB_LENGTH);
+                       length += (tab_count - 1) * TAB_LENGTH;
+               } else
+                       length = strlen (match);
+       }
+
+       for (ii = 0; ii < length; ii++)
+               g_string_append (res, "&nbsp;");
+
+       g_free (match);
+
+       return FALSE;
+}
+
+static gboolean
+surround_links_with_anchor (const gchar *text)
+{
+       return (strstr (text, "http") || strstr (text, "ftp") ||
+               strstr (text, "www") || strstr (text, "@"));
+}
+
+static void
+append_new_paragraph (WebKitDOMElement *parent,
+                      WebKitDOMElement **paragraph)
+{
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (parent),
+               WEBKIT_DOM_NODE (*paragraph),
+               NULL);
+
+       *paragraph = NULL;
+}
+
+static WebKitDOMElement *
+create_and_append_new_paragraph (WebKitDOMDocument *document,
+                                 WebKitDOMElement *parent,
+                                 const gchar *content)
+{
+       WebKitDOMElement *paragraph;
+
+       paragraph = dom_get_paragraph_element (document, -1, 0);
+
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (paragraph),
+               content,
+               NULL);
+
+       append_new_paragraph (parent, &paragraph);
+
+       return paragraph;
+}
+
+static void
+append_citation_mark (WebKitDOMDocument *document,
+                      WebKitDOMElement *parent,
+                     const gchar *citation_mark_text)
+{
+       WebKitDOMText *text;
+
+       text = webkit_dom_document_create_text_node (document, citation_mark_text);
+
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (parent),
+               WEBKIT_DOM_NODE (text),
+               NULL);
+}
+
+static glong
+get_decoded_line_length (WebKitDOMDocument *document,
+                         const gchar *line_text)
+{
+       gchar *decoded_text;
+       glong length = 0;
+       WebKitDOMElement *decode;
+
+       decode = webkit_dom_document_create_element (document, "DIV", NULL);
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (decode), line_text, NULL);
+
+       decoded_text = webkit_dom_html_element_get_inner_text (
+               WEBKIT_DOM_HTML_ELEMENT (decode));
+       length = g_utf8_strlen (decoded_text, -1);
+
+       g_free (decoded_text);
+       g_object_unref (decode);
+
+       return length;
+}
+
+static gboolean
+check_if_end_paragraph (const gchar *input,
+                        glong length)
+{
+       const gchar *next_space;
+
+       next_space = strstr (input, " ");
+       if (next_space) {
+               const gchar *next_br;
+               glong length_next_word =
+                       next_space - input - 4;
+
+               if (g_str_has_prefix (input + 4, "<br>"))
+                       length_next_word = 0;
+
+               if (length_next_word > 0)
+                       next_br = strstr (input + 4, "<br>");
+
+               if (length_next_word > 0 && next_br < next_space)
+                       length_next_word = 0;
+
+               if (length_next_word + length < 72)
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
+/* This parses the HTML code (that contains just text, &nbsp; and BR elements)
+ * into paragraphs.
+ * HTML code in that format we can get by taking innerText from some element,
+ * setting it to another one and finally getting innerHTML from it */
+static void
+parse_html_into_paragraphs (WebKitDOMDocument *document,
+                            WebKitDOMElement *blockquote,
+                            const gchar *html)
+{
+       gboolean ignore_next_br = FALSE;
+       gboolean first_element = TRUE;
+       gboolean citation_was_first_element = FALSE;
+       const gchar *prev_br, *next_br;
+       gchar *inner_html;
+       GRegex *regex_nbsp = NULL, *regex_links = NULL;
+       GString *start, *end;
+       WebKitDOMElement *paragraph = NULL;
+
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (blockquote), "", NULL);
+
+       prev_br = html;
+       next_br = strstr (prev_br, "<br>");
+
+       /* Replace single spaces on the beginning of line, 2+ spaces and
+        * tabulators with non breaking spaces */
+       regex_nbsp = g_regex_new ("^\\s{1}|\\s{2,}|\x9", 0, 0, NULL);
+       regex_links = g_regex_new (URL_PATTERN, 0, 0, NULL);
+
+       while (next_br) {
+               gboolean local_ignore_next_br = ignore_next_br;
+               gboolean prevent_block = TRUE;
+               const gchar *citation = NULL, *citation_end = NULL;
+               const gchar *rest = NULL, *with_br = NULL;
+               gchar *to_insert = NULL;
+
+               ignore_next_br = FALSE;
+
+               to_insert = g_utf8_substring (
+                       prev_br, 0, g_utf8_pointer_to_offset (prev_br, next_br));
+
+               with_br = strstr (to_insert, "<br>");
+               citation = strstr (to_insert, "##CITATION_");
+               if (citation) {
+                       gchar *citation_mark;
+
+                       if (strstr (citation, "END##")) {
+                               ignore_next_br = TRUE;
+                               if (paragraph)
+                                       append_new_paragraph (blockquote, &paragraph);
+                       }
+
+                       citation_end = strstr (citation + 2, "##");
+                       if (citation_end)
+                               rest = citation_end + 2;
+
+                       if (first_element)
+                               citation_was_first_element = TRUE;
+
+                       if (paragraph)
+                               append_new_paragraph (blockquote, &paragraph);
+
+                       citation_mark = g_utf8_substring (
+                               citation, 0, g_utf8_pointer_to_offset (citation, rest));
+
+                       append_citation_mark (document, blockquote, citation_mark);
+
+                       g_free (citation_mark);
+               } else
+                       rest = with_br ?
+                               to_insert + 4 + (with_br - to_insert) : to_insert;
+
+               if (!rest)
+                       goto next;
+
+               if (*rest) {
+                       gboolean empty = FALSE;
+                       gchar *truncated = g_strdup (rest);
+                       gchar *rest_to_insert;
+
+                       g_strchomp (truncated);
+                       empty = !*truncated && strlen (rest) > 0;
+
+                       if (strchr (" +- *=", *rest))
+                               prevent_block = FALSE;
+
+                       rest_to_insert = g_regex_replace_eval (
+                               regex_nbsp,
+                               empty ? rest : truncated,
+                               -1,
+                               0,
+                               0,
+                               (GRegexEvalCallback) replace_to_nbsp,
+                               NULL,
+                               NULL);
+                       g_free (truncated);
+
+                       if (surround_links_with_anchor (rest_to_insert)) {
+                               truncated = g_regex_replace_eval (
+                                       regex_links,
+                                       rest_to_insert,
+                                       -1,
+                                       0,
+                                       0,
+                                       create_anchor_for_link,
+                                       NULL,
+                                       NULL);
+
+                               g_free (rest_to_insert);
+                               rest_to_insert = truncated;
+                       }
+
+                       if (g_strcmp0 (rest_to_insert, UNICODE_ZERO_WIDTH_SPACE) == 0) {
+                               paragraph = create_and_append_new_paragraph (
+                                       document, blockquote, "<br>");
+                       } else if (prevent_block) {
+                               gchar *html;
+                               gchar *new_content;
+
+                               if (!paragraph)
+                                       paragraph = dom_get_paragraph_element (
+                                               document, -1, 0);
+
+                               html = webkit_dom_html_element_get_inner_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (paragraph));
+
+                               new_content = g_strconcat (
+                                       html && *html ? html : "",
+                                       html && *html ? " " : "",
+                                       rest_to_insert ? rest_to_insert : "<br>",
+                                       NULL),
+
+                               webkit_dom_html_element_set_inner_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (paragraph),
+                                       new_content,
+                                       NULL);
+
+                               g_free (html);
+                               g_free (new_content);
+                       } else
+                               paragraph = create_and_append_new_paragraph (
+                                       document, blockquote, rest_to_insert);
+
+                       if (rest_to_insert && *rest_to_insert && prevent_block && paragraph) {
+                               glong length = 0;
+
+                               if (strstr (rest, "&"))
+                                       length = get_decoded_line_length (document, rest);
+                               else
+                                       length = g_utf8_strlen (rest, -1);
+
+                               /* End the block if there is line with less that 62 characters. */
+                               /* The shorter line can also mean that there is a long word on next
+                                * line (and the line was wrapped). So look at it and decide what to do. */
+                               if (length < 62 && check_if_end_paragraph (next_br, length))
+                                       append_new_paragraph (blockquote, &paragraph);
+
+                               if (length > 72)
+                                       append_new_paragraph (blockquote, &paragraph);
+                       }
+
+                       citation_was_first_element = FALSE;
+
+                       g_free (rest_to_insert);
+               } else if (with_br) {
+                       if (!citation && (!local_ignore_next_br || citation_was_first_element)) {
+                               if (paragraph)
+                                       append_new_paragraph (blockquote, &paragraph);
+
+                               paragraph = create_and_append_new_paragraph (
+                                       document, blockquote, "<br>");
+
+                               citation_was_first_element = FALSE;
+                       } else if (first_element && !citation_was_first_element) {
+                               paragraph = create_and_append_new_paragraph (
+                                       document,
+                                       blockquote,
+                                       "<br class=\"-x-evo-first-br\">");
+                       }
+               }
+ next:
+               first_element = FALSE;
+               prev_br = next_br;
+               next_br = strstr (prev_br + 4, "<br>");
+               g_free (to_insert);
+       }
+
+       if (paragraph)
+               append_new_paragraph (blockquote, &paragraph);
+
+       if (g_utf8_strlen (prev_br, -1) > 0) {
+               gchar *rest_to_insert;
+               gchar *truncated = g_strdup (
+                       g_str_has_prefix (prev_br, "<br>") ? prev_br + 4 : prev_br);
+
+               /* On the end on the HTML there is always an extra BR element,
+                * so skip it and if there was another BR element before it mark it. */
+               if (truncated && !*truncated) {
+                       WebKitDOMNode *child;
+
+                       child = webkit_dom_node_get_last_child (
+                               WEBKIT_DOM_NODE (blockquote));
+                       if (child) {
+                               child = webkit_dom_node_get_first_child (child);
+                               if (child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)) {
+                                       element_add_class (
+                                               WEBKIT_DOM_ELEMENT (child),
+                                               "-x-evo-last-br");
+                               }
+                       }
+                       g_free (truncated);
+                       goto end;
+               }
+
+               if (g_ascii_strncasecmp (truncated, "##CITATION_END##", 16) == 0) {
+                       append_citation_mark (document, blockquote, truncated);
+                       g_free (truncated);
+                       goto end;
+               }
+
+               g_strchomp (truncated);
+
+               rest_to_insert = g_regex_replace_eval (
+                       regex_nbsp,
+                       truncated,
+                       -1,
+                       0,
+                       0,
+                       (GRegexEvalCallback) replace_to_nbsp,
+                       NULL,
+                       NULL);
+               g_free (truncated);
+
+               if (surround_links_with_anchor (rest_to_insert)) {
+                       truncated = g_regex_replace_eval (
+                               regex_links,
+                               rest_to_insert,
+                               -1,
+                               0,
+                               0,
+                               create_anchor_for_link,
+                               NULL,
+                               NULL);
+
+                       g_free (rest_to_insert);
+                       rest_to_insert = truncated;
+               }
+
+               if (g_strcmp0 (rest_to_insert, UNICODE_ZERO_WIDTH_SPACE) == 0)
+                       create_and_append_new_paragraph (
+                               document, blockquote, "<br>");
+               else
+                       create_and_append_new_paragraph (
+                               document, blockquote, rest_to_insert);
+
+               g_free (rest_to_insert);
+       }
+
+ end:
+       /* Replace text markers with actual HTML blockquotes */
+       inner_html = webkit_dom_html_element_get_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (blockquote));
+       start = e_str_replace_string (
+               inner_html, "##CITATION_START##","<blockquote type=\"cite\">");
+       end = e_str_replace_string (
+               start->str, "##CITATION_END##", "</blockquote>");
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (blockquote), end->str, NULL);
+
+       g_regex_unref (regex_nbsp);
+       g_regex_unref (regex_links);
+       g_free (inner_html);
+       g_string_free (start, TRUE);
+       g_string_free (end, TRUE);
+}
+
+static void
+mark_citation (WebKitDOMElement *citation)
+{
+       gchar *inner_html, *surrounded;
+
+       inner_html = webkit_dom_html_element_get_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (citation));
+
+       surrounded = g_strconcat (
+               "<span>##CITATION_START##</span>", inner_html,
+               "<span>##CITATION_END##</span>", NULL);
+
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (citation), surrounded, NULL);
+
+       element_add_class (citation, "marked");
+
+       g_free (inner_html);
+       g_free (surrounded);
+}
+
+static gint
+create_text_markers_for_citations_in_document (WebKitDOMDocument *document)
+{
+       gint count = 0;
+       WebKitDOMElement *citation;
+
+       citation = webkit_dom_document_query_selector (
+               document, "blockquote[type=cite]:not(.marked)", NULL);
+
+       while (citation) {
+               mark_citation (citation);
+               count ++;
+
+               citation = webkit_dom_document_query_selector (
+                       document, "blockquote[type=cite]:not(.marked)", NULL);
+       }
+
+       return count;
+}
+
+static gint
+create_text_markers_for_citations_in_element (WebKitDOMElement *element)
+{
+       gint count = 0;
+       WebKitDOMElement *citation;
+
+       citation = webkit_dom_element_query_selector (
+               element, "blockquote[type=cite]:not(.marked)", NULL);
+
+       while (citation) {
+               mark_citation (citation);
+               count ++;
+
+               citation = webkit_dom_element_query_selector (
+                       element, "blockquote[type=cite]:not(.marked)", NULL);
+       }
+
+       return count;
+}
+
+static void
+quote_plain_text_elements_after_wrapping_in_document (WebKitDOMDocument *document)
+{
+       gint length, ii;
+       WebKitDOMNodeList *list;
+
+       list = webkit_dom_document_query_selector_all (
+               document, "blockquote[type=cite] > div.-x-evo-paragraph", NULL);
+
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++) {
+               gint citation_level;
+               WebKitDOMNode *child;
+
+               child = webkit_dom_node_list_item (list, ii);
+               citation_level = get_citation_level (child, TRUE);
+               quote_plain_text_element_after_wrapping (
+                       document, WEBKIT_DOM_ELEMENT (child), citation_level);
+       }
+       g_object_unref (list);
+}
+
+static void
+html_editor_convert_view_content (EHTMLEditorWebExtension *extension,
+                                  WebKitDOMDocument *document,
+                                  const gchar *preferred_text)
+{
+       gboolean start_bottom, empty = FALSE;
+       gchar *inner_html;
+       gint ii, length;
+       GSettings *settings;
+       WebKitDOMElement *paragraph, *content_wrapper, *top_signature;
+       WebKitDOMElement *cite_body, *signature, *wrapper;
+       WebKitDOMHTMLElement *body;
+       WebKitDOMNodeList *list;
+       WebKitDOMNode *node;
+
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom");
+       g_object_unref (settings);
+
+       body = webkit_dom_document_get_body (document);
+       /* Wrapper that will represent the new body. */
+       wrapper = webkit_dom_document_create_element (document, "div", NULL);
+
+       webkit_dom_element_set_attribute (
+               WEBKIT_DOM_ELEMENT (body), "data-converted", "", NULL);
+
+       cite_body = webkit_dom_document_query_selector (
+               document, "span.-x-evo-cite-body", NULL);
+
+       /* content_wrapper when the processed text will be placed. */
+       content_wrapper = webkit_dom_document_create_element (
+               document, cite_body ? "blockquote" : "div", NULL);
+       if (cite_body) {
+               webkit_dom_element_set_attribute (content_wrapper, "type", "cite", NULL);
+               webkit_dom_element_set_attribute (content_wrapper, "id", "-x-evo-main-cite", NULL);
+       }
+
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (wrapper), WEBKIT_DOM_NODE (content_wrapper), NULL);
+
+       /* Remove all previously inserted paragraphs. */
+       list = webkit_dom_document_query_selector_all (
+               document, ".-x-evo-paragraph", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++)
+               remove_node (webkit_dom_node_list_item (list, ii));
+       g_object_unref (list);
+
+       /* Insert the paragraph where the caret will be. */
+       paragraph = prepare_paragraph (document, TRUE);
+       webkit_dom_element_set_id (paragraph, "-x-evo-input-start");
+       webkit_dom_node_insert_before (
+               WEBKIT_DOM_NODE (wrapper),
+               WEBKIT_DOM_NODE (paragraph),
+               start_bottom ?
+                       webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (content_wrapper)) :
+                       WEBKIT_DOM_NODE (content_wrapper),
+               NULL);
+
+       /* Insert signature (if presented) to the right position. */
+       top_signature = webkit_dom_document_query_selector (
+               document, ".-x-evo-top-signature", NULL);
+       signature = webkit_dom_document_query_selector (
+               document, ".-x-evo-signature-content_wrapper", NULL);
+       if (signature) {
+               if (top_signature) {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (wrapper),
+                               WEBKIT_DOM_NODE (signature),
+                               start_bottom ?
+                                       WEBKIT_DOM_NODE (content_wrapper) :
+                                       webkit_dom_node_get_next_sibling (
+                                               WEBKIT_DOM_NODE (paragraph)),
+                               NULL);
+                       /* Insert NL after the signature */
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (wrapper),
+                               WEBKIT_DOM_NODE (prepare_paragraph (
+                                       selection, document, FALSE)),
+                               webkit_dom_node_get_next_sibling (
+                                       WEBKIT_DOM_NODE (signature)),
+                               NULL);
+               } else {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (wrapper),
+                               WEBKIT_DOM_NODE (signature),
+                               webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (
+                                       start_bottom ? paragraph : content_wrapper)),
+                               NULL);
+               }
+       }
+
+       /* Move credits to the body */
+       list = webkit_dom_document_query_selector_all (
+               document, "span.-x-evo-to-body[data-credits]", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *node, *child;
+
+               node = webkit_dom_node_list_item (list, ii);
+               while ((child = webkit_dom_node_get_first_child (node))) {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (wrapper),
+                               child,
+                               WEBKIT_DOM_NODE (content_wrapper),
+                               NULL);
+               }
+
+               remove_node (node);
+       }
+       g_object_unref (list);
+
+       /* Move headers to body */
+       list = webkit_dom_document_query_selector_all (
+               document, "span.-x-evo-to-body[data-headers]", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *node, *child;
+
+               node = webkit_dom_node_list_item (list, ii);
+               while ((child = webkit_dom_node_get_first_child (node))) {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (wrapper),
+                               child,
+                               WEBKIT_DOM_NODE (content_wrapper),
+                               NULL);
+               }
+
+               remove_node (node);
+       }
+       g_object_unref (list);
+
+       repair_gmail_blockquotes (document);
+       create_text_markers_for_citations_in_document (document);
+
+       if (preferred_text && *preferred_text)
+               webkit_dom_html_element_set_inner_text (
+                       WEBKIT_DOM_HTML_ELEMENT (content_wrapper), preferred_text, NULL);
+       else {
+               gchar *inner_text;
+
+               inner_text = webkit_dom_html_element_get_inner_text (body);
+               webkit_dom_html_element_set_inner_text (
+                       WEBKIT_DOM_HTML_ELEMENT (content_wrapper), inner_text, NULL);
+
+               g_free (inner_text);
+       }
+
+       inner_html = webkit_dom_html_element_get_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (content_wrapper));
+
+       /* Replace the old body with the new one. */
+       node = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), FALSE);
+       webkit_dom_node_replace_child (
+               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
+               node,
+               WEBKIT_DOM_NODE (body),
+               NULL);
+       body = WEBKIT_DOM_HTML_ELEMENT (node);
+
+       /* Copy all to nodes to the new body. */
+       while ((node = webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (wrapper)))) {
+               webkit_dom_node_insert_before (
+                       WEBKIT_DOM_NODE (body),
+                       WEBKIT_DOM_NODE (node),
+                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
+                       NULL);
+       }
+       remove_node (WEBKIT_DOM_NODE (wrapper));
+
+       /* FIXME XXX */
+       length = webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (body));
+       if (length <= 1) {
+               empty = TRUE;
+               if (length == 1) {
+                       WebKitDOMNode *child;
+
+                       child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+                       empty = child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child);
+               }
+       }
+
+       if (preferred_text && *preferred_text)
+               empty = FALSE;
+
+       if (!empty)
+               parse_html_into_paragraphs (document, content_wrapper, inner_html);
+
+       if (!cite_body) {
+               if (!empty) {
+                       WebKitDOMNode *child;
+
+                       while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (content_wrapper)))) 
{
+                               webkit_dom_node_insert_before (
+                                       webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (content_wrapper)),
+                                       child,
+                                       WEBKIT_DOM_NODE (content_wrapper),
+                                       NULL);
+                       }
+               }
+
+               remove_node (WEBKIT_DOM_NODE (content_wrapper));
+       }
+
+       if (e_html_editor_web_extension_is_message_from_edit_as_new (extension) ||
+           e_html_editor_web_extension_get_remove_initial_input_line (extension)) {
+               WebKitDOMNode *child;
+
+               remove_node (WEBKIT_DOM_NODE (paragraph));
+               child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+               if (child)
+                       add_selection_markers_into_element_start (
+                               document, WEBKIT_DOM_ELEMENT (child), NULL, NULL);
+       }
+
+       paragraph = webkit_dom_document_query_selector (document, "br.-x-evo-last-br", NULL);
+       if (paragraph)
+               webkit_dom_element_remove_attribute (paragraph, "class");
+       paragraph = webkit_dom_document_query_selector (document, "br.-x-evo-first-br", NULL);
+       if (paragraph)
+               webkit_dom_element_remove_attribute (paragraph, "class");
+
+       if (!is_in_html_mode (extension)) {
+               dom_wrap_paragraphs_in_document (document);
+
+               quote_plain_text_elements_after_wrapping_in_document (document);
+       }
+
+       dom_selection_restore (selection);
+       dom_force_spell_check (document);
+
+       /* Register on input event that is called when the content (body) is modified */
+       webkit_dom_event_target_add_event_listener (
+               WEBKIT_DOM_EVENT_TARGET (body),
+               "input",
+               G_CALLBACK (body_input_event_cb),
+               FALSE,
+               document);
+
+       g_free (inner_html);
+}
+
+static gint
+get_indentation_level (WebKitDOMElement *element)
+{
+       WebKitDOMElement *parent;
+       gint level = 1;
+
+       parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (element));
+       /* Count level of indentation */
+       while (!WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+               if (element_has_class (parent, "-x-evo-indented"))
+                       level++;
+
+               parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (parent));
+       }
+
+       return level;
+}
+
+static void
+process_blockquote (WebKitDOMElement *blockquote)
+{
+       WebKitDOMNodeList *list;
+       int jj, length;
+
+       /* First replace wrappers */
+       list = webkit_dom_element_query_selector_all (
+               blockquote, "span.-x-evo-temp-text-wrapper", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for (jj = 0; jj < length; jj++) {
+               WebKitDOMNode *quoted_node;
+               gchar *text_content;
+
+               quoted_node = webkit_dom_node_list_item (list, jj);
+               text_content = webkit_dom_node_get_text_content (quoted_node);
+               webkit_dom_html_element_set_outer_html (
+                       WEBKIT_DOM_HTML_ELEMENT (quoted_node), text_content, NULL);
+
+               g_free (text_content);
+       }
+       g_object_unref (list);
+
+       /* Afterwards replace quote nodes with symbols */
+       list = webkit_dom_element_query_selector_all (
+               blockquote, "span.-x-evo-quoted", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for (jj = 0; jj < length; jj++) {
+               WebKitDOMNode *quoted_node;
+               gchar *text_content;
+
+               quoted_node = webkit_dom_node_list_item (list, jj);
+               text_content = webkit_dom_node_get_text_content (quoted_node);
+               webkit_dom_html_element_set_outer_html (
+                       WEBKIT_DOM_HTML_ELEMENT (quoted_node), text_content, NULL);
+
+               g_free (text_content);
+       }
+       g_object_unref (list);
+
+       if (element_has_class (blockquote, "-x-evo-indented")) {
+               WebKitDOMNode *child;
+               gchar *spaces;
+
+               spaces = g_strnfill (4 * get_indentation_level (blockquote), ' ');
+
+               child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (blockquote));
+               while (child) {
+                       /* If next sibling is indented blockqoute skip it,
+                        * it will be processed afterwards */
+                       if (WEBKIT_DOM_IS_ELEMENT (child) &&
+                           element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-indented"))
+                               child = webkit_dom_node_get_next_sibling (child);
+
+                       if (WEBKIT_DOM_IS_TEXT (child)) {
+                               gchar *text_content;
+                               gchar *indented_text;
+
+                               text_content = webkit_dom_text_get_whole_text (WEBKIT_DOM_TEXT (child));
+                               indented_text = g_strconcat (spaces, text_content, NULL);
+
+                               webkit_dom_text_replace_whole_text (
+                                       WEBKIT_DOM_TEXT (child),
+                                       indented_text,
+                                       NULL);
+
+                               g_free (text_content);
+                               g_free (indented_text);
+                       }
+
+                       if (!child)
+                               break;
+
+                       /* Move to next node */
+                       if (webkit_dom_node_has_child_nodes (child))
+                               child = webkit_dom_node_get_first_child (child);
+                       else if (webkit_dom_node_get_next_sibling (child))
+                               child = webkit_dom_node_get_next_sibling (child);
+                       else {
+                               if (webkit_dom_node_is_equal_node (WEBKIT_DOM_NODE (blockquote), child))
+                                       break;
+
+                               child = webkit_dom_node_get_parent_node (child);
+                               if (child)
+                                       child = webkit_dom_node_get_next_sibling (child);
+                       }
+               }
+               g_free (spaces);
+
+               webkit_dom_element_remove_attribute (blockquote, "style");
+       }
+}
+
+/* Taken from GtkHTML */
+static gchar *
+get_alpha_value (gint value,
+                 gboolean lower)
+{
+       GString *str;
+       gchar *rv;
+       gint add = lower ? 'a' : 'A';
+
+       str = g_string_new (". ");
+
+       do {
+               g_string_prepend_c (str, ((value - 1) % 26) + add);
+               value = (value - 1) / 26;
+       } while (value);
+
+       rv = str->str;
+       g_string_free (str, FALSE);
+
+       return rv;
+}
+
+/* Taken from GtkHTML */
+static gchar *
+get_roman_value (gint value,
+                 gboolean lower)
+{
+       GString *str;
+       const gchar *base = "IVXLCDM";
+       gchar *rv;
+       gint b, r, add = lower ? 'a' - 'A' : 0;
+
+       if (value > 3999)
+               return g_strdup ("?. ");
+
+       str = g_string_new (". ");
+
+       for (b = 0; value > 0 && b < 7 - 1; b += 2, value /= 10) {
+               r = value % 10;
+               if (r != 0) {
+                       if (r < 4) {
+                               for (; r; r--)
+                                       g_string_prepend_c (str, base[b] + add);
+                       } else if (r == 4) {
+                               g_string_prepend_c (str, base[b + 1] + add);
+                               g_string_prepend_c (str, base[b] + add);
+                       } else if (r == 5) {
+                               g_string_prepend_c (str, base[b + 1] + add);
+                       } else if (r < 9) {
+                               for (; r > 5; r--)
+                                       g_string_prepend_c (str, base[b] + add);
+                               g_string_prepend_c (str, base[b + 1] + add);
+                       } else if (r == 9) {
+                               g_string_prepend_c (str, base[b + 2] + add);
+                               g_string_prepend_c (str, base[b] + add);
+                       }
+               }
+       }
+
+       rv = str->str;
+       g_string_free (str, FALSE);
+
+       return rv;
+}
+
+static void
+process_list_to_plain_text (EHTMLEditorWebExtension *extension,
+                            WebKitDOMElement *element,
+                            gint level,
+                            GString *output)
+{
+       EHTMLEditorSelectionBlockFormat format;
+       EHTMLEditorSelectionAlignment alignment;
+       gint counter = 1;
+       gchar *indent_per_level = g_strnfill (SPACES_PER_LIST_LEVEL, ' ');
+       WebKitDOMNode *item;
+       gint word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
+
+       format = dom_get_list_format_from_node (
+               WEBKIT_DOM_NODE (element));
+
+       /* Process list items to plain text */
+       item = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element));
+       while (item) {
+               if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (item))
+                       g_string_append (output, "\n");
+
+               if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (item)) {
+                       gchar *space, *item_str = NULL;
+                       gint ii = 0;
+                       WebKitDOMElement *wrapped;
+                       GString *item_value = g_string_new ("");
+
+                       alignment = dom_get_list_alignment_from_node (
+                               WEBKIT_DOM_NODE (item));
+
+                       wrapped = webkit_dom_element_query_selector (
+                               WEBKIT_DOM_ELEMENT (item), ".-x-evo-wrap-br", NULL);
+                       /* Wrapped text */
+                       if (wrapped) {
+                               WebKitDOMNode *node = webkit_dom_node_get_first_child (item);
+                               GString *line = g_string_new ("");
+                               while (node) {
+                                       if (WEBKIT_DOM_IS_TEXT (node)) {
+                                               /* append text from line */
+                                               gchar *text_content;
+                                               text_content = webkit_dom_node_get_text_content (node);
+                                               g_string_append (line, text_content);
+                                               g_free (text_content);
+                                       }
+                                       if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (node) &&
+                                           element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-wrap-br")) {
+                                               g_string_append (line, "\n");
+                                               /* put spaces before line characters -> wordwraplength - 
indentation */
+                                               for (ii = 0; ii < level; ii++)
+                                                       g_string_append (line, indent_per_level);
+                                               g_string_append (item_value, line->str);
+                                               g_string_erase (line, 0, -1);
+                                       }
+                                       node = webkit_dom_node_get_next_sibling (node);
+                               }
+
+                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT)
+                                       g_string_append (item_value, line->str);
+
+                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
+                                       gchar *fill = NULL;
+                                       gint fill_length;
+
+                                       fill_length = word_wrap_length - g_utf8_strlen (line->str, -1);
+                                       fill_length -= ii * SPACES_PER_LIST_LEVEL;
+                                       fill_length /= 2;
+
+                                       if (fill_length < 0)
+                                               fill_length = 0;
+
+                                       fill = g_strnfill (fill_length, ' ');
+
+                                       g_string_append (item_value, fill);
+                                       g_string_append (item_value, line->str);
+                                       g_free (fill);
+                               }
+
+                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
+                                       gchar *fill = NULL;
+                                       gint fill_length;
+
+                                       fill_length = word_wrap_length - g_utf8_strlen (line->str, -1);
+                                       fill_length -= ii * SPACES_PER_LIST_LEVEL;
+
+                                       if (fill_length < 0)
+                                               fill_length = 0;
+
+                                       fill = g_strnfill (fill_length, ' ');
+
+                                       g_string_append (item_value, fill);
+                                       g_string_append (item_value, line->str);
+                                       g_free (fill);
+                               }
+                               g_string_free (line, TRUE);
+                               /* that same here */
+                       } else {
+                               gchar *text_content =
+                                       webkit_dom_node_get_text_content (item);
+                               g_string_append (item_value, text_content);
+                               g_free (text_content);
+                       }
+
+                       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST) {
+                               space = g_strnfill (SPACES_PER_LIST_LEVEL - 2, ' ');
+                               item_str = g_strdup_printf (
+                                       "%s* %s", space, item_value->str);
+                               g_free (space);
+                       }
+
+                       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
+                               gint length = 1, tmp = counter;
+
+                               while ((tmp = tmp / 10) > 1)
+                                       length++;
+
+                               if (tmp == 1)
+                                       length++;
+
+                               space = g_strnfill (SPACES_PER_LIST_LEVEL - 2 - length, ' ');
+                               item_str = g_strdup_printf (
+                                       "%s%d. %s", space, counter, item_value->str);
+                               g_free (space);
+                       }
+
+                       if (format > E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
+                               gchar *value;
+
+                               if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA)
+                                       value = get_alpha_value (counter, FALSE);
+                               else
+                                       value = get_roman_value (counter, FALSE);
+
+                               /* Value already containes dot and space */
+                               space = g_strnfill (SPACES_PER_LIST_LEVEL - strlen (value), ' ');
+                               item_str = g_strdup_printf (
+                                       "%s%s%s", space, value, item_value->str);
+                               g_free (space);
+                               g_free (value);
+                       }
+
+                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT) {
+                               for (ii = 0; ii < level - 1; ii++) {
+                                       g_string_append (output, indent_per_level);
+                               }
+                               g_string_append (output, item_str);
+                       }
+
+                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
+                               if (!wrapped) {
+                                       gchar *fill = NULL;
+                                       gint fill_length;
+
+                                       fill_length = word_wrap_length - g_utf8_strlen (item_str, -1);
+                                       fill_length -= ii * SPACES_PER_LIST_LEVEL;
+
+                                       if (fill_length < 0)
+                                               fill_length = 0;
+
+                                       if (g_str_has_suffix (item_str, " "))
+                                               fill_length++;
+
+                                       fill = g_strnfill (fill_length, ' ');
+
+                                       g_string_append (output, fill);
+                                       g_free (fill);
+                               }
+                               if (g_str_has_suffix (item_str, " "))
+                                       g_string_append_len (output, item_str, g_utf8_strlen (item_str, -1) - 
1);
+                               else
+                                       g_string_append (output, item_str);
+                       }
+
+                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
+                               if (!wrapped) {
+                                       gchar *fill = NULL;
+                                       gint fill_length = 0;
+
+                                       for (ii = 0; ii < level - 1; ii++)
+                                               g_string_append (output, indent_per_level);
+
+                                       fill_length = word_wrap_length - g_utf8_strlen (item_str, -1);
+                                       fill_length -= ii * SPACES_PER_LIST_LEVEL;
+                                       fill_length /= 2;
+
+                                       if (fill_length < 0)
+                                               fill_length = 0;
+
+                                       if (g_str_has_suffix (item_str, " "))
+                                               fill_length++;
+
+                                       fill = g_strnfill (fill_length, ' ');
+
+                                       g_string_append (output, fill);
+                                       g_free (fill);
+                               }
+                               if (g_str_has_suffix (item_str, " "))
+                                       g_string_append_len (output, item_str, g_utf8_strlen (item_str, -1) - 
1);
+                               else
+                                       g_string_append (output, item_str);
+                       }
+
+                       counter++;
+                       item = webkit_dom_node_get_next_sibling (item);
+                       if (item)
+                               g_string_append (output, "\n");
+
+                       g_free (item_str);
+                       g_string_free (item_value, TRUE);
+               } else if (WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (item) ||
+                          WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (item)) {
+                       process_list_to_plain_text (
+                               extension, WEBKIT_DOM_ELEMENT (item), level + 1, output);
+                       item = webkit_dom_node_get_next_sibling (item);
+               } else {
+                       item = webkit_dom_node_get_next_sibling (item);
+               }
+       }
+
+       if (webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (element)))
+               g_string_append (output, "\n");
+
+       g_free (indent_per_level);
+}
+
+static void
+remove_base_attributes (WebKitDOMElement *element)
+{
+       webkit_dom_element_remove_attribute (element, "class");
+       webkit_dom_element_remove_attribute (element, "id");
+       webkit_dom_element_remove_attribute (element, "name");
+}
+
+static void
+remove_evolution_attributes (WebKitDOMElement *element)
+{
+       webkit_dom_element_remove_attribute (element, "x-evo-smiley");
+       webkit_dom_element_remove_attribute (element, "data-converted");
+       webkit_dom_element_remove_attribute (element, "data-edit-as-new");
+       webkit_dom_element_remove_attribute (element, "data-evo-draft");
+       webkit_dom_element_remove_attribute (element, "data-inline");
+       webkit_dom_element_remove_attribute (element, "data-uri");
+       webkit_dom_element_remove_attribute (element, "data-message");
+       webkit_dom_element_remove_attribute (element, "data-name");
+       webkit_dom_element_remove_attribute (element, "data-new-message");
+       webkit_dom_element_remove_attribute (element, "spellcheck");
+}
+/*
+static void
+remove_style_attributes (WebKitDOMElement *element)
+{
+       webkit_dom_element_remove_attribute (element, "bgcolor");
+       webkit_dom_element_remove_attribute (element, "background");
+       webkit_dom_element_remove_attribute (element, "style");
+}
+*/
+static gboolean
+replace_to_whitespaces (const GMatchInfo *info,
+                        GString *res,
+                        gpointer data)
+{
+       gint ii, length = 0;
+       gint chars_count = GPOINTER_TO_INT (data);
+
+       length = TAB_LENGTH - (chars_count %  TAB_LENGTH);
+
+       for (ii = 0; ii < length; ii++)
+               g_string_append (res, " ");
+
+       return FALSE;
+}
+
+static void
+process_elements (EHTMLEditorWebExtension *extension,
+                  WebKitDOMNode *node,
+                  gboolean to_html,
+                  gboolean changing_mode,
+                  gboolean to_plain_text,
+                  GString *buffer)
+{
+       WebKitDOMNodeList *nodes;
+       gulong ii, length;
+       gchar *content;
+       gboolean skip_nl = FALSE;
+
+       if (to_plain_text && !buffer)
+               return;
+
+       if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (node)) {
+               if (changing_mode && to_plain_text) {
+                       WebKitDOMNamedNodeMap *attributes;
+                       gulong attributes_length;
+
+                       /* Copy attributes */
+                       g_string_append (buffer, "<html><head></head><body ");
+                       attributes = webkit_dom_element_get_attributes (
+                               WEBKIT_DOM_ELEMENT (node));
+                       attributes_length =
+                               webkit_dom_named_node_map_get_length (attributes);
+
+                       for (ii = 0; ii < attributes_length; ii++) {
+                               gchar *name, *value;
+                               WebKitDOMNode *node =
+                                       webkit_dom_named_node_map_item (
+                                               attributes, ii);
+
+                               name = webkit_dom_node_get_local_name (node);
+                               value = webkit_dom_node_get_node_value (node);
+
+                               g_string_append (buffer, name);
+                               g_string_append (buffer, "=\"");
+                               g_string_append (buffer, value);
+                               g_string_append (buffer, "\" ");
+
+                               g_free (name);
+                               g_free (value);
+                       }
+                       g_string_append (buffer, ">");
+                       g_object_unref (attributes);
+               }
+               if (to_html)
+                       remove_evolution_attributes (WEBKIT_DOM_ELEMENT (node));
+       }
+
+       nodes = webkit_dom_node_get_child_nodes (node);
+       length = webkit_dom_node_list_get_length (nodes);
+
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *child;
+               gboolean skip_node = FALSE;
+
+               child = webkit_dom_node_list_item (nodes, ii);
+
+               if (WEBKIT_DOM_IS_TEXT (child)) {
+                       gchar *content, *tmp;
+                       GRegex *regex;
+                       gint char_count = 0;
+
+                       content = webkit_dom_node_get_text_content (child);
+                       if (!changing_mode && to_plain_text) {
+                               /* Replace tabs with 8 whitespaces, otherwise they got
+                                * replaced by single whitespace */
+                               if (strstr (content, "\x9")) {
+                                       if (buffer->str && *buffer->str) {
+                                               gchar *start_of_line = g_strrstr_len (
+                                                       buffer->str, -1, "\n") + 1;
+
+                                               if (start_of_line && *start_of_line)
+                                                               char_count = strlen (start_of_line);
+                                       } else
+                                               char_count = 0;
+
+                                       regex = g_regex_new ("\x9", 0, 0, NULL);
+                                       tmp = g_regex_replace_eval (
+                                               regex,
+                                               content,
+                                               -1,
+                                               0,
+                                               0,
+                                               (GRegexEvalCallback) replace_to_whitespaces,
+                                               GINT_TO_POINTER (char_count),
+                                               NULL);
+
+                                       g_string_append (buffer, tmp);
+                                       g_free (tmp);
+                                       g_free (content);
+                                       content = webkit_dom_node_get_text_content (child);
+                                       g_regex_unref (regex);
+                               }
+                       }
+
+                       if (strstr (content, UNICODE_ZERO_WIDTH_SPACE)) {
+                               regex = g_regex_new (UNICODE_ZERO_WIDTH_SPACE, 0, 0, NULL);
+                               tmp = g_regex_replace (
+                                       regex, content, -1, 0, "", 0, NULL);
+                               webkit_dom_node_set_text_content (child, tmp, NULL);
+                               g_free (tmp);
+                               g_free (content);
+                               content = webkit_dom_node_get_text_content (child);
+                               g_regex_unref (regex);
+                       }
+
+                       if (to_plain_text && !changing_mode) {
+                               gchar *class;
+                               const gchar *css_align;
+
+                               if (strstr (content, UNICODE_NBSP)) {
+                                       GString *nbsp_free;
+
+                                       nbsp_free = e_str_replace_string (
+                                               content, UNICODE_NBSP, " ");
+
+                                       g_free (content);
+                                       content = g_string_free (nbsp_free, FALSE);
+                               }
+
+                               class = webkit_dom_element_get_class_name (WEBKIT_DOM_ELEMENT (node));
+                               if ((css_align = strstr (class, "-x-evo-align-"))) {
+                                       gchar *align;
+                                       gchar *content_with_align;
+                                       gint length;
+                                       gint word_wrap_length = extension->priv->word_wrap_length;
+
+                                       if (!g_str_has_prefix (css_align + 13, "left")) {
+                                               if (g_str_has_prefix (css_align + 13, "center"))
+                                                       length = (word_wrap_length - g_utf8_strlen (content, 
-1)) / 2;
+                                               else
+                                                       length = word_wrap_length - g_utf8_strlen (content, 
-1);
+
+                                               if (length < 0)
+                                                       length = 0;
+
+                                               if (g_str_has_suffix (content, " ")) {
+                                                       char *tmp;
+
+                                                       length++;
+                                                       align = g_strnfill (length, ' ');
+
+                                                       tmp = g_strndup (content, g_utf8_strlen (content, -1) 
-1);
+
+                                                       content_with_align = g_strconcat (
+                                                               align, tmp, NULL);
+                                                       g_free (tmp);
+                                               } else {
+                                                       align = g_strnfill (length, ' ');
+
+                                                       content_with_align = g_strconcat (
+                                                               align, content, NULL);
+                                               }
+
+                                               g_free (content);
+                                               g_free (align);
+                                               content = content_with_align;
+                                       }
+                               }
+
+                               g_free (class);
+                       }
+
+                       if (to_plain_text || changing_mode)
+                               g_string_append (buffer, content);
+
+                       g_free (content);
+
+                       goto next;
+               }
+
+               if (WEBKIT_DOM_IS_COMMENT (child) || !WEBKIT_DOM_IS_ELEMENT (child))
+                       goto next;
+
+               /* Leave caret position untouched */
+               if (element_has_id (WEBKIT_DOM_ELEMENT (child), "-x-evo-caret-position")) {
+                       if (changing_mode && to_plain_text) {
+                               content = webkit_dom_html_element_get_outer_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (child));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                       }
+                       if (to_html)
+                               remove_node (child);
+
+                       skip_node = TRUE;
+                       goto next;
+               }
+
+               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "Apple-tab-span")) {
+                       if (!changing_mode && to_plain_text) {
+                               gchar *content, *tmp;
+                               GRegex *regex;
+                               gint char_count = 0;
+
+                               content = webkit_dom_node_get_text_content (child);
+                               /* Replace tabs with 8 whitespaces, otherwise they got
+                                * replaced by single whitespace */
+                               if (strstr (content, "\x9")) {
+                                       if (buffer->str && *buffer->str) {
+                                               gchar *start_of_line = g_strrstr_len (
+                                                       buffer->str, -1, "\n") + 1;
+
+                                               if (start_of_line && *start_of_line)
+                                                       char_count = strlen (start_of_line);
+                                       } else
+                                               char_count = 0;
+
+                                       regex = g_regex_new ("\x9", 0, 0, NULL);
+                                       tmp = g_regex_replace_eval (
+                                               regex,
+                                               content,
+                                               -1,
+                                               0,
+                                               0,
+                                               (GRegexEvalCallback) replace_to_whitespaces,
+                                               GINT_TO_POINTER (char_count),
+                                               NULL);
+
+                                       g_string_append (buffer, tmp);
+                                       g_free (tmp);
+                                       g_regex_unref (regex);
+                               } else if (content && *content) {
+                                       /* Some it happens that some text is written inside
+                                        * the tab span element, so save it. */
+                                       g_string_append (buffer, content);
+                               }
+                               g_free (content);
+                       }
+                       if (to_html) {
+                               element_remove_class (
+                                       WEBKIT_DOM_ELEMENT (child),
+                                       "Applet-tab-span");
+                       }
+
+                       skip_node = TRUE;
+                       goto next;
+               }
+
+               /* Leave blockquotes as they are */
+               if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (child)) {
+                       if (changing_mode && to_plain_text) {
+                               content = webkit_dom_html_element_get_outer_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (child));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                               skip_node = TRUE;
+                               goto next;
+                       } else {
+                               if (!changing_mode && to_plain_text) {
+                                       if (get_citation_level (child, FALSE) == 0) {
+                                               gchar *value = webkit_dom_element_get_attribute (
+                                                       WEBKIT_DOM_ELEMENT (child), "type");
+
+                                               if (value && g_strcmp0 (value, "cite") == 0)
+                                                       g_string_append (buffer, "\n");
+                                               g_free (value);
+                                       }
+                               }
+                               process_blockquote (WEBKIT_DOM_ELEMENT (child));
+                               if (to_html)
+                                       remove_base_attributes (WEBKIT_DOM_ELEMENT (child));
+                       }
+               }
+
+               if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (child) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-indented"))
+                       process_blockquote (WEBKIT_DOM_ELEMENT (child));
+
+               if (WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (child) ||
+                   WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (child)) {
+                       if (to_plain_text) {
+                               if (changing_mode) {
+                                       content = webkit_dom_html_element_get_outer_html (
+                                               WEBKIT_DOM_HTML_ELEMENT (child));
+                                       g_string_append (buffer, content);
+                                       g_free (content);
+                               } else {
+                                       process_list_to_plain_text (
+                                               extension, WEBKIT_DOM_ELEMENT (child), 1, buffer);
+                               }
+                               skip_node = TRUE;
+                               goto next;
+                       }
+               }
+
+               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-resizable-wrapper") &&
+                   !element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
+                       WebKitDOMNode *image =
+                               webkit_dom_node_get_first_child (child);
+
+                       if (to_html && WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (image)) {
+                               remove_evolution_attributes (
+                                       WEBKIT_DOM_ELEMENT (image));
+
+                               webkit_dom_node_replace_child (
+                                       node, image, child, NULL);
+                       }
+
+                       skip_node = TRUE;
+                       goto next;
+               }
+
+               /* Leave paragraphs as they are */
+               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-paragraph")) {
+                       if (changing_mode && to_plain_text) {
+                               content = webkit_dom_html_element_get_outer_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (child));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                               skip_node = TRUE;
+                               goto next;
+                       }
+                       if (to_html) {
+                               remove_base_attributes (WEBKIT_DOM_ELEMENT (child));
+                               remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child));
+                       }
+                       if (!changing_mode && to_plain_text)
+                               if (!webkit_dom_node_has_child_nodes (child))
+                                       g_string_append (buffer, "\n");
+               }
+
+               /* Signature */
+               if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (child) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-signature-wrapper")) {
+                       WebKitDOMNode *first_child;
+
+                       first_child = webkit_dom_node_get_first_child (child);
+
+                       if (to_html) {
+                               remove_base_attributes (
+                                       WEBKIT_DOM_ELEMENT (first_child));
+                               remove_evolution_attributes (
+                                       WEBKIT_DOM_ELEMENT (first_child));
+                       }
+                       if (to_plain_text && !changing_mode) {
+                               g_string_append (buffer, "\n");
+                               content = webkit_dom_html_element_get_inner_text (
+                                       WEBKIT_DOM_HTML_ELEMENT (first_child));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                               skip_nl = TRUE;
+                       }
+                       if (to_plain_text && changing_mode) {
+                               content = webkit_dom_html_element_get_outer_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (child));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                               skip_node = TRUE;
+                       }
+                       skip_node = TRUE;
+                       goto next;
+               }
+
+               /* Replace smileys with their text representation */
+               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
+                       if (to_plain_text && !changing_mode) {
+                               WebKitDOMNode *text_version;
+
+                               text_version = webkit_dom_node_get_last_child (child);
+                               content = webkit_dom_html_element_get_inner_text (
+                                       WEBKIT_DOM_HTML_ELEMENT (text_version));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                               skip_node = TRUE;
+                               goto next;
+                       }
+                       if (to_html) {
+                               WebKitDOMElement *img;
+
+                               img = WEBKIT_DOM_ELEMENT (
+                                       webkit_dom_node_get_first_child (child)),
+
+                               remove_evolution_attributes (img);
+                               remove_base_attributes (img);
+
+                               webkit_dom_node_insert_before (
+                                       webkit_dom_node_get_parent_node (child),
+                                       WEBKIT_DOM_NODE (img),
+                                       child,
+                                       NULL);
+                               remove_node (child);
+                               skip_node = TRUE;
+                               goto next;
+                       }
+               }
+
+               /* Leave PRE elements untouched */
+               if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (child)) {
+                       if (changing_mode && to_plain_text) {
+                               content = webkit_dom_html_element_get_outer_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (child));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                               skip_node = TRUE;
+                       }
+                       if (to_html)
+                               remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child));
+               }
+
+               if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)) {
+                       if (to_plain_text) {
+                               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-wrap-br")) {
+                                       g_string_append (buffer, changing_mode ? "<br>" : "\n");
+                                       goto next;
+                               }
+
+                               /* Insert new line when we hit the BR element that is
+                                * not the last element in the block */
+                               if (!webkit_dom_node_is_same_node (
+                                       child, webkit_dom_node_get_last_child (node))) {
+                                       g_string_append (buffer, changing_mode ? "<br>" : "\n");
+                               } else {
+                                       /* In citations in the empty lines the BR element
+                                        * is on the end and we have to put NL there */
+                                       WebKitDOMNode *parent;
+
+                                       parent = webkit_dom_node_get_parent_node (child);
+                                       if (webkit_dom_node_get_next_sibling (parent)) {
+                                               parent = webkit_dom_node_get_parent_node (parent);
+
+                                               if (is_citation_node (parent))
+                                                       g_string_append (buffer, changing_mode ? "<br>" : 
"\n");
+                                       }
+                               }
+                       }
+               }
+
+               if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (child)) {
+                       if (changing_mode && to_plain_text) {
+                               content = webkit_dom_html_element_get_outer_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (child));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                               skip_node = TRUE;
+                       }
+                       if (!changing_mode && to_plain_text) {
+                               content = webkit_dom_html_element_get_inner_text (
+                                       WEBKIT_DOM_HTML_ELEMENT (child));
+                               g_string_append (buffer, content);
+                               g_free (content);
+                               skip_node = TRUE;
+                       }
+               }
+ next:
+               if (webkit_dom_node_has_child_nodes (child) && !skip_node)
+                       process_elements (
+                               extension, child, to_html, changing_mode, to_plain_text, buffer);
+       }
+
+       if (to_plain_text && (
+           WEBKIT_DOM_IS_HTML_DIV_ELEMENT (node) ||
+           WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (node) ||
+           WEBKIT_DOM_IS_HTML_PRE_ELEMENT (node) ||
+           WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))) {
+
+               gboolean add_br = TRUE;
+               WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
+               WebKitDOMNode *last_child = webkit_dom_node_get_last_child (node);
+
+               if (last_child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (last_child))
+                       if (webkit_dom_node_get_previous_sibling (last_child))
+                               add_br = FALSE;
+
+               /* If we don't have next sibling (last element in body) or next element is
+                * signature we are not adding the BR element */
+               if (!next_sibling)
+                       add_br = FALSE;
+               else if (next_sibling && WEBKIT_DOM_IS_HTML_DIV_ELEMENT (next_sibling)) {
+                       if (webkit_dom_element_query_selector (
+                               WEBKIT_DOM_ELEMENT (next_sibling),
+                               "span.-x-evo-signature", NULL)) {
+
+                               add_br = FALSE;
+                       }
+               }
+
+               if (add_br && !skip_nl)
+                       g_string_append (buffer, changing_mode ? "<br>" : "\n");
+       }
+
+       g_object_unref (nodes);
+}
+
+static void
+remove_wrapping_from_document (WebKitDOMDocument *document)
+{
+       gint length;
+       gint ii;
+       WebKitDOMNodeList *list;
+
+       list = webkit_dom_document_query_selector_all (document, "br.-x-evo-wrap-br", NULL);
+
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++)
+               remove_node (webkit_dom_node_list_item (list, ii));
+
+       g_object_unref (list);
+}
+
+static void
+remove_image_attributes_from_element (WebKitDOMElement *element)
+{
+       webkit_dom_element_remove_attribute (element, "background");
+       webkit_dom_element_remove_attribute (element, "data-uri");
+       webkit_dom_element_remove_attribute (element, "data-inline");
+       webkit_dom_element_remove_attribute (element, "data-name");
+}
+
+static void
+remove_background_images_in_document (WebKitDOMDocument *document)
+{
+       gint length, ii;
+       WebKitDOMNodeList *elements;
+
+       elements = webkit_dom_document_query_selector_all (
+               document, "[background][data-inline]", NULL);
+
+       length = webkit_dom_node_list_get_length (elements);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMElement *element = WEBKIT_DOM_ELEMENT (
+                       webkit_dom_node_list_item (elements, ii));
+
+               remove_image_attributes_from_element (element);
+       }
+
+       g_object_unref (elements);
+}
+
+static void
+remove_images_in_element (WebKitDOMElement *element)
+{
+       gint length, ii;
+       WebKitDOMNodeList *images;
+
+       images = webkit_dom_element_query_selector_all (
+               element, "img:not(.-x-evo-smiley-img)", NULL);
+
+       length = webkit_dom_node_list_get_length (images);
+       for (ii = 0; ii < length; ii++)
+               remove_node (webkit_dom_node_list_item (images, ii));
+
+       g_object_unref (images);
+}
+
+static void
+remove_images (WebKitDOMDocument *document)
+{
+       remove_images_in_element (
+               WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)));
+}
+
+static void
+toggle_smileys (EHTMLEditorWebExtension *extension,
+                WebKitDOMDocument *document)
+{
+       gboolean html_mode;
+       gint length;
+       gint ii;
+       WebKitDOMNodeList *smileys;
+
+       html_mode = is_in_html_mode (extension);
+
+       smileys = webkit_dom_document_query_selector_all (
+               document, "img.-x-evo-smiley-img", NULL);
+
+       length = webkit_dom_node_list_get_length (smileys);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *img = webkit_dom_node_list_item (smileys, ii);
+               WebKitDOMNode *text = webkit_dom_node_get_next_sibling (img);
+               WebKitDOMElement *parent = webkit_dom_node_get_parent_element (img);
+
+               webkit_dom_element_set_attribute (
+                       WEBKIT_DOM_ELEMENT (html_mode ? text : img),
+                       "style",
+                       "display: none",
+                       NULL);
+
+               webkit_dom_element_remove_attribute (
+                       WEBKIT_DOM_ELEMENT (html_mode ? img : text), "style");
+
+               if (html_mode)
+                       element_add_class (parent, "-x-evo-resizable-wrapper");
+               else
+                       element_remove_class (parent, "-x-evo-resizable-wrapper");
+       }
+
+       g_object_unref (smileys);
+}
+
+static void
+toggle_paragraphs_style_in_element (WebKitDOMDocument *document,
+                                    WebKitDOMElement *element,
+                                   gboolean html_mode)
+{
+       gint ii, length;
+       WebKitDOMNodeList *paragraphs;
+
+       paragraphs = webkit_dom_element_query_selector_all (
+               element, ".-x-evo-paragraph", NULL);
+
+       length = webkit_dom_node_list_get_length (paragraphs);
+
+       for (ii = 0; ii < length; ii++) {
+               gchar *style;
+               const gchar *css_align;
+               WebKitDOMNode *node = webkit_dom_node_list_item (paragraphs, ii);
+
+               if (html_mode) {
+                       style = webkit_dom_element_get_attribute (
+                               WEBKIT_DOM_ELEMENT (node), "style");
+
+                       if ((css_align = strstr (style, "text-align: "))) {
+                               webkit_dom_element_set_attribute (
+                                       WEBKIT_DOM_ELEMENT (node),
+                                       "style",
+                                       g_str_has_prefix (css_align + 12, "center") ?
+                                               "text-align: center" :
+                                               "text-align: right",
+                                       NULL);
+                       } else {
+                               /* In HTML mode the paragraphs don't have width limit */
+                               webkit_dom_element_remove_attribute (
+                                       WEBKIT_DOM_ELEMENT (node), "style");
+                       }
+                       g_free (style);
+               } else {
+                       WebKitDOMNode *parent;
+
+                       parent = webkit_dom_node_get_parent_node (node);
+                       /* If the paragraph is inside indented paragraph don't set
+                        * the style as it will be inherited */
+                       if (!element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-indented")) {
+                               const gchar *style_to_add = "";
+                               style = webkit_dom_element_get_attribute (
+                                       WEBKIT_DOM_ELEMENT (node), "style");
+
+                               if ((css_align = strstr (style, "text-align: "))) {
+                                       style_to_add = g_str_has_prefix (
+                                               css_align + 12, "center") ?
+                                                       "text-align: center;" :
+                                                       "text-align: right;";
+                               }
+
+                               /* In plain text mode the paragraphs have width limit */
+                               dom_set_paragraph_style (
+                                       document, WEBKIT_DOM_ELEMENT (node), -1, 0, style_to_add);
+
+                               g_free (style);
+                       }
+               }
+       }
+       g_object_unref (paragraphs);
+}
+
+static void
+toggle_paragraphs_style (EHTMLEditorWebExtension *extension,
+                         WebKitDOMDocument *document)
+{
+       toggle_paragraphs_style_in_element (
+               document,
+               WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)),
+               is_in_html_mode (extension));
+}
+
+static gchar *
+process_content_for_saving_as_draft (WebKitDOMDocument *document)
+{
+       WebKitDOMHTMLElement *body;
+       WebKitDOMElement *document_element;
+       gchar *content;
+
+       body = webkit_dom_document_get_body (document);
+
+       webkit_dom_element_set_attribute (
+               WEBKIT_DOM_ELEMENT (body), "data-evo-draft", "", NULL);
+
+       document_element = webkit_dom_document_get_document_element (document);
+       content = webkit_dom_html_element_get_outer_html (
+               WEBKIT_DOM_HTML_ELEMENT (document_element));
+
+       webkit_dom_element_remove_attribute (
+               WEBKIT_DOM_ELEMENT (body), "data-evo-draft");
+
+       return content;
+}
+
+static gchar *
+process_content_for_mode_change (WebKitDOMDocument *document)
+{
+       WebKitDOMNode *body;
+       GString *plain_text;
+
+       body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
+
+       plain_text = g_string_sized_new (1024);
+
+       process_elements (extension, body, FALSE, TRUE, TRUE, plain_text);
+
+       g_string_append (plain_text, "</body></html>");
+
+       return g_string_free (plain_text, FALSE);
+}
+
+static void
+convert_element_from_html_to_plain_text (WebKitDOMDocument *document,
+                                         WebKitDOMElement *element,
+                                         gboolean *wrap,
+                                         gboolean *quote)
+{
+       gint blockquotes_count;
+       gchar *inner_text, *inner_html;
+       gboolean restore = TRUE;
+       WebKitDOMElement *top_signature, *signature, *blockquote, *main_blockquote;
+       WebKitDOMNode *signature_clone, *from;
+
+       top_signature = webkit_dom_element_query_selector (
+               element, ".-x-evo-top-signature", NULL);
+       signature = webkit_dom_element_query_selector (
+               element, "span.-x-evo-signature", NULL);
+       main_blockquote = webkit_dom_element_query_selector (
+               element, "#-x-evo-main-cite", NULL);
+
+       blockquote = webkit_dom_document_create_element (
+               document, "blockquote", NULL);
+
+       if (main_blockquote) {
+               WebKitDOMElement *input_start;
+
+               webkit_dom_element_set_attribute (
+                       blockquote, "type", "cite", NULL);
+
+               input_start = webkit_dom_element_query_selector (
+                       element, "#-x-evo-input-start", NULL);
+
+               restore = input_start ? TRUE : FALSE;
+
+               if (input_start)
+                       add_selection_markers_into_element_start (
+                               document, WEBKIT_DOM_ELEMENT (input_start), NULL, NULL);
+               from = WEBKIT_DOM_NODE (main_blockquote);
+       } else {
+               if (signature) {
+                       WebKitDOMNode *parent = webkit_dom_node_get_parent_node (
+                               WEBKIT_DOM_NODE (signature));
+                       signature_clone = webkit_dom_node_clone_node (parent, TRUE);
+                       remove_node (parent);
+               }
+               from = WEBKIT_DOM_NODE (element);
+       }
+
+       blockquotes_count = create_text_markers_for_citations_in_element (
+               WEBKIT_DOM_ELEMENT (from));
+
+       inner_text = webkit_dom_html_element_get_inner_text (
+               WEBKIT_DOM_HTML_ELEMENT (from));
+
+       webkit_dom_html_element_set_inner_text (
+               WEBKIT_DOM_HTML_ELEMENT (blockquote), inner_text, NULL);
+
+       inner_html = webkit_dom_html_element_get_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (blockquote));
+
+       parse_html_into_paragraphs (
+               document,
+               main_blockquote ? blockquote : WEBKIT_DOM_ELEMENT (element),
+               inner_html);
+
+       if (main_blockquote) {
+               webkit_dom_node_replace_child (
+                       webkit_dom_node_get_parent_node (
+                               WEBKIT_DOM_NODE (main_blockquote)),
+                       WEBKIT_DOM_NODE (blockquote),
+                       WEBKIT_DOM_NODE (main_blockquote),
+                       NULL);
+
+               remove_evolution_attributes (WEBKIT_DOM_ELEMENT (element));
+       } else {
+               WebKitDOMNode *first_child;
+
+               if (signature) {
+                       if (!top_signature) {
+                               signature_clone = webkit_dom_node_append_child (
+                                       WEBKIT_DOM_NODE (element),
+                                       signature_clone,
+                                       NULL);
+                       } else {
+                               webkit_dom_node_insert_before (
+                                       WEBKIT_DOM_NODE (element),
+                                       signature_clone,
+                                       webkit_dom_node_get_first_child (
+                                               WEBKIT_DOM_NODE (element)),
+                                       NULL);
+                       }
+               }
+
+               first_child = webkit_dom_node_get_first_child (
+                       WEBKIT_DOM_NODE (element));
+               if (first_child) {
+                       if (!webkit_dom_node_has_child_nodes (first_child)) {
+                               webkit_dom_html_element_set_inner_html (
+                                       WEBKIT_DOM_HTML_ELEMENT (first_child),
+                                       "<br>",
+                                       NULL);
+                       }
+                       add_selection_markers_into_element_start (
+                               document, WEBKIT_DOM_ELEMENT (first_child), NULL, NULL);
+               }
+       }
+
+       *wrap = TRUE;
+       *quote = main_blockquote || blockquotes_count > 0;
+
+       webkit_dom_element_set_attribute (
+               WEBKIT_DOM_ELEMENT (element), "data-converted", "", NULL);
+
+       g_free (inner_text);
+       g_free (inner_html);
+
+       if (restore)
+               dom_selection_restore (document);
+}
+
+static gchar *
+process_content_for_plain_text (EHTMLEditorWebExtension *extension,
+                                WebKitDOMDocument *document)
+{
+       gboolean wrap = FALSE, quote = FALSE, clean = FALSE;
+       gboolean converted, is_from_new_message;
+       gint length, ii;
+       GString *plain_text;
+       WebKitDOMNode *body, *source;
+       WebKitDOMNodeList *paragraphs;
+
+       plain_text = g_string_sized_new (1024);
+
+       body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
+       converted = webkit_dom_element_has_attribute (
+               WEBKIT_DOM_ELEMENT (body), "data-converted");
+       is_from_new_message = webkit_dom_element_has_attribute (
+               WEBKIT_DOM_ELEMENT (body), "data-new-message");
+       source = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
+
+       /* If composer is in HTML mode we have to move the content to plain version */
+       if (is_in_html_mode (extension)) {
+               if (converted || is_from_new_message) {
+                       toggle_paragraphs_style_in_element (
+                               document, WEBKIT_DOM_ELEMENT (source), FALSE);
+                       remove_images_in_element (
+                               document, WEBKIT_DOM_ELEMENT (source));
+                       remove_background_images_in_document (document);
+               } else {
+                       gchar *inner_html;
+                       WebKitDOMElement *div;
+
+                       inner_html = webkit_dom_html_element_get_inner_html (
+                               WEBKIT_DOM_HTML_ELEMENT (body));
+
+                       div = webkit_dom_document_create_element (
+                               document, "div", NULL);
+
+                       webkit_dom_html_element_set_inner_html (
+                               WEBKIT_DOM_HTML_ELEMENT (div), inner_html, NULL);
+
+                       webkit_dom_node_append_child (
+                               WEBKIT_DOM_NODE (body),
+                               WEBKIT_DOM_NODE (div),
+                               NULL);
+
+                       paragraphs = webkit_dom_element_query_selector_all (
+                               div, "#-x-evo-input-start", NULL);
+
+                       length = webkit_dom_node_list_get_length (paragraphs);
+                       for (ii = 0; ii < length; ii++) {
+                               WebKitDOMNode *paragraph;
+
+                               paragraph = webkit_dom_node_list_item (paragraphs, ii);
+
+                               webkit_dom_element_remove_attribute (
+                                       WEBKIT_DOM_ELEMENT (paragraph), "id");
+                       }
+                       g_object_unref (paragraphs);
+
+                       convert_element_from_html_to_plain_text (
+                               document, div, &wrap, &quote);
+
+                       g_object_unref (source);
+
+                       source = WEBKIT_DOM_NODE (div);
+
+                       clean = TRUE;
+               }
+       }
+
+       paragraphs = webkit_dom_element_query_selector_all (
+               WEBKIT_DOM_ELEMENT (source), ".-x-evo-paragraph", NULL);
+
+       length = webkit_dom_node_list_get_length (paragraphs);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *paragraph;
+
+               paragraph = webkit_dom_node_list_item (paragraphs, ii);
+
+               if (WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (paragraph) ||
+                   WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (paragraph)) {
+                       WebKitDOMNode *item = webkit_dom_node_get_first_child (paragraph);
+
+                       while (item) {
+                               WebKitDOMNode *next_item =
+                                       webkit_dom_node_get_next_sibling (item);
+
+                               if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (item)) {
+                                       dom_wrap_paragraph (
+                                               document, WEBKIT_DOM_ELEMENT (item));
+                               }
+                               item = next_item;
+                       }
+               } else {
+                       dom_wrap_paragraph (
+                               document, WEBKIT_DOM_ELEMENT (paragraph));
+               }
+       }
+       g_object_unref (paragraphs);
+
+       paragraphs = webkit_dom_element_query_selector_all (
+               WEBKIT_DOM_ELEMENT (source),
+               "span[id^=\"-x-evo-selection-\"], span#-x-evo-caret-position",
+               NULL);
+
+       length = webkit_dom_node_list_get_length (paragraphs);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *node = webkit_dom_node_list_item (paragraphs, ii);
+               WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
+
+               remove_node (node);
+               webkit_dom_node_normalize (parent);
+       }
+       g_object_unref (paragraphs);
+
+       if (is_in_html_mode (extension) || quote)
+               quote_plain_text_recursive (document, source, source, 0);
+
+       process_elements (extension, source, FALSE, FALSE, TRUE, plain_text);
+
+       if (clean)
+               remove_node (source);
+       else
+               g_object_unref (source);
+
+       /* Return text content between <body> and </body> */
+       return g_string_free (plain_text, FALSE);
+}
+
+static gchar *
+process_content_for_html (WebKitDOMDocument *document)
+{
+       WebKitDOMNode *body, *document_clone;
+       gchar *html_content;
+
+       document_clone = webkit_dom_node_clone_node (
+               WEBKIT_DOM_NODE (webkit_dom_document_get_document_element (document)), TRUE);
+       body = WEBKIT_DOM_NODE (webkit_dom_element_query_selector (
+               WEBKIT_DOM_ELEMENT (document_clone), "body", NULL));
+       process_elements (extension, body, TRUE, FALSE, FALSE, NULL);
+
+       html_content = webkit_dom_html_element_get_outer_html (
+               WEBKIT_DOM_HTML_ELEMENT (document_clone));
+
+       g_object_unref (document_clone);
+
+       return html_content;
+}
+
+static void
+clear_attributes (WebKitDOMDocument *document)
+{
+       gint length, ii;
+       WebKitDOMNamedNodeMap *attributes;
+       WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
+       WebKitDOMHTMLHeadElement *head = webkit_dom_document_get_head (document);
+       WebKitDOMElement *document_element =
+               webkit_dom_document_get_document_element (document);
+
+       /* Remove all attributes from HTML element */
+       attributes = webkit_dom_element_get_attributes (document_element);
+       length = webkit_dom_named_node_map_get_length (attributes);
+       for (ii = length - 1; ii >= 0; ii--) {
+               WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
+
+               webkit_dom_element_remove_attribute_node (
+                       document_element, WEBKIT_DOM_ATTR (node), NULL);
+       }
+       g_object_unref (attributes);
+
+       /* Remove everything from HEAD element */
+       while (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head)))
+               remove_node (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head)));
+
+       /* Remove non Evolution attributes from BODY element */
+       attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
+       length = webkit_dom_named_node_map_get_length (attributes);
+       for (ii = length - 1; ii >= 0; ii--) {
+               gchar *name;
+               WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
+
+               name = webkit_dom_node_get_local_name (node);
+
+               if (!g_str_has_prefix (name, "data-") ||
+                   g_str_has_prefix (name, "data-inline") ||
+                   g_str_has_prefix (name, "data-name")) {
+                       webkit_dom_element_remove_attribute_node (
+                               WEBKIT_DOM_ELEMENT (body),
+                               WEBKIT_DOM_ATTR (node),
+                               NULL);
+               }
+
+               g_free (name);
+       }
+       g_object_unref (attributes);
+}
+
+void
+convert_when_changing_composer_mode (WebKitDOMDocument *document)
+{
+       gboolean quote = FALSE, wrap = FALSE;
+       WebKitDOMHTMLElement *body;
+
+       body = webkit_dom_document_get_body (document);
+
+       convert_element_from_html_to_plain_text (
+               document, WEBKIT_DOM_ELEMENT (body), &wrap, &quote);
+
+       if (wrap)
+               dom_wrap_paragraphs_in_document (document);
+
+       if (quote) {
+               dom_selection_save (document);
+               if (wrap)
+                       quote_plain_text_elements_after_wrapping_in_document (
+                               document);
+               else
+                       body = WEBKIT_DOM_HTML_ELEMENT (dom_quote_plain_text (document));
+               dom_selection_restore (document);
+       }
+
+       toggle_paragraphs_style (document);
+       toggle_smileys (document);
+       remove_images (document);
+       remove_background_images_in_document (document);
+
+       clear_attributes (document);
+
+       webkit_dom_element_set_attribute (
+               WEBKIT_DOM_ELEMENT (body), "data-converted", "", NULL);
+}
+
+static void
+wrap_paragraphs_in_quoted_content (WebKitDOMDocument *document)
+{
+       gint ii, length;
+       WebKitDOMNodeList *paragraphs;
+
+       paragraphs = webkit_dom_document_query_selector_all (
+               document, "blockquote[type=cite] > .-x-evo-paragraph", NULL);
+
+       length = webkit_dom_node_list_get_length (paragraphs);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *paragraph;
+
+               paragraph = webkit_dom_node_list_item (paragraphs, ii);
+
+               dom_wrap_paragraph (document, WEBKIT_DOM_ELEMENT (paragraph));
+       }
+       g_object_unref (paragraphs);
+}
+
diff --git a/e-util/e-html-editor-view-dom-functions.h b/e-util/e-html-editor-view-dom-functions.h
index fe5d6ba..4bf6963 100644
--- a/e-util/e-html-editor-view-dom-functions.h
+++ b/e-util/e-html-editor-view-dom-functions.h
@@ -21,6 +21,8 @@
 
 #include <webkitdom/webkitdom.h>
 
+#include "web-extensions/e-html-editor-web-extension.h"
+
 #include "e-util-enums.h"
 
 G_BEGIN_DECLS
@@ -29,6 +31,20 @@ gboolean     dom_exec_command                (WebKitDOMDocument *document,
                                                 EHTMLEditorViewCommand command,
                                                 const gchar *value);
 
+void           dom_force_spell_check_for_current_paragraph
+                                               (WebKitDOMDocument *document);
+
+void           dom_force_spell_check           (WebKitDOMDocument *document);
+
+void           dom_convert_and_insert_html_into_selection
+                                               (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
+                                                const gchar *html,
+                                                gboolean is_html);
+
+WebKitDOMElement *
+               dom_quote_plain_text_element    (WebKitDOMDocument *document,
+                                                WebKitDOMElement *element);
 G_END_DECLS
 
 #endif /* E_HTML_EDITOR_VIEW_DOM_FUNCTIONS_H */
diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c
index 60373e0..40c60ea 100644
--- a/e-util/e-html-editor-view.c
+++ b/e-util/e-html-editor-view.c
@@ -25,14 +25,15 @@
 #include "e-html-editor-view.h"
 #include "e-html-editor.h"
 #include "e-emoticon-chooser.h"
+#include "e-misc-utils.h"
+
+#include "web-extensions/e-html-editor-web-extension-names.h"
 
 #include <e-util/e-util.h>
 #include <e-util/e-marshal.h>
 #include <glib/gi18n-lib.h>
 #include <gdk/gdkkeysyms.h>
 
-#include "web-extensions/e-html-editor-web-extension.h"
-
 #define E_HTML_EDITOR_VIEW_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), E_TYPE_HTML_EDITOR_VIEW, EHTMLEditorViewPrivate))
@@ -126,8 +127,6 @@ enum {
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-static CamelDataCache *emd_global_http_cache = NULL;
-
 typedef void (*PostReloadOperationFunc) (EHTMLEditorView *view, gpointer data);
 
 typedef struct {
@@ -164,54 +163,144 @@ html_editor_view_queue_post_reload_operation (EHTMLEditorView *view,
        g_queue_push_head (view->priv->post_reload_operations, op);
 }
 
-static WebKitDOMRange *
-html_editor_view_get_dom_range (EHTMLEditorView *view)
+static void
+html_editor_view_can_redo_cb (WebKitWebView *webkit_web_view,
+                              GAsyncResult *result,
+                              EHTMLEditorView *view)
 {
-       WebKitDOMDocument *document;
-       WebKitDOMDOMWindow *window;
-       WebKitDOMDOMSelection *selection;
+       gboolean value;
 
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       window = webkit_dom_document_get_default_view (document);
-       selection = webkit_dom_dom_window_get_selection (window);
+       value = webkit_web_view_can_execute_editing_command_finish (
+               webkit_web_view, result, NULL);
 
-       if (webkit_dom_dom_selection_get_range_count (selection) < 1) {
-               return NULL;
+       if (view->priv->can_redo != value) {
+               view->priv->can_redo = value;
+               g_object_notify (G_OBJECT (view), "can-redo");
+       }
+}
+
+static gboolean
+html_editor_view_can_redo (EHTMLEditorView *view)
+{
+       return view->priv->can_redo;
+}
+
+static void
+html_editor_view_can_undo_cb (WebKitWebView *webkit_web_view,
+                              GAsyncResult *result,
+                              EHTMLEditorView *view)
+{
+       gboolean value;
+
+       value = webkit_web_view_can_execute_editing_command_finish (
+               webkit_web_view, result, NULL);
+
+       if (view->priv->can_undo != value) {
+               view->priv->can_undo = value;
+               g_object_notify (G_OBJECT (view), "can-undo");
        }
+}
 
-       return webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+static gboolean
+html_editor_view_can_undo (EHTMLEditorView *view)
+{
+       return view->priv->can_undo;
 }
 
 static void
-html_editor_view_user_changed_contents_cb (EHTMLEditorView *view,
-                                           gpointer user_data)
+html_editor_view_user_changed_contents_cb (EHTMLEditorView *view)
 {
        WebKitWebView *web_view;
-       gboolean can_redo, can_undo;
 
        web_view = WEBKIT_WEB_VIEW (view);
 
        e_html_editor_view_set_changed (view, TRUE);
 
-       can_redo = webkit_web_view_can_redo (web_view);
-       if (view->priv->can_redo != can_redo) {
-               view->priv->can_redo = can_redo;
-               g_object_notify (G_OBJECT (view), "can-redo");
+       webkit_web_view_can_execute_editing_command (
+               WEBKIT_WEB_VIEW (web_view),
+               WEBKIT_EDITING_COMMAND_REDO,
+               NULL, /* cancellable */
+               (GAsyncReadyCallback) html_editor_view_can_redo_cb,
+               view);
+
+       webkit_web_view_can_execute_editing_command (
+               WEBKIT_WEB_VIEW (web_view),
+               WEBKIT_EDITING_COMMAND_UNDO,
+               NULL, /* cancellable */
+               (GAsyncReadyCallback) html_editor_view_can_undo_cb,
+               view);
+}
+
+static void
+html_editor_view_can_copy_cb (WebKitWebView *webkit_web_view,
+                              GAsyncResult *result,
+                              EHTMLEditorView *view)
+{
+       gboolean value;
+
+       value = webkit_web_view_can_execute_editing_command_finish (
+               webkit_web_view, result, NULL);
+
+       if (view->priv->can_copy != value) {
+               view->priv->can_copy = value;
+               g_object_notify (G_OBJECT (view), "can-copy");
        }
+}
 
-       can_undo = webkit_web_view_can_undo (web_view);
-       if (view->priv->can_undo != can_undo) {
-               view->priv->can_undo = can_undo;
-               g_object_notify (G_OBJECT (view), "can-undo");
+static gboolean
+html_editor_view_can_copy (EHTMLEditorView *view)
+{
+       return view->priv->can_copy;
+}
+
+static void
+html_editor_view_can_paste_cb (WebKitWebView *webkit_web_view,
+                              GAsyncResult *result,
+                              EHTMLEditorView *view)
+{
+       gboolean value;
+
+       value = webkit_web_view_can_execute_editing_command_finish (
+               webkit_web_view, result, NULL);
+
+       if (view->priv->can_paste != value) {
+               view->priv->can_paste = value;
+               g_object_notify (G_OBJECT (view), "can-paste");
        }
 }
 
+static gboolean
+html_editor_view_can_paste (EHTMLEditorView *view)
+{
+       return view->priv->can_paste;
+}
+
 static void
-html_editor_view_selection_changed_cb (EHTMLEditorView *view,
-                                       gpointer user_data)
+html_editor_view_can_cut_cb (WebKitWebView *webkit_web_view,
+                             GAsyncResult *result,
+                             EHTMLEditorView *view)
+{
+       gboolean value;
+
+       value = webkit_web_view_can_execute_editing_command_finish (
+               webkit_web_view, result, NULL);
+
+       if (view->priv->can_cut != value) {
+               view->priv->can_cut = value;
+               g_object_notify (G_OBJECT (view), "can-cut");
+       }
+}
+
+static gboolean
+html_editor_view_can_cut (EHTMLEditorView *view)
+{
+       return view->priv->can_cut;
+}
+
+static void
+html_editor_view_selection_changed_cb (EHTMLEditorView *view)
 {
        WebKitWebView *web_view;
-       gboolean can_copy, can_cut, can_paste;
 
        web_view = WEBKIT_WEB_VIEW (view);
 
@@ -224,23 +313,26 @@ html_editor_view_selection_changed_cb (EHTMLEditorView *view,
                return;
        }
 
-       can_copy = webkit_web_view_can_copy_clipboard (web_view);
-       if (view->priv->can_copy != can_copy) {
-               view->priv->can_copy = can_copy;
-               g_object_notify (G_OBJECT (view), "can-copy");
-       }
+       webkit_web_view_can_execute_editing_command (
+               WEBKIT_WEB_VIEW (web_view),
+               WEBKIT_EDITING_COMMAND_COPY,
+               NULL, /* cancellable */
+               (GAsyncReadyCallback) html_editor_view_can_copy_cb,
+               view);
 
-       can_cut = webkit_web_view_can_cut_clipboard (web_view);
-       if (view->priv->can_cut != can_cut) {
-               view->priv->can_cut = can_cut;
-               g_object_notify (G_OBJECT (view), "can-cut");
-       }
+       webkit_web_view_can_execute_editing_command (
+               WEBKIT_WEB_VIEW (web_view),
+               WEBKIT_EDITING_COMMAND_CUT,
+               NULL, /* cancellable */
+               (GAsyncReadyCallback) html_editor_view_can_cut_cb,
+               view);
 
-       can_paste = webkit_web_view_can_paste_clipboard (web_view);
-       if (view->priv->can_paste != can_paste) {
-               view->priv->can_paste = can_paste;
-               g_object_notify (G_OBJECT (view), "can-paste");
-       }
+       webkit_web_view_can_execute_editing_command (
+               WEBKIT_WEB_VIEW (web_view),
+               WEBKIT_EDITING_COMMAND_PASTE,
+               NULL, /* cancellable */
+               (GAsyncReadyCallback) html_editor_view_can_paste_cb,
+               view);
 }
 
 static gboolean
@@ -250,273 +342,48 @@ html_editor_view_should_show_delete_interface_for_element (EHTMLEditorView *view
        return FALSE;
 }
 
-static WebKitDOMElement *
-get_parent_block_element (WebKitDOMNode *node)
-{
-       WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
-
-       while (parent &&
-              !WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTML_HEADING_ELEMENT (parent) &&
-              !element_has_tag (parent, "address")) {
-               parent = webkit_dom_node_get_parent_element (
-                       WEBKIT_DOM_NODE (parent));
-       }
-
-       return parent;
-}
-
 void
 e_html_editor_view_force_spell_check_for_current_paragraph (EHTMLEditorView *view)
 {
-       EHTMLEditorSelection *selection;
-       WebKitDOMDocument *document;
-       WebKitDOMDOMSelection *dom_selection;
-       WebKitDOMDOMWindow *window;
-       WebKitDOMElement *selection_start_marker, *selection_end_marker;
-       WebKitDOMElement *parent, *element;
-       WebKitDOMRange *end_range, *actual;
-       WebKitDOMText *text;
-
+/* FIXME WK2
        if (!view->priv->inline_spelling)
                return;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       window = webkit_dom_document_get_default_view (document);
-       dom_selection = webkit_dom_dom_window_get_selection (window);
-
-       element = webkit_dom_document_query_selector (
-               document, "body[spellcheck=true]", NULL);
-
-       if (!element)
-               return;
-
-       selection = e_html_editor_view_get_selection (view);
-       e_html_editor_selection_save (selection);
-
-       selection_start_marker = webkit_dom_document_query_selector (
-               document, "span#-x-evo-selection-start-marker", NULL);
-       selection_end_marker = webkit_dom_document_query_selector (
-               document, "span#-x-evo-selection-end-marker", NULL);
-
-       if (!selection_start_marker || !selection_end_marker)
-               return;
-
+*/
        /* Block callbacks of selection-changed signal as we don't want to
         * recount all the block format things in EHTMLEditorSelection and here as well
         * when we are moving with caret */
+/* FIXME WK2
        g_signal_handlers_block_by_func (
                view, html_editor_view_selection_changed_cb, NULL);
        e_html_editor_selection_block_selection_changed (selection);
-
-       parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_end_marker));
-
-       /* Append some text on the end of the element */
-       text = webkit_dom_document_create_text_node (document, "-x-evo-end");
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (parent),
-               WEBKIT_DOM_NODE (text),
-               NULL);
-
-       parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_start_marker));
-
-       /* Create range that's pointing on the end of this text */
-       end_range = webkit_dom_document_create_range (document);
-       webkit_dom_range_select_node_contents (
-               end_range, WEBKIT_DOM_NODE (text), NULL);
-       webkit_dom_range_collapse (end_range, FALSE, NULL);
-
-       /* Move on the beginning of the paragraph */
-       actual = webkit_dom_document_create_range (document);
-       webkit_dom_range_select_node_contents (
-               actual, WEBKIT_DOM_NODE (parent), NULL);
-       webkit_dom_range_collapse (actual, TRUE, NULL);
-       webkit_dom_dom_selection_remove_all_ranges (dom_selection);
-       webkit_dom_dom_selection_add_range (dom_selection, actual);
-
-       /* Go through all words to spellcheck them. To avoid this we have to wait for
-        * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
-       actual = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       /* We are moving forward word by word until we hit the text on the end of
-        * the paragraph that we previously inserted there */
-       while (actual && webkit_dom_range_compare_boundary_points (end_range, 2, actual, NULL) != 0) {
-               webkit_dom_dom_selection_modify (
-                       dom_selection, "move", "forward", "word");
-               actual = webkit_dom_dom_selection_get_range_at (
-                       dom_selection, 0, NULL);
-       }
-
-       /* Remove the text that we inserted on the end of the paragraph */
-       remove_node (WEBKIT_DOM_NODE (text));
+*/
 
        /* Unblock the callbacks */
+/* FIXME WK2
        g_signal_handlers_unblock_by_func (
                view, html_editor_view_selection_changed_cb, NULL);
        e_html_editor_selection_unblock_selection_changed (selection);
-
-       e_html_editor_selection_restore (selection);
-}
-
-static WebKitDOMElement *
-create_selection_marker (WebKitDOMDocument *document,
-                         gboolean start)
-{
-       WebKitDOMElement *element;
-
-       element = webkit_dom_document_create_element (
-               document, "SPAN", NULL);
-       webkit_dom_element_set_id (
-               element,
-               start ? "-x-evo-selection-start-marker" :
-                       "-x-evo-selection-end-marker");
-
-       return element;
-}
-
-static void
-add_selection_markers_into_element_start (WebKitDOMDocument *document,
-                                          WebKitDOMElement *element,
-                                          WebKitDOMElement **selection_start_marker,
-                                          WebKitDOMElement **selection_end_marker)
-{
-       WebKitDOMElement *marker;
-
-       marker = create_selection_marker (document, FALSE);
-       webkit_dom_node_insert_before (
-               WEBKIT_DOM_NODE (element),
-               WEBKIT_DOM_NODE (marker),
-               webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
-               NULL);
-       if (selection_end_marker)
-               *selection_end_marker = marker;
-
-       marker = create_selection_marker (document, TRUE);
-       webkit_dom_node_insert_before (
-               WEBKIT_DOM_NODE (element),
-               WEBKIT_DOM_NODE (marker),
-               webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
-               NULL);
-       if (selection_start_marker)
-               *selection_start_marker = marker;
-}
-
-static void
-add_selection_markers_into_element_end (WebKitDOMDocument *document,
-                                        WebKitDOMElement *element,
-                                        WebKitDOMElement **selection_start_marker,
-                                        WebKitDOMElement **selection_end_marker)
-{
-       WebKitDOMElement *marker;
-
-       marker = create_selection_marker (document, TRUE);
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
-       if (selection_start_marker)
-               *selection_start_marker = marker;
-
-       marker = create_selection_marker (document, FALSE);
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
-       if (selection_end_marker)
-               *selection_end_marker = marker;
+*/
 }
 
 static void
 refresh_spell_check (EHTMLEditorView *view,
                      gboolean enable_spell_check)
 {
-       EHTMLEditorSelection *selection;
-       WebKitDOMDocument *document;
-       WebKitDOMDOMSelection *dom_selection;
-       WebKitDOMDOMWindow *window;
-       WebKitDOMElement *selection_start_marker, *selection_end_marker;
-       WebKitDOMHTMLElement *body;
-       WebKitDOMRange *end_range, *actual;
-       WebKitDOMText *text;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       window = webkit_dom_document_get_default_view (document);
-       dom_selection = webkit_dom_dom_window_get_selection (window);
-
-       /* Enable/Disable spellcheck in composer */
-       body = webkit_dom_document_get_body (document);
-       webkit_dom_element_set_attribute (
-               WEBKIT_DOM_ELEMENT (body),
-               "spellcheck",
-               enable_spell_check ? "true" : "false",
-               NULL);
-
-       selection = e_html_editor_view_get_selection (view);
-       e_html_editor_selection_save (selection);
-
-       selection_start_marker = webkit_dom_document_query_selector (
-               document, "span#-x-evo-selection-start-marker", NULL);
-       selection_end_marker = webkit_dom_document_query_selector (
-               document, "span#-x-evo-selection-end-marker", NULL);
-
-       /* Sometimes the web view is not focused, so we have to save the selection
-        * manually into the body */
-       if (!selection_start_marker || !selection_end_marker) {
-               WebKitDOMNode *child;
-
-               child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
-               if (!child)
-                       return;
-
-               add_selection_markers_into_element_start (
-                       document,
-                       WEBKIT_DOM_ELEMENT (child),
-                       &selection_start_marker,
-                       &selection_end_marker);
-       }
-
        /* Block callbacks of selection-changed signal as we don't want to
         * recount all the block format things in EHTMLEditorSelection and here as well
         * when we are moving with caret */
+/* FIXME WK2
        g_signal_handlers_block_by_func (
                view, html_editor_view_selection_changed_cb, NULL);
        e_html_editor_selection_block_selection_changed (selection);
-
-       /* Append some text on the end of the body */
-       text = webkit_dom_document_create_text_node (document, "-x-evo-end");
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (text), NULL);
-
-       /* Create range that's pointing on the end of this text */
-       end_range = webkit_dom_document_create_range (document);
-       webkit_dom_range_select_node_contents (
-               end_range, WEBKIT_DOM_NODE (text), NULL);
-       webkit_dom_range_collapse (end_range, FALSE, NULL);
-
-       /* Move on the beginning of the document */
-       webkit_dom_dom_selection_modify (
-               dom_selection, "move", "backward", "documentboundary");
-
-       /* Go through all words to spellcheck them. To avoid this we have to wait for
-        * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
-       actual = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       /* We are moving forward word by word until we hit the text on the end of
-        * the body that we previously inserted there */
-       while (actual && webkit_dom_range_compare_boundary_points (end_range, 2, actual, NULL) != 0) {
-               webkit_dom_dom_selection_modify (
-                       dom_selection, "move", "forward", "word");
-               actual = webkit_dom_dom_selection_get_range_at (
-                       dom_selection, 0, NULL);
-       }
-
-       /* Remove the text that we inserted on the end of the body */
-       remove_node (WEBKIT_DOM_NODE (text));
-
+*/
        /* Unblock the callbacks */
+/*
        g_signal_handlers_unblock_by_func (
                view, html_editor_view_selection_changed_cb, NULL);
        e_html_editor_selection_unblock_selection_changed (selection);
-
-       e_html_editor_selection_restore (selection);
+*/
 }
 
 void
@@ -532,339 +399,6 @@ e_html_editor_view_force_spell_check (EHTMLEditorView *view)
                refresh_spell_check (view, TRUE);
 }
 
-static gint
-get_citation_level (WebKitDOMNode *node,
-                    gboolean set_plaintext_quoted)
-{
-       WebKitDOMNode *parent = node;
-       gint level = 0;
-
-       while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
-               if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
-                   webkit_dom_element_has_attribute (WEBKIT_DOM_ELEMENT (parent), "type")) {
-                       level++;
-
-                       if (set_plaintext_quoted) {
-                               element_add_class (
-                                       WEBKIT_DOM_ELEMENT (parent),
-                                       "-x-evo-plaintext-quoted");
-                       }
-               }
-
-               parent = webkit_dom_node_get_parent_node (parent);
-       }
-
-       return level;
-}
-
-static gchar *
-get_quotation_for_level (gint quote_level)
-{
-       gint ii;
-       GString *output = g_string_new ("");
-
-       for (ii = 0; ii < quote_level; ii++) {
-               g_string_append (output, "<span class=\"-x-evo-quote-character\">");
-               g_string_append (output, QUOTE_SYMBOL);
-               g_string_append (output, " ");
-               g_string_append (output, "</span>");
-       }
-
-       return g_string_free (output, FALSE);
-}
-
-static void
-quote_plain_text_element_after_wrapping (WebKitDOMDocument *document,
-                                         WebKitDOMElement *element,
-                                         gint quote_level)
-{
-       WebKitDOMNodeList *list;
-       WebKitDOMNode *quoted_node;
-       gint length, ii;
-       gchar *quotation;
-
-       quoted_node = WEBKIT_DOM_NODE (
-               webkit_dom_document_create_element (document, "SPAN", NULL));
-       webkit_dom_element_set_class_name (
-               WEBKIT_DOM_ELEMENT (quoted_node), "-x-evo-quoted");
-       quotation = get_quotation_for_level (quote_level);
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (quoted_node), quotation, NULL);
-
-       list = webkit_dom_element_query_selector_all (
-               element, "br.-x-evo-wrap-br", NULL);
-       webkit_dom_node_insert_before (
-               WEBKIT_DOM_NODE (element),
-               quoted_node,
-               webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
-               NULL);
-
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *br = webkit_dom_node_list_item (list, ii);
-
-               webkit_dom_node_insert_before (
-                       webkit_dom_node_get_parent_node (br),
-                       webkit_dom_node_clone_node (quoted_node, TRUE),
-                       webkit_dom_node_get_next_sibling (br),
-                       NULL);
-       }
-
-       g_object_unref (list);
-       g_free (quotation);
-}
-
-static gboolean
-is_citation_node (WebKitDOMNode *node)
-{
-       char *value;
-
-       if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))
-               return FALSE;
-
-       value = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "type");
-
-       /* citation == <blockquote type='cite'> */
-       if (g_strcmp0 (value, "cite") == 0) {
-               g_free (value);
-               return TRUE;
-       } else {
-               g_free (value);
-               return FALSE;
-       }
-}
-
-static gboolean
-return_pressed_in_empty_line (EHTMLEditorSelection *selection,
-                              WebKitDOMDocument *document)
-{
-       WebKitDOMDOMSelection *dom_selection;
-       WebKitDOMDOMWindow *dom_window;
-       WebKitDOMNode *node;
-       WebKitDOMRange *range;
-
-       dom_window = webkit_dom_document_get_default_view (document);
-       dom_selection = webkit_dom_dom_window_get_selection (dom_window);
-
-       range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       if (!range)
-               return FALSE;
-
-       node = webkit_dom_range_get_start_container (range, NULL);
-       if (!WEBKIT_DOM_IS_TEXT (node)) {
-               WebKitDOMNode *first_child;
-
-               first_child = webkit_dom_node_get_first_child (node);
-               if (first_child && WEBKIT_DOM_IS_ELEMENT (first_child) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (first_child), "-x-evo-quoted")) {
-                       WebKitDOMNode *prev_sibling;
-
-                       prev_sibling = webkit_dom_node_get_previous_sibling (node);
-                       if (!prev_sibling)
-                               return webkit_dom_range_get_collapsed (range, NULL);
-               }
-       }
-
-       return FALSE;
-}
-
-static WebKitDOMNode *
-get_parent_block_node_from_child (WebKitDOMNode *node)
-{
-       WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
-
-       if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-temp-text-wrapper") ||
-           WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) ||
-           element_has_tag (WEBKIT_DOM_ELEMENT (parent), "b") ||
-           element_has_tag (WEBKIT_DOM_ELEMENT (parent), "i") ||
-           element_has_tag (WEBKIT_DOM_ELEMENT (parent), "u"))
-               parent = webkit_dom_node_get_parent_node (parent);
-
-       return parent;
-}
-
-static WebKitDOMElement *
-prepare_paragraph (EHTMLEditorSelection *selection,
-                   WebKitDOMDocument *document,
-                   gboolean with_selection)
-{
-       WebKitDOMElement *element, *paragraph;
-
-       paragraph = e_html_editor_selection_get_paragraph_element (
-               selection, document, -1, 0);
-
-       if (with_selection)
-               add_selection_markers_into_element_start (
-                       document, paragraph, NULL, NULL);
-
-       element = webkit_dom_document_create_element (document, "BR", NULL);
-
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (paragraph), WEBKIT_DOM_NODE (element), NULL);
-
-       return paragraph;
-}
-
-static WebKitDOMElement *
-insert_new_line_into_citation (EHTMLEditorView *view,
-                               const gchar *html_to_insert)
-{
-       gboolean html_mode, ret_val, avoid_editor_call;
-       EHTMLEditorSelection *selection;
-       WebKitDOMDocument *document;
-       WebKitDOMElement *element, *paragraph = NULL;
-
-       html_mode = e_html_editor_view_get_html_mode (view);
-       selection = e_html_editor_view_get_selection (view);
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       avoid_editor_call =
-               return_pressed_in_empty_line (selection, document);
-
-       if (avoid_editor_call) {
-               WebKitDOMElement *selection_start_marker;
-               WebKitDOMNode *current_block, *parent, *parent_block, *block_clone;
-
-               e_html_editor_selection_save (selection);
-
-               selection_start_marker = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-selection-start-marker");
-
-               current_block = get_parent_block_node_from_child (
-                       WEBKIT_DOM_NODE (selection_start_marker));
-
-               block_clone = webkit_dom_node_clone_node (current_block, TRUE);
-               /* Find selection start marker and restore it after the new line
-                * is inserted */
-               selection_start_marker = webkit_dom_element_query_selector (
-                       WEBKIT_DOM_ELEMENT (block_clone), "#-x-evo-selection-start-marker", NULL);
-
-               /* Find parent node that is immediate child of the BODY */
-               /* Build the same structure of parent nodes of the current block */
-               parent_block = current_block;
-               parent = webkit_dom_node_get_parent_node (parent_block);
-               while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
-                       WebKitDOMNode *node;
-
-                       parent_block = parent;
-                       node = webkit_dom_node_clone_node (parent_block, FALSE);
-                       webkit_dom_node_append_child (node, block_clone, NULL);
-                       block_clone = node;
-                       parent = webkit_dom_node_get_parent_node (parent_block);
-               }
-
-               paragraph = e_html_editor_selection_get_paragraph_element (
-                       selection, document, -1, 0);
-
-               webkit_dom_html_element_set_inner_text (
-                       WEBKIT_DOM_HTML_ELEMENT (paragraph),
-                       UNICODE_ZERO_WIDTH_SPACE,
-                       NULL);
-
-               /* Insert the selection markers to right place */
-               webkit_dom_node_insert_before (
-                       WEBKIT_DOM_NODE (paragraph),
-                       webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (selection_start_marker)),
-                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (paragraph)),
-                       NULL);
-               webkit_dom_node_insert_before (
-                       WEBKIT_DOM_NODE (paragraph),
-                       WEBKIT_DOM_NODE (selection_start_marker),
-                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (paragraph)),
-                       NULL);
-
-               /* Insert the cloned nodes before the BODY parent node */
-               webkit_dom_node_insert_before (
-                       webkit_dom_node_get_parent_node (parent_block),
-                       block_clone,
-                       parent_block,
-                       NULL);
-
-               /* Insert the new empty paragraph before the BODY parent node */
-               webkit_dom_node_insert_before (
-                       webkit_dom_node_get_parent_node (parent_block),
-                       WEBKIT_DOM_NODE (paragraph),
-                       parent_block,
-                       NULL);
-
-               /* Remove the old block (its copy was moved to the right place) */
-               remove_node (current_block);
-
-               e_html_editor_selection_restore (selection);
-
-               return NULL;
-       } else {
-               ret_val = e_html_editor_view_exec_command (
-                       view, E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, NULL);
-
-               if (!ret_val)
-                       return NULL;
-
-               element = webkit_dom_document_query_selector (
-                       document, "body>br", NULL);
-
-               if (!element)
-                       return NULL;
-       }
-
-       if (!html_mode) {
-               WebKitDOMNode *next_sibling;
-
-               next_sibling = webkit_dom_node_get_next_sibling (
-                       WEBKIT_DOM_NODE (element));
-
-               if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (next_sibling)) {
-                       gint citation_level, length;
-                       gint word_wrap_length =
-                               e_html_editor_selection_get_word_wrap_length (selection);
-                       WebKitDOMNode *node;
-
-                       node = webkit_dom_node_get_first_child (next_sibling);
-                       while (node && is_citation_node (node))
-                               node = webkit_dom_node_get_first_child (node);
-
-                       citation_level = get_citation_level (node, FALSE);
-                       length = word_wrap_length - 2 * citation_level;
-
-                       /* Rewrap and requote first block after the newly inserted line */
-                       if (node && WEBKIT_DOM_IS_ELEMENT (node)) {
-                               remove_quoting_from_element (WEBKIT_DOM_ELEMENT (node));
-                               remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (node));
-                               node = WEBKIT_DOM_NODE (e_html_editor_selection_wrap_paragraph_length (
-                                       selection, WEBKIT_DOM_ELEMENT (node), length));
-                               quote_plain_text_element_after_wrapping (
-                                       document, WEBKIT_DOM_ELEMENT (node), citation_level);
-                       }
-
-                       e_html_editor_view_force_spell_check (view);
-               }
-       }
-
-       if (html_to_insert && *html_to_insert) {
-               paragraph = prepare_paragraph (selection, document, FALSE);
-               webkit_dom_html_element_set_inner_html (
-                       WEBKIT_DOM_HTML_ELEMENT (paragraph),
-                       html_to_insert,
-                       NULL);
-               add_selection_markers_into_element_end (
-                       document, paragraph, NULL, NULL);
-       } else
-               paragraph = prepare_paragraph (selection, document, TRUE);
-
-       webkit_dom_node_insert_before (
-               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
-               WEBKIT_DOM_NODE (paragraph),
-               WEBKIT_DOM_NODE (element),
-               NULL);
-
-       remove_node (WEBKIT_DOM_NODE (element));
-
-       e_html_editor_selection_restore (selection);
-
-       return paragraph;
-}
-
 static void
 set_base64_to_element_attribute (EHTMLEditorView *view,
                                  WebKitDOMElement *element,
@@ -960,100 +494,6 @@ change_cid_images_src_to_base64 (EHTMLEditorView *view)
        g_hash_table_remove_all (view->priv->inline_images);
 }
 
-/* For purpose of this function see e-mail-formatter-quote.c */
-static void
-put_body_in_citation (WebKitDOMDocument *document)
-{
-       WebKitDOMElement *cite_body = webkit_dom_document_query_selector (
-               document, "span.-x-evo-cite-body", NULL);
-
-       if (cite_body) {
-               WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
-               WebKitDOMNode *citation;
-               WebKitDOMNode *sibling;
-
-               citation = WEBKIT_DOM_NODE (
-                       webkit_dom_document_create_element (document, "blockquote", NULL));
-               webkit_dom_element_set_id (WEBKIT_DOM_ELEMENT (citation), "-x-evo-main-cite");
-               webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (citation), "type", "cite", NULL);
-
-               webkit_dom_node_insert_before (
-                       WEBKIT_DOM_NODE (body),
-                       citation,
-                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
-                       NULL);
-
-               while ((sibling = webkit_dom_node_get_next_sibling (citation)))
-                       webkit_dom_node_append_child (citation, sibling, NULL);
-       }
-}
-
-/* For purpose of this function see e-mail-formatter-quote.c */
-static void
-move_elements_to_body (WebKitDOMDocument *document)
-{
-       WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
-       WebKitDOMNodeList *list;
-       gint ii;
-
-       list = webkit_dom_document_query_selector_all (
-               document, "span.-x-evo-to-body[data-headers]", NULL);
-       for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
-               WebKitDOMNode *child;
-               WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
-
-               while ((child = webkit_dom_node_get_first_child (node))) {
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (body),
-                               child,
-                               webkit_dom_node_get_first_child (
-                                       WEBKIT_DOM_NODE (body)),
-                               NULL);
-               }
-
-               remove_node (node);
-       }
-       g_object_unref (list);
-
-       list = webkit_dom_document_query_selector_all (
-               document, "span.-x-evo-to-body[data-credits]", NULL);
-       for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
-               WebKitDOMNode *child;
-               WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
-
-               while ((child = webkit_dom_node_get_first_child (node))) {
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (body),
-                               child,
-                               webkit_dom_node_get_first_child (
-                                       WEBKIT_DOM_NODE (body)),
-                               NULL);
-               }
-
-               remove_node (node);
-       }
-       g_object_unref (list);
-}
-
-static void
-repair_gmail_blockquotes (WebKitDOMDocument *document)
-{
-       WebKitDOMNodeList *list;
-       gint ii, length;
-
-       list = webkit_dom_document_query_selector_all (
-               document, "blockquote.gmail_quote", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
-
-               webkit_dom_element_remove_attribute (WEBKIT_DOM_ELEMENT (node), "class");
-               webkit_dom_element_remove_attribute (WEBKIT_DOM_ELEMENT (node), "style");
-               webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (node), "type", "cite", NULL);
-       }
-       g_object_unref (list);
-}
-
 /* Based on original use_pictograms() from GtkHTML */
 static const gchar *emoticons_chars =
        /*  0 */ "DO)(|/PQ*!"
@@ -1484,7 +924,7 @@ emoticon_read_async_cb (GFile *file,
                        misplaced_selection = TRUE;
 
        mime_type = g_content_type_get_mime_type (load_context->content_type);
-       range = html_editor_view_get_dom_range (view);
+       range = dom_get_range (view);
        node = webkit_dom_range_get_end_container (range, NULL);
        if (WEBKIT_DOM_IS_TEXT (node))
                node_text = webkit_dom_text_get_whole_text (WEBKIT_DOM_TEXT (node));
@@ -1683,395 +1123,34 @@ html_editor_view_check_magic_smileys (EHTMLEditorView *view,
 }
 
 static void
-html_editor_view_set_links_active (EHTMLEditorView *view,
-                                   gboolean active)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMElement *style;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       if (active) {
-               style = webkit_dom_document_get_element_by_id (
-                               document, "--evolution-editor-style-a");
-               if (style)
-                       remove_node (WEBKIT_DOM_NODE (style));
-       } else {
-               WebKitDOMHTMLHeadElement *head;
-               head = webkit_dom_document_get_head (document);
-
-               style = webkit_dom_document_create_element (document, "STYLE", NULL);
-               webkit_dom_element_set_id (style, "--evolution-editor-style-a");
-               webkit_dom_html_element_set_inner_text (
-                       WEBKIT_DOM_HTML_ELEMENT (style), "a { cursor: text; }", NULL);
-
-               webkit_dom_node_append_child (
-                       WEBKIT_DOM_NODE (head), WEBKIT_DOM_NODE (style), NULL);
-       }
-}
-
-static void
-fix_paragraph_structure_after_pressing_enter_after_smiley (EHTMLEditorSelection *selection,
-                                                           WebKitDOMDocument *document)
-{
-       WebKitDOMElement *element;
-
-       element = webkit_dom_document_query_selector (
-               document, "span.-x-evo-smiley-wrapper > br", NULL);
-
-       if (element) {
-               WebKitDOMNode *parent;
-
-               parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element));
-               webkit_dom_html_element_set_inner_html (
-                       WEBKIT_DOM_HTML_ELEMENT (
-                               webkit_dom_node_get_parent_node (parent)),
-                       UNICODE_ZERO_WIDTH_SPACE,
-                       NULL);
-       }
-}
-
-static void
-mark_node_as_paragraph_after_ending_list (EHTMLEditorSelection *selection,
-                                          WebKitDOMDocument *document)
-{
-       gint ii, length;
-       WebKitDOMNodeList *list;
-
-       /* When pressing Enter on empty line in the list WebKit will end that
-        * list and inserts <div><br></div> so mark it for wrapping */
-       list = webkit_dom_document_query_selector_all (
-               document, "body > div:not(.-x-evo-paragraph) > br", NULL);
-
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *node = webkit_dom_node_get_parent_node (
-                       webkit_dom_node_list_item (list, ii));
-
-               e_html_editor_selection_set_paragraph_style (
-                       selection, WEBKIT_DOM_ELEMENT (node), -1, 0, "");
-       }
-       g_object_unref (list);
-}
-
-static gboolean
-surround_text_with_paragraph_if_needed (EHTMLEditorSelection *selection,
-                                        WebKitDOMDocument *document,
-                                        WebKitDOMNode *node)
-{
-       WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
-       WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (node);
-       WebKitDOMElement *element;
-
-       /* All text in composer has to be written in div elements, so if
-        * we are writing something straight to the body, surround it with
-        * paragraph */
-       if (WEBKIT_DOM_IS_TEXT (node) &&
-           WEBKIT_DOM_IS_HTML_BODY_ELEMENT (webkit_dom_node_get_parent_node (node))) {
-               element = e_html_editor_selection_put_node_into_paragraph (
-                       selection,
-                       document,
-                       node,
-                       e_html_editor_selection_get_caret_position_node (document));
-
-               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (next_sibling))
-                       remove_node (next_sibling);
-
-               /* Tab character */
-               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "Apple-tab-span")) {
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (element),
-                               prev_sibling,
-                               webkit_dom_node_get_first_child (
-                                       WEBKIT_DOM_NODE (element)),
-                               NULL);
-               }
-
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
-static void
-body_input_event_cb (WebKitDOMElement *element,
-                     WebKitDOMEvent *event,
-                     EHTMLEditorView *view)
+insert_and_convert_html_into_selection (EHTMLEditorView *view,
+                                        const gchar *text,
+                                        gboolean is_html)
 {
-       EHTMLEditorSelection *selection;
-       GdkEventKey *key_event;
-       WebKitDOMNode *node;
-       WebKitDOMRange *range = html_editor_view_get_dom_range (view);
-       WebKitDOMDocument *document;
-
-       selection = e_html_editor_view_get_selection (view);
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
+       GDBusProxy *web_extension;
 
-       e_html_editor_view_set_changed (view, TRUE);
-       key_event = view->priv->key_event;
+       g_return_if_fail (view != NULL);
 
-       if (!key_event)
+       if (!text || !*text)
                return;
 
-       if (view->priv->magic_smileys && view->priv->html_mode)
-               html_editor_view_check_magic_smileys (view, range);
-
-       if (is_return_key (key_event) || (key_event->keyval == GDK_KEY_space)) {
-               html_editor_view_check_magic_links (view, range, FALSE, key_event);
-               mark_node_as_paragraph_after_ending_list (selection, document);
-               if (view->priv->html_mode)
-                       fix_paragraph_structure_after_pressing_enter_after_smiley (
-                               selection, document);
-       } else {
-               WebKitDOMNode *node;
-
-               node = webkit_dom_range_get_end_container (range, NULL);
-
-               if (surround_text_with_paragraph_if_needed (selection, document, node)) {
-                       e_html_editor_selection_restore_caret_position (selection);
-                       node = webkit_dom_range_get_end_container (range, NULL);
-                       range = html_editor_view_get_dom_range (view);
-               }
-
-               if (WEBKIT_DOM_IS_TEXT (node)) {
-                       gchar *text;
-
-                       text = webkit_dom_node_get_text_content (node);
-
-                       if (g_strcmp0 (text, "") != 0 && !g_unichar_isspace (g_utf8_get_char (text))) {
-                               WebKitDOMNode *prev_sibling;
-
-                               prev_sibling = webkit_dom_node_get_previous_sibling (node);
-
-                               if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling))
-                                       html_editor_view_check_magic_links (view, range, FALSE, key_event);
-                       }
-                       g_free (text);
-               }
-       }
-
-       node = webkit_dom_range_get_end_container (range, NULL);
-
-       /* After toggling monospaced format, we are using UNICODE_ZERO_WIDTH_SPACE
-        * to move caret into right space. When this callback is called it is not
-        * necassary anymore so remove it */
-       if (view->priv->html_mode) {
-               WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
-
-               if (parent) {
-                       WebKitDOMNode *prev_sibling;
-
-                       prev_sibling = webkit_dom_node_get_previous_sibling (
-                               WEBKIT_DOM_NODE (parent));
-
-                       if (prev_sibling && WEBKIT_DOM_IS_TEXT (prev_sibling)) {
-                               gchar *text = webkit_dom_node_get_text_content (
-                                       prev_sibling);
-
-                               if (g_strcmp0 (text, UNICODE_ZERO_WIDTH_SPACE) == 0)
-                                       remove_node (prev_sibling);
-
-                               g_free (text);
-                       }
-
-               }
-       }
-
-       /* If text before caret includes UNICODE_ZERO_WIDTH_SPACE character, remove it */
-       if (WEBKIT_DOM_IS_TEXT (node)) {
-               gchar *text = webkit_dom_character_data_get_data (WEBKIT_DOM_CHARACTER_DATA (node));
-               glong length = g_utf8_strlen (text, -1);
-               WebKitDOMNode *parent;
-
-               /* We have to preserve empty paragraphs with just UNICODE_ZERO_WIDTH_SPACE
-                * character as when we will remove it it will collapse */
-               if (length > 1) {
-                       if (g_str_has_prefix (text, UNICODE_ZERO_WIDTH_SPACE))
-                               webkit_dom_character_data_replace_data (
-                                       WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
-                       else if (g_str_has_suffix (text, UNICODE_ZERO_WIDTH_SPACE))
-                               webkit_dom_character_data_replace_data (
-                                       WEBKIT_DOM_CHARACTER_DATA (node), length - 1, 1, "", NULL);
-               }
-               g_free (text);
-
-               parent = webkit_dom_node_get_parent_node (node);
-               if ((WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (parent) ||
-                   WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent)) &&
-                   !element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph")) {
-                       if (e_html_editor_view_get_html_mode (view)) {
-                               element_add_class (
-                                       WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph");
-                       } else {
-                               e_html_editor_selection_set_paragraph_style (
-                                       selection,
-                                       WEBKIT_DOM_ELEMENT (parent),
-                                       -1, 0, "");
-                       }
-               }
-
-               /* When new smiley is added we have to use UNICODE_HIDDEN_SPACE to set the
-                * caret position to right place. It is removed when user starts typing. But
-                * when the user will press left arrow he will move the caret into
-                * smiley wrapper. If he will start to write there we have to move the written
-                * text out of the wrapper and move caret to right place */
-               if (WEBKIT_DOM_IS_ELEMENT (parent) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-smiley-wrapper")) {
-                       webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (parent),
-                               e_html_editor_selection_get_caret_position_node (
-                                       document),
-                               webkit_dom_node_get_next_sibling (parent),
-                               NULL);
-                       webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (parent),
-                               node,
-                               webkit_dom_node_get_next_sibling (parent),
-                               NULL);
-                       e_html_editor_selection_restore_caret_position (selection);
-               }
-       }
-
-       /* Writing into quoted content */
-       if (!view->priv->html_mode) {
-               gint citation_level;
-               WebKitDOMElement *selection_start_marker, *selection_end_marker;
-               WebKitDOMNode *node, *parent;
-               WebKitDOMRange *range;
-
-               range = html_editor_view_get_dom_range (view);
-               node = webkit_dom_range_get_end_container (range, NULL);
-
-               citation_level = get_citation_level (node, FALSE);
-               if (citation_level == 0)
-                       return;
-
-               selection_start_marker = webkit_dom_document_query_selector (
-                       document, "span#-x-evo-selection-start-marker", NULL);
-               if (selection_start_marker)
-                       return;
-
-               e_html_editor_selection_save (selection);
-
-               selection_start_marker = webkit_dom_document_query_selector (
-                       document, "span#-x-evo-selection-start-marker", NULL);
-               selection_end_marker = webkit_dom_document_query_selector (
-                       document, "span#-x-evo-selection-end-marker", NULL);
-               /* If the selection was not saved, move it into the first child of body */
-               if (!selection_start_marker || !selection_end_marker) {
-                       WebKitDOMHTMLElement *body;
-                       WebKitDOMNode *child;
-
-                       body = webkit_dom_document_get_body (document);
-                       child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
-
-                       add_selection_markers_into_element_start (
-                               document,
-                               WEBKIT_DOM_ELEMENT (child),
-                               &selection_start_marker,
-                               &selection_end_marker);
-               }
-
-               /* We have to process elements only inside normal block */
-               parent = WEBKIT_DOM_NODE (get_parent_block_element (
-                       WEBKIT_DOM_NODE (selection_start_marker)));
-               if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent)) {
-                       e_html_editor_selection_restore (selection);
-                       return;
-               }
-
-               if (selection_start_marker) {
-                       gchar *content;
-                       gint text_length, word_wrap_length, length;
-                       WebKitDOMElement *block;
-                       gboolean remove_quoting = FALSE;
-
-                       word_wrap_length =
-                               e_html_editor_selection_get_word_wrap_length (selection);
-                       length = word_wrap_length - 2 * citation_level;
-
-                       block = WEBKIT_DOM_ELEMENT (parent);
-                       if (webkit_dom_element_query_selector (
-                               WEBKIT_DOM_ELEMENT (block), ".-x-evo-quoted", NULL)) {
-                               WebKitDOMNode *prev_sibling;
-
-                               prev_sibling = webkit_dom_node_get_previous_sibling (
-                                       WEBKIT_DOM_NODE (selection_end_marker));
-
-                               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling))
-                                       remove_quoting = element_has_class (
-                                               WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-quoted");
-                       }
-
-                       content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (block));
-                       text_length = g_utf8_strlen (content, -1);
-                       g_free (content);
-
-                       /* Wrap and quote the line */
-                       if (!remove_quoting && text_length >= word_wrap_length) {
-                               remove_quoting_from_element (block);
-
-                               block = e_html_editor_selection_wrap_paragraph_length (
-                                       selection, block, length);
-                               webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
-                               quote_plain_text_element_after_wrapping (
-                                       document, WEBKIT_DOM_ELEMENT (block), citation_level);
-                               selection_start_marker = webkit_dom_document_query_selector (
-                                       document, "span#-x-evo-selection-start-marker", NULL);
-                               if (!selection_start_marker)
-                                       add_selection_markers_into_element_end (
-                                               document,
-                                               WEBKIT_DOM_ELEMENT (block),
-                                               NULL,
-                                               NULL);
-
-                               e_html_editor_selection_restore (selection);
-                               e_html_editor_view_force_spell_check_for_current_paragraph (view);
-                               return;
-                       }
-               }
-               e_html_editor_selection_restore (selection);
-       }
-}
-
-static void
-remove_input_event_listener_from_body (EHTMLEditorView *view)
-{
-       if (!view->priv->body_input_event_removed) {
-               WebKitDOMDocument *document;
-
-               document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-               webkit_dom_event_target_remove_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (
-                               webkit_dom_document_get_body (document)),
-                       "input",
-                       G_CALLBACK (body_input_event_cb),
-                       FALSE);
-
-               view->priv->body_input_event_removed = TRUE;
-       }
-}
-
-static void
-register_input_event_listener_on_body (EHTMLEditorView *view)
-{
-       if (view->priv->body_input_event_removed) {
-               WebKitDOMDocument *document;
-
-               document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (
-                               webkit_dom_document_get_body (document)),
-                       "input",
-                       G_CALLBACK (body_input_event_cb),
-                       FALSE,
-                       view);
+       web_extension = e_html_editor_view_get_web_extension_proxy (view);
+       if (!web_extension)
+               return;
 
-               view->priv->body_input_event_removed = FALSE;
-       }
+       g_dbus_proxy_call (
+               web_extension,
+               "DOMInsertAndConvertHTMLIntoSelection",
+               g_variant_new (
+                       "(tsb)",
+                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+                       text,
+                       is_html),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
 }
 
 static void
@@ -2079,14 +1158,7 @@ clipboard_text_received_for_paste_as_text (GtkClipboard *clipboard,
                                            const gchar *text,
                                            EHTMLEditorView *view)
 {
-       EHTMLEditorSelection *selection;
-
-       if (!text || !*text)
-               return;
-
-       selection = e_html_editor_view_get_selection (view);
-
-       html_editor_view_insert_converted_html_into_selection (view, TRUE, html);
+       insert_and_convert_html_into_selection (view, text, TRUE);
 }
 
 static void
@@ -2094,65 +1166,29 @@ clipboard_text_received (GtkClipboard *clipboard,
                          const gchar *text,
                          EHTMLEditorView *view)
 {
-       EHTMLEditorSelection *selection;
-       gchar *escaped_text;
-       WebKitDOMDocument *document;
-       WebKitDOMDOMWindow *window;
-       WebKitDOMDOMSelection *dom_selection;
-       WebKitDOMElement *blockquote, *element;
-       WebKitDOMNode *node;
-       WebKitDOMRange *range;
+       GDBusProxy *web_extension;
+
+       g_return_if_fail (view != NULL);
 
        if (!text || !*text)
                return;
 
-       selection = e_html_editor_view_get_selection (view);
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       window = webkit_dom_document_get_default_view (document);
-       dom_selection = webkit_dom_dom_window_get_selection (window);
-
-       /* This is a trick to escape any HTML characters (like <, > or &).
-        * <textarea> automatically replaces all these unsafe characters
-        * by &lt;, &gt; etc. */
-       element = webkit_dom_document_create_element (document, "textarea", NULL);
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (element), text, NULL);
-       escaped_text = webkit_dom_html_element_get_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (element));
-
-       element = webkit_dom_document_create_element (document, "pre", NULL);
-
-       webkit_dom_html_element_set_inner_text (
-               WEBKIT_DOM_HTML_ELEMENT (element), escaped_text, NULL);
-
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (element),
-               e_html_editor_selection_get_caret_position_node (document),
-               NULL);
-
-       blockquote = webkit_dom_document_create_element (document, "blockquote", NULL);
-       webkit_dom_element_set_attribute (blockquote, "type", "cite", NULL);
-
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (blockquote), WEBKIT_DOM_NODE (element), NULL);
-
-       if (!e_html_editor_view_get_html_mode (view))
-               e_html_editor_view_quote_plain_text_element (view, element);
-
-       range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       node = webkit_dom_range_get_end_container (range, NULL);
+       web_extension = e_html_editor_view_get_web_extension_proxy (view);
+       if (!web_extension)
+               return;
 
-       webkit_dom_node_append_child (
-               webkit_dom_node_get_parent_node (node),
-               WEBKIT_DOM_NODE (blockquote),
+       g_dbus_proxy_call (
+               web_extension,
+               "DOMQuoteAndInsertTextIntoSelection",
+               g_variant_new (
+                       "(tsb)",
+                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+                       text),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
                NULL);
-
-       e_html_editor_selection_restore_caret_position (selection);
-
-       e_html_editor_view_force_spell_check_for_current_paragraph (view);
-
-       g_free (escaped_text);
 }
 
 static void
@@ -2205,32 +1241,32 @@ html_editor_view_get_property (GObject *object,
        switch (property_id) {
                case PROP_CAN_COPY:
                        g_value_set_boolean (
-                               value, webkit_web_view_can_copy_clipboard (
-                               WEBKIT_WEB_VIEW (object)));
+                               value, html_editor_view_can_copy (
+                               E_HTML_EDITOR_VIEW (object)));
                        return;
 
                case PROP_CAN_CUT:
                        g_value_set_boolean (
-                               value, webkit_web_view_can_cut_clipboard (
-                               WEBKIT_WEB_VIEW (object)));
+                               value, html_editor_view_can_cut (
+                               E_HTML_EDITOR_VIEW (object)));
                        return;
 
                case PROP_CAN_PASTE:
                        g_value_set_boolean (
-                               value, webkit_web_view_can_paste_clipboard (
-                               WEBKIT_WEB_VIEW (object)));
+                               value, html_editor_view_can_paste (
+                               E_HTML_EDITOR_VIEW (object)));
                        return;
 
                case PROP_CAN_REDO:
                        g_value_set_boolean (
-                               value, webkit_web_view_can_redo (
-                               WEBKIT_WEB_VIEW (object)));
+                               value, html_editor_view_can_redo (
+                               E_HTML_EDITOR_VIEW (object)));
                        return;
 
                case PROP_CAN_UNDO:
                        g_value_set_boolean (
-                               value, webkit_web_view_can_undo (
-                               WEBKIT_WEB_VIEW (object)));
+                               value, html_editor_view_can_undo (
+                               E_HTML_EDITOR_VIEW (object)));
                        return;
 
                case PROP_CHANGED:
@@ -2452,218 +1488,6 @@ html_editor_view_button_release_event (GtkWidget *widget,
 }
 
 static gboolean
-prevent_from_deleting_last_element_in_body (EHTMLEditorView *view)
-{
-       gboolean ret_val = FALSE;
-       WebKitDOMDocument *document;
-       WebKitDOMHTMLElement *body;
-       WebKitDOMNodeList *list;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       body = webkit_dom_document_get_body (document);
-
-       list = webkit_dom_node_get_child_nodes (WEBKIT_DOM_NODE (body));
-
-       if (webkit_dom_node_list_get_length (list) <= 1) {
-               gchar *content;
-
-               content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (body));
-
-               if (!*content)
-                       ret_val = TRUE;
-
-               g_free (content);
-
-               if (webkit_dom_element_query_selector (WEBKIT_DOM_ELEMENT (body), "img", NULL))
-                       ret_val = FALSE;
-       }
-       g_object_unref (list);
-
-       return ret_val;
-}
-
-static gboolean
-change_quoted_block_to_normal (EHTMLEditorView *view)
-{
-       gint citation_level, success = FALSE;
-       WebKitDOMDocument *document;
-       WebKitDOMElement *selection_start_marker, *selection_end_marker, *block;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       selection_start_marker = webkit_dom_document_query_selector (
-               document, "span#-x-evo-selection-start-marker", NULL);
-       selection_end_marker = webkit_dom_document_query_selector (
-               document, "span#-x-evo-selection-end-marker", NULL);
-
-       if (!selection_start_marker || !selection_end_marker)
-               return FALSE;
-
-       block = WEBKIT_DOM_ELEMENT (get_parent_block_node_from_child (
-               WEBKIT_DOM_NODE (selection_start_marker)));
-
-       citation_level = get_citation_level (
-               WEBKIT_DOM_NODE (selection_start_marker), FALSE);
-
-       if (selection_start_marker && citation_level > 0) {
-               if (webkit_dom_element_query_selector (
-                       WEBKIT_DOM_ELEMENT (block), ".-x-evo-quoted", NULL)) {
-
-                       WebKitDOMNode *prev_sibling;
-
-                       webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
-
-                       prev_sibling = webkit_dom_node_get_previous_sibling (
-                               WEBKIT_DOM_NODE (selection_start_marker));
-
-                       if (WEBKIT_DOM_IS_ELEMENT (prev_sibling))
-                               success = element_has_class (
-                                       WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-quoted");
-                       /* We really have to be in the beginning of paragraph and
-                        * not on the beginning of some line in the paragraph */
-                       if (success && webkit_dom_node_get_previous_sibling (prev_sibling))
-                               success = FALSE;
-               }
-
-               if (view->priv->html_mode)
-                       success = WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (
-                               webkit_dom_node_get_parent_element (
-                                       WEBKIT_DOM_NODE (block)));
-       }
-
-       if (success && citation_level == 1) {
-               gchar *inner_html;
-               WebKitDOMElement *paragraph;
-
-               inner_html = webkit_dom_html_element_get_inner_html (
-                       WEBKIT_DOM_HTML_ELEMENT (block));
-               webkit_dom_element_set_id (
-                       WEBKIT_DOM_ELEMENT (block), "-x-evo-to-remove");
-
-               paragraph = insert_new_line_into_citation (view, inner_html);
-               g_free (inner_html);
-
-               if (paragraph) {
-                       if (view->priv->html_mode) {
-                               webkit_dom_node_insert_before (
-                                       WEBKIT_DOM_NODE (paragraph),
-                                       WEBKIT_DOM_NODE (selection_start_marker),
-                                       webkit_dom_node_get_first_child (
-                                               WEBKIT_DOM_NODE (paragraph)),
-                                       NULL);
-                               webkit_dom_node_insert_before (
-                                       WEBKIT_DOM_NODE (paragraph),
-                                       WEBKIT_DOM_NODE (selection_end_marker),
-                                       webkit_dom_node_get_first_child (
-                                               WEBKIT_DOM_NODE (paragraph)),
-                                       NULL);
-
-                       }
-
-                       remove_quoting_from_element (paragraph);
-                       remove_wrapping_from_element (paragraph);
-               }
-
-               if (block)
-                       remove_node (WEBKIT_DOM_NODE (block));
-               block = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-to-remove");
-               if (block)
-                       remove_node (WEBKIT_DOM_NODE (block));
-
-               if (paragraph)
-                       remove_node_if_empty (
-                               webkit_dom_node_get_next_sibling (
-                                       WEBKIT_DOM_NODE (paragraph)));
-       }
-
-       if (success && citation_level > 1) {
-               gint length, word_wrap_length;
-               EHTMLEditorSelection *selection;
-               WebKitDOMNode *parent;
-
-               selection = e_html_editor_view_get_selection (view);
-               word_wrap_length = e_html_editor_selection_get_word_wrap_length (selection);
-               length =  word_wrap_length - 2 * (citation_level - 1);
-
-               if (view->priv->html_mode) {
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (block),
-                               WEBKIT_DOM_NODE (selection_start_marker),
-                               webkit_dom_node_get_first_child (
-                                       WEBKIT_DOM_NODE (block)),
-                               NULL);
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (block),
-                               WEBKIT_DOM_NODE (selection_end_marker),
-                               webkit_dom_node_get_first_child (
-                                       WEBKIT_DOM_NODE (block)),
-                               NULL);
-
-               }
-
-               remove_quoting_from_element (block);
-               remove_wrapping_from_element (block);
-
-               block = e_html_editor_selection_wrap_paragraph_length (
-                       selection, block, length);
-               webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
-               quote_plain_text_element_after_wrapping (
-                       document, block, citation_level - 1);
-
-               parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (block));
-
-               if (!webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (block))) {
-                       /* Currect block is in the beginning of citation, just move it
-                        * before the citation where already is */
-                       webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (parent),
-                               WEBKIT_DOM_NODE (block),
-                               parent,
-                               NULL);
-               } else if (!webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (block))) {
-                       /* Currect block is at the end of the citation, just move it
-                        * after the citation where already is */
-                       webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (parent),
-                               WEBKIT_DOM_NODE (block),
-                               webkit_dom_node_get_next_sibling (parent),
-                               NULL);
-               } else {
-                       /* Current block is somewhere in the middle of the citation
-                        * so we need to split the citation and insert the block into
-                        * the citation that is one level lower */
-                       WebKitDOMNode *clone, *child;
-
-                       clone = webkit_dom_node_clone_node (parent, FALSE);
-
-                       /* Move nodes that are after the currect block into the
-                        * new blockquote */
-                       child = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (block));
-                       while (child) {
-                               WebKitDOMNode *next = webkit_dom_node_get_next_sibling (child);
-                               webkit_dom_node_append_child (clone, child, NULL);
-                               child = next;
-                       }
-
-                       clone = webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (parent),
-                               clone,
-                               webkit_dom_node_get_next_sibling (parent),
-                               NULL);
-
-                       webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (parent),
-                               WEBKIT_DOM_NODE (block),
-                               clone,
-                               NULL);
-               }
-       }
-
-       return success;
-}
-
-static gboolean
 html_editor_view_key_press_event (GtkWidget *widget,
                                   GdkEventKey *event)
 {
@@ -2922,101 +1746,6 @@ html_editor_view_paste_clipboard_quoted (EHTMLEditorView *view)
                view);
 }
 
-static gboolean
-html_editor_view_image_exists_in_cache (const gchar *image_uri)
-{
-       gchar *filename;
-       gchar *hash;
-       gboolean exists = FALSE;
-
-       g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
-
-       hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
-       filename = camel_data_cache_get_filename (
-               emd_global_http_cache, "http", hash);
-
-       if (filename != NULL) {
-               exists = g_file_test (filename, G_FILE_TEST_EXISTS);
-               g_free (filename);
-       }
-
-       g_free (hash);
-
-       return exists;
-}
-
-static gchar *
-html_editor_view_redirect_uri (EHTMLEditorView *view,
-                               const gchar *uri)
-{
-       EImageLoadingPolicy image_policy;
-       GSettings *settings;
-       gboolean uri_is_http;
-
-       uri_is_http =
-               g_str_has_prefix (uri, "http:") ||
-               g_str_has_prefix (uri, "https:") ||
-               g_str_has_prefix (uri, "evo-http:") ||
-               g_str_has_prefix (uri, "evo-https:");
-
-       /* Redirect http(s) request to evo-http(s) protocol.
-        * See EMailRequest for further details about this. */
-       if (uri_is_http) {
-               gchar *new_uri;
-               SoupURI *soup_uri;
-               gboolean image_exists;
-
-               /* Check Evolution's cache */
-               image_exists = html_editor_view_image_exists_in_cache (uri);
-
-               settings = e_util_ref_settings ("org.gnome.evolution.mail");
-               image_policy = g_settings_get_enum (settings, "image-loading-policy");
-               g_object_unref (settings);
-               /* If the URI is not cached and we are not allowed to load it
-                * then redirect to invalid URI, so that webkit would display
-                * a native placeholder for it. */
-               if (!image_exists && (image_policy == E_IMAGE_LOADING_POLICY_NEVER)) {
-                       return g_strdup ("about:blank");
-               }
-
-               new_uri = g_strconcat ("evo-", uri, NULL);
-               soup_uri = soup_uri_new (new_uri);
-               g_free (new_uri);
-
-               new_uri = soup_uri_to_string (soup_uri, FALSE);
-
-               soup_uri_free (soup_uri);
-
-               return new_uri;
-       }
-
-       return g_strdup (uri);
-}
-
-static void
-html_editor_view_resource_requested (WebKitWebView *web_view,
-                                     WebKitWebFrame *frame,
-                                     WebKitWebResource *resource,
-                                     WebKitNetworkRequest *request,
-                                     WebKitNetworkResponse *response,
-                                     gpointer user_data)
-{
-       const gchar *original_uri;
-
-       original_uri = webkit_network_request_get_uri (request);
-
-       if (original_uri != NULL) {
-               gchar *redirected_uri;
-
-               redirected_uri = html_editor_view_redirect_uri (
-                       E_HTML_EDITOR_VIEW (web_view), original_uri);
-
-               webkit_network_request_set_uri (request, redirected_uri);
-
-               g_free (redirected_uri);
-       }
-}
-
 static void
 web_extension_proxy_created_cb (GDBusProxy *proxy,
                                 GAsyncResult *result,
@@ -3044,7 +1773,7 @@ web_extension_appeared_cb (GDBusConnection *connection,
                NULL,
                name,
                E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
-               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE
+               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
                NULL,
                (GAsyncReadyCallback) web_extension_proxy_created_cb,
                view);
@@ -3055,7 +1784,7 @@ web_extension_vanished_cb (GDBusConnection *connection,
                            const gchar *name,
                            EHTMLEditorView *view)
 {
-       g_clear_object (&web_view->priv->web_extension);
+       g_clear_object (&view->priv->web_extension);
 }
 
 static void
@@ -3109,7 +1838,7 @@ e_html_editor_view_get_element_attribute (EHTMLEditorView *view,
                                           const gchar *attribute)
 {
        if (!view->priv->web_extension)
-               return;
+               return NULL;
 
        return g_dbus_proxy_call_sync (
                view->priv->web_extension,
@@ -3122,7 +1851,6 @@ e_html_editor_view_get_element_attribute (EHTMLEditorView *view,
                G_DBUS_CALL_FLAGS_NONE,
                -1,
                NULL,
-               NULL,
                NULL);
 }
 
@@ -3175,9 +1903,9 @@ e_html_editor_view_remove_element_attribute (EHTMLEditorView *view,
 }
 
 static GObjectConstructParam*
-find_property(guint n_properties,
-              GObjectConstructParam* properties,
-              GParamSpec* param_spec)
+find_property (guint n_properties,
+               GObjectConstructParam* properties,
+               GParamSpec* param_spec)
 {
        while (n_properties--) {
                if (properties->pspec == param_spec)
@@ -3188,7 +1916,7 @@ find_property(guint n_properties,
        return NULL;
 }
 
-static GObject*
+static GObject *
 html_editor_view_constructor (GType type,
                               guint n_construct_properties,
                               GObjectConstructParam *construct_properties)
@@ -3211,7 +1939,7 @@ html_editor_view_constructor (GType type,
 
        g_type_class_unref (object_class);
 
-       return G_OBJECT_CLASS (e_web_view_parent_class)->constructor(type, n_construct_properties, 
construct_properties);
+       return G_OBJECT_CLASS (e_html_editor_view_parent_class)->constructor(type, n_construct_properties, 
construct_properties);
 }
 
 static void
@@ -3467,1834 +2195,6 @@ e_html_editor_view_class_init (EHTMLEditorViewClass *class)
 }
 
 static void
-insert_quote_symbols (WebKitDOMHTMLElement *element,
-                      gint quote_level,
-                      gboolean skip_first,
-                      gboolean insert_newline)
-{
-       gchar *text;
-       gint ii;
-       GString *output;
-       gchar *quotation;
-
-       if (!WEBKIT_DOM_IS_HTML_ELEMENT (element))
-               return;
-
-       text = webkit_dom_html_element_get_inner_html (element);
-       output = g_string_new ("");
-       quotation = get_quotation_for_level (quote_level);
-
-       if (g_strcmp0 (text, "\n") == 0) {
-               g_string_append (output, "<span class=\"-x-evo-quoted\">");
-               g_string_append (output, quotation);
-               g_string_append (output, "</span>");
-               g_string_append (output, "\n");
-       } else {
-               gchar **lines;
-
-               lines = g_strsplit (text, "\n", 0);
-
-               for (ii = 0; lines[ii]; ii++) {
-                       if (ii == 0 && skip_first) {
-                               if (g_strv_length (lines) == 1) {
-                                       g_strfreev (lines);
-                                       goto exit;
-                               }
-                               g_string_append (output, lines[ii]);
-                               g_string_append (output, "\n");
-                       }
-
-                       g_string_append (output, "<span class=\"-x-evo-quoted\">");
-                       g_string_append (output, quotation);
-                       g_string_append (output, "</span>");
-
-                       /* Insert line of text */
-                       g_string_append (output, lines[ii]);
-                       if ((ii == g_strv_length (lines) - 1) &&
-                           !g_str_has_suffix (text, "\n") && !insert_newline) {
-                               /* If we are on last line and node's text doesn't
-                                * end with \n, don't insert it */
-                               break;
-                       }
-                       g_string_append (output, "\n");
-               }
-
-               g_strfreev (lines);
-       }
-
-       webkit_dom_html_element_set_inner_html (element, output->str, NULL);
- exit:
-       g_free (quotation);
-       g_free (text);
-       g_string_free (output, TRUE);
-}
-
-static void
-quote_node (WebKitDOMDocument *document,
-           WebKitDOMNode *node,
-           gint quote_level)
-{
-       gboolean skip_first = FALSE;
-       gboolean insert_newline = FALSE;
-       gboolean is_html_node = FALSE;
-       WebKitDOMElement *wrapper;
-       WebKitDOMNode *node_clone, *prev_sibling, *next_sibling;
-
-       /* Don't quote when we are not in citation */
-       if (quote_level == 0)
-               return;
-
-       if (WEBKIT_DOM_IS_COMMENT (node))
-               return;
-
-       if (WEBKIT_DOM_IS_HTML_ELEMENT (node)) {
-               insert_quote_symbols (
-                       WEBKIT_DOM_HTML_ELEMENT (node), quote_level, FALSE, FALSE);
-               return;
-       }
-
-       prev_sibling = webkit_dom_node_get_previous_sibling (node);
-       next_sibling = webkit_dom_node_get_next_sibling (node);
-
-       is_html_node =
-               !WEBKIT_DOM_IS_TEXT (prev_sibling) &&
-               !WEBKIT_DOM_IS_COMMENT (prev_sibling) && (
-               WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling) ||
-               element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "b") ||
-               element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "i") ||
-               element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "u"));
-
-       if (prev_sibling && is_html_node)
-               skip_first = TRUE;
-
-       /* Skip the BR between first blockquote and pre */
-       if (quote_level == 1 && next_sibling && WEBKIT_DOM_IS_HTML_PRE_ELEMENT (next_sibling))
-               return;
-
-       /* Do temporary wrapper */
-       wrapper = webkit_dom_document_create_element (document, "SPAN", NULL);
-       webkit_dom_element_set_class_name (wrapper, "-x-evo-temp-text-wrapper");
-
-       node_clone = webkit_dom_node_clone_node (node, TRUE);
-
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (wrapper),
-               node_clone,
-               NULL);
-
-       insert_quote_symbols (
-               WEBKIT_DOM_HTML_ELEMENT (wrapper),
-               quote_level,
-               skip_first,
-               insert_newline);
-
-       webkit_dom_node_replace_child (
-               webkit_dom_node_get_parent_node (node),
-               WEBKIT_DOM_NODE (wrapper),
-               node,
-               NULL);
-}
-
-static void
-insert_quote_symbols_before_node (WebKitDOMDocument *document,
-                                  WebKitDOMNode *node,
-                                  gint quote_level,
-                                  gboolean is_html_node)
-{
-       gboolean skip, wrap_br;
-       gchar *quotation;
-       WebKitDOMElement *element;
-
-       quotation = get_quotation_for_level (quote_level);
-       element = webkit_dom_document_create_element (document, "SPAN", NULL);
-       element_add_class (element, "-x-evo-quoted");
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (element), quotation, NULL);
-
-       /* Don't insert temporary BR before BR that is used for wrapping */
-       skip = WEBKIT_DOM_IS_HTMLBR_ELEMENT (node);
-       wrap_br = element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-wrap-br");
-       skip = skip && wrap_br;
-
-       if (is_html_node && !skip) {
-               WebKitDOMElement *new_br;
-
-               new_br = webkit_dom_document_create_element (document, "br", NULL);
-               element_add_class (new_br, "-x-evo-temp-br");
-
-               webkit_dom_node_insert_before (
-                       webkit_dom_node_get_parent_node (node),
-                       WEBKIT_DOM_NODE (new_br),
-                       node,
-                       NULL);
-       }
-
-       webkit_dom_node_insert_before (
-               webkit_dom_node_get_parent_node (node),
-               WEBKIT_DOM_NODE (element),
-               node,
-               NULL);
-
-       if (is_html_node && !wrap_br)
-               remove_node (node);
-
-       g_free (quotation);
-}
-
-static gboolean
-element_is_selection_marker (WebKitDOMElement *element)
-{
-       gboolean is_marker = FALSE;
-
-       is_marker =
-               element_has_id (element, "-x-evo-selection-start-marker") ||
-               element_has_id (element, "-x-evo-selection-end-marker");
-
-       return is_marker;
-}
-
-static gboolean
-check_if_suppress_next_node (WebKitDOMNode *node)
-{
-       if (!node)
-               return FALSE;
-
-       if (node && WEBKIT_DOM_IS_ELEMENT (node))
-               if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node)))
-                       if (!webkit_dom_node_get_previous_sibling (node))
-                               return FALSE;
-
-       return TRUE;
-}
-
-static void
-quote_br_node (WebKitDOMNode *node,
-               gint quote_level)
-{
-       gchar *quotation, *content;
-
-       quotation = get_quotation_for_level (quote_level);
-
-       content = g_strconcat (
-               "<span class=\"-x-evo-quoted\">",
-               quotation,
-               "</span><br class=\"-x-evo-temp-br\">",
-               NULL);
-
-       webkit_dom_html_element_set_outer_html (
-               WEBKIT_DOM_HTML_ELEMENT (node),
-               content,
-               NULL);
-
-       g_free (content);
-       g_free (quotation);
-}
-
-static void
-quote_plain_text_recursive (WebKitDOMDocument *document,
-                           WebKitDOMNode *node,
-                           WebKitDOMNode *start_node,
-                           gint quote_level)
-{
-       gboolean skip_node = FALSE;
-       gboolean move_next = FALSE;
-       gboolean suppress_next = FALSE;
-       gboolean is_html_node = FALSE;
-       gboolean next = FALSE;
-       WebKitDOMNode *next_sibling, *prev_sibling;
-
-       node = webkit_dom_node_get_first_child (node);
-
-       while (node) {
-               gchar *text_content;
-
-               skip_node = FALSE;
-               move_next = FALSE;
-               is_html_node = FALSE;
-
-               if (WEBKIT_DOM_IS_COMMENT (node) ||
-                   WEBKIT_DOM_IS_HTML_META_ELEMENT (node) ||
-                   WEBKIT_DOM_IS_HTML_STYLE_ELEMENT (node) ||
-                   WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (node)) {
-
-                       move_next = TRUE;
-                       goto next_node;
-               }
-
-               prev_sibling = webkit_dom_node_get_previous_sibling (node);
-               next_sibling = webkit_dom_node_get_next_sibling (node);
-
-               if (WEBKIT_DOM_IS_TEXT (node)) {
-                       /* Start quoting after we are in blockquote */
-                       if (quote_level > 0 && !suppress_next) {
-                               /* When quoting text node, we are wrappering it and
-                                * afterwards replacing it with that wrapper, thus asking
-                                * for next_sibling after quoting will return NULL bacause
-                                * that node don't exist anymore */
-                               quote_node (document, node, quote_level);
-                               node = next_sibling;
-                               skip_node = TRUE;
-                       }
-
-                       goto next_node;
-               }
-
-               if (!(WEBKIT_DOM_IS_ELEMENT (node) || WEBKIT_DOM_IS_HTML_ELEMENT (node)))
-                       goto next_node;
-
-               if (element_has_id (WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-position")) {
-                       if (quote_level > 0)
-                               element_add_class (
-                                       WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-quoting");
-
-                       move_next = TRUE;
-                       suppress_next = TRUE;
-                       next = FALSE;
-                       goto next_node;
-               }
-
-               if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node))) {
-                       /* If there is collapsed selection in the beginning of line
-                        * we cannot suppress first text that is after the end of
-                        * selection */
-                       suppress_next = check_if_suppress_next_node (prev_sibling);
-                       if (suppress_next)
-                               next = FALSE;
-                       move_next = TRUE;
-                       goto next_node;
-               }
-
-               if (!WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) &&
-                   webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (node)) != 0)
-                       goto with_children;
-
-               /* Even in plain text mode we can have some basic html element
-                * like anchor and others. When Forwaring e-mail as Quoted EMFormat
-                * generates header that contatains <b> tags (bold font).
-                * We have to treat these elements separately to avoid
-                * modifications of theirs inner texts */
-               is_html_node =
-                       WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) ||
-                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "b") ||
-                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "i") ||
-                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "u");
-
-               if (is_html_node) {
-                       gboolean wrap_br;
-
-                       wrap_br =
-                               prev_sibling &&
-                               WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling) &&
-                               element_has_class (
-                                       WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-wrap-br");
-
-                       if (!prev_sibling || wrap_br)
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-
-                       if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling) && !wrap_br)
-                               insert_quote_symbols_before_node (
-                                       document, prev_sibling, quote_level, TRUE);
-
-                       move_next = TRUE;
-                       goto next_node;
-               }
-
-               /* If element doesn't have children, we can quote it */
-               if (is_citation_node (node)) {
-                       /* Citation with just text inside */
-                       quote_node (document, node, quote_level + 1);
-                       /* Set citation as quoted */
-                       element_add_class (
-                               WEBKIT_DOM_ELEMENT (node),
-                               "-x-evo-plaintext-quoted");
-
-                       move_next = TRUE;
-                       goto next_node;
-               }
-
-               if (!WEBKIT_DOM_IS_HTMLBR_ELEMENT (node)) {
-                       if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling)) {
-                               move_next = TRUE;
-                               goto next_node;
-                       }
-                       goto not_br;
-               } else if (element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-first-br") ||
-                          element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-last-br")) {
-                       quote_br_node (node, quote_level);
-                       node = next_sibling;
-                       skip_node = TRUE;
-                       goto next_node;
-               }
-
-               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
-                   WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (next_sibling) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
-                       /* Situation when anchors are alone on line */
-                       text_content = webkit_dom_node_get_text_content (prev_sibling);
-
-                       if (g_str_has_suffix (text_content, "\n")) {
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-                               remove_node (node);
-                               g_free (text_content);
-                               node = next_sibling;
-                               skip_node = TRUE;
-                               goto next_node;
-                       }
-                       g_free (text_content);
-               }
-
-               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling)) {
-                       quote_br_node (prev_sibling, quote_level);
-                       node = next_sibling;
-                       skip_node = TRUE;
-                       goto next_node;
-               }
-
-               if (!prev_sibling && !next_sibling) {
-                       WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
-
-                       if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) ||
-                           WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) ||
-                           (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
-                            !is_citation_node (parent))) {
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-
-                               goto next_node;
-                       }
-               }
-
-               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
-                       text_content = webkit_dom_node_get_text_content (prev_sibling);
-                       if (text_content && !*text_content) {
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-
-                               g_free (text_content);
-                               goto next_node;
-
-                       }
-
-                       g_free (text_content);
-               }
-
-               if (is_citation_node (prev_sibling)) {
-                       insert_quote_symbols_before_node (
-                               document, node, quote_level, FALSE);
-                       goto next_node;
-               }
-
-               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (node) &&
-                   !next_sibling &&
-                   element_is_selection_marker (WEBKIT_DOM_ELEMENT (prev_sibling))) {
-                       insert_quote_symbols_before_node (
-                               document, node, quote_level, FALSE);
-                       goto next_node;
-               }
-
-               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (node)) {
-                       move_next = TRUE;
-                       goto next_node;
-               }
-
- not_br:
-               text_content = webkit_dom_node_get_text_content (node);
-               if (text_content && !*text_content) {
-                       g_free (text_content);
-                       move_next = TRUE;
-                       goto next_node;
-               }
-               g_free (text_content);
-
-               quote_node (document, node, quote_level);
-
-               move_next = TRUE;
-               goto next_node;
-
- with_children:
-               if (is_citation_node (node)) {
-                       /* Go deeper and increase level */
-                       quote_plain_text_recursive (
-                               document, node, start_node, quote_level + 1);
-                       /* set citation as quoted */
-                       element_add_class (
-                               WEBKIT_DOM_ELEMENT (node),
-                               "-x-evo-plaintext-quoted");
-                       move_next = TRUE;
-               } else {
-                       quote_plain_text_recursive (
-                               document, node, start_node, quote_level);
-                       move_next = TRUE;
-               }
- next_node:
-               if (next) {
-                       suppress_next = FALSE;
-                       next = FALSE;
-               }
-
-               if (suppress_next)
-                       next = TRUE;
-
-               if (!skip_node) {
-                       /* Move to next node */
-                       if (!move_next && webkit_dom_node_has_child_nodes (node)) {
-                               node = webkit_dom_node_get_first_child (node);
-                       } else if (webkit_dom_node_get_next_sibling (node)) {
-                               node = webkit_dom_node_get_next_sibling (node);
-                       } else {
-                               return;
-                       }
-               }
-       }
-}
-
-WebKitDOMElement *
-e_html_editor_view_quote_plain_text_element (EHTMLEditorView *view,
-                                             WebKitDOMElement *element)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMNode *element_clone;
-       WebKitDOMNodeList *list;
-       gint ii, length, level;
-
-       document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
-
-       element_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (element), TRUE);
-       level = get_citation_level (WEBKIT_DOM_NODE (element), TRUE);
-
-       /* Remove old quote characters if the exists */
-       list = webkit_dom_element_query_selector_all (
-               WEBKIT_DOM_ELEMENT (element_clone), "span.-x-evo-quoted", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for  (ii = 0; ii < length; ii++)
-               remove_node (webkit_dom_node_list_item (list, ii));
-
-       webkit_dom_node_normalize (element_clone);
-       quote_plain_text_recursive (
-               document, element_clone, element_clone, level);
-
-       /* Set citation as quoted */
-       if (is_citation_node (element_clone))
-               element_add_class (
-                       WEBKIT_DOM_ELEMENT (element_clone),
-                       "-x-evo-plaintext-quoted");
-
-       /* Replace old element with one, that is quoted */
-       webkit_dom_node_replace_child (
-               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
-               element_clone,
-               WEBKIT_DOM_NODE (element),
-               NULL);
-
-       g_object_unref (list);
-       return WEBKIT_DOM_ELEMENT (element_clone);
-}
-
-/**
- * e_html_editor_view_quote_plain_text:
- * @view: an #EHTMLEditorView
- *
- * Quote text inside citation blockquotes in plain text mode.
- *
- * As this function is cloning and replacing all citation blockquotes keep on
- * mind that any pointers to nodes inside these blockquotes will be invalidated.
- */
-WebKitDOMElement *
-e_html_editor_view_quote_plain_text (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMHTMLElement *body;
-       WebKitDOMNode *body_clone;
-       WebKitDOMNamedNodeMap *attributes;
-       WebKitDOMNodeList *list;
-       WebKitDOMElement *element;
-       gint ii, length;
-       gulong attributes_length;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       /* Check if the document is already quoted */
-       element = webkit_dom_document_query_selector (
-               document, ".-x-evo-plaintext-quoted", NULL);
-       if (element)
-               return NULL;
-
-       body = webkit_dom_document_get_body (document);
-       body_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
-
-       /* Clean unwanted spaces before and after blockquotes */
-       list = webkit_dom_element_query_selector_all (
-               WEBKIT_DOM_ELEMENT (body_clone), "blockquote[type|=cite]", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *blockquote = webkit_dom_node_list_item (list, ii);
-               WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (blockquote);
-               WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (blockquote);
-
-               if (prev_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling))
-                       remove_node (prev_sibling);
-
-               if (next_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (next_sibling))
-                       remove_node (next_sibling);
-
-               if (webkit_dom_node_has_child_nodes (blockquote)) {
-                       WebKitDOMNode *child = webkit_dom_node_get_first_child (blockquote);
-                       if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child))
-                               remove_node (child);
-               }
-       }
-       g_object_unref (list);
-
-       webkit_dom_node_normalize (body_clone);
-       quote_plain_text_recursive (document, body_clone, body_clone, 0);
-
-       /* Copy attributes */
-       attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
-       attributes_length = webkit_dom_named_node_map_get_length (attributes);
-       for (ii = 0; ii < attributes_length; ii++) {
-               gchar *name, *value;
-               WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
-
-               name = webkit_dom_node_get_local_name (node);
-               value = webkit_dom_node_get_node_value (node);
-
-               webkit_dom_element_set_attribute (
-                       WEBKIT_DOM_ELEMENT (body_clone), name, value, NULL);
-
-               g_free (name);
-               g_free (value);
-       }
-       g_object_unref (attributes);
-
-       /* Replace old BODY with one, that is quoted */
-       webkit_dom_node_replace_child (
-               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
-               body_clone,
-               WEBKIT_DOM_NODE (body),
-               NULL);
-
-       return WEBKIT_DOM_ELEMENT (body_clone);
-}
-
-/**
- * e_html_editor_view_dequote_plain_text:
- * @view: an #EHTMLEditorView
- *
- * Dequote already quoted plain text in editor.
- * Editor have to be quoted with e_html_editor_view_quote_plain_text otherwise
- * it's not working.
- */
-void
-e_html_editor_view_dequote_plain_text (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMNodeList *paragraphs;
-       gint length, ii;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       paragraphs = webkit_dom_document_query_selector_all (
-               document, "blockquote.-x-evo-plaintext-quoted", NULL);
-       length = webkit_dom_node_list_get_length (paragraphs);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMElement *element;
-
-               element = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (paragraphs, ii));
-
-               if (is_citation_node (WEBKIT_DOM_NODE (element))) {
-                       element_remove_class (element, "-x-evo-plaintext-quoted");
-                       remove_quoting_from_element (element);
-               }
-       }
-       g_object_unref (paragraphs);
-}
-
-static gboolean
-create_anchor_for_link (const GMatchInfo *info,
-                        GString *res,
-                        gpointer data)
-{
-       gint offset = 0;
-       gchar *match;
-       gboolean address_surrounded;
-
-       match = g_match_info_fetch (info, 0);
-
-       address_surrounded =
-               strstr (match, "@") &&
-               g_str_has_prefix (match, "&lt;") &&
-               g_str_has_suffix (match, "&gt;");
-
-       if (address_surrounded)
-               offset += 4;
-
-       if (g_str_has_prefix (match, "&nbsp;"))
-               offset += 6;
-
-       if (address_surrounded)
-               g_string_append (res, "&lt;");
-
-       g_string_append (res, "<a href=\"");
-       if (strstr (match, "@")) {
-               g_string_append (res, "mailto:";);
-               g_string_append (res, match + offset);
-               if (address_surrounded)
-                       g_string_truncate (res, res->len - 4);
-
-               g_string_append (res, "\">");
-               g_string_append (res, match + offset);
-               if (address_surrounded)
-                       g_string_truncate (res, res->len - 4);
-       } else {
-               g_string_append (res, match + offset);
-               g_string_append (res, "\">");
-               g_string_append (res, match + offset);
-       }
-       g_string_append (res, "</a>");
-
-       if (address_surrounded)
-               g_string_append (res, "&gt;");
-
-       g_free (match);
-
-       return FALSE;
-}
-
-static gboolean
-replace_to_nbsp (const GMatchInfo *info,
-                 GString *res,
-                 gboolean use_nbsp)
-{
-       gchar *match;
-       const gchar *string, *previous_tab;
-       gint ii, length = 0, start = 0;
-
-       match = g_match_info_fetch (info, 0);
-       g_match_info_fetch_pos (info, 0, &start, NULL);
-       string = g_match_info_get_string (info);
-
-       if (start > 0) {
-               previous_tab = g_strrstr_len (string, start, "\x9");
-               if (previous_tab && *previous_tab) {
-                       const char *act_tab = NULL;
-                       act_tab = strstr (previous_tab + 1, "\x9");
-
-                       if (act_tab && *act_tab) {
-                               length = act_tab - previous_tab - 1;
-                               length = TAB_LENGTH - length;
-                       }
-               }
-       }
-
-       if (length == 0) {
-               if (strstr (match, "\x9")) {
-                       gint tab_count = strlen (match);
-                       length = TAB_LENGTH - (start %  TAB_LENGTH);
-                       length += (tab_count - 1) * TAB_LENGTH;
-               } else
-                       length = strlen (match);
-       }
-
-       for (ii = 0; ii < length; ii++)
-               g_string_append (res, "&nbsp;");
-
-       g_free (match);
-
-       return FALSE;
-}
-
-static gboolean
-surround_links_with_anchor (const gchar *text)
-{
-       return (strstr (text, "http") || strstr (text, "ftp") ||
-               strstr (text, "www") || strstr (text, "@"));
-}
-
-static void
-append_new_paragraph (WebKitDOMElement *parent,
-                      WebKitDOMElement **paragraph)
-{
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (parent),
-               WEBKIT_DOM_NODE (*paragraph),
-               NULL);
-
-       *paragraph = NULL;
-}
-
-static WebKitDOMElement *
-create_and_append_new_paragraph (EHTMLEditorSelection *selection,
-                                 WebKitDOMDocument *document,
-                                 WebKitDOMElement *parent,
-                                 const gchar *content)
-{
-       WebKitDOMElement *paragraph;
-
-       paragraph = e_html_editor_selection_get_paragraph_element (
-               selection, document, -1, 0);
-
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (paragraph),
-               content,
-               NULL);
-
-       append_new_paragraph (parent, &paragraph);
-
-       return paragraph;
-}
-
-static void
-append_citation_mark (WebKitDOMDocument *document,
-                      WebKitDOMElement *parent,
-                     const gchar *citation_mark_text)
-{
-       WebKitDOMText *text;
-
-       text = webkit_dom_document_create_text_node (document, citation_mark_text);
-
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (parent),
-               WEBKIT_DOM_NODE (text),
-               NULL);
-}
-
-static glong
-get_decoded_line_length (WebKitDOMDocument *document,
-                         const gchar *line_text)
-{
-       gchar *decoded_text;
-       glong length = 0;
-       WebKitDOMElement *decode;
-
-       decode = webkit_dom_document_create_element (document, "DIV", NULL);
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (decode), line_text, NULL);
-
-       decoded_text = webkit_dom_html_element_get_inner_text (
-               WEBKIT_DOM_HTML_ELEMENT (decode));
-       length = g_utf8_strlen (decoded_text, -1);
-
-       g_free (decoded_text);
-       g_object_unref (decode);
-
-       return length;
-}
-
-static gboolean
-check_if_end_paragraph (const gchar *input,
-                        glong length)
-{
-       const gchar *next_space;
-
-       next_space = strstr (input, " ");
-       if (next_space) {
-               const gchar *next_br;
-               glong length_next_word =
-                       next_space - input - 4;
-
-               if (g_str_has_prefix (input + 4, "<br>"))
-                       length_next_word = 0;
-
-               if (length_next_word > 0)
-                       next_br = strstr (input + 4, "<br>");
-
-               if (length_next_word > 0 && next_br < next_space)
-                       length_next_word = 0;
-
-               if (length_next_word + length < 72)
-                       return TRUE;
-       }
-
-       return FALSE;
-}
-
-/* This parses the HTML code (that contains just text, &nbsp; and BR elements)
- * into paragraphs.
- * HTML code in that format we can get by taking innerText from some element,
- * setting it to another one and finally getting innerHTML from it */
-static void
-parse_html_into_paragraphs (EHTMLEditorView *view,
-                            WebKitDOMDocument *document,
-                            WebKitDOMElement *blockquote,
-                            const gchar *html)
-{
-       EHTMLEditorSelection *selection;
-       gboolean ignore_next_br = FALSE;
-       gboolean first_element = TRUE;
-       gboolean citation_was_first_element = FALSE;
-       const gchar *prev_br, *next_br;
-       gchar *inner_html;
-       GRegex *regex_nbsp = NULL, *regex_links = NULL;
-       GString *start, *end;
-       WebKitDOMElement *paragraph = NULL;
-
-       selection = e_html_editor_view_get_selection (view);
-
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (blockquote), "", NULL);
-
-       prev_br = html;
-       next_br = strstr (prev_br, "<br>");
-
-       /* Replace single spaces on the beginning of line, 2+ spaces and
-        * tabulators with non breaking spaces */
-       regex_nbsp = g_regex_new ("^\\s{1}|\\s{2,}|\x9", 0, 0, NULL);
-       regex_links = g_regex_new (URL_PATTERN, 0, 0, NULL);
-
-       while (next_br) {
-               gboolean local_ignore_next_br = ignore_next_br;
-               gboolean prevent_block = TRUE;
-               const gchar *citation = NULL, *citation_end = NULL;
-               const gchar *rest = NULL, *with_br = NULL;
-               gchar *to_insert = NULL;
-
-               ignore_next_br = FALSE;
-
-               to_insert = g_utf8_substring (
-                       prev_br, 0, g_utf8_pointer_to_offset (prev_br, next_br));
-
-               with_br = strstr (to_insert, "<br>");
-               citation = strstr (to_insert, "##CITATION_");
-               if (citation) {
-                       gchar *citation_mark;
-
-                       if (strstr (citation, "END##")) {
-                               ignore_next_br = TRUE;
-                               if (paragraph)
-                                       append_new_paragraph (blockquote, &paragraph);
-                       }
-
-                       citation_end = strstr (citation + 2, "##");
-                       if (citation_end)
-                               rest = citation_end + 2;
-
-                       if (first_element)
-                               citation_was_first_element = TRUE;
-
-                       if (paragraph)
-                               append_new_paragraph (blockquote, &paragraph);
-
-                       citation_mark = g_utf8_substring (
-                               citation, 0, g_utf8_pointer_to_offset (citation, rest));
-
-                       append_citation_mark (document, blockquote, citation_mark);
-
-                       g_free (citation_mark);
-               } else
-                       rest = with_br ?
-                               to_insert + 4 + (with_br - to_insert) : to_insert;
-
-               if (!rest)
-                       goto next;
-
-               if (*rest) {
-                       gboolean empty = FALSE;
-                       gchar *truncated = g_strdup (rest);
-                       gchar *rest_to_insert;
-
-                       g_strchomp (truncated);
-                       empty = !*truncated && strlen (rest) > 0;
-
-                       if (strchr (" +- *=", *rest))
-                               prevent_block = FALSE;
-
-                       rest_to_insert = g_regex_replace_eval (
-                               regex_nbsp,
-                               empty ? rest : truncated,
-                               -1,
-                               0,
-                               0,
-                               (GRegexEvalCallback) replace_to_nbsp,
-                               NULL,
-                               NULL);
-                       g_free (truncated);
-
-                       if (surround_links_with_anchor (rest_to_insert)) {
-                               truncated = g_regex_replace_eval (
-                                       regex_links,
-                                       rest_to_insert,
-                                       -1,
-                                       0,
-                                       0,
-                                       create_anchor_for_link,
-                                       NULL,
-                                       NULL);
-
-                               g_free (rest_to_insert);
-                               rest_to_insert = truncated;
-                       }
-
-                       if (g_strcmp0 (rest_to_insert, UNICODE_ZERO_WIDTH_SPACE) == 0) {
-                               paragraph = create_and_append_new_paragraph (
-                                       selection, document, blockquote, "<br>");
-                       } else if (prevent_block) {
-                               gchar *html;
-                               gchar *new_content;
-
-                               if (!paragraph)
-                                       paragraph = e_html_editor_selection_get_paragraph_element (
-                                               selection, document, -1, 0);
-
-                               html = webkit_dom_html_element_get_inner_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (paragraph));
-
-                               new_content = g_strconcat (
-                                       html && *html ? html : "",
-                                       html && *html ? " " : "",
-                                       rest_to_insert ? rest_to_insert : "<br>",
-                                       NULL),
-
-                               webkit_dom_html_element_set_inner_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (paragraph),
-                                       new_content,
-                                       NULL);
-
-                               g_free (html);
-                               g_free (new_content);
-                       } else
-                               paragraph = create_and_append_new_paragraph (
-                                       selection, document, blockquote, rest_to_insert);
-
-                       if (rest_to_insert && *rest_to_insert && prevent_block && paragraph) {
-                               glong length = 0;
-
-                               if (strstr (rest, "&"))
-                                       length = get_decoded_line_length (document, rest);
-                               else
-                                       length = g_utf8_strlen (rest, -1);
-
-                               /* End the block if there is line with less that 62 characters. */
-                               /* The shorter line can also mean that there is a long word on next
-                                * line (and the line was wrapped). So look at it and decide what to do. */
-                               if (length < 62 && check_if_end_paragraph (next_br, length))
-                                       append_new_paragraph (blockquote, &paragraph);
-
-                               if (length > 72)
-                                       append_new_paragraph (blockquote, &paragraph);
-                       }
-
-                       citation_was_first_element = FALSE;
-
-                       g_free (rest_to_insert);
-               } else if (with_br) {
-                       if (!citation && (!local_ignore_next_br || citation_was_first_element)) {
-                               if (paragraph)
-                                       append_new_paragraph (blockquote, &paragraph);
-
-                               paragraph = create_and_append_new_paragraph (
-                                       selection, document, blockquote, "<br>");
-
-                               citation_was_first_element = FALSE;
-                       } else if (first_element && !citation_was_first_element) {
-                               paragraph = create_and_append_new_paragraph (
-                                       selection,
-                                       document,
-                                       blockquote,
-                                       "<br class=\"-x-evo-first-br\">");
-                       }
-               }
- next:
-               first_element = FALSE;
-               prev_br = next_br;
-               next_br = strstr (prev_br + 4, "<br>");
-               g_free (to_insert);
-       }
-
-       if (paragraph)
-               append_new_paragraph (blockquote, &paragraph);
-
-       if (g_utf8_strlen (prev_br, -1) > 0) {
-               gchar *rest_to_insert;
-               gchar *truncated = g_strdup (
-                       g_str_has_prefix (prev_br, "<br>") ? prev_br + 4 : prev_br);
-
-               /* On the end on the HTML there is always an extra BR element,
-                * so skip it and if there was another BR element before it mark it. */
-               if (truncated && !*truncated) {
-                       WebKitDOMNode *child;
-
-                       child = webkit_dom_node_get_last_child (
-                               WEBKIT_DOM_NODE (blockquote));
-                       if (child) {
-                               child = webkit_dom_node_get_first_child (child);
-                               if (child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (child)) {
-                                       element_add_class (
-                                               WEBKIT_DOM_ELEMENT (child),
-                                               "-x-evo-last-br");
-                               }
-                       }
-                       g_free (truncated);
-                       goto end;
-               }
-
-               if (g_ascii_strncasecmp (truncated, "##CITATION_END##", 16) == 0) {
-                       append_citation_mark (document, blockquote, truncated);
-                       g_free (truncated);
-                       goto end;
-               }
-
-               g_strchomp (truncated);
-
-               rest_to_insert = g_regex_replace_eval (
-                       regex_nbsp,
-                       truncated,
-                       -1,
-                       0,
-                       0,
-                       (GRegexEvalCallback) replace_to_nbsp,
-                       NULL,
-                       NULL);
-               g_free (truncated);
-
-               if (surround_links_with_anchor (rest_to_insert)) {
-                       truncated = g_regex_replace_eval (
-                               regex_links,
-                               rest_to_insert,
-                               -1,
-                               0,
-                               0,
-                               create_anchor_for_link,
-                               NULL,
-                               NULL);
-
-                       g_free (rest_to_insert);
-                       rest_to_insert = truncated;
-               }
-
-               if (g_strcmp0 (rest_to_insert, UNICODE_ZERO_WIDTH_SPACE) == 0)
-                       create_and_append_new_paragraph (
-                               selection, document, blockquote, "<br>");
-               else
-                       create_and_append_new_paragraph (
-                               selection, document, blockquote, rest_to_insert);
-
-               g_free (rest_to_insert);
-       }
-
- end:
-       /* Replace text markers with actual HTML blockquotes */
-       inner_html = webkit_dom_html_element_get_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (blockquote));
-       start = e_str_replace_string (
-               inner_html, "##CITATION_START##","<blockquote type=\"cite\">");
-       end = e_str_replace_string (
-               start->str, "##CITATION_END##", "</blockquote>");
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (blockquote), end->str, NULL);
-
-       g_regex_unref (regex_nbsp);
-       g_regex_unref (regex_links);
-       g_free (inner_html);
-       g_string_free (start, TRUE);
-       g_string_free (end, TRUE);
-}
-
-static void
-mark_citation (WebKitDOMElement *citation)
-{
-       gchar *inner_html, *surrounded;
-
-       inner_html = webkit_dom_html_element_get_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (citation));
-
-       surrounded = g_strconcat (
-               "<span>##CITATION_START##</span>", inner_html,
-               "<span>##CITATION_END##</span>", NULL);
-
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (citation), surrounded, NULL);
-
-       element_add_class (citation, "marked");
-
-       g_free (inner_html);
-       g_free (surrounded);
-}
-
-static gint
-create_text_markers_for_citations_in_document (WebKitDOMDocument *document)
-{
-       gint count = 0;
-       WebKitDOMElement *citation;
-
-       citation = webkit_dom_document_query_selector (
-               document, "blockquote[type=cite]:not(.marked)", NULL);
-
-       while (citation) {
-               mark_citation (citation);
-               count ++;
-
-               citation = webkit_dom_document_query_selector (
-                       document, "blockquote[type=cite]:not(.marked)", NULL);
-       }
-
-       return count;
-}
-
-static gint
-create_text_markers_for_citations_in_element (WebKitDOMElement *element)
-{
-       gint count = 0;
-       WebKitDOMElement *citation;
-
-       citation = webkit_dom_element_query_selector (
-               element, "blockquote[type=cite]:not(.marked)", NULL);
-
-       while (citation) {
-               mark_citation (citation);
-               count ++;
-
-               citation = webkit_dom_element_query_selector (
-                       element, "blockquote[type=cite]:not(.marked)", NULL);
-       }
-
-       return count;
-}
-
-static void
-quote_plain_text_elements_after_wrapping_in_document (WebKitDOMDocument *document)
-{
-       gint length, ii;
-       WebKitDOMNodeList *list;
-
-       list = webkit_dom_document_query_selector_all (
-               document, "blockquote[type=cite] > div.-x-evo-paragraph", NULL);
-
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++) {
-               gint citation_level;
-               WebKitDOMNode *child;
-
-               child = webkit_dom_node_list_item (list, ii);
-               citation_level = get_citation_level (child, TRUE);
-               quote_plain_text_element_after_wrapping (
-                       document, WEBKIT_DOM_ELEMENT (child), citation_level);
-       }
-       g_object_unref (list);
-}
-
-static void
-html_editor_convert_view_content (EHTMLEditorView *view,
-                                  const gchar *preferred_text)
-{
-       EHTMLEditorSelection *selection = e_html_editor_view_get_selection (view);
-       gboolean start_bottom, empty = FALSE;
-       gchar *inner_html;
-       gint ii, length;
-       GSettings *settings;
-       WebKitDOMDocument *document;
-       WebKitDOMElement *paragraph, *content_wrapper, *top_signature;
-       WebKitDOMElement *cite_body, *signature, *wrapper;
-       WebKitDOMHTMLElement *body;
-       WebKitDOMNodeList *list;
-       WebKitDOMNode *node;
-
-       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-       start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom");
-       g_object_unref (settings);
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       body = webkit_dom_document_get_body (document);
-       /* Wrapper that will represent the new body. */
-       wrapper = webkit_dom_document_create_element (document, "div", NULL);
-
-       webkit_dom_element_set_attribute (
-               WEBKIT_DOM_ELEMENT (body), "data-converted", "", NULL);
-
-       cite_body = webkit_dom_document_query_selector (
-               document, "span.-x-evo-cite-body", NULL);
-
-       /* content_wrapper when the processed text will be placed. */
-       content_wrapper = webkit_dom_document_create_element (
-               document, cite_body ? "blockquote" : "div", NULL);
-       if (cite_body) {
-               webkit_dom_element_set_attribute (content_wrapper, "type", "cite", NULL);
-               webkit_dom_element_set_attribute (content_wrapper, "id", "-x-evo-main-cite", NULL);
-       }
-
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (wrapper), WEBKIT_DOM_NODE (content_wrapper), NULL);
-
-       /* Remove all previously inserted paragraphs. */
-       list = webkit_dom_document_query_selector_all (
-               document, ".-x-evo-paragraph", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++)
-               remove_node (webkit_dom_node_list_item (list, ii));
-       g_object_unref (list);
-
-       /* Insert the paragraph where the caret will be. */
-       paragraph = prepare_paragraph (selection, document, TRUE);
-       webkit_dom_element_set_id (paragraph, "-x-evo-input-start");
-       webkit_dom_node_insert_before (
-               WEBKIT_DOM_NODE (wrapper),
-               WEBKIT_DOM_NODE (paragraph),
-               start_bottom ?
-                       webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (content_wrapper)) :
-                       WEBKIT_DOM_NODE (content_wrapper),
-               NULL);
-
-       /* Insert signature (if presented) to the right position. */
-       top_signature = webkit_dom_document_query_selector (
-               document, ".-x-evo-top-signature", NULL);
-       signature = webkit_dom_document_query_selector (
-               document, ".-x-evo-signature-content_wrapper", NULL);
-       if (signature) {
-               if (top_signature) {
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (wrapper),
-                               WEBKIT_DOM_NODE (signature),
-                               start_bottom ?
-                                       WEBKIT_DOM_NODE (content_wrapper) :
-                                       webkit_dom_node_get_next_sibling (
-                                               WEBKIT_DOM_NODE (paragraph)),
-                               NULL);
-                       /* Insert NL after the signature */
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (wrapper),
-                               WEBKIT_DOM_NODE (prepare_paragraph (
-                                       selection, document, FALSE)),
-                               webkit_dom_node_get_next_sibling (
-                                       WEBKIT_DOM_NODE (signature)),
-                               NULL);
-               } else {
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (wrapper),
-                               WEBKIT_DOM_NODE (signature),
-                               webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (
-                                       start_bottom ? paragraph : content_wrapper)),
-                               NULL);
-               }
-       }
-
-       /* Move credits to the body */
-       list = webkit_dom_document_query_selector_all (
-               document, "span.-x-evo-to-body[data-credits]", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *node, *child;
-
-               node = webkit_dom_node_list_item (list, ii);
-               while ((child = webkit_dom_node_get_first_child (node))) {
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (wrapper),
-                               child,
-                               WEBKIT_DOM_NODE (content_wrapper),
-                               NULL);
-               }
-
-               remove_node (node);
-       }
-       g_object_unref (list);
-
-       /* Move headers to body */
-       list = webkit_dom_document_query_selector_all (
-               document, "span.-x-evo-to-body[data-headers]", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *node, *child;
-
-               node = webkit_dom_node_list_item (list, ii);
-               while ((child = webkit_dom_node_get_first_child (node))) {
-                       webkit_dom_node_insert_before (
-                               WEBKIT_DOM_NODE (wrapper),
-                               child,
-                               WEBKIT_DOM_NODE (content_wrapper),
-                               NULL);
-               }
-
-               remove_node (node);
-       }
-       g_object_unref (list);
-
-       repair_gmail_blockquotes (document);
-       create_text_markers_for_citations_in_document (document);
-
-       if (preferred_text && *preferred_text)
-               webkit_dom_html_element_set_inner_text (
-                       WEBKIT_DOM_HTML_ELEMENT (content_wrapper), preferred_text, NULL);
-       else {
-               gchar *inner_text;
-
-               inner_text = webkit_dom_html_element_get_inner_text (body);
-               webkit_dom_html_element_set_inner_text (
-                       WEBKIT_DOM_HTML_ELEMENT (content_wrapper), inner_text, NULL);
-
-               g_free (inner_text);
-       }
-
-       inner_html = webkit_dom_html_element_get_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (content_wrapper));
-
-       /* Replace the old body with the new one. */
-       node = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), FALSE);
-       webkit_dom_node_replace_child (
-               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
-               node,
-               WEBKIT_DOM_NODE (body),
-               NULL);
-       body = WEBKIT_DOM_HTML_ELEMENT (node);
-
-       /* Copy all to nodes to the new body. */
-       while ((node = webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (wrapper)))) {
-               webkit_dom_node_insert_before (
-                       WEBKIT_DOM_NODE (body),
-                       WEBKIT_DOM_NODE (node),
-                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
-                       NULL);
-       }
-       remove_node (WEBKIT_DOM_NODE (wrapper));
-
-       /* FIXME XXX */
-       length = webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (body));
-       if (length <= 1) {
-               empty = TRUE;
-               if (length == 1) {
-                       WebKitDOMNode *child;
-
-                       child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
-                       empty = child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (child);
-               }
-       }
-
-       if (preferred_text && *preferred_text)
-               empty = FALSE;
-
-       if (!empty)
-               parse_html_into_paragraphs (view, document, content_wrapper, inner_html);
-
-       if (!cite_body) {
-               if (!empty) {
-                       WebKitDOMNode *child;
-
-                       while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (content_wrapper)))) 
{
-                               webkit_dom_node_insert_before (
-                                       webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (content_wrapper)),
-                                       child,
-                                       WEBKIT_DOM_NODE (content_wrapper),
-                                       NULL);
-                       }
-               }
-
-               remove_node (WEBKIT_DOM_NODE (content_wrapper));
-       }
-
-       if (view->priv->is_message_from_edit_as_new || view->priv->remove_initial_input_line) {
-               WebKitDOMNode *child;
-
-               remove_node (WEBKIT_DOM_NODE (paragraph));
-               child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
-               if (child)
-                       add_selection_markers_into_element_start (
-                               document, WEBKIT_DOM_ELEMENT (child), NULL, NULL);
-       }
-
-       paragraph = webkit_dom_document_query_selector (document, "br.-x-evo-last-br", NULL);
-       if (paragraph)
-               webkit_dom_element_remove_attribute (paragraph, "class");
-       paragraph = webkit_dom_document_query_selector (document, "br.-x-evo-first-br", NULL);
-       if (paragraph)
-               webkit_dom_element_remove_attribute (paragraph, "class");
-
-       if (!e_html_editor_view_get_html_mode (view)) {
-               e_html_editor_selection_wrap_paragraphs_in_document (
-                       selection, document);
-
-               quote_plain_text_elements_after_wrapping_in_document (document);
-       }
-
-       e_html_editor_selection_restore (selection);
-       e_html_editor_view_force_spell_check (view);
-
-       /* Register on input event that is called when the content (body) is modified */
-       webkit_dom_event_target_add_event_listener (
-               WEBKIT_DOM_EVENT_TARGET (body),
-               "input",
-               G_CALLBACK (body_input_event_cb),
-               FALSE,
-               view);
-
-       g_free (inner_html);
-}
-
-static void
-fix_structure_after_pasting_multiline_content (WebKitDOMNode *node)
-{
-       WebKitDOMNode *first_child, *parent;
-
-       /* When pasting content that does not contain just the
-        * one line text WebKit inserts all the content after the
-        * first line into one element. So we have to take it out
-        * of this element and insert it after that element. */
-       parent = webkit_dom_node_get_parent_node (node);
-       if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent))
-               return;
-       first_child = webkit_dom_node_get_first_child (parent);
-       while (first_child) {
-               WebKitDOMNode *next_child =
-                       webkit_dom_node_get_next_sibling  (first_child);
-               if (webkit_dom_node_has_child_nodes (first_child))
-                       webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (parent),
-                               first_child,
-                               parent,
-                               NULL);
-               first_child = next_child;
-       }
-       remove_node (parent);
-}
-
-static void
-html_editor_view_insert_converted_html_into_selection (EHTMLEditorView *view,
-                                                       gboolean is_html,
-                                                       const gchar *html)
-{
-       EHTMLEditorSelection *selection = e_html_editor_view_get_selection (view);
-       gboolean has_selection;
-       gchar *inner_html;
-       gint citation_level;
-       WebKitDOMDocument *document;
-       WebKitDOMElement *element;
-       WebKitDOMNode *node;
-       WebKitDOMRange *range;
-
-       remove_input_event_listener_from_body (view);
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       element = webkit_dom_document_create_element (document, "div", NULL);
-       if (is_html) {
-               gchar *inner_text;
-
-               webkit_dom_html_element_set_inner_html (
-                       WEBKIT_DOM_HTML_ELEMENT (element), html, NULL);
-               inner_text = webkit_dom_html_element_get_inner_text (
-                       WEBKIT_DOM_HTML_ELEMENT (element));
-               webkit_dom_html_element_set_inner_text (
-                       WEBKIT_DOM_HTML_ELEMENT (element), inner_text, NULL);
-
-               g_free (inner_text);
-       } else
-               webkit_dom_html_element_set_inner_text (
-                       WEBKIT_DOM_HTML_ELEMENT (element), html, NULL);
-
-       inner_html = webkit_dom_html_element_get_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (element));
-       parse_html_into_paragraphs (view, document, element, inner_html);
-
-       g_free (inner_html);
-
-       has_selection = !e_html_editor_selection_is_collapsed (selection);
-
-       range = html_editor_view_get_dom_range (view);
-       node = webkit_dom_range_get_end_container (range, NULL);
-       citation_level = get_citation_level (node, FALSE);
-       /* Pasting into the citation */
-       if (citation_level > 0) {
-               gint length;
-               gint word_wrap_length = e_html_editor_selection_get_word_wrap_length (selection);
-               WebKitDOMElement *selection_start_marker, *selection_end_marker;
-               WebKitDOMElement *br;
-               WebKitDOMNode *first_paragraph, *last_paragraph;
-               WebKitDOMNode *child, *parent;
-
-               e_html_editor_selection_save (selection);
-               selection_start_marker = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-selection-start-marker");
-               selection_end_marker = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-selection-end-marker");
-
-               first_paragraph = webkit_dom_node_get_first_child (
-                       WEBKIT_DOM_NODE (element));
-               last_paragraph = webkit_dom_node_get_last_child (
-                       WEBKIT_DOM_NODE (element));
-
-               length = word_wrap_length - 2 * citation_level;
-
-               /* Pasting text that was parsed just into one paragraph */
-               if (webkit_dom_node_is_same_node (first_paragraph, last_paragraph)) {
-                       WebKitDOMNode *child, *parent;
-
-                       parent = get_parent_block_node_from_child (
-                               WEBKIT_DOM_NODE (selection_start_marker));
-
-                       remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
-                       remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
-
-                       while ((child = webkit_dom_node_get_first_child (first_paragraph)))
-                               webkit_dom_node_insert_before (
-                                       parent,
-                                       child,
-                                       WEBKIT_DOM_NODE (selection_start_marker),
-                                       NULL);
-
-                       parent = WEBKIT_DOM_NODE (
-                               e_html_editor_selection_wrap_paragraph_length (
-                                       selection, WEBKIT_DOM_ELEMENT (parent), length));
-                       webkit_dom_node_normalize (parent);
-                       quote_plain_text_element_after_wrapping (
-                               document, WEBKIT_DOM_ELEMENT (parent), citation_level);
-
-                       goto delete;
-               }
-
-               /* Pasting content parsed into the multiple paragraphs */
-               parent = get_parent_block_node_from_child (
-                       WEBKIT_DOM_NODE (selection_start_marker));
-
-               remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
-               remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
-
-               /* Move the elements from the first paragraph before the selection start element */
-               while ((child = webkit_dom_node_get_first_child (first_paragraph)))
-                       webkit_dom_node_insert_before (
-                               parent,
-                               child,
-                               WEBKIT_DOM_NODE (selection_start_marker),
-                               NULL);
-
-               remove_node (first_paragraph);
-
-               /* If the BR element is on the last position, remove it as we don't need it */
-               child = webkit_dom_node_get_last_child (parent);
-               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child))
-                       remove_node (child);
-
-               parent = get_parent_block_node_from_child (
-                       WEBKIT_DOM_NODE (selection_end_marker)),
-
-               child = webkit_dom_node_get_next_sibling (
-                       WEBKIT_DOM_NODE (selection_end_marker));
-               /* Move the elements that are in the same paragraph as the selection end
-                * on the end of pasted text, but avoid BR on the end of paragraph */
-               while (child) {
-                       WebKitDOMNode *next_child =
-                               webkit_dom_node_get_next_sibling  (child);
-                       if (!(!next_child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (child)))
-                               webkit_dom_node_append_child (last_paragraph, child, NULL);
-                       child = next_child;
-               }
-
-               /* Caret will be restored on the end of pasted text */
-               webkit_dom_node_append_child (
-                       last_paragraph,
-                       e_html_editor_selection_get_caret_position_node (document),
-                       NULL);
-
-               /* Insert the paragraph with the end of the pasted text after
-                * the paragraph that contains the selection end */
-               webkit_dom_node_insert_before (
-                       webkit_dom_node_get_parent_node (parent),
-                       last_paragraph,
-                       webkit_dom_node_get_next_sibling (parent),
-                       NULL);
-
-               /* Wrap, quote and move all paragraphs from pasted text into the body */
-               while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)))) {
-                       child = WEBKIT_DOM_NODE (e_html_editor_selection_wrap_paragraph_length (
-                               selection, WEBKIT_DOM_ELEMENT (child), length));
-                       quote_plain_text_element_after_wrapping (
-                               document, WEBKIT_DOM_ELEMENT (child), citation_level);
-                       webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (last_paragraph),
-                               child,
-                               last_paragraph,
-                               NULL);
-               }
-
-               webkit_dom_node_normalize (last_paragraph);
-
-               last_paragraph = WEBKIT_DOM_NODE (
-                       e_html_editor_selection_wrap_paragraph_length (
-                               selection, WEBKIT_DOM_ELEMENT (last_paragraph), length));
-               quote_plain_text_element_after_wrapping (
-                       document, WEBKIT_DOM_ELEMENT (last_paragraph), citation_level);
-
-               remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
-               remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
-
-               parent = get_parent_block_node_from_child (
-                       WEBKIT_DOM_NODE (selection_start_marker));
-               parent = WEBKIT_DOM_NODE (e_html_editor_selection_wrap_paragraph_length (
-                       selection, WEBKIT_DOM_ELEMENT (parent), length));
-               quote_plain_text_element_after_wrapping (
-                       document, WEBKIT_DOM_ELEMENT (parent), citation_level);
-
-               /* If the pasted text begun or ended with a new line we have to
-                * quote these paragraphs as well */
-               br = webkit_dom_element_query_selector (
-                       WEBKIT_DOM_ELEMENT (last_paragraph), "br.-x-evo-last-br", NULL);
-               if (br) {
-                       WebKitDOMNode *parent;
-
-                       parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (br));
-                       quote_plain_text_recursive (document, parent, parent, citation_level);
-                       webkit_dom_element_remove_attribute (br, "class");
-               }
-
-               br = webkit_dom_document_query_selector (
-                       document, "* > br.-x-evo-first-br", NULL);
-               if (br) {
-                       WebKitDOMNode *parent;
-
-                       parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (br));
-                       quote_plain_text_recursive (document, parent, parent, citation_level);
-                       webkit_dom_element_remove_attribute (br, "class");
-               }
- delete:
-               e_html_editor_selection_restore (selection);
-               /* Remove the text that was meant to be replaced by the pasted text */
-               if (has_selection)
-                       e_html_editor_view_exec_command (
-                               view, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
-
-               e_html_editor_selection_restore_caret_position (selection);
-               goto out;
-       }
-
-       inner_html = webkit_dom_html_element_get_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (element));
-       e_html_editor_view_exec_command (
-               view, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, inner_html);
-       g_free (inner_html);
-
-       e_html_editor_selection_save (selection);
-
-       element = webkit_dom_document_query_selector (
-               document, "* > br.-x-evo-first-br", NULL);
-       if (element) {
-               WebKitDOMNode *next_sibling;
-               WebKitDOMNode *parent;
-
-               parent = webkit_dom_node_get_parent_node (
-                       WEBKIT_DOM_NODE (element));
-
-               next_sibling = webkit_dom_node_get_next_sibling (parent);
-               if (next_sibling)
-                       remove_node (WEBKIT_DOM_NODE (parent));
-               else
-                       webkit_dom_element_remove_attribute (element, "class");
-       }
-
-       element = webkit_dom_document_query_selector (
-               document, "* > br.-x-evo-last-br", NULL);
-       if (element) {
-               WebKitDOMNode *parent;
-               WebKitDOMNode *child;
-               WebKitDOMElement *selection_marker;
-
-               parent = webkit_dom_node_get_parent_node (
-                       WEBKIT_DOM_NODE (element));
-
-               node = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent));
-               if (node) {
-                       node = webkit_dom_node_get_first_child (node);
-                       if (node) {
-                               inner_html = webkit_dom_node_get_text_content (node);
-                               if (g_str_has_prefix (inner_html, UNICODE_NBSP))
-                                       webkit_dom_character_data_replace_data (
-                                               WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
-                               g_free (inner_html);
-                       }
-               }
-
-               selection_marker = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-selection-end-marker");
-
-               if (has_selection) {
-                       /* Everything after the selection end marker have to be in separate
-                        * paragraph */
-                       child = webkit_dom_node_get_next_sibling (
-                               WEBKIT_DOM_NODE (selection_marker));
-                       /* Move the elements that are in the same paragraph as the selection end
-                        * on the end of pasted text, but avoid BR on the end of paragraph */
-                       while (child) {
-                               WebKitDOMNode *next_child =
-                                       webkit_dom_node_get_next_sibling  (child);
-                               if (!(!next_child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (child)))
-                                       webkit_dom_node_append_child (parent, child, NULL);
-                               child = next_child;
-                       }
-
-                       remove_node (WEBKIT_DOM_NODE (element));
-
-                       webkit_dom_node_insert_before (
-                               webkit_dom_node_get_parent_node (
-                                       webkit_dom_node_get_parent_node (
-                                               WEBKIT_DOM_NODE (selection_marker))),
-                               parent,
-                               webkit_dom_node_get_next_sibling (
-                                       webkit_dom_node_get_parent_node (
-                                               WEBKIT_DOM_NODE (selection_marker))),
-                               NULL);
-                       node = parent;
-               } else {
-                       node = webkit_dom_node_get_next_sibling (parent);
-                       if (!node)
-                               fix_structure_after_pasting_multiline_content (parent);
-               }
-
-               if (node) {
-                       /* Restore caret on the end of pasted text */
-                       webkit_dom_node_insert_before (
-                               node,
-                               WEBKIT_DOM_NODE (selection_marker),
-                               webkit_dom_node_get_first_child (node),
-                               NULL);
-
-                       selection_marker = webkit_dom_document_get_element_by_id (
-                               document, "-x-evo-selection-start-marker");
-                       webkit_dom_node_insert_before (
-                               node,
-                               WEBKIT_DOM_NODE (selection_marker),
-                               webkit_dom_node_get_first_child (node),
-                               NULL);
-               }
-
-               if (element)
-                       webkit_dom_element_remove_attribute (element, "class");
-
-               if (webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent)) && !has_selection)
-                       remove_node (parent);
-       } else {
-               /* When pasting the content that was copied from the composer, WebKit
-                * restores the selection wrongly, thus is saved wrongly and we have
-                * to fix it */
-               WebKitDOMElement *selection_start_marker, *selection_end_marker;
-               WebKitDOMNode *paragraph, *parent;
-
-               selection_start_marker = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-selection-start-marker");
-               selection_end_marker = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-selection-end-marker");
-
-               paragraph = get_parent_block_node_from_child (
-                       WEBKIT_DOM_NODE (selection_start_marker));
-               parent = webkit_dom_node_get_parent_node (paragraph);
-               if (element_has_class (WEBKIT_DOM_ELEMENT (paragraph), "-x-evo-paragraph") &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph"))
-                       fix_structure_after_pasting_multiline_content (paragraph);
-
-               webkit_dom_node_insert_before (
-                       webkit_dom_node_get_parent_node (
-                               WEBKIT_DOM_NODE (selection_start_marker)),
-                       WEBKIT_DOM_NODE (selection_end_marker),
-                       webkit_dom_node_get_next_sibling (
-                               WEBKIT_DOM_NODE (selection_start_marker)),
-                       NULL);
-       }
-
-       e_html_editor_selection_restore (selection);
- out:
-       e_html_editor_view_force_spell_check (view);
-       e_html_editor_selection_scroll_to_caret (selection);
-
-       register_input_event_listener_on_body (view);
-}
-
-static void
 initialize_web_extensions_cb (WebKitWebContext *web_context)
 {
        /* Set the web extensions dir before the process is launched */
@@ -5413,1466 +2313,6 @@ e_html_editor_view_get_html_mode (EHTMLEditorView *view)
        return view->priv->html_mode;
 }
 
-static gint
-get_indentation_level (WebKitDOMElement *element)
-{
-       WebKitDOMElement *parent;
-       gint level = 1;
-
-       parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (element));
-       /* Count level of indentation */
-       while (!WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
-               if (element_has_class (parent, "-x-evo-indented"))
-                       level++;
-
-               parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (parent));
-       }
-
-       return level;
-}
-
-static void
-process_blockquote (WebKitDOMElement *blockquote)
-{
-       WebKitDOMNodeList *list;
-       int jj, length;
-
-       /* First replace wrappers */
-       list = webkit_dom_element_query_selector_all (
-               blockquote, "span.-x-evo-temp-text-wrapper", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for (jj = 0; jj < length; jj++) {
-               WebKitDOMNode *quoted_node;
-               gchar *text_content;
-
-               quoted_node = webkit_dom_node_list_item (list, jj);
-               text_content = webkit_dom_node_get_text_content (quoted_node);
-               webkit_dom_html_element_set_outer_html (
-                       WEBKIT_DOM_HTML_ELEMENT (quoted_node), text_content, NULL);
-
-               g_free (text_content);
-       }
-       g_object_unref (list);
-
-       /* Afterwards replace quote nodes with symbols */
-       list = webkit_dom_element_query_selector_all (
-               blockquote, "span.-x-evo-quoted", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for (jj = 0; jj < length; jj++) {
-               WebKitDOMNode *quoted_node;
-               gchar *text_content;
-
-               quoted_node = webkit_dom_node_list_item (list, jj);
-               text_content = webkit_dom_node_get_text_content (quoted_node);
-               webkit_dom_html_element_set_outer_html (
-                       WEBKIT_DOM_HTML_ELEMENT (quoted_node), text_content, NULL);
-
-               g_free (text_content);
-       }
-       g_object_unref (list);
-
-       if (element_has_class (blockquote, "-x-evo-indented")) {
-               WebKitDOMNode *child;
-               gchar *spaces;
-
-               spaces = g_strnfill (4 * get_indentation_level (blockquote), ' ');
-
-               child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (blockquote));
-               while (child) {
-                       /* If next sibling is indented blockqoute skip it,
-                        * it will be processed afterwards */
-                       if (WEBKIT_DOM_IS_ELEMENT (child) &&
-                           element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-indented"))
-                               child = webkit_dom_node_get_next_sibling (child);
-
-                       if (WEBKIT_DOM_IS_TEXT (child)) {
-                               gchar *text_content;
-                               gchar *indented_text;
-
-                               text_content = webkit_dom_text_get_whole_text (WEBKIT_DOM_TEXT (child));
-                               indented_text = g_strconcat (spaces, text_content, NULL);
-
-                               webkit_dom_text_replace_whole_text (
-                                       WEBKIT_DOM_TEXT (child),
-                                       indented_text,
-                                       NULL);
-
-                               g_free (text_content);
-                               g_free (indented_text);
-                       }
-
-                       if (!child)
-                               break;
-
-                       /* Move to next node */
-                       if (webkit_dom_node_has_child_nodes (child))
-                               child = webkit_dom_node_get_first_child (child);
-                       else if (webkit_dom_node_get_next_sibling (child))
-                               child = webkit_dom_node_get_next_sibling (child);
-                       else {
-                               if (webkit_dom_node_is_equal_node (WEBKIT_DOM_NODE (blockquote), child))
-                                       break;
-
-                               child = webkit_dom_node_get_parent_node (child);
-                               if (child)
-                                       child = webkit_dom_node_get_next_sibling (child);
-                       }
-               }
-               g_free (spaces);
-
-               webkit_dom_element_remove_attribute (blockquote, "style");
-       }
-}
-
-/* Taken from GtkHTML */
-static gchar *
-get_alpha_value (gint value,
-                 gboolean lower)
-{
-       GString *str;
-       gchar *rv;
-       gint add = lower ? 'a' : 'A';
-
-       str = g_string_new (". ");
-
-       do {
-               g_string_prepend_c (str, ((value - 1) % 26) + add);
-               value = (value - 1) / 26;
-       } while (value);
-
-       rv = str->str;
-       g_string_free (str, FALSE);
-
-       return rv;
-}
-
-/* Taken from GtkHTML */
-static gchar *
-get_roman_value (gint value,
-                 gboolean lower)
-{
-       GString *str;
-       const gchar *base = "IVXLCDM";
-       gchar *rv;
-       gint b, r, add = lower ? 'a' - 'A' : 0;
-
-       if (value > 3999)
-               return g_strdup ("?. ");
-
-       str = g_string_new (". ");
-
-       for (b = 0; value > 0 && b < 7 - 1; b += 2, value /= 10) {
-               r = value % 10;
-               if (r != 0) {
-                       if (r < 4) {
-                               for (; r; r--)
-                                       g_string_prepend_c (str, base[b] + add);
-                       } else if (r == 4) {
-                               g_string_prepend_c (str, base[b + 1] + add);
-                               g_string_prepend_c (str, base[b] + add);
-                       } else if (r == 5) {
-                               g_string_prepend_c (str, base[b + 1] + add);
-                       } else if (r < 9) {
-                               for (; r > 5; r--)
-                                       g_string_prepend_c (str, base[b] + add);
-                               g_string_prepend_c (str, base[b + 1] + add);
-                       } else if (r == 9) {
-                               g_string_prepend_c (str, base[b + 2] + add);
-                               g_string_prepend_c (str, base[b] + add);
-                       }
-               }
-       }
-
-       rv = str->str;
-       g_string_free (str, FALSE);
-
-       return rv;
-}
-
-static void
-process_list_to_plain_text (EHTMLEditorView *view,
-                            WebKitDOMElement *element,
-                            gint level,
-                            GString *output)
-{
-       EHTMLEditorSelectionBlockFormat format;
-       EHTMLEditorSelectionAlignment alignment;
-       gint counter = 1;
-       gchar *indent_per_level = g_strnfill (SPACES_PER_LIST_LEVEL, ' ');
-       WebKitDOMNode *item;
-       gint word_wrap_length = e_html_editor_selection_get_word_wrap_length (
-               e_html_editor_view_get_selection (view));
-
-       format = e_html_editor_selection_get_list_format_from_node (
-               WEBKIT_DOM_NODE (element));
-
-       /* Process list items to plain text */
-       item = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element));
-       while (item) {
-               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (item))
-                       g_string_append (output, "\n");
-
-               if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (item)) {
-                       gchar *space, *item_str = NULL;
-                       gint ii = 0;
-                       WebKitDOMElement *wrapped;
-                       GString *item_value = g_string_new ("");
-
-                       alignment = e_html_editor_selection_get_list_alignment_from_node (
-                               WEBKIT_DOM_NODE (item));
-
-                       wrapped = webkit_dom_element_query_selector (
-                               WEBKIT_DOM_ELEMENT (item), ".-x-evo-wrap-br", NULL);
-                       /* Wrapped text */
-                       if (wrapped) {
-                               WebKitDOMNode *node = webkit_dom_node_get_first_child (item);
-                               GString *line = g_string_new ("");
-                               while (node) {
-                                       if (WEBKIT_DOM_IS_TEXT (node)) {
-                                               /* append text from line */
-                                               gchar *text_content;
-                                               text_content = webkit_dom_node_get_text_content (node);
-                                               g_string_append (line, text_content);
-                                               g_free (text_content);
-                                       }
-                                       if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (node) &&
-                                           element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-wrap-br")) {
-                                               g_string_append (line, "\n");
-                                               /* put spaces before line characters -> wordwraplength - 
indentation */
-                                               for (ii = 0; ii < level; ii++)
-                                                       g_string_append (line, indent_per_level);
-                                               g_string_append (item_value, line->str);
-                                               g_string_erase (line, 0, -1);
-                                       }
-                                       node = webkit_dom_node_get_next_sibling (node);
-                               }
-
-                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT)
-                                       g_string_append (item_value, line->str);
-
-                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
-                                       gchar *fill = NULL;
-                                       gint fill_length;
-
-                                       fill_length = word_wrap_length - g_utf8_strlen (line->str, -1);
-                                       fill_length -= ii * SPACES_PER_LIST_LEVEL;
-                                       fill_length /= 2;
-
-                                       if (fill_length < 0)
-                                               fill_length = 0;
-
-                                       fill = g_strnfill (fill_length, ' ');
-
-                                       g_string_append (item_value, fill);
-                                       g_string_append (item_value, line->str);
-                                       g_free (fill);
-                               }
-
-                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
-                                       gchar *fill = NULL;
-                                       gint fill_length;
-
-                                       fill_length = word_wrap_length - g_utf8_strlen (line->str, -1);
-                                       fill_length -= ii * SPACES_PER_LIST_LEVEL;
-
-                                       if (fill_length < 0)
-                                               fill_length = 0;
-
-                                       fill = g_strnfill (fill_length, ' ');
-
-                                       g_string_append (item_value, fill);
-                                       g_string_append (item_value, line->str);
-                                       g_free (fill);
-                               }
-                               g_string_free (line, TRUE);
-                               /* that same here */
-                       } else {
-                               gchar *text_content =
-                                       webkit_dom_node_get_text_content (item);
-                               g_string_append (item_value, text_content);
-                               g_free (text_content);
-                       }
-
-                       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST) {
-                               space = g_strnfill (SPACES_PER_LIST_LEVEL - 2, ' ');
-                               item_str = g_strdup_printf (
-                                       "%s* %s", space, item_value->str);
-                               g_free (space);
-                       }
-
-                       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
-                               gint length = 1, tmp = counter;
-
-                               while ((tmp = tmp / 10) > 1)
-                                       length++;
-
-                               if (tmp == 1)
-                                       length++;
-
-                               space = g_strnfill (SPACES_PER_LIST_LEVEL - 2 - length, ' ');
-                               item_str = g_strdup_printf (
-                                       "%s%d. %s", space, counter, item_value->str);
-                               g_free (space);
-                       }
-
-                       if (format > E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
-                               gchar *value;
-
-                               if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA)
-                                       value = get_alpha_value (counter, FALSE);
-                               else
-                                       value = get_roman_value (counter, FALSE);
-
-                               /* Value already containes dot and space */
-                               space = g_strnfill (SPACES_PER_LIST_LEVEL - strlen (value), ' ');
-                               item_str = g_strdup_printf (
-                                       "%s%s%s", space, value, item_value->str);
-                               g_free (space);
-                               g_free (value);
-                       }
-
-                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT) {
-                               for (ii = 0; ii < level - 1; ii++) {
-                                       g_string_append (output, indent_per_level);
-                               }
-                               g_string_append (output, item_str);
-                       }
-
-                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
-                               if (!wrapped) {
-                                       gchar *fill = NULL;
-                                       gint fill_length;
-
-                                       fill_length = word_wrap_length - g_utf8_strlen (item_str, -1);
-                                       fill_length -= ii * SPACES_PER_LIST_LEVEL;
-
-                                       if (fill_length < 0)
-                                               fill_length = 0;
-
-                                       if (g_str_has_suffix (item_str, " "))
-                                               fill_length++;
-
-                                       fill = g_strnfill (fill_length, ' ');
-
-                                       g_string_append (output, fill);
-                                       g_free (fill);
-                               }
-                               if (g_str_has_suffix (item_str, " "))
-                                       g_string_append_len (output, item_str, g_utf8_strlen (item_str, -1) - 
1);
-                               else
-                                       g_string_append (output, item_str);
-                       }
-
-                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
-                               if (!wrapped) {
-                                       gchar *fill = NULL;
-                                       gint fill_length = 0;
-
-                                       for (ii = 0; ii < level - 1; ii++)
-                                               g_string_append (output, indent_per_level);
-
-                                       fill_length = word_wrap_length - g_utf8_strlen (item_str, -1);
-                                       fill_length -= ii * SPACES_PER_LIST_LEVEL;
-                                       fill_length /= 2;
-
-                                       if (fill_length < 0)
-                                               fill_length = 0;
-
-                                       if (g_str_has_suffix (item_str, " "))
-                                               fill_length++;
-
-                                       fill = g_strnfill (fill_length, ' ');
-
-                                       g_string_append (output, fill);
-                                       g_free (fill);
-                               }
-                               if (g_str_has_suffix (item_str, " "))
-                                       g_string_append_len (output, item_str, g_utf8_strlen (item_str, -1) - 
1);
-                               else
-                                       g_string_append (output, item_str);
-                       }
-
-                       counter++;
-                       item = webkit_dom_node_get_next_sibling (item);
-                       if (item)
-                               g_string_append (output, "\n");
-
-                       g_free (item_str);
-                       g_string_free (item_value, TRUE);
-               } else if (WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (item) ||
-                          WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (item)) {
-                       process_list_to_plain_text (
-                               view, WEBKIT_DOM_ELEMENT (item), level + 1, output);
-                       item = webkit_dom_node_get_next_sibling (item);
-               } else {
-                       item = webkit_dom_node_get_next_sibling (item);
-               }
-       }
-
-       if (webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (element)))
-               g_string_append (output, "\n");
-
-       g_free (indent_per_level);
-}
-
-static void
-remove_base_attributes (WebKitDOMElement *element)
-{
-       webkit_dom_element_remove_attribute (element, "class");
-       webkit_dom_element_remove_attribute (element, "id");
-       webkit_dom_element_remove_attribute (element, "name");
-}
-
-static void
-remove_evolution_attributes (WebKitDOMElement *element)
-{
-       webkit_dom_element_remove_attribute (element, "x-evo-smiley");
-       webkit_dom_element_remove_attribute (element, "data-converted");
-       webkit_dom_element_remove_attribute (element, "data-edit-as-new");
-       webkit_dom_element_remove_attribute (element, "data-evo-draft");
-       webkit_dom_element_remove_attribute (element, "data-inline");
-       webkit_dom_element_remove_attribute (element, "data-uri");
-       webkit_dom_element_remove_attribute (element, "data-message");
-       webkit_dom_element_remove_attribute (element, "data-name");
-       webkit_dom_element_remove_attribute (element, "data-new-message");
-       webkit_dom_element_remove_attribute (element, "spellcheck");
-}
-/*
-static void
-remove_style_attributes (WebKitDOMElement *element)
-{
-       webkit_dom_element_remove_attribute (element, "bgcolor");
-       webkit_dom_element_remove_attribute (element, "background");
-       webkit_dom_element_remove_attribute (element, "style");
-}
-*/
-static gboolean
-replace_to_whitespaces (const GMatchInfo *info,
-                        GString *res,
-                        gpointer data)
-{
-       gint ii, length = 0;
-       gint chars_count = GPOINTER_TO_INT (data);
-
-       length = TAB_LENGTH - (chars_count %  TAB_LENGTH);
-
-       for (ii = 0; ii < length; ii++)
-               g_string_append (res, " ");
-
-       return FALSE;
-}
-
-static void
-process_elements (EHTMLEditorView *view,
-                  WebKitDOMNode *node,
-                  gboolean to_html,
-                  gboolean changing_mode,
-                  gboolean to_plain_text,
-                  GString *buffer)
-{
-       WebKitDOMNodeList *nodes;
-       gulong ii, length;
-       gchar *content;
-       gboolean skip_nl = FALSE;
-
-       if (to_plain_text && !buffer)
-               return;
-
-       if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (node)) {
-               if (changing_mode && to_plain_text) {
-                       WebKitDOMNamedNodeMap *attributes;
-                       gulong attributes_length;
-
-                       /* Copy attributes */
-                       g_string_append (buffer, "<html><head></head><body ");
-                       attributes = webkit_dom_element_get_attributes (
-                               WEBKIT_DOM_ELEMENT (node));
-                       attributes_length =
-                               webkit_dom_named_node_map_get_length (attributes);
-
-                       for (ii = 0; ii < attributes_length; ii++) {
-                               gchar *name, *value;
-                               WebKitDOMNode *node =
-                                       webkit_dom_named_node_map_item (
-                                               attributes, ii);
-
-                               name = webkit_dom_node_get_local_name (node);
-                               value = webkit_dom_node_get_node_value (node);
-
-                               g_string_append (buffer, name);
-                               g_string_append (buffer, "=\"");
-                               g_string_append (buffer, value);
-                               g_string_append (buffer, "\" ");
-
-                               g_free (name);
-                               g_free (value);
-                       }
-                       g_string_append (buffer, ">");
-                       g_object_unref (attributes);
-               }
-               if (to_html)
-                       remove_evolution_attributes (WEBKIT_DOM_ELEMENT (node));
-       }
-
-       nodes = webkit_dom_node_get_child_nodes (node);
-       length = webkit_dom_node_list_get_length (nodes);
-
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *child;
-               gboolean skip_node = FALSE;
-
-               child = webkit_dom_node_list_item (nodes, ii);
-
-               if (WEBKIT_DOM_IS_TEXT (child)) {
-                       gchar *content, *tmp;
-                       GRegex *regex;
-                       gint char_count = 0;
-
-                       content = webkit_dom_node_get_text_content (child);
-                       if (!changing_mode && to_plain_text) {
-                               /* Replace tabs with 8 whitespaces, otherwise they got
-                                * replaced by single whitespace */
-                               if (strstr (content, "\x9")) {
-                                       if (buffer->str && *buffer->str) {
-                                               gchar *start_of_line = g_strrstr_len (
-                                                       buffer->str, -1, "\n") + 1;
-
-                                               if (start_of_line && *start_of_line)
-                                                               char_count = strlen (start_of_line);
-                                       } else
-                                               char_count = 0;
-
-                                       regex = g_regex_new ("\x9", 0, 0, NULL);
-                                       tmp = g_regex_replace_eval (
-                                               regex,
-                                               content,
-                                               -1,
-                                               0,
-                                               0,
-                                               (GRegexEvalCallback) replace_to_whitespaces,
-                                               GINT_TO_POINTER (char_count),
-                                               NULL);
-
-                                       g_string_append (buffer, tmp);
-                                       g_free (tmp);
-                                       g_free (content);
-                                       content = webkit_dom_node_get_text_content (child);
-                                       g_regex_unref (regex);
-                               }
-                       }
-
-                       if (strstr (content, UNICODE_ZERO_WIDTH_SPACE)) {
-                               regex = g_regex_new (UNICODE_ZERO_WIDTH_SPACE, 0, 0, NULL);
-                               tmp = g_regex_replace (
-                                       regex, content, -1, 0, "", 0, NULL);
-                               webkit_dom_node_set_text_content (child, tmp, NULL);
-                               g_free (tmp);
-                               g_free (content);
-                               content = webkit_dom_node_get_text_content (child);
-                               g_regex_unref (regex);
-                       }
-
-                       if (to_plain_text && !changing_mode) {
-                               gchar *class;
-                               const gchar *css_align;
-
-                               if (strstr (content, UNICODE_NBSP)) {
-                                       GString *nbsp_free;
-
-                                       nbsp_free = e_str_replace_string (
-                                               content, UNICODE_NBSP, " ");
-
-                                       g_free (content);
-                                       content = g_string_free (nbsp_free, FALSE);
-                               }
-
-                               class = webkit_dom_element_get_class_name (WEBKIT_DOM_ELEMENT (node));
-                               if ((css_align = strstr (class, "-x-evo-align-"))) {
-                                       gchar *align;
-                                       gchar *content_with_align;
-                                       gint length;
-                                       gint word_wrap_length =
-                                               e_html_editor_selection_get_word_wrap_length (
-                                                       e_html_editor_view_get_selection (view));
-
-                                       if (!g_str_has_prefix (css_align + 13, "left")) {
-                                               if (g_str_has_prefix (css_align + 13, "center"))
-                                                       length = (word_wrap_length - g_utf8_strlen (content, 
-1)) / 2;
-                                               else
-                                                       length = word_wrap_length - g_utf8_strlen (content, 
-1);
-
-                                               if (length < 0)
-                                                       length = 0;
-
-                                               if (g_str_has_suffix (content, " ")) {
-                                                       char *tmp;
-
-                                                       length++;
-                                                       align = g_strnfill (length, ' ');
-
-                                                       tmp = g_strndup (content, g_utf8_strlen (content, -1) 
-1);
-
-                                                       content_with_align = g_strconcat (
-                                                               align, tmp, NULL);
-                                                       g_free (tmp);
-                                               } else {
-                                                       align = g_strnfill (length, ' ');
-
-                                                       content_with_align = g_strconcat (
-                                                               align, content, NULL);
-                                               }
-
-                                               g_free (content);
-                                               g_free (align);
-                                               content = content_with_align;
-                                       }
-                               }
-
-                               g_free (class);
-                       }
-
-                       if (to_plain_text || changing_mode)
-                               g_string_append (buffer, content);
-
-                       g_free (content);
-
-                       goto next;
-               }
-
-               if (WEBKIT_DOM_IS_COMMENT (child) || !WEBKIT_DOM_IS_ELEMENT (child))
-                       goto next;
-
-               /* Leave caret position untouched */
-               if (element_has_id (WEBKIT_DOM_ELEMENT (child), "-x-evo-caret-position")) {
-                       if (changing_mode && to_plain_text) {
-                               content = webkit_dom_html_element_get_outer_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (child));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                       }
-                       if (to_html)
-                               remove_node (child);
-
-                       skip_node = TRUE;
-                       goto next;
-               }
-
-               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "Apple-tab-span")) {
-                       if (!changing_mode && to_plain_text) {
-                               gchar *content, *tmp;
-                               GRegex *regex;
-                               gint char_count = 0;
-
-                               content = webkit_dom_node_get_text_content (child);
-                               /* Replace tabs with 8 whitespaces, otherwise they got
-                                * replaced by single whitespace */
-                               if (strstr (content, "\x9")) {
-                                       if (buffer->str && *buffer->str) {
-                                               gchar *start_of_line = g_strrstr_len (
-                                                       buffer->str, -1, "\n") + 1;
-
-                                               if (start_of_line && *start_of_line)
-                                                       char_count = strlen (start_of_line);
-                                       } else
-                                               char_count = 0;
-
-                                       regex = g_regex_new ("\x9", 0, 0, NULL);
-                                       tmp = g_regex_replace_eval (
-                                               regex,
-                                               content,
-                                               -1,
-                                               0,
-                                               0,
-                                               (GRegexEvalCallback) replace_to_whitespaces,
-                                               GINT_TO_POINTER (char_count),
-                                               NULL);
-
-                                       g_string_append (buffer, tmp);
-                                       g_free (tmp);
-                                       g_regex_unref (regex);
-                               } else if (content && *content) {
-                                       /* Some it happens that some text is written inside
-                                        * the tab span element, so save it. */
-                                       g_string_append (buffer, content);
-                               }
-                               g_free (content);
-                       }
-                       if (to_html) {
-                               element_remove_class (
-                                       WEBKIT_DOM_ELEMENT (child),
-                                       "Applet-tab-span");
-                       }
-
-                       skip_node = TRUE;
-                       goto next;
-               }
-
-               /* Leave blockquotes as they are */
-               if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (child)) {
-                       if (changing_mode && to_plain_text) {
-                               content = webkit_dom_html_element_get_outer_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (child));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                               skip_node = TRUE;
-                               goto next;
-                       } else {
-                               if (!changing_mode && to_plain_text) {
-                                       if (get_citation_level (child, FALSE) == 0) {
-                                               gchar *value = webkit_dom_element_get_attribute (
-                                                       WEBKIT_DOM_ELEMENT (child), "type");
-
-                                               if (value && g_strcmp0 (value, "cite") == 0)
-                                                       g_string_append (buffer, "\n");
-                                               g_free (value);
-                                       }
-                               }
-                               process_blockquote (WEBKIT_DOM_ELEMENT (child));
-                               if (to_html)
-                                       remove_base_attributes (WEBKIT_DOM_ELEMENT (child));
-                       }
-               }
-
-               if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (child) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-indented"))
-                       process_blockquote (WEBKIT_DOM_ELEMENT (child));
-
-               if (WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (child) ||
-                   WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (child)) {
-                       if (to_plain_text) {
-                               if (changing_mode) {
-                                       content = webkit_dom_html_element_get_outer_html (
-                                               WEBKIT_DOM_HTML_ELEMENT (child));
-                                       g_string_append (buffer, content);
-                                       g_free (content);
-                               } else {
-                                       process_list_to_plain_text (
-                                               view, WEBKIT_DOM_ELEMENT (child), 1, buffer);
-                               }
-                               skip_node = TRUE;
-                               goto next;
-                       }
-               }
-
-               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-resizable-wrapper") &&
-                   !element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
-                       WebKitDOMNode *image =
-                               webkit_dom_node_get_first_child (child);
-
-                       if (to_html && WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (image)) {
-                               remove_evolution_attributes (
-                                       WEBKIT_DOM_ELEMENT (image));
-
-                               webkit_dom_node_replace_child (
-                                       node, image, child, NULL);
-                       }
-
-                       skip_node = TRUE;
-                       goto next;
-               }
-
-               /* Leave paragraphs as they are */
-               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-paragraph")) {
-                       if (changing_mode && to_plain_text) {
-                               content = webkit_dom_html_element_get_outer_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (child));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                               skip_node = TRUE;
-                               goto next;
-                       }
-                       if (to_html) {
-                               remove_base_attributes (WEBKIT_DOM_ELEMENT (child));
-                               remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child));
-                       }
-                       if (!changing_mode && to_plain_text)
-                               if (!webkit_dom_node_has_child_nodes (child))
-                                       g_string_append (buffer, "\n");
-               }
-
-               /* Signature */
-               if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (child) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-signature-wrapper")) {
-                       WebKitDOMNode *first_child;
-
-                       first_child = webkit_dom_node_get_first_child (child);
-
-                       if (to_html) {
-                               remove_base_attributes (
-                                       WEBKIT_DOM_ELEMENT (first_child));
-                               remove_evolution_attributes (
-                                       WEBKIT_DOM_ELEMENT (first_child));
-                       }
-                       if (to_plain_text && !changing_mode) {
-                               g_string_append (buffer, "\n");
-                               content = webkit_dom_html_element_get_inner_text (
-                                       WEBKIT_DOM_HTML_ELEMENT (first_child));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                               skip_nl = TRUE;
-                       }
-                       if (to_plain_text && changing_mode) {
-                               content = webkit_dom_html_element_get_outer_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (child));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                               skip_node = TRUE;
-                       }
-                       skip_node = TRUE;
-                       goto next;
-               }
-
-               /* Replace smileys with their text representation */
-               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
-                       if (to_plain_text && !changing_mode) {
-                               WebKitDOMNode *text_version;
-
-                               text_version = webkit_dom_node_get_last_child (child);
-                               content = webkit_dom_html_element_get_inner_text (
-                                       WEBKIT_DOM_HTML_ELEMENT (text_version));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                               skip_node = TRUE;
-                               goto next;
-                       }
-                       if (to_html) {
-                               WebKitDOMElement *img;
-
-                               img = WEBKIT_DOM_ELEMENT (
-                                       webkit_dom_node_get_first_child (child)),
-
-                               remove_evolution_attributes (img);
-                               remove_base_attributes (img);
-
-                               webkit_dom_node_insert_before (
-                                       webkit_dom_node_get_parent_node (child),
-                                       WEBKIT_DOM_NODE (img),
-                                       child,
-                                       NULL);
-                               remove_node (child);
-                               skip_node = TRUE;
-                               goto next;
-                       }
-               }
-
-               /* Leave PRE elements untouched */
-               if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (child)) {
-                       if (changing_mode && to_plain_text) {
-                               content = webkit_dom_html_element_get_outer_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (child));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                               skip_node = TRUE;
-                       }
-                       if (to_html)
-                               remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child));
-               }
-
-               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child)) {
-                       if (to_plain_text) {
-                               if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-wrap-br")) {
-                                       g_string_append (buffer, changing_mode ? "<br>" : "\n");
-                                       goto next;
-                               }
-
-                               /* Insert new line when we hit the BR element that is
-                                * not the last element in the block */
-                               if (!webkit_dom_node_is_same_node (
-                                       child, webkit_dom_node_get_last_child (node))) {
-                                       g_string_append (buffer, changing_mode ? "<br>" : "\n");
-                               } else {
-                                       /* In citations in the empty lines the BR element
-                                        * is on the end and we have to put NL there */
-                                       WebKitDOMNode *parent;
-
-                                       parent = webkit_dom_node_get_parent_node (child);
-                                       if (webkit_dom_node_get_next_sibling (parent)) {
-                                               parent = webkit_dom_node_get_parent_node (parent);
-
-                                               if (is_citation_node (parent))
-                                                       g_string_append (buffer, changing_mode ? "<br>" : 
"\n");
-                                       }
-                               }
-                       }
-               }
-
-               if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (child)) {
-                       if (changing_mode && to_plain_text) {
-                               content = webkit_dom_html_element_get_outer_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (child));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                               skip_node = TRUE;
-                       }
-                       if (!changing_mode && to_plain_text) {
-                               content = webkit_dom_html_element_get_inner_text (
-                                       WEBKIT_DOM_HTML_ELEMENT (child));
-                               g_string_append (buffer, content);
-                               g_free (content);
-                               skip_node = TRUE;
-                       }
-               }
- next:
-               if (webkit_dom_node_has_child_nodes (child) && !skip_node)
-                       process_elements (
-                               view, child, to_html, changing_mode, to_plain_text, buffer);
-       }
-
-       if (to_plain_text && (
-           WEBKIT_DOM_IS_HTML_DIV_ELEMENT (node) ||
-           WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (node) ||
-           WEBKIT_DOM_IS_HTML_PRE_ELEMENT (node) ||
-           WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))) {
-
-               gboolean add_br = TRUE;
-               WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
-               WebKitDOMNode *last_child = webkit_dom_node_get_last_child (node);
-
-               if (last_child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (last_child))
-                       if (webkit_dom_node_get_previous_sibling (last_child))
-                               add_br = FALSE;
-
-               /* If we don't have next sibling (last element in body) or next element is
-                * signature we are not adding the BR element */
-               if (!next_sibling)
-                       add_br = FALSE;
-               else if (next_sibling && WEBKIT_DOM_IS_HTML_DIV_ELEMENT (next_sibling)) {
-                       if (webkit_dom_element_query_selector (
-                               WEBKIT_DOM_ELEMENT (next_sibling),
-                               "span.-x-evo-signature", NULL)) {
-
-                               add_br = FALSE;
-                       }
-               }
-
-               if (add_br && !skip_nl)
-                       g_string_append (buffer, changing_mode ? "<br>" : "\n");
-       }
-
-       g_object_unref (nodes);
-}
-
-static void
-remove_wrapping_from_view (EHTMLEditorView *view)
-{
-       gint length;
-       gint ii;
-       WebKitDOMDocument *document;
-       WebKitDOMNodeList *list;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       list = webkit_dom_document_query_selector_all (document, "br.-x-evo-wrap-br", NULL);
-
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++)
-               remove_node (webkit_dom_node_list_item (list, ii));
-
-       g_object_unref (list);
-}
-
-static void
-remove_image_attributes_from_element (WebKitDOMElement *element)
-{
-       webkit_dom_element_remove_attribute (element, "background");
-       webkit_dom_element_remove_attribute (element, "data-uri");
-       webkit_dom_element_remove_attribute (element, "data-inline");
-       webkit_dom_element_remove_attribute (element, "data-name");
-}
-
-static void
-remove_background_images_in_document (WebKitDOMDocument *document)
-{
-       gint length, ii;
-       WebKitDOMNodeList *elements;
-
-       elements = webkit_dom_document_query_selector_all (
-               document, "[background][data-inline]", NULL);
-
-       length = webkit_dom_node_list_get_length (elements);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMElement *element = WEBKIT_DOM_ELEMENT (
-                       webkit_dom_node_list_item (elements, ii));
-
-               remove_image_attributes_from_element (element);
-       }
-
-       g_object_unref (elements);
-}
-
-static void
-remove_images_in_element (EHTMLEditorView *view,
-                          WebKitDOMElement *element)
-{
-       gint length, ii;
-       WebKitDOMNodeList *images;
-
-       images = webkit_dom_element_query_selector_all (
-               element, "img:not(.-x-evo-smiley-img)", NULL);
-
-       length = webkit_dom_node_list_get_length (images);
-       for (ii = 0; ii < length; ii++)
-               remove_node (webkit_dom_node_list_item (images, ii));
-
-       g_object_unref (images);
-}
-
-static void
-remove_images (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       remove_images_in_element (
-               view, WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)));
-}
-
-static void
-toggle_smileys (EHTMLEditorView *view)
-{
-       gboolean html_mode;
-       gint length;
-       gint ii;
-       WebKitDOMDocument *document;
-       WebKitDOMNodeList *smileys;
-
-       html_mode = e_html_editor_view_get_html_mode (view);
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       smileys = webkit_dom_document_query_selector_all (
-               document, "img.-x-evo-smiley-img", NULL);
-
-       length = webkit_dom_node_list_get_length (smileys);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *img = webkit_dom_node_list_item (smileys, ii);
-               WebKitDOMNode *text = webkit_dom_node_get_next_sibling (img);
-               WebKitDOMElement *parent = webkit_dom_node_get_parent_element (img);
-
-               webkit_dom_element_set_attribute (
-                       WEBKIT_DOM_ELEMENT (html_mode ? text : img),
-                       "style",
-                       "display: none",
-                       NULL);
-
-               webkit_dom_element_remove_attribute (
-                       WEBKIT_DOM_ELEMENT (html_mode ? img : text), "style");
-
-               if (html_mode)
-                       element_add_class (parent, "-x-evo-resizable-wrapper");
-               else
-                       element_remove_class (parent, "-x-evo-resizable-wrapper");
-       }
-
-       g_object_unref (smileys);
-}
-
-static void
-toggle_paragraphs_style_in_element (EHTMLEditorView *view,
-                                    WebKitDOMElement *element,
-                                   gboolean html_mode)
-{
-       EHTMLEditorSelection *selection;
-       gint ii, length;
-       WebKitDOMNodeList *paragraphs;
-
-       selection = e_html_editor_view_get_selection (view);
-
-       paragraphs = webkit_dom_element_query_selector_all (
-               element, ".-x-evo-paragraph", NULL);
-
-       length = webkit_dom_node_list_get_length (paragraphs);
-
-       for (ii = 0; ii < length; ii++) {
-               gchar *style;
-               const gchar *css_align;
-               WebKitDOMNode *node = webkit_dom_node_list_item (paragraphs, ii);
-
-               if (html_mode) {
-                       style = webkit_dom_element_get_attribute (
-                               WEBKIT_DOM_ELEMENT (node), "style");
-
-                       if ((css_align = strstr (style, "text-align: "))) {
-                               webkit_dom_element_set_attribute (
-                                       WEBKIT_DOM_ELEMENT (node),
-                                       "style",
-                                       g_str_has_prefix (css_align + 12, "center") ?
-                                               "text-align: center" :
-                                               "text-align: right",
-                                       NULL);
-                       } else {
-                               /* In HTML mode the paragraphs don't have width limit */
-                               webkit_dom_element_remove_attribute (
-                                       WEBKIT_DOM_ELEMENT (node), "style");
-                       }
-                       g_free (style);
-               } else {
-                       WebKitDOMNode *parent;
-
-                       parent = webkit_dom_node_get_parent_node (node);
-                       /* If the paragraph is inside indented paragraph don't set
-                        * the style as it will be inherited */
-                       if (!element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-indented")) {
-                               const gchar *style_to_add = "";
-                               style = webkit_dom_element_get_attribute (
-                                       WEBKIT_DOM_ELEMENT (node), "style");
-
-                               if ((css_align = strstr (style, "text-align: "))) {
-                                       style_to_add = g_str_has_prefix (
-                                               css_align + 12, "center") ?
-                                                       "text-align: center;" :
-                                                       "text-align: right;";
-                               }
-
-                               /* In plain text mode the paragraphs have width limit */
-                               e_html_editor_selection_set_paragraph_style (
-                                       selection, WEBKIT_DOM_ELEMENT (node),
-                                       -1, 0, style_to_add);
-
-                               g_free (style);
-                       }
-               }
-       }
-       g_object_unref (paragraphs);
-}
-
-static void
-toggle_paragraphs_style (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       toggle_paragraphs_style_in_element (
-               view,
-               WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)),
-               view->priv->html_mode);
-}
-
-static gchar *
-process_content_for_saving_as_draft (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMHTMLElement *body;
-       WebKitDOMElement *document_element;
-       gchar *content;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       body = webkit_dom_document_get_body (document);
-
-       webkit_dom_element_set_attribute (
-               WEBKIT_DOM_ELEMENT (body), "data-evo-draft", "", NULL);
-
-       document_element = webkit_dom_document_get_document_element (document);
-       content = webkit_dom_html_element_get_outer_html (
-               WEBKIT_DOM_HTML_ELEMENT (document_element));
-
-       webkit_dom_element_remove_attribute (
-               WEBKIT_DOM_ELEMENT (body), "data-evo-draft");
-
-       return content;
-}
-
-static gchar *
-process_content_for_mode_change (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMNode *body;
-       GString *plain_text;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
-
-       plain_text = g_string_sized_new (1024);
-
-       process_elements (view, body, FALSE, TRUE, TRUE, plain_text);
-
-       g_string_append (plain_text, "</body></html>");
-
-       return g_string_free (plain_text, FALSE);
-}
-
-static void
-convert_element_from_html_to_plain_text (EHTMLEditorView *view,
-                                         WebKitDOMElement *element,
-                                         gboolean *wrap,
-                                         gboolean *quote)
-{
-       EHTMLEditorSelection *selection;
-       gint blockquotes_count;
-       gchar *inner_text, *inner_html;
-       gboolean restore = TRUE;
-       WebKitDOMDocument *document;
-       WebKitDOMElement *top_signature, *signature, *blockquote, *main_blockquote;
-       WebKitDOMNode *signature_clone, *from;
-
-       selection = e_html_editor_view_get_selection (view);
-
-       document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
-
-       top_signature = webkit_dom_element_query_selector (
-               element, ".-x-evo-top-signature", NULL);
-       signature = webkit_dom_element_query_selector (
-               element, "span.-x-evo-signature", NULL);
-       main_blockquote = webkit_dom_element_query_selector (
-               element, "#-x-evo-main-cite", NULL);
-
-       blockquote = webkit_dom_document_create_element (
-               document, "blockquote", NULL);
-
-       if (main_blockquote) {
-               WebKitDOMElement *input_start;
-
-               webkit_dom_element_set_attribute (
-                       blockquote, "type", "cite", NULL);
-
-               input_start = webkit_dom_element_query_selector (
-                       element, "#-x-evo-input-start", NULL);
-
-               restore = input_start ? TRUE : FALSE;
-
-               if (input_start)
-                       add_selection_markers_into_element_start (
-                               document, WEBKIT_DOM_ELEMENT (input_start), NULL, NULL);
-               from = WEBKIT_DOM_NODE (main_blockquote);
-       } else {
-               if (signature) {
-                       WebKitDOMNode *parent = webkit_dom_node_get_parent_node (
-                               WEBKIT_DOM_NODE (signature));
-                       signature_clone = webkit_dom_node_clone_node (parent, TRUE);
-                       remove_node (parent);
-               }
-               from = WEBKIT_DOM_NODE (element);
-       }
-
-       blockquotes_count = create_text_markers_for_citations_in_element (
-               WEBKIT_DOM_ELEMENT (from));
-
-       inner_text = webkit_dom_html_element_get_inner_text (
-               WEBKIT_DOM_HTML_ELEMENT (from));
-
-       webkit_dom_html_element_set_inner_text (
-               WEBKIT_DOM_HTML_ELEMENT (blockquote), inner_text, NULL);
-
-       inner_html = webkit_dom_html_element_get_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (blockquote));
-
-       parse_html_into_paragraphs (
-               view, document,
-               main_blockquote ? blockquote : WEBKIT_DOM_ELEMENT (element),
-               inner_html);
-
-       if (main_blockquote) {
-               webkit_dom_node_replace_child (
-                       webkit_dom_node_get_parent_node (
-                               WEBKIT_DOM_NODE (main_blockquote)),
-                       WEBKIT_DOM_NODE (blockquote),
-                       WEBKIT_DOM_NODE (main_blockquote),
-                       NULL);
-
-               remove_evolution_attributes (WEBKIT_DOM_ELEMENT (element));
-       } else {
-               WebKitDOMNode *first_child;
-
-               if (signature) {
-                       if (!top_signature) {
-                               signature_clone = webkit_dom_node_append_child (
-                                       WEBKIT_DOM_NODE (element),
-                                       signature_clone,
-                                       NULL);
-                       } else {
-                               webkit_dom_node_insert_before (
-                                       WEBKIT_DOM_NODE (element),
-                                       signature_clone,
-                                       webkit_dom_node_get_first_child (
-                                               WEBKIT_DOM_NODE (element)),
-                                       NULL);
-                       }
-               }
-
-               first_child = webkit_dom_node_get_first_child (
-                       WEBKIT_DOM_NODE (element));
-               if (first_child) {
-                       if (!webkit_dom_node_has_child_nodes (first_child)) {
-                               webkit_dom_html_element_set_inner_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (first_child),
-                                       "<br>",
-                                       NULL);
-                       }
-                       add_selection_markers_into_element_start (
-                               document, WEBKIT_DOM_ELEMENT (first_child), NULL, NULL);
-               }
-       }
-
-       *wrap = TRUE;
-       *quote = main_blockquote || blockquotes_count > 0;
-
-       webkit_dom_element_set_attribute (
-               WEBKIT_DOM_ELEMENT (element), "data-converted", "", NULL);
-
-       g_free (inner_text);
-       g_free (inner_html);
-
-       if (restore)
-               e_html_editor_selection_restore (selection);
-}
-
-static gchar *
-process_content_for_plain_text (EHTMLEditorView *view)
-{
-       EHTMLEditorSelection *selection;
-       gboolean wrap = FALSE, quote = FALSE, clean = FALSE;
-       gboolean converted, is_from_new_message;
-       gint length, ii;
-       GString *plain_text;
-       WebKitDOMDocument *document;
-       WebKitDOMNode *body, *source;
-       WebKitDOMNodeList *paragraphs;
-
-       plain_text = g_string_sized_new (1024);
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
-       converted = webkit_dom_element_has_attribute (
-               WEBKIT_DOM_ELEMENT (body), "data-converted");
-       is_from_new_message = webkit_dom_element_has_attribute (
-               WEBKIT_DOM_ELEMENT (body), "data-new-message");
-       source = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
-
-       selection = e_html_editor_view_get_selection (view);
-
-       /* If composer is in HTML mode we have to move the content to plain version */
-       if (view->priv->html_mode) {
-               if (converted || is_from_new_message) {
-                       toggle_paragraphs_style_in_element (
-                               view, WEBKIT_DOM_ELEMENT (source), FALSE);
-                       remove_images_in_element (
-                               view, WEBKIT_DOM_ELEMENT (source));
-                       remove_background_images_in_document (
-                               document);
-               } else {
-                       gchar *inner_html;
-                       WebKitDOMElement *div;
-
-                       inner_html = webkit_dom_html_element_get_inner_html (
-                               WEBKIT_DOM_HTML_ELEMENT (body));
-
-                       div = webkit_dom_document_create_element (
-                               document, "div", NULL);
-
-                       webkit_dom_html_element_set_inner_html (
-                               WEBKIT_DOM_HTML_ELEMENT (div), inner_html, NULL);
-
-                       webkit_dom_node_append_child (
-                               WEBKIT_DOM_NODE (body),
-                               WEBKIT_DOM_NODE (div),
-                               NULL);
-
-                       paragraphs = webkit_dom_element_query_selector_all (
-                               div, "#-x-evo-input-start", NULL);
-
-                       length = webkit_dom_node_list_get_length (paragraphs);
-                       for (ii = 0; ii < length; ii++) {
-                               WebKitDOMNode *paragraph;
-
-                               paragraph = webkit_dom_node_list_item (paragraphs, ii);
-
-                               webkit_dom_element_remove_attribute (
-                                       WEBKIT_DOM_ELEMENT (paragraph), "id");
-                       }
-                       g_object_unref (paragraphs);
-
-                       convert_element_from_html_to_plain_text (
-                               view, div, &wrap, &quote);
-
-                       g_object_unref (source);
-
-                       source = WEBKIT_DOM_NODE (div);
-
-                       clean = TRUE;
-               }
-       }
-
-       paragraphs = webkit_dom_element_query_selector_all (
-               WEBKIT_DOM_ELEMENT (source), ".-x-evo-paragraph", NULL);
-
-       length = webkit_dom_node_list_get_length (paragraphs);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *paragraph;
-
-               paragraph = webkit_dom_node_list_item (paragraphs, ii);
-
-               if (WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (paragraph) ||
-                   WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (paragraph)) {
-                       WebKitDOMNode *item = webkit_dom_node_get_first_child (paragraph);
-
-                       while (item) {
-                               WebKitDOMNode *next_item =
-                                       webkit_dom_node_get_next_sibling (item);
-
-                               if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (item)) {
-                                       e_html_editor_selection_wrap_paragraph (
-                                               selection, WEBKIT_DOM_ELEMENT (item));
-                               }
-                               item = next_item;
-                       }
-               } else {
-                       e_html_editor_selection_wrap_paragraph (
-                               selection, WEBKIT_DOM_ELEMENT (paragraph));
-               }
-       }
-       g_object_unref (paragraphs);
-
-       paragraphs = webkit_dom_element_query_selector_all (
-               WEBKIT_DOM_ELEMENT (source),
-               "span[id^=\"-x-evo-selection-\"], span#-x-evo-caret-position",
-               NULL);
-
-       length = webkit_dom_node_list_get_length (paragraphs);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *node = webkit_dom_node_list_item (paragraphs, ii);
-               WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
-
-               remove_node (node);
-               webkit_dom_node_normalize (parent);
-       }
-       g_object_unref (paragraphs);
-
-       if (view->priv->html_mode || quote)
-               quote_plain_text_recursive (document, source, source, 0);
-
-       process_elements (view, source, FALSE, FALSE, TRUE, plain_text);
-
-       if (clean)
-               remove_node (source);
-       else
-               g_object_unref (source);
-
-       /* Return text content between <body> and </body> */
-       return g_string_free (plain_text, FALSE);
-}
-
-static gchar *
-process_content_for_html (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMNode *body, *document_clone;
-       gchar *html_content;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       document_clone = webkit_dom_node_clone_node (
-               WEBKIT_DOM_NODE (webkit_dom_document_get_document_element (document)), TRUE);
-       body = WEBKIT_DOM_NODE (webkit_dom_element_query_selector (
-               WEBKIT_DOM_ELEMENT (document_clone), "body", NULL));
-       process_elements (view, body, TRUE, FALSE, FALSE, NULL);
-
-       html_content = webkit_dom_html_element_get_outer_html (
-               WEBKIT_DOM_HTML_ELEMENT (document_clone));
-
-       g_object_unref (document_clone);
-
-       return html_content;
-}
-
 static gboolean
 show_lose_formatting_dialog (EHTMLEditorView *view)
 {
@@ -6913,99 +2353,6 @@ show_lose_formatting_dialog (EHTMLEditorView *view)
 }
 
 static void
-clear_attributes (WebKitDOMDocument *document)
-{
-       gint length, ii;
-       WebKitDOMNamedNodeMap *attributes;
-       WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
-       WebKitDOMHTMLHeadElement *head = webkit_dom_document_get_head (document);
-       WebKitDOMElement *document_element =
-               webkit_dom_document_get_document_element (document);
-
-       /* Remove all attributes from HTML element */
-       attributes = webkit_dom_element_get_attributes (document_element);
-       length = webkit_dom_named_node_map_get_length (attributes);
-       for (ii = length - 1; ii >= 0; ii--) {
-               WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
-
-               webkit_dom_element_remove_attribute_node (
-                       document_element, WEBKIT_DOM_ATTR (node), NULL);
-       }
-       g_object_unref (attributes);
-
-       /* Remove everything from HEAD element */
-       while (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head)))
-               remove_node (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head)));
-
-       /* Remove non Evolution attributes from BODY element */
-       attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
-       length = webkit_dom_named_node_map_get_length (attributes);
-       for (ii = length - 1; ii >= 0; ii--) {
-               gchar *name;
-               WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
-
-               name = webkit_dom_node_get_local_name (node);
-
-               if (!g_str_has_prefix (name, "data-") ||
-                   g_str_has_prefix (name, "data-inline") ||
-                   g_str_has_prefix (name, "data-name")) {
-                       webkit_dom_element_remove_attribute_node (
-                               WEBKIT_DOM_ELEMENT (body),
-                               WEBKIT_DOM_ATTR (node),
-                               NULL);
-               }
-
-               g_free (name);
-       }
-       g_object_unref (attributes);
-}
-
-static void
-convert_when_changing_composer_mode (EHTMLEditorView *view)
-{
-       EHTMLEditorSelection *selection;
-       gboolean quote = FALSE, wrap = FALSE;
-       WebKitDOMDocument *document;
-       WebKitDOMHTMLElement *body;
-
-       selection = e_html_editor_view_get_selection (view);
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       body = webkit_dom_document_get_body (document);
-
-       convert_element_from_html_to_plain_text (
-               view, WEBKIT_DOM_ELEMENT (body), &wrap, &quote);
-
-       if (wrap)
-               e_html_editor_selection_wrap_paragraphs_in_document (selection, document);
-
-       if (quote) {
-               e_html_editor_selection_save (selection);
-               if (wrap)
-                       quote_plain_text_elements_after_wrapping_in_document (
-                               document);
-               else
-                       body = WEBKIT_DOM_HTML_ELEMENT (e_html_editor_view_quote_plain_text (view));
-               e_html_editor_selection_restore (selection);
-       }
-
-       toggle_paragraphs_style (view);
-       toggle_smileys (view);
-       remove_images (view);
-       remove_background_images_in_document (document);
-
-       clear_attributes (document);
-
-       webkit_dom_element_set_attribute (
-               WEBKIT_DOM_ELEMENT (body), "data-converted", "", NULL);
-
-       /* Update fonts - in plain text we only want monospace */
-       e_html_editor_view_update_fonts (view);
-
-       e_html_editor_view_force_spell_check (view);
-}
-
-static void
 html_editor_view_load_changed (EHTMLEditorView *view,
                                WebKitLoadEvent load_event)
 {
@@ -7075,28 +2422,6 @@ html_editor_view_load_changed (EHTMLEditorView *view,
                e_html_editor_view_turn_spell_check_off (view);
 }
 
-static void
-wrap_paragraphs_in_quoted_content (EHTMLEditorSelection *selection,
-                                   WebKitDOMDocument *document)
-{
-       gint ii, length;
-       WebKitDOMNodeList *paragraphs;
-
-       paragraphs = webkit_dom_document_query_selector_all (
-               document, "blockquote[type=cite] > .-x-evo-paragraph", NULL);
-
-       length = webkit_dom_node_list_get_length (paragraphs);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *paragraph;
-
-               paragraph = webkit_dom_node_list_item (paragraphs, ii);
-
-               e_html_editor_selection_wrap_paragraph (
-                       selection, WEBKIT_DOM_ELEMENT (paragraph));
-       }
-       g_object_unref (paragraphs);
-}
-
 /**
  * e_html_editor_view_set_html_mode:
  * @view: an #EHTMLEditorView
@@ -7146,7 +2471,32 @@ e_html_editor_view_set_html_mode (EHTMLEditorView *view,
 
                view->priv->html_mode = html_mode;
 
-               convert_when_changing_composer_mode (view);
+               GDBusProxy *web_extension;
+
+               g_return_if_fail (view != NULL);
+
+               web_extension = e_html_editor_view_get_web_extension_proxy (view);
+               if (!web_extension)
+                       return;
+
+               g_dbus_proxy_call (
+                       web_extension,
+                       "ConvertWhenChangingComposerMode",
+                       g_variant_new (
+                               "(tsb)",
+                               webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+                               text,
+                               TRUE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+
+               /* Update fonts - in plain text we only want monospace */
+               e_html_editor_view_update_fonts (view);
+
+               e_html_editor_view_force_spell_check (view);
 
                e_html_editor_selection_scroll_to_caret (selection);
 
@@ -7170,7 +2520,7 @@ e_html_editor_view_set_html_mode (EHTMLEditorView *view,
 
                toggle_paragraphs_style (view);
                toggle_smileys (view);
-               remove_wrapping_from_view (view);
+               remove_wrapping_from_document (view);
        } else {
                gchar *plain;
 
@@ -7209,13 +2559,12 @@ e_html_editor_view_set_html_mode (EHTMLEditorView *view,
 static void
 e_html_editor_view_init (EHTMLEditorView *view)
 {
-       WebKitWebSettings *settings;
+       WebKitSettings *settings;
        GSettings *g_settings;
        GSettingsSchema *settings_schema;
        ESpellChecker *checker;
        gchar **languages;
        gchar *comma_separated;
-       const gchar *user_cache_dir;
 
        view->priv = E_HTML_EDITOR_VIEW_GET_PRIVATE (view);
 
@@ -7244,9 +2593,6 @@ e_html_editor_view_init (EHTMLEditorView *view)
                view, "should-show-delete-interface-for-element",
                G_CALLBACK (html_editor_view_should_show_delete_interface_for_element), NULL);
        g_signal_connect (
-               view, "resource-request-starting",
-               G_CALLBACK (html_editor_view_resource_requested), NULL);
-       g_signal_connect (
                view, "load-changed",
                G_CALLBACK (html_editor_view_load_changed), NULL);
 
@@ -7319,21 +2665,10 @@ e_html_editor_view_init (EHTMLEditorView *view)
 
        /* Make WebKit think we are displaying a local file, so that it
         * does not block loading resources from file:// protocol */
-       webkit_web_view_load_string (
-               WEBKIT_WEB_VIEW (view), "", "text/html", "UTF-8", "file://");
+       webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), "", "file://");
 
        html_editor_view_set_links_active (view, FALSE);
 
-       if (emd_global_http_cache == NULL) {
-               user_cache_dir = e_get_user_cache_dir ();
-               emd_global_http_cache = camel_data_cache_new (user_cache_dir, NULL);
-
-               /* cache expiry - 2 hour access, 1 day max */
-               camel_data_cache_set_expire_age (
-                       emd_global_http_cache, 24 * 60 * 60);
-               camel_data_cache_set_expire_access (
-                       emd_global_http_cache, 2 * 60 * 60);
-       }
 }
 
 /**
@@ -7471,6 +2806,43 @@ e_html_editor_view_get_spell_checker (EHTMLEditorView *view)
        return E_SPELL_CHECKER (webkit_get_text_checker ());
 }
 
+static gchar *
+process_document (EHTMLEditorView *view,
+                  const gchar *function)
+{
+       GDBusProxy *web_extension;
+       GVariant *result;
+
+       g_return_val_if_fail (view != NULL, NULL);
+
+       web_extension = e_html_editor_view_get_web_extension_proxy (view);
+       if (!web_extension)
+               return NULL;
+
+       result = g_dbus_proxy_call_sync (
+               web_extension,
+               function,
+               g_variant_new (
+                       "(t)",
+                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               gchar *value;
+               gsize length = 0;
+
+               value = g_variant_dup_string (result, &length);
+               g_variant_unref (result);
+
+               return value;
+       }
+
+       return NULL;
+}
+
 /**
  * e_html_editor_view_get_text_html:
  * @view: an #EHTMLEditorView:
@@ -7483,7 +2855,7 @@ e_html_editor_view_get_spell_checker (EHTMLEditorView *view)
 gchar *
 e_html_editor_view_get_text_html (EHTMLEditorView *view)
 {
-       return process_content_for_html (view);
+       return process_document (view, "ProcessDocumentForHTML");
 }
 
 /**
@@ -7498,7 +2870,7 @@ e_html_editor_view_get_text_html (EHTMLEditorView *view)
 gchar *
 e_html_editor_view_get_text_html_for_drafts (EHTMLEditorView *view)
 {
-       return process_content_for_saving_as_draft (view);
+       return process_document (view, "ProcessDocumentForDrafts");
 }
 
 /**
@@ -7514,21 +2886,21 @@ e_html_editor_view_get_text_html_for_drafts (EHTMLEditorView *view)
 gchar *
 e_html_editor_view_get_text_plain (EHTMLEditorView *view)
 {
-       return process_content_for_plain_text (view);
+       return process_document (view, "ProcessDocumentForPlainText");
 }
 
 void
 e_html_editor_view_convert_and_insert_plain_text (EHTMLEditorView *view,
                                                   const gchar *text)
 {
-       html_editor_view_insert_converted_html_into_selection (view, FALSE, text);
+       insert_and_convert_html_into_selection (view, text, FALSE);
 }
 
 void
 e_html_editor_view_convert_and_insert_html_to_plain_text (EHTMLEditorView *view,
                                                           const gchar *html)
 {
-       html_editor_view_insert_converted_html_into_selection (view, TRUE, html);
+       insert_and_convert_html_into_selection (view, html, TRUE);
 }
 
 /**
@@ -7561,14 +2933,12 @@ e_html_editor_view_set_text_html (EHTMLEditorView *view,
        view->priv->reload_in_progress = TRUE;
 
        if (view->priv->is_message_from_draft) {
-               webkit_web_view_load_string (
-                       WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+               webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), text, "file://");
                return;
        }
 
        if (view->priv->is_message_from_selection && !view->priv->html_mode) {
-               webkit_web_view_load_string (
-                       WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+               webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), text, "file://");
                view->priv->convert_in_situ = TRUE;
                return;
        }
@@ -7578,17 +2948,15 @@ e_html_editor_view_set_text_html (EHTMLEditorView *view,
                if (strstr (text, "<!-- text/html -->")) {
                        if (!show_lose_formatting_dialog (view)) {
                                e_html_editor_view_set_html_mode (view, TRUE);
-                               webkit_web_view_load_string (
-                                       WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+                               webkit_web_view_load_html (
+                                       WEBKIT_WEB_VIEW (view), text, "file://");
                                return;
                        }
                }
-               webkit_web_view_load_string (
-                       WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+               webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), text, "file://");
                view->priv->convert_in_situ = TRUE;
        } else
-               webkit_web_view_load_string (
-                       WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+               webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), text, "file://");
 }
 
 /**
@@ -7659,16 +3027,20 @@ e_html_editor_view_paste_clipboard_quoted (EHTMLEditorView *view)
 void
 e_html_editor_view_embed_styles (EHTMLEditorView *view)
 {
-       WebKitWebSettings *settings;
-       WebKitDOMDocument *document;
-       WebKitDOMElement *sheet;
+       GDBusProxy *web_extension;
        gchar *stylesheet_uri;
        gchar *stylesheet_content;
        const gchar *stylesheet;
        gsize length;
+       WebKitSettings *settings;
+
+       g_return_if_fail (view != NULL);
+
+       web_extension = e_html_editor_view_get_web_extension_proxy (view);
+       if (!web_extension)
+               return;
 
        settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (view));
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
 
        g_object_get (
                G_OBJECT (settings),
@@ -7684,31 +3056,27 @@ e_html_editor_view_embed_styles (EHTMLEditorView *view)
                return;
        }
 
-       e_web_view_create_and_add_css_style_sheet (document, "-x-evo-composer-sheet");
-
-       sheet = webkit_dom_document_get_element_by_id (document, "-x-evo-composer-sheet");
-       webkit_dom_element_set_attribute (
-               sheet,
-               "type",
-               "text/css",
+       g_dbus_proxy_call (
+               web_extension,
+               "DOMEmbedStyleSheet",
+               g_variant_new (
+                       "(ts)",
+                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+                       stylesheet_content),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
                NULL);
 
-       webkit_dom_html_element_set_inner_html (WEBKIT_DOM_HTML_ELEMENT (sheet), stylesheet_content, NULL);
-
        g_free (stylesheet_content);
 }
 
 void
 e_html_editor_view_remove_embed_styles (EHTMLEditorView *view)
 {
-       WebKitDOMDocument *document;
-       WebKitDOMElement *sheet;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-       sheet = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-composer-sheet");
-
-       remove_node (WEBKIT_DOM_NODE (sheet));
+       e_html_editor_view_call_simple_extension_function (
+               view, "DOMRemoveEmbedStyleSheet");
 }
 
 static const gchar *
@@ -7745,7 +3113,7 @@ citation_color_level_5 (void)
  * e_html_editor_view_update_fonts:
  * @view: an #EHTMLEditorView
  *
- * Forces the editor to reload font settings from WebKitWebSettings and apply
+ * Forces the editor to reload font settings from WebKitSettings and apply
  * it on the content of the editor document.
  */
 void
@@ -7760,7 +3128,7 @@ e_html_editor_view_update_fonts (EHTMLEditorView *view)
        GString *stylesheet;
        GtkStyleContext *context;
        PangoFontDescription *ms, *vw;
-       WebKitWebSettings *settings;
+       WebKitSettings *settings;
 
        g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
 
@@ -8173,7 +3541,7 @@ e_html_editor_view_check_magic_links (EHTMLEditorView *view,
 
        g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
 
-       range = html_editor_view_get_dom_range (view);
+       range = dom_get_range (view);
        html_editor_view_check_magic_links (view, range, include_space, NULL);
 }
 
diff --git a/e-util/e-html-editor.c b/e-util/e-html-editor.c
index ee17cc0..d367249 100644
--- a/e-util/e-html-editor.c
+++ b/e-util/e-html-editor.c
@@ -307,7 +307,6 @@ static void
 html_editor_update_actions (EHTMLEditor *editor,
                             guint flags)
 {
-       WebKitWebView *web_view;
        WebKitSpellChecker *checker;
        WebKitHitTestResult *hit_test;
        WebKitHitTestResultContext context;
@@ -326,7 +325,6 @@ html_editor_update_actions (EHTMLEditor *editor,
        view = e_html_editor_get_view (editor);
        spell_checker = e_html_editor_view_get_spell_checker (view);
 
-       web_view = WEBKIT_WEB_VIEW (view);
        manager = e_html_editor_get_ui_manager (editor);
 
        visible = (flags & E_HTML_EDITOR_NODE_IS_IMAGE);
@@ -440,7 +438,7 @@ html_editor_spell_languages_changed (EHTMLEditor *editor)
 {
        EHTMLEditorView *view;
        ESpellChecker *spell_checker;
-       WebKitWebSettings *settings;
+       WebKitSettings *settings;
        gchar *comma_separated;
        gchar **languages;
 
@@ -496,11 +494,15 @@ html_editor_context_menu_cb (WebKitWebView *webkit_web_view,
        if (event)
                gtk_menu_popup (
                        GTK_MENU (menu), NULL, NULL, NULL,
-                       GTK_WIDGET (webkit_web_view), ((GdkEventButton*) event)->button, event->time);
+                       GTK_WIDGET (webkit_web_view),
+                       ((GdkEventButton*) event)->button,
+                       ((GdkEventButton*) event)->time);
        else
                gtk_menu_popup (
                        GTK_MENU (menu), NULL, NULL, NULL,
-                       GTK_WIDGET (webkit_web_view), 0, gtk_get_current_event_time ());
+                       GTK_WIDGET (webkit_web_view),
+                       0,
+                       gtk_get_current_event_time ());
 
        return TRUE;
 }
diff --git a/e-util/e-html-editor.h b/e-util/e-html-editor.h
index 5618cc8..5071435 100644
--- a/e-util/e-html-editor.h
+++ b/e-util/e-html-editor.h
@@ -64,7 +64,7 @@ struct _EHTMLEditorClass {
        GtkGridClass parent_class;
 
        void            (*update_actions)       (EHTMLEditor *editor,
-                                                GdkEventButton *event);
+                                                guint flags);
        void            (*spell_languages_changed)
                                                (EHTMLEditor *editor);
 };
diff --git a/e-util/web-extensions/Makefile.am b/e-util/web-extensions/Makefile.am
index 335ea9b..a93a3f6 100644
--- a/e-util/web-extensions/Makefile.am
+++ b/e-util/web-extensions/Makefile.am
@@ -2,7 +2,8 @@ webextensions_LTLIBRARIES = libehtmleditorwebextension.la
 
 libevolutionwebextension_la_SOURCES =                  \
        e-html-editor-web-extension.c                   \
-       e-html-editor-web-extension.h
+       e-html-editor-web-extension.h                   \
+       e-html-editor-web-extension-main.c
 
 libevolutionwebextension_la_CPPFLAGS =                 \
        $(AM_CPPFLAGS)                                  \
diff --git a/e-util/web-extensions/e-html-editor-web-extension-main.c 
b/e-util/web-extensions/e-html-editor-web-extension-main.c
new file mode 100644
index 0000000..aa4fcce
--- /dev/null
+++ b/e-util/web-extensions/e-html-editor-web-extension-main.c
@@ -0,0 +1,51 @@
+/*
+ * e-html-editor-web-extension-main.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "config.h"
+
+#include "e-html-editor-web-extension.h"
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+                 const gchar *name,
+                 EHTMLEditorWebExtension *extension)
+{
+       e_html_editor_web_extension_dbus_register (extension, connection);
+}
+
+/* Forward declaration */
+G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *wk_extension);
+
+G_MODULE_EXPORT void
+webkit_web_extension_initialize (WebKitWebExtension *wk_extension)
+{
+       EHTMLEditorWebExtension *extension;
+
+       extension = e_html_editor_web_extension_get ();
+       e_html_editor_web_extension_initialize (extension, wk_extension);
+
+       g_bus_own_name (
+               G_BUS_TYPE_SESSION,
+               E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
+               G_BUS_NAME_OWNER_FLAGS_NONE,
+               (GBusAcquiredCallback) bus_acquired_cb,
+               NULL, /* GBusNameAcquiredCallback */
+               NULL, /* GBusNameLostCallback */
+               g_object_ref (extension),
+               (GDestroyNotify) g_object_unref);
+}
diff --git a/web-extensions/evolution-web-extension.h 
b/e-util/web-extensions/e-html-editor-web-extension-names.h
similarity index 59%
rename from web-extensions/evolution-web-extension.h
rename to e-util/web-extensions/e-html-editor-web-extension-names.h
index ccee49f..0c42931 100644
--- a/web-extensions/evolution-web-extension.h
+++ b/e-util/web-extensions/e-html-editor-web-extension-names.h
@@ -1,5 +1,5 @@
 /*
- * evolution-web-extension.h
+ * e-html-editor-web-extension-names.h
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,11 @@
  *
  */
 
-#ifndef EVOLUTION_WEB_EXTENSION_H
-#define EVOLUTION_WEB_EXTENSION_H
+#ifndef E_HTML_EDITOR_WEB_EXTENSION_NAMES_H
+#define E_HTML_EDITOR_WEB_EXTENSION_NAMES_H
 
-#define EVOLUTION_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.WebExtension"
-#define EVOLUTION_WEB_EXTENSION_OBJECT_PATH  "/org/gnome/Evolution/WebExtension"
-#define EVOLUTION_WEB_EXTENSION_INTERFACE    "org.gnome.Evolution.WebExtension"
+#define E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.EHTMLEditor.WebExtension"
+#define E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH  "/org/gnome/Evolution/EHTMLEditor/WebExtension"
+#define E_HTML_EDITOR_WEB_EXTENSION_INTERFACE    "org.gnome.Evolution.EHTMLEditor.WebExtension"
 
-#endif /* EVOLUTION_WEB_EXTENSION_H */
+#endif /* E_HTML_EDITOR_WEB_EXTENSION_NAMES_H */
diff --git a/e-util/web-extensions/e-html-editor-web-extension.c 
b/e-util/web-extensions/e-html-editor-web-extension.c
index 5487aaa..251d471 100644
--- a/e-util/web-extensions/e-html-editor-web-extension.c
+++ b/e-util/web-extensions/e-html-editor-web-extension.c
@@ -16,14 +16,16 @@
  *
  */
 
+#include "config.h"
+
 #include "e-html-editor-web-extension.h"
 
+#include <string.h>
+
 #include <gio/gio.h>
 #include <gtk/gtk.h>
 #include <webkit2/webkit-web-extension.h>
 
-#include <string.h>
-
 #include <e-util/e-dom-utils.h>
 #include <e-util/e-html-editor-actions-dom-functions.h>
 #include <e-util/e-html-editor-cell-dialog-dom-functions.h>
@@ -35,28 +37,43 @@
 #include <e-util/e-html-editor-table-dialog-dom-functions.h>
 #include <e-util/e-html-editor-view-dom-functions.h>
 
-/* FIXME Clean it */
-static GDBusConnection *dbus_connection;
-
-/* These properties show the actual state of EHTMLEditorView */
-static EHTMLEditorSelectionAlignment alignment;
-static gchar *background_color = NULL;
-static EHTMLEditorSelectionBlockFormat block_format;
-static gboolean bold = FALSE;
-/* FIXME XXX WK2
-static GdkRGBA *font_color = NULL; */
-static gchar *font_color = NULL;
-static gchar *font_name = NULL;
-static gint font_size;
-static gboolean indented = FALSE;
-static gboolean italic = FALSE;
-static gboolean monospaced = FALSE;
-static gboolean strikethrough = FALSE;
-static gboolean subscript = FALSE;
-static gboolean superscript = FALSE;
-/* FIXME XXX WK2 is it needed?
-static gchar *text = NULL; */
-static gboolean underline = FALSE;
+#define E_HTML_EDITOR_WEB_EXTENSION_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), E_TYPE_HTML_EDITOR_WEB_EXTENSION, EHTMLEditorWebExtensionPrivate))
+
+struct _EWebExtensionPrivate {
+       WebKitWebExtension *wk_extension;
+
+       GDBusConnection *dbus_connection;
+       guint registration_id;
+
+       /* These properties show the actual state of EHTMLEditorView */
+       EHTMLEditorSelectionAlignment alignment;
+       EHTMLEditorSelectionBlockFormat block_format;
+       gchar *background_color;
+       gchar *font_color;
+       gchar *font_name;
+       gchar *text;
+       gint font_size;
+       gboolean bold;
+       gboolean indented;
+       gboolean italic;
+       gboolean monospaced;
+       gboolean strikethrough;
+       gboolean subscript;
+       gboolean superscript;
+       gboolean underline;
+
+       gboolean force_image_load;
+       gboolean changed;
+       gboolean inline_spelling;
+       gboolean magic_links;
+       gboolean magic_smileys;
+       gboolean html_mode;
+       gint word_wrap_length;
+};
+
+static CamelDataCache *emd_global_http_cache = NULL;
 
 static const char introspection_xml[] =
 "<node>"
@@ -65,6 +82,9 @@ static const char introspection_xml[] =
 "<!--                       PROPERTIES                          -->"
 "<!-- ********************************************************* -->"
 "    <property type='b' name='ForceImageLoad' access='readwrite'/>"
+"    <property type='b' name='InlineSpelling' access='readwrite'/>"
+"    <property type='b' name='MagicLinks' access='readwrite'/>"
+"    <property type='b' name='HTMLMode' access='readwrite'/>"
 "<!-- ********************************************************* -->"
 "<!-- These properties show the actual state of EHTMLEditorView -->"
 "<!-- ********************************************************* -->"
@@ -82,6 +102,7 @@ static const char introspection_xml[] =
 "    <property type='b' name='Subscript' access='readwrite'/>"
 "    <property type='b' name='Superscript' access='readwrite'/>"
 "    <property type='b' name='Underline' access='readwrite'/>"
+"    <property type='s' name='Text' access='readwrite'/>"
 "<!-- ********************************************************* -->"
 "<!--                          METHODS                          -->"
 "<!-- ********************************************************* -->"
@@ -336,10 +357,11 @@ handle_method_call (GDBusConnection *connection,
                     GDBusMethodInvocation *invocation,
                     gpointer user_data)
 {
-       WebKitWebExtension *web_extension = WEBKIT_WEB_EXTENSION (user_data);
-       WebKitWebPage *web_page;
-       WebKitDOMDocument *document;
        guint64 page_id;
+        EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (user_data);
+       WebKitDOMDocument *document;
+       WebKitWebExtension *web_extension = extension->priv->wk_extension;
+       WebKitWebPage *web_page;
 
        if (g_strcmp0 (interface_name, EVOLUTION_WEB_EXTENSION_INTERFACE) != 0)
                return;
@@ -1109,40 +1131,49 @@ handle_get_property (GDBusConnection *connection,
                      GError **error,
                      gpointer user_data)
 {
+       EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (user_data);
        GVariant *variant;
 
        if (g_strcmp0 (property_name, "ForceImageLoad") == 0)
-               variant = g_variant_new_boolean (force_image_load);
+               variant = g_variant_new_boolean (extension->priv->force_image_load);
+       else if (g_strcmp0 (property_name, "InlineSpelling") == 0)
+               variant = g_variant_new_boolean (extension->priv->inline_spelling);
+       else if (g_strcmp0 (property_name, "MagicLinks") == 0)
+               variant = g_variant_new_boolean (extension->priv->magic_links);
+       else if (g_strcmp0 (property_name, "HTMLMode") == 0)
+               variant = g_variant_new_boolean (extension->priv->html_mode);
        else if (g_strcmp0 (property_name, "Alignment") == 0)
-               variant = g_variant_new_int32 (alignment);
+               variant = g_variant_new_int32 (extension->priv->alignment);
        else if (g_strcmp0 (property_name, "BackgroundColor") == 0)
-               variant = g_variant_new_string (background_color);
+               variant = g_variant_new_string (extension->priv->background_color);
        else if (g_strcmp0 (property_name, "BlockFormat") == 0)
-               variant = g_variant_new_int32 (block_format);
+               variant = g_variant_new_int32 (extension->priv->block_format);
        else if (g_strcmp0 (property_name, "Bold") == 0)
-               variant = g_variant_new_boolean (bold);
+               variant = g_variant_new_boolean (extension->priv->bold);
        else if (g_strcmp0 (property_name, "FontColor") == 0)
-               variant = g_variant_new_string (font_color);
+               variant = g_variant_new_string (extension->priv->font_color);
        else if (g_strcmp0 (property_name, "FontName") == 0)
-               variant = g_variant_new_string (font_name);
+               variant = g_variant_new_string (extension->priv->font_name);
        else if (g_strcmp0 (property_name, "FontSize") == 0)
-               variant = g_variant_new_int32 (font_size);
+               variant = g_variant_new_int32 (extension->priv->font_size);
        else if (g_strcmp0 (property_name, "Indented") == 0)
-               variant = g_variant_new_boolean (indented);
+               variant = g_variant_new_boolean (extension->priv->indented);
        else if (g_strcmp0 (property_name, "Italic") == 0)
-               variant = g_variant_new_boolean (italic);
+               variant = g_variant_new_boolean (extension->priv->italic);
        else if (g_strcmp0 (property_name, "Monospaced") == 0)
-               variant = g_variant_new_boolean (monospaced);
+               variant = g_variant_new_boolean (extension->priv->monospaced);
        else if (g_strcmp0 (property_name, "Strikethrough") == 0)
-               variant = g_variant_new_boolean (strikethrough);
+               variant = g_variant_new_boolean (extension->priv->strikethrough);
        else if (g_strcmp0 (property_name, "Subscript") == 0)
-               variant = g_variant_new_boolean (subscript);
+               variant = g_variant_new_boolean (extension->priv->subscript);
        else if (g_strcmp0 (property_name, "Superscript") == 0)
-               variant = g_variant_new_boolean (superscript);
+               variant = g_variant_new_boolean (extension->priv->superscript);
        else if (g_strcmp0 (property_name, "Superscript") == 0)
-               variant = g_variant_new_boolean (superscript);
+               variant = g_variant_new_boolean (extension->priv->superscript);
        else if (g_strcmp0 (property_name, "Underline") == 0)
-               variant = g_variant_new_boolean (underline);
+               variant = g_variant_new_boolean (extension->priv->underline);
+       else if (g_strcmp0 (property_name, "Text") == 0)
+               variant = g_variant_new_string (extension->priv->text);
 
        return variant;
 }
@@ -1157,6 +1188,7 @@ handle_set_property (GDBusConnection *connection,
                      GError **error,
                      gpointer user_data)
 {
+       EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (user_data);
        GError *local_error = NULL;
        GVariantBuilder *builder;
 
@@ -1165,186 +1197,199 @@ handle_set_property (GDBusConnection *connection,
        if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == force_image_load)
+               if (value == extension->priv->force_image_load)
                        goto exit;
 
-               force_image_load = value;
+               extension->priv->force_image_load = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "ForceImageLoad",
-                       g_variant_new_boolean (force_image_load));
+                       g_variant_new_boolean (extension->priv->force_image_load));
        } else if (g_strcmp0 (property_name, "Alignment") == 0) {
                gint32 value = g_variant_get_int32 (variant);
 
-               if (value == alignment)
+               if (value == extension->priv->alignment)
                        goto exit;
 
-               alignment = value;
+               extension->priv->alignment = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Alignment",
-                       g_variant_new_int32 (alignment));
+                       g_variant_new_int32 (extension->priv->alignment));
        } else if (g_strcmp0 (property_name, "BackgroundColor") == 0) {
                const gchar *value = g_variant_get_string (variant);
 
-               if (g_strcmp0 (value, background_color) != 0)
+               if (g_strcmp0 (value, extension->priv->background_color) != 0)
                        goto exit;
 
-               g_free (background_color);
-               background_color = g_strdup (value);
+               g_free (extension->priv->background_color);
+               extension->priv->background_color = g_strdup (value);
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "BackgroundColor",
-                       g_variant_new_string (background_color));
+                       g_variant_new_string (extension->priv->background_color));
        } else if (g_strcmp0 (property_name, "BlockFormat") == 0) {
                gint32 value = g_variant_get_int32 (variant);
 
-               if (value == block_format)
+               if (value == extension->priv->block_format)
                        goto exit;
 
-               block_format = value;
+               extension->priv->block_format = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "BlockFormat",
-                       g_variant_new_int32 (block_format));
+                       g_variant_new_int32 (extension->priv->block_format));
        } else if (g_strcmp0 (property_name, "Bold") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == bold)
+               if (value == extension->priv->bold)
                        goto exit;
 
-               bold = value;
+               extension->priv->bold = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Bold",
-                       g_variant_new_boolean (bold));
+                       g_variant_new_boolean (extension->priv->bold));
        } else if (g_strcmp0 (property_name, "FontColor") == 0) {
                const gchar *value = g_variant_get_string (variant);
 
-               if (g_strcmp0 (value, font_color) != 0)
+               if (g_strcmp0 (value, extension->priv->font_color) != 0)
                        goto exit;
 
-               g_free (font_color);
-               font_color = g_strdup (value);
+               g_free (extension->priv->font_color);
+               extension->priv->font_color = g_strdup (value);
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "FontColor",
-                       g_variant_new_string (font_color));
+                       g_variant_new_string (extension->priv->font_color));
        } else if (g_strcmp0 (property_name, "FontName") == 0) {
                const gchar *value = g_variant_get_string (variant);
 
-               if (g_strcmp0 (value, font_name) != 0)
+               if (g_strcmp0 (value, extension->priv->font_name) != 0)
                        goto exit;
 
-               g_free (font_name);
-               font_name = g_strdup (value);
+               g_free (extension->priv->font_name);
+               extension->priv->font_name = g_strdup (value);
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "FontName",
-                       g_variant_new_string (font_name));
+                       g_variant_new_string (extension->priv->font_name));
        } else if (g_strcmp0 (property_name, "FontSize") == 0) {
                gint32 value = g_variant_get_int32 (variant);
 
-               if (value == font_size)
+               if (value == extension->priv->font_size)
                        goto exit;
 
-               font_size = value;
+               extension->priv->font_size = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "FontSize",
-                       g_variant_new_int32 (font_size));
+                       g_variant_new_int32 (extension->priv->font_size));
        } else if (g_strcmp0 (property_name, "Indented") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == indented)
+               if (value == extension->priv->indented)
                        goto exit;
 
-               indented = value;
+               extension->priv->indented = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Indented",
-                       g_variant_new_boolean (indented));
+                       g_variant_new_boolean (extension->priv->indented));
        } else if (g_strcmp0 (property_name, "Italic") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == italic)
+               if (value == extension->priv->italic)
                        goto exit;
 
-               italic = value;
+               extension->priv->italic = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Italic",
-                       g_variant_new_boolean (italic));
+                       g_variant_new_boolean (extension->priv->italic));
        } else if (g_strcmp0 (property_name, "Monospaced") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == monospaced)
+               if (value == extension->priv->monospaced)
                        goto exit;
 
-               monospaced = value;
+               extension->priv->monospaced = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Monospaced",
-                       g_variant_new_boolean (monospaced));
+                       g_variant_new_boolean (extension->priv->monospaced));
        } else if (g_strcmp0 (property_name, "Strikethrough") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == strikethrough)
+               if (value == extension->priv->strikethrough)
                        goto exit;
 
-               strikethrough = value;
+               extension->priv->strikethrough = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Strikethrough",
-                       g_variant_new_boolean (strikethrough));
+                       g_variant_new_boolean (extension->priv->strikethrough));
        } else if (g_strcmp0 (property_name, "Subscript") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == subscript)
+               if (value == extension->priv->subscript)
                        goto exit;
 
-               subscript = value;
+               extension->priv->subscript = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Subscript",
-                       g_variant_new_boolean (subscript));
+                       g_variant_new_boolean (extension->priv->subscript));
        } else if (g_strcmp0 (property_name, "Superscript") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == superscript)
+               if (value == extension->priv->superscript)
                        goto exit;
 
-               superscript = value;
+               extension->priv->superscript = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Superscript",
-                       g_variant_new_boolean (superscript));
+                       g_variant_new_boolean (extension->priv->superscript));
        } else if (g_strcmp0 (property_name, "Underline") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == underline)
+               if (value == extension->priv->underline)
                        goto exit;
 
-               underline = value;
+               extension->priv->underline = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "Undeline",
-                       g_variant_new_boolean (underline));
+                       g_variant_new_boolean (extension->priv->underline));
+       } else if (g_strcmp0 (property_name, "Text") == 0) {
+               const gchar *value = g_variant_get_string (variant);
+
+               if (g_strcmp0 (value, extension->priv->text) != 0)
+                       goto exit;
+
+               g_free (extension->priv->text);
+               extension->priv->text = g_strdup (value);
+
+               g_variant_builder_add (builder,
+                       "{sv}",
+                       "Text",
+                       g_variant_new_string (extension->priv->text));
        }
 
        g_dbus_connection_emit_signal (connection,
@@ -1374,48 +1419,376 @@ static const GDBusInterfaceVTable interface_vtable = {
 };
 
 static void
-bus_acquired_cb (GDBusConnection *connection,
-                 const char *name,
-                 gpointer user_data)
+e_html_editor_html_editor_web_extension_dispose (GObject *object)
+{
+       EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (object);
+
+       if (extension->priv->dbus_connection) {
+               g_dbus_connection_unregister_object (
+                       extension->priv->dbus_connection,
+                       extension->priv->registration_id);
+               extension->priv->registration_id = 0;
+               extension->priv->dbus_connection = NULL;
+       }
+
+       if (extension->priv->background_color != NULL) {
+               g_free (extension->priv->background_color);
+               extension->priv->background_color = NULL;
+       }
+
+       if (extension->priv->font_color != NULL) {
+               g_free (extension->priv->font_color);
+               extension->priv->font_color = NULL;
+       }
+
+       if (extension->priv->font_name != NULL) {
+               g_free (extension->priv->font_name);
+               extension->priv->font_name = NULL;
+       }
+
+       if (extension->priv->text != NULL) {
+               g_free (extension->priv->text);
+               extension->priv->text = NULL;
+       }
+
+       g_clear_object (&extension->priv->wk_extension);
+
+       G_OBJECT_CLASS (e_html_editor_web_extension_parent_class)->dispose (object);
+}
+
+static void
+e_html_editor_web_extension_class_init (EHTMLEditorWebExtensionClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->dispose = e_html_editor_web_extension_dispose;
+
+       g_type_class_add_private (object_class, sizeof(EHTMLEditorWebExtensionPrivate));
+}
+
+static void
+e_html_editor_web_extension_init (EHTMLEditorWebExtension *extension)
+{
+       extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension, E_TYPE_HTML_EDITOR_WEB_EXTENSION, 
EHTMLEditorWebExtensionPrivate);
+
+       extension->priv->bold = FALSE;
+       extension->priv->background_color = NULL;
+       extension->priv->font_color = NULL;
+       extension->priv->font_name = NULL;
+       extension->priv->text = NULL;
+       extension->priv->font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+       extension->priv->indented = FALSE;
+       extension->priv->italic = FALSE;
+       extension->priv->monospaced = FALSE;
+       extension->priv->strikethrough = FALSE;
+       extension->priv->subscript = FALSE;
+       extension->priv->superscript = FALSE;
+       extension->priv->underline = FALSE;
+       extension->priv->alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+       extension->priv->block_format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
+       extension->priv->changed = FALSE;
+       extension->priv->force_image_load = FALSE;
+       extension->priv->inline_spelling = FALSE;
+       extension->priv->magic_links = FALSE;
+       extension->priv->magic_smileys = FALSE;
+       extension->priv->html_mode = FALSE;
+       extension->priv->word_wrap_length = 71;
+}
+
+static gpointer
+e_html_editor_web_extension_create_instance(gpointer data)
+{
+       return g_object_new (E_TYPE_HTML_EDITOR_WEB_EXTENSION, NULL);
+}
+
+EHTMLEditorWebExtension *
+e_html_editor_web_extension_get (void)
+{
+       static GOnce once_init = G_ONCE_INIT;
+       return E_HTML_EDITOR_WEB_EXTENSION (g_once (&once_init, e_html_editor_web_extension_create_instance, 
NULL));
+}
+
+static gboolean
+image_exists_in_cache (const gchar *image_uri)
+{
+       gchar *filename;
+       gchar *hash;
+       gboolean exists = FALSE;
+
+       g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
+
+       hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
+       filename = camel_data_cache_get_filename (
+               emd_global_http_cache, "http", hash);
+
+       if (filename != NULL) {
+               exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+               g_free (filename);
+       }
+
+       g_free (hash);
+
+       return exists;
+}
+
+static EMailImageLoadingPolicy
+get_image_loading_policy (void)
+{
+       GSettings *settings;
+       EMailImageLoadingPolicy image_policy;
+
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       image_policy = g_settings_get_enum (settings, "image-loading-policy");
+       g_object_unref (settings);
+
+       return image_policy;
+}
+
+static void
+redirect_http_uri (EWebExtension *extension,
+                   WebKitWebPage *web_page,
+                   WebKitURIRequest *request)
+{
+       const gchar *uri;
+       gchar *new_uri;
+       SoupURI *soup_uri;
+       gboolean image_exists;
+       EMailImageLoadingPolicy image_policy;
+
+       uri = webkit_uri_request_get_uri (request);
+
+       /* Check Evolution's cache */
+       image_exists = image_exists_in_cache (uri);
+
+       /* If the URI is not cached and we are not allowed to load it
+        * then redirect to invalid URI, so that webkit would display
+        * a native placeholder for it. */
+       image_policy = get_image_loading_policy ();
+       if (!image_exists && !extension->priv->force_image_load &&
+           (image_policy == E_MAIL_IMAGE_LOADING_POLICY_NEVER)) {
+               webkit_uri_request_set_uri (request, "about:blank");
+               return;
+       }
+
+       new_uri = g_strconcat ("evo-", uri, NULL);
+       soup_uri = soup_uri_new (new_uri);
+       g_free (new_uri);
+
+       new_uri = soup_uri_to_string (soup_uri, FALSE);
+       webkit_uri_request_set_uri (request, new_uri);
+       soup_uri_free (soup_uri);
+
+       g_free (new_uri);
+}
+
+static gboolean
+web_page_send_request_cb (WebKitWebPage *web_page,
+                          WebKitURIRequest *request,
+                          WebKitURIResponse *redirected_response,
+                          EWebExtension *extension)
+{
+       const char *request_uri;
+       const char *page_uri;
+       gboolean uri_is_http;
+
+       request_uri = webkit_uri_request_get_uri (request);
+       page_uri = webkit_web_page_get_uri (web_page);
+
+       /* Always load the main resource. */
+       if (g_strcmp0 (request_uri, page_uri) == 0)
+               return FALSE;
+
+       uri_is_http =
+               g_str_has_prefix (request_uri, "http:") ||
+               g_str_has_prefix (request_uri, "https:") ||
+               g_str_has_prefix (request_uri, "evo-http:") ||
+               g_str_has_prefix (request_uri, "evo-https:");
+
+       if (uri_is_http)
+               redirect_http_uri (extension, web_page, request);
+
+       return FALSE;
+}
+
+static void
+web_page_document_loaded_cb (WebKitWebPage *web_page,
+                             gpointer user_data)
+{
+
+}
+
+static void
+web_page_created_cb (WebKitWebExtension *wk_extension,
+                     WebKitWebPage *web_page,
+                     EWebExtension *extension)
+{
+       g_signal_connect_object (
+               web_page, "send-request",
+               G_CALLBACK (web_page_send_request),
+               extension, 0);
+
+       g_signal_connect_object (
+               web_page, "document-loaded",
+               G_CALLBACK (web_page_document_loaded),
+               extension, 0);
+
+}
+
+void
+e_html_editor_web_extension_initialize (EWebExtension *extension,
+                                        WebKitWebExtension *wk_extension)
+{
+       g_return_if_fail (E_HTML_EDITOR_IS_WEB_EXTENSION (extension));
+
+       extension->priv->wk_extension = g_object_ref (wk_extension);
+
+       if (emd_global_http_cache == NULL) {
+               emd_global_http_cache = camel_data_cache_new (
+                       e_get_user_cache_dir (), NULL);
+
+               /* cache expiry - 2 hour access, 1 day max */
+               camel_data_cache_set_expire_age (
+                       emd_global_http_cache, 24 * 60 * 60);
+               camel_data_cache_set_expire_access (
+                       emd_global_http_cache, 2 * 60 * 60);
+       }
+}
+
+void
+e_html_editor_web_extension_dbus_register (EHTMLEditorWebExtension *extension,
+                                           GDBusConnection *connection)
 {
-       guint registration_id;
        GError *error = NULL;
        static GDBusNodeInfo *introspection_data = NULL;
 
-       if (!introspection_data)
-               introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
-       registration_id =
-               g_dbus_connection_register_object (
-                       connection,
-                       EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
-                       introspection_data->interfaces[0],
-                       &interface_vtable,
-                       g_object_ref (user_data),
-                       g_object_unref,
-                       &error);
-
-       if (!registration_id) {
-               g_warning ("Failed to register object: %s\n", error->message);
-               g_error_free (error);
-       } else {
-               dbus_connection = connection;
-               g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&dbus_connection);
+       g_return_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension));
+       g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
+
+       if (!introspection_data) {
+               introspection_data =
+                       g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+
+               extension->priv->registration_id =
+                       g_dbus_connection_register_object (
+                               connection,
+                               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+                               introspection_data->interfaces[0],
+                               &interface_vtable,
+                               extension,
+                               NULL,
+                               &error);
+
+               if (!extension->priv->registration_id) {
+                       g_warning ("Failed to register object: %s\n", error->message);
+                       g_error_free (error);
+               } else {
+                       extension->priv->dbus_connection = connection;
+                       g_object_add_weak_pointer (
+                               G_OBJECT (connection),
+                               (gpointer *)&extension->priv->dbus_connection);
+               }
        }
 }
 
-/* Forward declaration */
-G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *extension);
+void
+set_dbus_property_boolean (EHTMLEditorWebExtension *extension,
+                           const gchar *name,
+                           gboolean value)
+{
+       g_dbus_connection_call (
+               extension->priv->dbus_connection,
+               E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
+               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+               "org.freedesktop.DBus.Properties",
+               "Set",
+               g_variant_new (
+                       "(ssv)",
+                       E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
+                       name,
+                       g_variant_new_boolean (value)),
+               NULL,
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+void
+e_html_editor_web_extension_set_content_changed (EHTMLEditorWebExtension *extension)
+{
+       set_dbus_property_boolean (extension, "Changed", TRUE);
+}
+
+gboolean
+e_html_editor_web_extension_get_html_mode (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->html_mode;
+}
+
+GDBusConnection *
+e_html_editor_web_extension_get_connection (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->connection;
+}
 
-G_MODULE_EXPORT void
-webkit_web_extension_initialize (WebKitWebExtension *extension)
+gint
+e_html_editor_web_extension_get_word_wrap_length (EHTMLEditorWebExtension *extension)
 {
-       g_bus_own_name (
-               G_BUS_TYPE_SESSION,
-               EVOLUTION_WEB_EXTENSION_SERVICE_NAME,
-               G_BUS_NAME_OWNER_FLAGS_NONE,
-               bus_acquired_cb,
-               NULL, NULL,
-               g_object_ref (extension),
-               g_object_unref);
+       return extension->priv->word_wrap_length;
 }
+
+const gchar *
+e_html_editor_web_extension_get_selection_text (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->text;
+}
+
+gboolean
+e_html_editor_web_extension_get_bold (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->bold;
+}
+
+gboolean
+e_html_editor_web_extension_get_italic (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->italic;
+}
+
+gboolean
+e_html_editor_web_extension_get_underline (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->underline;
+}
+
+gboolean
+e_html_editor_web_extension_get_striketrough (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->strikethrough;
+}
+
+gint
+e_html_editor_web_extension_get_font_size (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->font_size;
+}
+
+EHTMLEditorSelectionAlignment
+e_html_editor_web_extension_get_alignment (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->alignment;
+}
+
+gboolean
+e_html_editor_web_extension_is_message_from_edit_as_new (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->is_message_from_edit_as_new;
+}
+
+gboolean
+e_html_editor_web_extension_get_remove_initial_input_line (EHTMLEditorWebExtension *extension)
+{
+       return extension->priv->remove_initial_input_line;
+}
+
diff --git a/e-util/web-extensions/e-html-editor-web-extension.h 
b/e-util/web-extensions/e-html-editor-web-extension.h
index ec99d21..9803b2a 100644
--- a/e-util/web-extensions/e-html-editor-web-extension.h
+++ b/e-util/web-extensions/e-html-editor-web-extension.h
@@ -19,8 +19,106 @@
 #ifndef E_HTML_EDITOR_WEB_EXTENSION_H
 #define E_HTML_EDITOR_WEB_EXTENSION_H
 
-#define E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.EHTMLEditor.WebExtension"
-#define E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH  "/org/gnome/Evolution/EHTMLEditor/WebExtension"
-#define E_HTML_EDITOR_WEB_EXTENSION_INTERFACE    "org.gnome.Evolution.EHTMLEditor.WebExtension"
+#include "config.h"
+#include "e-util-enums.h"
+
+#include "e-html-editor-web-extension-names.h"
+
+#include <webkit2/webkit-web-extension.h>
+#include <glib-object.h>
+
+/* Standard GObject macros */
+#define E_TYPE_HTML_EDITOR_WEB_EXTENSION \
+       (e_html_editor_web_extension_get_type ())
+#define E_HTML_EDITOR_WEB_EXTENSION(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_HTML_EDITOR_WEB_EXTENSION, EHTMLEditorWebExtension))
+#define E_HTML_EDITOR_WEB_EXTENSION_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_HTML_EDITOR_WEB_EXTENSION, EHTMLEditorWebExtensionClass))
+#define E_IS_HTML_EDITOR_WEB_EXTENSION(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_HTML_EDITOR_WEB_EXTENSION))
+#define E_IS_HTML_EDITOR_WEB_EXTENSION_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_HTML_EDITOR_WEB_EXTENSION))
+#define E_HTML_EDITOR_WEB_EXTENSION_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_HTML_EDITOR_WEB_EXTENSION, EHTMLEditorWebExtensionClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EHTMLEditorWebExtension EHTMLEditorWebExtension;
+typedef struct _EHTMLEditorWebExtensionClass EHTMLEditorWebExtensionClass;
+typedef struct _EHTMLEditorWebExtensionPrivate EHTMLEditorWebExtensionPrivate;
+
+struct _EHTMLEditorWebExtension {
+       GObject parent;
+       EHTMLEditorWebExtensionPrivate *priv;
+};
+
+struct _EHTMLEditorWebExtensionClass
+{
+       GObjectClass parent_class;
+};
+
+GType          e_html_editor_web_extension_get_type
+                                               (void) G_GNUC_CONST;
+
+EHTMLEditorWebExtension *
+               e_html_editor_web_extension_get (void);
+
+void           e_html_editor_web_extension_initialize
+                                               (EHTMLEditorWebExtension *extension,
+                                               WebKitWebExtension *wk_extension);
+
+void           e_html_editor_web_extension_dbus_register
+                                               (EHTMLEditorWebExtension *extension,
+                                                GDBusConnection *connection);
+
+void           set_dbus_property_boolean       (EHTMLEditorWebExtension *extension,
+                                                const gchar *name,
+                                                gboolean value);
+
+void           e_html_editor_web_extension_set_content_changed
+                                               (EHTMLEditorWebExtension *extension);
+
+gboolean       e_html_editor_web_extension_get_html_mode
+                                               (EHTMLEditorWebExtension *extension);
+
+GDBusConnection *
+               e_html_editor_web_extension_get_connection
+                                               (EHTMLEditorWebExtension *extension);
+
+gint           e_html_editor_web_extension_get_word_wrap_length
+                                               (EHTMLEditorWebExtension *extension);
+
+const gchar *  e_html_editor_web_extension_get_selection_text
+                                               (EHTMLEditorWebExtension *extension);
+
+gboolean       e_html_editor_web_extension_get_bold
+                                               (EHTMLEditorWebExtension *extension);
+
+gboolean       e_html_editor_web_extension_get_italic
+                                               (EHTMLEditorWebExtension *extension);
+
+gboolean       e_html_editor_web_extension_get_underline
+                                               (EHTMLEditorWebExtension *extension);
+
+gboolean       e_html_editor_web_extension_get_strikethrough
+                                               (EHTMLEditorWebExtension *extension);
+
+gint           e_html_editor_web_extension_get_font_size
+                                               (EHTMLEditorWebExtension *extension);
+
+EHTMLEditorSelectionAlignment
+               e_html_editor_web_extension_get_alignment
+                                               (EHTMLEditorWebExtension *extension);
+
+gboolean       e_html_editor_web_extension_is_message_from_edit_as_new
+                                               (EHTMLEditorWebExtension *extension);
+
+gboolean       e_html_editor_web_extension_get_remove_initial_input_line
+                                               (EHTMLEditorWebExtension *extension);
 
 #endif /* E_HTML_EDITOR_WEB_EXTENSION_H */
diff --git a/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c 
b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
index 7fc005d..99fee71 100644
--- a/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
+++ b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
@@ -451,9 +451,7 @@ handle_method_call (GDBusConnection *connection,
                        document_saved, select_id);
 
                g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(s)", value));
-
-               g_free (value);
+                       invocation, g_variant_new_take_string (value));
        } else if (g_strcmp0 (method_name, "SelectSetSelected") == 0) {
                const gchar *select_id, *option;
 
@@ -537,9 +535,7 @@ handle_method_call (GDBusConnection *connection,
                                document_saved, area_id);
 
                g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(s)", value));
-
-               g_free (value);
+                       invocation, g_variant_new_take_string (value));
        } else if (g_strcmp0 (method_name, "RebuildSourceList") == 0) {
                const gchar *optgroup_id, *optgroup_label, *option_id, *option_label;
                gboolean writable;
diff --git a/modules/mail/web-extension/module-mail-web-extension.c 
b/modules/mail/web-extension/module-mail-web-extension.c
index a3c9a7e..1468319 100644
--- a/modules/mail/web-extension/module-mail-web-extension.c
+++ b/modules/mail/web-extension/module-mail-web-extension.c
@@ -81,9 +81,7 @@ handle_method_call (GDBusConnection *connection,
                element_name = e_dom_utils_get_active_element_name (document);
 
                g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(s)", element_name));
-
-               g_free (element_name);
+                       invocation, g_variant_new_take_string (element_name));
        }
 }
 
diff --git a/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c 
b/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
index e83efb0..9f3b4ca 100644
--- a/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
+++ b/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
@@ -116,9 +116,7 @@ handle_method_call (GDBusConnection *connection,
                        document_uri = g_strdup ("");
 
                g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(s)", document_uri));
-
-               g_free (document_uri);
+                       invocation, g_variant_new_take_string (document_uri));
        }
 }
 
diff --git a/modules/text-highlight/web-extension/module-text-highlight-web-extension.c 
b/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
index 229b981..84f4a72 100644
--- a/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
+++ b/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
@@ -116,9 +116,7 @@ handle_method_call (GDBusConnection *connection,
                        document_uri = g_strdup ("");
 
                g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(s)", document_uri));
-
-               g_free (document_uri);
+                       invocation, g_variant_new_take_string (document_uri));
        }
 }
 
diff --git a/web-extensions/Makefile.am b/web-extensions/Makefile.am
index 4b3441e..5516a46 100644
--- a/web-extensions/Makefile.am
+++ b/web-extensions/Makefile.am
@@ -1,8 +1,9 @@
 webextensions_LTLIBRARIES = libevolutionwebextension.la
 
 libevolutionwebextension_la_SOURCES =                  \
-       evolution-web-extension.c                       \
-       evolution-web-extension.h
+       e-web-extension.c                               \
+       e-web-extension.h                               \
+       e-web-extension-main.c
 
 libevolutionwebextension_la_CPPFLAGS =                 \
        $(AM_CPPFLAGS)                                  \
diff --git a/web-extensions/e-web-extension-main.c b/web-extensions/e-web-extension-main.c
new file mode 100644
index 0000000..5df0126
--- /dev/null
+++ b/web-extensions/e-web-extension-main.c
@@ -0,0 +1,51 @@
+/*
+ * e-web-extension-main.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "config.h"
+
+#include "e-web-extension.h"
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+                 const gchar *name,
+                 EWebExtension *extension)
+{
+       e_web_extension_dbus_register (extension, connection);
+}
+
+/* Forward declaration */
+G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *wk_extension);
+
+G_MODULE_EXPORT void
+webkit_web_extension_initialize (WebKitWebExtension *wk_extension)
+{
+       EWebExtension *extension;
+
+       extension = e_web_extension_get ();
+       e_web_extension_initialize (extension, wk_extension);
+
+       g_bus_own_name (
+               G_BUS_TYPE_SESSION,
+               E_WEB_EXTENSION_SERVICE_NAME,
+               G_BUS_NAME_OWNER_FLAGS_NONE,
+               (GBusAcquiredCallback) bus_acquired_cb,
+               NULL, /* GBusNameAcquiredCallback */
+               NULL, /* GBusNameLostCallback */
+               g_object_ref (extension),
+               (GDestroyNotify) g_object_unref);
+}
diff --git a/web-extensions/evolution-web-extension.c b/web-extensions/e-web-extension.c
similarity index 71%
rename from web-extensions/evolution-web-extension.c
rename to web-extensions/e-web-extension.c
index ef425ba..663d232 100644
--- a/web-extensions/evolution-web-extension.c
+++ b/web-extensions/e-web-extension.c
@@ -1,5 +1,5 @@
 /*
- * evolution-web-extension.c
+ * e-web-extension.c
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,12 @@
  *
  */
 
-#include "evolution-web-extension.h"
+#include "config.h"
+
+#include "e-web-extension.h"
 
 #include <gio/gio.h>
 #include <gtk/gtk.h>
-#include <webkit2/webkit-web-extension.h>
 
 #include <libemail-engine/e-mail-enums.h>
 
@@ -29,10 +30,20 @@
 #include <e-util/e-dom-utils.h>
 #include <libedataserver/libedataserver.h>
 
-/* FIXME Clean it */
-static GDBusConnection *dbus_connection;
-static gboolean need_input = FALSE;
-static gboolean force_image_load = FALSE;
+#define E_WEB_EXTENSION_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), E_TYPE_WEB_EXTENSION, EWebExtensionPrivate))
+
+struct _EWebExtensionPrivate {
+       WebKitWebExtension *wk_extension;
+
+       GDBusConnection *dbus_connection;
+       guint registration_id;
+
+       gboolean need_input;
+       gboolean force_image_load;
+};
+
 static CamelDataCache *emd_global_http_cache = NULL;
 
 static const char introspection_xml[] =
@@ -112,156 +123,7 @@ static const char introspection_xml[] =
 "  </interface>"
 "</node>";
 
-static gboolean
-image_exists_in_cache (const gchar *image_uri)
-{
-       gchar *filename;
-       gchar *hash;
-       gboolean exists = FALSE;
-
-       g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
-
-       hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
-       filename = camel_data_cache_get_filename (
-               emd_global_http_cache, "http", hash);
-
-       if (filename != NULL) {
-               exists = g_file_test (filename, G_FILE_TEST_EXISTS);
-               g_free (filename);
-       }
-
-       g_free (hash);
-
-       return exists;
-}
-
-static EMailImageLoadingPolicy
-get_image_loading_policy (void)
-{
-       GSettings *settings;
-       EMailImageLoadingPolicy image_policy;
-
-       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-       image_policy = g_settings_get_enum (settings, "image-loading-policy");
-       g_object_unref (settings);
-
-       return image_policy;
-}
-
-static void
-redirect_http_uri (WebKitWebPage *web_page,
-                   WebKitURIRequest *request)
-{
-       const gchar *uri, *page_uri;
-       gchar *new_uri, *mail_uri, *enc;
-       SoupURI *soup_uri;
-       GHashTable *query;
-       gboolean image_exists;
-       EMailImageLoadingPolicy image_policy;
-
-       uri = webkit_uri_request_get_uri (request);
-       page_uri = webkit_web_page_get_uri (web_page);
-
-       /* Check Evolution's cache */
-       image_exists = image_exists_in_cache (uri);
-
-       /* If the URI is not cached and we are not allowed to load it
-        * then redirect to invalid URI, so that webkit would display
-        * a native placeholder for it. */
-       image_policy = get_image_loading_policy ();
-       if (!image_exists && !force_image_load &&
-           (image_policy == E_MAIL_IMAGE_LOADING_POLICY_NEVER)) {
-               webkit_uri_request_set_uri (request, "about:blank");
-               return;
-       }
-
-       new_uri = g_strconcat ("evo-", uri, NULL);
-       mail_uri = g_strndup (page_uri, strstr (page_uri, "?") - page_uri);
-
-       soup_uri = soup_uri_new (new_uri);
-       if (soup_uri->query)
-               query = soup_form_decode (soup_uri->query);
-       else
-               query = g_hash_table_new_full (
-                       g_str_hash, g_str_equal,
-                       g_free, g_free);
-
-       enc = soup_uri_encode (mail_uri, NULL);
-       g_hash_table_insert (query, g_strdup ("__evo-mail"), enc);
-
-       if (force_image_load) {
-               g_hash_table_insert (
-                       query,
-                       g_strdup ("__evo-load-images"),
-                       g_strdup ("true"));
-       }
-
-       g_free (mail_uri);
-
-       soup_uri_set_query_from_form (soup_uri, query);
-       g_free (new_uri);
-
-       new_uri = soup_uri_to_string (soup_uri, FALSE);
-
-       webkit_uri_request_set_uri (request, new_uri);
-
-       soup_uri_free (soup_uri);
-       g_hash_table_unref (query);
-       g_free (new_uri);
-}
-
-static gboolean
-web_page_send_request (WebKitWebPage *web_page,
-                       WebKitURIRequest *request,
-                       WebKitURIResponse *redirected_response,
-                       gpointer user_data)
-{
-       const char *request_uri;
-       const char *page_uri;
-       gboolean uri_is_http;
-
-       request_uri = webkit_uri_request_get_uri (request);
-       page_uri = webkit_web_page_get_uri (web_page);
-
-       /* Always load the main resource. */
-       if (g_strcmp0 (request_uri, page_uri) == 0)
-               return FALSE;
-
-       uri_is_http =
-               g_str_has_prefix (request_uri, "http:") ||
-               g_str_has_prefix (request_uri, "https:") ||
-               g_str_has_prefix (request_uri, "evo-http:") ||
-               g_str_has_prefix (request_uri, "evo-https:");
-
-       if (uri_is_http)
-               redirect_http_uri (web_page, request);
-
-       return FALSE;
-}
-
-static void
-web_page_document_loaded (WebKitWebPage *web_page,
-                          gpointer user_data)
-{
-
-}
-
-static void
-web_page_created_callback (WebKitWebExtension *extension,
-                           WebKitWebPage *web_page,
-                           gpointer user_data)
-{
-       g_signal_connect_object (
-               web_page, "send-request",
-               G_CALLBACK (web_page_send_request),
-               NULL, 0);
-
-       g_signal_connect_object (
-               web_page, "document-loaded",
-               G_CALLBACK (web_page_document_loaded),
-               NULL, 0);
-
-}
+G_DEFINE_TYPE (EWebExtension, e_web_extension, G_TYPE_OBJECT)
 
 static WebKitWebPage *
 get_webkit_web_page_or_return_dbus_error (GDBusMethodInvocation *invocation,
@@ -287,17 +149,19 @@ handle_method_call (GDBusConnection *connection,
                     GDBusMethodInvocation *invocation,
                     gpointer user_data)
 {
-       WebKitWebExtension *web_extension = WEBKIT_WEB_EXTENSION (user_data);
-       WebKitWebPage *web_page;
-       WebKitDOMDocument *document;
        guint64 page_id;
+        EWebExtension *extension = E_WEB_EXTENSION (user_data);
+       WebKitDOMDocument *document;
+       WebKitWebExtension *web_extension = extension->priv->wk_extension;
+       WebKitWebPage *web_page;
 
-       if (g_strcmp0 (interface_name, EVOLUTION_WEB_EXTENSION_INTERFACE) != 0)
+       if (g_strcmp0 (interface_name, E_WEB_EXTENSION_INTERFACE) != 0)
                return;
 
        if (g_strcmp0 (method_name, "ReplaceLocalImageLinks") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -309,7 +173,8 @@ handle_method_call (GDBusConnection *connection,
                gchar *html_content;
 
                g_variant_get (parameters, "(t)", &page_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -317,14 +182,13 @@ handle_method_call (GDBusConnection *connection,
                html_content = e_dom_utils_get_document_content_html (document);
 
                g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(s)", html_content));
-
-               g_free (html_content);
+                       invocation, g_variant_new_take_string (html_content);
        } else if (g_strcmp0 (method_name, "GetSelectionContentHTML") == 0) {
                gchar *html_content;
 
                g_variant_get (parameters, "(t)", &page_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -332,14 +196,13 @@ handle_method_call (GDBusConnection *connection,
                html_content = e_dom_utils_get_selection_content_html (document);
 
                g_dbus_method_invocation_return_value (invocation,
-                       g_variant_new ("(s)", html_content));
-
-               g_free (html_content);
+                       invocation, g_variant_new_take_string (html_content);
        } else if (g_strcmp0 (method_name, "GetSelectionContentText") == 0) {
                gchar *text_content;
 
                g_variant_get (parameters, "(t)", &page_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -347,9 +210,7 @@ handle_method_call (GDBusConnection *connection,
                text_content = e_dom_utils_get_selection_content_html (document);
 
                g_dbus_method_invocation_return_value (invocation,
-                       g_variant_new ("(s)", text_content));
-
-               g_free (text_content);
+                       invocation, g_variant_new_take_string (text_content);
        } else if (g_strcmp0 (method_name, "AddCSSRuleIntoStyleSheet") == 0) {
                const gchar *style_sheet_id, *selector, *style;
 
@@ -358,7 +219,8 @@ handle_method_call (GDBusConnection *connection,
                        "(t&s&s&s)",
                        &page_id, &style_sheet_id, &selector, &style);
 
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -370,7 +232,8 @@ handle_method_call (GDBusConnection *connection,
                const gchar *style_sheet_id;
 
                g_variant_get (parameters, "(t&s)", &page_id, &style_sheet_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -380,7 +243,8 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EABContactFormatterBindDOM") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -390,7 +254,8 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EMailDisplayBindDOM") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -404,7 +269,8 @@ handle_method_call (GDBusConnection *connection,
                gboolean element_exists;
 
                g_variant_get (parameters, "(t&s)", &page_id, &element_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -417,7 +283,8 @@ handle_method_call (GDBusConnection *connection,
                gchar *element_name;
 
                g_variant_get (parameters, "(t)", &page_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -425,14 +292,13 @@ handle_method_call (GDBusConnection *connection,
                element_name = e_dom_utils_get_active_element_name (document);
 
                g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(s)", element_name));
-
-               g_free (element_name);
+                       invocation, g_variant_new_take_string (element_name));
        } else if (g_strcmp0 (method_name, "EMailPartHeadersBindDOMElement") == 0) {
                const gchar *element_id;
 
                g_variant_get (parameters, "(t&s)", &page_id, &element_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -444,7 +310,8 @@ handle_method_call (GDBusConnection *connection,
                const gchar *element_id;
 
                g_variant_get (parameters, "(t&s)", &page_id, &element_id);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -461,7 +328,8 @@ handle_method_call (GDBusConnection *connection,
                        "(t&s&s&s)",
                        &page_id, &button_id, &html_label, &access_key);
 
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -474,7 +342,8 @@ handle_method_call (GDBusConnection *connection,
                const gchar *src, *button_id;
 
                g_variant_get (parameters, "(t&s&s)", &page_id, &button_id, &src);
-               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (
+                       invocation, web_extension, page_id);
                if (!web_page)
                        return;
 
@@ -494,12 +363,13 @@ handle_get_property (GDBusConnection *connection,
                      GError **error,
                      gpointer user_data)
 {
+       EWebExtension *extension = E_WEB_EXTENSION (user_data);
        GVariant *variant;
 
        if (g_strcmp0 (property_name, "NeedInput") == 0) {
-               variant = g_variant_new_boolean (need_input);
+               variant = g_variant_new_boolean (extension->priv->need_input);
        } else if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
-               variant = g_variant_new_boolean (force_image_load);
+               variant = g_variant_new_boolean (extension->priv->force_image_load);
        }
 
        return variant;
@@ -515,6 +385,7 @@ handle_set_property (GDBusConnection *connection,
                      GError **error,
                      gpointer user_data)
 {
+       EWebExtension *extension = E_WEB_EXTENSION (user_data);
        GError *local_error = NULL;
        GVariantBuilder *builder;
 
@@ -523,27 +394,27 @@ handle_set_property (GDBusConnection *connection,
        if (g_strcmp0 (property_name, "NeedInput") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == need_input)
+               if (value == extension->priv->need_input)
                        goto exit;
 
-               need_input = value;
+               extension->priv->need_input = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "NeedInput",
-                       g_variant_new_boolean (need_input));
+                       g_variant_new_boolean (value));
        } else if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
                gboolean value = g_variant_get_boolean (variant);
 
-               if (value == force_image_load)
+               if (value == extension->priv->force_image_load)
                        goto exit;
 
-               force_image_load = value;
+               extension->priv->force_image_load = value;
 
                g_variant_builder_add (builder,
                        "{sv}",
                        "ForceImageLoad",
-                       g_variant_new_boolean (force_image_load));
+                       g_variant_new_boolean (value));
        }
 
        g_dbus_connection_emit_signal (connection,
@@ -573,64 +444,263 @@ static const GDBusInterfaceVTable interface_vtable = {
 };
 
 static void
-bus_acquired_cb (GDBusConnection *connection,
-                 const char *name,
-                 gpointer user_data)
+e_web_extension_dispose (GObject *object)
 {
-       guint registration_id;
-       GError *error = NULL;
-       static GDBusNodeInfo *introspection_data = NULL;
+       EWebExtension *extension = E_WEB_EXTENSION (object);
+
+       if (extension->priv->dbus_connection) {
+               g_dbus_connection_unregister_object (
+                       extension->priv->dbus_connection,
+                       extension->priv->registration_id);
+               extension->priv->registration_id = 0;
+               extension->priv->dbus_connection = NULL;
+       }
 
-       if (!introspection_data)
-               introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
-       registration_id =
-               g_dbus_connection_register_object (
-                       connection,
-                       EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
-                       introspection_data->interfaces[0],
-                       &interface_vtable,
-                       g_object_ref (user_data),
-                       g_object_unref,
-                       &error);
-
-       if (!registration_id) {
-               g_warning ("Failed to register object: %s\n", error->message);
-               g_error_free (error);
-       } else {
-               dbus_connection = connection;
-               g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&dbus_connection);
-
-               if (emd_global_http_cache == NULL) {
-                       emd_global_http_cache = camel_data_cache_new (
-                               e_get_user_cache_dir (), NULL);
-
-                       /* cache expiry - 2 hour access, 1 day max */
-                       camel_data_cache_set_expire_age (
-                               emd_global_http_cache, 24 * 60 * 60);
-                       camel_data_cache_set_expire_access (
-                               emd_global_http_cache, 2 * 60 * 60);
-               }
+       g_clear_object (&extension->priv->wk_extension);
+
+       G_OBJECT_CLASS (e_web_extension_parent_class)->dispose (object);
+}
+
+static void
+e_web_extension_class_init (EWebExtensionClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->dispose = e_web_extension_dispose;
+
+       g_type_class_add_private (object_class, sizeof(EWebExtensionPrivate));
+}
+
+static void
+e_web_extension_init (EWebExtension *extension)
+{
+       extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension, E_TYPE_WEB_EXTENSION, EWebExtensionPrivate);
+
+       extension->priv->need_input = FALSE;
+       extension->priv->force_image_load = FALSE;
+}
+
+static gpointer
+e_web_extension_create_instance(gpointer data)
+{
+       return g_object_new (E_TYPE_WEB_EXTENSION, NULL);
+}
+
+EWebExtension *
+e_web_extension_get (void)
+{
+       static GOnce once_init = G_ONCE_INIT;
+       return E_WEB_EXTENSION (g_once (&once_init, e_web_extension_create_instance, NULL));
+}
+
+static gboolean
+image_exists_in_cache (const gchar *image_uri)
+{
+       gchar *filename;
+       gchar *hash;
+       gboolean exists = FALSE;
+
+       g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
+
+       hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
+       filename = camel_data_cache_get_filename (
+               emd_global_http_cache, "http", hash);
+
+       if (filename != NULL) {
+               exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+               g_free (filename);
+       }
+
+       g_free (hash);
+
+       return exists;
+}
+
+static EMailImageLoadingPolicy
+get_image_loading_policy (void)
+{
+       GSettings *settings;
+       EMailImageLoadingPolicy image_policy;
+
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       image_policy = g_settings_get_enum (settings, "image-loading-policy");
+       g_object_unref (settings);
+
+       return image_policy;
+}
+
+static void
+redirect_http_uri (EWebExtension *extension,
+                   WebKitWebPage *web_page,
+                   WebKitURIRequest *request)
+{
+       const gchar *uri, *page_uri;
+       gchar *new_uri, *mail_uri, *enc;
+       SoupURI *soup_uri;
+       GHashTable *query;
+       gboolean image_exists;
+       EMailImageLoadingPolicy image_policy;
+
+       uri = webkit_uri_request_get_uri (request);
+       page_uri = webkit_web_page_get_uri (web_page);
+
+       /* Check Evolution's cache */
+       image_exists = image_exists_in_cache (uri);
+
+       /* If the URI is not cached and we are not allowed to load it
+        * then redirect to invalid URI, so that webkit would display
+        * a native placeholder for it. */
+       image_policy = get_image_loading_policy ();
+       if (!image_exists && !extension->priv->force_image_load &&
+           (image_policy == E_MAIL_IMAGE_LOADING_POLICY_NEVER)) {
+               webkit_uri_request_set_uri (request, "about:blank");
+               return;
+       }
+
+       new_uri = g_strconcat ("evo-", uri, NULL);
+       mail_uri = g_strndup (page_uri, strstr (page_uri, "?") - page_uri);
+
+       soup_uri = soup_uri_new (new_uri);
+       if (soup_uri->query)
+               query = soup_form_decode (soup_uri->query);
+       else
+               query = g_hash_table_new_full (
+                       g_str_hash, g_str_equal,
+                       g_free, g_free);
+
+       enc = soup_uri_encode (mail_uri, NULL);
+       g_hash_table_insert (query, g_strdup ("__evo-mail"), enc);
+
+       if (extension->priv->force_image_load) {
+               g_hash_table_insert (
+                       query,
+                       g_strdup ("__evo-load-images"),
+                       g_strdup ("true"));
        }
+
+       g_free (mail_uri);
+
+       soup_uri_set_query_from_form (soup_uri, query);
+       g_free (new_uri);
+
+       new_uri = soup_uri_to_string (soup_uri, FALSE);
+
+       webkit_uri_request_set_uri (request, new_uri);
+
+       soup_uri_free (soup_uri);
+       g_hash_table_unref (query);
+       g_free (new_uri);
+}
+
+static gboolean
+web_page_send_request_cb (WebKitWebPage *web_page,
+                          WebKitURIRequest *request,
+                          WebKitURIResponse *redirected_response,
+                          EWebExtension *extension)
+{
+       const char *request_uri;
+       const char *page_uri;
+       gboolean uri_is_http;
+
+       request_uri = webkit_uri_request_get_uri (request);
+       page_uri = webkit_web_page_get_uri (web_page);
+
+       /* Always load the main resource. */
+       if (g_strcmp0 (request_uri, page_uri) == 0)
+               return FALSE;
+
+       uri_is_http =
+               g_str_has_prefix (request_uri, "http:") ||
+               g_str_has_prefix (request_uri, "https:") ||
+               g_str_has_prefix (request_uri, "evo-http:") ||
+               g_str_has_prefix (request_uri, "evo-https:");
+
+       if (uri_is_http)
+               redirect_http_uri (extension, web_page, request);
+
+       return FALSE;
+}
+
+static void
+web_page_document_loaded_cb (WebKitWebPage *web_page,
+                             gpointer user_data)
+{
+
 }
 
-/* Forward declaration */
-G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *extension);
+static void
+web_page_created_cb (WebKitWebExtension *wk_extension,
+                     WebKitWebPage *web_page,
+                     EWebExtension *extension)
+{
+       g_signal_connect_object (
+               web_page, "send-request",
+               G_CALLBACK (web_page_send_request),
+               extension, 0);
+
+       g_signal_connect_object (
+               web_page, "document-loaded",
+               G_CALLBACK (web_page_document_loaded),
+               extension, 0);
+
+}
 
-G_MODULE_EXPORT void
-webkit_web_extension_initialize (WebKitWebExtension *extension)
+void
+e_web_extension_initialize (EWebExtension *extension,
+                            WebKitWebExtension *wk_extension)
 {
+       g_return_if_fail (E_IS_WEB_EXTENSION (extension));
+
+       extension->priv->wk_extension = g_object_ref (wk_extension);
+
+       if (emd_global_http_cache == NULL) {
+               emd_global_http_cache = camel_data_cache_new (
+                       e_get_user_cache_dir (), NULL);
+
+               /* cache expiry - 2 hour access, 1 day max */
+               camel_data_cache_set_expire_age (
+                       emd_global_http_cache, 24 * 60 * 60);
+               camel_data_cache_set_expire_access (
+                       emd_global_http_cache, 2 * 60 * 60);
+       }
+
        g_signal_connect (
-               extension, "page-created",
-               G_CALLBACK (web_page_created_callback),
-               NULL);
-
-       g_bus_own_name (
-               G_BUS_TYPE_SESSION,
-               EVOLUTION_WEB_EXTENSION_SERVICE_NAME,
-               G_BUS_NAME_OWNER_FLAGS_NONE,
-               bus_acquired_cb,
-               NULL, NULL,
-               g_object_ref (extension),
-               g_object_unref);
+               wk_extension, "page-created",
+               G_CALLBACK (web_page_created_cb), extension);
+}
+
+void
+e_web_extension_dbus_register (EWebExtension *extension,
+                               GDBusConnection *connection)
+{
+       GError *error = NULL;
+       static GDBusNodeInfo *introspection_data = NULL;
+
+       g_return_if_fail (E_IS_WEB_EXTENSION (extension));
+       g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
+
+       if (!introspection_data) {
+               introspection_data =
+                       g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+
+               extension->priv->registration_id =
+                       g_dbus_connection_register_object (
+                               connection,
+                               E_WEB_EXTENSION_OBJECT_PATH,
+                               introspection_data->interfaces[0],
+                               &interface_vtable,
+                               extension,
+                               NULL,
+                               &error);
+
+               if (!extension->priv->registration_id) {
+                       g_warning ("Failed to register object: %s\n", error->message);
+                       g_error_free (error);
+               } else {
+                       extension->priv->dbus_connection = connection;
+                       g_object_add_weak_pointer (
+                               G_OBJECT (connection),
+                               (gpointer *)&extension->priv->dbus_connection);
+               }
+       }
 }
diff --git a/web-extensions/e-web-extension.h b/web-extensions/e-web-extension.h
new file mode 100644
index 0000000..d54ea96
--- /dev/null
+++ b/web-extensions/e-web-extension.h
@@ -0,0 +1,76 @@
+/*
+ * e-web-extension.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_WEB_EXTENSION_H
+#define E_WEB_EXTENSION_H
+
+#include <webkit2/webkit-web-extension.h>
+#include <glib-object.h>
+
+/* Standard GObject macros */
+#define E_TYPE_WEB_EXTENSION \
+       (e_web_extension_get_type ())
+#define E_WEB_EXTENSION(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_WEB_EXTENSION, EWebExtension))
+#define E_WEB_EXTENSION_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_WEB_EXTENSION, EWebExtensionClass))
+#define E_IS_WEB_EXTENSION(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_WEB_EXTENSION))
+#define E_IS_WEB_EXTENSION_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_WEB_EXTENSION))
+#define E_WEB_EXTENSION_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_WEB_EXTENSION, EWebExtensionClass))
+
+#define E_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.WebExtension"
+#define E_WEB_EXTENSION_OBJECT_PATH  "/org/gnome/Evolution/WebExtension"
+#define E_WEB_EXTENSION_INTERFACE    "org.gnome.Evolution.WebExtension"
+
+G_BEGIN_DECLS
+
+typedef struct _EWebExtension EWebExtension;
+typedef struct _EWebExtensionClass EWebExtensionClass;
+typedef struct _EWebExtensionPrivate EWebExtensionPrivate;
+
+struct _EWebExtension {
+       GObject parent;
+       EWebExtensionPrivate *priv;
+};
+
+struct _EWebExtensionClass
+{
+       GObjectClass parent_class;
+};
+
+GType          e_web_extension_get_type        (void) G_GNUC_CONST;
+
+EWebExtension *        e_web_extension_get             (void);
+
+void           e_web_extension_initialize      (EWebExtension *extension,
+                                                WebKitWebExtension *wk_extension);
+
+void           e_web_extension_dbus_register   (EWebExtension *extension,
+                                                GDBusConnection *connection);
+
+G_END_DECLS
+
+#endif /* E_WEB_EXTENSION_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]