diff --git a/src/future/http/status/HTTPFutureHTTPResponseStatus.php b/src/future/http/status/HTTPFutureHTTPResponseStatus.php
index 6031553..466030b 100644
--- a/src/future/http/status/HTTPFutureHTTPResponseStatus.php
+++ b/src/future/http/status/HTTPFutureHTTPResponseStatus.php
@@ -1,63 +1,62 @@
 <?php
 
 final class HTTPFutureHTTPResponseStatus extends HTTPFutureResponseStatus {
 
   private $excerpt;
   private $expect;
 
   public function __construct(
     $status_code,
     $body,
     array $headers,
     $expect = null) {
 
     // NOTE: Avoiding PhutilUTF8StringTruncator here because this isn't lazy
     // and responses may be large.
     if (strlen($body) > 512) {
       $excerpt = substr($body, 0, 512).'...';
     } else {
       $excerpt = $body;
     }
 
     $content_type = BaseHTTPFuture::getHeader($headers, 'Content-Type');
     $match = null;
     if (preg_match('/;\s*charset=([^;]+)/', $content_type, $match)) {
       $encoding = trim($match[1], "\"'");
       try {
         $excerpt = phutil_utf8_convert($excerpt, 'UTF-8', $encoding);
-      } catch (Exception $ex) {
-      }
+      } catch (Exception $ex) {}
     }
 
     $this->excerpt = phutil_utf8ize($excerpt);
     $this->expect = $expect;
 
     parent::__construct($status_code);
   }
 
   protected function getErrorCodeType($code) {
     return 'HTTP';
   }
 
   public function isError() {
     if ($this->expect === null) {
         return ($this->getStatusCode() < 200) || ($this->getStatusCode() > 299);
     }
 
     return !in_array($this->getStatusCode(), $this->expect, true);
   }
 
   public function isTimeout() {
     return false;
   }
 
   protected function getErrorCodeDescription($code) {
     static $map = array(
       404 => 'Not Found',
       500 => 'Internal Server Error',
     );
 
     return idx($map, $code)."\n".$this->excerpt."\n";
   }
 
 }
