[
  {
    "path": ".gitattributes",
    "content": "/.github           export-ignore\n/build             export-ignore\n/examples          export-ignore\n/tests             export-ignore\n/tools             export-ignore\n/.gitattributes    export-ignore\n/.gitignore        export-ignore\n/.php_cs.dist.php  export-ignore\n/build.xml         export-ignore\n/phive.xml         export-ignore\n/phpunit.xml       export-ignore\n/psalm.xml         export-ignore\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: [theseer]\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: \"CI\"\n\non:\n  push:\n    branches:\n      - \"master\"\n  pull_request: null\n\njobs:\n  qa:\n    name: \"QA\"\n\n    runs-on: \"ubuntu-latest\"\n\n    steps:\n      - name: \"Checkout\"\n        uses: \"actions/checkout@v3.5.2\"\n\n      - name: \"Set up PHP\"\n        uses: \"shivammathur/setup-php@2.25.1\"\n        with:\n          coverage: \"none\"\n          php-version: \"8.0\"\n          tools: \"phive\"\n\n      - name: \"Install dependencies with composer\"\n        run: \"composer install --no-interaction --optimize-autoloader --prefer-dist\"\n\n      - name: \"Install dependencies with phive\"\n        env:\n          GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: \"ant install-tools\"\n\n      - name: \"Run php-cs-fixer\"\n        run: \"ant php-cs-fixer\"\n\n      - name: \"Run psalm\"\n        run: \"ant psalm\"\n\n  tests:\n    name: \"Tests\"\n\n    runs-on: \"ubuntu-latest\"\n\n    strategy:\n      fail-fast: false\n\n      matrix:\n        php-versions:\n          - \"7.2\"\n          - \"7.3\"\n          - \"7.4\"\n          - \"8.0\"\n          - \"8.1\"\n          - \"8.2\"\n          - \"8.3\"\n          - \"8.4\"\n\n    steps:\n      - name: \"Checkout\"\n        uses: \"actions/checkout@v3.5.2\"\n\n      - name: \"Set up PHP\"\n        uses: \"shivammathur/setup-php@2.25.1\"\n        env:\n          COMPOSER_TOKEN: \"${{ secrets.GITHUB_TOKEN }}\"\n        with:\n          coverage: \"pcov\"\n          extensions: \"${{ env.extensions }}\"\n          ini-values: \"display_errors=On, error_reporting=-1, memory_limit=2G\"\n          php-version: \"${{ matrix.php-versions }}\"\n          tools: \"phive\"\n\n      - name: \"Install dependencies with composer\"\n        run: \"composer install --no-interaction --optimize-autoloader --prefer-dist\"\n\n      - name: \"Install dependencies with phive\"\n        env:\n          GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: \"ant install-tools\"\n\n      - name: \"Run PHPUnit\"\n        run: \"tools/phpunit --coverage-clover build/logs/clover.xml\"\n\n      - name: \"Send code coverage report to codecov.io\"\n        uses: \"codecov/codecov-action@v3.1.4\"\n        with:\n          files: \"build/logs/clover.xml\"\n"
  },
  {
    "path": ".gitignore",
    "content": "/.idea\n/.php_cs.cache\n/src/autoload.php\n/tools\n/vendor\n\n/build\n.phpunit.result.cache\n.php-cs-fixer.cache\n"
  },
  {
    "path": ".php-cs-fixer.dist.php",
    "content": "<?php\n\nrequire __DIR__ . '/tools/php-cs-fixer.d/PhpdocSingleLineVarFixer.php';\n\n$header = file_get_contents(__DIR__ . '/tools/php-cs-fixer.d/header.txt');\n\nreturn (new PhpCsFixer\\Config())\n    ->registerCustomFixers([\n        new \\PharIo\\CSFixer\\PhpdocSingleLineVarFixer()\n    ])\n    ->setRiskyAllowed(true)\n    ->setRules(\n        [\n            'PharIo/phpdoc_single_line_var_fixer'           => true,\n\n            'align_multiline_comment'                       => true,\n            'array_indentation'                             => true,\n            'array_syntax'                                  => ['syntax' => 'short'],\n            'binary_operator_spaces'                        => [\n                'operators' => [\n                    '='  => 'align',\n                    '=>' => 'align',\n                ],\n            ],\n            'blank_line_after_namespace'                    => true,\n            'blank_line_after_opening_tag'                  => false,\n            'blank_line_before_statement'                   => [\n                'statements' => [\n                    'break',\n                    'continue',\n                    'declare',\n                    'do',\n                    'for',\n                    'foreach',\n                    'if',\n                    'include',\n                    'include_once',\n                    'require',\n                    'require_once',\n                    'return',\n                    'switch',\n                    'throw',\n                    'try',\n                    'while',\n                    'yield',\n                ],\n            ],\n            'braces'                                        => [\n                'allow_single_line_closure'                   => false,\n                'position_after_anonymous_constructs'         => 'same',\n                'position_after_control_structures'           => 'same',\n                'position_after_functions_and_oop_constructs' => 'same'\n            ],\n            'cast_spaces'                                   => ['space' => 'none'],\n\n            // This fixer removes the blank line at class start, no way to disable that, so we disable the fixer :(\n            //'class_attributes_separation'                   => ['elements' => ['const', 'method', 'property']],\n\n            'combine_consecutive_issets'                    => true,\n            'combine_consecutive_unsets'                    => true,\n            'compact_nullable_typehint'                     => true,\n            'concat_space'                                  => ['spacing' => 'one'],\n            'date_time_immutable'                           => true,\n            'declare_equal_normalize'                       => ['space' => 'single'],\n            'declare_strict_types'                          => true,\n            'dir_constant'                                  => true,\n            'elseif'                                        => true,\n            'encoding'                                      => true,\n            'full_opening_tag'                              => true,\n            'fully_qualified_strict_types'                  => true,\n            'function_declaration'                          => [\n                'closure_function_spacing' => 'one'\n            ],\n            'global_namespace_import'                       => [\n                'import_classes'   => true,\n                'import_constants' => true,\n                'import_functions' => true,\n            ],\n            'header_comment'                                => ['header' => $header, 'separate' => 'none'],\n            'indentation_type'                              => true,\n            'is_null'                                       => true,\n            'line_ending'                                   => true,\n            'list_syntax'                                   => ['syntax' => 'short'],\n            'logical_operators'                             => true,\n            'lowercase_cast'                                => true,\n            'constant_case'                                 => ['case' => 'lower'],\n            'lowercase_keywords'                            => true,\n            'lowercase_static_reference'                    => true,\n            'magic_constant_casing'                         => true,\n            'method_argument_space'                         => ['on_multiline' => 'ensure_fully_multiline'],\n            'modernize_types_casting'                       => true,\n            'multiline_comment_opening_closing'             => true,\n            'multiline_whitespace_before_semicolons'        => true,\n            'new_with_braces'                               => false,\n            'no_alias_functions'                            => true,\n            'no_alternative_syntax'                         => true,\n            'no_blank_lines_after_class_opening'            => false,\n            'no_blank_lines_after_phpdoc'                   => true,\n            'no_blank_lines_before_namespace'               => true,\n            'no_closing_tag'                                => true,\n            'no_empty_comment'                              => true,\n            'no_empty_phpdoc'                               => true,\n            'no_empty_statement'                            => true,\n            'no_extra_blank_lines'                          => true,\n            'no_homoglyph_names'                            => true,\n            'no_leading_import_slash'                       => true,\n            'no_leading_namespace_whitespace'               => true,\n            'no_mixed_echo_print'                           => ['use' => 'print'],\n            'no_multiline_whitespace_around_double_arrow'   => true,\n            'no_null_property_initialization'               => true,\n            'no_php4_constructor'                           => true,\n            'no_short_bool_cast'                            => true,\n            'echo_tag_syntax'                               => ['format' => 'long'],\n            'no_singleline_whitespace_before_semicolons'    => true,\n            'no_spaces_after_function_name'                 => true,\n            'no_spaces_inside_parenthesis'                  => true,\n            'no_superfluous_elseif'                         => true,\n            'no_superfluous_phpdoc_tags'                    => true,\n            'no_trailing_comma_in_list_call'                => true,\n            'no_trailing_comma_in_singleline_array'         => true,\n            'no_trailing_whitespace'                        => true,\n            'no_trailing_whitespace_in_comment'             => true,\n            'no_unneeded_control_parentheses'               => false,\n            'no_unneeded_curly_braces'                      => false,\n            'no_unneeded_final_method'                      => true,\n            'no_unreachable_default_argument_value'         => true,\n            'no_unset_on_property'                          => true,\n            'no_unused_imports'                             => true,\n            'no_useless_else'                               => true,\n            'no_useless_return'                             => true,\n            'no_whitespace_before_comma_in_array'           => true,\n            'no_whitespace_in_blank_line'                   => true,\n            'non_printable_character'                       => true,\n            'normalize_index_brace'                         => true,\n            'object_operator_without_whitespace'            => true,\n            'ordered_class_elements'                        => [\n                'order' => [\n                    'use_trait',\n                    'constant_public',\n                    'constant_protected',\n                    'constant_private',\n                    'property_public_static',\n                    'property_protected_static',\n                    'property_private_static',\n                    'property_public',\n                    'property_protected',\n                    'property_private',\n                    'method_public_static',\n                    'construct',\n                    'destruct',\n                    'magic',\n                    'phpunit',\n                    'method_public',\n                    'method_protected',\n                    'method_private',\n                    'method_protected_static',\n                    'method_private_static',\n                ],\n            ],\n            'ordered_imports' => [\n                'imports_order' => [\n                    PhpCsFixer\\Fixer\\Import\\OrderedImportsFixer::IMPORT_TYPE_CLASS,\n                    PhpCsFixer\\Fixer\\Import\\OrderedImportsFixer::IMPORT_TYPE_CONST,\n                    PhpCsFixer\\Fixer\\Import\\OrderedImportsFixer::IMPORT_TYPE_FUNCTION,\n                ]\n            ],\n            'phpdoc_add_missing_param_annotation'           => true,\n            'phpdoc_align'                                  => true,\n            'phpdoc_annotation_without_dot'                 => true,\n            'phpdoc_indent'                                 => true,\n            'phpdoc_no_access'                              => true,\n            'phpdoc_no_empty_return'                        => true,\n            'phpdoc_no_package'                             => true,\n            'phpdoc_order'                                  => true,\n            'phpdoc_return_self_reference'                  => true,\n            'phpdoc_scalar'                                 => true,\n            'phpdoc_separation'                             => true,\n            'phpdoc_single_line_var_spacing'                => true,\n            'phpdoc_to_comment'                             => true,\n            'phpdoc_trim'                                   => true,\n            'phpdoc_trim_consecutive_blank_line_separation' => true,\n            'phpdoc_types'                                  => ['groups' => ['simple', 'meta']],\n            'phpdoc_types_order'                            => true,\n            'phpdoc_to_return_type'                         => true,\n            'phpdoc_var_without_name'                       => true,\n            'pow_to_exponentiation'                         => true,\n            'protected_to_private'                          => true,\n            'return_assignment'                             => true,\n            'return_type_declaration'                       => ['space_before' => 'none'],\n            'self_accessor'                                 => false,\n            'semicolon_after_instruction'                   => true,\n            'set_type_to_cast'                              => true,\n            'short_scalar_cast'                             => true,\n            'simplified_null_return'                        => true,\n            'single_blank_line_at_eof'                      => true,\n            'single_import_per_statement'                   => true,\n            'single_line_after_imports'                     => true,\n            'single_quote'                                  => true,\n            'standardize_not_equals'                        => true,\n            'ternary_to_null_coalescing'                    => true,\n            'trailing_comma_in_multiline'                   => false,\n            'trim_array_spaces'                             => true,\n            'unary_operator_spaces'                         => true,\n            'visibility_required'                           => [\n                'elements' => [\n                    'const',\n                    'method',\n                    'property',\n                ],\n            ],\n            'void_return'                                   => true,\n            'whitespace_after_comma_in_array'               => true,\n            'yoda_style'                                    => false\n        ]\n    )\n    ->setFinder(\n        PhpCsFixer\\Finder::create()\n            ->files()\n            ->in(__DIR__ . '/build')\n            ->in(__DIR__ . '/src')\n            ->in(__DIR__ . '/tests')\n            ->notName('autoload.php')\n    );\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to phar-io/manifest are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.\n\n## [2.0.4] - 03-03-2024\n\n### Changed\n\n- Make `EMail` an optional attribute for author\n- Stick with PHP 7.2 compatibilty \n- Do not use implict nullable type (thanks @sebastianbergmann), this should make things work on PHP 8.4\n\n## [2.0.3] - 20.07.2021\n\n- Fixed PHP 7.2 / PHP 7.3 incompatibility introduced in previous release\n\n## [2.0.2] - 20.07.2021\n\n- Fixed PHP 8.1 deprecation notice\n\n## [2.0.1] - 27.06.2020\n\nThis release now supports the use of PHP 7.2+ and ^8.0\n\n## [2.0.0] - 10.05.2020\n\nThis release now requires PHP 7.2+\n\n### Changed\n\n- Upgraded to phar-io/version 3.0\n    - Version strings `v1.2.3` will now be converted to valid semantic version strings `1.2.3`\n    - Abreviated strings like `1.0` will get expaneded to `1.0.0`  \n\n### Unreleased\n\n[Unreleased]: https://github.com/phar-io/manifest/compare/2.1.0...HEAD\n[2.1.0]: https://github.com/phar-io/manifest/compare/2.0.3...2.1.0\n[2.0.3]: https://github.com/phar-io/manifest/compare/2.0.2...2.0.3\n[2.0.2]: https://github.com/phar-io/manifest/compare/2.0.1...2.0.2\n[2.0.1]: https://github.com/phar-io/manifest/compare/2.0.0...2.0.1\n[2.0.0]: https://github.com/phar-io/manifest/compare/1.0.1...2.0.0\n[1.0.3]: https://github.com/phar-io/manifest/compare/1.0.2...1.0.3\n[1.0.2]: https://github.com/phar-io/manifest/compare/1.0.1...1.0.2\n[1.0.1]: https://github.com/phar-io/manifest/compare/1.0.0...1.0.1\n"
  },
  {
    "path": "LICENSE",
    "content": "Phar.io - Manifest\n\nCopyright (c) 2016-2019 Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>, and contributors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice,\n  this list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of Arne Blankerts nor the names of contributors\n  may be used to endorse or promote products derived from this software\n  without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  * NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS\nBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\nOR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# Manifest\n\nComponent for reading [phar.io](https://phar.io/) manifest information from a [PHP Archive (PHAR)](http://php.net/phar).\n\n## Installation\n\nYou can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):\n\n    composer require phar-io/manifest\n\nIf you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:\n\n    composer require --dev phar-io/manifest\n\n## Usage Examples\n\n### Read from `manifest.xml`\n```php\nuse PharIo\\Manifest\\ManifestLoader;\nuse PharIo\\Manifest\\ManifestSerializer;\n\n$manifest = ManifestLoader::fromFile('manifest.xml');\n\nvar_dump($manifest);\n\necho (new ManifestSerializer)->serializeToString($manifest);\n```\n\n<details>\n  <summary>Output</summary>\n    \n```shell\nobject(PharIo\\Manifest\\Manifest)#14 (6) {\n  [\"name\":\"PharIo\\Manifest\\Manifest\":private]=>\n  object(PharIo\\Manifest\\ApplicationName)#10 (1) {\n    [\"name\":\"PharIo\\Manifest\\ApplicationName\":private]=>\n    string(12) \"some/library\"\n  }\n  [\"version\":\"PharIo\\Manifest\\Manifest\":private]=>\n  object(PharIo\\Version\\Version)#12 (5) {\n    [\"originalVersionString\":\"PharIo\\Version\\Version\":private]=>\n    string(5) \"1.0.0\"\n    [\"major\":\"PharIo\\Version\\Version\":private]=>\n    object(PharIo\\Version\\VersionNumber)#13 (1) {\n      [\"value\":\"PharIo\\Version\\VersionNumber\":private]=>\n      int(1)\n    }\n    [\"minor\":\"PharIo\\Version\\Version\":private]=>\n    object(PharIo\\Version\\VersionNumber)#23 (1) {\n      [\"value\":\"PharIo\\Version\\VersionNumber\":private]=>\n      int(0)\n    }\n    [\"patch\":\"PharIo\\Version\\Version\":private]=>\n    object(PharIo\\Version\\VersionNumber)#22 (1) {\n      [\"value\":\"PharIo\\Version\\VersionNumber\":private]=>\n      int(0)\n    }\n    [\"preReleaseSuffix\":\"PharIo\\Version\\Version\":private]=>\n    NULL\n  }\n  [\"type\":\"PharIo\\Manifest\\Manifest\":private]=>\n  object(PharIo\\Manifest\\Library)#6 (0) {\n  }\n  [\"copyrightInformation\":\"PharIo\\Manifest\\Manifest\":private]=>\n  object(PharIo\\Manifest\\CopyrightInformation)#19 (2) {\n    [\"authors\":\"PharIo\\Manifest\\CopyrightInformation\":private]=>\n    object(PharIo\\Manifest\\AuthorCollection)#9 (1) {\n      [\"authors\":\"PharIo\\Manifest\\AuthorCollection\":private]=>\n      array(1) {\n        [0]=>\n        object(PharIo\\Manifest\\Author)#15 (2) {\n          [\"name\":\"PharIo\\Manifest\\Author\":private]=>\n          string(13) \"Reiner Zufall\"\n          [\"email\":\"PharIo\\Manifest\\Author\":private]=>\n          object(PharIo\\Manifest\\Email)#16 (1) {\n            [\"email\":\"PharIo\\Manifest\\Email\":private]=>\n            string(16) \"reiner@zufall.de\"\n          }\n        }\n      }\n    }\n    [\"license\":\"PharIo\\Manifest\\CopyrightInformation\":private]=>\n    object(PharIo\\Manifest\\License)#11 (2) {\n      [\"name\":\"PharIo\\Manifest\\License\":private]=>\n      string(12) \"BSD-3-Clause\"\n      [\"url\":\"PharIo\\Manifest\\License\":private]=>\n      object(PharIo\\Manifest\\Url)#18 (1) {\n        [\"url\":\"PharIo\\Manifest\\Url\":private]=>\n        string(26) \"https://domain.tld/LICENSE\"\n      }\n    }\n  }\n  [\"requirements\":\"PharIo\\Manifest\\Manifest\":private]=>\n  object(PharIo\\Manifest\\RequirementCollection)#17 (1) {\n    [\"requirements\":\"PharIo\\Manifest\\RequirementCollection\":private]=>\n    array(1) {\n      [0]=>\n      object(PharIo\\Manifest\\PhpVersionRequirement)#20 (1) {\n        [\"versionConstraint\":\"PharIo\\Manifest\\PhpVersionRequirement\":private]=>\n        object(PharIo\\Version\\SpecificMajorAndMinorVersionConstraint)#24 (3) {\n          [\"originalValue\":\"PharIo\\Version\\AbstractVersionConstraint\":private]=>\n          string(3) \"7.0\"\n          [\"major\":\"PharIo\\Version\\SpecificMajorAndMinorVersionConstraint\":private]=>\n          int(7)\n          [\"minor\":\"PharIo\\Version\\SpecificMajorAndMinorVersionConstraint\":private]=>\n          int(0)\n        }\n      }\n    }\n  }\n  [\"bundledComponents\":\"PharIo\\Manifest\\Manifest\":private]=>\n  object(PharIo\\Manifest\\BundledComponentCollection)#8 (1) {\n    [\"bundledComponents\":\"PharIo\\Manifest\\BundledComponentCollection\":private]=>\n    array(0) {\n    }\n  }\n}\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"some/library\" version=\"1.0.0\" type=\"library\"/>\n    <copyright>\n        <author name=\"Reiner Zufall\" email=\"reiner@zufall.de\"/>\n        <license type=\"BSD-3-Clause\" url=\"https://domain.tld/LICENSE\"/>\n    </copyright>\n    <requires>\n        <php version=\"7.0\"/>\n    </requires>\n</phar>\n```\n</details>\n\n### Create via API\n```php\n$bundled = new \\PharIo\\Manifest\\BundledComponentCollection();\n$bundled->add(\n    new \\PharIo\\Manifest\\BundledComponent('vendor/packageA', new \\PharIo\\Version\\Version('1.2.3-dev')\n    )\n);\n\n$manifest = new PharIo\\Manifest\\Manifest(\n    new \\PharIo\\Manifest\\ApplicationName('vendor/package'),\n    new \\PharIo\\Version\\Version('1.0.0'),\n    new \\PharIo\\Manifest\\Library(),\n    new \\PharIo\\Manifest\\CopyrightInformation(\n        new \\PharIo\\Manifest\\AuthorCollection(),\n        new \\PharIo\\Manifest\\License(\n            'BSD-3-Clause',\n            new \\PharIo\\Manifest\\Url('https://spdx.org/licenses/BSD-3-Clause.html')\n        )\n    ),\n    new \\PharIo\\Manifest\\RequirementCollection(),\n    $bundled\n);\n\necho (new ManifestSerializer)->serializeToString($manifest);\n```\n\n<details>\n  <summary>Output</summary>\n    \n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"vendor/package\" version=\"1.0.0\" type=\"library\"/>\n    <copyright>\n        <license type=\"BSD-3-Clause\" url=\"https://spdx.org/licenses/BSD-3-Clause.html\"/>\n    </copyright>\n    <requires>\n        <php version=\"*\"/>\n    </requires>\n    <bundles>\n        <component name=\"vendor/packageA\" version=\"1.2.3-dev\"/>\n    </bundles>\n</phar>\n```\n    \n</details>\n\n"
  },
  {
    "path": "build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project name=\"manifest\" default=\"setup\">\n    <property name=\"phive.bin\" value=\"phive\" />\n\n    <target name=\"setup\" depends=\"clean,install-tools,install-dependencies\"/>\n\n    <target name=\"clean\" unless=\"clean.done\" description=\"Cleanup build artifacts\">\n        <delete dir=\"${basedir}/tools\"/>\n        <delete dir=\"${basedir}/vendor\"/>\n        <delete file=\"${basedir}/src/autoload.php\"/>\n\n        <property name=\"clean.done\" value=\"true\"/>\n    </target>\n\n    <target name=\"prepare\" unless=\"prepare.done\" depends=\"clean\" description=\"Prepare for build\">\n        <property name=\"prepare.done\" value=\"true\"/>\n    </target>\n\n    <target name=\"install-dependencies\" description=\"Install dependencies with Composer\">\n        <exec executable=\"${basedir}/tools/composer\" taskname=\"composer\">\n            <env key=\"COMPOSER_DISABLE_XDEBUG_WARN\" value=\"1\"/>\n            <arg value=\"install\"/>\n            <arg value=\"--no-interaction\"/>\n            <arg value=\"--no-progress\"/>\n            <arg value=\"--no-ansi\"/>\n            <arg value=\"--optimize-autoloader\"/>\n        </exec>\n    </target>\n\n    <target name=\"install-tools\" unless=\"tools-installed\" depends=\"-tools-installed\" description=\"Install tools with Phive\">\n        <exec executable=\"${phive.bin}\" taskname=\"phive\" failonerror=\"true\">\n            <arg value=\"--no-progress\" />\n            <arg value=\"install\"/>\n            <arg value=\"--copy\" />\n            <arg value=\"--trust-gpg-keys\" />\n            <!--        phpab,           phpunit,         phpstan,         psaml,           php-cs-fixer,    composer     -->\n            <arg value=\"4AA394086372C20A,2A8299CE842DD38C,CF1A108D0E7AE720,12CE0F1D262429A5,E82B2FB314E9906E,CBB3D576F2A0946F\" />\n        </exec>\n    </target>\n\n    <target name=\"php-cs-fixer\" depends=\"install-tools\" description=\"Dry run php csfixer\">\n        <exec executable=\"${basedir}/tools/php-cs-fixer\" failonerror=\"true\">\n            <arg value=\"fix\" />\n            <arg value=\"--dry-run\" />\n        </exec>\n    </target>\n\n    <target name=\"psalm\" depends=\"install-tools,install-dependencies\" description=\"Run psalm\">\n        <exec executable=\"${basedir}/tools/psalm\" taskname=\"psalm-cache-clear\">\n            <arg value=\"--config=psalm.xml\" />\n            <arg value=\"--clear-cache\" />\n        </exec>\n\n        <exec executable=\"${basedir}/tools/psalm\" taskname=\"psalm\" failonerror=\"true\">\n            <arg value=\"--config=psalm.xml\" />\n            <arg value=\"--show-info=true\" />\n            <arg value=\"--stats\" />\n        </exec>\n    </target>\n\n    <target name=\"psalm-baseline\" depends=\"install-tools,install-dependencies\" description=\"Run psalm\">\n        <exec executable=\"${basedir}/tools/psalm\" taskname=\"psalm-cache-clear\">\n            <arg value=\"--config=psalm.xml\" />\n            <arg value=\"--clear-cache\" />\n        </exec>\n\n        <exec executable=\"${basedir}/tools/psalm\" taskname=\"psalm-baseline\">\n            <arg value=\"--config=psalm.xml\" />\n            <arg value=\"--set-baseline=build/psalm-baseline.xml\" />\n            <arg value=\"--show-info=false\" />\n        </exec>\n    </target>\n\n    <target name=\"test\" depends=\"install-tools,install-dependencies\" description=\"Run tests\">\n        <exec executable=\"${basedir}/tools/phpunit\" taskname=\"phpunit\"/>\n    </target>\n\n    <target name=\"phpunit-ci\">\n        <condition property=\"phpunit\" value=\"phpunit.bat\" else=\"phpunit\">\n            <os family=\"windows\" />\n        </condition>\n        <exec executable=\"${basedir}/tools/${phpunit}\" taskname=\"phpunit\">\n            <arg value=\"--coverage-clover build/logs/clover.xml\" />\n        </exec>\n    </target>\n\n    <target name=\"-tools-installed\">\n        <available file=\"${basedir}/tools/phpunit\" property=\"tools-installed\" type=\"file\"/>\n    </target>\n</project>\n\n"
  },
  {
    "path": "composer.json",
    "content": "{\n  \"name\": \"phar-io/manifest\",\n  \"description\": \"Component for reading phar.io manifest information from a PHP Archive (PHAR)\",\n  \"license\": \"BSD-3-Clause\",\n  \"authors\": [\n    {\n      \"name\": \"Arne Blankerts\",\n      \"email\": \"arne@blankerts.de\",\n      \"role\": \"Developer\"\n    },\n    {\n      \"name\": \"Sebastian Heuer\",\n      \"email\": \"sebastian@phpeople.de\",\n      \"role\": \"Developer\"\n    },\n    {\n      \"name\": \"Sebastian Bergmann\",\n      \"email\": \"sebastian@phpunit.de\",\n      \"role\": \"Developer\"\n    }\n  ],\n  \"support\": {\n    \"issues\": \"https://github.com/phar-io/manifest/issues\"\n  },\n  \"require\": {\n    \"php\": \"^7.2 || ^8.0\",\n    \"ext-dom\": \"*\",\n    \"ext-phar\": \"*\",\n    \"ext-libxml\": \"*\",\n    \"ext-xmlwriter\": \"*\",\n    \"phar-io/version\": \"^3.0.1\"\n  },\n  \"autoload\": {\n    \"classmap\": [\n      \"src/\"\n    ]\n  },\n  \"extra\": {\n    \"branch-alias\": {\n        \"dev-master\": \"2.0.x-dev\"\n    }\n  }\n}\n"
  },
  {
    "path": "examples/example-01.php",
    "content": "<?php\n/*\n * This file is part of PharIo\\Manifest.\n *\n * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nuse PharIo\\Manifest\\ManifestLoader;\nuse PharIo\\Manifest\\ManifestSerializer;\n\nrequire __DIR__ . '/../vendor/autoload.php';\n\n$manifest = ManifestLoader::fromFile(__DIR__ . '/../tests/_fixture/phpunit-5.6.5.xml');\n\necho sprintf(\n    \"Manifest for %s (%s):\\n\\n\",\n    $manifest->getName()->asString(),\n    $manifest->getVersion()->getVersionString()\n);\n\necho (new ManifestSerializer)->serializeToString($manifest);\n"
  },
  {
    "path": "examples/example-02.php",
    "content": "<?php declare(strict_types = 1);\n/**\n * Thanks to @llaville for this example\n */\nuse PharIo\\Manifest\\ManifestSerializer;\n\nrequire __DIR__ . '/../vendor/autoload.php';\n\n$bundledComponentCollection = new \\PharIo\\Manifest\\BundledComponentCollection();\n$bundledComponentCollection->add(\n    new \\PharIo\\Manifest\\BundledComponent(\n        'vendor/packageA',\n        new \\PharIo\\Version\\Version('0.0.0-dev')\n    )\n);\n\n$manifest = new PharIo\\Manifest\\Manifest(\n    new \\PharIo\\Manifest\\ApplicationName('vendor/package'),\n    new \\PharIo\\Version\\Version('1.0.0'),\n    new \\PharIo\\Manifest\\Library(),\n    new \\PharIo\\Manifest\\CopyrightInformation(\n        new \\PharIo\\Manifest\\AuthorCollection(),\n        new \\PharIo\\Manifest\\License(\n            'BSD-3-Clause',\n            new \\PharIo\\Manifest\\Url('https://spdx.org/licenses/BSD-3-Clause.html')\n        )\n    ),\n    new \\PharIo\\Manifest\\RequirementCollection(),\n    $bundledComponentCollection\n);\n\necho (new ManifestSerializer)->serializeToString($manifest);\n\n/*\n * Output produced\n *\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"vendor/package\" version=\"1.0.0\" type=\"library\"/>\n    <copyright>\n        <license type=\"BSD-3-Clause\" url=\"https://spdx.org/licenses/BSD-3-Clause.html\"/>\n    </copyright>\n    <requires>\n        <php version=\"*\"/>\n    </requires>\n    <bundles>\n        <component name=\"vendor/packageA\" version=\"0.0.0-dev\"/>\n    </bundles>\n</phar>\n */\n"
  },
  {
    "path": "manifest.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" targetNamespace=\"https://phar.io/xml/manifest/1.0\"\n           xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:ns=\"https://phar.io/xml/manifest/1.0\">\n\n  <xs:element name=\"phar\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element ref=\"ns:contains\" maxOccurs=\"1\" />\n        <xs:element ref=\"ns:copyright\" maxOccurs=\"1\" />\n        <xs:element ref=\"ns:requires\" maxOccurs=\"1\" />\n        <xs:element ref=\"ns:bundles\" minOccurs=\"0\" maxOccurs=\"1\" />\n      </xs:sequence>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"contains\">\n    <xs:complexType>\n      <xs:simpleContent>\n        <xs:extension base=\"xs:string\">\n          <xs:attribute type=\"xs:string\" use=\"required\" name=\"name\"/>\n          <xs:attribute type=\"xs:string\" use=\"required\" name=\"version\"/>\n          <xs:attribute use=\"required\" name=\"type\">\n            <xs:simpleType>\n              <xs:restriction base=\"xs:string\">\n                <xs:enumeration value=\"application\"/>\n                <xs:enumeration value=\"extension\"/>\n                <xs:enumeration value=\"library\"/>\n                <xs:enumeration value=\"stub\"/>\n              </xs:restriction>\n            </xs:simpleType>\n          </xs:attribute>\n        </xs:extension>\n      </xs:simpleContent>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"copyright\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:choice maxOccurs=\"unbounded\">\n          <xs:element ref=\"ns:author\" minOccurs=\"1\" maxOccurs=\"unbounded\" />\n        </xs:choice>\n        <xs:element ref=\"ns:license\" minOccurs=\"1\" maxOccurs=\"1\" />\n      </xs:sequence>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"author\">\n    <xs:complexType>\n      <xs:simpleContent>\n        <xs:extension base=\"xs:string\">\n          <xs:attribute type=\"xs:string\" use=\"required\" name=\"name\"/>\n          <xs:attribute type=\"xs:string\" use=\"optional\" name=\"email\"/>\n        </xs:extension>\n      </xs:simpleContent>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"license\">\n    <xs:complexType>\n      <xs:simpleContent>\n        <xs:extension base=\"xs:string\">\n          <xs:attribute type=\"xs:string\" use=\"required\" name=\"type\"/>\n          <xs:attribute type=\"xs:string\" use=\"required\" name=\"url\"/>\n        </xs:extension>\n      </xs:simpleContent>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"requires\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element ref=\"ns:php\" />\n      </xs:sequence>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"php\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element ref=\"ns:ext\" maxOccurs=\"unbounded\" minOccurs=\"0\"  />\n      </xs:sequence>\n      <xs:attribute type=\"xs:string\" use=\"required\" name=\"version\"/>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"ext\">\n    <xs:complexType>\n      <xs:simpleContent>\n        <xs:extension base=\"xs:string\">\n          <xs:attribute type=\"xs:string\" name=\"name\" use=\"required\" />\n        </xs:extension>\n      </xs:simpleContent>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"bundles\">\n    <xs:complexType>\n      <xs:sequence>\n        <xs:element ref=\"ns:component\" maxOccurs=\"unbounded\" minOccurs=\"0\" />\n      </xs:sequence>\n    </xs:complexType>\n  </xs:element>\n\n  <xs:element name=\"component\">\n    <xs:complexType>\n      <xs:simpleContent>\n        <xs:extension base=\"xs:string\">\n          <xs:attribute type=\"xs:string\" name=\"name\" use=\"required\"/>\n          <xs:attribute type=\"xs:string\" name=\"version\" use=\"required\"/>\n        </xs:extension>\n      </xs:simpleContent>\n    </xs:complexType>\n  </xs:element>\n\n</xs:schema>\n"
  },
  {
    "path": "phive.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phive xmlns=\"https://phar.io/phive\">\n  <phar name=\"php-cs-fixer\" version=\"^3.17.0\" installed=\"3.17.0\" location=\"./tools/php-cs-fixer\" copy=\"true\"/>\n  <phar name=\"psalm\" version=\"^5.0\" installed=\"5.12.0\" location=\"./tools/psalm\" copy=\"true\"/>\n  <phar name=\"phpunit\" version=\"^9.6\" installed=\"9.6.8\" location=\"./tools/phpunit\" copy=\"true\"/>\n  <phar name=\"composer\" version=\"^2.5.5\" installed=\"2.5.7\" location=\"./tools/composer\" copy=\"true\"/>\n</phive>\n"
  },
  {
    "path": "phpunit.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"https://schema.phpunit.de/9.3/phpunit.xsd\" bootstrap=\"vendor/autoload.php\" backupGlobals=\"false\" beStrictAboutCoversAnnotation=\"true\" beStrictAboutOutputDuringTests=\"true\" beStrictAboutTestsThatDoNotTestAnything=\"true\" beStrictAboutTodoAnnotatedTests=\"true\" verbose=\"true\">\n  <coverage processUncoveredFiles=\"true\">\n    <include>\n      <directory suffix=\".php\">src</directory>\n    </include>\n  </coverage>\n  <testsuite name=\"phar.io manifest\">\n    <directory suffix=\"Test.php\">tests</directory>\n  </testsuite>\n</phpunit>\n"
  },
  {
    "path": "psalm.xml",
    "content": "<?xml version=\"1.0\"?>\n<psalm xmlns=\"https://getpsalm.org/schema/config\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd\"\n    errorBaseline=\"build/psalm-baseline.xml\"\n    errorLevel=\"1\"\n    findUnusedVariablesAndParams=\"true\"\n    resolveFromConfigFile=\"true\"\n    strictBinaryOperands=\"true\"\n    findUnusedBaselineEntry=\"true\"\n    findUnusedCode=\"true\"\n>\n    <projectFiles>\n        <directory name=\"src\" />\n        <ignoreFiles>\n            <directory name=\"vendor\" />\n        </ignoreFiles>\n    </projectFiles>\n</psalm>\n"
  },
  {
    "path": "src/ManifestDocumentMapper.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\Exception as VersionException;\nuse PharIo\\Version\\Version;\nuse PharIo\\Version\\VersionConstraintParser;\nuse Throwable;\nuse function sprintf;\n\nclass ManifestDocumentMapper {\n    public function map(ManifestDocument $document): Manifest {\n        try {\n            $contains          = $document->getContainsElement();\n            $type              = $this->mapType($contains);\n            $copyright         = $this->mapCopyright($document->getCopyrightElement());\n            $requirements      = $this->mapRequirements($document->getRequiresElement());\n            $bundledComponents = $this->mapBundledComponents($document);\n\n            return new Manifest(\n                new ApplicationName($contains->getName()),\n                new Version($contains->getVersion()),\n                $type,\n                $copyright,\n                $requirements,\n                $bundledComponents\n            );\n        } catch (Throwable $e) {\n            throw new ManifestDocumentMapperException($e->getMessage(), (int)$e->getCode(), $e);\n        }\n    }\n\n    private function mapType(ContainsElement $contains): Type {\n        switch ($contains->getType()) {\n            case 'application':\n                return Type::application();\n            case 'library':\n                return Type::library();\n            case 'extension':\n                return $this->mapExtension($contains->getExtensionElement());\n        }\n\n        throw new ManifestDocumentMapperException(\n            sprintf('Unsupported type %s', $contains->getType())\n        );\n    }\n\n    private function mapCopyright(CopyrightElement $copyright): CopyrightInformation {\n        $authors = new AuthorCollection();\n\n        foreach ($copyright->getAuthorElements() as $authorElement) {\n            $authors->add(\n                new Author(\n                    $authorElement->getName(),\n                    $authorElement->hasEMail() ? new Email($authorElement->getEmail()) : null\n                )\n            );\n        }\n\n        $licenseElement = $copyright->getLicenseElement();\n        $license        = new License(\n            $licenseElement->getType(),\n            new Url($licenseElement->getUrl())\n        );\n\n        return new CopyrightInformation(\n            $authors,\n            $license\n        );\n    }\n\n    private function mapRequirements(RequiresElement $requires): RequirementCollection {\n        $collection = new RequirementCollection();\n        $phpElement = $requires->getPHPElement();\n        $parser     = new VersionConstraintParser;\n\n        try {\n            $versionConstraint = $parser->parse($phpElement->getVersion());\n        } catch (VersionException $e) {\n            throw new ManifestDocumentMapperException(\n                sprintf('Unsupported version constraint - %s', $e->getMessage()),\n                (int)$e->getCode(),\n                $e\n            );\n        }\n\n        $collection->add(\n            new PhpVersionRequirement(\n                $versionConstraint\n            )\n        );\n\n        if (!$phpElement->hasExtElements()) {\n            return $collection;\n        }\n\n        foreach ($phpElement->getExtElements() as $extElement) {\n            $collection->add(\n                new PhpExtensionRequirement($extElement->getName())\n            );\n        }\n\n        return $collection;\n    }\n\n    private function mapBundledComponents(ManifestDocument $document): BundledComponentCollection {\n        $collection = new BundledComponentCollection();\n\n        if (!$document->hasBundlesElement()) {\n            return $collection;\n        }\n\n        foreach ($document->getBundlesElement()->getComponentElements() as $componentElement) {\n            $collection->add(\n                new BundledComponent(\n                    $componentElement->getName(),\n                    new Version(\n                        $componentElement->getVersion()\n                    )\n                )\n            );\n        }\n\n        return $collection;\n    }\n\n    private function mapExtension(ExtensionElement $extension): Extension {\n        try {\n            $versionConstraint = (new VersionConstraintParser)->parse($extension->getCompatible());\n\n            return Type::extension(\n                new ApplicationName($extension->getFor()),\n                $versionConstraint\n            );\n        } catch (VersionException $e) {\n            throw new ManifestDocumentMapperException(\n                sprintf('Unsupported version constraint - %s', $e->getMessage()),\n                (int)$e->getCode(),\n                $e\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/ManifestLoader.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse function sprintf;\n\nclass ManifestLoader {\n    public static function fromFile(string $filename): Manifest {\n        try {\n            return (new ManifestDocumentMapper())->map(\n                ManifestDocument::fromFile($filename)\n            );\n        } catch (Exception $e) {\n            throw new ManifestLoaderException(\n                sprintf('Loading %s failed.', $filename),\n                (int)$e->getCode(),\n                $e\n            );\n        }\n    }\n\n    public static function fromPhar(string $filename): Manifest {\n        return self::fromFile('phar://' . $filename . '/manifest.xml');\n    }\n\n    public static function fromString(string $manifest): Manifest {\n        try {\n            return (new ManifestDocumentMapper())->map(\n                ManifestDocument::fromString($manifest)\n            );\n        } catch (Exception $e) {\n            throw new ManifestLoaderException(\n                'Processing string failed',\n                (int)$e->getCode(),\n                $e\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/ManifestSerializer.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\AnyVersionConstraint;\nuse PharIo\\Version\\Version;\nuse PharIo\\Version\\VersionConstraint;\nuse XMLWriter;\nuse function count;\nuse function file_put_contents;\nuse function str_repeat;\n\n/** @psalm-suppress MissingConstructor */\nclass ManifestSerializer {\n    /** @var XMLWriter */\n    private $xmlWriter;\n\n    public function serializeToFile(Manifest $manifest, string $filename): void {\n        file_put_contents(\n            $filename,\n            $this->serializeToString($manifest)\n        );\n    }\n\n    public function serializeToString(Manifest $manifest): string {\n        $this->startDocument();\n\n        $this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType());\n        $this->addCopyright($manifest->getCopyrightInformation());\n        $this->addRequirements($manifest->getRequirements());\n        $this->addBundles($manifest->getBundledComponents());\n\n        return $this->finishDocument();\n    }\n\n    private function startDocument(): void {\n        $xmlWriter = new XMLWriter();\n        $xmlWriter->openMemory();\n        $xmlWriter->setIndent(true);\n        $xmlWriter->setIndentString(str_repeat(' ', 4));\n        $xmlWriter->startDocument('1.0', 'UTF-8');\n        $xmlWriter->startElement('phar');\n        $xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0');\n\n        $this->xmlWriter = $xmlWriter;\n    }\n\n    private function finishDocument(): string {\n        $this->xmlWriter->endElement();\n        $this->xmlWriter->endDocument();\n\n        return $this->xmlWriter->outputMemory();\n    }\n\n    private function addContains(ApplicationName $name, Version $version, Type $type): void {\n        $this->xmlWriter->startElement('contains');\n        $this->xmlWriter->writeAttribute('name', $name->asString());\n        $this->xmlWriter->writeAttribute('version', $version->getVersionString());\n\n        switch (true) {\n            case $type->isApplication(): {\n                $this->xmlWriter->writeAttribute('type', 'application');\n\n                break;\n            }\n\n            case $type->isLibrary(): {\n                $this->xmlWriter->writeAttribute('type', 'library');\n\n                break;\n            }\n\n            case $type->isExtension(): {\n                $this->xmlWriter->writeAttribute('type', 'extension');\n                /* @var $type Extension */\n                $this->addExtension(\n                    $type->getApplicationName(),\n                    $type->getVersionConstraint()\n                );\n\n                break;\n            }\n\n            default: {\n                $this->xmlWriter->writeAttribute('type', 'custom');\n            }\n        }\n\n        $this->xmlWriter->endElement();\n    }\n\n    private function addCopyright(CopyrightInformation $copyrightInformation): void {\n        $this->xmlWriter->startElement('copyright');\n\n        foreach ($copyrightInformation->getAuthors() as $author) {\n            $this->xmlWriter->startElement('author');\n            $this->xmlWriter->writeAttribute('name', $author->getName());\n            $this->xmlWriter->writeAttribute('email', $author->getEmail()->asString());\n            $this->xmlWriter->endElement();\n        }\n\n        $license = $copyrightInformation->getLicense();\n\n        $this->xmlWriter->startElement('license');\n        $this->xmlWriter->writeAttribute('type', $license->getName());\n        $this->xmlWriter->writeAttribute('url', $license->getUrl()->asString());\n        $this->xmlWriter->endElement();\n\n        $this->xmlWriter->endElement();\n    }\n\n    private function addRequirements(RequirementCollection $requirementCollection): void {\n        $phpRequirement = new AnyVersionConstraint();\n        $extensions     = [];\n\n        foreach ($requirementCollection as $requirement) {\n            if ($requirement instanceof PhpVersionRequirement) {\n                $phpRequirement = $requirement->getVersionConstraint();\n\n                continue;\n            }\n\n            if ($requirement instanceof PhpExtensionRequirement) {\n                $extensions[] = $requirement->asString();\n            }\n        }\n\n        $this->xmlWriter->startElement('requires');\n        $this->xmlWriter->startElement('php');\n        $this->xmlWriter->writeAttribute('version', $phpRequirement->asString());\n\n        foreach ($extensions as $extension) {\n            $this->xmlWriter->startElement('ext');\n            $this->xmlWriter->writeAttribute('name', $extension);\n            $this->xmlWriter->endElement();\n        }\n\n        $this->xmlWriter->endElement();\n        $this->xmlWriter->endElement();\n    }\n\n    private function addBundles(BundledComponentCollection $bundledComponentCollection): void {\n        if (count($bundledComponentCollection) === 0) {\n            return;\n        }\n        $this->xmlWriter->startElement('bundles');\n\n        foreach ($bundledComponentCollection as $bundledComponent) {\n            $this->xmlWriter->startElement('component');\n            $this->xmlWriter->writeAttribute('name', $bundledComponent->getName());\n            $this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString());\n            $this->xmlWriter->endElement();\n        }\n\n        $this->xmlWriter->endElement();\n    }\n\n    private function addExtension(ApplicationName $applicationName, VersionConstraint $versionConstraint): void {\n        $this->xmlWriter->startElement('extension');\n        $this->xmlWriter->writeAttribute('for', $applicationName->asString());\n        $this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString());\n        $this->xmlWriter->endElement();\n    }\n}\n"
  },
  {
    "path": "src/exceptions/ElementCollectionException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse InvalidArgumentException;\n\nclass ElementCollectionException extends InvalidArgumentException implements Exception {\n}\n"
  },
  {
    "path": "src/exceptions/Exception.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse Throwable;\n\ninterface Exception extends Throwable {\n}\n"
  },
  {
    "path": "src/exceptions/InvalidApplicationNameException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse InvalidArgumentException;\n\nclass InvalidApplicationNameException extends InvalidArgumentException implements Exception {\n    public const InvalidFormat = 2;\n}\n"
  },
  {
    "path": "src/exceptions/InvalidEmailException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse InvalidArgumentException;\n\nclass InvalidEmailException extends InvalidArgumentException implements Exception {\n}\n"
  },
  {
    "path": "src/exceptions/InvalidUrlException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse InvalidArgumentException;\n\nclass InvalidUrlException extends InvalidArgumentException implements Exception {\n}\n"
  },
  {
    "path": "src/exceptions/ManifestDocumentException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse RuntimeException;\n\nclass ManifestDocumentException extends RuntimeException implements Exception {\n}\n"
  },
  {
    "path": "src/exceptions/ManifestDocumentLoadingException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse LibXMLError;\nuse function sprintf;\n\nclass ManifestDocumentLoadingException extends \\Exception implements Exception {\n    /** @var LibXMLError[] */\n    private $libxmlErrors;\n\n    /**\n     * ManifestDocumentLoadingException constructor.\n     *\n     * @param LibXMLError[] $libxmlErrors\n     */\n    public function __construct(array $libxmlErrors) {\n        $this->libxmlErrors = $libxmlErrors;\n        $first              = $this->libxmlErrors[0];\n\n        parent::__construct(\n            sprintf(\n                '%s (Line: %d / Column: %d / File: %s)',\n                $first->message,\n                $first->line,\n                $first->column,\n                $first->file\n            ),\n            $first->code\n        );\n    }\n\n    /**\n     * @return LibXMLError[]\n     */\n    public function getLibxmlErrors(): array {\n        return $this->libxmlErrors;\n    }\n}\n"
  },
  {
    "path": "src/exceptions/ManifestDocumentMapperException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse RuntimeException;\n\nclass ManifestDocumentMapperException extends RuntimeException implements Exception {\n}\n"
  },
  {
    "path": "src/exceptions/ManifestElementException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse RuntimeException;\n\nclass ManifestElementException extends RuntimeException implements Exception {\n}\n"
  },
  {
    "path": "src/exceptions/ManifestLoaderException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass ManifestLoaderException extends \\Exception implements Exception {\n}\n"
  },
  {
    "path": "src/exceptions/NoEmailAddressException.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse InvalidArgumentException;\n\nclass NoEmailAddressException extends InvalidArgumentException implements Exception {\n}\n"
  },
  {
    "path": "src/values/Application.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass Application extends Type {\n    public function isApplication(): bool {\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/values/ApplicationName.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse function preg_match;\nuse function sprintf;\n\nclass ApplicationName {\n    /** @var string */\n    private $name;\n\n    public function __construct(string $name) {\n        $this->ensureValidFormat($name);\n        $this->name = $name;\n    }\n\n    public function asString(): string {\n        return $this->name;\n    }\n\n    public function isEqual(ApplicationName $name): bool {\n        return $this->name === $name->name;\n    }\n\n    private function ensureValidFormat(string $name): void {\n        if (!preg_match('#\\w/\\w#', $name)) {\n            throw new InvalidApplicationNameException(\n                sprintf('Format of name \"%s\" is not valid - expected: vendor/packagename', $name),\n                InvalidApplicationNameException::InvalidFormat\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/values/Author.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse function sprintf;\n\nclass Author {\n    /** @var string */\n    private $name;\n\n    /** @var null|Email */\n    private $email;\n\n    public function __construct(string $name, ?Email $email = null) {\n        $this->name  = $name;\n        $this->email = $email;\n    }\n\n    public function asString(): string {\n        if (!$this->hasEmail()) {\n            return $this->name;\n        }\n\n        return sprintf(\n            '%s <%s>',\n            $this->name,\n            $this->email->asString()\n        );\n    }\n\n    public function getName(): string {\n        return $this->name;\n    }\n\n    /**\n     * @psalm-assert-if-true Email $this->email\n     */\n    public function hasEmail(): bool {\n        return $this->email !== null;\n    }\n\n    public function getEmail(): Email {\n        if (!$this->hasEmail()) {\n            throw new NoEmailAddressException();\n        }\n\n        return $this->email;\n    }\n}\n"
  },
  {
    "path": "src/values/AuthorCollection.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse Countable;\nuse IteratorAggregate;\nuse function count;\n\n/** @template-implements IteratorAggregate<int,Author> */\nclass AuthorCollection implements Countable, IteratorAggregate {\n    /** @var Author[] */\n    private $authors = [];\n\n    public function add(Author $author): void {\n        $this->authors[] = $author;\n    }\n\n    /**\n     * @return Author[]\n     */\n    public function getAuthors(): array {\n        return $this->authors;\n    }\n\n    public function count(): int {\n        return count($this->authors);\n    }\n\n    public function getIterator(): AuthorCollectionIterator {\n        return new AuthorCollectionIterator($this);\n    }\n}\n"
  },
  {
    "path": "src/values/AuthorCollectionIterator.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse Iterator;\nuse function count;\n\n/** @template-implements Iterator<int,Author> */\nclass AuthorCollectionIterator implements Iterator {\n    /** @var Author[] */\n    private $authors;\n\n    /** @var int */\n    private $position = 0;\n\n    public function __construct(AuthorCollection $authors) {\n        $this->authors = $authors->getAuthors();\n    }\n\n    public function rewind(): void {\n        $this->position = 0;\n    }\n\n    public function valid(): bool {\n        return $this->position < count($this->authors);\n    }\n\n    public function key(): int {\n        return $this->position;\n    }\n\n    public function current(): Author {\n        return $this->authors[$this->position];\n    }\n\n    public function next(): void {\n        $this->position++;\n    }\n}\n"
  },
  {
    "path": "src/values/BundledComponent.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\Version;\n\nclass BundledComponent {\n    /** @var string */\n    private $name;\n\n    /** @var Version */\n    private $version;\n\n    public function __construct(string $name, Version $version) {\n        $this->name    = $name;\n        $this->version = $version;\n    }\n\n    public function getName(): string {\n        return $this->name;\n    }\n\n    public function getVersion(): Version {\n        return $this->version;\n    }\n}\n"
  },
  {
    "path": "src/values/BundledComponentCollection.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse Countable;\nuse IteratorAggregate;\nuse function count;\n\n/** @template-implements IteratorAggregate<int,BundledComponent> */\nclass BundledComponentCollection implements Countable, IteratorAggregate {\n    /** @var BundledComponent[] */\n    private $bundledComponents = [];\n\n    public function add(BundledComponent $bundledComponent): void {\n        $this->bundledComponents[] = $bundledComponent;\n    }\n\n    /**\n     * @return BundledComponent[]\n     */\n    public function getBundledComponents(): array {\n        return $this->bundledComponents;\n    }\n\n    public function count(): int {\n        return count($this->bundledComponents);\n    }\n\n    public function getIterator(): BundledComponentCollectionIterator {\n        return new BundledComponentCollectionIterator($this);\n    }\n}\n"
  },
  {
    "path": "src/values/BundledComponentCollectionIterator.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse Iterator;\nuse function count;\n\n/** @template-implements Iterator<int,BundledComponent> */\nclass BundledComponentCollectionIterator implements Iterator {\n    /** @var BundledComponent[] */\n    private $bundledComponents;\n\n    /** @var int */\n    private $position = 0;\n\n    public function __construct(BundledComponentCollection $bundledComponents) {\n        $this->bundledComponents = $bundledComponents->getBundledComponents();\n    }\n\n    public function rewind(): void {\n        $this->position = 0;\n    }\n\n    public function valid(): bool {\n        return $this->position < count($this->bundledComponents);\n    }\n\n    public function key(): int {\n        return $this->position;\n    }\n\n    public function current(): BundledComponent {\n        return $this->bundledComponents[$this->position];\n    }\n\n    public function next(): void {\n        $this->position++;\n    }\n}\n"
  },
  {
    "path": "src/values/CopyrightInformation.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass CopyrightInformation {\n    /** @var AuthorCollection */\n    private $authors;\n\n    /** @var License */\n    private $license;\n\n    public function __construct(AuthorCollection $authors, License $license) {\n        $this->authors = $authors;\n        $this->license = $license;\n    }\n\n    public function getAuthors(): AuthorCollection {\n        return $this->authors;\n    }\n\n    public function getLicense(): License {\n        return $this->license;\n    }\n}\n"
  },
  {
    "path": "src/values/Email.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse const FILTER_VALIDATE_EMAIL;\nuse function filter_var;\n\nclass Email {\n    /** @var string */\n    private $email;\n\n    public function __construct(string $email) {\n        $this->ensureEmailIsValid($email);\n\n        $this->email = $email;\n    }\n\n    public function asString(): string {\n        return $this->email;\n    }\n\n    private function ensureEmailIsValid(string $url): void {\n        if (filter_var($url, FILTER_VALIDATE_EMAIL) === false) {\n            throw new InvalidEmailException;\n        }\n    }\n}\n"
  },
  {
    "path": "src/values/Extension.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\Version;\nuse PharIo\\Version\\VersionConstraint;\n\nclass Extension extends Type {\n    /** @var ApplicationName */\n    private $application;\n\n    /** @var VersionConstraint */\n    private $versionConstraint;\n\n    public function __construct(ApplicationName $application, VersionConstraint $versionConstraint) {\n        $this->application       = $application;\n        $this->versionConstraint = $versionConstraint;\n    }\n\n    public function getApplicationName(): ApplicationName {\n        return $this->application;\n    }\n\n    public function getVersionConstraint(): VersionConstraint {\n        return $this->versionConstraint;\n    }\n\n    public function isExtension(): bool {\n        return true;\n    }\n\n    public function isExtensionFor(ApplicationName $name): bool {\n        return $this->application->isEqual($name);\n    }\n\n    public function isCompatibleWith(ApplicationName $name, Version $version): bool {\n        return $this->isExtensionFor($name) && $this->versionConstraint->complies($version);\n    }\n}\n"
  },
  {
    "path": "src/values/Library.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass Library extends Type {\n    public function isLibrary(): bool {\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/values/License.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass License {\n    /** @var string */\n    private $name;\n\n    /** @var Url */\n    private $url;\n\n    public function __construct(string $name, Url $url) {\n        $this->name = $name;\n        $this->url  = $url;\n    }\n\n    public function getName(): string {\n        return $this->name;\n    }\n\n    public function getUrl(): Url {\n        return $this->url;\n    }\n}\n"
  },
  {
    "path": "src/values/Manifest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\Version;\n\nclass Manifest {\n    /** @var ApplicationName */\n    private $name;\n\n    /** @var Version */\n    private $version;\n\n    /** @var Type */\n    private $type;\n\n    /** @var CopyrightInformation */\n    private $copyrightInformation;\n\n    /** @var RequirementCollection */\n    private $requirements;\n\n    /** @var BundledComponentCollection */\n    private $bundledComponents;\n\n    public function __construct(ApplicationName $name, Version $version, Type $type, CopyrightInformation $copyrightInformation, RequirementCollection $requirements, BundledComponentCollection $bundledComponents) {\n        $this->name                 = $name;\n        $this->version              = $version;\n        $this->type                 = $type;\n        $this->copyrightInformation = $copyrightInformation;\n        $this->requirements         = $requirements;\n        $this->bundledComponents    = $bundledComponents;\n    }\n\n    public function getName(): ApplicationName {\n        return $this->name;\n    }\n\n    public function getVersion(): Version {\n        return $this->version;\n    }\n\n    public function getType(): Type {\n        return $this->type;\n    }\n\n    public function getCopyrightInformation(): CopyrightInformation {\n        return $this->copyrightInformation;\n    }\n\n    public function getRequirements(): RequirementCollection {\n        return $this->requirements;\n    }\n\n    public function getBundledComponents(): BundledComponentCollection {\n        return $this->bundledComponents;\n    }\n\n    public function isApplication(): bool {\n        return $this->type->isApplication();\n    }\n\n    public function isLibrary(): bool {\n        return $this->type->isLibrary();\n    }\n\n    public function isExtension(): bool {\n        return $this->type->isExtension();\n    }\n\n    public function isExtensionFor(ApplicationName $application, ?Version $version = null): bool {\n        if (!$this->isExtension()) {\n            return false;\n        }\n\n        /** @var Extension $type */\n        $type = $this->type;\n\n        if ($version !== null) {\n            return $type->isCompatibleWith($application, $version);\n        }\n\n        return $type->isExtensionFor($application);\n    }\n}\n"
  },
  {
    "path": "src/values/PhpExtensionRequirement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass PhpExtensionRequirement implements Requirement {\n    /** @var string */\n    private $extension;\n\n    public function __construct(string $extension) {\n        $this->extension = $extension;\n    }\n\n    public function asString(): string {\n        return $this->extension;\n    }\n}\n"
  },
  {
    "path": "src/values/PhpVersionRequirement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\VersionConstraint;\n\nclass PhpVersionRequirement implements Requirement {\n    /** @var VersionConstraint */\n    private $versionConstraint;\n\n    public function __construct(VersionConstraint $versionConstraint) {\n        $this->versionConstraint = $versionConstraint;\n    }\n\n    public function getVersionConstraint(): VersionConstraint {\n        return $this->versionConstraint;\n    }\n}\n"
  },
  {
    "path": "src/values/Requirement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\ninterface Requirement {\n}\n"
  },
  {
    "path": "src/values/RequirementCollection.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse Countable;\nuse IteratorAggregate;\nuse function count;\n\n/** @template-implements IteratorAggregate<int,Requirement> */\nclass RequirementCollection implements Countable, IteratorAggregate {\n    /** @var Requirement[] */\n    private $requirements = [];\n\n    public function add(Requirement $requirement): void {\n        $this->requirements[] = $requirement;\n    }\n\n    /**\n     * @return Requirement[]\n     */\n    public function getRequirements(): array {\n        return $this->requirements;\n    }\n\n    public function count(): int {\n        return count($this->requirements);\n    }\n\n    public function getIterator(): RequirementCollectionIterator {\n        return new RequirementCollectionIterator($this);\n    }\n}\n"
  },
  {
    "path": "src/values/RequirementCollectionIterator.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse Iterator;\nuse function count;\n\n/** @template-implements Iterator<int,Requirement> */\nclass RequirementCollectionIterator implements Iterator {\n    /** @var Requirement[] */\n    private $requirements;\n\n    /** @var int */\n    private $position = 0;\n\n    public function __construct(RequirementCollection $requirements) {\n        $this->requirements = $requirements->getRequirements();\n    }\n\n    public function rewind(): void {\n        $this->position = 0;\n    }\n\n    public function valid(): bool {\n        return $this->position < count($this->requirements);\n    }\n\n    public function key(): int {\n        return $this->position;\n    }\n\n    public function current(): Requirement {\n        return $this->requirements[$this->position];\n    }\n\n    public function next(): void {\n        $this->position++;\n    }\n}\n"
  },
  {
    "path": "src/values/Type.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\VersionConstraint;\n\nabstract class Type {\n    public static function application(): Application {\n        return new Application;\n    }\n\n    public static function library(): Library {\n        return new Library;\n    }\n\n    public static function extension(ApplicationName $application, VersionConstraint $versionConstraint): Extension {\n        return new Extension($application, $versionConstraint);\n    }\n\n    /** @psalm-assert-if-true Application $this */\n    public function isApplication(): bool {\n        return false;\n    }\n\n    /** @psalm-assert-if-true Library $this */\n    public function isLibrary(): bool {\n        return false;\n    }\n\n    /** @psalm-assert-if-true Extension $this */\n    public function isExtension(): bool {\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/values/Url.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse const FILTER_VALIDATE_URL;\nuse function filter_var;\n\nclass Url {\n    /** @var string */\n    private $url;\n\n    public function __construct(string $url) {\n        $this->ensureUrlIsValid($url);\n\n        $this->url = $url;\n    }\n\n    public function asString(): string {\n        return $this->url;\n    }\n\n    /**\n     * @throws InvalidUrlException\n     */\n    private function ensureUrlIsValid(string $url): void {\n        if (filter_var($url, FILTER_VALIDATE_URL) === false) {\n            throw new InvalidUrlException;\n        }\n    }\n}\n"
  },
  {
    "path": "src/xml/AuthorElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass AuthorElement extends ManifestElement {\n    public function getName(): string {\n        return $this->getAttributeValue('name');\n    }\n\n    public function getEmail(): string {\n        return $this->getAttributeValue('email');\n    }\n\n    public function hasEMail(): bool {\n        return $this->hasAttribute('email');\n    }\n}\n"
  },
  {
    "path": "src/xml/AuthorElementCollection.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass AuthorElementCollection extends ElementCollection {\n    public function current(): AuthorElement {\n        return new AuthorElement(\n            $this->getCurrentElement()\n        );\n    }\n}\n"
  },
  {
    "path": "src/xml/BundlesElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass BundlesElement extends ManifestElement {\n    public function getComponentElements(): ComponentElementCollection {\n        return new ComponentElementCollection(\n            $this->getChildrenByName('component')\n        );\n    }\n}\n"
  },
  {
    "path": "src/xml/ComponentElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass ComponentElement extends ManifestElement {\n    public function getName(): string {\n        return $this->getAttributeValue('name');\n    }\n\n    public function getVersion(): string {\n        return $this->getAttributeValue('version');\n    }\n}\n"
  },
  {
    "path": "src/xml/ComponentElementCollection.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass ComponentElementCollection extends ElementCollection {\n    public function current(): ComponentElement {\n        return new ComponentElement(\n            $this->getCurrentElement()\n        );\n    }\n}\n"
  },
  {
    "path": "src/xml/ContainsElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass ContainsElement extends ManifestElement {\n    public function getName(): string {\n        return $this->getAttributeValue('name');\n    }\n\n    public function getVersion(): string {\n        return $this->getAttributeValue('version');\n    }\n\n    public function getType(): string {\n        return $this->getAttributeValue('type');\n    }\n\n    public function getExtensionElement(): ExtensionElement {\n        return new ExtensionElement(\n            $this->getChildByName('extension')\n        );\n    }\n}\n"
  },
  {
    "path": "src/xml/CopyrightElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass CopyrightElement extends ManifestElement {\n    public function getAuthorElements(): AuthorElementCollection {\n        return new AuthorElementCollection(\n            $this->getChildrenByName('author')\n        );\n    }\n\n    public function getLicenseElement(): LicenseElement {\n        return new LicenseElement(\n            $this->getChildByName('license')\n        );\n    }\n}\n"
  },
  {
    "path": "src/xml/ElementCollection.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMElement;\nuse DOMNodeList;\nuse Iterator;\nuse ReturnTypeWillChange;\nuse function count;\nuse function get_class;\nuse function sprintf;\n\n/** @template-implements Iterator<int,DOMElement> */\nabstract class ElementCollection implements Iterator {\n    /** @var DOMElement[] */\n    private $nodes = [];\n\n    /** @var int */\n    private $position;\n\n    public function __construct(DOMNodeList $nodeList) {\n        $this->position = 0;\n        $this->importNodes($nodeList);\n    }\n\n    #[ReturnTypeWillChange]\n    abstract public function current();\n\n    public function next(): void {\n        $this->position++;\n    }\n\n    public function key(): int {\n        return $this->position;\n    }\n\n    public function valid(): bool {\n        return $this->position < count($this->nodes);\n    }\n\n    public function rewind(): void {\n        $this->position = 0;\n    }\n\n    protected function getCurrentElement(): DOMElement {\n        return $this->nodes[$this->position];\n    }\n\n    private function importNodes(DOMNodeList $nodeList): void {\n        foreach ($nodeList as $node) {\n            if (!$node instanceof DOMElement) {\n                throw new ElementCollectionException(\n                    sprintf('\\DOMElement expected, got \\%s', get_class($node))\n                );\n            }\n\n            $this->nodes[] = $node;\n        }\n    }\n}\n"
  },
  {
    "path": "src/xml/ExtElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass ExtElement extends ManifestElement {\n    public function getName(): string {\n        return $this->getAttributeValue('name');\n    }\n}\n"
  },
  {
    "path": "src/xml/ExtElementCollection.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass ExtElementCollection extends ElementCollection {\n    public function current(): ExtElement {\n        return new ExtElement(\n            $this->getCurrentElement()\n        );\n    }\n}\n"
  },
  {
    "path": "src/xml/ExtensionElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass ExtensionElement extends ManifestElement {\n    public function getFor(): string {\n        return $this->getAttributeValue('for');\n    }\n\n    public function getCompatible(): string {\n        return $this->getAttributeValue('compatible');\n    }\n}\n"
  },
  {
    "path": "src/xml/LicenseElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass LicenseElement extends ManifestElement {\n    public function getType(): string {\n        return $this->getAttributeValue('type');\n    }\n\n    public function getUrl(): string {\n        return $this->getAttributeValue('url');\n    }\n}\n"
  },
  {
    "path": "src/xml/ManifestDocument.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\nuse DOMElement;\nuse Throwable;\nuse function count;\nuse function file_get_contents;\nuse function is_file;\nuse function libxml_clear_errors;\nuse function libxml_get_errors;\nuse function libxml_use_internal_errors;\nuse function sprintf;\n\nclass ManifestDocument {\n    public const XMLNS = 'https://phar.io/xml/manifest/1.0';\n\n    /** @var DOMDocument */\n    private $dom;\n\n    public static function fromFile(string $filename): ManifestDocument {\n        if (!is_file($filename)) {\n            throw new ManifestDocumentException(\n                sprintf('File \"%s\" not found', $filename)\n            );\n        }\n\n        return self::fromString(\n            file_get_contents($filename)\n        );\n    }\n\n    public static function fromString(string $xmlString): ManifestDocument {\n        $prev = libxml_use_internal_errors(true);\n        libxml_clear_errors();\n\n        try {\n            $dom = new DOMDocument();\n            $dom->loadXML($xmlString);\n            $errors = libxml_get_errors();\n            libxml_use_internal_errors($prev);\n        } catch (Throwable $t) {\n            throw new ManifestDocumentException($t->getMessage(), 0, $t);\n        }\n\n        if (count($errors) !== 0) {\n            throw new ManifestDocumentLoadingException($errors);\n        }\n\n        return new self($dom);\n    }\n\n    private function __construct(DOMDocument $dom) {\n        $this->ensureCorrectDocumentType($dom);\n\n        $this->dom = $dom;\n    }\n\n    public function getContainsElement(): ContainsElement {\n        return new ContainsElement(\n            $this->fetchElementByName('contains')\n        );\n    }\n\n    public function getCopyrightElement(): CopyrightElement {\n        return new CopyrightElement(\n            $this->fetchElementByName('copyright')\n        );\n    }\n\n    public function getRequiresElement(): RequiresElement {\n        return new RequiresElement(\n            $this->fetchElementByName('requires')\n        );\n    }\n\n    public function hasBundlesElement(): bool {\n        return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1;\n    }\n\n    public function getBundlesElement(): BundlesElement {\n        return new BundlesElement(\n            $this->fetchElementByName('bundles')\n        );\n    }\n\n    private function ensureCorrectDocumentType(DOMDocument $dom): void {\n        $root = $dom->documentElement;\n\n        if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) {\n            throw new ManifestDocumentException('Not a phar.io manifest document');\n        }\n    }\n\n    private function fetchElementByName(string $elementName): DOMElement {\n        $element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);\n\n        if (!$element instanceof DOMElement) {\n            throw new ManifestDocumentException(\n                sprintf('Element %s missing', $elementName)\n            );\n        }\n\n        return $element;\n    }\n}\n"
  },
  {
    "path": "src/xml/ManifestElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMElement;\nuse DOMNodeList;\nuse function sprintf;\n\nclass ManifestElement {\n    public const XMLNS = 'https://phar.io/xml/manifest/1.0';\n\n    /** @var DOMElement */\n    private $element;\n\n    public function __construct(DOMElement $element) {\n        $this->element = $element;\n    }\n\n    protected function getAttributeValue(string $name): string {\n        if (!$this->element->hasAttribute($name)) {\n            throw new ManifestElementException(\n                sprintf(\n                    'Attribute %s not set on element %s',\n                    $name,\n                    $this->element->localName\n                )\n            );\n        }\n\n        return $this->element->getAttribute($name);\n    }\n\n    protected function hasAttribute(string $name): bool {\n        return $this->element->hasAttribute($name);\n    }\n\n    protected function getChildByName(string $elementName): DOMElement {\n        $element = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);\n\n        if (!$element instanceof DOMElement) {\n            throw new ManifestElementException(\n                sprintf('Element %s missing', $elementName)\n            );\n        }\n\n        return $element;\n    }\n\n    protected function getChildrenByName(string $elementName): DOMNodeList {\n        $elementList = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName);\n\n        if ($elementList->length === 0) {\n            throw new ManifestElementException(\n                sprintf('Element(s) %s missing', $elementName)\n            );\n        }\n\n        return $elementList;\n    }\n\n    protected function hasChild(string $elementName): bool {\n        return $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->length !== 0;\n    }\n}\n"
  },
  {
    "path": "src/xml/PhpElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass PhpElement extends ManifestElement {\n    public function getVersion(): string {\n        return $this->getAttributeValue('version');\n    }\n\n    public function hasExtElements(): bool {\n        return $this->hasChild('ext');\n    }\n\n    public function getExtElements(): ExtElementCollection {\n        return new ExtElementCollection(\n            $this->getChildrenByName('ext')\n        );\n    }\n}\n"
  },
  {
    "path": "src/xml/RequiresElement.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nclass RequiresElement extends ManifestElement {\n    public function getPHPElement(): PhpElement {\n        return new PhpElement(\n            $this->getChildByName('php')\n        );\n    }\n}\n"
  },
  {
    "path": "tests/ManifestDocumentMapperTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\n/**\n * @covers \\PharIo\\Manifest\\ManifestDocumentMapper\n *\n * @uses \\PharIo\\Manifest\\ApplicationName\n * @uses \\PharIo\\Manifest\\Author\n * @uses \\PharIo\\Manifest\\AuthorCollection\n * @uses \\PharIo\\Manifest\\AuthorCollectionIterator\n * @uses \\PharIo\\Manifest\\AuthorElement\n * @uses \\PharIo\\Manifest\\AuthorElementCollection\n * @uses \\PharIo\\Manifest\\BundledComponent\n * @uses \\PharIo\\Manifest\\BundledComponentCollection\n * @uses \\PharIo\\Manifest\\BundledComponentCollectionIterator\n * @uses \\PharIo\\Manifest\\BundlesElement\n * @uses \\PharIo\\Manifest\\ComponentElement\n * @uses \\PharIo\\Manifest\\ComponentElementCollection\n * @uses \\PharIo\\Manifest\\ContainsElement\n * @uses \\PharIo\\Manifest\\CopyrightElement\n * @uses \\PharIo\\Manifest\\CopyrightInformation\n * @uses \\PharIo\\Manifest\\ElementCollection\n * @uses \\PharIo\\Manifest\\Email\n * @uses \\PharIo\\Manifest\\ExtElement\n * @uses \\PharIo\\Manifest\\ExtElementCollection\n * @uses \\PharIo\\Manifest\\License\n * @uses \\PharIo\\Manifest\\LicenseElement\n * @uses \\PharIo\\Manifest\\Manifest\n * @uses \\PharIo\\Manifest\\ManifestDocument\n * @uses \\PharIo\\Manifest\\ManifestDocumentMapper\n * @uses \\PharIo\\Manifest\\ManifestElement\n * @uses \\PharIo\\Manifest\\ManifestLoader\n * @uses \\PharIo\\Manifest\\PhpElement\n * @uses \\PharIo\\Manifest\\PhpExtensionRequirement\n * @uses \\PharIo\\Manifest\\PhpVersionRequirement\n * @uses \\PharIo\\Manifest\\RequirementCollection\n * @uses \\PharIo\\Manifest\\RequirementCollectionIterator\n * @uses \\PharIo\\Manifest\\RequiresElement\n * @uses \\PharIo\\Manifest\\Type\n * @uses \\PharIo\\Manifest\\Url\n * @uses \\PharIo\\Version\\Version\n * @uses \\PharIo\\Version\\VersionConstraint\n */\nclass ManifestDocumentMapperTest extends \\PHPUnit\\Framework\\TestCase {\n    /**\n     * @dataProvider dataProvider\n     *\n     * @uses         \\PharIo\\Manifest\\Application\n     * @uses         \\PharIo\\Manifest\\ApplicationName\n     * @uses         \\PharIo\\Manifest\\Library\n     * @uses         \\PharIo\\Manifest\\Extension\n     * @uses         \\PharIo\\Manifest\\ExtensionElement\n     */\n    public function testCanSerializeToString($expected): void {\n        $manifestDocument = ManifestDocument::fromFile($expected);\n        $mapper           = new ManifestDocumentMapper();\n\n        $this->assertInstanceOf(\n            Manifest::class,\n            $mapper->map($manifestDocument)\n        );\n    }\n\n    public function dataProvider() {\n        return [\n            'application'   => [__DIR__ . '/_fixture/phpunit-5.6.5.xml'],\n            'library'       => [__DIR__ . '/_fixture/library.xml'],\n            'extension'     => [__DIR__ . '/_fixture/extension.xml'],\n            'noemailauthor' => [__DIR__ . '/_fixture/noemailauthor.xml']\n        ];\n    }\n\n    public function testThrowsExceptionOnUnsupportedType(): void {\n        $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/custom.xml');\n        $mapper           = new ManifestDocumentMapper();\n\n        $this->expectException(ManifestDocumentMapperException::class);\n        $mapper->map($manifestDocument);\n    }\n\n    public function testInvalidVersionInformationThrowsException(): void {\n        $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/invalidversion.xml');\n        $mapper           = new ManifestDocumentMapper();\n\n        $this->expectException(ManifestDocumentMapperException::class);\n        $mapper->map($manifestDocument);\n    }\n\n    public function testInvalidVersionConstraintThrowsException(): void {\n        $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/invalidversionconstraint.xml');\n        $mapper           = new ManifestDocumentMapper();\n\n        $this->expectException(ManifestDocumentMapperException::class);\n        $mapper->map($manifestDocument);\n    }\n\n    /**\n     * @uses \\PharIo\\Manifest\\ExtensionElement\n     */\n    public function testInvalidCompatibleConstraintThrowsException(): void {\n        $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/extension-invalidcompatible.xml');\n        $mapper           = new ManifestDocumentMapper();\n\n        $this->expectException(ManifestDocumentMapperException::class);\n        $mapper->map($manifestDocument);\n    }\n}\n"
  },
  {
    "path": "tests/ManifestLoaderTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse function file_get_contents;\n\n/**\n * @covers \\PharIo\\Manifest\\ManifestLoader\n *\n * @uses \\PharIo\\Manifest\\Author\n * @uses \\PharIo\\Manifest\\AuthorCollection\n * @uses \\PharIo\\Manifest\\AuthorCollectionIterator\n * @uses \\PharIo\\Manifest\\AuthorElement\n * @uses \\PharIo\\Manifest\\AuthorElementCollection\n * @uses \\PharIo\\Manifest\\ApplicationName\n * @uses \\PharIo\\Manifest\\BundledComponent\n * @uses \\PharIo\\Manifest\\BundledComponentCollection\n * @uses \\PharIo\\Manifest\\BundledComponentCollectionIterator\n * @uses \\PharIo\\Manifest\\BundlesElement\n * @uses \\PharIo\\Manifest\\ComponentElement\n * @uses \\PharIo\\Manifest\\ComponentElementCollection\n * @uses \\PharIo\\Manifest\\ContainsElement\n * @uses \\PharIo\\Manifest\\CopyrightElement\n * @uses \\PharIo\\Manifest\\CopyrightInformation\n * @uses \\PharIo\\Manifest\\ElementCollection\n * @uses \\PharIo\\Manifest\\Email\n * @uses \\PharIo\\Manifest\\ExtElement\n * @uses \\PharIo\\Manifest\\ExtElementCollection\n * @uses \\PharIo\\Manifest\\License\n * @uses \\PharIo\\Manifest\\LicenseElement\n * @uses \\PharIo\\Manifest\\Manifest\n * @uses \\PharIo\\Manifest\\ManifestDocument\n * @uses \\PharIo\\Manifest\\ManifestDocumentMapper\n * @uses \\PharIo\\Manifest\\ManifestElement\n * @uses \\PharIo\\Manifest\\ManifestLoader\n * @uses \\PharIo\\Manifest\\PhpElement\n * @uses \\PharIo\\Manifest\\PhpExtensionRequirement\n * @uses \\PharIo\\Manifest\\PhpVersionRequirement\n * @uses \\PharIo\\Manifest\\RequirementCollection\n * @uses \\PharIo\\Manifest\\RequirementCollectionIterator\n * @uses \\PharIo\\Manifest\\RequiresElement\n * @uses \\PharIo\\Manifest\\Type\n * @uses \\PharIo\\Manifest\\Url\n * @uses \\PharIo\\Version\\Version\n * @uses \\PharIo\\Version\\VersionConstraint\n */\nclass ManifestLoaderTest extends \\PHPUnit\\Framework\\TestCase {\n    public function testCanBeLoadedFromFile(): void {\n        $this->assertInstanceOf(\n            Manifest::class,\n            ManifestLoader::fromFile(__DIR__ . '/_fixture/library.xml')\n        );\n    }\n\n    public function testCanBeLoadedFromString(): void {\n        $this->assertInstanceOf(\n            Manifest::class,\n            ManifestLoader::fromString(\n                file_get_contents(__DIR__ . '/_fixture/library.xml')\n            )\n        );\n    }\n\n    public function testCanBeLoadedFromPhar(): void {\n        $this->assertInstanceOf(\n            Manifest::class,\n            ManifestLoader::fromPhar(__DIR__ . '/_fixture/test.phar')\n        );\n    }\n\n    public function testLoadingNonExistingFileThrowsException(): void {\n        $this->expectException(ManifestLoaderException::class);\n        ManifestLoader::fromFile('/not/existing');\n    }\n\n    /**\n     * @uses \\PharIo\\Manifest\\ManifestDocumentLoadingException\n     */\n    public function testLoadingInvalidXmlThrowsException(): void {\n        $this->expectException(ManifestLoaderException::class);\n        ManifestLoader::fromString('<?xml version=\"1.0\" ?><broken>');\n    }\n}\n"
  },
  {
    "path": "tests/ManifestSerializerTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\Version;\nuse function file_get_contents;\nuse function sys_get_temp_dir;\nuse function uniqid;\nuse function unlink;\n\n/**\n * @covers \\PharIo\\Manifest\\ManifestSerializer\n *\n * @uses \\PharIo\\Manifest\\ApplicationName\n * @uses \\PharIo\\Manifest\\Author\n * @uses \\PharIo\\Manifest\\AuthorCollection\n * @uses \\PharIo\\Manifest\\AuthorCollectionIterator\n * @uses \\PharIo\\Manifest\\AuthorElement\n * @uses \\PharIo\\Manifest\\AuthorElementCollection\n * @uses \\PharIo\\Manifest\\BundledComponent\n * @uses \\PharIo\\Manifest\\BundledComponentCollection\n * @uses \\PharIo\\Manifest\\BundledComponentCollectionIterator\n * @uses \\PharIo\\Manifest\\BundlesElement\n * @uses \\PharIo\\Manifest\\ComponentElement\n * @uses \\PharIo\\Manifest\\ComponentElementCollection\n * @uses \\PharIo\\Manifest\\ContainsElement\n * @uses \\PharIo\\Manifest\\CopyrightElement\n * @uses \\PharIo\\Manifest\\CopyrightInformation\n * @uses \\PharIo\\Manifest\\ElementCollection\n * @uses \\PharIo\\Manifest\\Email\n * @uses \\PharIo\\Manifest\\ExtElement\n * @uses \\PharIo\\Manifest\\ExtElementCollection\n * @uses \\PharIo\\Manifest\\License\n * @uses \\PharIo\\Manifest\\LicenseElement\n * @uses \\PharIo\\Manifest\\Manifest\n * @uses \\PharIo\\Manifest\\ManifestDocument\n * @uses \\PharIo\\Manifest\\ManifestDocumentMapper\n * @uses \\PharIo\\Manifest\\ManifestElement\n * @uses \\PharIo\\Manifest\\ManifestLoader\n * @uses \\PharIo\\Manifest\\PhpElement\n * @uses \\PharIo\\Manifest\\PhpExtensionRequirement\n * @uses \\PharIo\\Manifest\\PhpVersionRequirement\n * @uses \\PharIo\\Manifest\\RequirementCollection\n * @uses \\PharIo\\Manifest\\RequirementCollectionIterator\n * @uses \\PharIo\\Manifest\\RequiresElement\n * @uses \\PharIo\\Manifest\\Type\n * @uses \\PharIo\\Manifest\\Url\n * @uses \\PharIo\\Version\\Version\n * @uses \\PharIo\\Version\\VersionConstraint\n */\nclass ManifestSerializerTest extends \\PHPUnit\\Framework\\TestCase {\n    /**\n     * @dataProvider dataProvider\n     *\n     * @uses \\PharIo\\Manifest\\Application\n     * @uses \\PharIo\\Manifest\\Library\n     * @uses \\PharIo\\Manifest\\Extension\n     * @uses \\PharIo\\Manifest\\ExtensionElement\n     */\n    public function testCanSerializeToString($expected): void {\n        $manifest = ManifestLoader::fromString($expected);\n\n        $serializer = new ManifestSerializer();\n\n        $this->assertXmlStringEqualsXmlString(\n            $expected,\n            $serializer->serializeToString($manifest)\n        );\n    }\n\n    public function dataProvider() {\n        return [\n            'application' => [file_get_contents(__DIR__ . '/_fixture/phpunit-5.6.5.xml')],\n            'library'     => [file_get_contents(__DIR__ . '/_fixture/library.xml')],\n            'extension'   => [file_get_contents(__DIR__ . '/_fixture/extension.xml')]\n        ];\n    }\n\n    /**\n     * @uses \\PharIo\\Manifest\\Library\n     * @uses \\PharIo\\Manifest\\ApplicationName\n     */\n    public function testCanSerializeToFile(): void {\n        $src        = __DIR__ . '/_fixture/library.xml';\n        $dest       = sys_get_temp_dir() . '/' . uniqid('serializer', true);\n        $manifest   = ManifestLoader::fromFile($src);\n        $serializer = new ManifestSerializer();\n        $serializer->serializeToFile($manifest, $dest);\n        $this->assertXmlFileEqualsXmlFile($src, $dest);\n        unlink($dest);\n    }\n\n    /**\n     * @uses \\PharIo\\Manifest\\ApplicationName\n     */\n    public function testCanHandleUnknownType(): void {\n        $type     = $this->getMockForAbstractClass(Type::class);\n        $manifest = new Manifest(\n            new ApplicationName('testvendor/testname'),\n            new Version('1.0.0'),\n            $type,\n            new CopyrightInformation(\n                new AuthorCollection(),\n                new License('bsd-3', new Url('https://some/uri'))\n            ),\n            new RequirementCollection(),\n            new BundledComponentCollection()\n        );\n\n        $serializer = new ManifestSerializer();\n        $this->assertXmlStringEqualsXmlFile(\n            __DIR__ . '/_fixture/custom.xml',\n            $serializer->serializeToString($manifest)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/_fixture/custom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"testvendor/testname\" version=\"1.0.0\" type=\"custom\"/>\n    <copyright>\n        <license type=\"bsd-3\" url=\"https://some/uri\"/>\n    </copyright>\n    <requires>\n        <php version=\"*\"/>\n    </requires>\n</phar>\n"
  },
  {
    "path": "tests/_fixture/extension-invalidcompatible.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"phpunit/phpunit-example-extension\" version=\"1.0.0\" type=\"extension\">\n        <extension for=\"phpunit/phpunit\" compatible=\"invalid\"/>\n    </contains>\n    <copyright>\n        <author name=\"Sebastian Bergmann\" email=\"sebastian@phpunit.de\"/>\n        <license type=\"BSD-3-Clause\" url=\"https://github.com/sebastianbergmann/phpunit-example-extension/blob/master/LICENSE\"/>\n    </copyright>\n    <requires>\n        <php version=\"^7.0\"/>\n    </requires>\n</phar>\n"
  },
  {
    "path": "tests/_fixture/extension.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"phpunit/phpunit-example-extension\" version=\"1.0.0\" type=\"extension\">\n        <extension for=\"phpunit/phpunit\" compatible=\"^5.7\"/>\n    </contains>\n    <copyright>\n        <author name=\"Sebastian Bergmann\" email=\"sebastian@phpunit.de\"/>\n        <license type=\"BSD-3-Clause\" url=\"https://github.com/sebastianbergmann/phpunit-example-extension/blob/master/LICENSE\"/>\n    </copyright>\n    <requires>\n        <php version=\"^7.0\"/>\n    </requires>\n</phar>\n"
  },
  {
    "path": "tests/_fixture/invalidversion.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"some/library\" version=\"abc\" type=\"library\" />\n    <copyright>\n        <author name=\"Reiner Zufall\" email=\"reiner@zufall.de\"/>\n        <license type=\"BSD-3-Clause\" url=\"https://domain.tld/LICENSE\"/>\n    </copyright>\n    <requires>\n        <php version=\"7.0\"/>\n    </requires>\n</phar>\n"
  },
  {
    "path": "tests/_fixture/invalidversionconstraint.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"some/library\" version=\"1.0.0\" type=\"library\" />\n    <copyright>\n        <author name=\"Reiner Zufall\" email=\"reiner@zufall.de\"/>\n        <license type=\"BSD-3-Clause\" url=\"https://domain.tld/LICENSE\"/>\n    </copyright>\n    <requires>\n        <php version=\"invalid\"/>\n    </requires>\n</phar>\n"
  },
  {
    "path": "tests/_fixture/library.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"some/library\" version=\"1.0.0\" type=\"library\" />\n    <copyright>\n        <author name=\"Reiner Zufall\" email=\"reiner@zufall.de\"/>\n        <license type=\"BSD-3-Clause\" url=\"https://domain.tld/LICENSE\"/>\n    </copyright>\n    <requires>\n        <php version=\"7.0\"/>\n    </requires>\n</phar>\n"
  },
  {
    "path": "tests/_fixture/manifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"some/library\" version=\"1.0.0\" type=\"library\" />\n    <copyright>\n        <author name=\"Reiner Zufall\" email=\"reiner@zufall.de\"/>\n        <license type=\"BSD-3-Clause\" url=\"https://domain.tld/LICENSE\"/>\n    </copyright>\n    <requires>\n        <php version=\"7.0\"/>\n    </requires>\n</phar>\n"
  },
  {
    "path": "tests/_fixture/noemailauthor.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"some/library\" version=\"1.0.0\" type=\"library\" />\n    <copyright>\n        <author name=\"Reiner Zufall\" />\n        <license type=\"BSD-3-Clause\" url=\"https://domain.tld/LICENSE\"/>\n    </copyright>\n    <requires>\n        <php version=\"7.0\"/>\n    </requires>\n</phar>\n"
  },
  {
    "path": "tests/_fixture/phpunit-5.6.5.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phar xmlns=\"https://phar.io/xml/manifest/1.0\">\n    <contains name=\"phpunit/phpunit\" version=\"5.6.5\" type=\"application\"/>\n    <copyright>\n        <author name=\"Sebastian Bergmann\" email=\"sebastian@phpunit.de\"/>\n        <license type=\"BSD-3-Clause\" url=\"https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE\"/>\n    </copyright>\n    <requires>\n        <!-- constraint on next line should be ^5.6 || ^7.0 -->\n        <php version=\"^7.0\">\n            <ext name=\"dom\"/>\n            <ext name=\"json\"/>\n            <ext name=\"mbstring\"/>\n            <ext name=\"xml\"/>\n            <ext name=\"libxml\"/>\n        </php>\n    </requires>\n    <bundles>\n        <component name=\"doctrine/instantiator\" version=\"1.0.5\"/>\n        <component name=\"myclabs/deep-copy\" version=\"1.5.5\"/>\n        <component name=\"phpdocumentor/reflection-common\" version=\"1.0.0\"/>\n        <component name=\"phpdocumentor/reflection-docblock\" version=\"3.1.1\"/>\n        <component name=\"phpdocumentor/type-resolver\" version=\"0.2.0\"/>\n        <component name=\"phpspec/prophecy\" version=\"1.6.2\"/>\n        <component name=\"phpunit/dbunit\" version=\"2.0.2\"/>\n        <component name=\"phpunit/php-code-coverage\" version=\"4.0.2\"/>\n        <component name=\"phpunit/php-file-iterator\" version=\"1.4.1\"/>\n        <component name=\"phpunit/php-invoker\" version=\"1.1.4\"/>\n        <component name=\"phpunit/php-text-template\" version=\"1.2.1\"/>\n        <component name=\"phpunit/php-timer\" version=\"1.0.8\"/>\n        <component name=\"phpunit/php-token-stream\" version=\"1.4.9\"/>\n        <component name=\"phpunit/phpunit-mock-objects\" version=\"3.4.1\"/>\n        <component name=\"sebastian/code-unit-reverse-lookup\" version=\"1.0.0\"/>\n        <component name=\"sebastian/comparator\" version=\"1.2.2\"/>\n        <component name=\"sebastian/diff\" version=\"1.4.1\"/>\n        <component name=\"sebastian/environment\" version=\"1.3.8\"/>\n        <component name=\"sebastian/exporter\" version=\"2.0.0\"/>\n        <component name=\"sebastian/global-state\" version=\"1.1.1\"/>\n        <component name=\"sebastian/object-enumerator\" version=\"2.0.0\"/>\n        <component name=\"sebastian/recursion-context\" version=\"2.0.0\"/>\n        <component name=\"sebastian/resource-operations\" version=\"1.0.0\"/>\n        <component name=\"sebastian/version\" version=\"2.0.0\"/>\n        <component name=\"symfony/yaml\" version=\"3.1.7\"/>\n        <component name=\"webmozart/assert\" version=\"1.1.0\"/>\n    </bundles>\n</phar>\n"
  },
  {
    "path": "tests/exceptions/ManifestDocumentLoadingExceptionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\nuse LibXMLError;\nuse function libxml_get_errors;\nuse function libxml_use_internal_errors;\n\nclass ManifestDocumentLoadingExceptionTest extends \\PHPUnit\\Framework\\TestCase {\n    public function testXMLErrorsCanBeRetrieved(): void {\n        $dom  = new DOMDocument();\n        $prev = libxml_use_internal_errors(true);\n        $dom->loadXML('<?xml version=\"1.0\" ?><broken>');\n        $exception = new ManifestDocumentLoadingException(libxml_get_errors());\n        libxml_use_internal_errors($prev);\n\n        $this->assertContainsOnlyInstancesOf(LibXMLError::class, $exception->getLibxmlErrors());\n    }\n}\n"
  },
  {
    "path": "tests/values/ApplicationNameTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass ApplicationNameTest extends TestCase {\n    public function testCanBeCreatedWithValidName(): void {\n        $this->assertInstanceOf(\n            ApplicationName::class,\n            new ApplicationName('foo/bar')\n        );\n    }\n\n    public function testUsingInvalidFormatForNameThrowsException(): void {\n        $this->expectException(InvalidApplicationNameException::class);\n        $this->expectExceptionCode(InvalidApplicationNameException::InvalidFormat);\n        new ApplicationName('foo');\n    }\n\n    public function testReturnsTrueForEqualNamesWhenCompared(): void {\n        $app = new ApplicationName('foo/bar');\n        $this->assertTrue(\n            $app->isEqual($app)\n        );\n    }\n\n    public function testReturnsFalseForNonEqualNamesWhenCompared(): void {\n        $app1 = new ApplicationName('foo/bar');\n        $app2 = new ApplicationName('foo/foo');\n        $this->assertFalse(\n            $app1->isEqual($app2)\n        );\n    }\n\n    public function testCanBeConvertedToString(): void {\n        $this->assertEquals(\n            'foo/bar',\n            (new ApplicationName('foo/bar'))->asString()\n        );\n    }\n}\n"
  },
  {
    "path": "tests/values/ApplicationTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\Application\n * @covers PharIo\\Manifest\\Type\n */\nclass ApplicationTest extends TestCase {\n    /** @var Application */\n    private $type;\n\n    protected function setUp(): void {\n        $this->type = Type::application();\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(Application::class, $this->type);\n    }\n\n    public function testIsApplication(): void {\n        $this->assertTrue($this->type->isApplication());\n    }\n\n    public function testIsNotLibrary(): void {\n        $this->assertFalse($this->type->isLibrary());\n    }\n\n    public function testIsNotExtension(): void {\n        $this->assertFalse($this->type->isExtension());\n    }\n}\n"
  },
  {
    "path": "tests/values/AuthorCollectionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\PharIo\\Manifest\\AuthorCollection\n * @covers \\PharIo\\Manifest\\AuthorCollectionIterator\n *\n * @uses \\PharIo\\Manifest\\Author\n * @uses \\PharIo\\Manifest\\Email\n */\nclass AuthorCollectionTest extends TestCase {\n    /** @var AuthorCollection */\n    private $collection;\n\n    /** @var Author */\n    private $item;\n\n    protected function setUp(): void {\n        $this->collection = new AuthorCollection;\n        $this->item       = new Author('Joe Developer', new Email('user@example.com'));\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(AuthorCollection::class, $this->collection);\n    }\n\n    public function testCanBeCounted(): void {\n        $this->collection->add($this->item);\n\n        $this->assertCount(1, $this->collection);\n    }\n\n    public function testCanBeIterated(): void {\n        $this->collection->add(\n            new Author('Dummy First', new Email('dummy@example.com'))\n        );\n        $this->collection->add($this->item);\n        $this->assertContains($this->item, $this->collection);\n    }\n\n    public function testKeyPositionCanBeRetrieved(): void {\n        $this->collection->add($this->item);\n\n        foreach ($this->collection as $key => $item) {\n            $this->assertEquals(0, $key);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/values/AuthorTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\Author\n *\n * @uses PharIo\\Manifest\\Email\n */\nclass AuthorTest extends TestCase {\n    /** @var Author */\n    private $author;\n\n    protected function setUp(): void {\n        $this->author = new Author('Joe Developer', new Email('user@example.com'));\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(Author::class, $this->author);\n    }\n\n    public function testNameCanBeRetrieved(): void {\n        $this->assertEquals('Joe Developer', $this->author->getName());\n    }\n\n    public function testEmailCanBeRetrieved(): void {\n        $email = $this->author->getEmail();\n        $this->assertEquals('user@example.com', $email->asString());\n    }\n\n    public function testCanBeUsedAsString(): void {\n        $this->assertEquals('Joe Developer <user@example.com>', $this->author->asString());\n    }\n\n    public function testCanBeCreatedWithoutEmail(): void {\n        $this->assertInstanceOf(Author::class, new Author('Joe Developer'));\n    }\n\n    public function testHasEmailReturnsTrueWhenEMailIsSet(): void {\n        $this->assertTrue($this->author->hasEmail());\n    }\n\n    public function testHasEmailReturnsFalseOnMissingEMail(): void {\n        $this->assertFalse((new Author('Joe Developer'))->hasEmail());\n    }\n\n    public function testThrowsExceptionWhenMissingEmailAddressIsQueried(): void {\n        $author = new Author('Joe Developer');\n        $this->expectException(NoEmailAddressException::class);\n        $author->getEmail();\n    }\n}\n"
  },
  {
    "path": "tests/values/BundledComponentCollectionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\Version;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\PharIo\\Manifest\\BundledComponentCollection\n * @covers \\PharIo\\Manifest\\BundledComponentCollectionIterator\n *\n * @uses \\PharIo\\Manifest\\BundledComponent\n * @uses \\PharIo\\Version\\Version\n */\nclass BundledComponentCollectionTest extends TestCase {\n    /** @var BundledComponentCollection */\n    private $collection;\n\n    /** @var BundledComponent */\n    private $item;\n\n    protected function setUp(): void {\n        $this->collection = new BundledComponentCollection;\n        $this->item       = new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2'));\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(BundledComponentCollection::class, $this->collection);\n    }\n\n    public function testCanBeCounted(): void {\n        $this->collection->add($this->item);\n\n        $this->assertCount(1, $this->collection);\n    }\n\n    public function testCanBeIterated(): void {\n        $this->collection->add($this->createMock(BundledComponent::class));\n        $this->collection->add($this->item);\n\n        $this->assertContains($this->item, $this->collection);\n    }\n\n    public function testKeyPositionCanBeRetrieved(): void {\n        $this->collection->add($this->item);\n\n        foreach ($this->collection as $key => $item) {\n            $this->assertEquals(0, $key);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/values/BundledComponentTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\Version;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\BundledComponent\n *\n * @uses \\PharIo\\Version\\Version\n */\nclass BundledComponentTest extends TestCase {\n    /** @var BundledComponent */\n    private $bundledComponent;\n\n    protected function setUp(): void {\n        $this->bundledComponent = new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2'));\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(BundledComponent::class, $this->bundledComponent);\n    }\n\n    public function testNameCanBeRetrieved(): void {\n        $this->assertEquals('phpunit/php-code-coverage', $this->bundledComponent->getName());\n    }\n\n    public function testVersionCanBeRetrieved(): void {\n        $this->assertEquals('4.0.2', $this->bundledComponent->getVersion()->getVersionString());\n    }\n}\n"
  },
  {
    "path": "tests/values/CopyrightInformationTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\CopyrightInformation\n *\n * @uses PharIo\\Manifest\\AuthorCollection\n * @uses PharIo\\Manifest\\AuthorCollectionIterator\n * @uses PharIo\\Manifest\\Author\n * @uses PharIo\\Manifest\\Email\n * @uses PharIo\\Manifest\\License\n * @uses PharIo\\Manifest\\Url\n */\nclass CopyrightInformationTest extends TestCase {\n    /** @var CopyrightInformation */\n    private $copyrightInformation;\n\n    /** @var Author */\n    private $author;\n\n    /** @var License */\n    private $license;\n\n    protected function setUp(): void {\n        $this->author  = new Author('Joe Developer', new Email('user@example.com'));\n        $this->license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE'));\n\n        $authors = new AuthorCollection;\n        $authors->add($this->author);\n\n        $this->copyrightInformation = new CopyrightInformation($authors, $this->license);\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(CopyrightInformation::class, $this->copyrightInformation);\n    }\n\n    public function testAuthorsCanBeRetrieved(): void {\n        $this->assertContains($this->author, $this->copyrightInformation->getAuthors());\n    }\n\n    public function testLicenseCanBeRetrieved(): void {\n        $this->assertEquals($this->license, $this->copyrightInformation->getLicense());\n    }\n}\n"
  },
  {
    "path": "tests/values/EmailTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\PharIo\\Manifest\\Email\n */\nclass EmailTest extends TestCase {\n    public function testCanBeCreatedForValidEmail(): void {\n        $this->assertInstanceOf(Email::class, new Email('user@example.com'));\n    }\n\n    public function testCanBeRequestedAsString(): void {\n        $this->assertEquals('user@example.com', (new Email('user@example.com'))->asString());\n    }\n\n    /**\n     * @covers \\PharIo\\Manifest\\InvalidEmailException\n     */\n    public function testCannotBeCreatedForInvalidEmail(): void {\n        $this->expectException(InvalidEmailException::class);\n\n        new Email('invalid');\n    }\n}\n"
  },
  {
    "path": "tests/values/ExtensionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\AnyVersionConstraint;\nuse PharIo\\Version\\Version;\nuse PharIo\\Version\\VersionConstraint;\nuse PharIo\\Version\\VersionConstraintParser;\nuse PHPUnit\\Framework\\TestCase;\nuse PHPUnit_Framework_MockObject_MockObject;\n\n/**\n * @covers \\PharIo\\Manifest\\Extension\n * @covers \\PharIo\\Manifest\\Type\n *\n * @uses \\PharIo\\Version\\VersionConstraint\n * @uses \\PharIo\\Manifest\\ApplicationName\n */\nclass ExtensionTest extends TestCase {\n    /** @var Extension */\n    private $type;\n\n    /** @var ApplicationName|PHPUnit_Framework_MockObject_MockObject */\n    private $name;\n\n    protected function setUp(): void {\n        $this->name = $this->createMock(ApplicationName::class);\n        $this->type = Type::extension($this->name, new AnyVersionConstraint);\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(Extension::class, $this->type);\n    }\n\n    public function testIsNotApplication(): void {\n        $this->assertFalse($this->type->isApplication());\n    }\n\n    public function testIsNotLibrary(): void {\n        $this->assertFalse($this->type->isLibrary());\n    }\n\n    public function testIsExtension(): void {\n        $this->assertTrue($this->type->isExtension());\n    }\n\n    public function testApplicationCanBeRetrieved(): void {\n        $this->assertInstanceOf(ApplicationName::class, $this->type->getApplicationName());\n    }\n\n    public function testVersionConstraintCanBeRetrieved(): void {\n        $this->assertInstanceOf(\n            VersionConstraint::class,\n            $this->type->getVersionConstraint()\n        );\n    }\n\n    public function testApplicationCanBeQueried(): void {\n        $this->name->method('isEqual')->willReturn(true);\n        $this->assertTrue(\n            $this->type->isExtensionFor($this->createMock(ApplicationName::class))\n        );\n    }\n\n    public function testCompatibleWithReturnsTrueForMatchingVersionConstraintAndApplication(): void {\n        $app       = new ApplicationName('foo/bar');\n        $extension = Type::extension($app, (new VersionConstraintParser)->parse('^1.0'));\n        $version   = new Version('1.0.0');\n\n        $this->assertTrue(\n            $extension->isCompatibleWith($app, $version)\n        );\n    }\n\n    public function testCompatibleWithReturnsFalseForNotMatchingVersionConstraint(): void {\n        $app       = new ApplicationName('foo/bar');\n        $extension = Type::extension($app, (new VersionConstraintParser)->parse('^1.0'));\n        $version   = new Version('2.0.0');\n\n        $this->assertFalse(\n            $extension->isCompatibleWith($app, $version)\n        );\n    }\n\n    public function testCompatibleWithReturnsFalseForNotMatchingApplication(): void {\n        $app1      = new ApplicationName('foo/bar');\n        $app2      = new ApplicationName('foo/foo');\n        $extension = Type::extension($app1, (new VersionConstraintParser)->parse('^1.0'));\n        $version   = new Version('1.0.0');\n\n        $this->assertFalse(\n            $extension->isCompatibleWith($app2, $version)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/values/LibraryTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\Library\n * @covers PharIo\\Manifest\\Type\n */\nclass LibraryTest extends TestCase {\n    /** @var Library */\n    private $type;\n\n    protected function setUp(): void {\n        $this->type = Type::library();\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(Library::class, $this->type);\n    }\n\n    public function testIsNotApplication(): void {\n        $this->assertFalse($this->type->isApplication());\n    }\n\n    public function testIsLibrary(): void {\n        $this->assertTrue($this->type->isLibrary());\n    }\n\n    public function testIsNotExtension(): void {\n        $this->assertFalse($this->type->isExtension());\n    }\n}\n"
  },
  {
    "path": "tests/values/LicenseTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\License\n *\n * @uses PharIo\\Manifest\\Url\n */\nclass LicenseTest extends TestCase {\n    /** @var License */\n    private $license;\n\n    protected function setUp(): void {\n        $this->license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE'));\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(License::class, $this->license);\n    }\n\n    public function testNameCanBeRetrieved(): void {\n        $this->assertEquals('BSD-3-Clause', $this->license->getName());\n    }\n\n    public function testUrlCanBeRetrieved(): void {\n        $this->assertEquals(\n            'https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE',\n            $this->license->getUrl()->asString()\n        );\n    }\n}\n"
  },
  {
    "path": "tests/values/ManifestTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\AnyVersionConstraint;\nuse PharIo\\Version\\Version;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\PharIo\\Manifest\\Manifest\n *\n * @uses \\PharIo\\Manifest\\ApplicationName\n * @uses \\PharIo\\Manifest\\Author\n * @uses \\PharIo\\Manifest\\AuthorCollection\n * @uses \\PharIo\\Manifest\\BundledComponent\n * @uses \\PharIo\\Manifest\\BundledComponentCollection\n * @uses \\PharIo\\Manifest\\CopyrightInformation\n * @uses \\PharIo\\Manifest\\Email\n * @uses \\PharIo\\Manifest\\License\n * @uses \\PharIo\\Manifest\\RequirementCollection\n * @uses \\PharIo\\Manifest\\PhpVersionRequirement\n * @uses \\PharIo\\Manifest\\Type\n * @uses \\PharIo\\Manifest\\Application\n * @uses \\PharIo\\Manifest\\Url\n * @uses \\PharIo\\Version\\Version\n * @uses \\PharIo\\Version\\VersionConstraint\n */\nclass ManifestTest extends TestCase {\n    /** @var ApplicationName */\n    private $name;\n\n    /** @var Version */\n    private $version;\n\n    /** @var Type */\n    private $type;\n\n    /** @var CopyrightInformation */\n    private $copyrightInformation;\n\n    /** @var RequirementCollection */\n    private $requirements;\n\n    /** @var BundledComponentCollection */\n    private $bundledComponents;\n\n    /** @var Manifest */\n    private $manifest;\n\n    protected function setUp(): void {\n        $this->version = new Version('5.6.5');\n\n        $this->type = Type::application();\n\n        $author  = new Author('Joe Developer', new Email('user@example.com'));\n        $license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE'));\n\n        $authors = new AuthorCollection;\n        $authors->add($author);\n\n        $this->copyrightInformation = new CopyrightInformation($authors, $license);\n\n        $this->requirements = new RequirementCollection;\n        $this->requirements->add(new PhpVersionRequirement(new AnyVersionConstraint));\n\n        $this->bundledComponents = new BundledComponentCollection;\n        $this->bundledComponents->add(new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2')));\n\n        $this->name = new ApplicationName('phpunit/phpunit');\n\n        $this->manifest = new Manifest(\n            $this->name,\n            $this->version,\n            $this->type,\n            $this->copyrightInformation,\n            $this->requirements,\n            $this->bundledComponents\n        );\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(Manifest::class, $this->manifest);\n    }\n\n    public function testNameCanBeRetrieved(): void {\n        $this->assertEquals($this->name, $this->manifest->getName());\n    }\n\n    public function testVersionCanBeRetrieved(): void {\n        $this->assertEquals($this->version, $this->manifest->getVersion());\n    }\n\n    public function testTypeCanBeRetrieved(): void {\n        $this->assertEquals($this->type, $this->manifest->getType());\n    }\n\n    public function testTypeCanBeQueried(): void {\n        $this->assertTrue($this->manifest->isApplication());\n        $this->assertFalse($this->manifest->isLibrary());\n        $this->assertFalse($this->manifest->isExtension());\n    }\n\n    public function testCopyrightInformationCanBeRetrieved(): void {\n        $this->assertEquals($this->copyrightInformation, $this->manifest->getCopyrightInformation());\n    }\n\n    public function testRequirementsCanBeRetrieved(): void {\n        $this->assertEquals($this->requirements, $this->manifest->getRequirements());\n    }\n\n    public function testBundledComponentsCanBeRetrieved(): void {\n        $this->assertEquals($this->bundledComponents, $this->manifest->getBundledComponents());\n    }\n\n    /**\n     * @uses \\PharIo\\Manifest\\Extension\n     */\n    public function testExtendedApplicationCanBeQueriedForExtension(): void {\n        $appName  = new ApplicationName('foo/bar');\n        $manifest = new Manifest(\n            new ApplicationName('foo/foo'),\n            new Version('1.0.0'),\n            Type::extension($appName, new AnyVersionConstraint),\n            $this->copyrightInformation,\n            new RequirementCollection,\n            new BundledComponentCollection\n        );\n\n        $this->assertTrue($manifest->isExtensionFor($appName));\n    }\n\n    public function testNonExtensionReturnsFalseWhenQueriesForExtension(): void {\n        $appName  = new ApplicationName('foo/bar');\n        $manifest = new Manifest(\n            new ApplicationName('foo/foo'),\n            new Version('1.0.0'),\n            Type::library(),\n            $this->copyrightInformation,\n            new RequirementCollection,\n            new BundledComponentCollection\n        );\n\n        $this->assertFalse($manifest->isExtensionFor($appName));\n    }\n\n    /**\n     * @uses \\PharIo\\Manifest\\Extension\n     */\n    public function testExtendedApplicationCanBeQueriedForExtensionWithVersion(): void {\n        $appName  = new ApplicationName('foo/bar');\n        $manifest = new Manifest(\n            new ApplicationName('foo/foo'),\n            new Version('1.0.0'),\n            Type::extension($appName, new AnyVersionConstraint),\n            $this->copyrightInformation,\n            new RequirementCollection,\n            new BundledComponentCollection\n        );\n\n        $this->assertTrue($manifest->isExtensionFor($appName, new Version('1.2.3')));\n    }\n}\n"
  },
  {
    "path": "tests/values/PhpExtensionRequirementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\PhpExtensionRequirement\n */\nclass PhpExtensionRequirementTest extends TestCase {\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(PhpExtensionRequirement::class, new PhpExtensionRequirement('dom'));\n    }\n\n    public function testCanBeConvertedToString(): void {\n        $this->assertEquals('dom', (new PhpExtensionRequirement('dom'))->asString());\n    }\n}\n"
  },
  {
    "path": "tests/values/PhpVersionRequirementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\ExactVersionConstraint;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\PhpVersionRequirement\n *\n * @uses \\PharIo\\Version\\VersionConstraint\n */\nclass PhpVersionRequirementTest extends TestCase {\n    /** @var PhpVersionRequirement */\n    private $requirement;\n\n    protected function setUp(): void {\n        $this->requirement = new PhpVersionRequirement(new ExactVersionConstraint('7.1.0'));\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(PhpVersionRequirement::class, $this->requirement);\n    }\n\n    public function testVersionConstraintCanBeRetrieved(): void {\n        $this->assertEquals('7.1.0', $this->requirement->getVersionConstraint()->asString());\n    }\n}\n"
  },
  {
    "path": "tests/values/RequirementCollectionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PharIo\\Version\\ExactVersionConstraint;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\PharIo\\Manifest\\RequirementCollection\n * @covers \\PharIo\\Manifest\\RequirementCollectionIterator\n *\n * @uses \\PharIo\\Manifest\\PhpVersionRequirement\n * @uses \\PharIo\\Version\\VersionConstraint\n */\nclass RequirementCollectionTest extends TestCase {\n    /** @var RequirementCollection */\n    private $collection;\n\n    /** @var Requirement */\n    private $item;\n\n    protected function setUp(): void {\n        $this->collection = new RequirementCollection;\n        $this->item       = new PhpVersionRequirement(new ExactVersionConstraint('7.1.0'));\n    }\n\n    public function testCanBeCreated(): void {\n        $this->assertInstanceOf(RequirementCollection::class, $this->collection);\n    }\n\n    public function testCanBeCounted(): void {\n        $this->collection->add($this->item);\n\n        $this->assertCount(1, $this->collection);\n    }\n\n    public function testCanBeIterated(): void {\n        $this->collection->add(new PhpVersionRequirement(new ExactVersionConstraint('5.6.0')));\n        $this->collection->add($this->item);\n\n        $this->assertContains($this->item, $this->collection);\n    }\n\n    public function testKeyPositionCanBeRetrieved(): void {\n        $this->collection->add($this->item);\n\n        foreach ($this->collection as $key => $item) {\n            $this->assertEquals(0, $key);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/values/UrlTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers PharIo\\Manifest\\Url\n */\nclass UrlTest extends TestCase {\n    public function testCanBeCreatedForValidUrl(): void {\n        $this->assertInstanceOf(Url::class, new Url('https://phar.io/'));\n    }\n\n    public function testCanBeConvertedToString(): void {\n        $this->assertEquals('https://phar.io/', (new Url('https://phar.io/'))->asString());\n    }\n\n    /**\n     * @covers PharIo\\Manifest\\InvalidUrlException\n     */\n    public function testCannotBeCreatedForInvalidUrl(): void {\n        $this->expectException(InvalidUrlException::class);\n\n        new Url('invalid');\n    }\n}\n"
  },
  {
    "path": "tests/xml/AuthorElementCollectionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass AuthorElementCollectionTest extends \\PHPUnit\\Framework\\TestCase {\n    public function testAuthorElementCanBeRetrievedFromCollection(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><author xmlns=\"https://phar.io/xml/manifest/1.0\" name=\"Reiner Zufall\" email=\"reiner@zufall.de\" />');\n        $collection = new AuthorElementCollection($dom->childNodes);\n\n        foreach ($collection as $authorElement) {\n            $this->assertInstanceOf(AuthorElement::class, $authorElement);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/xml/AuthorElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass AuthorElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var AuthorElement */\n    private $author;\n\n    protected function setUp(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><author xmlns=\"https://phar.io/xml/manifest/1.0\" name=\"Reiner Zufall\" email=\"reiner@zufall.de\" />');\n        $this->author = new AuthorElement($dom->documentElement);\n    }\n\n    public function testNameCanBeRetrieved(): void {\n        $this->assertEquals('Reiner Zufall', $this->author->getName());\n    }\n\n    public function testEmailCanBeRetrieved(): void {\n        $this->assertEquals('reiner@zufall.de', $this->author->getEmail());\n    }\n\n    public function testHasEmailReturnsTrueWhenEMailIsSet(): void {\n        $this->assertTrue($this->author->hasEmail());\n    }\n\n    public function testHasEMailReturnsFalseWhenNoEMailAddressIsSet(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><author xmlns=\"https://phar.io/xml/manifest/1.0\" name=\"Reiner Zufall\" />');\n\n        $this->assertFalse((new AuthorElement($dom->documentElement))->hasEMail());\n    }\n}\n"
  },
  {
    "path": "tests/xml/BundlesElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass BundlesElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var DOMDocument */\n    private $dom;\n\n    /** @var BundlesElement */\n    private $bundles;\n\n    protected function setUp(): void {\n        $this->dom = new DOMDocument();\n        $this->dom->loadXML('<?xml version=\"1.0\" ?><bundles xmlns=\"https://phar.io/xml/manifest/1.0\" />');\n        $this->bundles = new BundlesElement($this->dom->documentElement);\n    }\n\n    public function testThrowsExceptionWhenGetComponentElementsIsCalledButNodesAreMissing(): void {\n        $this->expectException(ManifestElementException::class);\n        $this->bundles->getComponentElements();\n    }\n\n    public function testGetComponentElementsReturnsComponentElementCollection(): void {\n        $this->addComponent();\n        $this->assertInstanceOf(\n            ComponentElement::class,\n            $this->bundles->getComponentElements()->current()\n        );\n    }\n\n    private function addComponent(): void {\n        $this->dom->documentElement->appendChild(\n            $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'component')\n        );\n    }\n}\n"
  },
  {
    "path": "tests/xml/ComponentElementCollectionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass ComponentElementCollectionTest extends \\PHPUnit\\Framework\\TestCase {\n    public function testComponentElementCanBeRetrievedFromCollection(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><component xmlns=\"https://phar.io/xml/manifest/1.0\" />');\n        $collection = new ComponentElementCollection($dom->childNodes);\n\n        foreach ($collection as $componentElement) {\n            $this->assertInstanceOf(ComponentElement::class, $componentElement);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/xml/ComponentElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass ComponentElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var ComponentElement */\n    private $component;\n\n    protected function setUp(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><component xmlns=\"https://phar.io/xml/manifest/1.0\" name=\"phar-io/phive\" version=\"0.6.0\" />');\n        $this->component = new ComponentElement($dom->documentElement);\n    }\n\n    public function testNameCanBeRetrieved(): void {\n        $this->assertEquals('phar-io/phive', $this->component->getName());\n    }\n\n    public function testEmailCanBeRetrieved(): void {\n        $this->assertEquals('0.6.0', $this->component->getVersion());\n    }\n}\n"
  },
  {
    "path": "tests/xml/ContainsElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\nuse DOMElement;\n\nclass ContainsElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var DOMElement */\n    private $domElement;\n\n    /** @var ContainsElement */\n    private $contains;\n\n    protected function setUp(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><php xmlns=\"https://phar.io/xml/manifest/1.0\" name=\"phpunit/phpunit\" version=\"5.6.5\" type=\"application\" />');\n        $this->domElement = $dom->documentElement;\n        $this->contains   = new ContainsElement($this->domElement);\n    }\n\n    public function testVersionCanBeRetrieved(): void {\n        $this->assertEquals('5.6.5', $this->contains->getVersion());\n    }\n\n    public function testThrowsExceptionWhenVersionAttributeIsMissing(): void {\n        $this->domElement->removeAttribute('version');\n        $this->expectException(ManifestElementException::class);\n        $this->contains->getVersion();\n    }\n\n    public function testNameCanBeRetrieved(): void {\n        $this->assertEquals('phpunit/phpunit', $this->contains->getName());\n    }\n\n    public function testThrowsExceptionWhenNameAttributeIsMissing(): void {\n        $this->domElement->removeAttribute('name');\n        $this->expectException(ManifestElementException::class);\n        $this->contains->getName();\n    }\n\n    public function testTypeCanBeRetrieved(): void {\n        $this->assertEquals('application', $this->contains->getType());\n    }\n\n    public function testThrowsExceptionWhenTypeAttributeIsMissing(): void {\n        $this->domElement->removeAttribute('type');\n        $this->expectException(ManifestElementException::class);\n        $this->contains->getType();\n    }\n\n    public function testGetExtensionElementReturnsExtensionElement(): void {\n        $this->domElement->appendChild(\n            $this->domElement->ownerDocument->createElementNS('https://phar.io/xml/manifest/1.0', 'extension')\n        );\n        $this->assertInstanceOf(ExtensionElement::class, $this->contains->getExtensionElement());\n    }\n}\n"
  },
  {
    "path": "tests/xml/CopyrightElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass CopyrightElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var DOMDocument */\n    private $dom;\n\n    /** @var CopyrightElement */\n    private $copyright;\n\n    protected function setUp(): void {\n        $this->dom = new DOMDocument();\n        $this->dom->loadXML('<?xml version=\"1.0\" ?><copyright xmlns=\"https://phar.io/xml/manifest/1.0\" />');\n        $this->copyright = new CopyrightElement($this->dom->documentElement);\n    }\n\n    public function testThrowsExceptionWhenGetAuthroElementsIsCalledButNodesAreMissing(): void {\n        $this->expectException(ManifestElementException::class);\n        $this->copyright->getAuthorElements();\n    }\n\n    public function testThrowsExceptionWhenGetLicenseElementIsCalledButNodeIsMissing(): void {\n        $this->expectException(ManifestElementException::class);\n        $this->copyright->getLicenseElement();\n    }\n\n    public function testGetAuthorElementsReturnsAuthorElementCollection(): void {\n        $this->dom->documentElement->appendChild(\n            $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'author')\n        );\n        $this->assertInstanceOf(\n            AuthorElementCollection::class,\n            $this->copyright->getAuthorElements()\n        );\n    }\n\n    public function testGetLicenseElementReturnsLicenseElement(): void {\n        $this->dom->documentElement->appendChild(\n            $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'license')\n        );\n        $this->assertInstanceOf(\n            LicenseElement::class,\n            $this->copyright->getLicenseElement()\n        );\n    }\n}\n"
  },
  {
    "path": "tests/xml/ElementCollectionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ElementCollectionTest extends TestCase {\n    public function testEnforcesDOMElementsOnly(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\"?><root>text</root>');\n\n        $this->expectException(ElementCollectionException::class);\n\n        new class($dom->documentElement->childNodes) extends ElementCollection {\n            public function current(): void {\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "tests/xml/ExtElementCollectionTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass ExtElementCollectionTest extends \\PHPUnit\\Framework\\TestCase {\n    public function testComponentElementCanBeRetrievedFromCollection(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><ext xmlns=\"https://phar.io/xml/manifest/1.0\" />');\n        $collection = new ExtElementCollection($dom->childNodes);\n\n        foreach ($collection as $position => $extElement) {\n            $this->assertInstanceOf(ExtElement::class, $extElement);\n            $this->assertEquals(0, $position);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/xml/ExtElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass ExtElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var ExtElement */\n    private $ext;\n\n    protected function setUp(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><ext xmlns=\"https://phar.io/xml/manifest/1.0\" name=\"dom\" />');\n        $this->ext = new ExtElement($dom->documentElement);\n    }\n\n    public function testNameCanBeRetrieved(): void {\n        $this->assertEquals('dom', $this->ext->getName());\n    }\n}\n"
  },
  {
    "path": "tests/xml/ExtensionElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass ExtensionElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var ExtensionElement */\n    private $extension;\n\n    protected function setUp(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><extension xmlns=\"https://phar.io/xml/manifest/1.0\" for=\"phar-io/phive\" compatible=\"~0.6\" />');\n        $this->extension = new ExtensionElement($dom->documentElement);\n    }\n\n    public function testNForCanBeRetrieved(): void {\n        $this->assertEquals('phar-io/phive', $this->extension->getFor());\n    }\n\n    public function testCompatibleVersionConstraintCanBeRetrieved(): void {\n        $this->assertEquals('~0.6', $this->extension->getCompatible());\n    }\n}\n"
  },
  {
    "path": "tests/xml/LicenseElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass LicenseElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var LicenseElement */\n    private $license;\n\n    protected function setUp(): void {\n        $dom = new DOMDocument();\n        $dom->loadXML('<?xml version=\"1.0\" ?><license xmlns=\"https://phar.io/xml/manifest/1.0\" type=\"BSD-3\" url=\"https://some.tld/LICENSE\" />');\n        $this->license = new LicenseElement($dom->documentElement);\n    }\n\n    public function testTypeCanBeRetrieved(): void {\n        $this->assertEquals('BSD-3', $this->license->getType());\n    }\n\n    public function testUrlCanBeRetrieved(): void {\n        $this->assertEquals('https://some.tld/LICENSE', $this->license->getUrl());\n    }\n}\n"
  },
  {
    "path": "tests/xml/ManifestDocumentTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse function file_get_contents;\n\nclass ManifestDocumentTest extends \\PHPUnit\\Framework\\TestCase {\n    public function testThrowsExceptionWhenFileDoesNotExist(): void {\n        $this->expectException(ManifestDocumentException::class);\n        ManifestDocument::fromFile('/does/not/exist');\n    }\n\n    public function testCanBeCreatedFromFile(): void {\n        $this->assertInstanceOf(\n            ManifestDocument::class,\n            ManifestDocument::fromFile(__DIR__ . '/../_fixture/phpunit-5.6.5.xml')\n        );\n    }\n\n    public function testFromStringThrowsExceptionOnEmptyString(): void {\n        $this->expectException(ManifestDocumentException::class);\n        ManifestDocument::fromString('');\n    }\n\n    public function testCanBeConstructedFromString(): void {\n        $content = file_get_contents(__DIR__ . '/../_fixture/phpunit-5.6.5.xml');\n        $this->assertInstanceOf(\n            ManifestDocument::class,\n            ManifestDocument::fromString($content)\n        );\n    }\n\n    public function testThrowsExceptionOnInvalidXML(): void {\n        $this->expectException(ManifestDocumentLoadingException::class);\n        ManifestDocument::fromString('<?xml version=\"1.0\" ?><root>');\n    }\n\n    public function testLoadingDocumentWithWrongRootNameThrowsException(): void {\n        $this->expectException(ManifestDocumentException::class);\n        ManifestDocument::fromString('<?xml version=\"1.0\" ?><root />');\n    }\n\n    public function testLoadingDocumentWithWrongNamespaceThrowsException(): void {\n        $this->expectException(ManifestDocumentException::class);\n        ManifestDocument::fromString('<?xml version=\"1.0\" ?><phar xmlns=\"foo:bar\" />');\n    }\n\n    public function testContainsElementCanBeRetrieved(): void {\n        $this->assertInstanceOf(\n            ContainsElement::class,\n            $this->loadFixture()->getContainsElement()\n        );\n    }\n\n    public function testRequiresElementCanBeRetrieved(): void {\n        $this->assertInstanceOf(\n            RequiresElement::class,\n            $this->loadFixture()->getRequiresElement()\n        );\n    }\n\n    public function testCopyrightElementCanBeRetrieved(): void {\n        $this->assertInstanceOf(\n            CopyrightElement::class,\n            $this->loadFixture()->getCopyrightElement()\n        );\n    }\n\n    public function testBundlesElementCanBeRetrieved(): void {\n        $this->assertInstanceOf(\n            BundlesElement::class,\n            $this->loadFixture()->getBundlesElement()\n        );\n    }\n\n    public function testThrowsExceptionWhenContainsIsMissing(): void {\n        $this->expectException(ManifestDocumentException::class);\n        $this->loadEmptyFixture()->getContainsElement();\n    }\n\n    public function testThrowsExceptionWhenCopyirhgtIsMissing(): void {\n        $this->expectException(ManifestDocumentException::class);\n        $this->loadEmptyFixture()->getCopyrightElement();\n    }\n\n    public function testThrowsExceptionWhenRequiresIsMissing(): void {\n        $this->expectException(ManifestDocumentException::class);\n        $this->loadEmptyFixture()->getRequiresElement();\n    }\n\n    public function testThrowsExceptionWhenBundlesIsMissing(): void {\n        $this->expectException(ManifestDocumentException::class);\n        $this->loadEmptyFixture()->getBundlesElement();\n    }\n\n    public function testHasBundlesReturnsTrueWhenBundlesNodeIsPresent(): void {\n        $this->assertTrue(\n            $this->loadFixture()->hasBundlesElement()\n        );\n    }\n\n    public function testHasBundlesReturnsFalseWhenBundlesNoNodeIsPresent(): void {\n        $this->assertFalse(\n            $this->loadEmptyFixture()->hasBundlesElement()\n        );\n    }\n\n    private function loadFixture() {\n        return ManifestDocument::fromFile(__DIR__ . '/../_fixture/phpunit-5.6.5.xml');\n    }\n\n    private function loadEmptyFixture() {\n        return ManifestDocument::fromString(\n            '<?xml version=\"1.0\" ?><phar xmlns=\"https://phar.io/xml/manifest/1.0\" />'\n        );\n    }\n}\n"
  },
  {
    "path": "tests/xml/PhpElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass PhpElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var DOMDocument */\n    private $dom;\n\n    /** @var PhpElement */\n    private $php;\n\n    protected function setUp(): void {\n        $this->dom = new DOMDocument();\n        $this->dom->loadXML('<?xml version=\"1.0\" ?><php xmlns=\"https://phar.io/xml/manifest/1.0\" version=\"^5.6 || ^7.0\" />');\n        $this->php = new PhpElement($this->dom->documentElement);\n    }\n\n    public function testVersionConstraintCanBeRetrieved(): void {\n        $this->assertEquals('^5.6 || ^7.0', $this->php->getVersion());\n    }\n\n    public function testHasExtElementsReturnsFalseWhenNoExtensionsAreRequired(): void {\n        $this->assertFalse($this->php->hasExtElements());\n    }\n\n    public function testHasExtElementsReturnsTrueWhenExtensionsAreRequired(): void {\n        $this->addExtElement();\n        $this->assertTrue($this->php->hasExtElements());\n    }\n\n    public function testGetExtElementsReturnsExtElementCollection(): void {\n        $this->addExtElement();\n        $this->assertInstanceOf(ExtElementCollection::class, $this->php->getExtElements());\n    }\n\n    private function addExtElement(): void {\n        $this->dom->documentElement->appendChild(\n            $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'ext')\n        );\n    }\n}\n"
  },
  {
    "path": "tests/xml/RequiresElementTest.php",
    "content": "<?php declare(strict_types = 1);\n/*\n * This file is part of PharIo\\Manifest.\n *\n * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n */\nnamespace PharIo\\Manifest;\n\nuse DOMDocument;\n\nclass RequiresElementTest extends \\PHPUnit\\Framework\\TestCase {\n    /** @var DOMDocument */\n    private $dom;\n\n    /** @var RequiresElement */\n    private $requires;\n\n    protected function setUp(): void {\n        $this->dom = new DOMDocument();\n        $this->dom->loadXML('<?xml version=\"1.0\" ?><requires xmlns=\"https://phar.io/xml/manifest/1.0\" />');\n        $this->requires = new RequiresElement($this->dom->documentElement);\n    }\n\n    public function testThrowsExceptionWhenGetPhpElementIsCalledButElementIsMissing(): void {\n        $this->expectException(ManifestElementException::class);\n        $this->requires->getPHPElement();\n    }\n\n    public function testHasExtElementsReturnsTrueWhenExtensionsAreRequired(): void {\n        $this->dom->documentElement->appendChild(\n            $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'php')\n        );\n\n        $this->assertInstanceOf(PhpElement::class, $this->requires->getPHPElement());\n    }\n}\n"
  }
]