diff --git a/conf/mime.conf b/conf/mime.conf
index 26657a89510154320f90a551e7661edfeebcc1ec..0be3b1aa8ffdd4d5af87d47e146654ff3d9b5d9a 100644
--- a/conf/mime.conf
+++ b/conf/mime.conf
@@ -1,15 +1,22 @@
 #Add extensions and mimetypes of files you want to allow to upload here
 
-jpg			image/jpeg 
-jpeg		image/jpeg 
-gif			image/gif
-png			image/png
-tgz			application/octet-stream
-tar			application/octet-stream
-gz			application/octet-stream
-zip			application/octet-stream
-pdf			application/octet-stream  #FIXME
-txt			text/plain
-html		text/html
-htm			text/html
+jpg     image/jpeg 
+jpeg    image/jpeg 
+gif     image/gif
+png     image/png
+tgz     application/octet-stream
+tar     application/x-gtar
+gz      application/octet-stream
+zip     application/zip
+pdf     application/pdf
+txt     text/plain
+html    text/html
+htm     text/html
+ps      application/postscript
+doc     application/msword
+xls     application/msexcel
+ppt     application/mspowerpoint
+rtf     text/rtf
+xml     text/xml
+swf     application/x-shockwave-flash
 
diff --git a/data/wiki/syntax.txt b/data/wiki/syntax.txt
index b73be38a98d0557d01ce08713bc682cbf1186d03..0d5fb1345c3fa7c7cefd9233abdc27054d5d3630 100644
--- a/data/wiki/syntax.txt
+++ b/data/wiki/syntax.txt
@@ -89,9 +89,9 @@ Notes:
 
 You can also use an image to link to another internal or external page by combining the syntax for links and images (see below) like this:
 
