You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by ch...@apache.org on 2008/08/02 16:11:44 UTC

svn commit: r681982 [18/27] - in /incubator/shindig/trunk/php: external/ external/PHPUnit/ external/PHPUnit/Extensions/ external/PHPUnit/Extensions/Database/ external/PHPUnit/Extensions/Database/Constraint/ external/PHPUnit/Extensions/Database/DB/ exte...

Added: incubator/shindig/trunk/php/external/PHPUnit/Util/Configuration.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/external/PHPUnit/Util/Configuration.php?rev=681982&view=auto
==============================================================================
--- incubator/shindig/trunk/php/external/PHPUnit/Util/Configuration.php (added)
+++ incubator/shindig/trunk/php/external/PHPUnit/Util/Configuration.php Sat Aug  2 07:11:35 2008
@@ -0,0 +1,551 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2008, Sebastian Bergmann <sb...@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *   * Neither the name of Sebastian Bergmann nor the names of his
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    SVN: $Id: Configuration.php 2111 2008-01-15 09:55:15Z sb $
+ * @link       http://www.phpunit.de/
+ * @since      File available since Release 3.2.0
+ */
+
+require_once 'PHPUnit/Util/Filter.php';
+require_once 'PHPUnit/Runner/IncludePathTestCollector.php';
+require_once 'PHPUnit/Util/XML.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * Wrapper for the PHPUnit XML configuration file.
+ *
+ * Example XML configuration file:
+ * <code>
+ * <?xml version="1.0" encoding="utf-8" ?>
+ *
+ * <phpunit>
+ *   <testsuite name="My Test Suite">
+ *     <directory suffix="Test.php">/path/to/files</directory>
+ *     <file>/path/to/MyTest.php</file>
+ *   </testsuite>
+ *
+ *   <groups>
+ *     <include>
+ *       <group>name</group>
+ *     </include>
+ *     <exclude>
+ *       <group>name</group>
+ *     </exclude>
+ *   </groups>
+ *
+ *   <filter>
+ *     <blacklist>
+ *       <directory suffix=".php">/path/to/files</directory>
+ *       <file>/path/to/file</file>
+ *       <exclude>
+ *         <directory suffix=".php">/path/to/files</directory>
+ *         <file>/path/to/file</file>
+ *       </exclude>
+ *     </blacklist>
+ *     <whitelist addUncoveredFilesFromWhitelist="true">
+ *       <directory suffix=".php">/path/to/files</directory>
+ *       <file>/path/to/file</file>
+ *       <exclude>
+ *         <directory suffix=".php">/path/to/files</directory>
+ *         <file>/path/to/file</file>
+ *       </exclude>
+ *     </whitelist>
+ *   </filter>
+ *
+ *   <logging>
+ *     <log type="coverage-html" target="/tmp/report" charset="UTF-8"
+ *          yui="true" highlight="false"
+ *          lowUpperBound="35" highLowerBound="70"/>
+ *     <log type="coverage-xml" target="/tmp/coverage.xml"/>
+ *     <log type="graphviz" target="/tmp/logfile.dot"/>
+ *     <log type="json" target="/tmp/logfile.json"/>
+ *     <log type="metrics-xml" target="/tmp/metrics.xml"/>
+ *     <log type="plain" target="/tmp/logfile.txt"/>
+ *     <log type="pmd-xml" target="/tmp/pmd.xml" cpdMinLines="5" cpdMinMatches="70"/>
+ *     <log type="tap" target="/tmp/logfile.tap"/>
+ *     <log type="test-xml" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
+ *     <log type="testdox-html" target="/tmp/testdox.html"/>
+ *     <log type="testdox-text" target="/tmp/testdox.txt"/>
+ * 
+ *     <pmd>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Project_CRAP"
+ *             threshold="5,30" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_DepthOfInheritanceTree"
+ *             threshold="6" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_EfferentCoupling"
+ *             threshold="20" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_ExcessiveClassLength"
+ *             threshold="1000" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_ExcessivePublicCount"
+ *             threshold="45" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Class_TooManyFields"
+ *             threshold="15" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_CodeCoverage"
+ *             threshold="35,70" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_CRAP"
+ *             threshold="30" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_CyclomaticComplexity"
+ *             threshold="20" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_ExcessiveMethodLength"
+ *             threshold="100" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_ExcessiveParameterList"
+ *             threshold="10" priority="1"/>
+ *       <rule class="PHPUnit_Util_Log_PMD_Rule_Function_NPathComplexity"
+ *             threshold="200" priority="1"/>
+ *     </pmd>
+ *   </logging>
+ *
+ *   <php>
+ *     <ini name="foo" value="bar"/>
+ *     <var name="foo" value="bar"/>
+ *   </php>
+ *
+ *   <selenium>
+ *     <browser name="" browser="" host="" port="" timeout="">
+ *   </selenium>
+ * </phpunit>
+ * </code>
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    Release: 3.2.9
+ * @link       http://www.phpunit.de/
+ * @since      Class available since Release 3.2.0
+ */
+class PHPUnit_Util_Configuration
+{
+    protected $document;
+    protected $xpath;
+
+    /**
+     * Loads a PHPUnit configuration file.
+     *
+     * @param  string $filename
+     * @access public
+     */
+    public function __construct($filename)
+    {
+        $this->document = PHPUnit_Util_XML::load($filename);
+        $this->xpath    = new DOMXPath($this->document);
+    }
+
+    /**
+     * Returns the configuration for SUT filtering.
+     *
+     * @return array
+     * @access public
+     * @since  Method available since Release 3.2.1
+     */
+    public function getFilterConfiguration()
+    {
+        $addUncoveredFilesFromWhitelist = TRUE;
+
+        $tmp = $this->xpath->query('filter/whitelist');
+
+        if ($tmp->length == 1 &&
+            $tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) {
+            $addUncoveredFilesFromWhitelist = $this->getBoolean(
+              (string)$tmp->item(0)->getAttribute('addUncoveredFilesFromWhitelist'),
+              TRUE
+            );
+        }
+
+        return array(
+          'blacklist' => array(
+            'include' => array(
+              'directory' => $this->readFilterDirectories(
+                'filter/blacklist/directory'
+              ),
+              'file' => $this->readFilterFiles(
+                'filter/blacklist/file'
+              )
+            ),
+            'exclude' => array(
+              'directory' => $this->readFilterDirectories(
+                'filter/blacklist/exclude/directory'
+               ),
+              'file' => $this->readFilterFiles(
+                'filter/blacklist/exclude/file'
+              )
+            )
+          ),
+          'whitelist' => array(
+            'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist,
+            'include' => array(
+              'directory' => $this->readFilterDirectories(
+                'filter/whitelist/directory'
+              ),
+              'file' => $this->readFilterFiles(
+                'filter/whitelist/file'
+              )
+            ),
+            'exclude' => array(
+              'directory' => $this->readFilterDirectories(
+                'filter/whitelist/exclude/directory'
+              ),
+              'file' => $this->readFilterFiles(
+                'filter/whitelist/exclude/file'
+              )
+            )
+          )
+        );
+    }
+
+    /**
+     * Returns the configuration for groups.
+     *
+     * @return array
+     * @access public
+     * @since  Method available since Release 3.2.1
+     */
+    public function getGroupConfiguration()
+    {
+        $groups = array(
+          'include' => array(),
+          'exclude' => array()
+        );
+
+        foreach ($this->xpath->query('groups/include/group') as $group) {
+            $groups['include'][] = (string)$group->nodeValue;
+        }
+
+        foreach ($this->xpath->query('groups/exclude/group') as $group) {
+            $groups['exclude'][] = (string)$group->nodeValue;
+        }
+
+        return $groups;
+    }
+
+    /**
+     * Returns the logging configuration.
+     *
+     * @return array
+     * @access public
+     */
+    public function getLoggingConfiguration()
+    {
+        $result = array();
+
+        foreach ($this->xpath->query('logging/log') as $log) {
+            $type   = (string)$log->getAttribute('type');
+            $target = (string)$log->getAttribute('target');
+
+            if ($type == 'coverage-html') {
+                if ($log->hasAttribute('charset')) {
+                    $result['charset'] = (string)$log->getAttribute('charset');
+                }
+
+                if ($log->hasAttribute('lowUpperBound')) {
+                    $result['lowUpperBound'] = (string)$log->getAttribute('lowUpperBound');
+                }
+
+                if ($log->hasAttribute('highLowerBound')) {
+                    $result['highLowerBound'] = (string)$log->getAttribute('highLowerBound');
+                }
+
+                if ($log->hasAttribute('yui')) {
+                    $result['yui'] = $this->getBoolean(
+                      (string)$log->getAttribute('yui'),
+                      FALSE
+                    );
+                }
+
+                if ($log->hasAttribute('highlight')) {
+                    $result['highlight'] = $this->getBoolean(
+                      (string)$log->getAttribute('highlight'),
+                      FALSE
+                    );
+                }
+            }
+
+            else if ($type == 'pmd-xml') {
+                if ($log->hasAttribute('cpdMinLines')) {
+                    $result['cpdMinLines'] = (string)$log->getAttribute('cpdMinLines');
+                }
+
+                if ($log->hasAttribute('cpdMinMatches')) {
+                    $result['cpdMinMatches'] = (string)$log->getAttribute('cpdMinMatches');
+                }
+            }
+
+            else if ($type == 'test-xml') {
+                if ($log->hasAttribute('logIncompleteSkipped')) {
+                    $result['logIncompleteSkipped'] = $this->getBoolean(
+                      (string)$log->getAttribute('logIncompleteSkipped'),
+                      FALSE
+                    );
+                }
+            }
+
+            $result[$type] = $target;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the PHP configuration.
+     *
+     * @return array
+     * @access public
+     * @since  Method available since Release 3.2.1
+     */
+    public function getPHPConfiguration()
+    {
+        $result = array(
+          'ini' => array(),
+          'var' => array()
+        );
+
+        foreach ($this->xpath->query('php/ini') as $ini) {
+            $name  = (string)$ini->getAttribute('name');
+            $value = (string)$ini->getAttribute('value');
+
+            $result['ini'][$name] = $value;
+        }
+
+        foreach ($this->xpath->query('php/var') as $var) {
+            $name  = (string)$var->getAttribute('name');
+            $value = (string)$var->getAttribute('value');
+
+            if (strtolower($value) == 'false') {
+                $value = FALSE;
+            }
+
+            else if (strtolower($value) == 'true') {
+                $value = TRUE;
+            }
+
+            $result['var'][$name] = $value;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the configuration for PMD rules.
+     *
+     * @return array
+     * @access public
+     */
+    public function getPMDConfiguration()
+    {
+        $result = array();
+
+        foreach ($this->xpath->query('logging/pmd/rule') as $rule) {
+            $class     = (string)$rule->getAttribute('class');
+
+            $threshold = (string)$rule->getAttribute('threshold');
+            $threshold = explode(',', $threshold);
+
+            if (count($threshold) == 1) {
+                $threshold = $threshold[0];
+            }
+
+            $priority = (int)$rule->getAttribute('priority');
+
+            $result[$class] = array(
+              'threshold' => $threshold,
+              'priority'  => $priority
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the SeleniumTestCase browser configuration.
+     *
+     * @return array
+     * @access public
+     * @since  Method available since Release 3.2.9
+     */
+    public function getSeleniumBrowserConfiguration()
+    {
+        $result = array();
+
+        foreach ($this->xpath->query('selenium/browser') as $config) {
+            $name    = (string)$config->getAttribute('name');
+            $browser = (string)$config->getAttribute('browser');
+
+            if ($config->hasAttribute('host')) {
+                $host = (string)$config->getAttribute('host');
+            } else {
+                $host = 'localhost';
+            }
+
+            if ($config->hasAttribute('port')) {
+                $host = (int)$config->getAttribute('port');
+            } else {
+                $host = 4444;
+            }
+
+            if ($config->hasAttribute('timeout')) {
+                $host = (int)$config->getAttribute('timeout');
+            } else {
+                $host = 30000;
+            }
+
+            $result[] = array(
+              'name'    => $name,
+              'browser' => $browser,
+              'host'    => $host,
+              'port'    => $port,
+              'timeout' => $timeout
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the test suite configuration.
+     *
+     * @return PHPUnit_Framework_TestSuite
+     * @access public
+     * @since  Method available since Release 3.2.1
+     */
+    public function getTestSuiteConfiguration()
+    {
+        $testSuiteNode = $this->xpath->query('testsuite');
+
+        if ($testSuiteNode->length > 0) {
+            $testSuiteNode = $testSuiteNode->item(0);
+
+            if ($testSuiteNode->hasAttribute('name')) {
+                $suite = new PHPUnit_Framework_TestSuite(
+                  (string)$testSuiteNode->getAttribute('name')
+                );
+            } else {
+                $suite = new PHPUnit_Framework_TestSuite;
+            }
+
+            foreach ($this->xpath->query('testsuite/directory') as $directoryNode) {
+                if ($directoryNode->hasAttribute('suffix')) {
+                    $suffix = (string)$directoryNode->getAttribute('suffix');
+                } else {
+                    $suffix = 'Test.php';
+                }
+
+                $testCollector = new PHPUnit_Runner_IncludePathTestCollector(
+                  array((string)$directoryNode->nodeValue),
+                  $suffix
+                );
+
+                $suite->addTestFiles($testCollector->collectTests());
+            }
+
+            foreach ($this->xpath->query('testsuite/file') as $fileNode) {
+                $suite->addTestFile((string)$fileNode->nodeValue);
+            }
+
+            return $suite;
+        }
+    }
+
+    /**
+     * @param  string  $value
+     * @param  boolean $default
+     * @return boolean
+     * @access protected
+     * @since  Method available since Release 3.2.3
+     */
+    protected function getBoolean($value, $default)
+    {
+        if (strtolower($value) == 'false') {
+            return FALSE;
+        }
+
+        else if (strtolower($value) == 'true') {
+            return TRUE;
+        }
+
+        return $default;
+    }
+
+    /**
+     * @param  string $query
+     * @return array
+     * @access protected
+     * @since  Method available since Release 3.2.3
+     */
+    protected function readFilterDirectories($query)
+    {
+        $directories = array();
+
+        foreach ($this->xpath->query($query) as $directory) {
+            if ($directory->hasAttribute('suffix')) {
+                $suffix = (string)$directory->getAttribute('suffix');
+            } else {
+                $suffix = '.php';
+            }
+
+            $directories[] = array(
+              'path'   => (string)$directory->nodeValue,
+              'suffix' => $suffix
+            );
+        }
+
+        return $directories;
+    }
+
+    /**
+     * @param  string $query
+     * @return array
+     * @access protected
+     * @since  Method available since Release 3.2.3
+     */
+    protected function readFilterFiles($query)
+    {
+        $files = array();
+
+        foreach ($this->xpath->query($query) as $file) {
+            $files[] = (string)$file->nodeValue;
+        }
+
+        return $files;
+    }
+}
+?>

Added: incubator/shindig/trunk/php/external/PHPUnit/Util/ErrorHandler.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/external/PHPUnit/Util/ErrorHandler.php?rev=681982&view=auto
==============================================================================
--- incubator/shindig/trunk/php/external/PHPUnit/Util/ErrorHandler.php (added)
+++ incubator/shindig/trunk/php/external/PHPUnit/Util/ErrorHandler.php Sat Aug  2 07:11:35 2008
@@ -0,0 +1,93 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2008, Sebastian Bergmann <sb...@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *   * Neither the name of Sebastian Bergmann nor the names of his
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    SVN: $Id: ErrorHandler.php 1985 2007-12-26 18:11:55Z sb $
+ * @link       http://www.phpunit.de/
+ * @since      File available since Release 2.3.0
+ */
+
+require_once 'PHPUnit/Framework.php';
+require_once 'PHPUnit/Util/Filter.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * @param  integer $errno
+ * @param  string  $errstr
+ * @param  string  $errfile
+ * @param  integer $errline
+ * @throws PHPUnit_Framework_Error
+ * @since  Function available since Release 2.3.0
+ */
+function PHPUnit_Util_ErrorHandler($errno, $errstr, $errfile, $errline)
+{
+    if (!($errno & error_reporting())) {
+        return;
+    }
+
+    $trace = debug_backtrace();
+    array_shift($trace);
+
+    foreach ($trace as $frame) {
+        if ($frame['function'] == '__toString') {
+            return;
+        }
+    }
+
+    if ($errno == E_NOTICE || $errno == E_STRICT) {
+        if (PHPUnit_Framework_Notice::$enabled !== TRUE) {
+            return;
+        }
+
+        $exception = 'PHPUnit_Framework_Notice';
+    } else {
+        $exception = 'PHPUnit_Framework_Error';
+    }
+
+    throw new $exception(
+      $errstr,
+      $errno,
+      $errfile,
+      $errline,
+      $trace
+    );
+}
+?>

Added: incubator/shindig/trunk/php/external/PHPUnit/Util/Fileloader.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/external/PHPUnit/Util/Fileloader.php?rev=681982&view=auto
==============================================================================
--- incubator/shindig/trunk/php/external/PHPUnit/Util/Fileloader.php (added)
+++ incubator/shindig/trunk/php/external/PHPUnit/Util/Fileloader.php Sat Aug  2 07:11:35 2008
@@ -0,0 +1,212 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2008, Sebastian Bergmann <sb...@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *   * Neither the name of Sebastian Bergmann nor the names of his
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    SVN: $Id: Fileloader.php 2092 2008-01-14 16:40:53Z sb $
+ * @link       http://www.phpunit.de/
+ * @since      File available since Release 2.3.0
+ */
+
+require_once 'PHPUnit/Util/Filter.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * Utility methods to load PHP sourcefiles.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    Release: @package_version@
+ * @link       http://www.phpunit.de/
+ * @since      Class available since Release 2.3.0
+ */
+class PHPUnit_Util_Fileloader
+{
+    /**
+     * Path to the PHP interpreter that is to be used.
+     *
+     * @var    string $phpBinary
+     * @access public
+     * @static
+     */
+    public static $phpBinary = NULL;
+
+    /**
+     * Checks if a PHP sourcefile is readable and is optionally checked for
+     * syntax errors through the syntaxCheck() method. The sourcefile is
+     * loaded through the load() method.
+     *
+     * @param  string  $filename
+     * @param  boolean $syntaxCheck
+     * @throws RuntimeException
+     * @access public
+     * @static
+     */
+    public static function checkAndLoad($filename, $syntaxCheck = TRUE)
+    {
+        if (!is_readable($filename)) {
+            $filename = './' . $filename;
+        }
+
+        if (!is_readable($filename)) {
+            throw new RuntimeException(
+              sprintf(
+                'File "%s" could not be found or is not readable.',
+
+                str_replace('./', '', $filename)
+              )
+            );
+        }
+
+        if ($syntaxCheck) {
+            self::syntaxCheck($filename);
+        }
+
+        self::load($filename);
+    }
+
+    /**
+     * Loads a PHP sourcefile.
+     *
+     * When the Xdebug extension is loaded and its "xdebug.collect_vars"
+     * configuration directive is enabled, all global variables declared
+     * in the loaded PHP sourcefile will be added to $GLOBALS.
+     *
+     * @param  string $filename
+     * @access protected
+     * @static
+     * @since  Method available since Release 3.0.0
+     */
+    protected static function load($filename)
+    {
+        $xdebugLoaded      = extension_loaded('xdebug');
+        $xdebugCollectVars = $xdebugLoaded && ini_get('xdebug.collect_vars') == '1';
+
+        if ($xdebugCollectVars) {
+            $variables = xdebug_get_declared_vars();
+        }
+
+        include_once $filename;
+
+        if ($xdebugCollectVars) {
+            $variables = array_values(
+              array_diff(xdebug_get_declared_vars(), $variables)
+            );
+
+            foreach ($variables as $variable) {
+                if (isset($$variable)) {
+                    $GLOBALS[$variable] = $$variable;
+                }
+            }
+        }
+    }
+
+    /**
+     * Uses a separate process to perform a syntax check on a PHP sourcefile.
+     *
+     * PHPUnit_Util_Fileloader::$phpBinary contains the path to the PHP
+     * interpreter used for this. If unset, the following assumptions will
+     * be made:
+     *
+     *   1. When the PHP CLI/CGI binary configured with the PEAR Installer
+     *      (php_bin configuration value) is readable, it will be used.
+     *
+     *   2. When PHPUnit is run using the CLI SAPI and the $_SERVER['_']
+     *      variable does not contain the string "PHPUnit", $_SERVER['_']
+     *      is assumed to contain the path to the current PHP interpreter
+     *      and that will be used.
+     *
+     *   3. When PHPUnit is run using the CLI SAPI and the $_SERVER['_']
+     *      variable contains the string "PHPUnit", the file that $_SERVER['_']
+     *      points is assumed to be the PHPUnit TextUI CLI wrapper script
+     *      "phpunit" and the binary set up using #! on that file's first
+     *      line of code is assumed to contain the path to the current PHP
+     *      interpreter and that will be used.
+     *
+     *   4. The current PHP interpreter is assumed to be in the $PATH and
+     *      to be invokable through "php".
+     *
+     * @param  string $filename
+     * @throws RuntimeException
+     * @access protected
+     * @static
+     * @since  Method available since Release 3.0.0
+     */
+    protected static function syntaxCheck($filename)
+    {
+        if (self::$phpBinary === NULL) {
+            if (is_readable('@php_bin@')) {
+                self::$phpBinary = '@php_bin@';
+            }
+
+            else if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) {
+                self::$phpBinary = $_SERVER['_'];
+
+                if (strpos(self::$phpBinary, 'phpunit') !== FALSE) {
+                    $file            = file(self::$phpBinary);
+                    $tmp             = explode(' ', $file[0]);
+                    self::$phpBinary = trim($tmp[1]);
+                }
+            }
+
+            if (!is_readable(self::$phpBinary)) {
+                self::$phpBinary = 'php';
+            } else {
+                self::$phpBinary = escapeshellarg(self::$phpBinary);
+            }
+        }
+
+        $command = self::$phpBinary . ' -l ' . escapeshellarg($filename);
+
+        if (DIRECTORY_SEPARATOR == '\\') {
+            $command = '"' . $command . '"';
+        }
+
+        $output = shell_exec($command);
+
+        if (strpos($output, 'Errors parsing') !== FALSE) {
+            throw new RuntimeException($output);
+        }
+    }
+}
+?>

Added: incubator/shindig/trunk/php/external/PHPUnit/Util/Filesystem.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/external/PHPUnit/Util/Filesystem.php?rev=681982&view=auto
==============================================================================
--- incubator/shindig/trunk/php/external/PHPUnit/Util/Filesystem.php (added)
+++ incubator/shindig/trunk/php/external/PHPUnit/Util/Filesystem.php Sat Aug  2 07:11:35 2008
@@ -0,0 +1,160 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2008, Sebastian Bergmann <sb...@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *   * Neither the name of Sebastian Bergmann nor the names of his
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    SVN: $Id: Filesystem.php 2050 2008-01-09 14:54:58Z sb $
+ * @link       http://www.phpunit.de/
+ * @since      File available since Release 3.0.0
+ */
+
+require_once 'PHPUnit/Util/Filter.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * Filesystem helpers.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    Release: 3.2.9
+ * @link       http://www.phpunit.de/
+ * @since      Class available since Release 3.0.0
+ * @abstract
+ */
+class PHPUnit_Util_Filesystem
+{
+    /**
+     * Wrapper for file_exists() that searches the include_path.
+     *
+     * @param  string $file
+     * @return mixed
+     * @access public
+     * @static
+     * @author Mattis Stordalen Flister <ma...@xait.no>
+     * @since  Method available since Release 3.2.9
+     */
+    public static function fileExistsInIncludePath($file) {
+        $paths = explode(PATH_SEPARATOR, get_include_path());
+
+        foreach ($paths as $path) {
+            $fullpath = $path . DIRECTORY_SEPARATOR . $file;
+
+            if (file_exists($fullpath)) {
+                return realpath($fullpath);
+            }
+        }
+
+        return FALSE;
+    }
+
+    /**
+     * Returns the common path of a set of files.
+     *
+     * @param  array $paths
+     * @return string
+     * @access public
+     * @static
+     * @since  Method available since Release 3.1.0
+     */
+    public static function getCommonPath(array $paths)
+    {
+        $count = count($paths);
+
+        if ($count == 1) {
+            return dirname($paths[0]) . DIRECTORY_SEPARATOR;
+        }
+
+        $_paths = array();
+
+        for ($i = 0; $i < $count; $i++) {
+            $_paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
+
+            if (empty($_paths[$i][0])) {
+                $_paths[$i][0] = DIRECTORY_SEPARATOR;
+            }
+        }
+
+        $common = '';
+        $done   = FALSE;
+        $j      = 0;
+        $count--;
+
+        while (!$done) {
+            for ($i = 0; $i < $count; $i++) {
+                if ($_paths[$i][$j] != $_paths[$i+1][$j]) {
+                    $done = TRUE;
+                    break;
+                }
+            }
+
+            if (!$done) {
+                $common .= $_paths[0][$j];
+
+                if ($j > 0) {
+                    $common .= DIRECTORY_SEPARATOR;
+                }
+            }
+
+            $j++;
+        }
+
+        return $common;
+    }
+
+    /**
+     * Returns a filesystem safe version of the passed filename.
+     * This function does not operate on full paths, just filenames.
+     *
+     * @param  string $filename
+     * @return string
+     * @access public
+     * @static
+     * @author Michael Lively Jr. <m...@digitalsandwich.com>
+     */
+    public static function getSafeFilename($filename)
+    {
+        /* characters allowed: A-Z, a-z, 0-9, _ and . */
+        return preg_replace('#[^\w.]#', '_', $filename);
+    }
+}
+?>

Added: incubator/shindig/trunk/php/external/PHPUnit/Util/Filter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/external/PHPUnit/Util/Filter.php?rev=681982&view=auto
==============================================================================
--- incubator/shindig/trunk/php/external/PHPUnit/Util/Filter.php (added)
+++ incubator/shindig/trunk/php/external/PHPUnit/Util/Filter.php Sat Aug  2 07:11:35 2008
@@ -0,0 +1,550 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2008, Sebastian Bergmann <sb...@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *   * Neither the name of Sebastian Bergmann nor the names of his
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    SVN: $Id: Filter.php 2041 2008-01-08 10:00:39Z sb $
+ * @link       http://www.phpunit.de/
+ * @since      File available since Release 2.0.0
+ */
+
+require_once 'PHPUnit/Util/FilterIterator.php';
+
+/**
+ * Utility class for code filtering.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    Release: 3.2.9
+ * @link       http://www.phpunit.de/
+ * @since      Class available since Release 2.0.0
+ */
+class PHPUnit_Util_Filter
+{
+    /**
+     * @var    boolean
+     * @access public
+     * @static
+     */
+    public static $addUncoveredFilesFromWhitelist = TRUE;
+
+    /**
+     * @var    boolean
+     * @access public
+     * @static
+     */
+    public static $filterPHPUnit = TRUE;
+
+    /**
+     * @var    boolean
+     * @access protected
+     * @static
+     */
+    protected static $filter = TRUE;
+
+    /**
+     * @var    boolean
+     * @access protected
+     * @static
+     */
+    protected static $blackListConverstionForWindowsDone = FALSE;
+
+    /**
+     * Source files that are blacklisted.
+     *
+     * @var    array
+     * @access protected
+     * @static
+     */
+    protected static $blacklistedFiles = array(
+      'DEFAULT' => array(),
+      'PHPUNIT' => array(),
+      'TESTS' => array(),
+      'PEAR' => array(
+        'Console/Getopt.php',
+        'Image/GraphViz.php',
+        'Log/composite.php',
+        'Log/console.php',
+        'Log/daemon.php',
+        'Log/display.php',
+        'Log/error_log.php',
+        'Log/file.php',
+        'Log/mail.php',
+        'Log/mcal.php',
+        'Log/mdb2.php',
+        'Log/null.php',
+        'Log/observer.php',
+        'Log/sql.php',
+        'Log/sqlite.php',
+        'Log/syslog.php',
+        'Log/win.php',
+        'Log.php',
+        'PEAR/Installer/Role/Common.php',
+        'PEAR/Installer/Role.php',
+        'PEAR/Config.php',
+        'PEAR/DependencyDB.php',
+        'PEAR/Registry.php',
+        'PEAR/Remote.php',
+        'PEAR/RunTest.php',
+        'PEAR/XMLParser.php',
+        'PEAR.php',
+        'System.php'
+      )
+    );
+
+    /**
+     * Source files that are whitelisted.
+     *
+     * @var    array
+     * @access protected
+     * @static
+     */
+    protected static $whitelistedFiles = array();
+
+    /**
+     * Adds a directory to the blacklist (recursively).
+     *
+     * @param  string $directory
+     * @param  string $suffix
+     * @param  string $group
+     * @access public
+     * @static
+     * @since  Method available since Release 3.1.5
+     */
+    public static function addDirectoryToFilter($directory, $suffix = '.php', $group = 'DEFAULT')
+    {
+        if (file_exists($directory)) {
+            foreach (self::getIterator($directory, $suffix) as $file) {
+                self::addFileToFilter($file->getPathName(), $group);
+            }
+        }
+    }
+
+    /**
+     * Adds a new file to be filtered (blacklist).
+     *
+     * @param  string $filename
+     * @param  string $group
+     * @access public
+     * @static
+     * @since  Method available since Release 2.1.0
+     */
+    public static function addFileToFilter($filename, $group = 'DEFAULT')
+    {
+        if (file_exists($filename)) {
+            $filename = realpath($filename);
+
+            if (!isset(self::$blacklistedFiles[$group])) {
+                self::$blacklistedFiles[$group] = array($filename);
+            }
+
+            else if (!in_array($filename, self::$blacklistedFiles[$group])) {
+                self::$blacklistedFiles[$group][] = $filename;
+            }
+        }
+    }
+
+    /**
+     * Removes a directory from the blacklist (recursively).
+     *
+     * @param  string $directory
+     * @param  string $suffix
+     * @param  string $group
+     * @access public
+     * @static
+     * @since  Method available since Release 3.1.5
+     */
+    public static function removeDirectoryFromFilter($directory, $suffix = '.php', $group = 'DEFAULT')
+    {
+        if (file_exists($directory)) {
+            foreach (self::getIterator($directory, $suffix) as $file) {
+                self::removeFileFromFilter($file->getPathName(), $group);
+            }
+        }
+    }
+
+    /**
+     * Removes a file from the filter (blacklist).
+     *
+     * @param  string $filename
+     * @param  string $group
+     * @access public
+     * @static
+     * @since  Method available since Release 2.1.0
+     */
+    public static function removeFileFromFilter($filename, $group = 'DEFAULT')
+    {
+        if (file_exists($filename)) {
+            if (isset(self::$blacklistedFiles[$group])) {
+                $filename = realpath($filename);
+
+                foreach (self::$blacklistedFiles[$group] as $key => $_filename) {
+                    if ($filename == $_filename) {
+                        unset(self::$blacklistedFiles[$group][$key]);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds a directory to the whitelist (recursively).
+     *
+     * @param  string $directory
+     * @param  string $suffix
+     * @access public
+     * @static
+     * @since  Method available since Release 3.1.5
+     */
+    public static function addDirectoryToWhitelist($directory, $suffix = '.php')
+    {
+        if (file_exists($directory)) {
+            foreach (self::getIterator($directory, $suffix) as $file) {
+                self::addFileToWhitelist($file->getPathName());
+            }
+        }
+    }
+
+    /**
+     * Adds a new file to the whitelist.
+     *
+     * When the whitelist is empty (default), blacklisting is used.
+     * When the whitelist is not empty, whitelisting is used.
+     *
+     * @param  string $filename
+     * @access public
+     * @static
+     * @since  Method available since Release 3.1.0
+     */
+    public static function addFileToWhitelist($filename)
+    {
+        if (file_exists($filename)) {
+            $filename = realpath($filename);
+
+            if (!in_array($filename, self::$whitelistedFiles)) {
+                self::$whitelistedFiles[] = $filename;
+            }
+        }
+    }
+
+    /**
+     * Removes a directory from the whitelist (recursively).
+     *
+     * @param  string $directory
+     * @param  string $suffix
+     * @access public
+     * @static
+     * @since  Method available since Release 3.1.5
+     */
+    public static function removeDirectoryFromWhitelist($directory, $suffix = '.php')
+    {
+        if (file_exists($directory)) {
+            foreach (self::getIterator($directory, $suffix) as $file) {
+                self::removeFileFromWhitelist($file->getPathName());
+            }
+        }
+    }
+
+    /**
+     * Removes a file from the whitelist.
+     *
+     * @param  string $filename
+     * @access public
+     * @static
+     * @since  Method available since Release 3.1.0
+     */
+    public static function removeFileFromWhitelist($filename)
+    {
+        if (file_exists($filename)) {
+            $filename = realpath($filename);
+
+            foreach (self::$whitelistedFiles as $key => $_filename) {
+                if ($filename == $_filename) {
+                    unset(self::$whitelistedFiles[$key]);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns data about files within code coverage information, specifically
+     * which ones will be filtered out and which ones may be whitelisted but not
+     * touched by coverage.
+     * 
+     * Returns a two-item array. The first item is an array indexed by filenames 
+     * with a boolean payload of whether they should be filtered out.
+     * 
+     * The second item is an array of filenames which are 
+     * whitelisted but which are absent from the coverage information.
+     *
+     * @param  array   $codeCoverageInformation
+     * @param  boolean $filterTests
+     * @return array
+     * @access public
+     * @static
+     */
+    public static function getFileCodeCoverageDisposition(array $codeCoverageInformation, $filterTests = TRUE)
+    {
+        if (!self::$filter) {
+            return array(array(), array());
+        }             
+
+        $isFilteredCache = array();
+        $coveredFiles    = array();
+
+        foreach ($codeCoverageInformation as $k => $test) {
+            foreach (array_keys($test['files']) as $file) {
+                if (!isset($isFilteredCache[$file])) {
+                    $isFilteredCache[$file] = self::isFiltered(
+                      $file, $filterTests
+                    );
+                }
+            }
+        }        
+
+        $coveredFiles = array_keys($isFilteredCache);
+        $missedFiles  = array_diff(self::$whitelistedFiles,$coveredFiles);                
+        $missedFiles  = array_filter($missedFiles,'file_exists');
+
+        return array($isFilteredCache,$missedFiles);
+    }
+    
+    /**
+     * @param  array   $codeCoverageInformation
+     * @param  boolean $addUncoveredFilesFromWhitelist
+     * @return array
+     * @access public
+     * @static
+     */
+    public static function getFilteredCodeCoverage(array $codeCoverageInformation, $filterTests = TRUE)
+    {
+        if (self::$filter) {
+            list($isFilteredCache, $missedFiles) = self::getFileCodeCoverageDisposition(
+              $codeCoverageInformation, $filterTests
+            );
+
+            foreach ($codeCoverageInformation as $k => $test) {
+                foreach (array_keys($test['files']) as $file) {
+                    if ($isFilteredCache[$file]) {
+                        unset($codeCoverageInformation[$k]['files'][$file]);
+                    }
+                }
+            }
+
+            if (self::$addUncoveredFilesFromWhitelist) {
+                foreach ($missedFiles as $missedFile) {
+                    xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
+                    include_once $missedFile;
+                    $coverage = xdebug_get_code_coverage();
+                    xdebug_stop_code_coverage();
+
+                    if (isset($coverage[$missedFile])) {
+                        foreach ($coverage[$missedFile] as $line => $flag) {
+                            if ($flag > 0) {
+                                $coverage[$missedFile][$line] = -1;
+                            }
+                        }
+
+                        $codeCoverageInformation[] = array(
+                          'test'  => NULL,
+                          'files' => array(
+                            $missedFile => $coverage[$missedFile]
+                          )
+                        );
+                    }
+                }
+            }
+        }
+
+        return $codeCoverageInformation;
+    }
+
+    /**
+     * Filters stack frames from PHPUnit classes.
+     *
+     * @param  Exception $e
+     * @param  boolean   $filterTests
+     * @param  boolean   $asString
+     * @return string
+     * @access public
+     * @static
+     */
+    public static function getFilteredStacktrace(Exception $e, $filterTests = TRUE, $asString = TRUE)
+    {
+        if ($asString === TRUE) {
+            $filteredStacktrace = '';
+        } else {
+            $filteredStacktrace = array();
+        }
+
+        foreach ($e->getTrace() as $frame) {
+            if (!self::$filter || (isset($frame['file']) && !self::isFiltered($frame['file'], $filterTests, TRUE))) {
+                if ($asString === TRUE) {
+                    $filteredStacktrace .= sprintf(
+                      "%s:%s\n",
+
+                      $frame['file'],
+                      isset($frame['line']) ? $frame['line'] : '?'
+                    );
+                } else {
+                    $filteredStacktrace[] = $frame;
+                }
+            }
+        }
+
+        return $filteredStacktrace;
+    }
+
+    /**
+     * Activates or deactivates filtering.
+     *
+     * @param  boolean $filter
+     * @throws InvalidArgumentException
+     * @access public
+     * @static
+     * @since  Method available since Release 3.0.0
+     */
+    public static function setFilter($filter)
+    {
+        if (is_bool($filter)) {
+            self::$filter = $filter;
+        } else {
+            throw new InvalidArgumentException;
+        }
+    }
+
+    /**
+     * Returns a PHPUnit_Util_FilterIterator that iterates
+     * over all files in the given directory that have the
+     * given suffix.
+     *
+     * @param  string $directory
+     * @param  string $suffix
+     * @return Iterator
+     * @access protected
+     * @static
+     * @since  Method available since Release 3.1.5
+     */
+    protected static function getIterator($directory, $suffix)
+    {
+        return new PHPUnit_Util_FilterIterator(
+          new RecursiveIteratorIterator(
+            new RecursiveDirectoryIterator($directory)
+          ),
+          $suffix
+        );
+    }
+
+    /**
+     * @param  string  $filename
+     * @param  boolean $filterTests
+     * @param  boolean $ignoreWhitelist
+     * @return boolean
+     * @access protected
+     * @static
+     * @since  Method available since Release 2.1.3
+     */
+    protected static function isFiltered($filename, $filterTests = TRUE, $ignoreWhitelist = FALSE)
+    {
+        $filename = realpath($filename);
+
+        // Use blacklist.
+        if ($ignoreWhitelist || empty(self::$whitelistedFiles)) {
+            if (DIRECTORY_SEPARATOR == '\\' &&
+                !self::$blackListConverstionForWindowsDone) {
+                $count = count(self::$blacklistedFiles['PEAR']);
+
+                for ($i = 0; $i < $count; $i++) {
+                    self::$blacklistedFiles['PEAR'][$i] = str_replace(
+                      '/', '\\', self::$blacklistedFiles['PEAR'][$i]
+                    );
+                }
+
+                self::$blackListConverstionForWindowsDone = TRUE;
+            }
+
+            $blacklistedFiles = array_merge(
+              self::$blacklistedFiles['DEFAULT'],
+              self::$blacklistedFiles['PEAR']
+            );
+
+            if ($filterTests) {
+                $blacklistedFiles = array_merge(
+                  $blacklistedFiles,
+                  self::$blacklistedFiles['TESTS']
+                );
+            }
+
+            if (self::$filterPHPUnit) {
+                $blacklistedFiles = array_merge(
+                  $blacklistedFiles,
+                  self::$blacklistedFiles['PHPUNIT']
+                );
+            }
+
+            if (in_array($filename, $blacklistedFiles)) {
+                return TRUE;
+            }
+
+            foreach ($blacklistedFiles as $filteredFile) {
+                if (strpos($filename, $filteredFile) !== FALSE) {
+                    return TRUE;
+                }
+            }
+
+            return FALSE;
+        }
+
+        // Use whitelist.
+        else
+        {
+            if (in_array($filename, self::$whitelistedFiles)) {
+                return FALSE;
+            }
+
+            return TRUE;
+        }
+    }
+}
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+?>

Added: incubator/shindig/trunk/php/external/PHPUnit/Util/FilterIterator.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/external/PHPUnit/Util/FilterIterator.php?rev=681982&view=auto
==============================================================================
--- incubator/shindig/trunk/php/external/PHPUnit/Util/FilterIterator.php (added)
+++ incubator/shindig/trunk/php/external/PHPUnit/Util/FilterIterator.php Sat Aug  2 07:11:35 2008
@@ -0,0 +1,92 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2008, Sebastian Bergmann <sb...@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *   * Neither the name of Sebastian Bergmann nor the names of his
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    SVN: $Id: FilterIterator.php 1985 2007-12-26 18:11:55Z sb $
+ * @link       http://www.phpunit.de/
+ * @since      File available since Release 3.0.0
+ */
+
+require_once 'PHPUnit/Util/Filter.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ *
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    Release: 3.2.9
+ * @link       http://www.phpunit.de/
+ * @since      Class available since Release 3.0.0
+ */
+
+class PHPUnit_Util_FilterIterator extends FilterIterator
+{
+    /**
+     * @var    string
+     * @access protected
+     */
+    protected $suffix;
+
+    /**
+     * @param  Iterator $iterator
+     * @param  string   $suffix
+     * @access public
+     */
+    public function __construct(Iterator $iterator, $suffix = 'Test.php')
+    {
+        parent::__construct($iterator);
+        $this->suffix = $suffix;
+    }
+
+    /**
+     * @return boolean
+     * @access public
+     */
+    public function accept()
+    {
+        return substr($this->getInnerIterator()->current(), -1 * strlen($this->suffix)) == $this->suffix;
+    }
+}
+?>

Added: incubator/shindig/trunk/php/external/PHPUnit/Util/Getopt.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/external/PHPUnit/Util/Getopt.php?rev=681982&view=auto
==============================================================================
--- incubator/shindig/trunk/php/external/PHPUnit/Util/Getopt.php (added)
+++ incubator/shindig/trunk/php/external/PHPUnit/Util/Getopt.php Sat Aug  2 07:11:35 2008
@@ -0,0 +1,181 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2008, Sebastian Bergmann <sb...@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *   * Neither the name of Sebastian Bergmann nor the names of his
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    SVN: $Id: Getopt.php 1985 2007-12-26 18:11:55Z sb $
+ * @link       http://www.phpunit.de/
+ * @since      File available since Release 3.0.0
+ */
+
+require_once 'PHPUnit/Util/Filter.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * Command-line options parsing class.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Andrei Zmievski <an...@php.net>
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    Release: 3.2.9
+ * @link       http://www.phpunit.de/
+ * @since      Class available since Release 3.0.0
+ * @abstract
+ */
+class PHPUnit_Util_Getopt {
+    public static function getopt(array $args, $short_options, $long_options = null)
+    {
+        if (empty($args)) {
+            return array(array(), array());
+        }
+
+        $opts     = array();
+        $non_opts = array();
+
+        if ($long_options) {
+            sort($long_options);
+        }
+
+        if (isset($args[0]{0}) && $args[0]{0} != '-') {
+            array_shift($args);
+        }
+
+        reset($args);
+
+        while (list($i, $arg) = each($args)) {
+            if ($arg == '--') {
+                $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
+                break;
+            }
+
+            if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
+                $non_opts = array_merge($non_opts, array_slice($args, $i));
+                break;
+            }
+
+            elseif (strlen($arg) > 1 && $arg{1} == '-') {
+                self::parseLongOption(substr($arg, 2), $long_options, $opts, $args);
+            }
+
+            else {
+                self::parseShortOption(substr($arg, 1), $short_options, $opts, $args);
+            }
+        }
+
+        return array($opts, $non_opts);
+    }
+
+    protected static function parseShortOption($arg, $short_options, &$opts, &$args)
+    {
+        for ($i = 0; $i < strlen($arg); $i++) {
+            $opt = $arg{$i};
+            $opt_arg = null;
+
+            if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') {
+                throw new RuntimeException("unrecognized option -- $opt");
+            }
+
+            if (strlen($spec) > 1 && $spec{1} == ':') {
+                if (strlen($spec) > 2 && $spec{2} == ':') {
+                    if ($i + 1 < strlen($arg)) {
+                        $opts[] = array($opt, substr($arg, $i + 1));
+                        break;
+                    }
+                } else {
+                    if ($i + 1 < strlen($arg)) {
+                        $opts[] = array($opt, substr($arg, $i + 1));
+                        break;
+                    }
+
+                    else if (list(, $opt_arg) = each($args)) {
+                    }
+
+                    else {
+                        throw new RuntimeException("option requires an argument -- $opt");
+                    }
+                }
+            }
+
+            $opts[] = array($opt, $opt_arg);
+        }
+    }
+
+    protected static function parseLongOption($arg, $long_options, &$opts, &$args)
+    {
+        @list($opt, $opt_arg) = explode('=', $arg);
+        $opt_len = strlen($opt);
+
+        for ($i = 0; $i < count($long_options); $i++) {
+            $long_opt  = $long_options[$i];
+            $opt_start = substr($long_opt, 0, $opt_len);
+
+            if ($opt_start != $opt) continue;
+
+            $opt_rest = substr($long_opt, $opt_len);
+
+            if ($opt_rest != '' && $opt{0} != '=' &&
+                $i + 1 < count($long_options) &&
+                $opt == substr($long_options[$i+1], 0, $opt_len)) {
+                throw new RuntimeException("option --$opt is ambiguous");
+            }
+
+            if (substr($long_opt, -1) == '=') {
+                if (substr($long_opt, -2) != '==') {
+                    if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
+                        throw new RuntimeException("option --$opt requires an argument");
+                    }
+                }
+            }
+
+            else if ($opt_arg) {
+                throw new RuntimeException("option --$opt doesn't allow an argument");
+            }
+
+            $opts[] = array('--' . $opt, $opt_arg);
+            return;
+        }
+
+        throw new RuntimeException("unrecognized option --$opt");
+    }
+}
+?>

Added: incubator/shindig/trunk/php/external/PHPUnit/Util/Log/CPD.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/external/PHPUnit/Util/Log/CPD.php?rev=681982&view=auto
==============================================================================
--- incubator/shindig/trunk/php/external/PHPUnit/Util/Log/CPD.php (added)
+++ incubator/shindig/trunk/php/external/PHPUnit/Util/Log/CPD.php Sat Aug  2 07:11:35 2008
@@ -0,0 +1,133 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2008, Sebastian Bergmann <sb...@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *
+ *   * Neither the name of Sebastian Bergmann nor the names of his
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    SVN: $Id: CPD.php 1985 2007-12-26 18:11:55Z sb $
+ * @link       http://www.phpunit.de/
+ * @since      File available since Release 3.2.0
+ */
+
+require_once 'PHPUnit/Runner/Version.php';
+require_once 'PHPUnit/Util/Metrics/Project.php';
+require_once 'PHPUnit/Util/CodeCoverage.php';
+require_once 'PHPUnit/Util/Filter.php';
+require_once 'PHPUnit/Util/Printer.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * Generates an XML logfile with code duplication information.
+ *
+ * @category   Testing
+ * @package    PHPUnit
+ * @author     Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @copyright  2002-2008 Sebastian Bergmann <sb...@sebastian-bergmann.de>
+ * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
+ * @version    Release: 3.2.9
+ * @link       http://www.phpunit.de/
+ * @since      Class available since Release 3.2.0
+ */
+class PHPUnit_Util_Log_CPD extends PHPUnit_Util_Printer
+{
+    /**
+     * @param  PHPUnit_Framework_TestResult $result
+     * @access public
+     */
+    public function process(PHPUnit_Framework_TestResult $result, $minLines = 5, $minMatches = 70)
+    {
+        $codeCoverage = $result->getCodeCoverageInformation();
+        $summary      = PHPUnit_Util_CodeCoverage::getSummary($codeCoverage);
+        $files        = array_keys($summary);
+        $metrics      = new PHPUnit_Util_Metrics_Project($files, $summary, TRUE, $minLines, $minMatches);
+
+        $document = new DOMDocument('1.0', 'UTF-8');
+        $document->formatOutput = TRUE;
+
+        $cpd = $document->createElement('pmd-cpd');
+        $cpd->setAttribute('version', 'PHPUnit ' . PHPUnit_Runner_Version::id());
+        $document->appendChild($cpd);
+
+        foreach ($metrics->getDuplicates() as $duplicate) {
+            $xmlDuplication = $cpd->appendChild(
+              $document->createElement('duplication')
+            );
+
+            $xmlDuplication->setAttribute('lines', $duplicate['numLines']);
+            $xmlDuplication->setAttribute('tokens', $duplicate['numTokens']);
+
+            $xmlFile = $xmlDuplication->appendChild(
+              $document->createElement('file')
+            );
+
+            $xmlFile->setAttribute('path', $duplicate['fileA']->getPath());
+            $xmlFile->setAttribute('line', $duplicate['firstLineA']);
+
+            $xmlFile = $xmlDuplication->appendChild(
+              $document->createElement('file')
+            );
+
+            $xmlFile->setAttribute('path', $duplicate['fileB']->getPath());
+            $xmlFile->setAttribute('line', $duplicate['firstLineB']);
+
+            $codefragment = $xmlDuplication->appendChild(
+              $document->createElement('codefragment')
+            );
+
+            $codefragment->appendChild(
+              $document->createCDATASection(
+                utf8_encode(
+                  join(
+                    '',
+                    array_slice(
+                      $duplicate['fileA']->getLines(),
+                      $duplicate['firstLineA'] - 1,
+                      $duplicate['numLines']
+                    )
+                  )
+                )
+              )
+            );
+        }
+
+        $this->write($document->saveXML());
+        $this->flush();
+    }
+}
+?>