painter = $painter;
		$this->base_dir = $base_dir;
	}
	function paintHeader($test_name, $charset="UTF-8") 
	{
		$this->sendNoCacheHeaders();
		header('Content-Type: text/html; Charset='.$charset);
		print "\n
\n$test_name\n";
		print "";
		print "\n";
		print "\n\n";
		print "$test_name
\n";
		flush();
	
		if (extension_loaded('xdebug')) 
			xdebug_start_code_coverage(XDEBUG_CC_UNUSED);
	}	
	/**
	 *
	 */
	function _getCss() 
	{
		$contents = parent::_getCss()."\n ";
		$contents .= '
	 .bar { float: left; display: inline;  border: 1px solid #eee; width: 300px; white-space: nowrap;} 
	.percentage { float: left; background-color: #eef;  font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;  font-size: 0.65em;  padding: 5px;  margin-right: } 
	.coverage {margin: 0.4em; } 
	.coverage a {
		padding-left: 0.5em;
	}
	.coverage:after { 
	content: "."; 
	display: block; 
	height: 0; 
	clear: both; 
	visibility: hidden;
	}
	.coverage {display: inline-block;}
	/* Hides from IE-mac \*/
	* html .coverage {height: 1%;}
	.coverage {display: block;}
	/* End hide from IE-mac */
	';
		Return $contents;
	}
	function paintFooter($test_name) 
	{
		if (extension_loaded('xdebug')) 
		{
			$this->coverage = xdebug_get_code_coverage();
			xdebug_stop_code_coverage();
		}
		$colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
		print "";
		print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount();
		print " test cases complete:\n";
		print "" . $this->getPassCount() . " passes, ";
		print "" . $this->getFailCount() . " fails and ";
		print "" . $this->getExceptionCount() . " exceptions.";
		print "
\n";
		$this->paintCoverage();
		print "\n\n";
	}
	function paintCoverage()
	{
		$dir = dirname(__FILE__);
		if(count($this->coverage) > 0)
			print 'Code Coverage
';
	
		
		ksort($this->coverage);		
		
		$details = array();
		foreach($this->coverage as $file => $coverage)
		{
			if(is_int(strpos($file, $dir)) == false
			&& is_int(strpos($file, 'simpletest')) == false
			&& is_int(strpos($file, $this->base_dir)))
			{
				$total = HTMLCoverageReport::codelines($file);
				$executed = count($coverage);
				$percentage = sprintf('%01d',$executed/$total*100);
				$width = $percentage * 3;
				$filename = str_replace($this->base_dir, '',$file);
				$link = $this->constructURL($filename, $coverage);
				
				$detail['total'] = $total;
				$detail['executed'] = $executed;
				$detail['width'] = $width;
				$detail['filename'] = $filename;
				$detail['link'] = $link;
				$details[$percentage][] = $detail;
			}
		}
		krsort($details);
		foreach($details as $percentage => $files)
		{
			foreach($files as $detail)
			{
				$total = $detail['total'];
				$executed = $detail['executed'];
				$width = $detail['width'];
				$filename = $detail['filename'];
				$link = $detail['link'];
				print "";
				print "
";
				print "";
				print "$executed/$total\n";
				print "$percentage%\n";
				print "
{$filename}\n";
				print "
$num $line
\n";
			else
			echo "$num $line
\n";
		}
		$this->paintFooter();
	}
	function paintHeader($file, $charset="UTF-8") 
	{
		$total = $this->codelines($this->file);
		$executed = count($this->lines);
		$percentage = sprintf('%01.2f',$executed/$total*100);
		$this->sendNoCacheHeaders();
		header('Content-Type: text/html Charset='.$charset);
		print "\n\nCode Coverage: $file\n";
		print "";
		print "\n";
		print "\n\n";
		print "Code Coverage
\n";
		print "$file
";
		print "    Total code lines: {$total} 
 Total lines executed: {$executed} ({$percentage}%)
";
		flush();
	}
	function paintFooter($test_name)
	{
		print "\n\n";
	}
	static function codelines($file)
	{
		$source = file_get_contents($file);
		$tokens = @token_get_all($source);
		$lines = '';
		foreach ($tokens as $token) 
		{
			if (is_string($token)) 
			{
				// simple 1-character token
				$lines .= $token;
			} 
			else 
			{
					// token array
				list($id, $text) = $token;
				switch ($id) 
				{ 
					case T_COMMENT: 
					case T_ML_COMMENT: // we've defined this
					case T_DOC_COMMENT: // and this
					// no action on comments
					break;
					default:
					// anything else -> output "as is"
					//echo $text;
					$lines .= $text;
					break;
				}
			}
		}
		$lines =  preg_replace('/\\n\s*$/m',"",$lines);
		$codelines = explode("\n",$lines);
		$count = 0;
		$patterns[] = '^\s*{\s*$';
		$patterns[] = '<\?';
		$patterns[] = '^\s*(private|protected|public)\s+\$';
		$pattern = '/'.implode('|', $patterns).'/';
		foreach($codelines as $line)
		{
			if(!preg_match($pattern, $line))
				$count++;
		}
		return $count;
		//var_dump($codelines);
		//return count($codelines);
	}
}
?>