/**
  * The internal _parse() method uses a fairly simple regular expression to match key/value pairs
  * within the Doc Comment string returned by any of our _get…Meta() methods
  * 
  * @param type $comment
  * @return type
  */
 protected function _parse($comment)
 {
     $meta = array();
     $pattern = '(@[a-zá-žA-ZÁ-Ž]+\\s*[a-zá-žA-ZÁ-Ž0-9, ()_]*)';
     $matches = StringMethods::match($comment, $pattern);
     if ($matches != null) {
         foreach ($matches as $match) {
             $parts = ArrayMethods::clean(ArrayMethods::trim(StringMethods::split($match, '[\\s]', 2)));
             $meta[$parts[0]] = true;
             if (count($parts) > 1) {
                 $meta[$parts[0]] = ArrayMethods::clean(ArrayMethods::trim(StringMethods::split($parts[1], ',')));
             }
         }
     }
     return $meta;
 }
 /**
  * The _array() method essentially deconstructs a template string into 
  * arrays of tags, text, and a combination of the two
  * 
  * @param string $source
  * @return array
  */
 protected function _array($source)
 {
     $parts = array();
     $tags = array();
     $all = array();
     $type = null;
     $delimiter = null;
     while ($source) {
         $match = $this->_implementation->match($source);
         $type = $match["type"];
         $delimiter = $match["delimiter"];
         $opener = strpos($source, $type["opener"]);
         $closer = strpos($source, $type["closer"]) + strlen($type["closer"]);
         if ($opener !== false) {
             $parts[] = substr($source, 0, $opener);
             $tags[] = substr($source, $opener, $closer - $opener);
             $source = substr($source, $closer);
         } else {
             $parts[] = $source;
             $source = "";
         }
     }
     foreach ($parts as $i => $part) {
         $all[] = $part;
         if (isset($tags[$i])) {
             $all[] = $tags[$i];
         }
     }
     return array("text" => ArrayMethods::clean($parts), "tags" => ArrayMethods::clean($tags), "all" => ArrayMethods::clean($all));
 }