private static function parseReportBlueprint($xml)
 {
     $blueprint = new ReportBlueprint((string) $xml['key']);
     $blueprint->setName((string) $xml['name']);
     $blueprint->setRowIdKey((string) $xml['rowIdKey']);
     $blueprint->setQuery((string) $xml->query);
     // list fields (double as report fields)
     foreach ($xml->field as $f) {
         $field = new ListField((string) $f['key']);
         $field->setDisplayName((string) $f->displayName);
         $field->setFormat((string) $f->format);
         $field->setHref((string) $f->href);
         $blueprint->add($field);
     }
     return $blueprint;
 }
echo "<h1>Testing ReportTableDrafter</h1>";
$reportBP = ReportBlueprint::reportBlueprintWithQuery("SELECT * FROM Member", "id", "MemberList");
$drafter = new ReportTableDrafter($reportBP);
echo $drafter->render();
/*
// #3
*/
echo "<h1>Testing ReportTableDrafter with Specific Fields</h1>";
$reportBP = ReportBlueprint::reportBlueprintWithQuery("SELECT * FROM Member", "id", "MemberList");
$login = new ListField("login");
$login->setDisplayName("Login");
$reportBP->add($login);
$passwd = new ListField("passwd");
$passwd->setDisplayName("Secret Key");
$passwd->setFormat("password");
$reportBP->add($passwd);
$email = new ListField("email");
$email->setDisplayName("Email Address");
$email->setHref("/admin/members/send-email.php?id={id}");
$reportBP->add($email);
$params = array();
$params["order"] = "modified DESC";
$params["where"] = "login IS NOT NULL";
$actions = array();
$deleteAction = ReportAction::initWith("delete", ReportAction::REPORT_ACTION_TARGET_TYPE_COLLECTION, "Delete", "alert('Dummy!')");
$actions[] = $deleteAction;
$viewAction = ReportAction::initWith("view", ReportAction::REPORT_ACTION_TARGET_TYPE_ROW, "Details", "alert('Sure')");
$actions[] = $viewAction;
$params["actions"] = $actions;
$drafter = new ReportTableDrafter($reportBP, $params);
echo $drafter->render();