void StatisticsWriterXml::Write(const Statistics *stats)
{
	*stream() << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
	          << "<stats script=\"" << script_name() << "\"";
	
	if (print_date()) {
		*stream() << " timestamp=\"" << TimeStamp::Now() << "\"";
	}

	if (print_run_time()) {
		*stream() << " run_time=\"" << Seconds(stats->GetTotalRunTime()).count() << "\'";
	}

	*stream() << ">\n";

	std::vector<FunctionStatistics*> all_fn_stats;
	stats->GetStatistics(all_fn_stats);

	Nanoseconds time_all;
	for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
			iterator != all_fn_stats.end(); ++iterator)
	{
		const FunctionStatistics *fn_stats = *iterator;
		time_all += fn_stats->total_time() - fn_stats->child_time(); 
	}

	Nanoseconds total_time_all;
	for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
			iterator != all_fn_stats.end(); ++iterator)
	{
		const FunctionStatistics *fn_stats = *iterator;
		total_time_all += fn_stats->total_time(); 
	}

	for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
			iterator != all_fn_stats.end(); ++iterator)
	{
		const FunctionStatistics *fn_stats = *iterator;

		double self_time_sec = Seconds(fn_stats->GetSelfTime()).count();
		double self_time_percent = fn_stats->GetSelfTime().count() * 100 / time_all.count();

		double total_time_sec = Seconds(fn_stats->total_time()).count();
		double total_time_percent = fn_stats->total_time().count() * 100 / total_time_all.count();

		*stream() << "\t<function"
			<< " type=\"" << fn_stats->function()->type() << "\""
			<< " name=\"" << fn_stats->function()->name() << "\""
			<< " calls=\"" << fn_stats->num_calls() << "\""
			<< " self_time=\"" << fn_stats->GetSelfTime().count() << "\""
			<< " self_time_sec=\"" << self_time_sec << "\""
			<< " self_time_percent=\"" <<  std::fixed << std::setprecision(2) << self_time_percent << "\""
			<< " total_time=\"" << fn_stats->total_time().count() << "\""
			<< " total_time_sec=\"" << total_time_sec << "\""
			<< " total_time_percent=\"" <<  std::fixed << std::setprecision(2) << total_time_percent << "\""
		<< "/>\n";
	}

	*stream() << "</stats>";
}
void StatisticsWriterHtml::Write(const Statistics *stats)
{
  *stream() <<
  "<!DOCTYPE html>\n"
  "<html>\n"
  "<head>\n"
  "  <title>" << "Profile of '" << script_name() << "'</title>\n"
  "  <script type=\"text/javascript\"\n"
  "          src=\"http://code.jquery.com/jquery-latest.min.js\">\n"
  "  </script>\n"
  "  <script type=\"text/javascript\"\n"
  "          src=\"http://tablesorter.com/__jquery.tablesorter.min.js\">\n"
  "  </script>\n"
  "  <script type=\"text/javascript\">\n"
  "    $(document).ready(function() {\n"
  "      $('#data').tablesorter();\n"
  "    });\n"
  "  </script>\n"
  "</head>\n"
  "<body>\n"
  ;

  *stream() <<
  "  <style type=\"text/css\">\n"
  "    table {\n"
  "      border-spacing: 0;\n"
  "      border-collapse: collapse;\n"
  "    }\n"
  "    table#data {\n"
  "      width: 100%;\n"
  "    }\n"
  "    table, th, td {\n"
  "      border-width: thin;\n"
  "      border-style: solid;\n"
  "      border-color: #aaaaaa;\n"
  "    }\n"
  "    th {\n"
  "      text-align: left;\n"
  "      background-color: #cccccc;\n"
  "    }\n"
  "    th.group {\n"
  "      text-align: center;\n"
  "    }\n"
  "    td {\n"
  "      text-align: left;\n"
  "      font-family: Consolas, \"DejaVu Sans Mono\", \"Courier New\", Monospace;\n"
  "    }\n"
  "    tbody tr:nth-child(odd) {\n"
  "      background-color: #eeeeee;\n"
  "    }\n"
  "    tbody tr:hover {\n"
  "      background-color: #c0e3eb;\n"
  "    }\n"
  "  </style>\n"
  "  <table id=\"meta\">\n"
  "    <thead>\n"
  "      <tr>\n"
  "        <th>Name</th>\n"
  "        <th>Value</th>\n"
  "      </tr>\n"
  "    </thead>\n"
  "    <tbody>\n"
  ;

  if (print_date()) {
    *stream() <<
    "      <tr>\n"
    "        <td>Date</td>\n"
    "        <td>" << CTime() << "</td>\n"
    "      </tr>\n"
    ;
  }

  if (print_run_time()) {
    *stream() <<
    "      <tr>\n"
    "        <td>Duration</td>\n"
    "        <td>" << TimeSpan(stats->GetTotalRunTime()) << "</td>\n"
    "      </tr>\n"
    ;
  }

  *stream() <<
  "    </tbody>\n"
  "  </table>\n"
  "  <br/>\n"
  "  <table id=\"data\" class=\"tablesorter\">\n"
  "    <thead>\n"
  "      <tr>\n"
  "        <th rowspan=\"2\">Type</th>\n"
  "        <th rowspan=\"2\">Name</th>\n"
  "        <th rowspan=\"2\">Calls</th>\n"
  "        <th colspan=\"4\" class=\"group\">Self Time</th>\n"
  "        <th colspan=\"4\" class=\"group\">Total Time</th>\n"
  "      </tr>\n"
  "      <tr>\n"
  "        <th>%</th>\n"
  "        <th>Overall</th>\n"
  "        <th>Average</th>\n"
  "        <th>Worst</th>\n"
  "        <th>%</th>\n"
  "        <th>Overall</th>\n"
  "        <th>Average</th>\n"
  "        <th>Worst</th>\n"
  "      </tr>\n"
  "    </thead>\n"
  "    <tbody>\n"
  ;

  std::vector<FunctionStatistics*> all_fn_stats;
  stats->GetStatistics(all_fn_stats);

  Nanoseconds self_time_all;
  for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
       iterator != all_fn_stats.end(); ++iterator)
  {
    const FunctionStatistics *fn_stats = *iterator;
    self_time_all += fn_stats->self_time();
  };

  Nanoseconds total_time_all;
  for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
       iterator != all_fn_stats.end(); ++iterator)
  {
    const FunctionStatistics *fn_stats = *iterator;
    total_time_all += fn_stats->total_time();
  };

  std::ostream::fmtflags flags = stream()->flags();
  stream()->flags(flags | std::ostream::fixed);

  for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
       iterator != all_fn_stats.end(); ++iterator)
  {
    const FunctionStatistics *fn_stats = *iterator;

    double self_time_percent = fn_stats->self_time().count() * 100 / self_time_all.count();
    double total_time_percent = fn_stats->total_time().count() * 100 / total_time_all.count();

    double self_time = Seconds(fn_stats->self_time()).count();
    double total_time = Seconds(fn_stats->total_time()).count();

    double avg_self_time = Milliseconds(fn_stats->self_time()).count() / fn_stats->num_calls();
    double avg_total_time = Milliseconds(fn_stats->total_time()).count() / fn_stats->num_calls();

    double worst_self_time = Milliseconds(fn_stats->worst_self_time()).count();
    double worst_total_time = Milliseconds(fn_stats->worst_total_time()).count();

    *stream()
    << "    <tr>\n"
    << "      <td>" << fn_stats->function()->GetTypeString() << "</td>\n"
    << "      <td>" << fn_stats->function()->name() << "</td>\n"
    << "      <td>" << fn_stats->num_calls() << "</td>\n"
    << "      <td>" << std::setprecision(2) << self_time_percent << "%</td>\n"
    << "      <td>" << std::setprecision(1) << self_time << "</td>\n"
    << "      <td>" << std::setprecision(1) << avg_self_time << "</td>\n"
    << "      <td>" << std::setprecision(1) << worst_self_time << "</td>\n"
    << "      <td>" << std::setprecision(2) << total_time_percent << "%</td>\n"
    << "      <td>" << std::setprecision(1) << total_time << "</td>\n"
    << "      <td>" << std::setprecision(1) << avg_total_time << "</td>\n"
    << "      <td>" << std::setprecision(1) << worst_total_time << "</td>\n"
    << "    </tr>\n";
  };

  stream()->flags(flags);

  *stream() <<
  "    </tbody>\n"
  "  </table>\n"
  "</body>\n"
  "</html>\n"
  ;
}
void StatisticsWriterHtml::Write(const Statistics *stats)
{
	*stream() <<
	"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n"
	"\"http://www.w3.org/TR/html4/loose.dtd\">\n"
	"<html>\n"
	"<head>\n"
	"	<title>" << "Profile of '" << script_name() << "'</title>\n"
	"</head>\n"
	"<body>\n";

	*stream() <<
	"	<style type=\"text/css\">\n"
	"	table.meta {\n"
	"		width: auto;\n"
	"	}\n"
	"	table {\n"
	"		border-spacing:0;\n"
	"		border-collapse: collapse;\n"
	"	}\n"
	"	table, th, td {\n"
	"		border: 1px solid #cccccc;\n"
	"	}\n"
	"	td {\n"
	"		font-family: Consolas, \"Courier New\", \"Monospace\";\n"
	"		border: solid 5x transparent;\n"
	"	}\n"
	"	th {\n"
	"		background-color: #cccccc;\n"
	"	}\n"
	"	</style>\n"
	"	<table class=\"meta\" border=\"1\">\n"
	"		<thead>\n"
	"			<tr>\n"
	"				<th>Name</th>\n"
	"				<th>Value</th>\n"
	"			</tr>\n"
	"		</thead>\n"
	"		<tbody>\n";

	if (print_date()) {
		*stream() <<
		"			<tr>\n"
		"				<td>Date</td>\n"
		"				<td>" << CTime() << "</td>\n"
		"			</tr>\n";
	}

	if (print_run_time()) {
		*stream() <<
		"			<tr>\n"
		"				<td>Duration</td>\n"
		"				<td>" << TimeSpan(stats->GetTotalRunTime()) << "</td>\n"
		"			</tr>\n";
	}

	*stream() <<
	"		</tbody>\n"
	"	</table>\n"
	"	<br/>"
	"	<style type=\"text/css\">\n"
	"	tr:nth-child(odd) {\n"
	"		background-color: #eeeeee;\n"
	"	}\n"
	"	</style>\n"
	"	<table id=\"func-stats\" class=\"tablesorter\" border=\"1\" width=\"100%\">\n"
	"		<thead>\n"
	"			<tr>\n"
	"				<th>Type</th>\n"
	"				<th>Name</th>\n"
	"				<th>Calls</th>\n"
	"				<th colspan=\"2\">Self Time</th>\n"
	"				<th colspan=\"2\">Total Time</th>\n"
	"				<th>Best time</th>\n"
	"				<th>Worst time</th>\n"
	"				<th>Average time</th>\n"
	"			</tr>\n"
	"		</thead>\n"
	"		<tbody>\n"
	;

	std::vector<FunctionStatistics*> all_fn_stats;
	stats->GetStatistics(all_fn_stats);

	Nanoseconds time_all;
	for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
			iterator != all_fn_stats.end(); ++iterator)
	{
		const FunctionStatistics *fn_stats = *iterator;
		time_all += fn_stats->total_time() - fn_stats->child_time(); 
	};

	Nanoseconds total_time_all;
	for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
			iterator != all_fn_stats.end(); ++iterator)
	{
		const FunctionStatistics *fn_stats = *iterator;
		total_time_all += fn_stats->total_time(); 
	};

	for (std::vector<FunctionStatistics*>::const_iterator iterator = all_fn_stats.begin();
			iterator != all_fn_stats.end(); ++iterator)
	{
		const FunctionStatistics *fn_stats = *iterator;

		double self_time_sec = Seconds(fn_stats->GetSelfTime()).count();
		double self_time_percent = fn_stats->GetSelfTime().count() * 100 / time_all.count();

		double total_time_sec = Seconds(fn_stats->total_time()).count();
		double total_time_percent = fn_stats->total_time().count() * 100 / total_time_all.count();

		double best_time_sec = Seconds(fn_stats->best_time()).count();
		double worst_time_sec = Seconds(fn_stats->worst_time()).count();
		double average_time_sec = Seconds(fn_stats->average_time()).count();

		*stream()
		<< "		<tr>\n"
		<< "			<td>" << fn_stats->function()->type() << "</td>\n"
		<< "			<td>" << fn_stats->function()->name() << "</td>\n"
		<< "			<td>" << fn_stats->num_calls() << "</td>\n"
		<< "			<td>" << std::fixed << std::setprecision(2) << self_time_percent << "%</td>\n"
		<< "			<td>" << std::fixed << std::setprecision(3) << self_time_sec << "s</td>\n"
		<< "			<td>" << std::fixed << std::setprecision(2) << total_time_percent << "%</td>\n"
		<< "			<td>" << std::fixed << std::setprecision(3) << total_time_sec << "s</td>\n"
		<< "			<td>" << std::fixed << std::setprecision(3) << best_time_sec << "s</td>\n"
		<< "			<td>" << std::fixed << std::setprecision(3) << worst_time_sec << "s</td>\n"
		<< "			<td>" << std::fixed << std::setprecision(3) << average_time_sec << "s</td>\n"
		<< "			</td>\n"
		<< "		</tr>\n";
	};

	*stream() <<
	"		</tbody>\n"
	"	</table>\n"
	;

	*stream() <<
	"	<script type=\"text/javascript\"\n"
	"		src=\"http://code.jquery.com/jquery-latest.min.js\"></script>\n"
	"	<script type=\"text/javascript\"\n"
	"		src=\"http://tablesorter.com/__jquery.tablesorter.min.js\"></script>\n"
	"	<script type=\"text/javascript\">\n"
	"	$(document).ready(function() {\n"
	"		$(\"#func-stats\").tablesorter();\n"
	"	});\n"
	"	</script>\n"
	"	<br/>\n"
	"	<footer>\n"
	;

	*stream() <<
	"	</footer>\n"
	"</body>\n"
	"</html>\n"
	;
}