function convert ($format, $attr, $showMessages=false) {
		$currentFormat = $this->format();
		$format = strtolower(trim($format));
		if ($format == '')
			return false;
		if ($currentFormat == $format)
			return $this;
			
		$name = file_strip_extension($this->fname);  // remove file extension		
		$mo = MediaObjectFactory::createMediaObject($this->pagename, "$name.$format");
		if (!$mo->exists() || $mo->olderThan($this)) {
			if ($showMessages)
				message("creating FIG image in ".strtoupper($format)." format", 'start');
			// fig2dev doesn't like DOS/Win newlines => convert newlines to UNIX format
			// if $this->path() is a symbolic link we convert the actual fig file (link target)
			$path = $this->path();
			if (is_link($path))
				$path = readlink($path);
			RunTool('dos2unix', "IN=$path");
			$resfile = $this->fig2format($this->path(), $format);
			return $resfile ? $mo : false;

		}
		return $mo;
	}
	function convert ($format, $attr) {
		if ($this->isRemote() || $format != 'png') // @@
			return false;
		$name = file_strip_extension($this->fname);  // remove file extension
		$mo = MediaObjectFactory::createMediaObject($this->pagename, "$name.$format");
		if (!$mo->exists() || $mo->olderThan($this)) {
			@unlink($mo->path());
			RunTool('ffmpeg', sprintf("IN=%s OUT=%s TARGETFORMAT=%s TIME=2", $this->path(), $mo->path(), $format), 'pipe');
			return $mo->exists() ? $mo : false;
		}
		return $mo;
	}
	function createMO ($format, $attr, $showMessages=false) {
		$fname = file_strip_extension($this->fname).".$format";
		$mo = MediaObjectFactory::createMediaObject($this->pagename, $fname);
		if ($this->mustReconvert($mo)) {
			$in  = $this->path();
			$out = $mo->path();
			RunTool('pec2img', "IN=$in OUT=$out");
			if ($format != 'eps' && $format != 'pdf' && isset($attr['scale'])) 
				RunTool('mogrify', "SCALE=$attr[scale] FILE=".$mo->path());
//			$mo->scale($this->attribs->getAttrib('scale'));
		}
		return $mo;
	}
	function createMO ($format, $attr, $showMessages=false) {
		//      Example:
		//      set terminal gif
		//      set output "test.gif"
		//      plot x**2

		$fname = file_strip_extension($this->fname).".$format";
		$mo = MediaObjectFactory::createMediaObject($this->pagename, $fname);
		if ($this->mustReconvert($mo)) {
			if ($showMessages)
				message("creating gnuplot image in ".strtoupper($format)." format", 'start');
			$scripthead = "cd '".$mo->dir()."'\nset output '$fname'\n";
			switch ($format) {
				case "gif":	$scripthead .= "set term gif transparent crop";	break;
				case "png":	$scripthead .= "set term png truecolor crop";	break;
				case 'eps': $scripthead .= "set term postscript eps color"; break;
				case 'pdf': $scripthead .= "set term pdf color"; break;
			}
			$script = file_get_contents($this->path());
			$script = preg_replace('/^\s*set?\s+((o)|(ou\w*))/', '', $script); // remove "set output" statements
			$script = preg_replace('/^\s*set?\s+t\w/', '', $script);           // remove "set terminal" statements
			$script = "$scripthead\n$script";
			$tmpfile = $this->path().".tmp";
			$f = fopen($tmpfile, "w");
			fputs($f, $script);
			fclose($f);
			RunTool('gnuplot', "SCRIPT=$tmpfile");
//			unlink($tmpfile);
			if ($format == 'pdf') {
				// the gnuplot generated bounding box is too wide, so we
				// compute and assign a minimal box
				if ($showMessages)
					message("adapting bounding box");
//				assignMinimalBoundingBoxToPDF($mo->path());
			}
			// @@ the current gnuplot version doesn't handle transparency correctly, so we apply it seperately
			// @@ can hopefully be removed again
			elseif ($format == 'png')
				RunTool('convert', "IN=".$mo->path()." OUT=".$mo->path()." TRANSPARENT=white");

			if ($format != 'eps' && $format != 'pdf' && isset($attr['scale'])) 
				RunTool('mogrify', "SCALE=$attr[scale] FILE=".$mo->path());
			if ($showMessages)
				message("", 'end');
		}
		return $mo;
	}
	function convert ($format, $attr) {
		$currentFormat = $this->format();
		$format = strtolower(trim($format));
		if ($format == '')
			return false;
		if ($currentFormat == $format)
			return $this;
			
		$name = file_strip_extension($this->fname);  // remove file extension
		$newMO = MediaObjectFactory::createMediaObject($this->pagename, "$name.$format");
		if (!$newMO->exists() || $newMO->olderThan($this)) {
			if ($showMessages)
				message("creating FIG image in ".strtoupper($format)." format", 'start');
			RunTool('fig2dev', "IN=".$this->path()." OUT=".$mo->path()." FORMAT=$format");
		}
		return $newMO;
	}
	function createMO ($format, $attr, $showMessages=false) {
		$code = preg_replace("/{$this->remove}/", '', file_get_contents($this->path()));
		$hash = file_strip_extension($this->fname);
		$mo = MediaObjectFactory::createMediaObject($this->pagename, "$hash.$format");
		if ($mo->filesize() == 0)
			$mo->remove();
		$error = false;
		if ($this->mustReconvert($mo)) {
			if ($showMessages)
				message("creating ".$this->scripttype()." image in ".strtoupper($format)." format");
			$latex = "{$this->preamble}\n{$this->packages}\n";
			$latex.=" \\begin{document}\\newsavebox{\\mybox}\n";
			$latex.= "\\sbox\\mybox{{$this->openEnv}$code{$this->closeEnv}}\n";
			$latex.= "\\usebox\\mybox\n";
			$latex.= "\\typeout{width=\\the\\wd\\mybox}\n";
			$latex.= "\\typeout{height=\\the\\ht\\mybox}\n";
			$latex.= "\\typeout{depth=\\the\\dp\\mybox}\n";
			$latex.= "\\end{document}\n";
			$dir = getcwd();
			chdir($this->dir());
			$texfile = $this->path();
			$f = fopen($texfile, "w");
			fputs($f, $latex);
			fclose($f);

			switch ($format) {
				case 'eps': $res = $this->tex2eps($texfile); break;
				case 'pdf': $res = $this->tex2pdf($texfile); break;
				default   : $res = $this->tex2format($texfile, $format); 
			}
//			$this->message = $this->latexErrorInMessage($output);
			if ($this->message || $res === false)
				$error = true;

			// remove temporary files
			foreach (array('aux', 'dvi', 'log', 'tex') as $ext)
				if ($format != $ext)
					@unlink("$hash.$ext");
			chdir($dir);
		}
		return $error ? false : $mo;
	}		
	function createMediaObject ($pagename, $fname, $attribs=false) {
		if (trim($fname) == '')
			return false; 

		$type = MediaObjectFactory::type($fname);
		$ext = strtolower(file_extension($fname));
		// special case: RealAudio/-Video
		switch ($ext) {
			case 'smi' :
			case 'smil':
			case 'rm':
				if ($attribs->attribs['media'] == 'audio')
					return new RealAudioObject($pagename, $fname, $attribs);
				else
					return new RealVideoObject($pagename, $fname, $attribs);
			case 'htm' :
			case 'html':
				return new IFrameObject($pagename, $fname, $attribs);
		}

		switch ($type) {
			case 'image' : return MediaObjectFactory::createImageObject($pagename, $fname, $attribs);
			case 'audio' : return MediaObjectFactory::createAudioObject($pagename, $fname, $attribs);
			case 'video' : return MediaObjectFactory::createVideoObject($pagename, $fname, $attribs);
		}
		// try to create a ScriptObject
		if ($so = ScriptObjectFactory::createScriptObjectFromFilename($pagename, $fname, $attribs))
			return $so;

		if (is_object($attribs)) {
			$attr = $attribs->getAttribs();
			if (isset($attr['url']))
				return new IFrameObject($pagename, $fname, $attribs);
		}

		$co = new CodeObject($pagename, $fname, $attribs);
		return $co->isBinary() ? false : $co;
	}
	function validate () {
		$attr = $this->attribs->getAttribs('html');
		$file = $attr['file'];
		$msg = "";
		if ($file == '' && $attr['url'] == '')
			return $showErrors ? errorHTML("No <i>file</i> attribute found in (:embed:) statement") : '';
		
		if ($attr['file']=='' && $attr['url'] != '')
			$file = $attr['url'];

		$mo = MediaObjectFactory::createMediaObject($this->pagename, $file, $this->attribs);
		if ($mo == false || !$mo->exists()) {
			global $ScriptUrl;
			$msg = "Embedded file <i>$file</i> not found<br>";
			$msg.= "<a href='$ScriptUrl?n={$this->pagename}/?action=upload&upname=$file'>upload now</a>";
		}
		elseif ($mo->isRemote() && !$mo->urlSupported()) {
			$msg = "<i>url</i> attribute not supported for filetype ".strtoupper($mo->format());
		}
		
		// test if print-file attribnute is given and if referenced file exists 
		$attr = $this->attribs->getAttribs('fo', true);
		if (isset($attr['file'])) {
			$file = $attr['file'];
			$mo = MediaObjectFactory::createMediaObject($this->pagename, $file, $this->attribs);
			if ($mo == false || !$mo->exists()) {
				global $ScriptUrl;
				if ($msg != "")
					$msg .= "<hr/>";
				$msg .= "Embedded print file <i>$file</i> not found<br>";
				$msg .= "<a href='$ScriptUrl?n={$this->pagename}/?action=upload&upname=$file'>upload now</a>";
			}
		}
		return $msg;
	}
	function convert ($format, $attr) {
		$currentFormat = $this->format();
		$format = strtolower(trim($format));
		if ($format == '')
			return false;
		if ($currentFormat == $format)
			return $this;
			
		$name = file_strip_extension($this->fname);  // remove file extension
		$newMO = MediaObjectFactory::createMediaObject($this->pagename, "$name.$format");
		if (!$newMO->exists() || $newMO->olderThan($this)) {
			if ($currentFormat == 'svg') {  // TODO move to SVGObject class
				switch ($format) {
					case 'eps': $this->svg2eps($this->path(), $newMO->path()); break;
					case 'pdf': $this->svg2pdf($this->path(), $newMO->path()); break;
					default   : $this->svg2format($this->path(), $newMO->path(), $format); break;
				}
			}
			elseif ($currentFormat == 'eps' && $format == 'pdf')
				RunTool("epstopdf", "IN=".$this->path()." OUT=".$newMO->path());
			else {			
				RunTool('convert', "IN=".$this->path()." OUT=".$newMO->path());
				$t = isset($attr['transparent']) ? " TRANSPARENT=$attr[transparent]" : '';
				// for some reason we have to call "convert" twice to get transperency
				if ($t != '')
					RunTool('convert', "IN=".$newMO->path()." OUT=".$newMO->path().$t);
			}
		}
		return $newMO;
	}