diff --git a/src/markup/engine/PhutilRemarkupEngine.php b/src/markup/engine/PhutilRemarkupEngine.php
index 8f8ebe0..7c551c9 100644
--- a/src/markup/engine/PhutilRemarkupEngine.php
+++ b/src/markup/engine/PhutilRemarkupEngine.php
@@ -1,298 +1,296 @@
 <?php
 
 final class PhutilRemarkupEngine extends PhutilMarkupEngine {
 
   const MODE_DEFAULT = 0;
   const MODE_TEXT = 1;
 
   const MAX_CHILD_DEPTH = 32;
 
   private $blockRules = array();
   private $config = array();
   private $mode;
   private $metadata = array();
   private $states = array();
   private $postprocessRules = array();
 
   public function setConfig($key, $value) {
     $this->config[$key] = $value;
     return $this;
   }
 
   public function getConfig($key, $default = null) {
     return idx($this->config, $key, $default);
   }
 
   public function setMode($mode) {
     $this->mode = $mode;
     return $this;
   }
 
   public function isTextMode() {
     return $this->mode & self::MODE_TEXT;
   }
 
   public function setBlockRules(array $rules) {
     assert_instances_of($rules, 'PhutilRemarkupBlockRule');
 
     $rules = msort($rules, 'getPriority');
 
     $this->blockRules = $rules;
     foreach ($this->blockRules as $rule) {
       $rule->setEngine($this);
     }
 
     $post_rules = array();
     foreach ($this->blockRules as $block_rule) {
       foreach ($block_rule->getMarkupRules() as $rule) {
         $key = $rule->getPostprocessKey();
         if ($key !== null) {
           $post_rules[$key] = $rule;
         }
       }
     }
 
     $this->postprocessRules = $post_rules;
 
     return $this;
   }
 
   public function getTextMetadata($key, $default = null) {
     if (isset($this->metadata[$key])) {
       return $this->metadata[$key];
     }
     return idx($this->metadata, $key, $default);
   }
 
   public function setTextMetadata($key, $value) {
     $this->metadata[$key] = $value;
     return $this;
   }
 
   public function storeText($text) {
     if ($this->isTextMode()) {
       $text = phutil_safe_html($text);
     }
     return $this->storage->store($text);
   }
 
   public function overwriteStoredText($token, $new_text) {
     if ($this->isTextMode()) {
       $new_text = phutil_safe_html($new_text);
     }
     $this->storage->overwrite($token, $new_text);
     return $this;
   }
 
   public function markupText($text) {
     return $this->postprocessText($this->preprocessText($text));
   }
 
   public function pushState($state) {
     if (empty($this->states[$state])) {
       $this->states[$state] = 0;
     }
     $this->states[$state]++;
     return $this;
   }
 
   public function popState($state) {
     if (empty($this->states[$state])) {
       throw new Exception("State '{$state}' pushed more than popped!");
     }
     $this->states[$state]--;
     if (!$this->states[$state]) {
       unset($this->states[$state]);
     }
     return $this;
   }
 
   public function getState($state) {
     return !empty($this->states[$state]);
   }
 
   public function preprocessText($text) {
     $this->metadata = array();
     $this->storage = new PhutilRemarkupBlockStorage();
 
     $blocks = $this->splitTextIntoBlocks($text);
 
     $output = array();
     foreach ($blocks as $block) {
       $output[] = $this->markupBlock($block);
     }
     $output = $this->flattenOutput($output);
 
     $map = $this->storage->getMap();
     unset($this->storage);
     $metadata = $this->metadata;
 
 
     return array(
       'output'    => $output,
       'storage'   => $map,
       'metadata'  => $metadata,
     );
   }
 
   private function splitTextIntoBlocks($text, $depth = 0) {
     // Apply basic block and paragraph normalization to the text. NOTE: We don't
     // strip trailing whitespace because it is semantic in some contexts,
     // notably inlined diffs that the author intends to show as a code block.
     $text = phutil_split_lines($text, true);
     $block_rules = $this->blockRules;
     $blocks = array();
     $cursor = 0;
     $prev_block = array();
 
     while (isset($text[$cursor])) {
       $starting_cursor = $cursor;
       foreach ($block_rules as $block_rule) {
         $num_lines = $block_rule->getMatchingLineCount($text, $cursor);
 
         if ($num_lines) {
           if ($blocks) {
             $prev_block = last($blocks);
           }
 
           $curr_block = array(
             'start' => $cursor,
             'num_lines' => $num_lines,
             'rule' => $block_rule,
             'is_empty' => self::isEmptyBlock($text, $cursor, $num_lines),
             'children' => array(),
           );
 
           if ($prev_block
             && self::shouldMergeBlocks($text, $prev_block, $curr_block)) {
             $blocks[last_key($blocks)]['num_lines'] += $curr_block['num_lines'];
             $blocks[last_key($blocks)]['is_empty'] =
               $blocks[last_key($blocks)]['is_empty'] && $curr_block['is_empty'];
           } else {
             $blocks[] = $curr_block;
           }
 
           $cursor += $num_lines;
           break;
         }
       }
 
       if ($starting_cursor === $cursor) {
         throw new Exception('Block in text did not match any block rule.');
       }
     }
 
     foreach ($blocks as $key => $block) {
       $lines = array_slice($text, $block['start'], $block['num_lines']);
       $blocks[$key]['text'] = implode('', $lines);
     }
 
     // Stop splitting child blocks apart if we get too deep. This arrests
     // any blocks which have looping child rules, and stops the stack from
     // exploding if someone writes a hilarious comment with 5,000 levels of
     // quoted text.
 
     if ($depth < self::MAX_CHILD_DEPTH) {
       foreach ($blocks as $key => $block) {
         $rule = $block['rule'];
         if (!$rule->supportsChildBlocks()) {
           continue;
         }
 
         list($parent_text, $child_text) = $rule->extractChildText(
           $block['text']);
         $blocks[$key]['text'] = $parent_text;
         $blocks[$key]['children'] = $this->splitTextIntoBlocks(
           $child_text,
           $depth + 1);
       }
     }
 
     return $blocks;
   }
 
   private function markupBlock(array $block) {
     $children = array();
     foreach ($block['children'] as $child) {
       $children[] = $this->markupBlock($child);
     }
 
     if ($children) {
       $children = $this->flattenOutput($children);
     } else {
       $children = null;
     }
 
     return $block['rule']->markupText($block['text'], $children);
   }
 
   private function flattenOutput(array $output) {
     if ($this->isTextMode()) {
       $output = implode("\n\n", $output)."\n";
     } else {
       $output = phutil_implode_html("\n\n", $output);
     }
 
     return $output;
   }
 
   private static function shouldMergeBlocks($text, $prev_block, $curr_block) {
     $block_rules = ipull(array($prev_block, $curr_block), 'rule');
 
     $default_rule = 'PhutilRemarkupDefaultBlockRule';
     try {
       assert_instances_of($block_rules, $default_rule);
 
       // If the last block was empty keep merging
       if ($prev_block['is_empty']) {
         return true;
       }
 
       // If this line is blank keep merging
       if ($curr_block['is_empty']) {
         return true;
       }
 
       // If the current line and the last line have content, keep merging
       if (strlen(trim($text[$curr_block['start'] - 1]))) {
         if (strlen(trim($text[$curr_block['start']]))) {
           return true;
         }
       }
-    } catch (Exception $e) {
-
-    }
+    } catch (Exception $e) {}
 
     return false;
   }
 
   private static function isEmptyBlock($text, $start, $num_lines) {
     for ($cursor = $start; $cursor < $start + $num_lines; $cursor++) {
       if (strlen(trim($text[$cursor]))) {
         return false;
       }
     }
     return true;
   }
 
   public function postprocessText(array $dict) {
     $this->metadata = idx($dict, 'metadata', array());
 
     $this->storage = new PhutilRemarkupBlockStorage();
     $this->storage->setMap(idx($dict, 'storage', array()));
 
     foreach ($this->blockRules as $block_rule) {
       $block_rule->postprocess();
     }
 
     foreach ($this->postprocessRules as $rule) {
       $rule->didMarkupText();
     }
 
     return $this->restoreText(idx($dict, 'output'), $this->isTextMode());
   }
 
   public function restoreText($text) {
     return $this->storage->restore($text, $this->isTextMode());
   }
 }
