[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/lib/simpletestlib/ -> expectation.php (source)

   1  <?php
   2      /**
   3       *    base include file for SimpleTest
   4       *    @package    SimpleTest
   5       *    @subpackage    UnitTester
   6       *    @version    $Id$
   7       */
   8       
   9      /**#@+
  10       *    include other SimpleTest class files
  11       */
  12      require_once(dirname(__FILE__) . '/dumper.php');
  13      require_once(dirname(__FILE__) . '/compatibility.php');
  14      /**#@-*/
  15      
  16      /**
  17       *    Assertion that can display failure information.
  18       *    Also includes various helper methods.
  19       *    @package SimpleTest
  20       *    @subpackage UnitTester
  21       *    @abstract
  22       */
  23      class SimpleExpectation {
  24          var $_dumper;
  25          var $_message;
  26          
  27          /**
  28           *    Creates a dumper for displaying values and sets
  29           *    the test message.
  30           *    @param string $message    Customised message on failure.
  31           */
  32          function SimpleExpectation($message = '%s') {
  33              $this->_message = $message;
  34          }
  35          
  36          /**
  37           *    Tests the expectation. True if correct.
  38           *    @param mixed $compare        Comparison value.
  39           *    @return boolean              True if correct.
  40           *    @access public
  41           *    @abstract
  42           */
  43          function test($compare) {
  44          }
  45          
  46          /**
  47           *    Returns a human readable test message.
  48           *    @param mixed $compare      Comparison value.
  49           *    @return string             Description of success
  50           *                               or failure.
  51           *    @access public
  52           *    @abstract
  53           */
  54          function testMessage($compare) {
  55          }
  56          
  57          /**
  58           *    Overlays the generated message onto the stored user
  59           *    message. An additional message can be interjected.
  60           *    @param mixed $compare        Comparison value.
  61           *    @param SimpleDumper $dumper  For formatting the results.
  62           *    @return string               Description of success
  63           *                                 or failure.
  64           *    @access public
  65           */
  66          function overlayMessage($compare, $dumper) {
  67              $this->_dumper = $dumper;
  68              return sprintf($this->_message, $this->testMessage($compare));
  69          }
  70          
  71          /**
  72           *    Accessor for the dumper.
  73           *    @return SimpleDumper    Current value dumper.
  74           *    @access protected
  75           */
  76          function &_getDumper() {
  77              return $this->_dumper;
  78          }
  79          
  80          /**
  81           *    Test to see if a value is an expectation object.
  82           *    A useful utility method.
  83           *    @param mixed $expectation    Hopefully an Epectation
  84           *                                 class.
  85           *    @return boolean              True if descended from
  86           *                                 this class.
  87           *    @access public
  88           *    @static
  89           */
  90          function isExpectation($expectation) {
  91              return is_object($expectation) &&
  92                      SimpleTestCompatibility::isA($expectation, 'SimpleExpectation');
  93          }
  94      }
  95  
  96      /**
  97       *    A wildcard expectation always matches.
  98       *    @package SimpleTest
  99       *    @subpackage MockObjects
 100       */
 101      class AnythingExpectation extends SimpleExpectation {
 102  
 103          /**
 104           *    Tests the expectation. Always true.
 105           *    @param mixed $compare  Ignored.
 106           *    @return boolean        True.
 107           *    @access public
 108           */
 109          function test($compare) {
 110              return true;
 111          }
 112  
 113          /**
 114           *    Returns a human readable test message.
 115           *    @param mixed $compare      Comparison value.
 116           *    @return string             Description of success
 117           *                               or failure.
 118           *    @access public
 119           */
 120          function testMessage($compare) {
 121              $dumper = &$this->_getDumper();
 122              return 'Anything always matches [' . $dumper->describeValue($compare) . ']';
 123          }
 124      }
 125  
 126      /**
 127       *    An expectation that passes on boolean true.
 128       *    @package SimpleTest
 129       *    @subpackage MockObjects
 130       */
 131      class TrueExpectation extends SimpleExpectation {
 132  
 133          /**
 134           *    Tests the expectation.
 135           *    @param mixed $compare  Should be true.
 136           *    @return boolean        True on match.
 137           *    @access public
 138           */
 139          function test($compare) {
 140              return (boolean)$compare;
 141          }
 142  
 143          /**
 144           *    Returns a human readable test message.
 145           *    @param mixed $compare      Comparison value.
 146           *    @return string             Description of success
 147           *                               or failure.
 148           *    @access public
 149           */
 150          function testMessage($compare) {
 151              $dumper = &$this->_getDumper();
 152              return 'Expected true, got [' . $dumper->describeValue($compare) . ']';
 153          }
 154      }
 155      
 156      /**
 157       *    An expectation that passes on boolean false.
 158       *    @package SimpleTest
 159       *    @subpackage MockObjects
 160       */
 161      class FalseExpectation extends SimpleExpectation {
 162  
 163          /**
 164           *    Tests the expectation.
 165           *    @param mixed $compare  Should be false.
 166           *    @return boolean        True on match.
 167           *    @access public
 168           */
 169          function test($compare) {
 170              return ! (boolean)$compare;
 171          }
 172  
 173          /**
 174           *    Returns a human readable test message.
 175           *    @param mixed $compare      Comparison value.
 176           *    @return string             Description of success
 177           *                               or failure.
 178           *    @access public
 179           */
 180          function testMessage($compare) {
 181              $dumper = &$this->_getDumper();
 182              return 'Expected false, got [' . $dumper->describeValue($compare) . ']';
 183          }
 184      }
 185      
 186      /**
 187       *    Test for equality.
 188       *      @package SimpleTest
 189       *      @subpackage UnitTester
 190       */
 191      class EqualExpectation extends SimpleExpectation {
 192          var $_value;
 193          
 194          /**
 195           *    Sets the value to compare against.
 196           *    @param mixed $value        Test value to match.
 197           *    @param string $message     Customised message on failure.
 198           *    @access public
 199           */
 200          function EqualExpectation($value, $message = '%s') {
 201              $this->SimpleExpectation($message);
 202              $this->_value = $value;
 203          }
 204          
 205          /**
 206           *    Tests the expectation. True if it matches the
 207           *    held value.
 208           *    @param mixed $compare        Comparison value.
 209           *    @return boolean              True if correct.
 210           *    @access public
 211           */
 212          function test($compare) {
 213              return (($this->_value == $compare) && ($compare == $this->_value));
 214          }
 215          
 216          /**
 217           *    Returns a human readable test message.
 218           *    @param mixed $compare      Comparison value.
 219           *    @return string             Description of success
 220           *                               or failure.
 221           *    @access public
 222           */
 223          function testMessage($compare) {
 224              if ($this->test($compare)) {
 225                  return "Equal expectation [" . $this->_dumper->describeValue($this->_value) . "]";
 226              } else {
 227                  return "Equal expectation fails " .
 228                          $this->_dumper->describeDifference($this->_value, $compare);
 229              }
 230          }
 231  
 232          /**
 233           *    Accessor for comparison value.
 234           *    @return mixed       Held value to compare with.
 235           *    @access protected
 236           */
 237          function _getValue() {
 238              return $this->_value;
 239          }
 240      }
 241      
 242      /**
 243       *    Test for inequality.
 244       *      @package SimpleTest
 245       *      @subpackage UnitTester
 246       */
 247      class NotEqualExpectation extends EqualExpectation {
 248          
 249          /**
 250           *    Sets the value to compare against.
 251           *    @param mixed $value       Test value to match.
 252           *    @param string $message    Customised message on failure.
 253           *    @access public
 254           */
 255          function NotEqualExpectation($value, $message = '%s') {
 256              $this->EqualExpectation($value, $message);
 257          }
 258          
 259          /**
 260           *    Tests the expectation. True if it differs from the
 261           *    held value.
 262           *    @param mixed $compare        Comparison value.
 263           *    @return boolean              True if correct.
 264           *    @access public
 265           */
 266          function test($compare) {
 267              return ! parent::test($compare);
 268          }
 269          
 270          /**
 271           *    Returns a human readable test message.
 272           *    @param mixed $compare      Comparison value.
 273           *    @return string             Description of success
 274           *                               or failure.
 275           *    @access public
 276           */
 277          function testMessage($compare) {
 278              $dumper = &$this->_getDumper();
 279              if ($this->test($compare)) {
 280                  return "Not equal expectation passes " .
 281                          $dumper->describeDifference($this->_getValue(), $compare);
 282              } else {
 283                  return "Not equal expectation fails [" .
 284                          $dumper->describeValue($this->_getValue()) .
 285                          "] matches";
 286              }
 287          }
 288      }
 289      
 290      /**
 291       *    Test for being within a range.
 292       *      @package SimpleTest
 293       *      @subpackage UnitTester
 294       */
 295      class WithinMarginExpectation extends SimpleExpectation {
 296          var $_upper;
 297          var $_lower;
 298          
 299          /**
 300           *    Sets the value to compare against and the fuzziness of
 301           *    the match. Used for comparing floating point values.
 302           *    @param mixed $value        Test value to match.
 303           *    @param mixed $margin       Fuzziness of match.
 304           *    @param string $message     Customised message on failure.
 305           *    @access public
 306           */
 307          function WithinMarginExpectation($value, $margin, $message = '%s') {
 308              $this->SimpleExpectation($message);
 309              $this->_upper = $value + $margin;
 310              $this->_lower = $value - $margin;
 311          }
 312          
 313          /**
 314           *    Tests the expectation. True if it matches the
 315           *    held value.
 316           *    @param mixed $compare        Comparison value.
 317           *    @return boolean              True if correct.
 318           *    @access public
 319           */
 320          function test($compare) {
 321              return (($compare <= $this->_upper) && ($compare >= $this->_lower));
 322          }
 323          
 324          /**
 325           *    Returns a human readable test message.
 326           *    @param mixed $compare      Comparison value.
 327           *    @return string             Description of success
 328           *                               or failure.
 329           *    @access public
 330           */
 331          function testMessage($compare) {
 332              if ($this->test($compare)) {
 333                  return $this->_withinMessage($compare);
 334              } else {
 335                  return $this->_outsideMessage($compare);
 336              }
 337          }
 338          
 339          /**
 340           *    Creates a the message for being within the range.
 341           *    @param mixed $compare        Value being tested.
 342           *    @access private
 343           */
 344          function _withinMessage($compare) {
 345              return "Within expectation [" . $this->_dumper->describeValue($this->_lower) . "] and [" .
 346                      $this->_dumper->describeValue($this->_upper) . "]";
 347          }
 348          
 349          /**
 350           *    Creates a the message for being within the range.
 351           *    @param mixed $compare        Value being tested.
 352           *    @access private
 353           */
 354          function _outsideMessage($compare) {
 355              if ($compare > $this->_upper) {
 356                  return "Outside expectation " .
 357                          $this->_dumper->describeDifference($compare, $this->_upper);
 358              } else {
 359                  return "Outside expectation " .
 360                          $this->_dumper->describeDifference($compare, $this->_lower);
 361              }
 362          }
 363      }
 364      
 365      /**
 366       *    Test for being outside of a range.
 367       *      @package SimpleTest
 368       *      @subpackage UnitTester
 369       */
 370      class OutsideMarginExpectation extends WithinMarginExpectation {
 371          
 372          /**
 373           *    Sets the value to compare against and the fuzziness of
 374           *    the match. Used for comparing floating point values.
 375           *    @param mixed $value        Test value to not match.
 376           *    @param mixed $margin       Fuzziness of match.
 377           *    @param string $message     Customised message on failure.
 378           *    @access public
 379           */
 380          function OutsideMarginExpectation($value, $margin, $message = '%s') {
 381              $this->WithinMarginExpectation($value, $margin, $message);
 382          }
 383          
 384          /**
 385           *    Tests the expectation. True if it matches the
 386           *    held value.
 387           *    @param mixed $compare        Comparison value.
 388           *    @return boolean              True if correct.
 389           *    @access public
 390           */
 391          function test($compare) {
 392              return ! parent::test($compare);
 393          }
 394          
 395          /**
 396           *    Returns a human readable test message.
 397           *    @param mixed $compare      Comparison value.
 398           *    @return string             Description of success
 399           *                               or failure.
 400           *    @access public
 401           */
 402          function testMessage($compare) {
 403              if (! $this->test($compare)) {
 404                  return $this->_withinMessage($compare);
 405              } else {
 406                  return $this->_outsideMessage($compare);
 407              }
 408          }
 409      }
 410      
 411      /**
 412       *    Test for identity.
 413       *    @package SimpleTest
 414       *    @subpackage UnitTester
 415       */
 416      class IdenticalExpectation extends EqualExpectation {
 417          
 418          /**
 419           *    Sets the value to compare against.
 420           *    @param mixed $value       Test value to match.
 421           *    @param string $message    Customised message on failure.
 422           *    @access public
 423           */
 424          function IdenticalExpectation($value, $message = '%s') {
 425              $this->EqualExpectation($value, $message);
 426          }
 427          
 428          /**
 429           *    Tests the expectation. True if it exactly
 430           *    matches the held value.
 431           *    @param mixed $compare        Comparison value.
 432           *    @return boolean              True if correct.
 433           *    @access public
 434           */
 435          function test($compare) {
 436              return SimpleTestCompatibility::isIdentical($this->_getValue(), $compare);
 437          }
 438          
 439          /**
 440           *    Returns a human readable test message.
 441           *    @param mixed $compare      Comparison value.
 442           *    @return string             Description of success
 443           *                               or failure.
 444           *    @access public
 445           */
 446          function testMessage($compare) {
 447              $dumper = &$this->_getDumper();
 448              if ($this->test($compare)) {
 449                  return "Identical expectation [" . $dumper->describeValue($this->_getValue()) . "]";
 450              } else {
 451                  return "Identical expectation [" . $dumper->describeValue($this->_getValue()) .
 452                          "] fails with [" .
 453                          $dumper->describeValue($compare) . "] " .
 454                          $dumper->describeDifference($this->_getValue(), $compare, TYPE_MATTERS);
 455              }
 456          }
 457      }
 458      
 459      /**
 460       *    Test for non-identity.
 461       *    @package SimpleTest
 462       *    @subpackage UnitTester
 463       */
 464      class NotIdenticalExpectation extends IdenticalExpectation {
 465          
 466          /**
 467           *    Sets the value to compare against.
 468           *    @param mixed $value        Test value to match.
 469           *    @param string $message     Customised message on failure.
 470           *    @access public
 471           */
 472          function NotIdenticalExpectation($value, $message = '%s') {
 473              $this->IdenticalExpectation($value, $message);
 474          }
 475          
 476          /**
 477           *    Tests the expectation. True if it differs from the
 478           *    held value.
 479           *    @param mixed $compare        Comparison value.
 480           *    @return boolean              True if correct.
 481           *    @access public
 482           */
 483          function test($compare) {
 484              return ! parent::test($compare);
 485          }
 486          
 487          /**
 488           *    Returns a human readable test message.
 489           *    @param mixed $compare      Comparison value.
 490           *    @return string             Description of success
 491           *                               or failure.
 492           *    @access public
 493           */
 494          function testMessage($compare) {
 495              $dumper = &$this->_getDumper();
 496              if ($this->test($compare)) {
 497                  return "Not identical expectation passes " .
 498                          $dumper->describeDifference($this->_getValue(), $compare, TYPE_MATTERS);
 499              } else {
 500                  return "Not identical expectation [" . $dumper->describeValue($this->_getValue()) . "] matches";
 501              }
 502          }
 503      }
 504      
 505      /**
 506       *    Test for a pattern using Perl regex rules.
 507       *    @package SimpleTest
 508       *    @subpackage UnitTester
 509       */
 510      class PatternExpectation extends SimpleExpectation {
 511          var $_pattern;
 512          
 513          /**
 514           *    Sets the value to compare against.
 515           *    @param string $pattern    Pattern to search for.
 516           *    @param string $message    Customised message on failure.
 517           *    @access public
 518           */
 519          function PatternExpectation($pattern, $message = '%s') {
 520              $this->SimpleExpectation($message);
 521              $this->_pattern = $pattern;
 522          }
 523          
 524          /**
 525           *    Accessor for the pattern.
 526           *    @return string       Perl regex as string.
 527           *    @access protected
 528           */
 529          function _getPattern() {
 530              return $this->_pattern;
 531          }
 532          
 533          /**
 534           *    Tests the expectation. True if the Perl regex
 535           *    matches the comparison value.
 536           *    @param string $compare        Comparison value.
 537           *    @return boolean               True if correct.
 538           *    @access public
 539           */
 540          function test($compare) {
 541              return (boolean)preg_match($this->_getPattern(), $compare);
 542          }
 543          
 544          /**
 545           *    Returns a human readable test message.
 546           *    @param mixed $compare      Comparison value.
 547           *    @return string             Description of success
 548           *                               or failure.
 549           *    @access public
 550           */
 551          function testMessage($compare) {
 552              if ($this->test($compare)) {
 553                  return $this->_describePatternMatch($this->_getPattern(), $compare);
 554              } else {
 555                  $dumper = &$this->_getDumper();
 556                  return "Pattern [" . $this->_getPattern() .
 557                          "] not detected in [" .
 558                          $dumper->describeValue($compare) . "]";
 559              }
 560          }
 561          
 562          /**
 563           *    Describes a pattern match including the string
 564           *    found and it's position.
 565           *    @package SimpleTest
 566           *    @subpackage UnitTester
 567           *    @param string $pattern        Regex to match against.
 568           *    @param string $subject        Subject to search.
 569           *    @access protected
 570           */
 571          function _describePatternMatch($pattern, $subject) {
 572              preg_match($pattern, $subject, $matches);
 573              $position = strpos($subject, $matches[0]);
 574              $dumper = $this->_getDumper();
 575              return "Pattern [$pattern] detected at character [$position] in [" .
 576                      $dumper->describeValue($subject) . "] as [" .
 577                      $matches[0] . "] in region [" .
 578                      $dumper->clipString($subject, 100, $position) . "]";
 579          }
 580      }
 581      
 582      /**
 583       *      @deprecated
 584       */
 585      class WantedPatternExpectation extends PatternExpectation {
 586      }
 587      
 588      /**
 589       *    Fail if a pattern is detected within the
 590       *    comparison.
 591       *      @package SimpleTest
 592       *      @subpackage UnitTester
 593       */
 594      class NoPatternExpectation extends PatternExpectation {
 595          
 596          /**
 597           *    Sets the reject pattern
 598           *    @param string $pattern    Pattern to search for.
 599           *    @param string $message    Customised message on failure.
 600           *    @access public
 601           */
 602          function NoPatternExpectation($pattern, $message = '%s') {
 603              $this->PatternExpectation($pattern, $message);
 604          }
 605          
 606          /**
 607           *    Tests the expectation. False if the Perl regex
 608           *    matches the comparison value.
 609           *    @param string $compare        Comparison value.
 610           *    @return boolean               True if correct.
 611           *    @access public
 612           */
 613          function test($compare) {
 614              return ! parent::test($compare);
 615          }
 616          
 617          /**
 618           *    Returns a human readable test message.
 619           *    @param string $compare      Comparison value.
 620           *    @return string              Description of success
 621           *                                or failure.
 622           *    @access public
 623           */
 624          function testMessage($compare) {
 625              if ($this->test($compare)) {
 626                  $dumper = &$this->_getDumper();
 627                  return "Pattern [" . $this->_getPattern() .
 628                          "] not detected in [" .
 629                          $dumper->describeValue($compare) . "]";
 630              } else {
 631                  return $this->_describePatternMatch($this->_getPattern(), $compare);
 632              }
 633          }
 634      }
 635      
 636      /**
 637       *    @package SimpleTest
 638       *    @subpackage UnitTester
 639       *      @deprecated
 640       */
 641      class UnwantedPatternExpectation extends NoPatternExpectation {
 642      }
 643      
 644      /**
 645       *    Tests either type or class name if it's an object.
 646       *      @package SimpleTest
 647       *      @subpackage UnitTester
 648       */
 649      class IsAExpectation extends SimpleExpectation {
 650          var $_type;
 651          
 652          /**
 653           *    Sets the type to compare with.
 654           *    @param string $type       Type or class name.
 655           *    @param string $message    Customised message on failure.
 656           *    @access public
 657           */
 658          function IsAExpectation($type, $message = '%s') {
 659              $this->SimpleExpectation($message);
 660              $this->_type = $type;
 661          }
 662          
 663          /**
 664           *    Accessor for type to check against.
 665           *    @return string    Type or class name.
 666           *    @access protected
 667           */
 668          function _getType() {
 669              return $this->_type;
 670          }
 671          
 672          /**
 673           *    Tests the expectation. True if the type or
 674           *    class matches the string value.
 675           *    @param string $compare        Comparison value.
 676           *    @return boolean               True if correct.
 677           *    @access public
 678           */
 679          function test($compare) {
 680              if (is_object($compare)) {
 681                  return SimpleTestCompatibility::isA($compare, $this->_type);
 682              } else {
 683                  return (strtolower(gettype($compare)) == $this->_canonicalType($this->_type));
 684              }
 685          }
 686  
 687          /**
 688           *    Coerces type name into a gettype() match.
 689           *    @param string $type        User type.
 690           *    @return string             Simpler type.
 691           *    @access private
 692           */
 693          function _canonicalType($type) {
 694              $type = strtolower($type);
 695              $map = array(
 696                      'bool' => 'boolean',
 697                      'float' => 'double',
 698                      'real' => 'double',
 699                      'int' => 'integer');
 700              if (isset($map[$type])) {
 701                  $type = $map[$type];
 702              }
 703              return $type;
 704          }
 705  
 706          /**
 707           *    Returns a human readable test message.
 708           *    @param mixed $compare      Comparison value.
 709           *    @return string             Description of success
 710           *                               or failure.
 711           *    @access public
 712           */
 713          function testMessage($compare) {
 714              $dumper = &$this->_getDumper();
 715              return "Value [" . $dumper->describeValue($compare) .
 716                      "] should be type [" . $this->_type . "]";
 717          }
 718      }
 719      
 720      /**
 721       *    Tests either type or class name if it's an object.
 722       *    Will succeed if the type does not match.
 723       *      @package SimpleTest
 724       *      @subpackage UnitTester
 725       */
 726      class NotAExpectation extends IsAExpectation {
 727          var $_type;
 728          
 729          /**
 730           *    Sets the type to compare with.
 731           *    @param string $type       Type or class name.
 732           *    @param string $message    Customised message on failure.
 733           *    @access public
 734           */
 735          function NotAExpectation($type, $message = '%s') {
 736              $this->IsAExpectation($type, $message);
 737          }
 738          
 739          /**
 740           *    Tests the expectation. False if the type or
 741           *    class matches the string value.
 742           *    @param string $compare        Comparison value.
 743           *    @return boolean               True if different.
 744           *    @access public
 745           */
 746          function test($compare) {
 747              return ! parent::test($compare);
 748          }
 749  
 750          /**
 751           *    Returns a human readable test message.
 752           *    @param mixed $compare      Comparison value.
 753           *    @return string             Description of success
 754           *                               or failure.
 755           *    @access public
 756           */
 757          function testMessage($compare) {
 758              $dumper = &$this->_getDumper();
 759              return "Value [" . $dumper->describeValue($compare) .
 760                      "] should not be type [" . $this->_getType() . "]";
 761          }
 762      }
 763  
 764      /**
 765       *    Tests for existance of a method in an object
 766       *      @package SimpleTest
 767       *      @subpackage UnitTester
 768       */
 769      class MethodExistsExpectation extends SimpleExpectation {
 770          var $_method;
 771          
 772          /**
 773           *    Sets the value to compare against.
 774           *    @param string $method     Method to check.
 775           *    @param string $message    Customised message on failure.
 776           *    @access public
 777           *    @return void
 778           */
 779          function MethodExistsExpectation($method, $message = '%s') {
 780              $this->SimpleExpectation($message);
 781              $this->_method = &$method;
 782          }
 783          
 784          /**
 785           *    Tests the expectation. True if the method exists in the test object.
 786           *    @param string $compare        Comparison method name.
 787           *    @return boolean               True if correct.
 788           *    @access public
 789           */
 790          function test($compare) {
 791              return (boolean)(is_object($compare) && method_exists($compare, $this->_method));
 792          }
 793          
 794          /**
 795           *    Returns a human readable test message.
 796           *    @param mixed $compare      Comparison value.
 797           *    @return string             Description of success
 798           *                               or failure.
 799           *    @access public
 800           */
 801          function testMessage($compare) {
 802              $dumper = &$this->_getDumper();
 803              if (! is_object($compare)) {
 804                  return 'No method on non-object [' . $dumper->describeValue($compare) . ']';
 805              }
 806              $method = $this->_method;
 807              return "Object [" . $dumper->describeValue($compare) .
 808                      "] should contain method [$method]";
 809          }
 810      }
 811  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7