diff --git a/lib/exe/spellcheck.php b/lib/exe/spellcheck.php
index 7147673b700323eaa560fc9e04f304458cc0c16b..86e0e438e88e8cb1edbfdfd0f2063cb895059c82 100644
--- a/lib/exe/spellcheck.php
+++ b/lib/exe/spellcheck.php
@@ -105,12 +105,6 @@ function spell_check() {
   // we need the text as array later
   $data = explode("\n",$string);
 
-
-  // keep some words from being checked (use blanks to preserve the offset)
-  // FIXME doesn't work yet... however with the used html mode of aspell this isn't really needed
-/*  $string = preg_replace('!<\?(code|del|file)( \+)?>!e','spellclean(\\1)',$string); */
-//  $string = preg_replace('!()!e','spellclean(\\1)',$string);
-
   // don't check links and medialinks for spelling errors
   $string = preg_replace('/\{\{[^\|]*\|?(.*)\}\}/e','spaceslink("\\0","\\1")',$string);
   $string = preg_replace('/\[\[[^\|]*\|?(.*)\]\]/e','spaceslink("\\0","\\1")',$string);
@@ -173,8 +167,10 @@ function spell_check() {
     $string = '0'.join('<br />',$data);
   }
 
-  // encode multibyte chars as entities for broken Konqueror
-  $string = utf8_tohtml($string);
+  if(!$_POST['utf8']){
+    // encode multibyte chars as entities for broken Konqueror
+    $string = utf8_tohtml($string);
+  }
 
   //output 
   print $string;
@@ -193,8 +189,11 @@ function spell_formatword($word,$suggestions=null){
     $suggestions = array_slice($suggestions,0,7);
     $suggestions = array_map('htmlspecialchars',$suggestions);
 
-    //konqueror's broken UTF-8 handling needs this
-    $suggestions = array_map('utf8_tohtml',$suggestions);
+    if(!$_POST['utf8']){
+      //konqueror's broken UTF-8 handling needs this
+      $suggestions = array_map('utf8_tohtml',$suggestions);
+    }
+
     $suggestions = array_map('addslashes',$suggestions);
 
     $sug = ",'".join("','",$suggestions)."'"; // build javascript args
@@ -226,16 +225,25 @@ function spell_resume(){
   // restore quoted special chars
   $text = unhtmlspecialchars($text);
 
-  // but protect '&' (gets removed in JS later)
-  $text = str_replace('&','&amp;',$text);
-  // encode multibyte chars as entities for broken Konqueror
-  $text = utf8_tohtml($text);
-
+  // check if UTF-8 is accepted
+  if(!$_POST['utf8']){
+    // protect '&' (gets removed in JS later)
+    $text = str_replace('&','&amp;',$text);
+    // encode multibyte chars as entities for broken Konqueror
+    $text = utf8_tohtml($text);
+  }
 
   // output
   print $text;
 }
 
+/**
+ * Just send data back as received for UTF-8 testing
+ */
+function spell_utf8test(){
+  print $_POST['data'];
+}
+
 /**
  * Reverse htmlspecialchars
  *
diff --git a/lib/scripts/spellcheck.js b/lib/scripts/spellcheck.js
index 3df9a25ffb651544874683360fb2161aaeb78983..9c33f12c8c04128c63ece01c02f4f1ce804928c0 100644
--- a/lib/scripts/spellcheck.js
+++ b/lib/scripts/spellcheck.js
@@ -124,6 +124,7 @@ function spellButton(imageFile, speedTip, funcCall, accessKey) {
  */
 function ajax_spell_class(){
   this.inited = false;
+  this.utf8ok = 1;
   this.handler = DOKU_BASE+'lib/exe/spellcheck.php';
   // to hold the page objects (initialized with init())
   this.textboxObj = null;
@@ -153,7 +154,7 @@ function ajax_spell_class(){
     this.inited = true;
 
     // check for AJAX availability
-    var ajax = new sack();
+    var ajax = new sack(this.handler);
     if(ajax.failed) return;
 
     // get Elements
@@ -171,13 +172,11 @@ function ajax_spell_class(){
     this.txtNoSug = txtNoSug;
     this.txtChange= txtChange;
 
-    // register click event
-    document.onclick = this.docClick;
-
-    // register focus event
-    this.textboxObj.onfocus = this.setState;
-
-    this.setState('start');    
+    // start UTF-8 compliance test - send an UTF-8 char and see what comes back
+    ajax.AjaxFailedAlert = '';
+    ajax.encodeURIString = false;
+    ajax.onCompletion    = this.initReady;
+    ajax.runAJAX('call=utf8test&data='+encodeURIComponent('ü'));
   }
 
   /**
@@ -297,6 +296,30 @@ function ajax_spell_class(){
 
   // --- Callbacks ---
 
+  /**
+   * Callback. Called after the object was initialized and UTF-8 tested
+   * Inside the callback 'this' is the SACK object!!
+   *
+   * @author Andreas Gohr <andi@splitbrain.org>
+   */
+  this.initReady = function(){
+    var data = this.response;
+
+    //test for UTF-8 compliance (will fail for konqueror)
+    if(data != 'ü'){
+      ajax_spell.utf8ok = 0;
+    }
+
+    // register click event
+    document.onclick = ajax_spell.docClick;
+
+    // register focus event
+    ajax_spell.textboxObj.onfocus = ajax_spell.setState;
+
+    // get started
+    ajax_spell.setState('start');    
+  }
+
   /**
    * Callback. Called after finishing spellcheck.
    * Inside the callback 'this' is the SACK object!!
@@ -309,11 +332,15 @@ function ajax_spell_class(){
         data  = data.substring(1);
     if(error == '1'){
       ajax_spell.setState('stop');
-      // convert numeric entities back to UTF-8
-      data = data.replace(/&#(\d+);/g,
-                          function(whole,match1) {
-                            return String.fromCharCode(+match1);
-                          });
+
+      // convert numeric entities back to UTF-8 if needed
+      if(!ajax_spell.utf8ok){
+        data = data.replace(/&#(\d+);/g,
+                            function(whole,match1) {
+                              return String.fromCharCode(+match1);
+                            });
+      }
+
       // replace textbox through div
       ajax_spell.showboxObj.innerHTML     = data;
       ajax_spell.showboxObj.style.width   = ajax_spell.textboxObj.style.width;
@@ -340,15 +367,16 @@ function ajax_spell_class(){
   this.stop = function(){
     var data = this.response;
 
-    // convert numeric entities back to UTF-8
-    data = data.replace(/&#(\d+);/g,
+    // convert numeric entities back to UTF-8 if needed
+    if(!ajax_spell.utf8ok){
+      data = data.replace(/&#(\d+);/g,
                           function(whole,match1) {
                             return String.fromCharCode(+match1);
-                        });
-    // now remove &amp; protection
-    data = data.replace(/&amp;/g,'&'); 
+                          });
+      // now remove &amp; protection
+      data = data.replace(/&amp;/g,'&'); 
+    }
 
-    ajax_spell.setState('start');
     // replace div with textbox again
     ajax_spell.textboxObj.value         = data;
     ajax_spell.textboxObj.disabled      = false;
@@ -356,6 +384,7 @@ function ajax_spell_class(){
     ajax_spell.textboxObj.style.display = 'block';
     ajax_spell.editbarObj.style.visibility = 'visible';
     ajax_spell.showboxObj.innerHTML     = '';
+    ajax_spell.setState('start');
   }
 
   // --- Callers ---
@@ -372,7 +401,8 @@ function ajax_spell_class(){
     ajax.AjaxFailedAlert = '';
     ajax.encodeURIString = false;
     ajax.onCompletion    = this.start;
-    ajax.runAJAX('call=check&data='+encodeURIComponent(this.textboxObj.value));
+    ajax.runAJAX('call=check&utf8='+ajax_spell.utf8ok+
+                 '&data='+encodeURIComponent(this.textboxObj.value));
   }
 
   /**
@@ -388,7 +418,8 @@ function ajax_spell_class(){
       ajax.AjaxFailedAlert = '';
       ajax.encodeURIString = false;
       ajax.onCompletion    = this.stop;
-      ajax.runAJAX('call=resume&data='+encodeURIComponent(text));
+      ajax.runAJAX('call=resume&utf8='+ajax_spell.utf8ok+
+                   '&data='+encodeURIComponent(text));
     }
   }