diff --git a/src/object/__tests__/PhutilTestPhobject.php b/src/object/__tests__/PhutilTestPhobject.php
index 40735e8..7bd5b81 100644
--- a/src/object/__tests__/PhutilTestPhobject.php
+++ b/src/object/__tests__/PhutilTestPhobject.php
@@ -1,5 +1,3 @@
 <?php
 
-final class PhutilTestPhobject extends Phobject {
-
-}
+final class PhutilTestPhobject extends Phobject {}
diff --git a/src/parser/PhutilTypeSpec.php b/src/parser/PhutilTypeSpec.php
index 7282c44..156d498 100644
--- a/src/parser/PhutilTypeSpec.php
+++ b/src/parser/PhutilTypeSpec.php
@@ -1,1914 +1,1912 @@
 <?php
 
 /**
  * Perform type checks using a simple type grammar. The grammar supports the
  * following basic types:
  *
  *    int
  *    float
  *    bool
  *    string
  *    null
  *    callable
  *    regex
  *    wild
  *    AnyClassOrInterfaceName
  *
  * It supports the following complex types:
  *
  *    list<type>
  *    map<type, type>
  *    type|type
  *
  * A type may be marked as optional by suffixing it with "?" or prefixing it
  * with the word "optional":
  *
  *    int?
  *    optional int
  *
  * A type may have a human-readable comment in parentheses, at the end:
  *
  *    int (must be even)
  *
  * For example, these are valid type specifications:
  *
  *    int|string
  *    map<int, bool>
  *    list<list<wild>>
  *    optional int
  *    string (uppercase)
  *
  */
 final class PhutilTypeSpec {
 
   private $type;
   private $subtypes = array();
   private $optional;
   private $comment;
 
-  private function __construct() {
-
-  }
+  private function __construct() {}
 
   public function getType() {
     return $this->type;
   }
 
   public function check($value, $name = null) {
     switch ($this->type) {
       case 'int':
         if (!is_int($value)) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         break;
       case 'float':
         if (!is_float($value)) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         break;
       case 'bool':
         if (!is_bool($value)) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         break;
       case 'string':
         if (!is_string($value)) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         break;
       case 'regex':
         $trap = new PhutilErrorTrap();
           $ok = @preg_match($value, '');
           $err = $trap->getErrorsAsString();
         $trap->destroy();
 
         if ($ok === false) {
           throw new PhutilTypeCheckException($this, $value, $name, $err);
         }
         break;
       case 'null':
         if (!is_null($value)) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         break;
       case 'list':
         if (!is_array($value)) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         if ($value && (array_keys($value) !== range(0, count($value) - 1))) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         try {
           foreach ($value as $v) {
             $this->subtypes[0]->check($v);
           }
         } catch (PhutilTypeCheckException $ex) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         break;
       case 'map':
         if (!is_array($value)) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         try {
           foreach ($value as $k => $v) {
             $this->subtypes[0]->check($k);
             $this->subtypes[1]->check($v);
           }
         } catch (PhutilTypeCheckException $ex) {
           throw new PhutilTypeCheckException($this, $value, $name);
         }
         break;
       case 'or':
         foreach ($this->subtypes as $subtype) {
           try {
             $subtype->check($value);
             return;
           } catch (PhutilTypeCheckException $ex) {
             // Ignore.
           }
         }
         throw new PhutilTypeCheckException($this, $value, $name);
       case 'wild':
         return;
       default:
         if (class_exists($this->type, false)) {
           if ($value instanceof $this->type) {
             return;
           }
         } else if (interface_exists($this->type, false)) {
           if ($value instanceof $this->type) {
             return;
           }
         }
 
         throw new PhutilTypeCheckException($this, $value, $name);
     }
   }
 
   public static function checkMap(array $values, array $types) {
     $extra = array_diff_key($values, $types);
     if ($extra) {
       throw new PhutilTypeExtraParametersException($extra);
     }
 
     $missing = array();
     foreach ($types as $key => $type) {
       $types[$key] = self::newFromString($type);
       if (!array_key_exists($key, $values)) {
         if (!$types[$key]->optional) {
           $missing[] = $key;
         }
       }
     }
 
     if ($missing) {
       throw new PhutilTypeMissingParametersException($missing);
     }
 
     foreach ($types as $key => $type) {
       if (array_key_exists($key, $values)) {
         $type->check($values[$key]);
       }
     }
   }
 
   public static function getCommonParentClass($class_a, $class_b) {
     $ancestors_a = array();
     do {
       $ancestors_a[] = $class_a;
     } while ($class_a = get_parent_class($class_a));
 
     $ancestors_b = array();
     do {
       $ancestors_b[] = $class_b;
     } while ($class_b = get_parent_class($class_b));
 
     return head(array_intersect($ancestors_a, $ancestors_b));
   }
 
   public static function getTypeOf($value) {
     if (is_int($value)) {
       return 'int';
     } else if (is_float($value)) {
       return 'float';
     } else if (is_bool($value)) {
       return 'bool';
     } else if (is_string($value)) {
       return 'string';
     } else if (is_null($value)) {
       return 'null';
     } else if (is_object($value)) {
       return get_class($value);
     } else if (is_array($value)) {
       $vtype = self::getTypeOfVector($value);
       if ($value && (array_keys($value) === range(0, count($value) - 1))) {
         return 'list<'.$vtype.'>';
       } else {
         $ktype = self::getTypeOfVector(array_keys($value));
         return "map<{$ktype}, {$vtype}>";
       }
     } else {
       return 'wild';
     }
   }
 
   private static function getTypeOfVector(array $vector) {
     if (!$vector) {
       return 'wild';
     }
 
     $type = null;
     foreach ($vector as $value) {
       $vtype = self::getTypeOf($value);
       if ($type === null) {
         $type = $vtype;
       } else if ($type === $vtype) {
         continue;
       } else {
         $parent = self::getCommonParentClass($type, $vtype);
         if ($parent) {
           $type = $parent;
         } else {
           return 'wild';
         }
       }
     }
 
     return $type;
   }
 
   public function toString() {
     $sub = array();
     foreach ($this->subtypes as $subtype) {
       $sub[] = $subtype->toString();
     }
 
     switch ($this->type) {
       case 'map':
         $string = 'map<'.$sub[0].', '.$sub[1].'>';
         break;
       case 'list':
         $string = 'list<'.$sub[0].'>';
         break;
       case 'or':
         $string = implode('|', $sub);
         break;
       default:
         $string = $this->type;
         break;
     }
 
     if ($this->optional) {
       $string = 'optional '.$string;
     }
 
     if ($this->comment) {
       $string .= ' ('.$this->comment.')';
     }
 
     return $string;
   }
 
   public static function newFromString($string) {
     $lexer = self::getLexer();
     $tokens = $lexer->getTokens($string);
 
     // Strip whitespace tokens.
     foreach ($tokens as $key => $token) {
       $type = $token[0];
       if ($type == ' ') {
         unset($tokens[$key]);
       }
     }
 
     $tokens = array_values($tokens);
     $callback = array(__CLASS__, 'didReduceTokens');
     return self::parseTokens($tokens, $callback);
   }
 
   public static function didReduceTokens($rule, $production, array $tokens) {
     switch ($rule) {
       case 'start':
       case 'some_type':
       case 'not_or_type':
         return $tokens[0];
       case 'type':
         if ($production == 'yes') {
           $tokens[0]->optional = true;
         }
         return $tokens[0];
       case 'basic_type':
         $obj = new PhutilTypeSpec();
         $obj->type = $tokens[0][1];
         return $obj;
       case 'or_type':
         $l = $tokens[0];
         $r = $tokens[2];
 
         if ($l->type == 'or') {
           if ($r->type == 'or') {
             foreach ($r->subtypes as $subtype) {
               $l->subtypes[] = $subtype;
             }
           } else {
             $l->subtypes[] = $r;
           }
           return $l;
         } else if ($r->type == 'or') {
           $r->subtypes[] = $l;
           return $r;
         } else {
           $obj = new PhutilTypeSpec();
           $obj->type = 'or';
           $obj->subtypes[] = $l;
           $obj->subtypes[] = $r;
           return $obj;
         }
         break;
       case 'map_type':
         $obj = new PhutilTypeSpec();
         $obj->type = 'map';
         $obj->subtypes[] = $tokens[2];
         $obj->subtypes[] = $tokens[4];
         return $obj;
       case 'list_type':
         $obj = new PhutilTypeSpec();
         $obj->type = 'list';
         $obj->subtypes[] = $tokens[2];
         return $obj;
       case 'maybe_optional':
         if ($production == 'yes') {
           $tokens[1]->optional = true;
           return $tokens[1];
         } else {
           return $tokens[0];
         }
         break;
       case 'maybe_comment':
         if ($production == 'yes') {
           $tokens[0]->comment = $tokens[1];
         }
         return $tokens[0];
       case 'comment':
         return $tokens[1];
       case 'comment_text':
         $result = '';
         foreach ($tokens as $token) {
           if (is_array($token)) {
             $result .= $token[1];
           } else {
             $result .= $token;
           }
         }
         return $result;
       default:
         throw new Exception("Unhandled parser rule '{$rule}'!");
     }
   }
 
   private static function getLexer() {
     static $lexer;
     if (!$lexer) {
       $lexer = new PhutilTypeLexer();
     }
     return $lexer;
   }
 
   private static function parseTokens(array $tokens, $callback) {
     // NOTE: This is automatically generated by the script
     // `support/parser/generate-type-parser.php`.
 
     return PhutilParserGenerator::parseTokensWithTables(
       array(
         0 => array(
           'opt' => array(
             0 => 'S',
             1 => 3,
           ),
           'k' => array(
             0 => 'S',
             1 => 20,
           ),
           'map' => array(
             0 => 'S',
             1 => 21,
           ),
           'list' => array(
             0 => 'S',
             1 => 71,
           ),
         ),
         1 => array(
           '(end-of-file)' => array(
             0 => 'A',
           ),
         ),
         2 => array(
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'start',
               1 => 0,
               2 => 1,
             ),
           ),
         ),
         3 => array(
           'k' => array(
             0 => 'S',
             1 => 20,
           ),
           'map' => array(
             0 => 'S',
             1 => 21,
           ),
           'list' => array(
             0 => 'S',
             1 => 71,
           ),
         ),
         4 => array(
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'maybe_optional',
               1 => 'yes',
               2 => 2,
             ),
           ),
         ),
         5 => array(
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'maybe_comment',
               1 => 'no',
               2 => 1,
             ),
           ),
           '(' => array(
             0 => 'S',
             1 => 7,
           ),
         ),
         6 => array(
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'maybe_comment',
               1 => 'yes',
               2 => 2,
             ),
           ),
         ),
         7 => array(
           'cm' => array(
             0 => 'S',
             1 => 11,
           ),
         ),
         8 => array(
           ')' => array(
             0 => 'S',
             1 => 9,
           ),
           'cm' => array(
             0 => 'S',
             1 => 10,
           ),
         ),
         9 => array(
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'comment',
               1 => 0,
               2 => 3,
             ),
           ),
         ),
         10 => array(
           ')' => array(
             0 => 'R',
             1 => array(
               0 => 'comment_text',
               1 => 0,
               2 => 2,
             ),
           ),
           'cm' => array(
             0 => 'R',
             1 => array(
               0 => 'comment_text',
               1 => 0,
               2 => 2,
             ),
           ),
         ),
         11 => array(
           ')' => array(
             0 => 'R',
             1 => array(
               0 => 'comment_text',
               1 => 1,
               2 => 1,
             ),
           ),
           'cm' => array(
             0 => 'R',
             1 => array(
               0 => 'comment_text',
               1 => 1,
               2 => 1,
             ),
           ),
         ),
         12 => array(
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'type',
               1 => 'no',
               2 => 1,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'type',
               1 => 'no',
               2 => 1,
             ),
           ),
           '?' => array(
             0 => 'S',
             1 => 13,
           ),
         ),
         13 => array(
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'type',
               1 => 'yes',
               2 => 2,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'type',
               1 => 'yes',
               2 => 2,
             ),
           ),
         ),
         14 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'S',
             1 => 15,
           ),
         ),
         15 => array(
           'k' => array(
             0 => 'S',
             1 => 20,
           ),
           'map' => array(
             0 => 'S',
             1 => 21,
           ),
           'list' => array(
             0 => 'S',
             1 => 71,
           ),
         ),
         16 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
         ),
         17 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
         ),
         18 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
         ),
         19 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
         ),
         20 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
         ),
         21 => array(
           '<' => array(
             0 => 'S',
             1 => 22,
           ),
         ),
         22 => array(
           'k' => array(
             0 => 'S',
             1 => 57,
           ),
           'map' => array(
             0 => 'S',
             1 => 58,
           ),
           'list' => array(
             0 => 'S',
             1 => 67,
           ),
         ),
         23 => array(
           ',' => array(
             0 => 'S',
             1 => 24,
           ),
         ),
         24 => array(
           'k' => array(
             0 => 'S',
             1 => 35,
           ),
           'map' => array(
             0 => 'S',
             1 => 36,
           ),
           'list' => array(
             0 => 'S',
             1 => 45,
           ),
         ),
         25 => array(
           '>' => array(
             0 => 'S',
             1 => 26,
           ),
         ),
         26 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
         ),
         27 => array(
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'type',
               1 => 'no',
               2 => 1,
             ),
           ),
           '?' => array(
             0 => 'S',
             1 => 28,
           ),
         ),
         28 => array(
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'type',
               1 => 'yes',
               2 => 2,
             ),
           ),
         ),
         29 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'S',
             1 => 30,
           ),
         ),
         30 => array(
           'k' => array(
             0 => 'S',
             1 => 35,
           ),
           'map' => array(
             0 => 'S',
             1 => 36,
           ),
           'list' => array(
             0 => 'S',
             1 => 45,
           ),
         ),
         31 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
         ),
         32 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
         ),
         33 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
         ),
         34 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
         ),
         35 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
         ),
         36 => array(
           '<' => array(
             0 => 'S',
             1 => 37,
           ),
         ),
         37 => array(
           'k' => array(
             0 => 'S',
             1 => 57,
           ),
           'map' => array(
             0 => 'S',
             1 => 58,
           ),
           'list' => array(
             0 => 'S',
             1 => 67,
           ),
         ),
         38 => array(
           ',' => array(
             0 => 'S',
             1 => 39,
           ),
         ),
         39 => array(
           'k' => array(
             0 => 'S',
             1 => 35,
           ),
           'map' => array(
             0 => 'S',
             1 => 36,
           ),
           'list' => array(
             0 => 'S',
             1 => 45,
           ),
         ),
         40 => array(
           '>' => array(
             0 => 'S',
             1 => 41,
           ),
         ),
         41 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
         ),
         42 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'S',
             1 => 43,
           ),
         ),
         43 => array(
           'k' => array(
             0 => 'S',
             1 => 35,
           ),
           'map' => array(
             0 => 'S',
             1 => 36,
           ),
           'list' => array(
             0 => 'S',
             1 => 45,
           ),
         ),
         44 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
         ),
         45 => array(
           '<' => array(
             0 => 'S',
             1 => 46,
           ),
         ),
         46 => array(
           'k' => array(
             0 => 'S',
             1 => 35,
           ),
           'map' => array(
             0 => 'S',
             1 => 36,
           ),
           'list' => array(
             0 => 'S',
             1 => 45,
           ),
         ),
         47 => array(
           '>' => array(
             0 => 'S',
             1 => 48,
           ),
         ),
         48 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
           '>' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
         ),
         49 => array(
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'type',
               1 => 'no',
               2 => 1,
             ),
           ),
           '?' => array(
             0 => 'S',
             1 => 50,
           ),
         ),
         50 => array(
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'type',
               1 => 'yes',
               2 => 2,
             ),
           ),
         ),
         51 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 0,
               2 => 1,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'S',
             1 => 52,
           ),
         ),
         52 => array(
           'k' => array(
             0 => 'S',
             1 => 57,
           ),
           'map' => array(
             0 => 'S',
             1 => 58,
           ),
           'list' => array(
             0 => 'S',
             1 => 67,
           ),
         ),
         53 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 0,
               2 => 3,
             ),
           ),
         ),
         54 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 0,
               2 => 1,
             ),
           ),
         ),
         55 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 1,
               2 => 1,
             ),
           ),
         ),
         56 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'not_or_type',
               1 => 2,
               2 => 1,
             ),
           ),
         ),
         57 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'basic_type',
               1 => 0,
               2 => 1,
             ),
           ),
         ),
         58 => array(
           '<' => array(
             0 => 'S',
             1 => 59,
           ),
         ),
         59 => array(
           'k' => array(
             0 => 'S',
             1 => 57,
           ),
           'map' => array(
             0 => 'S',
             1 => 58,
           ),
           'list' => array(
             0 => 'S',
             1 => 67,
           ),
         ),
         60 => array(
           ',' => array(
             0 => 'S',
             1 => 61,
           ),
         ),
         61 => array(
           'k' => array(
             0 => 'S',
             1 => 35,
           ),
           'map' => array(
             0 => 'S',
             1 => 36,
           ),
           'list' => array(
             0 => 'S',
             1 => 45,
           ),
         ),
         62 => array(
           '>' => array(
             0 => 'S',
             1 => 63,
           ),
         ),
         63 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'map_type',
               1 => 0,
               2 => 6,
             ),
           ),
         ),
         64 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 1,
               2 => 1,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'S',
             1 => 65,
           ),
         ),
         65 => array(
           'k' => array(
             0 => 'S',
             1 => 57,
           ),
           'map' => array(
             0 => 'S',
             1 => 58,
           ),
           'list' => array(
             0 => 'S',
             1 => 67,
           ),
         ),
         66 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
         ),
         67 => array(
           '<' => array(
             0 => 'S',
             1 => 68,
           ),
         ),
         68 => array(
           'k' => array(
             0 => 'S',
             1 => 35,
           ),
           'map' => array(
             0 => 'S',
             1 => 36,
           ),
           'list' => array(
             0 => 'S',
             1 => 45,
           ),
         ),
         69 => array(
           '>' => array(
             0 => 'S',
             1 => 70,
           ),
         ),
         70 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
           ',' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
         ),
         71 => array(
           '<' => array(
             0 => 'S',
             1 => 72,
           ),
         ),
         72 => array(
           'k' => array(
             0 => 'S',
             1 => 35,
           ),
           'map' => array(
             0 => 'S',
             1 => 36,
           ),
           'list' => array(
             0 => 'S',
             1 => 45,
           ),
         ),
         73 => array(
           '>' => array(
             0 => 'S',
             1 => 74,
           ),
         ),
         74 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'list_type',
               1 => 0,
               2 => 4,
             ),
           ),
         ),
         75 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'some_type',
               1 => 1,
               2 => 1,
             ),
           ),
           '|' => array(
             0 => 'S',
             1 => 76,
           ),
         ),
         76 => array(
           'k' => array(
             0 => 'S',
             1 => 20,
           ),
           'map' => array(
             0 => 'S',
             1 => 21,
           ),
           'list' => array(
             0 => 'S',
             1 => 71,
           ),
         ),
         77 => array(
           '?' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
           '(' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
           '|' => array(
             0 => 'R',
             1 => array(
               0 => 'or_type',
               1 => 1,
               2 => 3,
             ),
           ),
         ),
         78 => array(
           '(end-of-file)' => array(
             0 => 'R',
             1 => array(
               0 => 'maybe_optional',
               1 => 'no',
               2 => 1,
             ),
           ),
         ),
       ),
       array(
         0 => array(
           'start' => 1,
           'maybe_optional' => 2,
           'maybe_comment' => 78,
           'type' => 5,
           'some_type' => 12,
           'or_type' => 14,
           'not_or_type' => 75,
           'basic_type' => 17,
           'map_type' => 18,
           'list_type' => 19,
         ),
         3 => array(
           'maybe_comment' => 4,
           'type' => 5,
           'some_type' => 12,
           'or_type' => 14,
           'not_or_type' => 75,
           'basic_type' => 17,
           'map_type' => 18,
           'list_type' => 19,
         ),
         5 => array(
           'comment' => 6,
         ),
         7 => array(
           'comment_text' => 8,
         ),
         15 => array(
           'not_or_type' => 16,
           'basic_type' => 17,
           'map_type' => 18,
           'list_type' => 19,
         ),
         22 => array(
           'type' => 23,
           'some_type' => 49,
           'or_type' => 51,
           'not_or_type' => 64,
           'basic_type' => 54,
           'map_type' => 55,
           'list_type' => 56,
         ),
         24 => array(
           'type' => 25,
           'some_type' => 27,
           'or_type' => 29,
           'not_or_type' => 42,
           'basic_type' => 32,
           'map_type' => 33,
           'list_type' => 34,
         ),
         30 => array(
           'not_or_type' => 31,
           'basic_type' => 32,
           'map_type' => 33,
           'list_type' => 34,
         ),
         37 => array(
           'type' => 38,
           'some_type' => 49,
           'or_type' => 51,
           'not_or_type' => 64,
           'basic_type' => 54,
           'map_type' => 55,
           'list_type' => 56,
         ),
         39 => array(
           'type' => 40,
           'some_type' => 27,
           'or_type' => 29,
           'not_or_type' => 42,
           'basic_type' => 32,
           'map_type' => 33,
           'list_type' => 34,
         ),
         43 => array(
           'not_or_type' => 44,
           'basic_type' => 32,
           'map_type' => 33,
           'list_type' => 34,
         ),
         46 => array(
           'type' => 47,
           'some_type' => 27,
           'or_type' => 29,
           'not_or_type' => 42,
           'basic_type' => 32,
           'map_type' => 33,
           'list_type' => 34,
         ),
         52 => array(
           'not_or_type' => 53,
           'basic_type' => 54,
           'map_type' => 55,
           'list_type' => 56,
         ),
         59 => array(
           'type' => 60,
           'some_type' => 49,
           'or_type' => 51,
           'not_or_type' => 64,
           'basic_type' => 54,
           'map_type' => 55,
           'list_type' => 56,
         ),
         61 => array(
           'type' => 62,
           'some_type' => 27,
           'or_type' => 29,
           'not_or_type' => 42,
           'basic_type' => 32,
           'map_type' => 33,
           'list_type' => 34,
         ),
         65 => array(
           'not_or_type' => 66,
           'basic_type' => 54,
           'map_type' => 55,
           'list_type' => 56,
         ),
         68 => array(
           'type' => 69,
           'some_type' => 27,
           'or_type' => 29,
           'not_or_type' => 42,
           'basic_type' => 32,
           'map_type' => 33,
           'list_type' => 34,
         ),
         72 => array(
           'type' => 73,
           'some_type' => 27,
           'or_type' => 29,
           'not_or_type' => 42,
           'basic_type' => 32,
           'map_type' => 33,
           'list_type' => 34,
         ),
         76 => array(
           'not_or_type' => 77,
           'basic_type' => 17,
           'map_type' => 18,
           'list_type' => 19,
         ),
       ),
       '(end-of-file)',
       $tokens,
       $callback);
   }
 
 }