-  [[http://www.php.net|{{wiki:php-powered.png}}]]
+  [[http://www.php.net|{{wiki:dokuwiki-128.png}}]]
 
-[[http://www.php.net|{{wiki:php-powered.png}}]]
+[[http://www.php.net|{{wiki:dokuwiki-128.png}}]]
 
 Please note: The image formatting is the only formatting syntax accepted in link names.
 
@@ -121,36 +121,37 @@ By using four or more dashes, you can make a horizontal line:
 
 You can include external and internal [[doku>images]] with curly brackets. Optionally you can specify the size of them.
 
-Real size:                        {{wiki:php-powered.png}}
+Real size:                        {{wiki:dokuwiki-128.png}}
 
-Resize to given width:            {{wiki:php-powered.png?100}}
+Resize to given width:            {{wiki:dokuwiki-128.png?100}}
 
-Resize to given width and height: {{wiki:php-powered.png?100x100}}
+Resize to given width and height: {{wiki:dokuwiki-128.png?100x200}}
 
 Resized external image:           {{http://de3.php.net/images/php.gif?100x100}}
 
-  Real size:                        {{wiki:php-powered.png}}
-  Resize to given width:            {{wiki:php-powered.png?100}}
-  Resize to given width and height: {{wiki:php-powered.png?100x100}}
+  Real size:                        {{wiki:dokuwiki-128.png}}
+  Resize to given width:            {{wiki:dokuwiki-128.png?100}}
+  Resize to given width and height: {{wiki:dokuwiki-128.png?100x200}}
   Resized external image:           {{http://de3.php.net/images/php.gif?100x100}}
 
+
 By using left or right whitespaces you can choose the alignment
 
-{{ wiki:php-powered.png}}
+{{ wiki:dokuwiki-128.png}}
 
-{{wiki:php-powered.png }}
+{{wiki:dokuwiki-128.png }}
 
-{{ wiki:php-powered.png }}
+{{ wiki:dokuwiki-128.png }}
 
-  {{ wiki:php-powered.png}}
-  {{wiki:php-powered.png }}
-  {{ wiki:php-powered.png }}
+  {{ wiki:dokuwiki-128.png}}
+  {{wiki:dokuwiki-128.png }}
+  {{ wiki:dokuwiki-128.png }}
 
 Of course, you can add a title (displayed as a tooltip by most browsers), too.
 
-{{ wiki:php-powered.png |This is the caption}}
+{{ wiki:dokuwiki-128.png |This is the caption}}
 
-  {{ wiki:php-powered.png |This is the caption}}
+  {{ wiki:dokuwiki-128.png |This is the caption}}
 
 If you specify a filename (external or internal) that is not an image (''gif,jpeg,png''), then it will be displayed as a link instead.
 
diff --git a/fetch.php b/fetch.php
index cd35b9be680c2c0c4d61e7f713c6732886b6b6f7..b991f14ec3c16fc5a525a28181fd18a5d3e1e224 100644
--- a/fetch.php
+++ b/fetch.php
@@ -18,10 +18,8 @@
 	$CACHE  = calc_cache($_REQUEST['cache']);
 	$WIDTH  = $_REQUEST['w'];
 	$HEIGHT = $_REQUEST['h'];
-  $EXT    = media_extension($MEDIA);
-  if($EXT !== false){
-    $MIME = $mimetypes[$EXT];
-  }else{
+  list($EXT,$MIME) = mimetype($MEDIA);
+  if($EXT === false){
     $EXT  = 'unknown';
     $MIME = 'application/octet-stream';
   }
diff --git a/inc/parser/action.php b/inc/parser/action.php
index 4e971ed4a52ad30297a7253db67d5a178f1357f5..3935bbeaef21f3dc7ce445d2b192574d1939a2fb 100644
--- a/inc/parser/action.php
+++ b/inc/parser/action.php
@@ -95,10 +95,35 @@ function render_as_xhtml($instructions){
   return $Renderer->doc;
 }
 
+/**
+ * Returns a full media id
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @todo move to utils? 
+ */
+function resolve_mediaid(&$page,&$exists){
+  global $ID;
+  global $conf;
+  $ns = getNS($ID);
+  //if links starts with . add current namespace
+  if($page{0} == '.'){
+    $page = $ns.':'.substr($page,1);
+  }
+
+  //if link contains no namespace. add current namespace (if any)
+  if($ns !== false && strpos($page,':') === false){
+    $page = $ns.':'.$page;
+  }
+
+  $page   = cleanID($page);
+  $file   = mediaFN($page);
+  $exists = @file_exists($file);
+}
+
 /**
  * Returns a full page id
  *
- * @todo move to renderer? 
+ * @todo move to utils? 
  */
 function resolve_pageid(&$page,&$exists){
   global $ID;
diff --git a/inc/parser/handler.php b/inc/parser/handler.php
index 75020059ea6f5528f9138511c4ab4b4f77e9635e..108a522a5154c98cbfc04b37d44c8c05985ed38c 100644
--- a/inc/parser/handler.php
+++ b/inc/parser/handler.php
@@ -532,62 +532,47 @@ function Doku_Handler_Parse_Media($match) {
     if ( !isset($link[1]) ) {
         $link[1] = NULL;
     }
-    
-    // img src url from params
-    // What if it's an external image where URL contains '?' char?
-    $src = preg_split('/\?/u',$link[0],2);
-    
-    // Strip any alignment whitespace
-    $src[0] = trim($src[0]);
-    
-    // Check for width, height and caching params
-    if ( isset($src[1]) ) {
-        
-        if(preg_match('#(\d*)(x(\d*))?#i',$src[1],$matches)){
-            
-            if(isset($matches[1])) {
-                $width = $matches[1];
-            } else {
-                $width = NULL;
-            }
-            
-            if(isset($matches[3])) {
-                $height = $matches[3];
-            } else {
-                $height = NULL;
-            }
-            
-            $cache = !(bool)preg_match('/nocache/i',$src[1]);
-        }
-        
-    } else {
-        $width = NULL;
-        $height = NULL;
-        $cache = TRUE;
+   
+    //remove aligning spaces
+    $link[0] = trim($link[0]);
+ 
+    //split into src and parameters (using the very last questionmark)
+    $pos = strrpos($link[0], '?');
+    if($pos !== false){
+        $src   = substr($link[0],0,$pos);
+        $param = substr($link[0],$pos+1);
+    }else{
+        $src   = $link[0];
+        $param = '';
     }
-    
-    // Check whether this is a local or remote image
-    if ( substr($src[0],0,4) == 'http' ) {
-        $call = 'external';
-    } else {
-        $call = 'internal';
+
+    //parse width and height
+    if(preg_match('#(\d+)(x(\d+))?#i',$param,$size)){
+        ($size[1]) ? $w = $size[1] : $w = NULL;
+        ($size[3]) ? $h = $size[3] : $h = NULL;
     }
-    
-    // Check this is actually an image...
-    if ( !preg_match('/\.(gif|png|jpe?g)$/',$src[0] ) ) {
-        // Security implications?...
-        $call .= 'link';
+
+    //get caching command
+    if (preg_match('/(nocache|recache)/i',$param,$cachemode)){
+        $cache = $cachemode[1];
+    }else{
+        $cache = 'cache';
+    }
+   
+    // Check whether this is a local or remote image
+    if ( preg_match('#^(https?|ftp)#i',$src) ) {
+        $call = 'externalmedia';
     } else {
-        $call .= 'media';
+        $call = 'internalmedia';
     }
-    
+
     $params = array(
         'type'=>$call,
-        'src'=>$src[0],
+        'src'=>$src,
         'title'=>$link[1],
         'align'=>$align,
-        'width'=>$width,
-        'height'=>$height,
+        'width'=>$w,
+        'height'=>$h,
         'cache'=>$cache,
     );
     
@@ -1497,4 +1482,4 @@ class Doku_Handler_Toc {
 }
 
 
-//Setup VIM: ex: et ts=2 enc=utf-8 :
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php
index b5c2b5d8dc7a597cca056828731cc898d19d9bb1..377b514be7ab5104935af16076b91116002b7ace 100644
--- a/inc/parser/xhtml.php
+++ b/inc/parser/xhtml.php
@@ -39,7 +39,7 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     }
     
     function document_end() {
-				// add button for last section if any
+        // add button for last section if any
         if($this->lastsec) $this->__secedit($this->lastsec,'');
         
         if ( count ($this->footnotes) > 0 ) {
@@ -93,13 +93,13 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     
     function header($text, $level, $pos) {
         global $conf;
-				//handle section editing 
+        //handle section editing 
         if($level <= $conf['maxseclevel']){
             // add button for last section if any
             if($this->lastsec) $this->__secedit($this->lastsec,$pos-1);
-						// remember current position
-	          $this->lastsec = $pos;
-				}
+            // remember current position
+            $this->lastsec = $pos;
+        }
 
         echo DOKU_LF.'<a name="'.$this->__headerToLink($text).'"></a><h'.$level.'>';
         echo $this->__xmlEntities($text);
@@ -247,23 +247,23 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     /**
     */
     function php($text) {
-				global $conf;
-				if($conf['phpok']){
-						eval($text);
+        global $conf;
+        if($conf['phpok']){
+            eval($text);
         }else{
-					  $this->file($text);
-				}
+            $this->file($text);
+        }
     }
     
     /**
     */
     function html($text) {
-				global $conf;
+        global $conf;
         if($conf['htmlok']){
-					echo $text;
-				}else{
-	        $this->file($text);
-				}
+          echo $text;
+        }else{
+          $this->file($text);
+        }
     }
     
     function preformatted($text) {
@@ -291,7 +291,7 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     /**
     */
     function code($text, $language = NULL) {
-				global $conf;
+        global $conf;
     
         if ( is_null($language) ) {
             $this->preformatted($text);
@@ -302,7 +302,7 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
             $geshi->enable_classes();
             $geshi->set_header_type(GESHI_HEADER_PRE);
             $geshi->set_overall_class('code');
-						$geshi->set_link_target($conf['target']['extern']);
+            $geshi->set_link_target($conf['target']['extern']);
             
             $text = $geshi->parse_code();
             echo $text;
@@ -378,7 +378,7 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     /**
     */
     function camelcaselink($link) {
-    	$this->internallink($link,$link); 
+      $this->internallink($link,$link); 
     }
     
     /**
@@ -386,7 +386,7 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     * @TODO correct attributes
     */
     function internallink($id, $name = NULL) {
-				global $conf;
+        global $conf;
 
         $name = $this->__getLinkTitle($name, $this->__simpleTitle($id), $isImage);
         resolve_pageid($id,$exists);
@@ -401,7 +401,7 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
             $class='media';
         }
         
-				//prepare for formating
+        //prepare for formating
         $link['target'] = $conf['target']['wiki'];
         $link['style']  = '';
         $link['pre']    = '';
@@ -579,67 +579,103 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     }
     
     /**
-    * @TODO Resolve namespaces
-    * @TODO Add image caching
-    * @TODO Remove hard coded link to splitbrain.org
-    */
-    function internalmedia (
-        $src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL
-        ) {
-        
-        // Sort out the namespace here...
-        if ( strpos($src,':') ) {
-            $src = explode(':',$src);
-            $src = $src[1];
-        }
-        echo '<img class="media" src="http://wiki.splitbrain.org/media/wiki/'.$this->__xmlEntities($src).'"';
-        
-        if ( !is_null($title) ) {
-            echo ' title="'.$this->__xmlEntities($title).'"';
-        }
-        
-        if ( !is_null($align) ) {
-            echo ' align="'.$align.'"';
-        }
-        
-        if ( !is_null($width) ) {
-            echo ' width="'.$this->__xmlEntities($width).'"';
-        }
-        
-        if ( !is_null($height) ) {
-            echo ' height="'.$this->__xmlEntities($height).'"';
-        }
-        
-        echo '/>'; 
+     * @todo don't add link for flash
+     */
+    function internalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
+                            $height=NULL, $cache=NULL) {
         
+        resolve_mediaid($src, $exists);
+
+        $this->internallink($src, $title =
+                                    array( 'type'   => 'internalmedia',
+                                           'src'    => $src,
+                                           'title'  => $title,
+                                           'align'  => $align,
+                                           'width'  => $width,
+                                           'height' => $height,
+                                           'cache'  => $cache,
+                                           'link'   => $link ));
     }
     
     /**
-    * @TODO Add image caching
-    */
-    function externalmedia (
-        $src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL
-        ) {
-        
-        echo '<img class="media" src="'.$this->__xmlEntities($src).'"';
-        
-        if ( !is_null($title) ) {
-            echo ' title="'.$this->__xmlEntities($title).'"';
-        }
-        
-        if ( !is_null($align) ) {
-            echo ' align="'.$align.'"';
-        }
+     * @todo don't add link for flash
+     */
+    function externalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
+                            $height=NULL, $cache=NULL) {
+
+        $this->externallink($src, $title =
+                                    array( 'type'   => 'externalmedia',
+                                           'src'    => $src,
+                                           'title'  => $title,
+                                           'align'  => $align,
+                                           'width'  => $width,
+                                           'height' => $height,
+                                           'cache'  => $cache,
+                                           'link'   => $link ));
+    }
+
+    /**
+     * Renders internal and external media
+     * 
+     * @author Andreas Gohr <andi@splitbrain.org>
+     * @todo   handle center align
+     */
+    function __media ($src, $title=NULL, $align=NULL, $width=NULL,
+                      $height=NULL, $cache=NULL) {
+
+        $ret = '';
+
+        list($ext,$mime) = mimetype($src);
+        if(substr($mime,0,5) == 'image'){
+            //add image tag
+            $ret .= '<img class="media" src="'.
+                    DOKU_BASE.'fetch.php?media='.urlencode($src).
+                    '&amp;w='.$width.'&amp;h='.$height.
+                    '&amp;cache='.$cache.'"';
+        
+            if (!is_null($title))
+                $ret .= ' title="'.$this->__xmlEntities($title).'"';
+            
         
-        if ( !is_null($width) ) {
-            echo ' width="'.$this->__xmlEntities($width).'"';
-        }
+            if (!is_null($align))
+                $ret .= ' align="'.$align.'"'; #FIXME use class!
+          
+            if ( !is_null($width) )
+                $ret .= ' width="'.$this->__xmlEntities($width).'"';
         
-        if ( !is_null($height) ) {
-            echo ' height="'.$this->__xmlEntities($height).'"';
+            if ( !is_null($height) )
+                $ret .= ' height="'.$this->__xmlEntities($height).'"';
+
+            $ret .= ' />'; 
+
+        }elseif($mime == 'application/x-shockwave-flash'){
+            //FIXME default to a higher flash version?
+
+            $ret .= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'.
+                    ' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0"';
+            if ( !is_null($width) ) $ret .= ' width="'.$this->__xmlEntities($width).'"';
+            if ( !is_null($height) ) $ret .= ' height="'.$this->__xmlEntities($height).'"';
+            $ret .= '>'.DOKU_LF;
+            $ret .= '<param name="movie" value="'.DOKU_BASE.'fetch.php?media='.urlencode($src).'" />'.DOKU_LF;
+            $ret .= '<param name="quality" value="high" />'.DOKU_LF;
+            $ret .= '<embed src="'.DOKU_BASE.'fetch.php?media='.urlencode($src).'"'.
+                    ' quality="high" bgcolor="#000000"';
+            if ( !is_null($width) ) $ret .= ' width="'.$this->__xmlEntities($width).'"';
+            if ( !is_null($height) ) $ret .= ' height="'.$this->__xmlEntities($height).'"';
+            $ret .= ' type="application/x-shockwave-flash"'.
+                    ' pluginspage="http://www.macromedia.com/shockwave/download/index.cgi'.
+                    '?P1_Prod_Version=ShockwaveFlash"></embed>'.DOKU_LF;
+            $ret .= '</object>'.DOKU_LF;
+
+        }elseif(!is_null($title)){
+            // well at least we have a title to display
+            $ret .= $this->__xmlEntities($title);
+        }else{
+            // just show the source
+            $ret .= $this->__xmlEntities($src);
         }
-        
-        echo '/>'; 
+
+        return $ret;
     }
     
     // $numrows not yet implemented
@@ -699,27 +735,27 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
      * @author Andreas Gohr <andi@splitbrain.org>
      */
     function __formatLink($link){
-      //make sure the url is XHTML compliant (skip mailto)
-      if(substr($link['url'],0,7) != 'mailto:'){
-        $link['url'] = str_replace('&','&amp;',$link['url']);
-        $link['url'] = str_replace('&amp;amp;','&amp;',$link['url']);
-      }
-      //remove double encodings in titles
-      $link['title'] = str_replace('&amp;amp;','&amp;',$link['title']);
-
-      $ret  = '';
-      $ret .= $link['pre'];
-      $ret .= '<a href="'.$link['url'].'"';
-      if($link['class'])  $ret .= ' class="'.$link['class'].'"';
-      if($link['target']) $ret .= ' target="'.$link['target'].'"';
-      if($link['title'])  $ret .= ' title="'.$link['title'].'"';
-      if($link['style'])  $ret .= ' style="'.$link['style'].'"';
-      if($link['more'])   $ret .= ' '.$link['more'];
-      $ret .= '>';
-      $ret .= $link['name'];
-      $ret .= '</a>';
-      $ret .= $link['suf'];
-      return $ret;
+        //make sure the url is XHTML compliant (skip mailto)
+        if(substr($link['url'],0,7) != 'mailto:'){
+            $link['url'] = str_replace('&','&amp;',$link['url']);
+            $link['url'] = str_replace('&amp;amp;','&amp;',$link['url']);
+        }
+        //remove double encodings in titles
+        $link['title'] = str_replace('&amp;amp;','&amp;',$link['title']);
+
+        $ret  = '';
+        $ret .= $link['pre'];
+        $ret .= '<a href="'.$link['url'].'"';
+        if($link['class'])  $ret .= ' class="'.$link['class'].'"';
+        if($link['target']) $ret .= ' target="'.$link['target'].'"';
+        if($link['title'])  $ret .= ' title="'.$link['title'].'"';
+        if($link['style'])  $ret .= ' style="'.$link['style'].'"';
+        if($link['more'])   $ret .= ' '.$link['more'];
+        $ret .= '>';
+        $ret .= $link['name'];
+        $ret .= '</a>';
+        $ret .= $link['suf'];
+        return $ret;
     }
 
     /**
@@ -729,13 +765,13 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
      * @author Andreas Gohr <andi@splitbrain.org>
      */
     function __simpleTitle($name){
-			global $conf;
-      if($conf['useslash']){
-        $nssep = '[:;/]';
-      }else{
-        $nssep = '[:;]';
-      }
-      return preg_replace('!.*'.$nssep.'!','',$name);
+        global $conf;
+        if($conf['useslash']){
+            $nssep = '[:;/]';
+        }else{
+            $nssep = '[:;]';
+        }
+        return preg_replace('!.*'.$nssep.'!','',$name);
     }
 
     
@@ -758,9 +794,9 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     /**
      * Adds code for section editing button
      */
-		function __secedit($f, $t){
+    function __secedit($f, $t){
         print '<!-- SECTION ['.$f.'-'.$t.'] -->';
-		}
+    }
     
     function __getLinkTitle($title, $default, & $isImage) {
         $isImage = FALSE;
@@ -781,12 +817,20 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
     }
     
     /**
-    * @TODO Resolve namespace on internal images
-    * @TODO Remove hard coded url to splitbrain.org
-    * @TODO Image caching
-    */
+     * @TODO Resolve namespace on internal images
+     */
     function __imageTitle($img) {
-        
+
+        //FIXME resolve internal links
+
+        return $this->__media($img['src'],
+                              $img['title'],
+                              $img['align'],
+                              $img['width'],
+                              $img['height'],
+                              $img['cache']);
+
+/*        
         if ( $img['type'] == 'internalmedia' ) {
             
             // Resolve here...
@@ -826,6 +870,7 @@ class Doku_Renderer_XHTML extends Doku_Renderer {
         $imgStr .= '/>';
         
         return $imgStr;
+*/
     }
 }
 
@@ -876,4 +921,4 @@ msg("deprecated wikiPageExists called",-1);
 }
 
 
-//Setup VIM: ex: et ts=2 enc=utf-8 :
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/inc/utils.php b/inc/utils.php
index 6610c217a9c6294c735d6c466ce4120c81e85aa1..114fa3024bdacc0a499903f84e9b26f661f8c88a 100644
--- a/inc/utils.php
+++ b/inc/utils.php
@@ -9,21 +9,24 @@
   if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
 
 /**
- * Returns the (known) extension of a given filename
- *
- * returns false if not a known extension
+ * Returns the (known) extension and mimetype of a given filename
  *
  * @author Andreas Gohr <andi@splitbrain.org>
  */
-function media_extension($file){
-  $exts = join('|',array_keys(getMimeTypes()));
+function mimetype($file){
+  $ret    = array(false,false); // return array
+  $mtypes = getMimeTypes();     // known mimetypes
+  $exts   = join('|',array_keys($mtypes));  // known extensions (regexp)
   if(preg_match('#\.('.$exts.')$#i',$file,$matches)){
-    return strtolower($matches[1]);
+    $ext = strtolower($matches[1]);
   }
-  
-  return false;
-}
 
+  if($ext && $mtypes[$ext]){
+    $ret = array($ext, $mtypes[$ext]);
+  }
+
+  return $ret;
+}
 
 /**
  * returns a hash of mimetypes