diff --git a/src/parser/aast/api/AASTNodeList.php b/src/parser/aast/api/AASTNodeList.php
index 25e8240..d8e6ade 100644
--- a/src/parser/aast/api/AASTNodeList.php
+++ b/src/parser/aast/api/AASTNodeList.php
@@ -1,137 +1,135 @@
 <?php
 
 final class AASTNodeList implements Iterator, Countable {
 
   protected $list;
   protected $tree;
   protected $ids;
   protected $pos;
 
   public function count() {
     return count($this->ids);
   }
 
   public function current() {
     return $this->list[$this->key()];
   }
 
   public function rewind() {
     $this->pos = 0;
   }
 
   public function valid() {
     return $this->pos < count($this->ids);
   }
 
   public function next() {
     $this->pos++;
   }
 
   public function key() {
     return $this->ids[$this->pos];
   }
 
   public static function newFromTreeAndNodes(AASTTree $tree, array $nodes) {
     assert_instances_of($nodes, 'AASTNode');
     $obj = new AASTNodeList();
     $obj->tree = $tree;
     $obj->list = $nodes;
     $obj->ids  = array_keys($nodes);
     return $obj;
   }
 
   public static function newFromTree(AASTTree $tree) {
     $obj = new AASTNodeList();
     $obj->tree = $tree;
     $obj->list = array(0 => $tree->getRootNode());
     $obj->ids = array(0 => 0);
     return $obj;
   }
 
-  protected function __construct() {
-
-  }
+  protected function __construct() {}
 
   public function getDescription() {
     if (empty($this->list)) {
       return 'an empty node list';
     }
 
     $desc = array();
     $desc[] = 'a list of '.count($this->list).' nodes:';
     foreach ($this->list as $node) {
       $desc[] = '  '.$node->getDescription().';';
     }
 
     return implode("\n", $desc);
   }
 
 
 
   protected function newList(array $nodes) {
     return AASTNodeList::newFromTreeAndNodes(
       $this->tree,
       $nodes);
   }
 
   public function selectDescendantsOfType($type_name) {
     $results = array();
     foreach ($this->list as $id => $node) {
       $results += $node->selectDescendantsOfType($type_name)->getRawNodes();
     }
     return $this->newList($results);
   }
 
   public function selectDescendantsOfTypes(array $type_names) {
     $results = array();
     foreach ($type_names as $type_name) {
       foreach ($this->list as $id => $node) {
         $results += $node->selectDescendantsOfType($type_name)->getRawNodes();
       }
     }
     return $this->newList($results);
   }
 
   public function getChildrenByIndex($index) {
     $results = array();
     foreach ($this->list as $id => $node) {
       $child = $node->getChildByIndex($index);
       $results[$child->getID()] = $child;
     }
     return $this->newList($results);
   }
 
   public function add(AASTNodeList $list) {
     foreach ($list->list as $id => $node) {
       $this->list[$id] = $node;
     }
     $this->ids = array_keys($this->list);
     return $this;
   }
 
 
   protected function executeSelectDescendantsOfType($node, $type) {
     $results = array();
     foreach ($node->getChildren() as $id => $child) {
       if ($child->getTypeID() == $type) {
         $results[$id] = $child;
       } else {
         $results += $this->executeSelectDescendantsOfType($child, $type);
       }
     }
     return $results;
   }
 
   public function getTokens() {
     $tokens = array();
     foreach ($this->list as $node) {
       $tokens += $node->getTokens();
     }
     return $tokens;
   }
 
   public function getRawNodes() {
     return $this->list;
   }
 
 }
diff --git a/src/serviceprofiler/PhutilServiceProfiler.php b/src/serviceprofiler/PhutilServiceProfiler.php
index 815ed11..4429488 100644
--- a/src/serviceprofiler/PhutilServiceProfiler.php
+++ b/src/serviceprofiler/PhutilServiceProfiler.php
@@ -1,162 +1,161 @@
 <?php
 
 /**
  * Simple event store for service calls, so they can be printed to stdout or
  * displayed in a debug console.
  */
 final class PhutilServiceProfiler {
 
   private static $instance;
   private $listeners = array();
   private $events = array();
   private $logSize = 0;
   private $discardMode = false;
 
-  private function __construct() {
-  }
+  private function __construct() {}
 
   public function enableDiscardMode() {
     $this->discardMode = true;
   }
 
   public static function getInstance() {
     if (empty(self::$instance)) {
       self::$instance = new PhutilServiceProfiler();
     }
     return self::$instance;
   }
 
   public function beginServiceCall(array $data) {
     $data['begin'] = microtime(true);
     $id = $this->logSize++;
     $this->events[$id] = $data;
     foreach ($this->listeners as $listener) {
       call_user_func($listener, 'begin', $id, $data);
     }
     return $id;
   }
 
   public function endServiceCall($call_id, array $data) {
     $data = ($this->events[$call_id] + $data);
     $data['end'] = microtime(true);
     $data['duration'] = ($data['end'] - $data['begin']);
     $this->events[$call_id] = $data;
     foreach ($this->listeners as $listener) {
       call_user_func($listener, 'end', $call_id, $data);
     }
     if ($this->discardMode) {
       unset($this->events[$call_id]);
     }
   }
 
   public function getServiceCallLog() {
     return $this->events;
   }
 
   public function addListener($callback) {
     $this->listeners[] = $callback;
   }
 
   public static function installEchoListener() {
     $instance = PhutilServiceProfiler::getInstance();
     $instance->addListener(array('PhutilServiceProfiler', 'echoListener'));
   }
 
   public static function echoListener($type, $id, $data) {
     $is_begin = false;
     $is_end   = false;
 
     switch ($type) {
       case 'begin':
         $is_begin = true;
         $mark = '>>>';
         break;
       case 'end':
         $is_end = true;
         $mark = '<<<';
         break;
       default:
         $mark = null;
         break;
     }
 
     $type = idx($data, 'type', 'mystery');
 
     $desc = null;
     if ($is_begin) {
       switch ($type) {
         case 'connect':
           $desc = $data['database'];
           break;
         case 'query':
           $desc = substr($data['query'], 0, 512);
           break;
         case 'multi-query':
           $desc = array();
           foreach ($data['queries'] as $query) {
             $desc[] = substr($query, 0, 256);
           }
           $desc = implode('; ', $desc);
           break;
         case 'exec':
           $desc = '$ '.$data['command'];
           break;
         case 'conduit':
           if (isset($data['size'])) {
             $desc = $data['method'].'() <bytes = '.$data['size'].'>';
           } else {
             $desc = $data['method'].'()';
           }
           break;
         case 'http':
           $desc = phutil_censor_credentials($data['uri']);
           break;
         case 'lint':
           $desc = $data['linter'];
           if (isset($data['paths'])) {
             $desc .= ' <paths = '.count($data['paths']).'>';
           }
           break;
         case 'lock':
           $desc = $data['name'];
           break;
         case 'event':
           $desc = $data['kind'].' <listeners = '.$data['count'].'>';
           break;
         case 'ldap':
           $call = idx($data, 'call', '?');
           $params = array();
           switch ($call) {
             case 'connect':
               $params[] = $data['host'].':'.$data['port'];
               break;
             case 'start-tls':
               break;
             case 'bind':
               $params[] = $data['user'];
               break;
             case 'search':
               $params[] = $data['dn'];
               $params[] = $data['query'];
               break;
             default:
               $params[] = '?';
               break;
           }
           $desc = "{$call} (".implode(', ', $params).")";
           break;
       }
     } else if ($is_end) {
       $desc = number_format((int)(1000000 * $data['duration'])).' us';
     }
 
     $console = PhutilConsole::getConsole();
     $console->writeLog(
       "%s [%s] <%s> %s\n",
       $mark,
       $id,
       $type,
       $desc);
   }
 
 }