[
  {
    "path": ".gitignore",
    "content": "target\ntarget/*\n\n# Eclipse\n.settings\n.project\n.classpath\n\n# Idea\n*.iml\n.idea\n\n# Atlassian\natlassian-ide-plugin.xml"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"etc\"]\n\tpath = etc\n\turl = git://github.com/trautonen/etc.git\n"
  },
  {
    "path": ".travis.yml",
    "content": "dist: xenial\n\nlanguage: java\n\nsudo: false\n\njdk:\n  - openjdk8\n  - openjdk10\n  - openjdk11\n\nenv:\n  global:\n    - secure: \"pmNBqCAW1rc4WKHEmnroZNwAMus18K1VWhRYwt+CN0acH8griJp612tjwWcI\\n9XkZcSPR0CJx1TZqGDZZTFH44Pkm6ELU1kc54xtJR6WMXnubEVoEom0tcv/1\\nNyzxv9UFJfaNgaTESww+OXSlO9wQre5ZS0/wn2xrz0+twtOPYDU=\"\n    - secure: \"CZ9mejMLJdrh+a5TFXsNSiYyK9K/zNYOtubv2sPq1OEGhuohdUfLtdsk7bK9\\nQcIlhZjrE5Q/wVgjZcFsnVpKhnUSRLC7sTOh6tu08EwpNtnNLl5AeUztOMCs\\nxhG5H7jDu9uEH81WDZnIuK4Zq4qxXx523rnqQfk4DsTCKLVh9jI=\"\n\naddons:\n  apt:\n    packages:\n      - python-yaml\n\nbefore_install:\n  - git submodule update --init --recursive\n\nbefore_script:\n  - python etc/travis-sonatype.py\n\nscript: python etc/travis-build.py --settings ~/.m2/sonatype.xml\n\nafter_success:\n  - mvn clean cobertura:cobertura org.eluder.coveralls:coveralls-maven-plugin:report\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## 4.2.0\n\n- #95, #96: Improved error message for misbehaving Coveralls API\n- #92: Support for HTTP proxies in settings.xml\n- #91: Support for epoch formatted timestamps\n\n\n## 4.1.0\n\n- #88: Support for AppVeyor CI\n\n\n## 4.0.0\n\n- #85: Merge coverages from multiple reports to single source file\n- #84: Change source content to source digest per new Coveralls API\n- #83: Require Java 7 to support new features and syntax\n- #77: Support for custom build timestamp format\n\n\n## 3.2.1\n\n- #87: Downgraded jgit version to support Java 6\n\n\n## 3.2.0\n\n- #82: Improved error message for duplicate classes in different modules\n- #76: Property to allow Coveralls service fail without build failure\n- #74: Handle transitive logging dependencies better\n\n\n## 3.1.0\n\n- #67: Configurable project basedir\n- #65, #66, #68: Support for Shippable CI\n- #63: Directory scanning source loader\n\n\n## 3.0.1\n\n- #53: Improved error message for missing source encoding\n- #52: Ignore duplicate source files on Cobertura aggregate mode\n\n\n## 3.0.0\n\n- #48: Removed support for URL based source loading due to Coveralls changes\n- #42, #45, #46: Support Coveralls new GitHub based source view \n- #40: Proper multi-module support and report aggregation\n- #37, #41: Disclaimer for Java 8 usage\n\n\n## 2.2.0\n\n- #31: Improved error messages for Coveralls API failures\n- #30: Improved error message for missing charset\n- #28: More lenient XML parsing\n- #26, #29: Support for Saga coverage tool and chain multiple coverage reports\n\n\n## 2.1.0\n\n- #24: Filter out remote names from git branches\n- #19, #20: Skip configuration property to allow skipping of plugin execution\n\n\n## 2.0.1\n\n- #18: Update to HttpComponents HttpClient 4.3\n- #15, #16, #17: Disable PKCS cryptography provider at runtime to work around OpenJDK SSL issue\n\n\n## 2.0.0\n\n- #13: Dry run property for test builds\n- #12: Use ServiceSetup as secondary configuration source and Maven/VM properties as primary\n- #11: Support multiple source directories\n- #9: Support for other CI tools and platforms\n- #8: Aggregated reports for multi-module projects\n\n\n## 1.2.0\n\n- #10: Validation of the Coveralls job\n- #4: Report build timestamp to Coveralls\n- #3: Log code lines from generated report to Maven console\n\n\n## 1.1.0\n\n- #1: Easier configuration for Travis CI\n\n\n## 1.0.0\n\n- Initial release\n"
  },
  {
    "path": "LICENSE.MIT",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 - 2016, Tapio Rautonen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "MIGRATION.md",
    "content": "# Migration guide\n\nChanges marked with bold affect the plugin usage. Other changes are only related to development\nand codebase.\n\n\n## 2.x to 3.x\n\n-\n\n\n## 1.x to 2.x\n\n- **`sourceDirectory` parameter removed and replaced with a list parameter `sourceDirectories`**\n- **service environment parameters do not override configuration parameters**\n- `org.eluder.coveralls.maven.plugin.service.ServiceSetup` interface completely changed to reflect\n  the service specific configuration properly\n- `org.eluder.coveralls.maven.plugin.service.Travis` changed to reflect the new service setup\n  interface\n- `org.eluder.coveralls.maven.plugin.domain.JobValidator` and all validation related code is\n  now located in `org.eluder.coveralls.maven.plugin.validation` package\n- `org.eluder.coveralls.maven.plugin.domain.GitRepository` does not take custom branch parameter\n  as constructor argument anymore, the same behavior is handled with the new service environment\n  setup\n- `org.eluder.coveralls.maven.plugin.domain.Job` has only default constructor and initialization\n  is done with _with*_ methods, _validate()_ method returns list of validation errors instead of\n  throwing exception\n- `org.eluder.coveralls.maven.plugin.domain.SourceLoader` constructor takes a list of source\n  directories instead of a single source directory\n"
  },
  {
    "path": "README.md",
    "content": "coveralls-maven-plugin\n======================\n\n[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)\n[![Coverage Status](http://img.shields.io/coveralls/trautonen/coveralls-maven-plugin/master.svg?style=flat-square)](https://coveralls.io/r/trautonen/coveralls-maven-plugin?branch=master)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.eluder.coveralls/coveralls-maven-plugin/badge.svg?style=flat-square)](https://maven-badges.herokuapp.com/maven-central/org.eluder.coveralls/coveralls-maven-plugin/)\n\nMaven plugin for submitting Java code coverage reports to [Coveralls](https://coveralls.io/) web\nservice.\n\n## !!! Deprecated !!!\n\nThis project is deprecated due to lack of time and interest. Please use https://github.com/hazendaz/coveralls-maven-plugin from now on.\n\n\n### Requirements\n\n* Java 6 up to 3.x and Java 7 for 4.x onwards.\n* Maven 3.0.0 or newer.\n\n\n### Features\n\n* Supports [Cobertura](http://mojo.codehaus.org/cobertura-maven-plugin/),\n  [JaCoCo](http://www.eclemma.org/jacoco/trunk/doc/maven.html) and\n  [Saga](http://timurstrekalov.github.io/saga/) coverage tools\n* Multi-module report aggregation\n* Built-in support for [Travis CI](https://travis-ci.org/), [Circle](https://circleci.com/),\n  [Codeship](https://www.codeship.io/), [Jenkins](http://jenkins-ci.org/),\n  [Bamboo](https://www.atlassian.com/software/bamboo/), [Shippable](https://www.shippable.com/)\n  and [Appveyor](http://www.appveyor.com/) continuous integration services\n* Fully streaming implementation for fast report generation and small memory footprint\n* Provides clean interfaces to allow easy extending to different coverage tools\n* Convention over configuration for almost zero configuration usage\n* Applies [semantic versioning](http://semver.org/)\n\n\n### Usage\n\nSet up the Coveralls maven plugin in the build section of the project pom.xml:\n\n```xml\n<plugin>\n    <groupId>org.eluder.coveralls</groupId>\n    <artifactId>coveralls-maven-plugin</artifactId>\n    <version>4.3.0</version>\n    <configuration>\n        <repoToken>yourcoverallsprojectrepositorytoken</repoToken>\n    </configuration>\n</plugin>\n```\n\n#### Configuration\n\nIf used as a standalone Maven build or with any continuous integration server other than Travis\nCI, the Coveralls repository token must be provided. This can be achieved by setting the\nconfiguration section in the plugin or setting the Maven property `repoToken` to your coveralls\nproject repository token, using `-DrepoToken=yourcoverallsprojectrepositorytoken` when running the\nmaven command. **Do not publish your repository token in public GitHub repositories.** If you do,\nanyone can submit coverage data without permission.\n\nIf you are using Travis CI, CircleCI, Codeship, Jenkins or Bamboo continuous integration services,\nno other configuration is required. The plugin's built-in service environment support take care of\nthe rest. The plugin tries to find report files for any of the supported coverage tools and\nfinally aggregates the coverage report. Java 8 is currently supported only by JaCoCo.\n\nSee [Complete plugin configuration](#complete-plugin-configuration) for all of the available\nconfiguration parameters.\n\n\n#### Cobertura\n\nSet up the Cobertura Maven plugin with XML report format in the build section of the project\npom.xml:\n\n```xml\n<plugin>\n    <groupId>org.codehaus.mojo</groupId>\n    <artifactId>cobertura-maven-plugin</artifactId>\n    <version>2.7</version>\n    <configuration>\n        <format>xml</format>\n        <maxmem>256m</maxmem>\n        <!-- aggregated reports for multi-module projects -->\n        <aggregate>true</aggregate>\n    </configuration>\n</plugin>\n```\n\nExecute Maven to create Cobertura report and submit Coveralls data:\n\n```\nmvn cobertura:cobertura coveralls:report\n```\n\nFor example if you are using Travis CI this means you need to add to your `.travis.yml` the lines:\n\n```\nafter_success:\n  - mvn clean cobertura:cobertura coveralls:report\n```\n\n\n#### JaCoCo\n\nSet up the JaCoCo Maven plugin in the build section of the project pom.xml:\n\n```xml\n<plugin>\n    <groupId>org.jacoco</groupId>\n    <artifactId>jacoco-maven-plugin</artifactId>\n    <version>0.7.6.201602180812</version>\n    <executions>\n        <execution>\n            <id>prepare-agent</id>\n            <goals>\n                <goal>prepare-agent</goal>\n            </goals>\n        </execution>\n    </executions>\n</plugin>\n```\n\nExecute Maven to create JaCoCo report and submit Coveralls data:\n\n```\nmvn clean test jacoco:report coveralls:report\n```\n\nAgain, if you are using Travis CI this means you need to add to your `.travis.yml` the lines:\n\n```\nafter_success:\n  - mvn clean test jacoco:report coveralls:report\n```\n\n\n#### Saga\n\nSet up the Saga Maven plugin in the build section of the project pom.xml:\n\n```xml\n<plugin>\n    <groupId>com.github.timurstrekalov</groupId>\n    <artifactId>saga-maven-plugin</artifactId>\n    <version>1.5.5</version>\n    <executions>\n        <execution>\n            <goals>\n                <goal>coverage</goal>\n            </goals>\n        </execution>\n    </executions>\n    <configuration>\n        <baseDir>http://localhost:${jasmine.serverPort}</baseDir>\n        <outputDir>${project.build.directory}/saga-coverage</outputDir>\n        <noInstrumentPatterns>\n            <pattern>.*/spec/.*</pattern>\n            <pattern>.*/classpath/.*</pattern>\n            <pattern>.*/webjars/.*</pattern>\n        </noInstrumentPatterns>\n    </configuration>\n</plugin>\n```\n\nNote that Saga does not have default report output directory, but the plugin assumes\n`${project.build.directory}/saga-coverage`.\n\nExecute Maven to create Saga report and submit Coveralls data:\n\n```\nmvn clean test saga:coverage coveralls:report\n```\n\nAnd if you are using Travis CI this means you need to add to your `.travis.yml` the lines:\n\n```\nafter_success:\n  - mvn clean test saga:coverage coveralls:report\n```\n\n\n#### Aggregate multiple reports\n\nReport aggregation is applied by default and the only thing the user must take care of is to run\nall the desired coverage tools. You can use JaCoCo in a multi-module project so that all modules\nrun JaCoCo separately and let the plugin aggregate the report, or you can run Saga and Cobertura\nin same project and get coverage report for JavaScript and Java files.\n\nExecute Maven to create Saga and Cobertura report and submit Coveralls data:\n\n```\nmvn clean test saga:coverage cobertura:cobertura coveralls:report\n```\n\nAnd if you are using Travis CI this means you need to add to your `.travis.yml` the lines:\n\n```\nafter_success:\n  - mvn clean test saga:coverage cobertura:cobertura coveralls:report\n```\n\n\n### Complete plugin configuration\n\nConfiguration can be changed by the configuration section of plugin's definition in POM or with\nJava virtual machine system properties using the syntax `-Dparameter=value`. See\n[Maven plugin guide](http://maven.apache.org/guides/plugin/guide-java-plugin-development.html#Configuring_Parameters_in_a_Project)\nhow different types are mapped in the configuration XML. Some of the optional parameters are set\nby the built-in service environment setups. Note that if a parameter is explicitly defined, the\nservice environment will not override it.\n\n| Parameter | Type | Description |\n| --------- | ---- | ----------- |\n| `jacocoReports` | `List<File>` | List of additional JaCoCo report files. ${project.reporting.outputDirectory}/jacoco/jacoco.xml is used as default for every module. |\n| `coberturaReports` | `List<File>` | List of additional Cobertura report files. ${project.reporting.outputDirectory}/cobertura/coverage.xml is used as default for every module. |\n| `sagaReports` | `List<File>` | List of additional Saga report files. ${project.build.directory}/saga-coverage/total-coverage.xml is used as default for every module. |\n| `relativeReportDirs` | `List<String>` | List of additional relative report directories. Directories relative to ${project.reporting.outputDirectory} and ${project.build.directory} are scanned for reports. |\n| `coverallsFile` | `File` | **Default: ${project.build.directory}/coveralls.json**<br>File path to write and submit Coveralls data. |\n| `coverallsUrl` | `String` | **Default: https://coveralls.io/api/v1/jobs**<br>Url for the Coveralls API. |\n| `sourceDirectories` | `List<File>` | List of additional source directories. The plugin will scan the project's compiled source roots for defaults. |\n| `sourceEncoding` | `String` | **Default: ${project.build.sourceEncoding}**<br>Source file encoding. |\n| `serviceName` | `String` | CI service name. If not provided the supported service environments are used. |\n| `serviceJobId` | `String` | CI service job id. Currently supported only with Travis CI. If this property is set, `repoToken` is not required. If not provided the supported service environments are used. |\n| `serviceBuildNumber` | `String` | CI service build number. If not provided the supported service environments are used. |\n| `serviceBuildUrl` | `String` | CI service build url. If not provided the supported service environments are used. |\n| `serviceEnvironment` | `Properties` | CI service specific environment properties. If not provided the supported service environments are used. |\n| `repoToken` | `String` | Coveralls repository token. **Do not publish this parameter unencrypted in public GitHub repositories.** |\n| `parallel` | `boolean` | **Default: false**<br> Coveralls API flag: If this is set, the build will not be considered done until a webhook has been sent to https://coveralls.io/webhook?repo_token=… |\n| `branch` | `String` | Git branch name. If not provided the supported service environments are used. |\n| `pullRequest` | `String` | GitHub pull request identifier. If not provided the supported service environments are used. |\n| `timestampFormat` | `String` | **Default: ${maven.build.timestamp}**<br>Build timestamp format. Must be in format supported by SimpleDateFormat. |\n| `timestamp` | `String` | **Default: ${timestamp}**<br>Build timestamp. Must be in format defined by 'timestampFormat' if it's available or in default timestamp format yyyy-MM-dd'T'HH:mm:ss'Z'. |\n| `dryRun` | `boolean` | **Default: false**<br>Dry run Coveralls report without actually sending it. |\n| `failOnServiceError` | `boolean` | **Default: true**<br> Fail build if Coveralls service is not available or submission fails for internal errors. |\n| `scanForSources` | `boolean` | **Default: false**<br>Scan subdirectories for source files. |\n| `coveralls.basedir` | `File` | **Default: ${project.basedir}**<br>Base directory of the project. |\n| `coveralls.skip` | `boolean` | **Default: false**<br>Skip the plugin execution. |\n\n\n### FAQ\n\n> **Q:** How do I know that my coverage report was submitted successfully to Coveralls?  \n> **A:** The plugin will end with BUILD SUCCESS and the log contains the reported job id and\n> direct URL to Coveralls.\n\n<!-- -->\n> **Q:** I get BUILD SUCCESS but why Coveralls shows only question marks in the reports?  \n> **A:** The data is most likely reported correctly, but Coveralls might take hours, or even a\n> day, to update the actual coverage numbers.\n\n<!-- -->\n> **Q:** Can I use Java 8 with the plugin?  \n> **A:** Yes. The Coveralls plugin works fine with Java 8, but the problem is the coverage tools.\n> Currently only tool supporting Java 8 is JaCoCo. You can use JaCoCo in a single module or\n> a multi-module project and let the Coveralls plugin handle the report aggregation. This is not\n> true aggregation though and does not address cross module coverage calculation (see\n> https://github.com/jacoco/jacoco/pull/97)\n\n<!-- -->\n> **Q:** Build fails with 'javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated'\n> exception, what to do?  \n> **A:** If the build is run with OpenJDK, you probably hit an issue with the Cryptography Package\n> Providers not supporting all Elliptic Curves. The [issue](https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/1006776)\n> is described in the Ubuntu issue tracker. A workaround is to disable the PKCS provider from the\n> `java.security` options file.\n> ```\n> sudo sed -i 's/security.provider.9/#security.provider.9/g' $JAVA_HOME/jre/lib/security/java.security\n> ```\n> In Travis CI the above command can be added to before_install phase. See complete example from\n> this project's `.travis.yml`.\n\n<!-- -->\n> **Q:** How can I use Scala or some other project which sources reside in other folder than\n> `src/main/java`?  \n> **A:** The plugin uses all compiled source roots available for the project at runtime. If the\n> source directories are available, everything is fine. Otherwise additional source directories\n> can be applied with `sourceDirectories` configuration parameter that takes a Maven configuration\n> style list of source directories.\n\n<!-- -->\n> **Q:** How can I set the plugin to use multiple source directories?  \n> **A:** For multi-module projects, the plugin automatically scans the project hierarchy and adds\n> all required source directories. You can also customize the used source directories with\n> `sourceDirectories` configuration parameter that takes a Maven configuration style list of\n> source directories.\n\n<!-- -->\n> **Q:** Why source files are not found for generated sources?  \n> **A:** Generated source directories under target are not added to the sources list\n> automatically. It is often not good practice to test generated code, because the code is not\n> managed by the project under test, unless you are testing a source generator. Cobertura and\n> JaCoCo both have `<excludes>` configuration directive that provides ignoring of class files. If\n> the generated sources still must be tested, all source directories can be explicitly defined\n> with `sourceDirectories` configuration parameter.\n\n<!-- -->\n> **Q:** JaCoCo or Cobertura, which one should i choose?  \n> **A:** For multi-module projects, only Cobertura supports report aggregation out of the box. The\n> coverage metrics and performance of the two plugins are not much different for a small or medium\n> sized project, but there are 2 notable differences with the tools:\n> - JaCoCo does not track how many times a single line of code is hit by all the tests together,\n> so Coveralls is always reported with 1 as the number of hits if the line is covered. Cobertura\n> tracks the number of hits and the number is reported to Coveralls.\n> - Cobertura tracks all inner classes separately, so a single source file will contain multiple\n> records with same file name in Coveralls if there are any innner classes defined. The\n> coveralls-maven-plugin adds classifier from the inner class to distinguish the files, but if\n> there are lot of inner classes defined this creates some noise to the Coveralls reports. JaCoCo\n> tracks inner classes within same source file so each source file is only reported once to\n> Coveralls.\n\n\n### Changelog\n\nSee [changelog](CHANGELOG.md) for more details.\n\n\n### Migration\n\nSee [migration](MIGRATION.md) documentation for more information.\n\n\n### Credits\n\n- Jakub Bednář (@bednar) for Saga integration and the idea of chaining multiple reports provided\n  by different coverage tools.\n- Marvin Froeder (@velo) for Shippable and Appveyor support, configurable basedir and directory\n  scanning source loader.\n- Pasi Niemi (@psiniemi) for coverage merging from different reports to single source file.\n\n\n### Continuous integration\n\nTravis CI builds the plugin with Oracle JDK 7. All successfully built snapshots are deployed to\nSonatype OSS repository. Cobertura is used to gather coverage metrics and the report is submitted\nto Coveralls with this plugin.\n\n\n### Using test versions\n\nAdd the following repository configurations to your `pom.xml` to enable snapshot versions of this\nplugin to be used.\n\n```xml\n  <repositories>\n    <repository>\n      <id>sonatype-nexus-snapshots</id>\n      <url>https://oss.sonatype.org/content/repositories/snapshots</url>\n      <releases><enabled>false</enabled></releases>\n      <snapshots><enabled>true</enabled></snapshots>\n    </repository>\n  </repositories>\n  <pluginRepositories>\n    <pluginRepository>\n      <id>sonatype-nexus-snapshot</id>\n      <url>https://oss.sonatype.org/content/repositories/snapshots</url>\n      <releases><enabled>false</enabled></releases>\n      <snapshots><enabled>true</enabled></snapshots>\n    </pluginRepository>\n  </pluginRepositories>\n```\n\n\n### License\n\nThe project coveralls-maven-plugin is licensed under the MIT license.\n"
  },
  {
    "path": "README_2_x.md",
    "content": "coveralls-maven-plugin\n======================\n\n[![Build Status](http://img.shields.io/travis/trautonen/coveralls-maven-plugin/master.svg)](https://travis-ci.org/trautonen/coveralls-maven-plugin)\n[![Coverage Status](http://img.shields.io/coveralls/trautonen/coveralls-maven-plugin/master.svg)](https://coveralls.io/r/trautonen/coveralls-maven-plugin?branch=master)\n\nMaven plugin for submitting Java code coverage reports to [Coveralls](https://coveralls.io/) web\nservice.\n\n\n### Features\n\n* Supports [Cobertura](http://mojo.codehaus.org/cobertura-maven-plugin/),\n  [JaCoCo](http://www.eclemma.org/jacoco/trunk/doc/maven.html) and\n  [Saga](http://timurstrekalov.github.io/saga/) coverage tools\n* Multi-module report aggregation with Cobertura\n* Built-in support for [Travis CI](https://travis-ci.org/), [Circle](https://circleci.com/),\n  [Codeship](https://www.codeship.io/), [Jenkins](http://jenkins-ci.org/) and\n  [Bamboo](https://www.atlassian.com/software/bamboo/) continuous integration services\n* Fully streaming implementation for fast report generation and small memory footprint\n* Provides clean interfaces to allow easy extending to different coverage tools\n* Convention over configuration for almost zero configuration usage\n* Applies [semantic versioning](http://semver.org/)\n\n\n### Usage\n\nSet up the Coveralls maven plugin in the build section of the project pom.xml:\n\n```xml\n<plugin>\n    <groupId>org.eluder.coveralls</groupId>\n    <artifactId>coveralls-maven-plugin</artifactId>\n    <version>2.2.0</version>\n    <configuration>\n        <repoToken>yourcoverallsprojectrepositorytoken</repoToken>\n    </configuration>\n</plugin>\n```\n\n#### Configuration\n\nIf used as a standalone Maven build or with any continuous integration server other than Travis\nCI, the Coveralls repository token must be provided. This can be achieved by setting the\nconfiguration section in the plugin or setting the Maven property `repoToken` to your coveralls project repository token, using\n`-DrepoToken=yourcoverallsprojectrepositorytoken` when running the maven command. **Do not publish\nyour repository token in public GitHub repositories.** If you do, anyone can submit coverage data without permission.\n\nIf you are using Travis CI, Circle, Codeship, Jenkins or Bamboo continuous integration services, no\nother configuration is required. The plugin's built-in service environment support take care of\nthe rest. Multi-module projects that require aggregated reports have to set up Cobertura Maven\nplugin for the root project with `aggregate=true`. For other projects you are free to choose\neither [Cobertura](#cobertura) or [JaCoCo](#jacoco) plugin. Finally add the corresponding Maven\ncommand for the selected plugin to your continuous integration service build job.\n\nSee [Complete plugin configuration](#complete-plugin-configuration) for all of the available\nconfiguration parameters.\n\n\n#### Cobertura\n\nSet up the Cobertura Maven plugin with XML report format in the build section of the project\npom.xml:\n\n```xml\n<plugin>\n    <groupId>org.codehaus.mojo</groupId>\n    <artifactId>cobertura-maven-plugin</artifactId>\n    <version>2.6</version>\n    <configuration>\n        <format>xml</format>\n        <maxmem>256m</maxmem>\n        <!-- aggregated reports for multi-module projects -->\n        <aggregate>true</aggregate>\n    </configuration>\n</plugin>\n```\n\nExecute Maven to create Cobertura report and submit Coveralls data:\n\n```\nmvn cobertura:cobertura coveralls:cobertura\n```\n\nFor example if you are using Travis CI this means you need to add to your `.travis.yml` the lines:\n\n```\nafter_success:\n  - mvn clean cobertura:cobertura coveralls:cobertura\n```\n\n\n#### JaCoCo\n\nSet up the JaCoCo Maven plugin in the build section of the project pom.xml:\n\n```xml\n<plugin>\n    <groupId>org.jacoco</groupId>\n    <artifactId>jacoco-maven-plugin</artifactId>\n    <version>0.7.2.201409121644</version>\n    <executions>\n        <execution>\n            <id>prepare-agent</id>\n            <goals>\n                <goal>prepare-agent</goal>\n            </goals>\n        </execution>\n    </executions>\n</plugin>\n```\n\nExecute Maven to create JaCoCo report and submit Coveralls data:\n\n```\nmvn clean test jacoco:report coveralls:jacoco\n```\n\nAgain, if you are using Travis CI this means you need to add to your `.travis.yml` the lines:\n\n```\nafter_success:\n  - mvn clean test jacoco:report coveralls:jacoco\n```\n\n\n#### Saga\n\nSet up the Saga Maven plugin in the build section of the project pom.xml:\n\n```xml\n<plugin>\n    <groupId>com.github.timurstrekalov</groupId>\n    <artifactId>saga-maven-plugin</artifactId>\n    <version>1.5.2</version>\n    <executions>\n        <execution>\n            <goals>\n                <goal>coverage</goal>\n            </goals>\n        </execution>\n    </executions>\n    <configuration>\n        <baseDir>http://localhost:${jasmine.serverPort}</baseDir>\n        <outputDir>${project.build.directory}/saga-coverage</outputDir>\n        <noInstrumentPatterns>\n            <pattern>.*/spec/.*</pattern>\n        </noInstrumentPatterns>\n    </configuration>\n</plugin>\n```\n\nYou should also set the `sourceUrls` parameter for the plugin to load the sources from Jaasmine\nserver. This allows creating coverage reports also for example CoffeeScript sources:\n\n```xml\n<sourceUrls>\n    <sourceUrl>http://localhost:${jasmine.serverPort}</sourceUrl>\n</sourceUrls>\n```\n\nExecute Maven to create Saga report and submit Coveralls data:\n\n```\nmvn clean test saga:coverage coveralls:saga\n```\n\nAnd if you are using Travis CI this means you need to add to your `.travis.yml` the lines:\n```\nafter_success:\n  - mvn clean test saga:coverage coveralls:saga\n```\n\n\n#### Chain\n\nCreate Coveralls data from multiple coverage tools.\n*Note: The chaining approach will be the default approach for future versions of coveralls maven\nplugin usage. Probably with the difference that the goal is changed from `chain` to `report`.*\n\nConfigure the coverage plugins as described earlier and instead of single coverage tool goal\nuse the `chain` goal to aggregate all coverage sources.\n\nExecute Maven to create Cobertura and Saga report and submit Coveralls data:\n\n```\nmvn clean test saga:coverage cobertura:cobertura coveralls:chain\n```\n\nAnd if you are using Travis CI this means you need to add to your `.travis.yml` the lines:\n\n```\nafter_success:\n  - mvn clean test saga:coverage cobertura:cobertura coveralls:chain\n```\n\n\n### Complete plugin configuration\n\nConfiguration can be changed by the configuration section of plugin's definition in POM or with\nJava virtual machine system properties using the syntax `-Dparameter=value`. See\n[Maven plugin guide](http://maven.apache.org/guides/plugin/guide-java-plugin-development.html#Configuring_Parameters_in_a_Project)\nhow different types are mapped in the configuration XML. Some of the optional parameters are set\nby the built-in service environment setups. Note that if a parameter is explicitly defined, the\nservice environment will not override it.\n\n| Parameter | Type | Description |\n| --------- | ---- | ----------- |\n| `coverallsFile` | `File` | **Default: ${project.build.directory}/coveralls.json**<br>File path to write and submit Coveralls data. |\n| `coverallsUrl` | `String` | **Default: https://coveralls.io/api/v1/jobs**<br>Url for the Coveralls API. |\n| `sourceDirectories` | `List<File>` | List of source directories. If not provided, the plugin will scan the project's compiled source roots. |\n| `sourceUrls` | `List<URL>` | List of source urls. Can be used to load sources from external service, e.g. Jasmine server. |\n| `sourceEncoding` | `String` | **Default: ${project.build.sourceEncoding}**<br>Source file encoding. |\n| `serviceName` | `String` | CI service name. If not provided the supported service environments are used. |\n| `serviceJobId` | `String` | CI service job id. Currently supported only with Travis CI. If this property is set, `repoToken` is not required. If not provided the supported service environments are used. | \n| `serviceBuildNumber` | `String` | CI service build number. If not provided the supported service environments are used. |\n| `serviceBuildUrl` | `String` | CI service build url. If not provided the supported service environments are used. |\n| `serviceEnvironment` | `Properties` | CI service specific environment properties. If not provided the supported service environments are used. |\n| `repoToken` | `String` | Coveralls repository token. **Do not publish this parameter unencrypted in public GitHub repositories.** |\n| `branch` | `String` | Git branch name. If not provided the supported service environments are used. |\n| `pullRequest` | `String` | GitHub pull request identifier. If not provided the supported service environments are used. |\n| `timestamp` | `Date` | **Default: ${timestamp}**<br>Build timestamp. Must be in Maven supported 'yyyy-MM-dd HH:mm:ssa' format. |\n| `dryRun` | `boolean` | **Default: false**<br>Dry run Coveralls report without actually sending it. |\n| `coveralls.skip` | `boolean` | **Default: false**<br>Skip the plugin execution. |\n| `coberturaFile` | `File` | **Default: ${project.reporting.outputDirectory}/cobertura/coverage.xml**<br>Only for `chain` goal. Cobertura report file. |\n| `jacocoFile` | `File` | **Default: ${project.reporting.outputDirectory}/jacoco/jacoco.xml**<br>Only for `chain` goal. JaCoCo report file. |\n| `sagaFile` | `File` | **Default: ${project.build.directory}/saga-coverage/total-coverage.xml**<br>Only for `chain` goal. Saga report file. |\n\n\n### FAQ\n\n> **Q:** How do I know that my coverage report was submitted successfully to Coveralls?  \n> **A:** The plugin will end with BUILD SUCCESS and the log contains the reported job id and\n> direct URL to Coveralls.\n\n<!-- -->\n> **Q:** I get BUILD SUCCESS but why Coveralls shows only question marks in the reports?  \n> **A:** The data is most likely reported correctly, but Coveralls might take hours, or even a\n> day, to update the actual coverage numbers.\n\n<!-- -->\n> **Q:** Build fails with 'javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated'\n> exception, what to do?  \n> **A:** If the build is run with OpenJDK, you probably hit an issue with the Cryptography Package\n> Providers not supporting all Elliptic Curves. The [issue](https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/1006776)\n> is described in the Ubuntu issue tracker. A workaround is to disable the PKCS provider from the\n> `java.security` options file.\n> ```\n> sudo sed -i 's/security.provider.9/#security.provider.9/g' $JAVA_HOME/jre/lib/security/java.security\n> ```\n> In Travis CI the above command can be added to before_install phase. See complete example from\n> this project's `.travis.yml`.\n\n<!-- -->\n> **Q:** How can I use Scala or some other project which sources reside in other folder than\n> `src/main/java`?  \n> **A:** The plugin uses all compiled source roots available for the project at runtime. If the\n> source directories are available, everything is fine. Otherwise the used source directories can\n> be changed with `sourceDirectories` configuration parameter that takes a Maven configuration\n> style list of source directories.\n\n<!-- -->\n> **Q:** How can I set the plugin to use multiple source directories?  \n> **A:** For multi-module projects, the plugin automatically scans the project hierarchy and adds\n> all required source directories. You can also customize the used source directories with\n> `sourceDirectories` configuration parameter that takes a Maven configuration style list of\n> source directories.\n\n<!-- -->\n> **Q:** Why source files are not found for generated sources?  \n> **A:** Generated source directories under target are not added to the sources list\n> automatically. It is often not good practice to test generated code, because the code is not\n> managed by the project under test, unless you are testing a source generator. Cobertura and\n> JaCoCo both have `<excludes>` configuration directive that provides ignoring of class files. If\n> the generated sources still must be tested, all source directories can be explicitly defined\n> with `sourceDirectories` configuration parameter.\n\n<!-- -->\n> **Q:** JaCoCo or Cobertura, which one should i choose?  \n> **A:** For multi-module projects, only Cobertura supports report aggregation out of the box. The\n> coverage metrics and performance of the two plugins are not much different for a small or medium\n> sized project, but there are 2 notable differences with the tools:\n> - JaCoCo does not track how many times a single line of code is hit by all the tests together,\n> so Coveralls is always reported with 1 as the number of hits if the line is covered. Cobertura\n> tracks the number of hits and the number is reported to Coveralls.\n> - Cobertura tracks all inner classes separately, so a single source file will contain multiple\n> records with same file name in Coveralls if there are any innner classes defined. The\n> coveralls-maven-plugin adds classifier from the inner class to distinguish the files, but if\n> there are lot of inner classes defined this creates some noise to the Coveralls reports. JaCoCo\n> tracks inner classes within same source file so each source file is only reported once to\n> Coveralls.\n\n\n### Changelog\n\n#### 2.2.0\n\n- #31: Improved error messages for Coveralls API failures\n- #30: Improved error message for missing charset\n- #28: More lenient XML parsing\n- #26, #29: Support for Saga coverage tool and chain multiple coverage reports\n\n\n#### 2.1.0\n\n- #24: Filter out remote names from git branches\n- #19, #20: Skip configuration property to allow skipping of plugin execution\n\n\n#### 2.0.1\n\n- #18: Update to HttpComponents HttpClient 4.3\n- #15, #16, #17: Disable PKCS cryptography provider at runtime to work around OpenJDK SSL issue\n\n\n#### 2.0.0\n\n- #13: Dry run property for test builds\n- #12: Use ServiceSetup as secondary configuration source and Maven/VM properties as primary\n- #11: Support multiple source directories\n- #9: Support for other CI tools and platforms\n- #8: Aggregated reports for multi-module projects\n\n\n#### 1.2.0\n\n- #10: Validation of the Coveralls job\n- #4: Report build timestamp to Coveralls\n- #3: Log code lines from generated report to Maven console\n\n\n#### 1.1.0\n\n- #1: Easier configuration for Travis CI\n\n\n#### 1.0.0\n\n- Initial release\n\n\n### Migration guide\n\nChanges marked with bold affect the plugin usage. Other changes are only related to development\nand codebase.\n\n\n#### 1.x to 2.x\n\n- **`sourceDirectory` parameter removed and replaced with a list parameter `sourceDirectories`**\n- **service environment parameters do not override configuration parameters**\n- `org.eluder.coveralls.maven.plugin.service.ServiceSetup` interface completely changed to reflect\n  the service specific configuration properly\n- `org.eluder.coveralls.maven.plugin.service.Travis` changed to reflect the new service setup\n  interface\n- `org.eluder.coveralls.maven.plugin.domain.JobValidator` and all validation related code is\n  now located in `org.eluder.coveralls.maven.plugin.validation` package\n- `org.eluder.coveralls.maven.plugin.domain.GitRepository` does not take custom branch parameter\n  as constructor argument anymore, the same behavior is handled with the new service environment\n  setup\n- `org.eluder.coveralls.maven.plugin.domain.Job` has only default constructor and initialization\n  is done with _with*_ methods, _validate()_ method returns list of validation errors instead of\n  throwing exception\n- `org.eluder.coveralls.maven.plugin.domain.SourceLoader` constructor takes a list of source\n  directories instead of a single source directory\n\n\n### Credits\n\n- Jakub Bednář (@bednar) for Saga integration and the idea of chaining multiple reports provided\n  by different coverage tools.\n\n\n### Continuous integration\n\nTravis CI builds the plugin with Oracle JDK 7. All successfully built snapshots are deployed to\nSonatype OSS repository. Cobertura is used to gather coverage metrics and the report is submitted\nto Coveralls with this plugin.\n\n\n### License\n\nThe project coveralls-maven-plugin is licensed under the MIT license.\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.eluder</groupId>\n    <artifactId>eluder-parent</artifactId>\n    <version>9</version>\n  </parent>\n\n  <groupId>org.eluder.coveralls</groupId>\n  <artifactId>coveralls-maven-plugin</artifactId>\n  <version>4.4.0-SNAPSHOT</version>\n  <packaging>maven-plugin</packaging>\n\n  <name>coveralls-maven-plugin</name>\n  <description>Maven plugin for submitting Java code coverage reports to Coveralls web service.</description>\n  <url>https://github.com/trautonen/coveralls-maven-plugin</url>\n  <inceptionYear>2013</inceptionYear>\n\n  <developers>\n    <developer>\n      <name>Tapio Rautonen</name>\n    </developer>\n  </developers>\n\n  <licenses>\n    <license>\n      <name>The MIT License (MIT)</name>\n      <url>http://opensource.org/licenses/MIT</url>\n      <distribution>repo</distribution>\n    </license>\n  </licenses>\n\n  <scm>\n    <connection>scm:git:git://github.com/trautonen/coveralls-maven-plugin.git</connection>\n    <developerConnection>scm:git:git://github.com/trautonen/coveralls-maven-plugin.git</developerConnection>\n    <url>https://github.com/trautonen/coveralls-maven-plugin</url>\n  </scm>\n\n  <properties>\n    <java.version>1.8</java.version>\n    <httpclient.version>4.5.10</httpclient.version>\n    <jackson.version>2.10.0</jackson.version>\n    <jgit.version>4.5.0.201609210915-r</jgit.version>\n    <maven.version>3.5.4</maven.version>\n    <maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>\n    <timestamp>${maven.build.timestamp}</timestamp>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.httpcomponents</groupId>\n      <artifactId>httpclient</artifactId>\n      <exclusions>\n        <exclusion>\n          <artifactId>commons-logging</artifactId>\n          <groupId>commons-logging</groupId>\n        </exclusion>\n      </exclusions>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.httpcomponents</groupId>\n      <artifactId>httpmime</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>commons-codec</groupId>\n      <artifactId>commons-codec</artifactId>\n      <version>1.13</version>\n    </dependency>\n    <dependency>\n      <groupId>com.fasterxml.jackson.core</groupId>\n      <artifactId>jackson-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.fasterxml.jackson.core</groupId>\n      <artifactId>jackson-annotations</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.fasterxml.jackson.core</groupId>\n      <artifactId>jackson-databind</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.eclipse.jgit</groupId>\n      <artifactId>org.eclipse.jgit</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.codehaus.plexus</groupId>\n      <artifactId>plexus-utils</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.maven</groupId>\n      <artifactId>maven-plugin-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.maven</groupId>\n      <artifactId>maven-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.maven.plugin-tools</groupId>\n      <artifactId>maven-plugin-annotations</artifactId>\n      <version>3.5.2</version>\n      <scope>provided</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.slf4j</groupId>\n      <artifactId>slf4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.slf4j</groupId>\n      <artifactId>jcl-over-slf4j</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.hamcrest</groupId>\n      <artifactId>hamcrest-all</artifactId>\n      <version>1.3</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-lang3</artifactId>\n      <version>3.9</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.github.tomakehurst</groupId>\n      <artifactId>wiremock</artifactId>\n      <version>2.25.1</version>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <dependencyManagement>\n    <dependencies>\n      <dependency>\n        <groupId>org.apache.httpcomponents</groupId>\n        <artifactId>httpclient</artifactId>\n        <version>${httpclient.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.httpcomponents</groupId>\n        <artifactId>httpmime</artifactId>\n        <version>${httpclient.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>com.fasterxml.jackson.core</groupId>\n        <artifactId>jackson-core</artifactId>\n        <version>${jackson.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>com.fasterxml.jackson.core</groupId>\n        <artifactId>jackson-annotations</artifactId>\n        <version>${jackson.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>com.fasterxml.jackson.core</groupId>\n        <artifactId>jackson-databind</artifactId>\n        <version>${jackson.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.eclipse.jgit</groupId>\n        <artifactId>org.eclipse.jgit</artifactId>\n        <version>${jgit.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-plugin-api</artifactId>\n        <version>${maven.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-model</artifactId>\n        <version>${maven.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-artifact</artifactId>\n        <version>${maven.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-core</artifactId>\n        <version>${maven.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-settings</artifactId>\n        <version>${maven.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-settings-builder</artifactId>\n        <version>${maven.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-repository-metadata</artifactId>\n        <version>${maven.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-model-builder</artifactId>\n        <version>${maven.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.sonatype.sisu</groupId>\n        <artifactId>sisu-inject-plexus</artifactId>\n        <version>1.4.3.2</version>\n      </dependency>\n      <dependency>\n        <groupId>org.codehaus.plexus</groupId>\n        <artifactId>plexus-utils</artifactId>\n        <version>2.0.7</version>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-plugin-plugin</artifactId>\n        <version>3.5.2</version>\n        <configuration>\n          <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>\n        </configuration>\n        <executions>\n          <execution>\n            <id>mojo-descriptor</id>\n            <goals>\n              <goal>descriptor</goal>\n            </goals>\n          </execution>\n          <execution>\n            <id>help-goal</id>\n            <goals>\n              <goal>helpmojo</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.codehaus.mojo</groupId>\n        <artifactId>cobertura-maven-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <groupId>org.eluder.coveralls</groupId>\n        <artifactId>coveralls-maven-plugin</artifactId>\n        <version>${project.version}</version>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-checkstyle-plugin</artifactId>\n      </plugin>\n    </plugins>\n\n    <pluginManagement>\n      <plugins>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-jar-plugin</artifactId>\n          <version>2.6</version>\n        </plugin>\n        <plugin>\n          <groupId>org.codehaus.mojo</groupId>\n          <artifactId>cobertura-maven-plugin</artifactId>\n          <version>${maven.cobertura.version}</version>\n          <configuration>\n            <instrumentation>\n              <excludes>\n                <exclude>**/HelpMojo.class</exclude>\n              </excludes>\n            </instrumentation>\n          </configuration>\n        </plugin>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-checkstyle-plugin</artifactId>\n          <version>2.17</version>\n          <configuration>\n            <excludes>**/HelpMojo.java</excludes>\n          </configuration>\n        </plugin>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-javadoc-plugin</artifactId>\n          <version>${maven.javadoc.version}</version>\n          <configuration>\n            <sourcepath>${project.basedir}/src/main/java</sourcepath>\n          </configuration>\n        </plugin>\n        <plugin>\n          <groupId>org.codehaus.mojo</groupId>\n          <artifactId>license-maven-plugin</artifactId>\n          <version>${maven.license.version}</version>\n          <configuration>\n            <excludes>\n              <exclude>**/cobertura.xml</exclude>\n              <exclude>**/jacoco1.xml</exclude>\n              <exclude>**/jacoco2.xml</exclude>\n              <exclude>**/SimpleCoverage.java</exclude>\n              <exclude>**/InnerClassCoverage.java</exclude>\n              <exclude>**/PartialCoverage.java</exclude>\n              <exclude>**/saga.xml</exclude>\n              <exclude>**/Components.js</exclude>\n              <exclude>**/Localization.js</exclude>\n            </excludes>\n          </configuration>\n        </plugin>\n      </plugins>\n    </pluginManagement>\n  </build>\n</project>\n"
  },
  {
    "path": "sample/README.md",
    "content": "Coverage samples\n================\n\n### Cobertura\n\n```\nmvn -Pcobertura clean cobertura:cobertura\n```\n\n\n### JaCoCo\n\n```\nmvn -Pjacoco clean verify jacoco:report\n```\n\n\n### Saga\n\n```\nmvn -Psaga clean test saga:coverage\n```\n"
  },
  {
    "path": "sample/module1/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  \n  <parent>\n    <artifactId>sample</artifactId>\n    <groupId>org.eluder.coverage</groupId>\n    <version>1.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>module1</artifactId>\n  <version>1.0-SNAPSHOT</version>\n  <packaging>jar</packaging>\n\n\n</project>"
  },
  {
    "path": "sample/module1/src/main/java/org/eluder/coverage/sample/InnerClassCoverage.java",
    "content": "package org.eluder.coverage.sample;\n\npublic class InnerClassCoverage {\n\n    public void anonymous() {\n        InnerClass i = new InnerClass() {\n            @Override\n            public void run() {\n                System.out.println(\"overridden\");\n            }\n        };\n        i.run();\n    }\n    \n    public boolean delegate() {\n        return new InnerClass().isInner();\n    }\n    \n    public static class InnerClass {\n        \n        public boolean isInner() {\n            return true;\n        }\n        \n        public void run() {\n            System.out.println(\"run\");\n        }\n    }\n    \n}\n"
  },
  {
    "path": "sample/module1/src/main/java/org/eluder/coverage/sample/SimpleCoverage.java",
    "content": "package org.eluder.coverage.sample;\n\npublic class SimpleCoverage {\n\n    public boolean isTested() {\n        return false;\n    }\n    \n    public void neverRun() {\n        System.out.println(\"oops\");\n    }\n    \n}\n"
  },
  {
    "path": "sample/module1/src/main/resources/Components.js",
    "content": "(function() {\n  this.Components = {};\n\n}).call(this);\n"
  },
  {
    "path": "sample/module1/src/main/resources/Localization.js",
    "content": "(function() {\n  var Localization;\n\n  Localization = (function() {\n    function Localization(values) {\n      this.values = values;\n    }\n\n    Localization.prototype.byKey = function(key) {\n      return this.values[key];\n    };\n\n    return Localization;\n\n  })();\n\n}).call(this);\n"
  },
  {
    "path": "sample/module1/src/test/java/org/eluder/coverage/sample/InnerClassCoverageTest.java",
    "content": "package org.eluder.coverage.sample;\n\nimport org.junit.Test;\n\npublic class InnerClassCoverageTest {\n\n    @Test\n    public void testAnonymous() {\n        new InnerClassCoverage().anonymous();\n    }\n    \n    @Test\n    public void testDelegate() {\n        new InnerClassCoverage().delegate();\n    }\n    \n}\n"
  },
  {
    "path": "sample/module1/src/test/java/org/eluder/coverage/sample/SimpleCoverageTest.java",
    "content": "package org.eluder.coverage.sample;\n\nimport org.junit.Test;\n\npublic class SimpleCoverageTest {\n\n    @Test\n    public void test() {\n        new SimpleCoverage().isTested();\n    }\n    \n}\n"
  },
  {
    "path": "sample/module1/src/test/specs/ComponentsSpec.coffee",
    "content": "describe 'Components testing', ->\n\n    it 'Components object on window not null', ->\n\n        expect(window.Components).not.toBe(null)\n"
  },
  {
    "path": "sample/module2/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  \n  <parent>\n    <artifactId>sample</artifactId>\n    <groupId>org.eluder.coverage</groupId>\n    <version>1.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>module2</artifactId>\n  <version>1.0-SNAPSHOT</version>\n  <packaging>jar</packaging>\n\n\n</project>"
  },
  {
    "path": "sample/module2/src/main/java/org/eluder/coverage/sample/PartialCoverage.java",
    "content": "package org.eluder.coverage.sample;\n\npublic class PartialCoverage {\n    \n    public void partial(boolean test) {\n        if (test) {\n            System.out.println(\"test\");\n        } else {\n            System.out.println(\"not test\");\n        }\n    }\n    \n}\n"
  },
  {
    "path": "sample/module2/src/test/java/org/eluder/coverage/sample/PartialCoverageIT.java",
    "content": "package org.eluder.coverage.sample;\n\nimport org.junit.Test;\n\npublic class PartialCoverageIT {\n\n    @Test\n    public void testSum() {\n        new PartialCoverage().partial(false);\n    }\n\n}\n"
  },
  {
    "path": "sample/module2/src/test/java/org/eluder/coverage/sample/PartialCoverageTest.java",
    "content": "package org.eluder.coverage.sample;\n\nimport org.junit.Test;\n\npublic class PartialCoverageTest {\n\n    @Test\n    public void testPartial() {\n        new PartialCoverage().partial(true);\n    }\n    \n}\n"
  },
  {
    "path": "sample/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.eluder</groupId>\n    <artifactId>eluder-parent</artifactId>\n    <version>9</version>\n    <relativePath></relativePath>\n  </parent>\n\n  <groupId>org.eluder.coverage</groupId>\n  <artifactId>sample</artifactId>\n  <version>1.0-SNAPSHOT</version>\n  <packaging>pom</packaging>\n\n  <prerequisites>\n    <maven>3.1.0</maven>\n  </prerequisites>\n\n  <properties>\n    <maven.jacoco.version>0.8.1</maven.jacoco.version>\n    <maven.cobertura.version>2.7</maven.cobertura.version>\n    <maven.jasmine.version>2.2</maven.jasmine.version>\n    <maven.saga.version>1.5.5</maven.saga.version>\n  </properties>\n\n  <modules>\n    <module>module1</module>\n    <module>module2</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.eluder.coveralls</groupId>\n        <artifactId>coveralls-maven-plugin</artifactId>\n        <version>4.3.0</version>\n        <configuration>\n          <sourceDirectories>\n            <sourceDirectory>module1/src/main/resources</sourceDirectory>\n          </sourceDirectories>\n        </configuration>\n      </plugin>\n      <plugin>\n        <artifactId>maven-surefire-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <artifactId>maven-failsafe-plugin</artifactId>\n      </plugin>\n    </plugins>\n    <pluginManagement>\n      <plugins>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-jar-plugin</artifactId>\n          <version>2.6</version>\n        </plugin>\n      </plugins>\n    </pluginManagement>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>cobertura</id>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.codehaus.mojo</groupId>\n            <artifactId>cobertura-maven-plugin</artifactId>\n            <version>${maven.cobertura.version}</version>\n            <executions>\n              <execution>\n                <goals>\n                  <goal>cobertura</goal>\n                </goals>\n              </execution>\n            </executions>\n            <configuration>\n              <aggregate>true</aggregate>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n    <profile>\n      <id>jacoco</id>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.jacoco</groupId>\n            <artifactId>jacoco-maven-plugin</artifactId>\n            <version>${maven.jacoco.version}</version>\n            <executions>\n              <execution>\n                <id>default-prepare-agent</id>\n                <goals>\n                  <goal>prepare-agent</goal>\n                </goals>\n              </execution>\n              <execution>\n                <id>default-prepare-agent-integration</id>\n                <goals>\n                  <goal>prepare-agent-integration</goal>\n                </goals>\n              </execution>\n              <execution>\n                <id>default-report</id>\n                <goals>\n                  <goal>report</goal>\n                </goals>\n              </execution>\n              <execution>\n                <id>default-report-integration</id>\n                <goals>\n                  <goal>report-integration</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n    <profile>\n      <id>saga</id>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>com.github.searls</groupId>\n            <artifactId>jasmine-maven-plugin</artifactId>\n            <version>${maven.jasmine.version}</version>\n            <executions>\n              <execution>\n                <goals>\n                  <goal>test</goal>\n                </goals>\n              </execution>\n            </executions>\n            <configuration>\n              <jsSrcDir>${project.basedir}/src/main/resources/</jsSrcDir>\n              <jsTestSrcDir>${project.basedir}/src/test/specs</jsTestSrcDir>\n              <keepServerAlive>true</keepServerAlive>\n              <webDriverClassName>org.openqa.selenium.htmlunit.HtmlUnitDriver</webDriverClassName>\n            </configuration>\n          </plugin>\n          <plugin>\n            <groupId>com.github.timurstrekalov</groupId>\n            <artifactId>saga-maven-plugin</artifactId>\n            <version>${maven.saga.version}</version>\n            <executions>\n              <execution>\n                <goals>\n                  <goal>coverage</goal>\n                </goals>\n              </execution>\n            </executions>\n            <configuration>\n              <baseDir>http://localhost:${jasmine.serverPort}</baseDir>\n              <outputDir>${project.build.directory}/saga-coverage</outputDir>\n              <noInstrumentPatterns>\n                <pattern>.*/spec/.*</pattern>\n                <pattern>.*/classpath/.*</pattern>\n                <pattern>.*/webjars/.*</pattern>\n              </noInstrumentPatterns>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>"
  },
  {
    "path": "scripts/bump-version.sh",
    "content": "#!/bin/bash\n\nif [ $# -ne 1 ]\nthen\n    echo \"Invalid number of arguments\"\n    echo \"USAGE: $0 <version>\"\n    exit 1\nfi\n\nversion=$1\nscript_dir=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\nworking_dir=\"$( pwd )\"\nfiles=( \"pom.xml\" \"README.md\" )\n\nsource $script_dir/functions.sh\n\nif ! ( contains_files ${files[@]} )\nthen\n    working_dir=$working_dir/..\n    cd $working_dir\nfi\n\nif ! ( contains_files ${files[@]} )\nthen\n    echo \"Some of the required files (${files[@]}) not found, aborting version bump\"\n    exit 1\nfi\n\necho \"Updating version to $version in all poms\"\nmvn versions:set -DnewVersion=$version > /dev/null\nmvn versions:commit > /dev/null\n\nif [[ \"$version\" != *-SNAPSHOT ]]; then\n    echo \"Replacing version numbers in readme\"\n    sed -n -i '1h;1!H;${;g;s,<artifactId>coveralls-maven-plugin</artifactId>\\n    <version>[^<]*</version>,<artifactId>coveralls-maven-plugin</artifactId>\\n    <version>'\"$version\"'</version>,g;p;}' README.md\nfi\n\necho \"Committing version changes\"\ngit add ${files[@]}\ngit commit -m \"Updated to version $version.\"\n"
  },
  {
    "path": "scripts/functions.sh",
    "content": "#!/bin/bash\n\ncontains_files()\n{\n    for file in \"$@\"\n    do\n        if ! [ -f $file ]\n        then\n            return 1\n        fi\n    done\n    return 0\n}\n"
  },
  {
    "path": "scripts/release.sh",
    "content": "#!/bin/bash\n\nscript_dir=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\nworking_dir=\"$( pwd )\"\nfiles=( \"pom.xml\" \"README.md\" )\n\nsource $script_dir/functions.sh\n\nif ! ( contains_files ${files[@]} )\nthen\n    working_dir=$working_dir/..\n    cd $working_dir\nfi\n\nif ! ( contains_files ${files[@]} )\nthen\n    echo \"Some of the required files (${files[@]}) not found, aborting release\"\n    exit 1\nfi\n\necho -n \"Enter release version: \"\nread release_version\n\necho -n \"Enter new development version: \"\nread develop_version\n\necho -n \"Enter GPG passphrase: \"\nstty_orig=$(stty -g)\nstty -echo \nread passphrase\nstty $stty_orig\n\necho \"$passphrase\" | gpg --passphrase-fd 0 --armor --output pom.xml.asc --detach-sig pom.xml > /dev/null\ngpg --verify pom.xml.asc > /dev/null\nif [ $? -ne 0 ]; then\n    echo \"Seems that the GPG passphrase was invalid\"\n    exit $?\nfi\nrm pom.xml.asc\n\necho \"\"\necho \"Starting release process for $release_version\"\necho \"Working in $( pwd )\"\necho \"Press return to continue or CTRL-C to abort\"\nread\n\necho \"Cleaning project\"\nmvn clean > /dev/null\n\necho \"Updating license information\"\nmvn license:update-project-license license:update-file-header > /dev/null\ngit add -A\ngit commit -m \"Updated license information.\"\n\n$script_dir/bump-version.sh $release_version\n\necho \"Creating tag for v$release_version\"\ngit tag -a v$release_version -m \"coveralls-maven-plugin version $release_version\"\ngit checkout v$release_version\n\necho \"\"\necho \"If everything went fine artifacts can be deployed to staging repository\"\necho \"After artifacts are deployed, login to https://oss.sonatype.org/ and complete the release\"\necho \"Press return to continue deploying or CTRL-C to abort\"\nread\n\nmvn -Pprepare-deploy,prepare-release -Dgpg.passphrase=$passphrase clean deploy\n\necho \"\"\necho \"Preparing for next development version $develop_version\"\ngit checkout master\n$script_dir/bump-version.sh $develop_version\n\necho \"\"\necho \"Pushing everything to origin\"\ngit push origin\ngit push origin --tags\n\necho \"\"\necho \"Release completed for $release_version, current development version is $develop_version!\"\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/CoverageParser.java",
    "content": "package org.eluder.coveralls.maven.plugin;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\n\n\n/**\n * Handles parsing of a coverage report. The implemenation can be statefull, and the same instance\n * should be used only one time to parse a coverage report. Completed source files are passed to\n * the {@link org.eluder.coveralls.maven.plugin.source.SourceCallback} handler. To maximize performance, the parser should use streaming.\n */\npublic interface CoverageParser {\n\n    /**\n     * Parses a coverage report. Parsed source files are passed to the callback handler. This\n     * method should be called only once per instance.\n     * \n     * @param callback the source callback handler\n     * @throws ProcessingException if processing of the coverage report fails\n     * @throws IOException if an I/O error occurs\n     */\n    void parse(SourceCallback callback) throws ProcessingException, IOException;\n    \n    /**\n     * @return the coverage report file under processing\n     */\n    File getCoverageFile();\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/CoverallsReportMojo.java",
    "content": "package org.eluder.coveralls.maven.plugin;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.plugin.AbstractMojo;\nimport org.apache.maven.plugin.MojoExecutionException;\nimport org.apache.maven.plugin.MojoFailureException;\nimport org.apache.maven.plugins.annotations.Component;\nimport org.apache.maven.plugins.annotations.Mojo;\nimport org.apache.maven.plugins.annotations.Parameter;\nimport org.apache.maven.project.MavenProject;\nimport org.apache.maven.settings.Settings;\nimport org.eluder.coveralls.maven.plugin.domain.CoverallsResponse;\nimport org.eluder.coveralls.maven.plugin.domain.Git;\nimport org.eluder.coveralls.maven.plugin.domain.GitRepository;\nimport org.eluder.coveralls.maven.plugin.domain.Job;\nimport org.eluder.coveralls.maven.plugin.httpclient.CoverallsClient;\nimport org.eluder.coveralls.maven.plugin.httpclient.CoverallsProxyClient;\nimport org.eluder.coveralls.maven.plugin.json.JsonWriter;\nimport org.eluder.coveralls.maven.plugin.logging.CoverageTracingLogger;\nimport org.eluder.coveralls.maven.plugin.logging.DryRunLogger;\nimport org.eluder.coveralls.maven.plugin.logging.JobLogger;\nimport org.eluder.coveralls.maven.plugin.logging.Logger;\nimport org.eluder.coveralls.maven.plugin.logging.Logger.Position;\nimport org.eluder.coveralls.maven.plugin.service.Appveyor;\nimport org.eluder.coveralls.maven.plugin.service.Bamboo;\nimport org.eluder.coveralls.maven.plugin.service.Circle;\nimport org.eluder.coveralls.maven.plugin.service.General;\nimport org.eluder.coveralls.maven.plugin.service.Jenkins;\nimport org.eluder.coveralls.maven.plugin.service.ServiceSetup;\nimport org.eluder.coveralls.maven.plugin.service.Shippable;\nimport org.eluder.coveralls.maven.plugin.service.Travis;\nimport org.eluder.coveralls.maven.plugin.service.Wercker;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\nimport org.eluder.coveralls.maven.plugin.source.UniqueSourceCallback;\nimport org.eluder.coveralls.maven.plugin.util.CoverageParsersFactory;\nimport org.eluder.coveralls.maven.plugin.util.SourceLoaderFactory;\nimport org.eluder.coveralls.maven.plugin.util.TimestampParser;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\n\n@Mojo(name = \"report\", threadSafe = false, aggregator = true)\npublic class CoverallsReportMojo extends AbstractMojo {\n\n    /**\n     * File paths to additional JaCoCo coverage report files.\n     */\n    @Parameter(property = \"jacocoReports\")\n    protected List<File> jacocoReports;\n\n    /**\n     * File paths to additional Cobertura coverage report files.\n     */\n    @Parameter(property = \"coberturaReports\")\n    protected List<File> coberturaReports;\n\n    /**\n     * File paths to additional Saga coverage report files.\n     */\n    @Parameter(property = \"sagaReports\")\n    protected List<File> sagaReports;\n\n    /**\n     * Directories for relative per module specific report files.\n     */\n    @Parameter(property = \"relativeReportDirs\")\n    protected List<String> relativeReportDirs;\n\n    /**\n     * File path to write and submit Coveralls data.\n     */\n    @Parameter(property = \"coverallsFile\", defaultValue = \"${project.build.directory}/coveralls.json\")\n    protected File coverallsFile;\n    \n    /**\n     * Url for the Coveralls API.\n     */\n    @Parameter(property = \"coverallsUrl\", defaultValue = \"https://coveralls.io/api/v1/jobs\")\n    protected String coverallsUrl;\n\n    /**\n     * Source directories.\n     */\n    @Parameter(property = \"sourceDirectories\")\n    protected List<File> sourceDirectories;\n    \n    /**\n     * Source file encoding.\n     */\n    @Parameter(property = \"sourceEncoding\", defaultValue = \"${project.build.sourceEncoding}\")\n    protected String sourceEncoding;\n    \n    /**\n     * CI service name.\n     */\n    @Parameter(property = \"serviceName\")\n    protected String serviceName;\n    \n    /**\n     * CI service job id.\n     */\n    @Parameter(property = \"serviceJobId\")\n    protected String serviceJobId;\n    \n    /**\n     * CI service build number.\n     */\n    @Parameter(property = \"serviceBuildNumber\")\n    protected String serviceBuildNumber;\n    \n    /**\n     * CI service build url.\n     */\n    @Parameter(property = \"serviceBuildUrl\")\n    protected String serviceBuildUrl;\n    \n    /**\n     * CI service specific environment properties.\n     */\n    @Parameter(property = \"serviceEnvironment\")\n    protected Properties serviceEnvironment;\n    \n    /**\n     * Coveralls repository token.\n     */\n    @Parameter(property = \"repoToken\")\n    protected String repoToken;\n    \n    /**\n     * Git branch name.\n     */\n    @Parameter(property = \"branch\")\n    protected String branch;\n\n    /**\n     * GitHub pull request identifier.\n     */\n    @Parameter(property = \"pullRequest\")\n    protected String pullRequest;\n\n    /**\n     * Coveralls parallel flag.\n     */\n    @Parameter(property = \"parallel\")\n    protected boolean parallel;\n\n    /**\n     * Build timestamp format. Must be in format supported by SimpleDateFormat.\n     */\n    @Parameter(property = \"timestampFormat\", defaultValue = \"${maven.build.timestamp.format}\")\n    protected String timestampFormat;\n\n    /**\n     * Build timestamp. Must be in format defined by 'timestampFormat' if it's available or in\n     * default timestamp format yyyy-MM-dd'T'HH:mm:ss'Z'.\n     */\n    @Parameter(property = \"timestamp\", defaultValue = \"${maven.build.timestamp}\")\n    protected String timestamp;\n    \n    /**\n     * Dry run Coveralls report without actually sending it.\n     */\n    @Parameter(property = \"dryRun\", defaultValue = \"false\")\n    protected boolean dryRun;\n\n    /**\n     * Fail build if Coveralls service is not available or submission fails for internal errors.\n     */\n    @Parameter(property = \"failOnServiceError\", defaultValue = \"true\")\n    protected boolean failOnServiceError;\n\n    /**\n     * Scan subdirectories for source files.\n     */\n    @Parameter(property = \"scanForSources\", defaultValue = \"false\")\n    protected boolean scanForSources;\n\n    /**\n     * Base directory of the project.\n     */\n    @Parameter(property = \"coveralls.basedir\", defaultValue = \"${project.basedir}\")\n    protected File basedir;\n\n    /**\n     * Skip the plugin execution.\n     */\n    @Parameter(property = \"coveralls.skip\", defaultValue = \"false\")\n    protected boolean skip;\n\n\n    /**\n     * Maven settings.\n     */\n    @Parameter(defaultValue = \"${settings}\", readonly = true, required = true)\n    protected Settings settings;\n\n    /**\n     * Maven project for runtime value resolution.\n     */\n    @Component\n    protected MavenProject project;\n\n\n    @Override\n    public final void execute() throws MojoExecutionException, MojoFailureException {\n        if (skip) {\n            getLog().info(\"Skip property set, skipping plugin execution\");\n            return;\n        }\n        \n        try {\n            createEnvironment().setup();\n            Job job = createJob();\n            job.validate().throwOrInform(getLog());\n            SourceLoader sourceLoader = createSourceLoader(job);\n            List<CoverageParser> parsers = createCoverageParsers(sourceLoader);\n            JsonWriter writer = createJsonWriter(job);\n            CoverallsClient client = createCoverallsClient();\n            List<Logger> reporters = new ArrayList<>();\n            reporters.add(new JobLogger(job));\n            SourceCallback sourceCallback = createSourceCallbackChain(writer, reporters);\n            reporters.add(new DryRunLogger(job.isDryRun(), writer.getCoverallsFile()));\n            \n            report(reporters, Position.BEFORE);\n            writeCoveralls(writer, sourceCallback, parsers);\n            report(reporters, Position.AFTER);\n            \n            if (!job.isDryRun()) {\n                submitData(client, writer.getCoverallsFile());\n            }\n        } catch (ProcessingException ex) {\n            throw new MojoFailureException(\"Processing of input or output data failed\", ex);\n        } catch (IOException ex) {\n            throw new MojoFailureException(\"I/O operation failed\", ex);\n        } catch (Exception ex) {\n            throw new MojoExecutionException(\"Build error\", ex);\n        }\n    }\n\n    /**\n     * \n     * @param sourceLoader source loader that extracts source files\n     * @return coverage parsers for all maven modules and additional reports\n     * @throws IOException if parsers cannot be created\n     */\n    protected List<CoverageParser> createCoverageParsers(final SourceLoader sourceLoader) throws IOException {\n        return new CoverageParsersFactory(project, sourceLoader)\n                .withJaCoCoReports(jacocoReports)\n                .withCoberturaReports(coberturaReports)\n                .withSagaReports(sagaReports)\n                .withRelativeReportDirs(relativeReportDirs)\n                .createParsers();\n    }\n    \n    /**\n     * @return source loader that extracts source files\n     * \n     * @param job the job describing the coveralls report\n     */\n    protected SourceLoader createSourceLoader(final Job job) {\n        return new SourceLoaderFactory(job.getGit().getBaseDir(), project, sourceEncoding)\n                .withSourceDirectories(sourceDirectories)\n                .withScanForSources(scanForSources)\n                .createSourceLoader();\n    }\n\n    /**\n     * @return environment to setup mojo and service specific properties\n     */\n    protected Environment createEnvironment() {\n        return new Environment(this, getServices());\n    }\n    \n    /**\n     * @return list of available continuous integration services\n     */\n    protected List<ServiceSetup> getServices() {\n        Map<String, String> env = System.getenv();\n        List<ServiceSetup> services = new ArrayList<>();\n        services.add(new Shippable(env));\n        services.add(new Travis(env));\n        services.add(new Circle(env));\n        services.add(new Jenkins(env));\n        services.add(new Bamboo(env));\n        services.add(new Appveyor(env));\n        services.add(new Wercker(env));\n        services.add(new General(env));\n        return services;\n    }\n    \n    /**\n     * @return job that describes the coveralls report\n     * @throws ProcessingException if processing of timestamp fails\n     * @throws IOException if an I/O error occurs\n     */\n    protected Job createJob() throws ProcessingException, IOException {\n        Git git = new GitRepository(basedir).load();\n        Date time = new TimestampParser(timestampFormat).parse(timestamp);\n        return new Job()\n            .withRepoToken(repoToken)\n            .withServiceName(serviceName)\n            .withServiceJobId(serviceJobId)\n            .withServiceBuildNumber(serviceBuildNumber)\n            .withServiceBuildUrl(serviceBuildUrl)\n            .withParallel(parallel)\n            .withServiceEnvironment(serviceEnvironment)\n            .withDryRun(dryRun)\n            .withBranch(branch)\n            .withPullRequest(pullRequest)\n            .withTimestamp(time)\n            .withGit(git);\n    }\n    \n    /**\n     * @param job the job describing the coveralls report\n     * @return JSON writer that writes the coveralls data\n     * @throws IOException if an I/O error occurs\n     */\n    protected JsonWriter createJsonWriter(final Job job) throws IOException {\n        return new JsonWriter(job, coverallsFile);\n    }\n    \n    /**\n     * @return http client that submits the coveralls data\n     */\n    protected CoverallsClient createCoverallsClient() {\n        return new CoverallsProxyClient(coverallsUrl, settings.getActiveProxy());\n    }\n    \n    /**\n     * @param writer the JSON writer\n     * @param reporters the logging reporters\n     * @return source callback chain for different source handlers\n     */\n    protected SourceCallback createSourceCallbackChain(final JsonWriter writer, final List<Logger> reporters) {\n        SourceCallback chain = writer;\n        if (getLog().isInfoEnabled()) {\n            CoverageTracingLogger coverageTracingReporter = new CoverageTracingLogger(chain);\n            chain = coverageTracingReporter;\n            reporters.add(coverageTracingReporter);\n        }\n        chain = new UniqueSourceCallback(chain);\n        return chain;\n    }\n\n    /**\n     * Writes coverage data to JSON file.\n     *\n     * @param writer JSON writer that writes the coveralls data\n     * @param sourceCallback the source callback handler\n     * @param parsers list of coverage parsers\n     * @throws ProcessingException if process to to create JSON file fails\n     * @throws IOException if an I/O error occurs\n     */\n    protected void writeCoveralls(final JsonWriter writer, final SourceCallback sourceCallback, final List<CoverageParser> parsers) throws ProcessingException, IOException {\n        try {\n            getLog().info(\"Writing Coveralls data to \" + writer.getCoverallsFile().getAbsolutePath() + \"...\");\n            long now = System.currentTimeMillis();\n            sourceCallback.onBegin();\n            for (CoverageParser parser : parsers) {\n                getLog().info(\"Processing coverage report from \" + parser.getCoverageFile().getAbsolutePath());\n                parser.parse(sourceCallback);\n            }\n            sourceCallback.onComplete();\n            long duration = System.currentTimeMillis() - now;\n            getLog().info(\"Successfully wrote Coveralls data in \" + duration + \"ms\");\n        } finally {\n            writer.close();\n        }\n    }\n    \n    private void submitData(final CoverallsClient client, final File coverallsFile) throws ProcessingException, IOException {\n        getLog().info(\"Submitting Coveralls data to API\");\n        long now = System.currentTimeMillis();\n        try {\n            CoverallsResponse response = client.submit(coverallsFile);\n            long duration = System.currentTimeMillis() - now;\n            getLog().info(\"Successfully submitted Coveralls data in \" + duration + \"ms for \" + response.getMessage());\n            getLog().info(response.getUrl());\n            getLog().info(\"*** It might take hours for Coveralls to update the actual coverage numbers for a job\");\n            getLog().info(\"    If you see question marks in the report, please be patient\");\n        } catch (ProcessingException ex) {\n            long duration = System.currentTimeMillis() - now;\n            String message = \"Submission failed in \" + duration + \"ms while processing data\";\n            handleSubmissionError(ex, message, true);\n        } catch (IOException ex) {\n            long duration = System.currentTimeMillis() - now;\n            String message = \"Submission failed in \" + duration + \"ms while handling I/O operations\";\n            handleSubmissionError(ex, message, failOnServiceError);\n        }\n    }\n\n    private <T extends Exception> void handleSubmissionError(final T ex, final String message, final boolean failOnException) throws T {\n        if (failOnException) {\n            getLog().error(message);\n            throw ex;\n        } else {\n            getLog().warn(message);\n        }\n    }\n    \n    private void report(final List<Logger> reporters, final Position position) {\n        for (Logger reporter : reporters) {\n            if (position.equals(reporter.getPosition())) {\n                reporter.log(getLog());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/Environment.java",
    "content": "package org.eluder.coveralls.maven.plugin;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.util.Properties;\n\nimport org.codehaus.plexus.util.StringUtils;\nimport org.eluder.coveralls.maven.plugin.service.ServiceSetup;\n\n/**\n * Constructs and setups the project environment and continuous integration service.\n */\npublic final class Environment {\n    \n    private final CoverallsReportMojo mojo;\n    private final Iterable<ServiceSetup> services;\n\n    public Environment(final CoverallsReportMojo mojo, final Iterable<ServiceSetup> services) {\n        if (mojo == null) {\n            throw new IllegalArgumentException(\"mojo must be defined\");\n        }\n        if (services == null) {\n            throw new IllegalArgumentException(\"services must be defined\");\n        }\n        this.mojo = mojo;\n        this.services = services;\n    }\n    \n    public void setup() {\n        setupService();\n        verify();\n    }\n    \n    private void verify() {\n        if (mojo.sourceEncoding == null) {\n            throw new IllegalArgumentException(\"Source encoding not set, use <sourceEncoding> configuration option or set project wide property <project.build.sourceEncoding>\");\n        }\n    }\n    \n    private void setupService() {\n        for (ServiceSetup service : services) {\n            if (service.isSelected()) {\n                setupEnvironment(service);\n                break;\n            }\n        }\n    }\n    \n    private void setupEnvironment(final ServiceSetup service) {\n        String name = service.getName();\n        if (StringUtils.isBlank(mojo.serviceName) && StringUtils.isNotBlank(name)) {\n            mojo.serviceName = name;\n        }\n        \n        String jobId = service.getJobId();\n        if (StringUtils.isBlank(mojo.serviceJobId) && StringUtils.isNotBlank(jobId)) {\n            mojo.serviceJobId = jobId;\n        }\n        \n        String buildNumber = service.getBuildNumber();\n        if (StringUtils.isBlank(mojo.serviceBuildNumber) && StringUtils.isNotBlank(buildNumber)) {\n            mojo.serviceBuildNumber = buildNumber;\n        }\n        \n        String buildUrl = service.getBuildUrl();\n        if (StringUtils.isBlank(mojo.serviceBuildUrl) && StringUtils.isNotBlank(buildUrl)) {\n            mojo.serviceBuildUrl = buildUrl;\n        }\n        \n        String branch = service.getBranch();\n        if (StringUtils.isBlank(mojo.branch) && StringUtils.isNotBlank(branch)) {\n            mojo.branch = branch;\n        }\n        \n        String pullRequest = service.getPullRequest();\n        if (StringUtils.isBlank(mojo.pullRequest) && StringUtils.isNotBlank(pullRequest)) {\n            mojo.pullRequest = pullRequest;\n        }\n        \n        Properties environment = service.getEnvironment();\n        if ((mojo.serviceEnvironment == null || mojo.serviceEnvironment.isEmpty()) &&\n                (environment != null && !environment.isEmpty())) {\n            mojo.serviceEnvironment = environment;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/ProcessingException.java",
    "content": "package org.eluder.coveralls.maven.plugin;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\n/**\n * Exception to indicate if processing of input or output data fails.\n */\npublic class ProcessingException extends Exception {\n\n    public ProcessingException() {\n        super();\n    }\n\n    public ProcessingException(final String message) {\n        super(message);\n    }\n\n    public ProcessingException(final Throwable cause) {\n        super(cause);\n    }\n\n    public ProcessingException(final String message, final Throwable cause) {\n        super(message, cause);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/domain/Branch.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\npublic class Branch {\n\n    private final int lineNumber;\n\n    private final int blockNumber;\n\n    private final int branchNumber;\n\n    private final int hits;\n\n    public Branch(final int lineNumber,\n                  final int blockNumber,\n                  final int branchNumber,\n                  final int hits) {\n        this.lineNumber = lineNumber;\n        this.blockNumber = blockNumber;\n        this.branchNumber = branchNumber;\n        this.hits = hits;\n    }\n\n    public int getLineNumber() {\n        return lineNumber;\n    }\n\n    public int getBlockNumber() {\n        return blockNumber;\n    }\n\n    public int getBranchNumber() {\n        return branchNumber;\n    }\n\n    public int getHits() {\n        return hits;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/domain/CoverallsResponse.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport com.fasterxml.jackson.annotation.JsonCreator;\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\npublic final class CoverallsResponse implements JsonObject {\n\n    private final String message;\n    private final boolean error;\n    private final String url;\n    \n    @JsonCreator\n    public CoverallsResponse(\n            @JsonProperty(\"message\") final String message,\n            @JsonProperty(\"error\") final boolean error,\n            @JsonProperty(\"url\") final String url) {\n        this.message = message;\n        this.error = error;\n        this.url = url;\n    }\n    \n    public String getMessage() {\n        return message;\n    }\n\n    public boolean isError() {\n        return error;\n    }\n    \n    public String getUrl() {\n        return url;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/domain/Git.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.io.Serializable;\nimport java.util.List;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\npublic class Git implements JsonObject {\n\n    @JsonIgnore\n    private final File baseDir;\n    \n    @JsonProperty(\"head\")\n    private final Head head;\n    \n    @JsonProperty(\"branch\")\n    private final String branch;\n    \n    @JsonProperty(\"remotes\")\n    private final List<Remote> remotes;\n    \n    public Git(final File baseDir, final Head head, final String branch, final List<Remote> remotes) {\n        this.baseDir = baseDir;\n        this.head = head;\n        this.branch = branch;\n        this.remotes = remotes;\n    }\n\n    public File getBaseDir() {\n        return baseDir;\n    }\n\n    public Head getHead() {\n        return head;\n    }\n    \n    public String getBranch() {\n        return branch;\n    }\n    \n    public List<Remote> getRemotes() {\n        return remotes;\n    }\n\n    public static class Head implements Serializable {\n        @JsonProperty(\"id\")\n        private final String id;\n        \n        @JsonProperty(\"author_name\")\n        private final String authorName;\n        \n        @JsonProperty(\"author_email\")\n        private final String authorEmail;\n        \n        @JsonProperty(\"committer_name\")\n        private final String committerName;\n        \n        @JsonProperty(\"committer_email\")\n        private final String committerEmail;\n        \n        @JsonProperty(\"message\")\n        private final String message;\n        \n        public Head(final String id, final String authorName, final String authorEmail, final String committerName, final String committerEmail, final String message) {\n            this.id = id;\n            this.authorName = authorName;\n            this.authorEmail = authorEmail;\n            this.committerName = committerName;\n            this.committerEmail = committerEmail;\n            this.message = message;\n        }\n        \n        public String getId() {\n            return id;\n        }\n        \n        public String getAuthorName() {\n            return authorName;\n        }\n        \n        public String getAuthorEmail() {\n            return authorEmail;\n        }\n        \n        public String getCommitterName() {\n            return committerName;\n        }\n        \n        public String getCommitterEmail() {\n            return committerEmail;\n        }\n        \n        public String getMessage() {\n            return message;\n        }\n    }\n    \n    public static class Remote implements Serializable {\n        @JsonProperty(\"name\")\n        private final String name;\n        \n        @JsonProperty(\"url\")\n        private final String url;\n        \n        public Remote(final String name, final String url) {\n            this.name = name;\n            this.url = url;\n        }\n\n        public String getName() {\n            return name;\n        }\n        \n        public String getUrl() {\n            return url;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/domain/GitRepository.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eclipse.jgit.lib.Config;\nimport org.eclipse.jgit.lib.Constants;\nimport org.eclipse.jgit.lib.ObjectId;\nimport org.eclipse.jgit.lib.Repository;\nimport org.eclipse.jgit.lib.RepositoryBuilder;\nimport org.eclipse.jgit.revwalk.RevCommit;\nimport org.eclipse.jgit.revwalk.RevWalk;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class GitRepository {\n    \n    private final File sourceDirectory;\n    \n    public GitRepository(final File sourceDirectory) {\n        this.sourceDirectory = sourceDirectory;\n    }\n    \n    public Git load() throws IOException {\n        try (Repository repository = new RepositoryBuilder().findGitDir(this.sourceDirectory).build()) {\n            Git.Head head = getHead(repository);\n            String branch = getBranch(repository);\n            List<Git.Remote> remotes = getRemotes(repository);\n            return new Git(repository.getWorkTree(), head, branch, remotes);\n        }\n    }\n\n    private Git.Head getHead(final Repository repository) throws IOException {\n        ObjectId revision = repository.resolve(Constants.HEAD);\n        RevCommit commit = new RevWalk(repository).parseCommit(revision);\n        Git.Head head = new Git.Head(\n                revision.getName(),\n                commit.getAuthorIdent().getName(),\n                commit.getAuthorIdent().getEmailAddress(),\n                commit.getCommitterIdent().getName(),\n                commit.getCommitterIdent().getEmailAddress(),\n                commit.getFullMessage()\n        );\n        return head;\n    }\n    \n    private String getBranch(final Repository repository) throws IOException {\n        return repository.getBranch();\n    }\n    \n    private List<Git.Remote> getRemotes(final Repository repository) {\n        Config config = repository.getConfig();\n        List<Git.Remote> remotes = new ArrayList<>();\n        for (String remote : config.getSubsections(\"remote\")) {\n            String url = config.getString(\"remote\", remote, \"url\");\n            remotes.add(new Git.Remote(remote, url));\n        }\n        return remotes;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/domain/Job.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\nimport java.util.Date;\nimport java.util.Properties;\n\nimport org.eluder.coveralls.maven.plugin.domain.Git.Remote;\nimport org.eluder.coveralls.maven.plugin.validation.JobValidator;\nimport org.eluder.coveralls.maven.plugin.validation.ValidationErrors;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\npublic class Job {\n\n    private String repoToken;\n    private String serviceName;\n    private String serviceJobId;\n    private String serviceBuildNumber;\n    private String serviceBuildUrl;\n    private boolean parallel;\n    private Properties serviceEnvironment;\n    private Date timestamp;\n    private boolean dryRun;\n    private String branch;\n    private String pullRequest;\n    private Git git;\n    \n    public Job() {\n        // noop\n    }\n\n    public Job withRepoToken(final String repoToken) {\n        this.repoToken = repoToken;\n        return this;\n    }\n    \n    public Job withServiceName(final String serviceName) {\n        this.serviceName = serviceName;\n        return this;\n    }\n    \n    public Job withServiceJobId(final String serviceJobId) {\n        this.serviceJobId = serviceJobId;\n        return this;\n    }\n    \n    public Job withServiceBuildNumber(final String serviceBuildNumber) {\n        this.serviceBuildNumber = serviceBuildNumber;\n        return this;\n    }\n    \n    public Job withServiceBuildUrl(final String serviceBuildUrl) {\n        this.serviceBuildUrl = serviceBuildUrl;\n        return this;\n    }\n\n    public Job withParallel(final boolean parallel) {\n        this.parallel = parallel;\n        return this;\n    }\n    \n    public Job withServiceEnvironment(final Properties serviceEnvironment) {\n        this.serviceEnvironment = serviceEnvironment;\n        return this;\n    }\n    \n    public Job withTimestamp(final Date timestamp) {\n        this.timestamp = timestamp;\n        return this;\n    }\n    \n    public Job withDryRun(final boolean dryRun) {\n        this.dryRun = dryRun;\n        return this;\n    }\n    \n    public Job withBranch(final String branch) {\n        this.branch = branch;\n        return this;\n    }\n    \n    public Job withPullRequest(final String pullRequest) {\n        this.pullRequest = pullRequest;\n        return this;\n    }\n    \n    public Job withGit(final Git git) {\n        this.git = git;\n        return this;\n    }\n    \n    public String getRepoToken() {\n        return repoToken;\n    }\n    \n    public String getServiceName() {\n        return serviceName;\n    }\n    \n    public String getServiceJobId() {\n        return serviceJobId;\n    }\n    \n    public String getServiceBuildNumber() {\n        return serviceBuildNumber;\n    }\n    \n    public String getServiceBuildUrl() {\n        return serviceBuildUrl;\n    }\n    \n    public Properties getServiceEnvironment() {\n        return serviceEnvironment;\n    }\n    \n    public Date getTimestamp() {\n        return timestamp;\n    }\n\n    public boolean isParallel() {\n        return parallel;\n    }\n\n    public boolean isDryRun() {\n        return dryRun;\n    }\n    \n    public String getBranch() {\n        if (branch != null && getGit() != null && getGit().getRemotes() != null) {\n            for (Remote remote : getGit().getRemotes()) {\n                if (branch.startsWith(remote.getName() + \"/\")) {\n                    return branch.substring(remote.getName().length() + 1);\n                }\n            }\n        }\n        return branch;\n    }\n    \n    public String getPullRequest() {\n        return pullRequest;\n    }\n    \n    public Git getGit() {\n        return git;\n    }\n    \n    public ValidationErrors validate() {\n        JobValidator validator = new JobValidator(this);\n        return validator.validate();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/domain/JsonObject.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.Serializable;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.jackson.annotation.JsonInclude.Include;\n\n@JsonIgnoreProperties(ignoreUnknown = true)\n@JsonInclude(Include.NON_NULL)\npublic interface JsonObject extends Serializable {\n\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/domain/Source.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.ListIterator;\nimport java.util.Objects;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic final class Source implements JsonObject {\n    \n    private static final Pattern NEWLINE = Pattern.compile(\"\\r\\n|\\r|\\n\");\n    //private static final String CLASSIFIER_SEPARATOR = \"#\";\n    \n    private final String name;\n    private final String digest;\n    private final Integer[] coverage;\n    private final List<Branch> branches;\n    private String classifier;\n    \n    public Source(final String name, final String source, final String digest) {\n        this(name, getLines(source), digest, null);\n    }\n\n    protected Source(final String name, final int lines, final String digest, final String classifier) {\n        this.name = name;\n        this.digest = digest;\n        this.coverage = new Integer[lines];\n        this.classifier = classifier;\n        this.branches = new ArrayList<>();\n    }\n    \n    @JsonIgnore\n    public String getName() {\n        return name;\n    }\n    \n    @JsonProperty(\"name\")\n    public String getFullName() {\n        return name;\n\n        // #45: cannot use identifier due to unfetchable source files\n        //return (classifier == null ? name : name + CLASSIFIER_SEPARATOR + classifier);\n    }\n    \n    @JsonProperty(\"source_digest\")\n    public String getDigest() {\n        return digest;\n    }\n    \n    @JsonProperty(\"coverage\")\n    public Integer[] getCoverage() {\n        return coverage;\n    }\n    \n    @JsonProperty(\"branches\")\n    public Integer[] getBranches() {\n        final List<Integer> branchesRaw = new ArrayList<>(branches.size() * 4);\n        for (final Branch b : branches) {\n            branchesRaw.add(b.getLineNumber());\n            branchesRaw.add(b.getBlockNumber());\n            branchesRaw.add(b.getBranchNumber());\n            branchesRaw.add(b.getHits());\n        }\n        return branchesRaw.toArray(new Integer[branchesRaw.size()]);\n    }\n\n    public List<Branch> getBranchesList() {\n        return Collections.unmodifiableList(branches);\n    }\n\n    @JsonIgnore\n    public String getClassifier() {\n        return classifier;\n    }\n    \n    public void setClassifier(final String classifier) {\n        this.classifier = classifier;\n    }\n    \n    private void checkLineRange(final int lineNumber) {\n        int index = lineNumber - 1;\n        if (index >= this.coverage.length) {\n            throw new IllegalArgumentException(\"Line number \" + lineNumber + \" is greater than the source file \" + name + \" size\");\n        }\n    }\n\n    public void addCoverage(final int lineNumber, final Integer coverage) {\n        checkLineRange(lineNumber);\n        this.coverage[lineNumber - 1] = coverage;\n    }\n\n    public void addBranchCoverage(final int lineNumber,\n                                  final int blockNumber,\n                                  final int branchNumber,\n                                  final int hits) {\n        addBranchCoverage(false, lineNumber, blockNumber, branchNumber, hits);\n    }\n\n    private void addBranchCoverage(final boolean merge,\n                                   final int lineNumber,\n                                   final int blockNumber,\n                                   final int branchNumber,\n                                   final int hits) {\n        checkLineRange(lineNumber);\n        int hitSum = hits;\n        final ListIterator<Branch> it = this.branches.listIterator();\n        while (it.hasNext()) {\n            final Branch b = it.next();\n            if (b.getLineNumber() == lineNumber &&\n                b.getBlockNumber() == blockNumber &&\n                b.getBranchNumber() == branchNumber) {\n                    it.remove();\n                    if (merge) {\n                        hitSum += b.getHits();\n                    }\n                }\n        }\n        this.branches.add(new Branch(lineNumber, blockNumber, branchNumber, hitSum));\n    }\n\n    public Source merge(final Source source) {\n        Source copy = new Source(this.name, this.coverage.length, this.digest, this.classifier);\n        System.arraycopy(this.coverage, 0, copy.coverage, 0, this.coverage.length);\n        copy.branches.addAll(this.branches);\n        if (copy.equals(source)) {\n            for (int i = 0; i < copy.coverage.length; i++) {\n                if (source.coverage[i] != null) {\n                    int base = copy.coverage[i] != null ? copy.coverage[i] : 0;\n                    copy.coverage[i] = base + source.coverage[i];\n                }\n            }\n            for (final Branch b : source.branches) {\n                copy.addBranchCoverage(true,\n                        b.getLineNumber(),\n                        b.getBlockNumber(),\n                        b.getBranchNumber(),\n                        b.getHits());\n            }\n        }\n        return copy;\n    }\n\n    @Override\n    public boolean equals(final Object obj) {\n        if (!(obj instanceof Source)) {\n            return false;\n        }\n        Source other = (Source) obj;\n        return (Objects.equals(this.name, other.name) &&\n                Objects.equals(this.digest, other.digest) &&\n                Objects.equals(this.coverage.length, other.coverage.length));\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(this.name, this.digest, this.coverage.length);\n    }\n    \n    private static int getLines(final String source) {\n        int lines = 1;\n        Matcher matcher = NEWLINE.matcher(source);\n        while (matcher.find()) {\n            lines++;\n        }\n        return lines;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/httpclient/CoverallsClient.java",
    "content": "package org.eluder.coveralls.maven.plugin.httpclient;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport org.apache.http.HttpEntity;\nimport org.apache.http.HttpResponse;\nimport org.apache.http.HttpStatus;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.client.methods.HttpPost;\nimport org.apache.http.entity.ContentType;\nimport org.apache.http.entity.mime.HttpMultipartMode;\nimport org.apache.http.entity.mime.MultipartEntityBuilder;\nimport org.codehaus.plexus.util.IOUtil;\nimport org.codehaus.plexus.util.StringUtils;\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.CoverallsResponse;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.security.Provider;\nimport java.security.Security;\n\npublic class CoverallsClient {\n\n    static {\n        for (Provider provider : Security.getProviders()) {\n            if (provider.getName().startsWith(\"SunPKCS11\")) {\n                Security.removeProvider(provider.getName());\n            }\n        }\n    }\n    \n    private static final String FILE_NAME = \"coveralls.json\";\n    private static final ContentType MIME_TYPE = ContentType.create(\"application/octet-stream\", \"utf-8\");\n    \n    private final String coverallsUrl;\n    private final HttpClient httpClient;\n    private final ObjectMapper objectMapper;\n    \n    public CoverallsClient(final String coverallsUrl) {\n        this(coverallsUrl, new HttpClientFactory(coverallsUrl).create(), new ObjectMapper());\n    }\n    \n    public CoverallsClient(final String coverallsUrl, final HttpClient httpClient, final ObjectMapper objectMapper) {\n        this.coverallsUrl = coverallsUrl;\n        this.httpClient = httpClient;\n        this.objectMapper = objectMapper;\n    }\n    \n    public CoverallsResponse submit(final File file) throws ProcessingException, IOException {\n        HttpEntity entity = MultipartEntityBuilder.create()\n                .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)\n                .addBinaryBody(\"json_file\", file, MIME_TYPE, FILE_NAME)\n                .build();\n        HttpPost post = new HttpPost(coverallsUrl);\n        post.setEntity(entity);\n        HttpResponse response = httpClient.execute(post);\n        return parseResponse(response);\n    }\n    \n    private CoverallsResponse parseResponse(final HttpResponse response) throws ProcessingException, IOException {\n        HttpEntity entity = response.getEntity();\n        ContentType contentType = ContentType.getOrDefault(entity);\n        if (contentType.getCharset() == null) {\n            throw new ProcessingException(getResponseErrorMessage(response, \"Response doesn't contain Content-Type header\"));\n        }\n        InputStreamReader reader = null;\n        try {\n            if (response.getStatusLine().getStatusCode() >= HttpStatus.SC_INTERNAL_SERVER_ERROR) {\n                throw new IOException(\"Coveralls API internal error\");\n            }\n            reader = new InputStreamReader(entity.getContent(), contentType.getCharset());\n            CoverallsResponse cr = objectMapper.readValue(reader, CoverallsResponse.class);\n            if (cr.isError()) {\n                throw new ProcessingException(getResponseErrorMessage(response, cr.getMessage()));\n            }\n            return cr;\n        } catch (JsonProcessingException ex) {\n            throw new ProcessingException(getResponseErrorMessage(response, ex.getMessage()), ex);\n        } catch (IOException ex) {\n            throw new IOException(getResponseErrorMessage(response, ex.getMessage()), ex);\n        } finally {\n            IOUtil.close(reader);\n        }\n    }\n    \n    private String getResponseErrorMessage(final HttpResponse response, final String message) {\n        int status = response.getStatusLine().getStatusCode();\n        String reason = response.getStatusLine().getReasonPhrase();\n        String errorMessage = \"Report submission to Coveralls API failed with HTTP status \" + status + \":\";\n        if (StringUtils.isNotBlank(reason)) {\n            errorMessage += \" \" + reason;\n        }\n        if (StringUtils.isNotBlank(message)) {\n            errorMessage += \" (\" + message + \")\";\n        }\n        return errorMessage;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/httpclient/CoverallsProxyClient.java",
    "content": "package org.eluder.coveralls.maven.plugin.httpclient;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport org.apache.maven.settings.Proxy;\n\npublic class CoverallsProxyClient extends CoverallsClient {\n\n    public CoverallsProxyClient(final String coverallsUrl, final Proxy proxy) {\n        super(coverallsUrl, new HttpClientFactory(coverallsUrl).proxy(proxy).create(), new ObjectMapper());\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/httpclient/HttpClientFactory.java",
    "content": "package org.eluder.coveralls.maven.plugin.httpclient;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.http.HttpHost;\nimport org.apache.http.auth.AuthScope;\nimport org.apache.http.auth.UsernamePasswordCredentials;\nimport org.apache.http.client.CredentialsProvider;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.client.config.RequestConfig;\nimport org.apache.http.impl.client.BasicCredentialsProvider;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.apache.maven.settings.Proxy;\nimport org.codehaus.plexus.util.StringUtils;\nimport org.eluder.coveralls.maven.plugin.util.UrlUtils;\nimport org.eluder.coveralls.maven.plugin.util.Wildcards;\n\nclass HttpClientFactory {\n\n    private static final int DEFAULT_CONNECTION_TIMEOUT = 10000;\n    private static final int DEFAULT_SOCKET_TIMEOUT = 60000;\n\n    private final String targetUrl;\n\n    private final HttpClientBuilder hcb = HttpClientBuilder.create();\n    private final RequestConfig.Builder rcb = RequestConfig.custom()\n            .setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT)\n            .setSocketTimeout(DEFAULT_SOCKET_TIMEOUT);\n\n    HttpClientFactory(final String targetUrl) {\n        this.targetUrl = targetUrl;\n    }\n\n    public HttpClientFactory proxy(final Proxy proxy) {\n        if (proxy != null && isProxied(targetUrl, proxy)) {\n            rcb.setProxy(new HttpHost(proxy.getHost(), proxy.getPort(), proxy.getProtocol()));\n            if (StringUtils.isNotBlank(proxy.getUsername())) {\n                CredentialsProvider cp = new BasicCredentialsProvider();\n                cp.setCredentials(\n                        new AuthScope(proxy.getHost(), proxy.getPort()),\n                        new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword())\n                );\n                hcb.setDefaultCredentialsProvider(cp);\n            }\n        }\n        return this;\n    }\n\n    public HttpClient create() {\n        return hcb.setDefaultRequestConfig(rcb.build()).build();\n    }\n\n    private boolean isProxied(final String url, final Proxy proxy) {\n        if (StringUtils.isNotBlank(proxy.getNonProxyHosts())) {\n            String host = UrlUtils.create(url).getHost();\n            String[] excludes = proxy.getNonProxyHosts().split(\"\\\\|\");\n            for (String exclude : excludes) {\n                if (StringUtils.isNotBlank(exclude) && Wildcards.matches(host, exclude.trim())) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/json/JsonWriter.java",
    "content": "package org.eluder.coveralls.maven.plugin.json;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport com.fasterxml.jackson.core.JsonEncoding;\nimport com.fasterxml.jackson.core.JsonGenerator;\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.MappingJsonFactory;\nimport org.codehaus.plexus.util.StringUtils;\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Job;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\n\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.IOException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.Map.Entry;\nimport java.util.Properties;\n\npublic class JsonWriter implements SourceCallback, Closeable {\n\n    protected static final String TIMESTAMP_FORMAT = \"yyyy-MM-dd HH:mm:ss Z\";\n    \n    private final Job job;\n    private final File coverallsFile;\n    private final JsonGenerator generator;\n    \n    public JsonWriter(final Job job, final File coverallsFile) throws IOException {\n        File directory = coverallsFile.getParentFile();\n        if (!directory.exists()) {\n            directory.mkdirs();\n        }\n        this.job = job;\n        this.coverallsFile = coverallsFile;\n        this.generator = new MappingJsonFactory().createGenerator(coverallsFile, JsonEncoding.UTF8);\n    }\n    \n    public final Job getJob() {\n        return job;\n    }\n    \n    public final File getCoverallsFile() {\n        return coverallsFile;\n    }\n\n    @Override\n    public void onBegin() throws ProcessingException, IOException {\n        try {\n            generator.writeStartObject();\n            writeOptionalString(\"repo_token\", job.getRepoToken());\n            writeOptionalString(\"service_name\", job.getServiceName());\n            writeOptionalString(\"service_job_id\", job.getServiceJobId());\n            writeOptionalString(\"service_number\", job.getServiceBuildNumber());\n            writeOptionalString(\"service_build_url\", job.getServiceBuildUrl());\n            writeOptionalString(\"service_branch\", job.getBranch());\n            writeOptionalString(\"service_pull_request\", job.getPullRequest());\n            writeOptionalBoolean(\"parallel\", job.isParallel());\n            writeOptionalTimestamp(\"run_at\", job.getTimestamp());\n            writeOptionalEnvironment(\"environment\", job.getServiceEnvironment());\n            writeOptionalObject(\"git\", job.getGit());\n            generator.writeArrayFieldStart(\"source_files\");\n        } catch (JsonProcessingException ex) {\n            throw new ProcessingException(ex);\n        }\n    }\n\n    @Override\n    public void onSource(final Source source) throws ProcessingException, IOException {\n        try {\n            generator.writeObject(source);\n        } catch (JsonProcessingException ex) {\n            throw new ProcessingException(ex);\n        }\n    }\n\n    @Override\n    public void onComplete() throws ProcessingException, IOException {\n        try {\n            generator.writeEndArray();\n            generator.writeEndObject();\n        } catch (JsonProcessingException ex) {\n            throw new ProcessingException(ex);\n        }\n    }\n\n    @Override\n    public void close() throws IOException {\n        generator.close();\n    }\n    \n    private void writeOptionalString(final String field, final String value) throws ProcessingException, IOException {\n        if (StringUtils.isNotBlank(value)) {\n            generator.writeStringField(field, value);\n        }\n    }\n\n    private void writeOptionalBoolean(final String field, final boolean value) throws ProcessingException, IOException {\n        if (value) {\n            generator.writeBooleanField(field, value);\n        }\n    }\n    \n    private void writeOptionalObject(final String field, final Object value) throws ProcessingException, IOException {\n        if (value != null) {\n            generator.writeObjectField(field, value);\n        }\n    }\n    \n    private void writeOptionalTimestamp(final String field, final Date value) throws ProcessingException, IOException {\n        if (value != null) {\n            SimpleDateFormat format = new SimpleDateFormat(TIMESTAMP_FORMAT);\n            writeOptionalString(field, format.format(value));\n        }\n    }\n    \n    private void writeOptionalEnvironment(final String field, final Properties properties) throws ProcessingException, IOException {\n        if (properties != null) {\n            generator.writeObjectFieldStart(field);\n            for (Entry<Object, Object> property : properties.entrySet()) {\n                writeOptionalString(property.getKey().toString(), property.getValue().toString());\n            }\n            generator.writeEndObject();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/logging/CoverageTracingLogger.java",
    "content": "package org.eluder.coveralls.maven.plugin.logging;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.plugin.logging.Log;\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Branch;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.source.ChainingSourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\n\nimport java.io.IOException;\n\npublic class CoverageTracingLogger extends ChainingSourceCallback implements Logger {\n\n    private long files = 0;\n    private long lines = 0;\n    private long relevant = 0;\n    private long covered = 0;\n    private long branches = 0;\n    private long coveredBranches = 0;\n    \n    public CoverageTracingLogger(final SourceCallback chained) {\n        super(chained);\n    }\n    \n    public long getFiles() {\n        return files;\n    }\n    \n    public final long getLines() {\n        return lines;\n    }\n    \n    public final long getRelevant() {\n        return relevant;\n    }\n    \n    public final long getCovered() {\n        return covered;\n    }\n    \n    public final long getMissed() {\n        return relevant - covered;\n    }\n    \n    public final long getBranches() {\n        return branches;\n    }\n\n    public final long getCoveredBranches() {\n        return coveredBranches;\n    }\n\n    public final long getMissedBranches() {\n        return branches - coveredBranches;\n    }\n\n    @Override\n    public Position getPosition() {\n        return Position.AFTER;\n    }\n\n    @Override\n    public void log(final Log log) {\n        log.info(\"Gathered code coverage metrics for \" + getFiles() + \" source files with \" + getLines() + \" lines of code:\");\n        log.info(\"- \" + getRelevant() + \" relevant lines\");\n        log.info(\"- \" + getCovered() + \" covered lines\");\n        log.info(\"- \" + getMissed() + \" missed lines\");\n        log.info(\"- \" + getBranches() + \" branches\");\n        log.info(\"- \" + getCoveredBranches() + \" covered branches\");\n        log.info(\"- \" + getMissedBranches() + \" missed branches\");\n    }\n\n    @Override\n    protected void onSourceInternal(final Source source) throws ProcessingException, IOException {\n        files++;\n        lines += source.getCoverage().length;\n        for (Integer coverage : source.getCoverage()) {\n            if (coverage != null) {\n                relevant++;\n                if (coverage > 0) {\n                    covered++;\n                }\n            }\n        }\n\n        this.branches += source.getBranchesList().size();\n        for (final Branch b : source.getBranchesList()) {\n            if (b.getHits() > 0) {\n                coveredBranches++;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/logging/DryRunLogger.java",
    "content": "package org.eluder.coveralls.maven.plugin.logging;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\n\nimport org.apache.maven.plugin.logging.Log;\n\npublic class DryRunLogger implements Logger {\n\n    private final boolean dryRun;\n    private final File coverallsFile;\n    \n    public DryRunLogger(final boolean dryRun, final File coverallsFile) {\n        if (coverallsFile == null) {\n            throw new IllegalArgumentException(\"coverallsFile must be defined\");\n        }\n        this.dryRun = dryRun;\n        this.coverallsFile = coverallsFile;\n    }\n\n    @Override\n    public Position getPosition() {\n        return Position.AFTER;\n    }\n    \n    @Override\n    public void log(final Log log) {\n        if (dryRun) {\n            log.info(\"Dry run enabled, Coveralls report will NOT be submitted to API\");\n            log.info(coverallsFile.length() + \" bytes of data was recorded in \" + coverallsFile.getAbsolutePath());\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/logging/JobLogger.java",
    "content": "package org.eluder.coveralls.maven.plugin.logging;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.plugin.logging.Log;\nimport org.eluder.coveralls.maven.plugin.domain.Job;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.MapperFeature;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.SerializationFeature;\n\npublic class JobLogger implements Logger {\n\n    private static final int ABBREV = 7;\n    \n    private final Job job;\n    private final ObjectMapper jsonMapper;\n    \n    public JobLogger(final Job job) {\n        this(job, null);\n    }\n    \n    public JobLogger(final Job job, final ObjectMapper jsonMapper) {\n        if (job == null) {\n            throw new IllegalArgumentException(\"job must be defined\");\n        }\n        this.job = job;\n        this.jsonMapper = (jsonMapper != null ? jsonMapper : createDefaultJsonMapper());\n    }\n\n    @Override\n    public Position getPosition() {\n        return Position.BEFORE;\n    }\n    \n    @Override\n    public void log(final Log log) {\n        StringBuilder starting = new StringBuilder(\"Starting Coveralls job\");\n        if (job.getServiceName() != null) {\n            starting.append(\" for \" + job.getServiceName());\n            if (job.getServiceJobId() != null) {\n                starting.append(\" (\" + job.getServiceJobId() + \")\");\n            } else if (job.getServiceBuildNumber() != null) {\n                starting.append(\" (\" + job.getServiceBuildNumber());\n                if (job.getServiceBuildUrl() != null) {\n                    starting.append(\" / \" + job.getServiceBuildUrl());\n                }\n                starting.append(\")\");\n            }\n        }\n        if (job.isDryRun()) {\n            starting.append(\" in dry run mode\");\n        }\n        if (job.isParallel()) {\n            starting.append(\" with parallel option enabled\");\n        }\n        log.info(starting.toString());\n        \n        if (job.getRepoToken() != null) {\n            log.info(\"Using repository token <secret>\");\n        }\n        \n        if (job.getGit() != null) {\n            String commit = job.getGit().getHead().getId();\n            String branch = (job.getBranch() != null ? job.getBranch() : job.getGit().getBranch());\n            log.info(\"Git commit \" + commit.substring(0, ABBREV) + \" in \" + branch);\n        }\n        \n        if (log.isDebugEnabled()) {\n            try {\n                log.debug(\"Complete Job description:\\n\" + jsonMapper.writeValueAsString(job));\n            } catch (JsonProcessingException ex) {\n                throw new RuntimeException(ex);\n            }\n        }\n    }\n    \n    private ObjectMapper createDefaultJsonMapper() {\n        ObjectMapper mapper = new ObjectMapper();\n        mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);\n        mapper.configure(SerializationFeature.INDENT_OUTPUT, true);\n        mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);\n        return mapper;\n    }\n    \n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/logging/Logger.java",
    "content": "package org.eluder.coveralls.maven.plugin.logging;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.plugin.logging.Log;\n\npublic interface Logger {\n\n    /**\n     * Position of the log output.\n     */\n    enum Position {\n        BEFORE, AFTER\n    }\n    \n    \n    /**\n     * @return the position for log output, before or after the Coveralls data writing\n     */\n    Position getPosition();\n    \n    /**\n     * Create the log output.\n     * \n     * @param log the logger to output\n     */\n    void log(Log log);\n    \n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/parser/AbstractXmlEventParser.java",
    "content": "package org.eluder.coveralls.maven.plugin.parser;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.codehaus.plexus.util.IOUtil;\nimport org.codehaus.plexus.util.ReaderFactory;\nimport org.codehaus.plexus.util.xml.XmlStreamReader;\nimport org.eluder.coveralls.maven.plugin.CoverageParser;\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\nimport javax.xml.stream.FactoryConfigurationError;\nimport javax.xml.stream.XMLInputFactory;\nimport javax.xml.stream.XMLStreamConstants;\nimport javax.xml.stream.XMLStreamException;\nimport javax.xml.stream.XMLStreamReader;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.Reader;\n\npublic abstract class AbstractXmlEventParser implements CoverageParser {\n\n    private final File coverageFile;\n    private final SourceLoader sourceLoader;\n    \n    public AbstractXmlEventParser(final File coverageFile, final SourceLoader sourceLoader) {\n        this.coverageFile = coverageFile;\n        this.sourceLoader = sourceLoader;\n    }\n\n    @Override\n    public final void parse(final SourceCallback callback) throws ProcessingException, IOException {\n        XmlStreamReader reader = ReaderFactory.newXmlReader(coverageFile);\n        XMLStreamReader xml = createEventReader(reader);\n        try {\n            while (xml.hasNext()) {\n                xml.next();\n                onEvent(xml, callback);\n            }\n        } catch (XMLStreamException ex) {\n            throw new ProcessingException(ex);\n        } finally {\n            close(xml);\n            IOUtil.close(reader);\n        }\n    }\n    \n    @Override\n    public final File getCoverageFile() {\n        return coverageFile;\n    }\n    \n    protected XMLStreamReader createEventReader(final Reader reader) throws ProcessingException {\n        try {\n            XMLInputFactory xmlif = XMLInputFactory.newInstance();\n            xmlif.setProperty(XMLInputFactory.SUPPORT_DTD, false);\n            xmlif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);\n            xmlif.setProperty(XMLInputFactory.IS_VALIDATING, false);\n            return xmlif.createXMLStreamReader(reader);\n        } catch (FactoryConfigurationError ex) {\n            throw new IllegalArgumentException(ex);\n        } catch (XMLStreamException ex) {\n            throw new ProcessingException(ex);\n        }\n    }\n    \n    private void close(final XMLStreamReader xml) throws ProcessingException {\n        if (xml != null) {\n            try {\n                xml.close();\n            } catch (XMLStreamException ex) {\n                throw new ProcessingException(ex);\n            }\n        }\n    }\n    \n    protected abstract void onEvent(final XMLStreamReader xml, SourceCallback callback) throws XMLStreamException, ProcessingException, IOException;\n    \n    protected final Source loadSource(final String sourceFile) throws IOException {\n        return sourceLoader.load(sourceFile);\n    }\n    \n    protected final boolean isStartElement(final XMLStreamReader xml, final String name) {\n        return (XMLStreamConstants.START_ELEMENT == xml.getEventType() && xml.getLocalName().equals(name));\n    }\n    \n    protected final boolean isEndElement(final XMLStreamReader xml, final String name) {\n        return (XMLStreamConstants.END_ELEMENT == xml.getEventType() && xml.getLocalName().equals(name));\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/parser/CoberturaParser.java",
    "content": "package org.eluder.coveralls.maven.plugin.parser;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.io.IOException;\nimport javax.xml.stream.XMLStreamException;\nimport javax.xml.stream.XMLStreamReader;\n\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\npublic class CoberturaParser extends AbstractXmlEventParser {\n\n    protected Source source;\n    protected boolean inMethods;\n    private int branchId;\n\n    public CoberturaParser(final File coverageFile, final SourceLoader sourceLoader) {\n        super(coverageFile, sourceLoader);\n    }\n    \n    @Override\n    protected void onEvent(final XMLStreamReader xml, final SourceCallback callback) throws XMLStreamException, ProcessingException, IOException {\n        if (isStartElement(xml, \"class\")) {\n            source = loadSource(xml.getAttributeValue(null, \"filename\"));\n            String className = xml.getAttributeValue(null, \"name\");\n            int classifierPosition = className.indexOf('$');\n            if (classifierPosition > 0) {\n                source.setClassifier(className.substring(classifierPosition + 1));\n            }\n            this.branchId = 0;\n        } else\n        \n        if (isStartElement(xml, \"methods\") && source != null) {\n            inMethods = true;\n        } else\n        \n        if (isEndElement(xml, \"methods\") && source != null) {\n            inMethods = false;\n        } else\n        \n        if (isStartElement(xml, \"line\") && !inMethods && source != null) {\n            final int nr = Integer.parseInt(xml.getAttributeValue(null, \"number\"));\n            source.addCoverage(nr, Integer.valueOf(xml.getAttributeValue(null, \"hits\")));\n            if (Boolean.parseBoolean(xml.getAttributeValue(null, \"branch\"))) {\n                final String value = xml.getAttributeValue(null, \"condition-coverage\");\n\n                // Is \"condition-coverage\" attribute always here?\n                if (value == null) {\n                    return;\n                }\n\n                // C'mon Cobertura, human readable format for XML ?\n                final String[] values = value // 50% (2/4)\n                        .replace(\" \", \"\")     // 50%(2/4)\n                        .replace(\"%\", \"/\")    // 50/(2/4)\n                        .replace(\"(\", \"\")     // 50/2/4)\n                        .replace(\")\", \"\")     // 50/2/4\n                        .split(\"/\");\n\n                final int cb = Integer.parseInt(values[1]);\n                final int tb = Integer.parseInt(values[2]);\n                final int mb = tb - cb;\n\n                // add branches. unfortunately, there is NO block number and\n                // branch number will NOT be unique between coverage changes.\n                for (int b = 0; b < cb; b++) {\n                  this.source.addBranchCoverage(nr, 0, this.branchId++, 1);\n                }\n                for (int b = 0; b < mb; b++) {\n                  this.source.addBranchCoverage(nr, 0, this.branchId++, 0);\n                }\n            }\n        } else\n        \n        if (isEndElement(xml, \"class\") && source != null) {\n            callback.onSource(source);\n            source = null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/parser/JaCoCoParser.java",
    "content": "package org.eluder.coveralls.maven.plugin.parser;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.io.IOException;\nimport javax.xml.stream.XMLStreamException;\nimport javax.xml.stream.XMLStreamReader;\n\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\npublic class JaCoCoParser extends AbstractXmlEventParser {\n\n    private String packageName;\n    private Source source;\n    private int branchId;\n\n    public JaCoCoParser(final File coverageFile, final SourceLoader sourceLoader) {\n        super(coverageFile, sourceLoader);\n    }\n    \n    @Override\n    protected void onEvent(final XMLStreamReader xml, final SourceCallback callback) throws XMLStreamException, ProcessingException, IOException {\n        if (isStartElement(xml, \"package\")) {\n            this.packageName = xml.getAttributeValue(null, \"name\");\n        } else\n        \n        if (isStartElement(xml, \"sourcefile\") && packageName != null) {\n            String sourceFile = this.packageName + \"/\" + xml.getAttributeValue(null, \"name\");\n            this.source = loadSource(sourceFile);\n            this.branchId = 0;\n        } else\n        \n        if (isStartElement(xml, \"line\") && this.source != null) {\n            int ci = Integer.parseInt(xml.getAttributeValue(null, \"ci\"));\n            int cb = Integer.parseInt(xml.getAttributeValue(null, \"cb\"));\n            int mb = Integer.parseInt(xml.getAttributeValue(null, \"mb\"));\n            int nr = Integer.parseInt(xml.getAttributeValue(null, \"nr\"));\n\n            // jacoco does not count hits. this is why hits is always 0 or 1\n            this.source.addCoverage(nr, (ci == 0 ? 0 : 1));\n\n            // add branches. unfortunately, there is NO block number and\n            // branch number will NOT be unique between coverage changes.\n            for (int b = 0; b < cb; b++) {\n              this.source.addBranchCoverage(nr, 0, this.branchId++, 1);\n            }\n            for (int b = 0; b < mb; b++) {\n              this.source.addBranchCoverage(nr, 0, this.branchId++, 0);\n            }\n        } else\n        \n        if (isEndElement(xml, \"sourcefile\") && this.source != null) {\n            callback.onSource(this.source);\n            this.source = null;\n        } else\n        \n        if (isEndElement(xml, \"package\")) {\n            this.packageName = null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/parser/SagaParser.java",
    "content": "package org.eluder.coveralls.maven.plugin.parser;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.io.IOException;\nimport javax.xml.stream.XMLStreamException;\nimport javax.xml.stream.XMLStreamReader;\n\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\n/**\n * @author Jakub Bednář (25/12/2013 10:07)\n */\npublic class SagaParser extends CoberturaParser {\n\n    public SagaParser(final File coverageFile, final SourceLoader sourceLoader) {\n        super(coverageFile, sourceLoader);\n    }\n\n    @Override\n    protected void onEvent(final XMLStreamReader xml, final SourceCallback callback) throws XMLStreamException, ProcessingException, IOException {\n        if (isStartElement(xml, \"class\")) {\n            String name = xml.getAttributeValue(null, \"name\");\n            source = loadSource(name);\n        } else {\n            super.onEvent(xml, callback);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/AbstractServiceSetup.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.codehaus.plexus.util.StringUtils;\n\n/**\n * Convenient base class for service setups.\n */\npublic abstract class AbstractServiceSetup implements ServiceSetup {\n\n    private final Map<String, String> env;\n    \n    public AbstractServiceSetup(final Map<String, String> env) {\n        this.env = env;\n    }\n\n    @Override\n    public String getJobId() {\n        return null;\n    }\n\n    @Override\n    public String getBuildNumber() {\n        return null;\n    }\n\n    @Override\n    public String getBuildUrl() {\n        return null;\n    }\n\n    @Override\n    public String getBranch() {\n        return null;\n    }\n\n    @Override\n    public String getPullRequest() {\n        return null;\n    }\n\n    @Override\n    public Properties getEnvironment() {\n        return null;\n    }\n    \n    protected final String getProperty(final String name) {\n        return env.get(name);\n    }\n    \n    protected final void addProperty(final Properties properties, final String name, final String value) {\n        if (StringUtils.isBlank(name)) {\n            throw new IllegalArgumentException(\"name must be defined\");\n        }\n        if (StringUtils.isNotBlank(value)) {\n            properties.setProperty(name, value);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/Appveyor.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.util.Map;\n\n/**\n * Service implementation for Appveyor.\n * <p>\n * http://appveyor.com/\n */\npublic class Appveyor extends AbstractServiceSetup {\n\n    public static final String APPVEYOR_NAME = \"Appveyor\";\n    public static final String APPVEYOR = \"APPVEYOR\";\n    public static final String APPVEYOR_BUILD_NUMBER = \"APPVEYOR_BUILD_NUMBER\";\n    public static final String APPVEYOR_BUILD_ID = \"APPVEYOR_BUILD_ID\";\n    public static final String APPVEYOR_BRANCH = \"APPVEYOR_REPO_BRANCH\";\n    public static final String APPVEYOR_COMMIT = \"APPVEYOR_REPO_COMMIT\";\n    public static final String APPVEYOR_PULL_REQUEST = \"APPVEYOR_PULL_REQUEST_NUMBER\";\n    public static final String APPVEYOR_REPO_NAME = \"APPVEYOR_REPO_NAME\";\n\n    public Appveyor(final Map<String, String> env) {\n        super(env);\n    }\n\n    @Override\n    public boolean isSelected() {\n        return (\"true\".equalsIgnoreCase(getProperty(APPVEYOR)));\n    }\n\n    @Override\n    public String getName() {\n        return APPVEYOR_NAME;\n    }\n\n    @Override\n    public String getBuildNumber() {\n        return getProperty(APPVEYOR_BUILD_NUMBER);\n    }\n\n    @Override\n    public String getBuildUrl() {\n        return \"https://ci.appveyor.com/project/\" + getProperty(APPVEYOR_REPO_NAME) + \"/build/\" + getProperty(APPVEYOR_BUILD_NUMBER);\n    }\n\n    @Override\n    public String getBranch() {\n        return getProperty(APPVEYOR_BRANCH);\n    }\n\n    @Override\n    public String getPullRequest() {\n        return getProperty(APPVEYOR_PULL_REQUEST);\n    }\n\n\n    @Override\n    public String getJobId() {\n        return getProperty(APPVEYOR_BUILD_ID);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/Bamboo.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.util.Map;\n\n/**\n * Service implementation for Atlassian Bamboo.\n * <p>\n * https://www.atlassian.com/software/bamboo/\n */\npublic class Bamboo extends AbstractServiceSetup {\n\n    public static final String BAMBOO_NAME = \"bamboo\";\n    public static final String BAMBOO_BUILD_NUMBER = \"bamboo.buildNumber\";\n    public static final String BAMBOO_BUILD_URL = \"bamboo.buildResultsUrl\";\n    public static final String BAMBOO_BRANCH = \"bamboo.repository.git.branch\";\n    \n    public Bamboo(final Map<String, String> env) {\n        super(env);\n    }\n\n    @Override\n    public boolean isSelected() {\n        return (getProperty(BAMBOO_BUILD_NUMBER) != null);\n    }\n    \n    @Override\n    public String getName() {\n        return BAMBOO_NAME;\n    }\n    \n    @Override\n    public String getBuildNumber() {\n        return getProperty(BAMBOO_BUILD_NUMBER);\n    }\n    \n    @Override\n    public String getBuildUrl() {\n        return getProperty(BAMBOO_BUILD_URL);\n    }\n    \n    @Override\n    public String getBranch() {\n        return getProperty(BAMBOO_BRANCH);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/Circle.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.util.Map;\nimport java.util.Properties;\n\n/**\n * Service implementation for CircleCI.\n * <p>\n * https://circleci.com/\n */\npublic class Circle extends AbstractServiceSetup {\n\n    public static final String CIRCLE_NAME = \"circleci\";\n    public static final String CIRCLE = \"CIRCLECI\";\n    public static final String CIRCLE_BUILD_NUMBER  = \"CIRCLE_BUILD_NUM\";\n    public static final String CIRCLE_BRANCH = \"CIRCLE_BRANCH\";\n    public static final String CIRCLE_COMMIT = \"CIRCLE_SHA1\";\n    \n    public Circle(final Map<String, String> env) {\n        super(env);\n    }\n\n    @Override\n    public boolean isSelected() {\n        return (getProperty(CIRCLE) != null);\n    }\n    \n    @Override\n    public String getName() {\n        return CIRCLE_NAME;\n    }\n    \n    @Override\n    public String getBuildNumber() {\n        return getProperty(CIRCLE_BUILD_NUMBER);\n    }\n    \n    @Override\n    public String getBranch() {\n        return getProperty(CIRCLE_BRANCH);\n    }\n    \n    @Override\n    public Properties getEnvironment() {\n        Properties environment = new Properties();\n        addProperty(environment, \"circleci_build_num\", getProperty(CIRCLE_BUILD_NUMBER));\n        addProperty(environment, \"branch\", getProperty(CIRCLE_BRANCH));\n        addProperty(environment, \"commit_sha\", getProperty(CIRCLE_COMMIT));\n        return environment;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/General.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.util.Map;\n\n/**\n * General implementation for any continuous integration service that provides the required\n * environment properties.\n */\npublic class General extends AbstractServiceSetup {\n\n    public static final String CI_NAME = \"CI_NAME\";\n    public static final String CI_BUILD_NUMBER = \"CI_BUILD_NUMBER\";\n    public static final String CI_BUILD_URL = \"CI_BUILD_URL\";\n    public static final String CI_BRANCH = \"CI_BRANCH\";\n    public static final String CI_PULL_REQUEST = \"CI_PULL_REQUEST\";\n    \n    public General(final Map<String, String> env) {\n        super(env);\n    }\n\n    @Override\n    public boolean isSelected() {\n        return (getProperty(CI_NAME) != null);\n    }\n\n    @Override\n    public String getName() {\n        return getProperty(CI_NAME);\n    }\n\n    @Override\n    public String getBuildNumber() {\n        return getProperty(CI_BUILD_NUMBER);\n    }\n    \n    @Override\n    public String getBuildUrl() {\n        return getProperty(CI_BUILD_URL);\n    }\n    \n    @Override\n    public String getBranch() {\n        return getProperty(CI_BRANCH);\n    }\n    \n    @Override\n    public String getPullRequest() {\n        return getProperty(CI_PULL_REQUEST);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/Jenkins.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.util.Map;\nimport java.util.Properties;\n\n/**\n * Service implementation for Jenkins.\n * <p>\n * http://jenkins-ci.org/\n */\npublic class Jenkins extends AbstractServiceSetup {\n\n    public static final String JENKINS_NAME = \"jenkins\";\n    public static final String JENKINS_URL = \"JENKINS_URL\";\n    public static final String JENKINS_BUILD_NUMBER = \"BUILD_NUMBER\";\n    public static final String JENKINS_BUILD_URL = \"BUILD_URL\";\n    public static final String JENKINS_BRANCH = \"GIT_BRANCH\";\n    public static final String JENKINS_COMMIT = \"GIT_COMMIT\";\n    \n    public Jenkins(final Map<String, String> env) {\n        super(env);\n    }\n\n    @Override\n    public boolean isSelected() {\n        return (getProperty(JENKINS_URL) != null);\n    }\n    \n    @Override\n    public String getName() {\n        return JENKINS_NAME;\n    }\n    \n    @Override\n    public String getBuildNumber() {\n        return getProperty(JENKINS_BUILD_NUMBER);\n    }\n    \n    @Override\n    public String getBuildUrl() {\n        return getProperty(JENKINS_BUILD_URL);\n    }\n    \n    @Override\n    public String getBranch() {\n        return getProperty(JENKINS_BRANCH);\n    }\n    \n    @Override\n    public Properties getEnvironment() {\n        Properties environment = new Properties();\n        addProperty(environment, \"jenkins_build_num\", getProperty(JENKINS_BUILD_NUMBER));\n        addProperty(environment, \"jenkins_build_url\", getProperty(JENKINS_BUILD_URL));\n        addProperty(environment, \"branch\", getProperty(JENKINS_BRANCH));\n        addProperty(environment, \"commit_sha\", getProperty(JENKINS_COMMIT));\n        return environment;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/ServiceSetup.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\nimport java.util.Properties;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\n/**\n * Service specific mojo properties.\n */\npublic interface ServiceSetup {\n\n    /**\n     * @return <code>true</code> if this service is selected, otherwise <code>false</code>\n     */\n    boolean isSelected();\n    \n    /**\n     * @return service name\n     */\n    String getName();\n    \n    /**\n     * @return service job id, or <code>null</code> if not defined\n     */\n    String getJobId();\n    \n    /**\n     * @return service build number, or <code>null</code> if not defined\n     */\n    String getBuildNumber();\n    \n    /**\n     * @return service build url, or <code>null</code> if not defined\n     */\n    String getBuildUrl();\n    \n    /**\n     * @return git branch name, or <code>null</code> if not defined\n     */\n    String getBranch();\n    \n    /**\n     * @return pull request identifier, or <code>null</code> if not defined\n     */\n    String getPullRequest();\n    \n    /**\n     * @return environment related to service, or <code>null</code> if not defined\n     */\n    Properties getEnvironment();\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/Shippable.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.util.Map;\nimport java.util.Properties;\n\n/**\n * Service implementation for Shippable.\n * <p>\n * http://shippable.com/\n */\npublic class Shippable extends AbstractServiceSetup {\n\n    public static final String SHIPPABLE_NAME = \"shippable\";\n    public static final String SHIPPABLE = \"SHIPPABLE\";\n    public static final String SHIPPABLE_BUILD_NUMBER = \"SHIPPABLE_BUILD_NUMBER\";\n    public static final String SHIPPABLE_BUILD_ID = \"SHIPPABLE_BUILD_ID\";\n    public static final String SHIPPABLE_BRANCH = \"BRANCH\";\n    public static final String SHIPPABLE_COMMIT = \"COMMIT\";\n    public static final String SHIPPABLE_PULL_REQUEST = \"PULL_REQUEST\";\n\n    public Shippable(final Map<String, String> env) {\n        super(env);\n    }\n\n    @Override\n    public boolean isSelected() {\n        return (\"true\".equalsIgnoreCase(getProperty(SHIPPABLE)));\n    }\n\n    @Override\n    public String getName() {\n        return SHIPPABLE_NAME;\n    }\n\n    @Override\n    public String getBuildNumber() {\n        return getProperty(SHIPPABLE_BUILD_NUMBER);\n    }\n\n    @Override\n    public String getBuildUrl() {\n        return \"https://app.shippable.com/builds/\" + getProperty(SHIPPABLE_BUILD_ID);\n    }\n\n    @Override\n    public String getBranch() {\n        return getProperty(SHIPPABLE_BRANCH);\n    }\n\n    @Override\n    public String getPullRequest() {\n        String pullRequest = getProperty(SHIPPABLE_PULL_REQUEST);\n        if (\"false\".equals(pullRequest)) {\n            return null;\n        }\n        return pullRequest;\n    }\n\n    @Override\n    public Properties getEnvironment() {\n        Properties environment = new Properties();\n        addProperty(environment, \"shippable_build_number\", getProperty(SHIPPABLE_BUILD_NUMBER));\n        addProperty(environment, \"shippable_build_id\", getProperty(SHIPPABLE_BUILD_ID));\n        addProperty(environment, \"shippable_build_url\", getBuildUrl());\n        addProperty(environment, \"branch\", getProperty(SHIPPABLE_BRANCH));\n        addProperty(environment, \"commit_sha\", getProperty(SHIPPABLE_COMMIT));\n        return environment;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/Travis.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\nimport java.util.Map;\nimport java.util.Properties;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\n/**\n * Service implementation for Travis CI.\n * <p>\n * https://travis-ci.org/\n */\npublic class Travis extends AbstractServiceSetup {\n\n    public static final String TRAVIS_NAME = \"travis-ci\";\n    public static final String TRAVIS = \"TRAVIS\";\n    public static final String TRAVIS_JOB_ID = \"TRAVIS_JOB_ID\";\n    public static final String TRAVIS_BRANCH = \"TRAVIS_BRANCH\";\n    public static final String TRAVIS_PULL_REQUEST = \"TRAVIS_PULL_REQUEST\";\n    \n    public Travis(final Map<String, String> env) {\n        super(env);\n    }\n\n    @Override\n    public boolean isSelected() {\n        return (\"true\".equalsIgnoreCase(getProperty(TRAVIS)));\n    }\n\n    @Override\n    public String getName() {\n        return TRAVIS_NAME;\n    }\n    \n    @Override\n    public String getJobId() {\n        return getProperty(TRAVIS_JOB_ID);\n    }\n\n    @Override\n    public String getBranch() {\n        return getProperty(TRAVIS_BRANCH);\n    }\n    \n    @Override\n    public String getPullRequest() {\n        return getProperty(TRAVIS_PULL_REQUEST);\n    }\n    \n    @Override\n    public Properties getEnvironment() {\n        Properties environment = new Properties();\n        addProperty(environment, \"travis_job_id\", getProperty(TRAVIS_JOB_ID));\n        addProperty(environment, \"travis_pull_request\", getProperty(TRAVIS_PULL_REQUEST));\n        return environment;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/service/Wercker.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\nimport java.util.Map;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\n/**\n * Service implementation for Wercker CI.\n * <p>\n * http://wercker.com/\n */\npublic class Wercker extends AbstractServiceSetup {\n\n    public static final String WERCKER_NAME = \"wercker\";\n    public static final String WERCKER = \"WERCKER\";\n    public static final String WERCKER_BUILD_ID = \"WERCKER_BUILD_ID\";\n    public static final String WERCKER_BUILD_URL = \"WERCKER_BUILD_URL\";\n    public static final String WERCKER_BRANCH = \"WERCKER_GIT_BRANCH\";\n\n    public Wercker(final Map<String, String> env) {\n        super(env);\n    }\n\n    @Override\n    public boolean isSelected() {\n        return \"true\".equalsIgnoreCase(getProperty(WERCKER));\n    }\n\n    @Override\n    public String getName() {\n        return WERCKER_NAME;\n    }\n\n    @Override\n    public String getJobId() {\n        return getProperty(WERCKER_BUILD_ID);\n    }\n\n    @Override\n    public String getBuildUrl() {\n        return getProperty(WERCKER_BUILD_URL);\n    }\n\n    @Override\n    public String getBranch() {\n        return getProperty(WERCKER_BRANCH);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/AbstractSourceLoader.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.codehaus.plexus.util.IOUtil;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.util.Md5DigestInputStream;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.net.URI;\nimport java.nio.charset.Charset;\nimport java.security.NoSuchAlgorithmException;\n\npublic abstract class AbstractSourceLoader implements SourceLoader {\n\n    private final Charset sourceEncoding;\n    private final String directoryPrefix;\n    \n    public AbstractSourceLoader(final URI base, final URI sourceBase, final String sourceEncoding) {\n        this.sourceEncoding = Charset.forName(sourceEncoding);\n        this.directoryPrefix = base.relativize(sourceBase).toString();\n    }\n    \n    @Override\n    public Source load(final String sourceFile) throws IOException {\n        InputStream stream = locate(sourceFile);\n        if (stream != null) {\n            try (Md5DigestInputStream ds = new Md5DigestInputStream(stream);\n                    InputStreamReader reader = new InputStreamReader(ds, getSourceEncoding())) {\n                String source = IOUtil.toString(reader);\n                return new Source(getFileName(sourceFile), source, ds.getDigestHex());\n            } catch (NoSuchAlgorithmException ex) {\n                throw new IOException(\"MD5 algorithm not available\", ex);\n            }\n        } else {\n            return null;\n        }\n    }\n    \n    protected Charset getSourceEncoding() {\n        return sourceEncoding;\n    }\n    \n    protected String getFileName(final String sourceFile) {\n        return directoryPrefix + sourceFile;\n    }\n    \n    protected abstract InputStream locate(String sourceFile) throws IOException;\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/ChainingSourceCallback.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\n\nimport java.io.IOException;\n\n/**\n * Source callback handler that allows chaining multiple callback handlers. Chained callback\n * handler is executed after this callback.\n */\npublic abstract class ChainingSourceCallback implements SourceCallback {\n\n    private final SourceCallback chained;\n\n    public ChainingSourceCallback(final SourceCallback chained) {\n        if (chained == null) {\n            throw new IllegalArgumentException(\"chained must be defined\");\n        }\n        this.chained = chained;\n    }\n\n    @Override\n    public final void onBegin() throws ProcessingException, IOException {\n        onBeginInternal();\n        chained.onBegin();\n    }\n\n    @Override\n    public final void onSource(final Source source) throws ProcessingException, IOException {\n        onSourceInternal(source);\n        chained.onSource(source);\n    }\n\n    @Override\n    public final void onComplete() throws ProcessingException, IOException {\n        onCompleteInternal();\n        chained.onComplete();\n    }\n\n    /**\n     * Defaults to no-op implementation.\n     *\n     * @see #onBegin()\n     *\n     * @throws ProcessingException if processing fails\n     * @throws IOException if an I/O error occurs\n     */\n    protected void onBeginInternal() throws ProcessingException, IOException {\n\n    }\n\n    /**\n     * @see #onSource(Source)\n     * \n     * @param source the source file\n     * @throws ProcessingException if further processing of the source fails\n     * @throws IOException if an I/O error occurs\n     */\n    protected abstract void onSourceInternal(final Source source) throws ProcessingException, IOException;\n\n    /**\n     * Defaults to no-op implementation.\n     *\n     * @see #onComplete()\n     *\n     * @throws ProcessingException if processing fails\n     * @throws IOException if an I/O error occurs\n     */\n    protected void onCompleteInternal() throws ProcessingException, IOException {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/DirectorySourceLoader.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\n\npublic class DirectorySourceLoader extends AbstractSourceLoader {\n\n    private final File sourceDirectory;\n\n    public DirectorySourceLoader(final File base, final File sourceDirectory, final String sourceEncoding) {\n        super(base.toURI(), sourceDirectory.toURI(), sourceEncoding);\n        this.sourceDirectory = sourceDirectory;\n    }\n\n    @Override\n    protected InputStream locate(final String sourceFile) throws IOException {\n        File file = new File(sourceDirectory, sourceFile);\n        if (file.exists()) {\n            if (!file.isFile()) {\n                throw new IllegalArgumentException(file.getAbsolutePath() + \" is not file\");\n            }\n            return new BufferedInputStream(new FileInputStream(file));\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/MultiSourceLoader.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.domain.Source;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class MultiSourceLoader implements SourceLoader {\n    \n    private final List<SourceLoader> sourceLoaders = new ArrayList<>();\n    \n    public MultiSourceLoader add(final SourceLoader sourceLoader) {\n        this.sourceLoaders.add(sourceLoader);\n        return this;\n    }\n\n    @Override\n    public Source load(final String sourceFile) throws IOException {\n        for (SourceLoader sourceLoader : sourceLoaders) {\n            Source source = sourceLoader.load(sourceFile);\n            if (source != null) {\n                return source;\n            }\n        }\n        throw new IOException(\"No source found for \" + sourceFile);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/ScanSourceLoader.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.codehaus.plexus.util.DirectoryScanner;\nimport org.codehaus.plexus.util.FileUtils;\nimport org.codehaus.plexus.util.SelectorUtils;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ScanSourceLoader extends AbstractSourceLoader {\n    \n    private final Map<String, String[]> cache = new HashMap<>();\n\n    private final File sourceDirectory;\n\n    public ScanSourceLoader(final File base, final File sourceDirectory, final String sourceEncoding) {\n        super(base.toURI(), sourceDirectory.toURI(), sourceEncoding);\n        this.sourceDirectory = sourceDirectory;\n    }\n\n    @Override\n    protected InputStream locate(final String sourceFile) throws IOException {\n        File file = new File(sourceDirectory, getFileName(sourceFile));\n\n        if (file.exists()) {\n            if (!file.isFile()) {\n                throw new IllegalArgumentException(file.getAbsolutePath() + \" is not file\");\n            }\n            return new BufferedInputStream(new FileInputStream(file));\n        }\n        return null;\n    }\n\n    private String[] scanFor(final String extension) {\n        if (!cache.containsKey(extension)) {\n            DirectoryScanner scanner = new DirectoryScanner();\n            scanner.setBasedir(sourceDirectory);\n            scanner.addDefaultExcludes();\n            scanner.setIncludes(new String[] {\"**/*.\" + extension});\n            scanner.scan();\n\n            cache.put(extension, scanner.getIncludedFiles());\n        }\n        return cache.get(extension);\n    }\n\n    protected String getFileName(final String sourceFile) {\n        String extension = FileUtils.extension(sourceFile);\n        String[] matchingExtensionFiles = scanFor(extension);\n\n        for (String matchingExtensionFile : matchingExtensionFiles) {\n            if (SelectorUtils.matchPath(\"**/\" + sourceFile, matchingExtensionFile, true)) {\n                return matchingExtensionFile;\n            }\n        }\n\n        return sourceFile;\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/SourceCallback.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\n\nimport java.io.IOException;\n\n/**\n * Source callback handles parsed source files from coverage reports.\n */\npublic interface SourceCallback {\n\n    /**\n     * Called before source parsing has started.\n     *\n     * @throws ProcessingException if processing fails\n     * @throws IOException if an I/O error occurs\n     */\n    void onBegin() throws ProcessingException, IOException;\n\n    /**\n     * Handles a parsed source file.\n     * \n     * @param source the source file\n     * @throws ProcessingException if further processing of the source fails\n     * @throws IOException if an I/O error occurs\n     */\n    void onSource(Source source) throws ProcessingException, IOException;\n\n    /**\n     * Called after all sources are handled.\n     *\n     * @throws ProcessingException if processing fails\n     * @throws IOException if an I/O error occurs\n     */\n    void onComplete() throws ProcessingException, IOException;\n    \n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/SourceLoader.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.IOException;\n\nimport org.eluder.coveralls.maven.plugin.domain.Source;\n\npublic interface SourceLoader {\n    \n    Source load(String sourceFile) throws IOException;\n    \n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/UniqueSourceCallback.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\n\nimport java.io.IOException;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n/**\n * Source callback that tracks passed by source files and provides only unique\n * source files to the delegate. Note that the implementation is not thread\n * safe so the {@link #onSource(org.eluder.coveralls.maven.plugin.domain.Source)}\n * can be called only from single thread concurrently.\n */\npublic class UniqueSourceCallback implements SourceCallback {\n\n    private final Map<Source, Source> cache;\n    private final SourceCallback delegate;\n\n    public UniqueSourceCallback(final SourceCallback delegate) {\n        this.cache = new LinkedHashMap<>();\n        this.delegate = delegate;\n    }\n\n    @Override\n    public void onBegin() throws ProcessingException, IOException {\n        delegate.onBegin();\n    }\n\n    @Override\n    public void onSource(final Source source) throws ProcessingException, IOException {\n        Source merged = source.merge(cache.get(source));\n        cache.put(merged, merged);\n    }\n\n    @Override\n    public void onComplete() throws ProcessingException, IOException {\n        for (Source source : cache.values()) {\n            delegate.onSource(source);\n        }\n        delegate.onComplete();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/source/UrlSourceLoader.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\n\nimport org.eluder.coveralls.maven.plugin.util.UrlUtils;\n\npublic class UrlSourceLoader extends AbstractSourceLoader {\n\n    private final URL sourceUrl;\n\n    public UrlSourceLoader(final URL base, final URL sourceUrl, final String sourceEncoding) {\n        super(UrlUtils.toUri(base), UrlUtils.toUri(sourceUrl), sourceEncoding);\n        this.sourceUrl = sourceUrl;\n    }\n    \n    @Override\n    protected InputStream locate(final String sourceFile) throws IOException {\n        URL url = new URL(sourceUrl, sourceFile);\n        // Checkstyle OFF: EmptyBlock\n        try {\n            return url.openStream();\n        } catch (IOException ex) {\n            // not found from url\n        }\n        // Checkstyle ON: EmptyBlock\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/util/CoverageParsersFactory.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.project.MavenProject;\nimport org.eluder.coveralls.maven.plugin.CoverageParser;\nimport org.eluder.coveralls.maven.plugin.parser.CoberturaParser;\nimport org.eluder.coveralls.maven.plugin.parser.JaCoCoParser;\nimport org.eluder.coveralls.maven.plugin.parser.SagaParser;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\npublic class CoverageParsersFactory {\n\n    private static final String JACOCO_FILE = \"/jacoco.xml\";\n    private static final String JACOCO_PREFIX = \"/jacoco\";\n    private static final String JACOCO_IT_PREFIX = \"/jacoco-it\";\n\n    private static final String COBERTURA_FILE = \"/coverage.xml\";\n    private static final String COBERTURA_PREFIX = \"/cobertura\";\n\n    private static final String SAGA_FILE = \"/total-coverage.xml\";\n    private static final String SAGA_PREFIX = \"/saga-coverage\";\n    \n    private final MavenProject project;\n    private final SourceLoader sourceLoader;\n    private List<File> jacocoReports;\n    private List<File> coberturaReports;\n    private List<File> sagaReports;\n    private List<String> relativeReportDirs;\n\n    public CoverageParsersFactory(final MavenProject project, final SourceLoader sourceLoader) {\n        this.project = project;\n        this.sourceLoader = sourceLoader;\n    }\n    \n    public CoverageParsersFactory withJaCoCoReports(final List<File> jacocoReports) {\n        this.jacocoReports = jacocoReports;\n        return this;\n    }\n    \n    public CoverageParsersFactory withCoberturaReports(final List<File> coberturaReports) {\n        this.coberturaReports = coberturaReports;\n        return this;\n    }\n    \n    public CoverageParsersFactory withSagaReports(final List<File> sagaReports) {\n        this.sagaReports = sagaReports;\n        return this;\n    }\n\n    public CoverageParsersFactory withRelativeReportDirs(final List<String> relativeReportDirs) {\n        this.relativeReportDirs = relativeReportDirs;\n        return this;\n    }\n    \n    public List<CoverageParser> createParsers() throws IOException {\n        List<CoverageParser> parsers = new ArrayList<>();\n        List<MavenProject> projects = new MavenProjectCollector(project).collect();\n\n        ExistingFiles jacocoFiles = ExistingFiles.create(jacocoReports);\n        ExistingFiles coberturaFiles = ExistingFiles.create(coberturaReports);\n        ExistingFiles sagaFiles = ExistingFiles.create(sagaReports);\n        for (MavenProject p : projects) {\n            File reportingDirectory = new File(p.getModel().getReporting().getOutputDirectory());\n            File buildDirectory = new File(p.getBuild().getDirectory());\n            \n            jacocoFiles.add(new File(reportingDirectory, JACOCO_PREFIX + JACOCO_FILE));\n            jacocoFiles.add(new File(reportingDirectory, JACOCO_IT_PREFIX + JACOCO_FILE));\n            coberturaFiles.add(new File(reportingDirectory, COBERTURA_PREFIX + COBERTURA_FILE));\n            sagaFiles.add(new File(buildDirectory, SAGA_PREFIX + SAGA_FILE));\n\n            if (relativeReportDirs != null) {\n                for (String relativeReportPath : relativeReportDirs) {\n                    File relativeReportingDirectory = reportingDirectory;\n                    File relativeBuildDirectory = buildDirectory;\n                    if (!relativeReportPath.isEmpty() && !File.separator.equals(relativeReportPath)) {\n                        relativeReportingDirectory = new File(reportingDirectory, relativeReportPath);\n                        relativeBuildDirectory = new File(buildDirectory, relativeReportPath);\n                    }\n\n                    jacocoFiles.add(new File(relativeReportingDirectory, JACOCO_FILE));\n                    jacocoFiles.add(new File(relativeBuildDirectory, JACOCO_FILE));\n                    coberturaFiles.add(new File(relativeReportingDirectory, COBERTURA_FILE));\n                    coberturaFiles.add(new File(relativeBuildDirectory, COBERTURA_FILE));\n                    sagaFiles.add(new File(relativeReportingDirectory, SAGA_FILE));\n                    sagaFiles.add(new File(relativeBuildDirectory, SAGA_FILE));\n                }\n            }\n        }\n        \n        for (File jacocoFile : jacocoFiles) {\n            parsers.add(new JaCoCoParser(jacocoFile, sourceLoader));\n        }\n        for (File coberturaFile : coberturaFiles) {\n            parsers.add(new CoberturaParser(coberturaFile, sourceLoader));\n        }\n        for (File sagaFile : sagaFiles) {\n            parsers.add(new SagaParser(sagaFile, sourceLoader));\n        }\n        \n        if (parsers.isEmpty()) {\n            throw new IOException(\"No coverage report files found\");\n        }\n        \n        return Collections.unmodifiableList(parsers);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/util/ExistingFiles.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Iterator;\n\npublic class ExistingFiles implements Iterable<File> {\n    \n    private final ArrayList<File> delegate = new ArrayList<>();\n\n    public ExistingFiles addAll(final Iterable<File> files) {\n        if (files == null) {\n            throw new NullPointerException(\"Files must be defined\");\n        }\n        for (File file : files) {\n            add(file);\n        }\n        return this;\n    }\n    \n    public ExistingFiles add(final File file) {\n        if (file == null) {\n            throw new NullPointerException(\"File must be defined\");\n        }\n        if (file.exists() && file.isFile() && !delegate.contains(file)) {\n            delegate.add(file);\n        }\n        return this;\n    }\n    \n    @Override\n    public Iterator<File> iterator() {\n        return delegate.iterator();\n    }\n    \n    public static ExistingFiles create(final Iterable<File> files) {\n        ExistingFiles existingFiles = new ExistingFiles();\n        if (files != null) {\n            existingFiles.addAll(files);\n        }\n        return existingFiles;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/util/MavenProjectCollector.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.project.MavenProject;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\npublic class MavenProjectCollector {\n    \n    private final MavenProject root;\n\n    public MavenProjectCollector(final MavenProject root) {\n        this.root = root;\n    }\n    \n    public List<MavenProject> collect() {\n        List<MavenProject> projects = new ArrayList<>();\n        collect(root, projects);\n        return Collections.unmodifiableList(projects);\n    }\n    \n    private void collect(final MavenProject project, final List<MavenProject> projects) {\n        projects.add(project);\n        for (MavenProject child : project.getCollectedProjects()) {\n            collect(child, projects);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/util/Md5DigestInputStream.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.InputStream;\nimport java.security.DigestInputStream;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport org.apache.commons.codec.binary.Hex;\n\npublic class Md5DigestInputStream extends DigestInputStream {\n\n    public Md5DigestInputStream(final InputStream stream) throws NoSuchAlgorithmException {\n        super(stream, MessageDigest.getInstance(\"MD5\"));\n    }\n\n    public String getDigestHex() {\n        return Hex.encodeHexString(getMessageDigest().digest(), false);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/util/SourceLoaderFactory.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.project.MavenProject;\nimport org.eluder.coveralls.maven.plugin.source.DirectorySourceLoader;\nimport org.eluder.coveralls.maven.plugin.source.MultiSourceLoader;\nimport org.eluder.coveralls.maven.plugin.source.ScanSourceLoader;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class SourceLoaderFactory {\n\n    private final File baseDir;\n    private final MavenProject project;\n    private final String sourceEncoding;\n    private List<File> sourceDirectories;\n    private boolean scanForSources;\n\n    public SourceLoaderFactory(final File baseDir, final MavenProject project, final String sourceEncoding) {\n        this.baseDir = baseDir;\n        this.project = project;\n        this.sourceEncoding = sourceEncoding;\n    }\n\n    public SourceLoaderFactory withSourceDirectories(final List<File> sourceDirectories) {\n        this.sourceDirectories = sourceDirectories;\n        return this;\n    }\n\n    public SourceLoaderFactory withScanForSources(final boolean scanForSources) {\n        this.scanForSources = scanForSources;\n        return this;\n    }\n\n    public SourceLoader createSourceLoader() {\n        MultiSourceLoader multiSourceLoader = new MultiSourceLoader();\n        List<File> directories = new ArrayList<>();\n        List<MavenProject> modules = new MavenProjectCollector(project).collect();\n        for (MavenProject module : modules) {\n            for (String sourceRoot : module.getCompileSourceRoots()) {\n                File sourceDirectory = new File(sourceRoot);\n                directories.add(sourceDirectory);\n            }\n        }\n        if (sourceDirectories != null) {\n            directories.addAll(sourceDirectories);\n        }\n        for (File directory: directories) {\n            if (directory.exists() && directory.isDirectory()) {\n                DirectorySourceLoader moduleSourceLoader = new DirectorySourceLoader(baseDir, directory, sourceEncoding);\n                multiSourceLoader.add(moduleSourceLoader);\n            }\n        }\n\n        if (scanForSources) {\n            for (File directory: directories) {\n                if (directory.exists() && directory.isDirectory()) {\n                    ScanSourceLoader scanSourceLoader = new ScanSourceLoader(baseDir, directory, sourceEncoding);\n                    multiSourceLoader.add(scanSourceLoader);\n                }\n            }\n        }\n        return multiSourceLoader;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/util/TimestampParser.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.codehaus.plexus.util.StringUtils;\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\n\nimport java.text.DateFormat;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\n\npublic class TimestampParser {\n\n    public static final String EPOCH_MILLIS = \"EpochMillis\";\n\n    public static final String DEFAULT_FORMAT = \"yyyy-MM-dd'T'HH:mm:ss'Z'\";\n\n    private final Parser parser;\n\n    public TimestampParser(final String format) {\n        try {\n            if (EPOCH_MILLIS.equalsIgnoreCase(format)) {\n                this.parser = new EpochMillisParser();\n            } else if (StringUtils.isNotBlank(format)) {\n                this.parser = new DateFormatParser(format);\n            } else {\n                this.parser = new DateFormatParser(DEFAULT_FORMAT);\n            }\n        } catch (IllegalArgumentException ex) {\n            throw new IllegalArgumentException(\"Invalid timestamp format \\\"\" + format + \"\\\"\", ex);\n        }\n    }\n\n    public Date parse(final String timestamp) throws ProcessingException {\n        if (StringUtils.isBlank(timestamp)) {\n            return null;\n        }\n        try {\n            return parser.parse(timestamp);\n        } catch (Exception ex) {\n            throw new ProcessingException(\"Unable to parse timestamp \\\"\" + timestamp + \"\\\"\", ex);\n        }\n    }\n\n    private interface Parser {\n        Date parse(String timestamp) throws Exception;\n    }\n\n    private static class DateFormatParser implements Parser {\n\n        final DateFormat format;\n\n        DateFormatParser(final String format) {\n            this.format = new SimpleDateFormat(format);\n        }\n\n        @Override\n        public synchronized Date parse(final String timestamp) throws ParseException {\n            return format.parse(timestamp);\n        }\n    }\n\n    private static class EpochMillisParser implements Parser {\n\n        @Override\n        public Date parse(final String timestamp) {\n            return new Date(Long.valueOf(timestamp));\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/util/UrlUtils.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.net.MalformedURLException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\n\npublic final class UrlUtils {\n\n    public static URL create(final String url) {\n        try {\n            return new URL(url);\n        } catch (MalformedURLException ex) {\n            throw new IllegalArgumentException(ex);\n        }\n    }\n\n    public static URI toUri(final URL url) {\n        try {\n            return url.toURI();\n        } catch (URISyntaxException ex) {\n            throw new IllegalArgumentException(ex);\n        }\n    }\n    \n    private UrlUtils() {\n        // hide constructor\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/util/Wildcards.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\n/**\n * Wildcard text utilities.\n */\npublic final class Wildcards {\n\n    /**\n     * Matches text against a wildcard pattern where ? is single letter and * is zero or more\n     * letters.\n     *\n     * @param text the text to test against\n     * @param wildcard the wildcard pattern\n     * @return <code>true</code> if the given text matches the wildcard, otherwise <code>false</code>\n     */\n    public static boolean matches(final String text, final String wildcard) {\n        String pattern = wildcard.replace(\"?\", \"\\\\w\").replace(\"*\", \"\\\\w*\");\n        return (text != null && text.matches(pattern));\n    }\n\n    private Wildcards() {\n        // hide constructor\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/validation/JobValidator.java",
    "content": "package org.eluder.coveralls.maven.plugin.validation;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.codehaus.plexus.util.StringUtils;\nimport org.eluder.coveralls.maven.plugin.domain.Job;\nimport org.eluder.coveralls.maven.plugin.validation.ValidationError.Level;\n\nimport java.util.Collections;\nimport java.util.List;\n\npublic class JobValidator {\n\n    private final Job job;\n\n    public JobValidator(final Job job) {\n        if (job == null) {\n            throw new IllegalArgumentException(\"job must be defined\");\n        }\n        this.job = job;\n    }\n    \n    public ValidationErrors validate() {\n        ValidationErrors errors = new ValidationErrors();\n        errors.addAll(repoTokenOrTravis());\n        errors.addAll(git());\n        return errors;\n    }\n    \n    private List<ValidationError> repoTokenOrTravis() {\n        if (hasValue(job.getRepoToken())) {\n            return Collections.emptyList();\n        }\n        if (hasValue(job.getServiceName()) && hasValue(job.getServiceJobId())) {\n            return Collections.emptyList();\n        }\n        Level level = (job.isDryRun() ? Level.WARN : Level.ERROR);\n        String message = \"Either repository token or service with job id must be defined\";\n        return Collections.singletonList(new ValidationError(level, message));\n    }\n    \n    private List<ValidationError> git() {\n        if (job.getGit() == null) {\n            return Collections.emptyList();\n        }\n        if (hasValue(job.getGit().getHead().getId())) {\n            return Collections.emptyList();\n        }\n        return Collections.singletonList(new ValidationError(Level.ERROR, \"Commit id for HEAD must be defined\"));\n    }\n    \n    private boolean hasValue(final String value) {\n        return StringUtils.isNotBlank(value);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/validation/ValidationError.java",
    "content": "package org.eluder.coveralls.maven.plugin.validation;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\npublic final class ValidationError {\n\n    public enum Level {\n        WARN, ERROR\n    }\n    \n    private final Level level;\n    private final String message;\n    \n    public ValidationError(final Level level, final String message) {\n        if (level == null) {\n            throw new IllegalArgumentException(\"level must be defined\");\n        }\n        if (message == null) {\n            throw new IllegalArgumentException(\"message must be defined\");\n        }\n        this.level = level;\n        this.message = message;\n    }\n\n    public Level getLevel() {\n        return level;\n    }\n    \n    public String getMessage() {\n        return message;\n    }\n    \n    @Override\n    public String toString() {\n        return level + \": \" + message;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/validation/ValidationErrors.java",
    "content": "package org.eluder.coveralls.maven.plugin.validation;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.plugin.logging.Log;\nimport org.eluder.coveralls.maven.plugin.validation.ValidationError.Level;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class ValidationErrors extends ArrayList<ValidationError> {\n\n    public void throwOrInform(final Log log) {\n        List<ValidationError> errors = filter(Level.ERROR);\n        if (!errors.isEmpty()) {\n            throw new ValidationException(errors.get(0).getMessage());\n        }\n        for (ValidationError error : filter(Level.WARN)) {\n            log.warn(error.getMessage());\n        }\n    }\n    \n    private List<ValidationError> filter(final Level level) {\n        List<ValidationError> filtered = new ArrayList<>();\n        for (ValidationError error : this) {\n            if (level.equals(error.getLevel())) {\n                filtered.add(error);\n            }\n        }\n        return filtered;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/eluder/coveralls/maven/plugin/validation/ValidationException.java",
    "content": "package org.eluder.coveralls.maven.plugin.validation;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\npublic class ValidationException extends IllegalArgumentException {\n\n    public ValidationException() {\n        super();\n    }\n\n    public ValidationException(final String s) {\n        super(s);\n    }\n\n    public ValidationException(final Throwable cause) {\n        super(cause);\n    }\n    \n    public ValidationException(final String message, final Throwable cause) {\n        super(message, cause);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/CoverageFixture.java",
    "content": "package org.eluder.coveralls.maven.plugin;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\npublic final class CoverageFixture {\n\n    public static String[][] JAVA_FILES = new String[][] {\n            // file                                                 lines  covered lines               missed lines  covered branches missed brnches\n            { \"org/eluder/coverage/sample/SimpleCoverage.java\",     \"14\",  \"3,6\",                      \"10,11\",      \"\",              \"\" },\n            { \"org/eluder/coverage/sample/InnerClassCoverage.java\", \"31\",  \"3,6,9,10,12,13,16,19,22\",  \"26,27\",      \"\",              \"\" },\n            { \"org/eluder/coverage/sample/PartialCoverage.java\",    \"14\",  \"3,6,7,11\",                 \"9\",          \"6\",             \"6\" }\n    };\n\n    public static String[][] JAVA_FILES_IT = new String[][] {\n            // file                                                 lines  covered lines               missed lines  covered branches missed branches\n            { \"org/eluder/coverage/sample/SimpleCoverage.java\",     \"14\",  \"3,6\",                      \"10,11\",      \"\",              \"\" },\n            { \"org/eluder/coverage/sample/InnerClassCoverage.java\", \"31\",  \"3,6,9,10,12,13,16,19,22\",  \"26,27\",      \"\",              \"\" },\n            { \"org/eluder/coverage/sample/PartialCoverage.java\",    \"14\",  \"3,6,7,9,11\",               \"\",           \"6\",             \"6\" }\n    };\n\n    public static String[][] JAVASCRIPT_FILES = new String[][] {\n            // file                 lines   covered lines   missed lines covered branches missed branches\n            { \"Localization.js\",    \"18\",   \"1,2,4,5,9,13\", \"6,10\",      \"\",              \"\" },\n            { \"Components.js\",      \"5\",    \"1,2\",          \"\",          \"\",              \"\" }\n    };\n    \n    public static int getTotalLines(String[][] fixture) {\n        int lines = 0;\n        for (String[] file : fixture) {\n            lines += Integer.parseInt(file[1]);\n        }\n        return lines;\n    }\n    \n    public static int getTotalFiles(String[][] fixture) {\n        return fixture.length;\n    }\n    \n    private CoverageFixture() {\n        // hide constructor\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/CoverallsReportMojoTest.java",
    "content": "package org.eluder.coveralls.maven.plugin;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.model.Build;\nimport org.apache.maven.model.Model;\nimport org.apache.maven.model.Reporting;\nimport org.apache.maven.plugin.MojoExecutionException;\nimport org.apache.maven.plugin.MojoFailureException;\nimport org.apache.maven.plugin.logging.Log;\nimport org.apache.maven.project.MavenProject;\nimport org.apache.maven.settings.Settings;\nimport org.eluder.coveralls.maven.plugin.domain.CoverallsResponse;\nimport org.eluder.coveralls.maven.plugin.domain.Git;\nimport org.eluder.coveralls.maven.plugin.domain.Job;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.httpclient.CoverallsClient;\nimport org.eluder.coveralls.maven.plugin.json.JsonWriter;\nimport org.eluder.coveralls.maven.plugin.parser.CoberturaParser;\nimport org.eluder.coveralls.maven.plugin.service.ServiceSetup;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\nimport org.eluder.coveralls.maven.plugin.util.TestIoUtil;\nimport org.eluder.coveralls.maven.plugin.validation.ValidationErrors;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.Mockito;\nimport org.mockito.invocation.InvocationOnMock;\nimport org.mockito.runners.MockitoJUnitRunner;\nimport org.mockito.stubbing.Answer;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\n\nimport static org.hamcrest.Matchers.containsString;\nimport static org.junit.Assert.*;\nimport static org.mockito.Matchers.any;\nimport static org.mockito.Matchers.anyString;\nimport static org.mockito.Mockito.*;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class CoverallsReportMojoTest {\n    \n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n    public File coverallsFile;\n    \n    private CoverallsReportMojo mojo;\n    \n    @Mock\n    private CoverallsClient coverallsClientMock;\n    \n    @Mock\n    private SourceLoader sourceLoaderMock;\n    \n    @Mock\n    private Job jobMock;\n\n    @Mock\n    private Log logMock;\n\n    @Mock\n    private MavenProject projectMock;\n\n    @Mock\n    private MavenProject collectedProjectMock;\n    \n    @Mock\n    private Model modelMock;\n    \n    @Mock\n    private Reporting reportingMock;\n    \n    @Mock\n    private Build buildMock;\n\n    @Mock\n    private Settings settingsMock;\n    \n    @Before\n    public void init() throws Exception {\n        coverallsFile = folder.newFile();\n        \n        when(sourceLoaderMock.load(anyString())).then(new Answer<Source>() {\n            @Override\n            public Source answer(final InvocationOnMock invocation) throws Throwable {\n                String sourceFile = invocation.getArguments()[0].toString();\n                String content = readFileContent(sourceFile);\n                return new Source(sourceFile, content, TestIoUtil.getMd5DigestHex(content));\n            }\n        });\n        when(logMock.isInfoEnabled()).thenReturn(true);\n        when(jobMock.validate()).thenReturn(new ValidationErrors());\n\n        \n        mojo = new CoverallsReportMojo() {\n            @Override\n            protected SourceLoader createSourceLoader(final Job job) {\n                return sourceLoaderMock;\n            }\n            @Override\n            protected List<CoverageParser> createCoverageParsers(SourceLoader sourceLoader) throws IOException {\n                List<CoverageParser> parsers = new ArrayList<CoverageParser>();\n                parsers.add(new CoberturaParser(TestIoUtil.getFile(\"cobertura.xml\"), sourceLoader));\n                return parsers;\n            }\n            @Override\n            protected Environment createEnvironment() {\n                return new Environment(this, Collections.<ServiceSetup>emptyList());\n            }\n            @Override\n            protected Job createJob() throws IOException {\n                return jobMock;\n            }\n            @Override\n            protected JsonWriter createJsonWriter(final Job job) throws IOException {\n                return new JsonWriter(jobMock, CoverallsReportMojoTest.this.coverallsFile);\n            }\n            @Override\n            protected CoverallsClient createCoverallsClient() {\n                return coverallsClientMock;\n            }\n            @Override\n            public Log getLog() {\n                return logMock;\n            }\n        };\n        mojo.settings = settingsMock;\n        mojo.project = projectMock;\n        mojo.sourceEncoding = \"UTF-8\";\n        mojo.failOnServiceError = true;\n        \n        when(modelMock.getReporting()).thenReturn(reportingMock);\n        when(reportingMock.getOutputDirectory()).thenReturn(folder.getRoot().getAbsolutePath());\n        when(buildMock.getDirectory()).thenReturn(folder.getRoot().getAbsolutePath());\n        \n        List<MavenProject> projects = new ArrayList<MavenProject>();\n        projects.add(collectedProjectMock);\n        when(projectMock.getCollectedProjects()).thenReturn(projects);\n        when(projectMock.getBuild()).thenReturn(buildMock);\n        when(projectMock.getModel()).thenReturn(modelMock);\n        List<String> sourceRoots = new ArrayList<String>();\n        sourceRoots.add(folder.getRoot().getAbsolutePath());\n        when(collectedProjectMock.getCompileSourceRoots()).thenReturn(sourceRoots);\n        when(collectedProjectMock.getBuild()).thenReturn(buildMock);\n        when(collectedProjectMock.getModel()).thenReturn(modelMock);\n    }\n\n    @Test(expected = IOException.class)\n    public void testCreateCoverageParsersWithoutCoverageReports() throws Exception {\n        mojo = new CoverallsReportMojo();\n        mojo.settings = settingsMock;\n        mojo.project = projectMock;\n        mojo.createCoverageParsers(sourceLoaderMock);\n    }\n\n    @Test\n    public void testCreateSourceLoader() throws Exception {\n        Git gitMock = Mockito.mock(Git.class);\n        when(gitMock.getBaseDir()).thenReturn(folder.newFolder(\"git\"));\n        when(jobMock.getGit()).thenReturn(gitMock);\n        TestIoUtil.writeFileContent(\"public interface Test { }\", folder.newFile(\"source.java\"));\n        mojo = new CoverallsReportMojo();\n        mojo.settings = settingsMock;\n        mojo.project = projectMock;\n        mojo.sourceEncoding = \"UTF-8\";\n        SourceLoader sourceLoader = mojo.createSourceLoader(jobMock);\n        Source source = sourceLoader.load(\"source.java\");\n        assertNotNull(source);\n    }\n\n    @Test\n    public void testDefaultBehavior() throws Exception {\n        mojo = new CoverallsReportMojo() {\n            @Override\n            protected SourceLoader createSourceLoader(final Job job) {\n                return sourceLoaderMock;\n            }\n            @Override\n            protected List<CoverageParser> createCoverageParsers(SourceLoader sourceLoader) throws IOException {\n                return Collections.emptyList();\n            }\n        };\n        mojo.sourceDirectories = Arrays.asList(TestIoUtil.getFile(\"/\"));\n        mojo.sourceEncoding = \"UTF-8\";\n        mojo.settings = settingsMock;\n        mojo.project = projectMock;\n        mojo.repoToken = \"asdfg\";\n        mojo.coverallsFile = folder.newFile();\n        mojo.dryRun = true;\n        mojo.skip = false;\n        mojo.basedir = TestIoUtil.getFile(\"/\");\n        \n        mojo.execute();\n    }\n    \n    @Test\n    public void testSuccesfullSubmission() throws Exception {\n        when(coverallsClientMock.submit(any(File.class))).thenReturn(new CoverallsResponse(\"success\", false, null));\n        mojo.execute();\n        String json = TestIoUtil.readFileContent(coverallsFile);\n        assertNotNull(json);\n        \n        String[][] fixture = CoverageFixture.JAVA_FILES;\n        for (String[] coverageFile : fixture) {\n            assertThat(json, containsString(coverageFile[0]));\n        }\n\n        verifySuccessfullSubmit(logMock, fixture);\n    }\n    \n    @Test\n    public void testFailWithProcessingException() throws Exception {\n        when(coverallsClientMock.submit(any(File.class))).thenThrow(new ProcessingException());\n        try {\n            mojo.execute();\n            fail(\"Should have failed with MojoFailureException\");\n        } catch (MojoFailureException ex) {\n            assertEquals(ex.getCause().getClass(), ProcessingException.class);\n        }\n    }\n\n    @Test\n    public void testProcessingExceptionWithAllowedServiceFailure() throws Exception {\n        mojo.failOnServiceError = false;\n        when(coverallsClientMock.submit(any(File.class))).thenThrow(new ProcessingException());\n        try {\n            mojo.execute();\n            fail(\"Should have failed with MojoFailureException\");\n        } catch (MojoFailureException ex) {\n            assertEquals(ex.getCause().getClass(), ProcessingException.class);\n        }\n    }\n    \n    @Test\n    public void testFailWithIOException() throws Exception {\n        when(coverallsClientMock.submit(any(File.class))).thenThrow(new IOException());\n        try {\n            mojo.execute();\n            fail(\"Should have failed with MojoFailureException\");\n        } catch (MojoFailureException ex) {\n            assertEquals(ex.getCause().getClass(), IOException.class);\n        }\n    }\n\n    @Test\n    public void testIOExceptionWithAllowedServiceFailure() throws Exception {\n        mojo.failOnServiceError = false;\n        when(coverallsClientMock.submit(any(File.class))).thenThrow(new IOException());\n        mojo.execute();\n        verify(logMock).warn(anyString());\n    }\n    \n    @Test\n    public void testFailWithNullPointerException() throws Exception {\n        when(coverallsClientMock.submit(any(File.class))).thenThrow(new NullPointerException());\n        try {\n            mojo.execute();\n            fail(\"Should have failed with MojoFailureException\");\n        } catch (MojoExecutionException ex) {\n            assertEquals(ex.getCause().getClass(), NullPointerException.class);\n        }\n    }\n    \n    @Test\n    public void testSkipExecution() throws Exception {\n        mojo.skip = true;\n        mojo.execute();\n        \n        verifyZeroInteractions(jobMock);\n    }\n    \n    public static void verifySuccessfullSubmit(Log logMock, String[][] fixture) {\n        verify(logMock).info(\"Gathered code coverage metrics for \" + CoverageFixture.getTotalFiles(fixture) + \" source files with \" + CoverageFixture.getTotalLines(fixture) + \" lines of code:\");\n        verify(logMock).info(\"*** It might take hours for Coveralls to update the actual coverage numbers for a job\");\n    }\n\n    protected String readFileContent(final String sourceFile) throws IOException {\n        return TestIoUtil.readFileContent(TestIoUtil.getFile(sourceFile));\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/EnvironmentTest.java",
    "content": "package org.eluder.coveralls.maven.plugin;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.*;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Properties;\n\nimport org.apache.maven.plugin.logging.Log;\nimport org.eluder.coveralls.maven.plugin.service.ServiceSetup;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class EnvironmentTest {\n    \n    private CoverallsReportMojo mojo;\n    \n    @Mock\n    private CoverageParser coverageParserMock;\n    \n    @Mock\n    private Log logMock;\n    \n    @Mock\n    private ServiceSetup serviceMock;\n    \n    @Before\n    public void init() throws Exception {\n        mojo = new CoverallsReportMojo() {\n            @Override\n            protected List<CoverageParser> createCoverageParsers(SourceLoader sourceLoader) {\n                return Arrays.asList(coverageParserMock);\n            }\n\n            @Override\n            public Log getLog() {\n                return logMock;\n            }\n        };\n        mojo.serviceName = \"service\";\n        mojo.sourceEncoding = \"UTF-8\";\n        when(serviceMock.isSelected()).thenReturn(true);\n    }\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testMissingMojo() {\n        new Environment(null, Arrays.asList(serviceMock));\n    }\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testMissingServices() {\n        new Environment(mojo, null);\n    }\n    \n    @Test\n    public void testSetupWithoutServices() {\n        create(Collections.<ServiceSetup>emptyList()).setup();\n        assertEquals(\"service\", mojo.serviceName);\n    }\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testSetupWithoutSourceEncoding() {\n        mojo.sourceEncoding = null;\n        create(Arrays.asList(serviceMock)).setup();\n    }\n    \n    @Test\n    public void testSetupWithIncompleteJob() {\n        when(serviceMock.getJobId()).thenReturn(\"\");\n        when(serviceMock.getBuildUrl()).thenReturn(\"  \");\n        \n        create(Arrays.asList(serviceMock)).setup();\n        assertEquals(\"service\", mojo.serviceName);\n        assertNull(mojo.serviceJobId);\n        assertNull(mojo.serviceBuildNumber);\n        assertNull(mojo.serviceBuildUrl);\n        assertNull(mojo.branch);\n        assertNull(mojo.pullRequest);\n        assertNull(mojo.serviceEnvironment);\n    }\n    \n    @Test\n    public void testSetupWithCompleteJob() {\n        mojo.serviceName = null;\n        Properties environment = new Properties();\n        environment.setProperty(\"env\", \"true\");\n        when(serviceMock.getName()).thenReturn(\"defined service\");\n        when(serviceMock.getJobId()).thenReturn(\"123\");\n        when(serviceMock.getBuildNumber()).thenReturn(\"456\");\n        when(serviceMock.getBuildUrl()).thenReturn(\"http://ci.com/project\");\n        when(serviceMock.getBranch()).thenReturn(\"master\");\n        when(serviceMock.getPullRequest()).thenReturn(\"111\");\n        when(serviceMock.getEnvironment()).thenReturn(environment);\n        \n        create(Arrays.asList(mock(ServiceSetup.class), serviceMock)).setup();\n        assertEquals(\"defined service\", mojo.serviceName);\n        assertEquals(\"123\", mojo.serviceJobId);\n        assertEquals(\"456\", mojo.serviceBuildNumber);\n        assertEquals(\"http://ci.com/project\", mojo.serviceBuildUrl);\n        assertEquals(\"master\", mojo.branch);\n        assertEquals(\"111\", mojo.pullRequest);\n        assertEquals(\"true\", mojo.serviceEnvironment.get(\"env\"));\n    }\n    \n    @Test\n    public void testSetupWithoutJobOverride() {\n        Properties environment = new Properties();\n        environment.setProperty(\"env\", \"true\");\n        Properties serviceEnvironment = new Properties();\n        serviceEnvironment.setProperty(\"env\", \"setProperty\");\n        when(serviceMock.getName()).thenReturn(\"defined service\");\n        when(serviceMock.getJobId()).thenReturn(\"123\");\n        when(serviceMock.getBuildNumber()).thenReturn(\"456\");\n        when(serviceMock.getBuildUrl()).thenReturn(\"http://ci.com/project\");\n        when(serviceMock.getBranch()).thenReturn(\"master\");\n        when(serviceMock.getPullRequest()).thenReturn(\"111\");\n        when(serviceMock.getEnvironment()).thenReturn(environment);\n        mojo.serviceJobId = \"setJobId\";\n        mojo.serviceBuildNumber = \"setBuildNumber\";\n        mojo.serviceBuildUrl = \"setBuildUrl\";\n        mojo.serviceEnvironment = serviceEnvironment;\n        mojo.branch = \"setBranch\";\n        mojo.pullRequest = \"setPullRequest\";\n        \n        create(Arrays.asList(serviceMock)).setup();\n        \n        assertEquals(\"service\", mojo.serviceName);\n        assertEquals(\"setJobId\", mojo.serviceJobId);\n        assertEquals(\"setBuildNumber\", mojo.serviceBuildNumber);\n        assertEquals(\"setBuildUrl\", mojo.serviceBuildUrl);\n        assertEquals(\"setBranch\", mojo.branch);\n        assertEquals(\"setPullRequest\", mojo.pullRequest);\n        assertEquals(\"setProperty\", mojo.serviceEnvironment.get(\"env\"));        \n    }\n    \n    private Environment create(final Iterable<ServiceSetup> services) {\n        return new Environment(mojo, services);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/ProcessingExceptionTest.java",
    "content": "package org.eluder.coveralls.maven.plugin;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\nimport static org.junit.Assert.assertSame;\n\nimport org.junit.Test;\n\npublic class ProcessingExceptionTest {\n\n    private static final String MESSAGE = \"message\";\n    private static final RuntimeException CAUSE = new RuntimeException();\n    \n    @Test\n    public void testException() {\n        ProcessingException exception = new ProcessingException();\n        assertNull(exception.getMessage());\n        assertNull(exception.getCause());\n    }\n    \n    @Test\n    public void testExceptionWithMessage() {\n        ProcessingException exception = new ProcessingException(MESSAGE);\n        assertEquals(MESSAGE, exception.getMessage());\n        assertNull(exception.getCause());\n    }\n\n    @Test\n    public void testExceptionWithCause() {\n        ProcessingException exception = new ProcessingException(CAUSE);\n        assertEquals(CAUSE.toString(), exception.getMessage());\n        assertSame(CAUSE, exception.getCause());\n    }\n    \n    @Test\n    public void testExceptionWithMessageAndCause() {\n        ProcessingException exception = new ProcessingException(MESSAGE, CAUSE);\n        assertEquals(MESSAGE, exception.getMessage());\n        assertSame(CAUSE, exception.getCause());\n\n    }\n    \n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/domain/GitRepositoryTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertNotNull;\n\nimport org.eluder.coveralls.maven.plugin.util.TestIoUtil;\nimport org.junit.Test;\n\npublic class GitRepositoryTest {\n\n    /**\n     * This tests assumes that the project resides in git repository.\n     */\n    @Test\n    public void testLoad() throws Exception {\n        Git git = new GitRepository(TestIoUtil.getFile(\"/\")).load();\n        assertNotNull(git.getHead().getId());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/domain/JobTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\n\nimport java.io.File;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.eluder.coveralls.maven.plugin.domain.Git.Head;\nimport org.eluder.coveralls.maven.plugin.domain.Git.Remote;\nimport org.junit.Test;\n\npublic class JobTest {\n\n    @Test\n    public void testGetBranchWithRemote() {\n        List<Remote> remotes = Arrays.asList(new Remote(\"origin\", \"git@github.com\"));\n        Git git = new Git(new File(\".\"), new Head(null, null, null, null, null, null), \"master\", remotes);\n        Job job = new Job().withBranch(\"origin/master\").withGit(git);\n        assertEquals(\".\", git.getBaseDir().getPath());\n        assertEquals(\"master\", job.getBranch());\n    }\n    \n    @Test\n    public void testGetBranch() {\n        Job job = new Job().withBranch(\"master\");\n        assertEquals(\"master\", job.getBranch());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/domain/SourceTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.domain;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.junit.Ignore;\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\npublic class SourceTest {\n\n    @Test\n    public void testAddCoverage() {\n        Source source = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  \\n}\\n\", \"E8BD88CF0BDB77A6408234FD91FD22C3\");\n        source.addCoverage(1, 3);\n        source.addCoverage(3, 3);\n        assertArrayEquals(new Integer[] { 3, null, 3, null }, source.getCoverage());\n    }\n\n    @Test\n    public void testAddBranchCoverage() {\n        Source source = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  if(true) {\\n  }\\n}\\n\", \"609BD24390ADB11D11536CA2ADD18BD0\");\n        source.addBranchCoverage(2, 0, 0, 2);\n        source.addBranchCoverage(2, 0, 1, 3);\n        assertArrayEquals(new Integer[] { 2, 0, 0, 2, 2, 0, 1, 3 }, source.getBranches());\n    }\n\n    @Test\n    public void testAddSameBranchReplaceExistingOne() {\n        Source source = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  if(true) {\\n  }\\n}\\n\", \"609BD24390ADB11D11536CA2ADD18BD0\");\n        source.addBranchCoverage(2, 0, 0, 2);\n        source.addBranchCoverage(2, 0, 0, 3);\n        assertArrayEquals(new Integer[] { 2, 0, 0, 3 }, source.getBranches());\n    }\n\n    @Test\n    public void testAddSameBranchDoNotKeepOrdering() {\n        Source source = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  if(true) {\\n  }\\n}\\n\", \"609BD24390ADB11D11536CA2ADD18BD0\");\n        source.addBranchCoverage(2, 0, 0, 0);\n        source.addBranchCoverage(2, 0, 1, 0);\n        source.addBranchCoverage(2, 0, 0, 1);\n        assertArrayEquals(new Integer[] { 2, 0, 1, 0, 2, 0, 0, 1 }, source.getBranches());\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testAddCoverageForSourceOutOfBounds() {\n        Source source = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  \\n}\\n\", \"E8BD88CF0BDB77A6408234FD91FD22C3\");\n        source.addCoverage(5, 1);\n    }\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testAddBranchCoverageForSourceOutOfBounds() {\n        Source source = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  if(true) {\\n  }\\n}\\n\", \"609BD24390ADB11D11536CA2ADD18BD0\");\n        source.addBranchCoverage(6, 0, 0, 2);\n    }\n\n    @Test\n    @Ignore(\"#45: https://github.com/trautonen/coveralls-maven-plugin/issues/45\")\n    public void testGetNameWithClassifier() throws Exception {\n        Source source = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  \\n}\\n\", \"E8BD88CF0BDB77A6408234FD91FD22C3\");\n        source.setClassifier(\"Inner\");\n        assertEquals(\"src/main/java/Hello.java\", source.getName());\n        assertEquals(\"src/main/java/Hello.java#Inner\", source.getFullName());\n    }\n\n    @Test\n    public void testMerge() {\n        Source source1 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  if(true) {\\n  }\\n}\\n\", \"609BD24390ADB11D11536CA2ADD18BD0\");\n        source1.addCoverage(1, 2);\n        source1.addCoverage(3, 4);\n        source1.addBranchCoverage(2, 0, 0, 1);\n        Source source2 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  if(true) {\\n  }\\n}\\n\", \"609BD24390ADB11D11536CA2ADD18BD0\");\n        source2.addCoverage(2, 1);\n        source2.addCoverage(3, 3);\n        source2.addBranchCoverage(2, 0, 0, 1);\n        source2.addBranchCoverage(2, 0, 1, 3);\n\n        Source merged = source1.merge(source2);\n        assertFalse(source1 == merged);\n        assertFalse(source2 == merged);\n        assertEquals(source1.getName(), merged.getName());\n        assertEquals(source1.getDigest(), merged.getDigest());\n        assertEquals(source1.getClassifier(), merged.getClassifier());\n        assertEquals(new Integer(2), merged.getCoverage()[0]);\n        assertEquals(new Integer(1), merged.getCoverage()[1]);\n        assertEquals(new Integer(7), merged.getCoverage()[2]);\n        assertNull(merged.getCoverage()[3]);\n        assertEquals(new Integer(2), merged.getBranches()[0]);\n        assertEquals(new Integer(0), merged.getBranches()[1]);\n        assertEquals(new Integer(0), merged.getBranches()[2]);\n        assertEquals(new Integer(2), merged.getBranches()[3]);\n        assertEquals(new Integer(2), merged.getBranches()[4]);\n        assertEquals(new Integer(0), merged.getBranches()[5]);\n        assertEquals(new Integer(1), merged.getBranches()[6]);\n        assertEquals(new Integer(3), merged.getBranches()[7]);\n    }\n\n    @Test\n    public void testMergeDifferent() {\n        Source source1 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  \\n}\\n\", \"E8BD88CF0BDB77A6408234FD91FD22C3\");\n        source1.addCoverage(1, 3);\n        Source source2 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  void();\\n}\\n\", \"CBA7831606B51D1499349451B70758E3\");\n        source2.addCoverage(2, 4);\n        Source merged = source1.merge(source2);\n        assertFalse(source1 == merged);\n        assertFalse(source2 == merged);\n        assertArrayEquals(source1.getCoverage(), merged.getCoverage());\n    }\n\n    @Test\n    public void testEqualsForNull() {\n        Source source = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  \\n}\\n\", \"E8BD88CF0BDB77A6408234FD91FD22C3\");\n        assertFalse(source.equals(null));\n    }\n\n    @Test\n    public void testEqualsForDifferentSources() throws Exception {\n        Source source1 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  \\n}\\n\", \"E8BD88CF0BDB77A6408234FD91FD22C3\");\n        Source source2 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  void();\\n}\\n\", \"CBA7831606B51D1499349451B70758E3\");\n        assertFalse(source1.equals(source2));\n    }\n\n    @Test\n    public void testHashCode() {\n        Source source1 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  \\n}\\n\", \"E8BD88CF0BDB77A6408234FD91FD22C3\");\n        Source source2 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  \\n}\\n\", \"E8BD88CF0BDB77A6408234FD91FD22C3\");\n        Source source3 = new Source(\"src/main/java/Hello.java\", \"public class Hello {\\n  void();\\n}\\n\", \"CBA7831606B51D1499349451B70758E3\");\n        assertTrue(source1.hashCode() == source2.hashCode());\n        assertFalse(source1.hashCode() == source3.hashCode());\n        assertFalse(source2.hashCode() == source3.hashCode());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/httpclient/CoverallsClientTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.httpclient;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport org.apache.http.Header;\nimport org.apache.http.HeaderElement;\nimport org.apache.http.HttpEntity;\nimport org.apache.http.HttpResponse;\nimport org.apache.http.HttpVersion;\nimport org.apache.http.NameValuePair;\nimport org.apache.http.StatusLine;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.client.methods.HttpUriRequest;\nimport org.apache.http.message.BasicStatusLine;\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.CoverallsResponse;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport static org.junit.Assert.assertNotNull;\nimport static org.mockito.Matchers.any;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class CoverallsClientTest {\n\n    @Mock\n    private HttpClient httpClientMock;\n    \n    @Mock\n    private HttpResponse httpResponseMock;\n    \n    @Mock\n    private HttpEntity httpEntityMock;\n    \n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n    \n    private File file;\n    \n    @Before\n    public void init() throws IOException {\n        file = folder.newFile();\n    }\n    \n    @Test\n    public void testConstructors() {\n        assertNotNull(new CoverallsClient(\"http://test.com/coveralls\"));\n        assertNotNull(new CoverallsClient(\"http://test.com/coveralls\", httpClientMock, new ObjectMapper()));\n    }\n    \n    @Test\n    public void testSubmit() throws Exception {\n        StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 200, \"OK\");\n        when(httpResponseMock.getStatusLine()).thenReturn(statusLine);\n        when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock);\n        when(httpResponseMock.getEntity()).thenReturn(httpEntityMock);\n        when(httpEntityMock.getContent()).thenReturn(coverallsResponse(new CoverallsResponse(\"success\", false, \"\")));\n        CoverallsClient client = new CoverallsClient(\"http://test.com/coveralls\", httpClientMock, new ObjectMapper());\n        client.submit(file);\n    }\n\n    @Test(expected = IOException.class)\n    public void testFailOnServiceError() throws Exception {\n        StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 500, \"Internal Error\");\n        when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock);\n        when(httpResponseMock.getStatusLine()).thenReturn(statusLine);\n        CoverallsClient client = new CoverallsClient(\"http://test.com/coveralls\", httpClientMock, new ObjectMapper());\n        client.submit(file);\n    }\n    \n    @Test(expected = ProcessingException.class)\n    public void testParseInvalidResponse() throws Exception {\n        StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 200, \"OK\");\n        when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock);\n        when(httpResponseMock.getStatusLine()).thenReturn(statusLine);\n        when(httpResponseMock.getEntity()).thenReturn(httpEntityMock);\n        when(httpEntityMock.getContent()).thenReturn(new ByteArrayInputStream(\"{bogus}\".getBytes()));\n        CoverallsClient client = new CoverallsClient(\"http://test.com/coveralls\", httpClientMock, new ObjectMapper());\n        client.submit(file);\n    }\n    \n    @Test(expected = ProcessingException.class)\n    public void testParseErrorousResponse() throws Exception {\n        StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 400, \"Bad Request\");\n        when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock);\n        when(httpResponseMock.getStatusLine()).thenReturn(statusLine);\n        when(httpResponseMock.getEntity()).thenReturn(httpEntityMock);\n        when(httpEntityMock.getContent()).thenReturn(coverallsResponse(new CoverallsResponse(\"failure\", true, \"submission failed\")));\n        CoverallsClient client = new CoverallsClient(\"http://test.com/coveralls\", httpClientMock, new ObjectMapper());\n        client.submit(file);\n    }\n    \n    @Test(expected = IOException.class)\n    public void testParseFailingEntity() throws Exception {\n        StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 200, \"OK\");\n        when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock);\n        when(httpResponseMock.getStatusLine()).thenReturn(statusLine);\n        when(httpResponseMock.getEntity()).thenReturn(httpEntityMock);\n        when(httpEntityMock.getContent()).thenThrow(IOException.class);\n        CoverallsClient client = new CoverallsClient(\"http://test.com/coveralls\", httpClientMock, new ObjectMapper());\n        client.submit(file);\n    }\n\n    @Test(expected = ProcessingException.class)\n    public void testParseEntityWithoutContentType() throws Exception {\n        StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 400, \"Bad Request\");\n        when(httpResponseMock.getStatusLine()).thenReturn(statusLine);\n        when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock);\n        when(httpResponseMock.getEntity()).thenReturn(httpEntityMock);\n        Header header = mock(Header.class);\n        HeaderElement element = mock(HeaderElement.class);\n        when(element.getName()).thenReturn(\"HeaderName\");\n        NameValuePair pair = mock(NameValuePair.class);\n        when(pair.getName()).thenReturn(\"name\");\n        when(element.getParameters()).thenReturn(new NameValuePair[] { pair } );\n        when(header.getElements()).thenReturn(new HeaderElement[] { element } );\n        when(httpEntityMock.getContentType()).thenReturn(header);\n        CoverallsClient client = new CoverallsClient(\"http://test.com/coveralls\", httpClientMock, new ObjectMapper());\n        client.submit(file);\n    }\n    \n    private InputStream coverallsResponse(final CoverallsResponse coverallsResponse) throws Exception {\n        String content = new ObjectMapper().writeValueAsString(coverallsResponse);\n        return new ByteArrayInputStream(content.getBytes());\n    }\n    \n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/httpclient/CoverallsProxyClientTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.httpclient;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.settings.Proxy;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertNotNull;\n\npublic class CoverallsProxyClientTest {\n\n    @Test\n    public void testConstructorWithoutProxy() {\n        assertNotNull(new CoverallsProxyClient(\"http://test.com/coveralls\", null));\n    }\n\n    @Test\n    public void testConstructorWithProxy() {\n        Proxy proxy = new Proxy();\n        proxy.setHost(\"localhost\");\n        proxy.setPort(8080);\n        proxy.setProtocol(\"http\");\n\n        assertNotNull(new CoverallsProxyClient(\"http://test.com/coveralls\", proxy));\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/httpclient/HttpClientFactoryTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.httpclient;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport com.github.tomakehurst.wiremock.junit.WireMockRule;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.client.methods.HttpGet;\nimport org.apache.http.util.EntityUtils;\nimport org.apache.maven.settings.Proxy;\nimport org.junit.Assert;\nimport org.junit.Rule;\nimport org.junit.Test;\n\nimport static com.github.tomakehurst.wiremock.client.WireMock.*;\n\npublic class HttpClientFactoryTest {\n\n    private final int PROXY_PORT = 9797;\n    private final int TARGET_PORT = 9696;\n    private final String TARGET_URL = \"http://localhost:\" + TARGET_PORT;\n\n    @Rule\n    public WireMockRule targetServer = new WireMockRule(TARGET_PORT);\n\n    @Rule\n    public WireMockRule proxyServer = new WireMockRule(PROXY_PORT);\n\n\n    @Test\n    public void testSimpleRequest() throws Exception {\n        targetServer.stubFor(get(urlMatching(\".*\")).willReturn(aResponse().withBody(\"Hello World!\")));\n\n        HttpClient client = new HttpClientFactory(TARGET_URL).create();\n        String body = EntityUtils.toString(client.execute(new HttpGet(TARGET_URL)).getEntity());\n\n        Assert.assertEquals(\"Hello World!\", body);\n    }\n\n    @Test\n    public void testUnAuthorizedProxyRequest() throws Exception {\n        targetServer.stubFor(get(urlMatching(\".*\")).willReturn(aResponse().withBody(\"Hello World!\")));\n\n        proxyServer.stubFor(get(urlMatching(\".*\")).willReturn(aResponse().withBody(\"Hello Proxy!\")));\n\n        Proxy proxy = new Proxy();\n        proxy.setHost(\"localhost\");\n        proxy.setPort(PROXY_PORT);\n        proxy.setProtocol(\"http\");\n\n        HttpClient client = new HttpClientFactory(TARGET_URL).proxy(proxy).create();\n        String body = EntityUtils.toString(client.execute(new HttpGet(TARGET_URL)).getEntity());\n\n        Assert.assertEquals(\"Hello Proxy!\", body);\n    }\n\n    @Test\n    public void testAuthorixedProxyRequest() throws Exception {\n        targetServer.stubFor(get(urlMatching(\".*\")).willReturn(aResponse().withBody(\"Hello World!\")));\n\n        proxyServer.stubFor(get(urlMatching(\".*\")).withHeader(\"Proxy-Authorization\", matching(\"Basic Zm9vOmJhcg==\"))\n                .willReturn(aResponse().withBody(\"Hello Proxy!\"))\n                .atPriority(1));\n        proxyServer.stubFor(any(urlMatching(\".*\"))\n                .willReturn(aResponse().withStatus(407).withHeader(\"Proxy-Authenticate\", \"Basic\"))\n                .atPriority(2));\n\n        Proxy proxy = new Proxy();\n        proxy.setHost(\"localhost\");\n        proxy.setPort(PROXY_PORT);\n        proxy.setProtocol(\"http\");\n        proxy.setUsername(\"foo\");\n        proxy.setPassword(\"bar\");\n\n        HttpClient client = new HttpClientFactory(TARGET_URL).proxy(proxy).create();\n        String body = EntityUtils.toString(client.execute(new HttpGet(TARGET_URL)).getEntity());\n\n        Assert.assertEquals(\"Hello Proxy!\", body);\n    }\n\n    @Test\n    public void testNonProxiedHostRequest() throws Exception {\n        targetServer.stubFor(get(urlMatching(\".*\")).willReturn(aResponse().withBody(\"Hello World!\")));\n\n        proxyServer.stubFor(get(urlMatching(\".*\")).willReturn(aResponse().withBody(\"Hello Proxy!\")));\n\n        Proxy proxy = new Proxy();\n        proxy.setHost(\"localhost\");\n        proxy.setPort(PROXY_PORT);\n        proxy.setProtocol(\"http\");\n        proxy.setNonProxyHosts(\"localhost|example.com\");\n\n        HttpClient client = new HttpClientFactory(TARGET_URL).proxy(proxy).create();\n        String body = EntityUtils.toString(client.execute(new HttpGet(TARGET_URL)).getEntity());\n\n        Assert.assertEquals(\"Hello World!\", body);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/json/JsonWriterTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.json;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.type.MapType;\nimport org.eluder.coveralls.maven.plugin.domain.Git;\nimport org.eluder.coveralls.maven.plugin.domain.Job;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.util.TestIoUtil;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.sql.Date;\nimport java.text.SimpleDateFormat;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertSame;\nimport static org.junit.Assert.assertTrue;\n\npublic class JsonWriterTest {\n\n    private static final long TEST_TIME = 1357009200000l;\n    \n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n    \n    private File file;\n    \n    @Before\n    public void init() throws IOException {\n        file = folder.newFile();\n    }\n\n    @Test\n    public void testSubDirectoryCreation() throws Exception {\n        File f = new File(new File(folder.getRoot(), \"sub1\"), \"sub2\");\n        Job job = job();\n        assertTrue(new JsonWriter(job, f).getCoverallsFile().getParentFile().isDirectory());\n    }\n\n    @Test\n    @SuppressWarnings(\"resource\")\n    public void testGetJob() throws Exception {\n        Job job = job();\n        assertSame(job, new JsonWriter(job, file).getJob());\n    }\n    \n    @Test\n    @SuppressWarnings(\"resource\")\n    public void testGetCoverallsFile() throws Exception {\n        Job job = job();\n        assertSame(file, new JsonWriter(job, file).getCoverallsFile());\n        \n    }\n    \n    @SuppressWarnings(\"rawtypes\")\n    @Test\n    public void testWriteStartAndEnd() throws Exception {\n        JsonWriter writer = new JsonWriter(job(), file);\n        try {\n            writer.onBegin();\n            writer.onComplete();\n        } finally {\n            writer.close();\n        }\n        String content = TestIoUtil.readFileContent(file);\n        Map<String, Object> jsonMap = stringToJsonMap(content);\n        assertEquals(\"service\", jsonMap.get(\"service_name\"));\n        assertEquals(\"job123\", jsonMap.get(\"service_job_id\"));\n        assertEquals(\"build5\", jsonMap.get(\"service_number\"));\n        assertEquals(\"http://ci.com/build5\", jsonMap.get(\"service_build_url\"));\n        assertEquals(\"foobar\", ((Map) jsonMap.get(\"environment\")).get(\"custom_property\"));\n        assertEquals(\"master\", jsonMap.get(\"service_branch\"));\n        assertEquals(\"pull10\", jsonMap.get(\"service_pull_request\"));\n        assertEquals(new SimpleDateFormat(JsonWriter.TIMESTAMP_FORMAT).format(new Date(TEST_TIME)), jsonMap.get(\"run_at\"));\n        assertEquals(\"af456fge34acd\", ((Map) jsonMap.get(\"git\")).get(\"branch\"));\n        assertEquals(\"aefg837fge\", ((Map) ((Map) jsonMap.get(\"git\")).get(\"head\")).get(\"id\"));\n        assertEquals(0, ((Collection<?>) jsonMap.get(\"source_files\")).size());\n    }\n    \n    @Test\n    public void testOnSource() throws Exception {\n        JsonWriter writer = new JsonWriter(job(), file);\n        try {\n            writer.onBegin();\n            writer.onSource(source());\n            writer.onComplete();\n        } finally {\n            writer.close();\n        }\n        String content = TestIoUtil.readFileContent(file);\n        Map<String, Object> jsonMap = stringToJsonMap(content);\n        jsonMap = ((List<Map<String, Object>>)jsonMap.get(\"source_files\")).get(0);\n        assertEquals(\"Foo.java\", jsonMap.get(\"name\"));\n        assertEquals(\"6E0F89B516198DC6AB743EA5FBFB3108\", jsonMap.get(\"source_digest\"));\n        assertEquals(1, ((Collection<?>) jsonMap.get(\"coverage\")).size());\n    }\n    \n    private Job job() {\n        Git.Head head = new Git.Head(\"aefg837fge\", \"john\", \"john@mail.com\", \"john\", \"john@mail.com\", \"test commit\");\n        Git.Remote remote = new Git.Remote(\"origin\", \"git@git.com:foo.git\");\n        Properties environment = new Properties();\n        environment.setProperty(\"custom_property\", \"foobar\");\n        return new Job()\n            .withServiceName(\"service\")\n            .withServiceJobId(\"job123\")\n            .withServiceBuildNumber(\"build5\")\n            .withServiceBuildUrl(\"http://ci.com/build5\")\n            .withServiceEnvironment(environment)\n            .withBranch(\"master\")\n            .withPullRequest(\"pull10\")\n            .withTimestamp(new Date(TEST_TIME))\n            .withGit(new Git(null, head, \"af456fge34acd\", Arrays.asList(remote)));\n    }\n    \n    private Source source() {\n        return new Source(\"Foo.java\", \"public class Foo { }\", \"6E0F89B516198DC6AB743EA5FBFB3108\");\n    }\n    \n    private Map<String, Object> stringToJsonMap(final String content) throws Exception {\n        ObjectMapper mapper = new ObjectMapper();\n        MapType type = mapper.getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);\n        return mapper.readValue(content, type);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/logging/CoverageTracingLoggerTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.logging;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.plugin.logging.Log;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.logging.Logger.Position;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.UniqueSourceCallback;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Matchers.any;\nimport static org.mockito.Mockito.times;\nimport static org.mockito.Mockito.verify;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class CoverageTracingLoggerTest {\n\n    @Mock\n    private Log logMock;\n    \n    @Mock\n    private SourceCallback sourceCallbackMock;\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testConstructorWithNull() {\n        new CoverageTracingLogger(null);\n    }\n    \n    @Test\n    public void testGetPosition() {\n        assertEquals(Position.AFTER, new CoverageTracingLogger(sourceCallbackMock).getPosition());\n    }\n    \n    @Test\n    public void testLogForSources() throws Exception {\n        Source source1 = new Source(\"Source1.java\", \"public class Source1 {\\n  if(true) { }\\n}\\n\", \"FE0538639E8CE73733E77659C1043B5C\");\n        source1.addCoverage(1, 0);\n        source1.addCoverage(2, 0);\n        source1.addCoverage(3, 0);\n        source1.addBranchCoverage(2, 0, 0, 3);\n        source1.addBranchCoverage(2, 0, 1, 0);\n        Source source2 = new Source(\"Source2.java\", \"public class Source2 {\\n    new Interface() { public void run() { } };\\n}\\n\", \"34BD6501A6D1CE5181AECEA688C7D382\");\n        source2.addCoverage(1, 1);\n        source2.addCoverage(3, 1);\n        Source source2inner = new Source(\"Source2.java\", \"public class Source2 {\\n    new Interface() { public void run() { } };\\n}\\n\", \"34BD6501A6D1CE5181AECEA688C7D382\");\n        source2inner.setClassifier(\"$1\");\n        source2inner.addCoverage(2, 1);\n        \n        CoverageTracingLogger coverageTracingLogger = new CoverageTracingLogger(sourceCallbackMock);\n        UniqueSourceCallback uniqueSourceCallback = new UniqueSourceCallback(coverageTracingLogger);\n        uniqueSourceCallback.onSource(source1);\n        uniqueSourceCallback.onSource(source2);\n        uniqueSourceCallback.onSource(source2inner);\n        uniqueSourceCallback.onComplete();\n        coverageTracingLogger.log(logMock);\n        \n        assertEquals(8, coverageTracingLogger.getLines());\n        assertEquals(6, coverageTracingLogger.getRelevant());\n        assertEquals(3, coverageTracingLogger.getCovered());\n        assertEquals(3, coverageTracingLogger.getMissed());\n        assertEquals(2, coverageTracingLogger.getBranches());\n        assertEquals(1, coverageTracingLogger.getCoveredBranches());\n        assertEquals(1, coverageTracingLogger.getMissedBranches());\n        verify(sourceCallbackMock, times(2)).onSource(any(Source.class));\n        verify(logMock).info(\"Gathered code coverage metrics for 2 source files with 8 lines of code:\");\n        verify(logMock).info(\"- 6 relevant lines\");\n        verify(logMock).info(\"- 3 covered lines\");\n        verify(logMock).info(\"- 3 missed lines\");\n        verify(logMock).info(\"- 2 branches\");\n        verify(logMock).info(\"- 2 branches\");\n        verify(logMock).info(\"- 1 covered branches\");\n        verify(logMock).info(\"- 1 missed branches\");\n    }\n    \n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/logging/DryRunLoggerTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.logging;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.verifyZeroInteractions;\nimport static org.mockito.Mockito.when;\n\nimport java.io.File;\n\nimport org.apache.maven.plugin.logging.Log;\nimport org.eluder.coveralls.maven.plugin.logging.Logger.Position;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class DryRunLoggerTest {\n\n    @Mock\n    private Log logMock;\n    \n    @Mock\n    private File coverallsFileMock;\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testMissingCoverallsFile() {\n        new DryRunLogger(true, null);\n    }\n    \n    @Test\n    public void testGetPosition() {\n        assertEquals(Position.AFTER, new DryRunLogger(true, coverallsFileMock).getPosition());\n    }\n    \n    @Test\n    public void testLogDryRunDisabled() {\n        new DryRunLogger(false, coverallsFileMock).log(logMock);\n        \n        verifyZeroInteractions(logMock);\n    }\n    \n    @Test\n    public void testLogDryRunEnabled() {\n        when(coverallsFileMock.length()).thenReturn(1024l);\n        when(coverallsFileMock.getAbsolutePath()).thenReturn(\"/target/coveralls.json\");\n        \n        new DryRunLogger(true, coverallsFileMock).log(logMock);\n        \n        verify(logMock).info(\"Dry run enabled, Coveralls report will NOT be submitted to API\");\n        verify(logMock).info(\"1024 bytes of data was recorded in /target/coveralls.json\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/logging/JobLoggerTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.logging;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Matchers.same;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.verifyNoMoreInteractions;\nimport static org.mockito.Mockito.when;\n\nimport org.apache.maven.plugin.logging.Log;\nimport org.eluder.coveralls.maven.plugin.domain.Git;\nimport org.eluder.coveralls.maven.plugin.domain.Git.Head;\nimport org.eluder.coveralls.maven.plugin.domain.Job;\nimport org.eluder.coveralls.maven.plugin.logging.Logger.Position;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class JobLoggerTest {\n\n    @Mock\n    private Job jobMock;\n    \n    @Mock\n    private Log logMock;\n    \n    @Mock\n    private ObjectMapper jsonMapperMock;\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testMissingJob() {\n        new JobLogger(null);\n    }\n    \n    @Test\n    public void testGetPosition() {\n        assertEquals(Position.BEFORE, new JobLogger(jobMock).getPosition());\n    }\n    \n    @Test\n    public void testLogJobWithId() {\n        Git git = new Git(null, new Head(\"ab679cf2d81ac\", null, null, null, null, null), \"master\", null);\n        when(jobMock.getServiceName()).thenReturn(\"service\");\n        when(jobMock.getServiceJobId()).thenReturn(\"666\");\n        when(jobMock.getRepoToken()).thenReturn(\"123456789\");\n        when(jobMock.isDryRun()).thenReturn(true);\n        when(jobMock.getGit()).thenReturn(git);\n        \n        new JobLogger(jobMock).log(logMock);\n        \n        verify(logMock).info(\"Starting Coveralls job for service (666) in dry run mode\");\n        verify(logMock).info(\"Using repository token <secret>\");\n        verify(logMock).info(\"Git commit ab679cf in master\");\n        verify(logMock).isDebugEnabled();\n        verifyNoMoreInteractions(logMock);\n    }\n    \n    @Test\n    public void testLogWithBuildNumberAndUrl() {\n        when(jobMock.getServiceName()).thenReturn(\"service\");\n        when(jobMock.getServiceBuildNumber()).thenReturn(\"10\");\n        when(jobMock.getServiceBuildUrl()).thenReturn(\"http://ci.com/build/10\");\n        \n        new JobLogger(jobMock).log(logMock);\n        \n        verify(logMock).info(\"Starting Coveralls job for service (10 / http://ci.com/build/10)\");\n        verify(logMock).isDebugEnabled();\n        verifyNoMoreInteractions(logMock);\n    }\n    \n    @Test\n    public void testLogDryRun() {\n        when(jobMock.isDryRun()).thenReturn(true);\n        \n        new JobLogger(jobMock).log(logMock);\n        \n        verify(logMock).info(\"Starting Coveralls job in dry run mode\");\n        verify(logMock).isDebugEnabled();\n        verifyNoMoreInteractions(logMock);\n    }\n\n    @Test\n    public void testLogParallel() {\n        when(jobMock.isParallel()).thenReturn(true);\n\n        new JobLogger(jobMock).log(logMock);\n\n        verify(logMock).info(\"Starting Coveralls job with parallel option enabled\");\n        verify(logMock).isDebugEnabled();\n        verifyNoMoreInteractions(logMock);\n\n    }\n    \n    @Test\n    public void testLogJobWithDebug() throws Exception {\n        when(logMock.isDebugEnabled()).thenReturn(true);\n        when(jobMock.getServiceName()).thenReturn(\"service\");\n        when(jsonMapperMock.writeValueAsString(same(jobMock))).thenReturn(\"{\\\"serviceName\\\":\\\"service\\\"}\");\n        \n        new JobLogger(jobMock, jsonMapperMock).log(logMock);\n        \n        verify(logMock).info(\"Starting Coveralls job for service\");\n        verify(logMock).isDebugEnabled();\n        verify(logMock).debug(\"Complete Job description:\\n{\\\"serviceName\\\":\\\"service\\\"}\");\n        verifyNoMoreInteractions(logMock);\n    }\n    \n    @Test(expected = RuntimeException.class)\n    @SuppressWarnings(\"unchecked\")\n    public void testLogJobWithErrorInDebug() throws Exception {\n        when(logMock.isDebugEnabled()).thenReturn(true);\n        when(jobMock.getServiceName()).thenReturn(\"service\");\n        when(jsonMapperMock.writeValueAsString(same(jobMock))).thenThrow(JsonProcessingException.class);\n        \n        new JobLogger(jobMock, jsonMapperMock).log(logMock);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/parser/AbstractCoverageParserTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.parser;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.CoverageFixture;\nimport org.eluder.coveralls.maven.plugin.CoverageParser;\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.eluder.coveralls.maven.plugin.domain.Branch;\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.source.ChainingSourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.SourceCallback;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\nimport org.eluder.coveralls.maven.plugin.source.UniqueSourceCallback;\nimport org.eluder.coveralls.maven.plugin.util.TestIoUtil;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.ArgumentCaptor;\nimport org.mockito.Mock;\nimport org.mockito.invocation.InvocationOnMock;\nimport org.mockito.runners.MockitoJUnitRunner;\nimport org.mockito.stubbing.Answer;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport static org.junit.Assert.*;\nimport static org.mockito.Mockito.*;\n\n@RunWith(MockitoJUnitRunner.class)\npublic abstract class AbstractCoverageParserTest {\n    \n    @Mock\n    protected SourceLoader sourceLoaderMock;\n    \n    @Mock\n    protected SourceCallback sourceCallbackMock;\n    \n    @Before\n    public void init() throws IOException {\n        for (String[] coverageFile : getCoverageFixture()) {\n            final String name = sourceName(coverageFile[0]);\n            final String content = TestIoUtil.readFileContent(TestIoUtil.getFile(name));\n            when(sourceLoaderMock.load(name)).then(sourceAnswer(name, content));\n        }\n    }\n    \n    protected String sourceName(final String coverageFile) {\n        return coverageFile;\n    }\n    \n    protected Answer<Source> sourceAnswer(final String name, final String content) {\n        return new Answer<Source>() {\n            @Override\n            public Source answer(final InvocationOnMock invocation) throws Throwable {\n                return new Source(name, content, TestIoUtil.getMd5DigestHex(content));\n            }\n        };\n    }\n\n    @Test\n    public void testParseCoverage() throws Exception {\n        for (String coverageResource : getCoverageResources()) {\n            CoverageParser parser = createCoverageParser(TestIoUtil.getFile(coverageResource), sourceLoaderMock);\n            parser.parse(sourceCallbackMock);\n        }\n        \n        String[][] fixture = getCoverageFixture();\n        \n        ArgumentCaptor<Source> captor = ArgumentCaptor.forClass(Source.class);\n        verify(sourceCallbackMock, atLeast(CoverageFixture.getTotalFiles(fixture))).onSource(captor.capture());\n\n        SourceCollector sourceCollector = new SourceCollector();\n        UniqueSourceCallback uniqueSourceCallback = new UniqueSourceCallback(sourceCollector);\n        ClassifierRemover classifierRemover = new ClassifierRemover(uniqueSourceCallback);\n        classifierRemover.onBegin();\n        for (Source source: captor.getAllValues()) {\n            classifierRemover.onSource(source);\n        }\n        classifierRemover.onComplete();\n\n        for (String[] coverageFile : fixture) {\n            assertCoverage(sourceCollector.sources, coverageFile[0], Integer.parseInt(coverageFile[1]),\n                    toIntegerSet(coverageFile[2]), toIntegerSet(coverageFile[3]),\n                    toIntegerSet(coverageFile[4]), toIntegerSet(coverageFile[5]));\n        }\n    }\n    \n    protected abstract CoverageParser createCoverageParser(File coverageFile, SourceLoader sourceLoader);\n    \n    protected abstract List<String> getCoverageResources();\n\n    protected abstract String[][] getCoverageFixture();\n    \n    private Set<Integer> toIntegerSet(final String commaSeparated) {\n        if (commaSeparated.isEmpty()) {\n            return Collections.emptySet();\n        }\n        String[] split = commaSeparated.split(\",\");\n        Set<Integer> values = new HashSet<>();\n        for (String value : split) {\n            values.add(Integer.valueOf(value));\n        }\n        return values;\n    }\n\n    private static class SourceCollector implements SourceCallback {\n\n        private List<Source> sources = new ArrayList<>();\n\n        @Override\n        public void onBegin() throws ProcessingException, IOException {\n\n        }\n\n        @Override\n        public void onSource(Source source) throws ProcessingException, IOException {\n            sources.add(source);\n        }\n\n        @Override\n        public void onComplete() throws ProcessingException, IOException {\n\n        }\n    }\n\n    private static class ClassifierRemover extends ChainingSourceCallback {\n\n        public ClassifierRemover(SourceCallback chained) {\n            super(chained);\n        }\n\n        @Override\n        protected void onSourceInternal(Source source) throws ProcessingException, IOException {\n            source.setClassifier(null);\n        }\n    }\n\n    private static void assertCoverage(final Collection<Source> sources, final String name, final int lines,\n            final Set<Integer> coveredLines, final Set<Integer> missedLines,\n            final Set<Integer> coveredBranches, final Set<Integer> missedBranches) {\n\n        Source tested = null;\n        for (Source source : sources) {\n            if (source.getName().endsWith(name)) {\n                tested = source;\n                break;\n            }\n        }\n        if (tested == null) {\n            fail(\"Expected source \" + name + \" not found from coverage report\");\n        }\n        if (tested.getCoverage().length != lines) {\n            fail(\"Expected \" + lines + \" lines for \" + name + \" was \" + tested.getCoverage().length);\n        }\n        for (int i = 0; i < tested.getCoverage().length; i++) {\n            Integer lineNumber = i + 1;\n            String message = name + \" line \" + lineNumber + \" coverage\";\n            if (coveredLines.contains(lineNumber)) {\n                assertTrue(message, tested.getCoverage()[i] > 0);\n            } else if (missedLines.contains(lineNumber)) {\n                assertTrue(message, tested.getCoverage()[i] == 0);\n            } else {\n                assertNull(message, tested.getCoverage()[i]);\n            }\n        }\n        for (final Branch b : tested.getBranchesList()) {\n            final String message = name + \" branch \" + b.getBranchNumber() + \" coverage in line \" + b.getLineNumber();\n            if (b.getHits() > 0) {\n                assertTrue(message, coveredBranches.contains(b.getLineNumber()));\n            } else {\n                assertTrue(message, missedBranches.contains(b.getLineNumber()));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/parser/CoberturaParserTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.parser;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.eluder.coveralls.maven.plugin.CoverageFixture;\nimport org.eluder.coveralls.maven.plugin.CoverageParser;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\npublic class CoberturaParserTest extends AbstractCoverageParserTest {\n\n    @Override\n    protected CoverageParser createCoverageParser(final File coverageFile, final SourceLoader sourceLoader) {\n        return new CoberturaParser(coverageFile, sourceLoader);\n    }\n    \n    @Override\n    protected List<String> getCoverageResources() {\n        return Arrays.asList(\"cobertura.xml\");\n    }\n\n    @Override\n    protected String[][] getCoverageFixture() {\n        return CoverageFixture.JAVA_FILES;\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/parser/JaCoCoParserTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.parser;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.CoverageFixture;\nimport org.eluder.coveralls.maven.plugin.CoverageParser;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\nimport java.io.File;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class JaCoCoParserTest extends AbstractCoverageParserTest {\n    \n    @Override\n    protected CoverageParser createCoverageParser(final File coverageFile, final SourceLoader sourceLoader) {\n        return new JaCoCoParser(coverageFile, sourceLoader);\n    }\n    \n    @Override\n    protected List<String> getCoverageResources() {\n        return Arrays.asList(\"jacoco1.xml\", \"jacoco2.xml\", \"jacoco2-it.xml\");\n    }\n\n    @Override\n    protected String[][] getCoverageFixture() {\n        return CoverageFixture.JAVA_FILES_IT;\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/parser/SagaParserTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.parser;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.eluder.coveralls.maven.plugin.CoverageFixture;\nimport org.eluder.coveralls.maven.plugin.CoverageParser;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\n\n/**\n * @author Jakub Bednář (25/12/2013 10:17)\n */\npublic class SagaParserTest extends AbstractCoverageParserTest {\n\n    @Override\n    protected CoverageParser createCoverageParser(final File coverageFile, final SourceLoader sourceLoader) {\n        return new SagaParser(coverageFile, sourceLoader);\n    }\n\n    @Override\n    protected List<String> getCoverageResources() {\n        return Arrays.asList(\"saga.xml\");\n    }\n\n    @Override\n    protected String[][] getCoverageFixture() {\n        return CoverageFixture.JAVASCRIPT_FILES;\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/AbstractServiceSetupTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.junit.Test;\n\npublic class AbstractServiceSetupTest {\n\n    @Test\n    public void testGetMissingProperty() {\n        AbstractServiceSetup serviceSetup = create(new HashMap<String, String>());\n        assertNull(serviceSetup.getProperty(\"property\"));\n    }\n    \n    @Test\n    public void testGetProperty() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(\"CI_NAME\", \"bamboo\");\n        assertEquals(\"bamboo\", create(env).getProperty(\"CI_NAME\"));\n    }\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testAddPropertyWithoutName() {\n        create(new HashMap<String, String>()).addProperty(new Properties(), null, \"value\");\n    }\n    \n    @Test\n    public void testAddPropertyWithoutValue() {\n        Properties properties = new Properties();\n        create(new HashMap<String, String>()).addProperty(properties, \"prop\", \" \");\n        assertNull(properties.getProperty(\"prop\"));\n    }\n    \n    @Test\n    public void testAddPropertyWithValue() {\n        Properties properties = new Properties();\n        create(new HashMap<String, String>()).addProperty(properties, \"prop\", \"value\");\n        assertEquals(\"value\", properties.getProperty(\"prop\"));\n    }\n    \n    @Test\n    public void testGetDefaultValues() {\n        AbstractServiceSetup serviceSetup = create(new HashMap<String, String>());\n        assertNull(serviceSetup.getName());\n        assertNull(serviceSetup.getJobId());\n        assertNull(serviceSetup.getBuildNumber());\n        assertNull(serviceSetup.getBuildUrl());\n        assertNull(serviceSetup.getBranch());\n        assertNull(serviceSetup.getPullRequest());\n        assertNull(serviceSetup.getEnvironment());\n    }\n    \n    private AbstractServiceSetup create(final Map<String, String> env) {\n        return new AbstractServiceSetup(env) {\n            @Override\n            public boolean isSelected() {\n                return true;\n            }\n            @Override\n            public String getName() {\n                return getProperty(\"CI_NAME\");\n            }\n        };\n    }\n    \n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/AppveyorTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.junit.Test;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport static org.junit.Assert.*;\n\npublic class AppveyorTest {\n\n    private Map<String, String> env() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(Appveyor.APPVEYOR, \"true\");\n        env.put(Appveyor.APPVEYOR_BUILD_ID, \"54de3316c44f\");\n        env.put(Appveyor.APPVEYOR_BUILD_NUMBER, \"77\");\n        env.put(Appveyor.APPVEYOR_BRANCH, \"master\");\n        env.put(Appveyor.APPVEYOR_COMMIT, \"a3562fgcd2\");\n        env.put(Appveyor.APPVEYOR_PULL_REQUEST, \"10\");\n        env.put(Appveyor.APPVEYOR_REPO_NAME, \"owner/project\");\n        return env;\n    }\n\n    @Test\n    public void testIsSelectedForNothing() {\n        assertFalse(new Appveyor(new HashMap<String, String>()).isSelected());\n    }\n\n    @Test\n    public void testIsSelectedForAppveyor() {\n        assertTrue(new Appveyor(env()).isSelected());\n    }\n\n    @Test\n    public void testGetName() {\n        assertEquals(\"Appveyor\", new Appveyor(env()).getName());\n    }\n\n    @Test\n    public void testGetBuildNumber() {\n        assertEquals(\"77\", new Appveyor(env()).getBuildNumber());\n    }\n\n    @Test\n    public void testGetBuildUrl() {\n        assertEquals(\"https://ci.appveyor.com/project/owner/project/build/77\", new Appveyor(env()).getBuildUrl());\n    }\n\n    @Test\n    public void testGetBranch() {\n        assertEquals(\"master\", new Appveyor(env()).getBranch());\n    }\n\n    @Test\n    public void testPullRequest() {\n        assertEquals(\"10\", new Appveyor(env()).getPullRequest());\n    }\n\n    @Test\n    public void testGetJobId() {\n        assertEquals(\"54de3316c44f\", new Appveyor(env()).getJobId());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/BambooTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.junit.Test;\n\npublic class BambooTest {\n\n    private Map<String, String> env() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(\"bamboo.buildNumber\", \"build123\");\n        env.put(\"bamboo.buildResultsUrl\", \"http://company.com/bamboo/build123\");\n        env.put(\"bamboo.repository.git.branch\", \"master\");\n        return env;\n    }\n    \n    @Test\n    public void testIsSelectedForNothing() {\n        assertFalse(new Bamboo(new HashMap<String, String>()).isSelected());\n    }\n    \n    @Test\n    public void testIsSelectedForBamboo() {\n        assertTrue(new Bamboo(env()).isSelected());\n    }\n    \n    @Test\n    public void testGetName() {\n        assertEquals(\"bamboo\", new Bamboo(env()).getName());\n    }\n    \n    @Test\n    public void testGetBuildNumber() {\n        assertEquals(\"build123\", new Bamboo(env()).getBuildNumber());\n    }\n    \n    @Test\n    public void testGetBuildUrl() {\n        assertEquals(\"http://company.com/bamboo/build123\", new Bamboo(env()).getBuildUrl());\n    }\n    \n    @Test\n    public void testGetBranch() {\n        assertEquals(\"master\", new Bamboo(env()).getBranch());\n    }\n    \n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/CircleTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.junit.Test;\n\npublic class CircleTest {\n\n    private Map<String, String> env() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(\"CIRCLECI\", \"true\");\n        env.put(\"CIRCLE_BUILD_NUM\", \"build123\");\n        env.put(\"CIRCLE_BRANCH\", \"master\");\n        env.put(\"CIRCLE_SHA1\", \"a3562fgcd2\");\n        return env;\n    }\n    \n    @Test\n    public void testIsSelectedForNothing() {\n        assertFalse(new Circle(new HashMap<String, String>()).isSelected());\n    }\n    \n    @Test\n    public void testIsSelectedForCircle() {\n        assertTrue(new Circle(env()).isSelected());\n    }\n    \n    @Test\n    public void testGetName() {\n        assertEquals(\"circleci\", new Circle(env()).getName());\n    }\n    \n    @Test\n    public void testGetBuildNumber() {\n        assertEquals(\"build123\", new Circle(env()).getBuildNumber());\n    }\n    \n    @Test\n    public void testGetBranch() {\n        assertEquals(\"master\", new Circle(env()).getBranch());\n    }\n    \n    @Test\n    public void testGetEnvironment() {\n        Properties properties = new Circle(env()).getEnvironment();\n        assertEquals(3, properties.size());\n        assertEquals(\"build123\", properties.getProperty(\"circleci_build_num\"));\n        assertEquals(\"master\", properties.getProperty(\"branch\"));\n        assertEquals(\"a3562fgcd2\", properties.getProperty(\"commit_sha\"));\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/GeneralTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.junit.Test;\n\npublic class GeneralTest {\n\n    private Map<String, String> env() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(\"CI_NAME\", \"ci_service\");\n        env.put(\"CI_BUILD_NUMBER\", \"build123\");\n        env.put(\"CI_BUILD_URL\", \"http://ci.com/build123\");\n        env.put(\"CI_BRANCH\", \"master\");\n        env.put(\"CI_PULL_REQUEST\", \"pull10\");\n        return env;\n    }\n    \n    @Test\n    public void testIsSelectedForNothing() {\n        assertFalse(new General(new HashMap<String, String>()).isSelected());\n    }\n    \n    @Test\n    public void testIsSelectedForCi() {\n        assertTrue(new General(env()).isSelected());\n    }\n    \n    @Test\n    public void testGetName() {\n        assertEquals(\"ci_service\", new General(env()).getName());\n    }\n    \n    @Test\n    public void testGetBuildNumber() {\n        assertEquals(\"build123\", new General(env()).getBuildNumber());\n    }\n    \n    @Test\n    public void testGetBuildUrl() {\n        assertEquals(\"http://ci.com/build123\", new General(env()).getBuildUrl());\n    }\n    \n    @Test\n    public void testGetBranch() {\n        assertEquals(\"master\", new General(env()).getBranch());\n    }\n    \n    @Test\n    public void testGetPullRequest() {\n        assertEquals(\"pull10\", new General(env()).getPullRequest());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/JenkinsTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.junit.Test;\n\npublic class JenkinsTest {\n\n    private Map<String, String> env() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(\"JENKINS_URL\", \"http://company.com/jenkins\");\n        env.put(\"BUILD_NUMBER\", \"build123\");\n        env.put(\"BUILD_URL\", \"http://company.com/jenkins/build123\");\n        env.put(\"GIT_BRANCH\", \"master\");\n        env.put(\"GIT_COMMIT\", \"a3562fgcd2\");\n        return env;\n    }\n    \n    @Test\n    public void testIsSelectedForNothing() {\n        assertFalse(new Jenkins(new HashMap<String, String>()).isSelected());\n    }\n    \n    @Test\n    public void testIsSelectedForJenkins() {\n        assertTrue(new Jenkins(env()).isSelected());\n    }\n    \n    @Test\n    public void testGetName() {\n        assertEquals(\"jenkins\", new Jenkins(env()).getName());\n    }\n    \n    @Test\n    public void testGetBuildNumber() {\n        assertEquals(\"build123\", new Jenkins(env()).getBuildNumber());\n    }\n    \n    @Test\n    public void testGetBuildUrl() {\n        assertEquals(\"http://company.com/jenkins/build123\", new Jenkins(env()).getBuildUrl());\n    }\n    \n    @Test\n    public void testGetBranch() {\n        assertEquals(\"master\", new Jenkins(env()).getBranch());\n    }\n    \n    @Test\n    public void testGetEnvironment() {\n        Properties properties = new Jenkins(env()).getEnvironment();\n        assertEquals(4, properties.size());\n        assertEquals(\"build123\", properties.getProperty(\"jenkins_build_num\"));\n        assertEquals(\"http://company.com/jenkins/build123\", properties.getProperty(\"jenkins_build_url\"));\n        assertEquals(\"master\", properties.getProperty(\"branch\"));\n        assertEquals(\"a3562fgcd2\", properties.getProperty(\"commit_sha\"));\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/ShippableTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.junit.Test;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport static org.junit.Assert.*;\n\npublic class ShippableTest {\n\n    private Map<String, String> env() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(Shippable.SHIPPABLE, \"true\");\n        env.put(Shippable.SHIPPABLE_BUILD_ID, \"54de3316c44f\");\n        env.put(Shippable.SHIPPABLE_BUILD_NUMBER, \"431.1\");\n        env.put(Shippable.SHIPPABLE_BRANCH, \"master\");\n        env.put(Shippable.SHIPPABLE_COMMIT, \"a3562fgcd2\");\n        env.put(Shippable.SHIPPABLE_PULL_REQUEST, \"10\");\n        return env;\n    }\n\n    @Test\n    public void testIsSelectedForNothing() {\n        assertFalse(new Shippable(new HashMap<String, String>()).isSelected());\n    }\n\n    @Test\n    public void testIsSelectedForShippable() {\n        assertTrue(new Shippable(env()).isSelected());\n    }\n\n    @Test\n    public void testGetName() {\n        assertEquals(\"shippable\", new Shippable(env()).getName());\n    }\n\n    @Test\n    public void testGetBuildNumber() {\n        assertEquals(\"431.1\", new Shippable(env()).getBuildNumber());\n    }\n\n    @Test\n    public void testGetBuildUrl() {\n        assertEquals(\"https://app.shippable.com/builds/54de3316c44f\", new Shippable(env()).getBuildUrl());\n    }\n\n    @Test\n    public void testGetBranch() {\n        assertEquals(\"master\", new Shippable(env()).getBranch());\n    }\n\n    @Test\n    public void testPullRequest() {\n        assertEquals(\"10\", new Shippable(env()).getPullRequest());\n    }\n\n    @Test\n    public void testPullRequestFalse() {\n        Map<String, String> env = env();\n        env.put(Shippable.SHIPPABLE_PULL_REQUEST, \"false\");\n        assertNull(new Shippable(env).getPullRequest());\n    }\n\n    @Test\n    public void testGetEnvironment() {\n        Properties properties = new Shippable(env()).getEnvironment();\n        assertEquals(5, properties.size());\n        assertEquals(\"431.1\", properties.getProperty(\"shippable_build_number\"));\n        assertEquals(\"54de3316c44f\", properties.getProperty(\"shippable_build_id\"));\n        assertEquals(\"https://app.shippable.com/builds/54de3316c44f\", properties.getProperty(\"shippable_build_url\"));\n        assertEquals(\"master\", properties.getProperty(\"branch\"));\n        assertEquals(\"a3562fgcd2\", properties.getProperty(\"commit_sha\"));\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/TravisTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.junit.Test;\n\npublic class TravisTest {\n    \n    private Map<String, String> env() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(\"TRAVIS\", \"true\");\n        env.put(\"TRAVIS_JOB_ID\", \"job123\");\n        env.put(\"TRAVIS_BRANCH\", \"master\");\n        env.put(\"TRAVIS_PULL_REQUEST\", \"pull10\");\n        return env;\n    }\n    \n    @Test\n    public void testIsSelectedForNothing() {\n        assertFalse(new Travis(new HashMap<String, String>()).isSelected());\n    }\n    \n    @Test\n    public void testIsSelectedForTravis() {\n        assertTrue(new Travis(env()).isSelected());\n    }\n    \n    @Test\n    public void testGetName() {\n        assertEquals(\"travis-ci\", new Travis(env()).getName());\n    }\n    \n    @Test\n    public void testGetJobId() {\n        assertEquals(\"job123\", new Travis(env()).getJobId());\n    }\n\n    @Test\n    public void testGetBranch() {\n        assertEquals(\"master\", new Travis(env()).getBranch());\n    }\n    \n    @Test\n    public void testGetPullRequest() {\n        assertEquals(\"pull10\", new Travis(env()).getPullRequest());\n    }\n    \n    @Test\n    public void testGetEnvironment() {\n        Properties properties = new Travis(env()).getEnvironment();\n        assertEquals(2, properties.size());\n        assertEquals(\"job123\", properties.getProperty(\"travis_job_id\"));\n        assertEquals(\"pull10\", properties.getProperty(\"travis_pull_request\"));\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/service/WerckerTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.service;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.junit.Test;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\npublic class WerckerTest {\n    \n    private Map<String, String> env() {\n        Map<String, String> env = new HashMap<String, String>();\n        env.put(\"WERCKER\", \"true\");\n        env.put(\"WERCKER_BUILD_URL\", \"https://app.wercker.com/build/123456789\");\n        env.put(\"WERCKER_BUILD_ID\", \"123456789\");\n        env.put(\"WERCKER_GIT_BRANCH\", \"master\");\n        return env;\n    }\n    \n    @Test\n    public void testIsSelectedForNothing() {\n        assertFalse(new Wercker(new HashMap<String, String>()).isSelected());\n    }\n    \n    @Test\n    public void testIsSelectedForWercker() {\n        assertTrue(new Wercker(env()).isSelected());\n    }\n    \n    @Test\n    public void testGetName() {\n        assertEquals(\"wercker\", new Wercker(env()).getName());\n    }\n    \n    @Test\n    public void testGetJobId() {\n        assertEquals(\"123456789\", new Wercker(env()).getJobId());\n    }\n\n    @Test\n    public void testGetBuildUrl() {\n        assertEquals(\"https://app.wercker.com/build/123456789\", new Wercker(env()).getBuildUrl());\n    }\n\n    @Test\n    public void testGetBranch() {\n        assertEquals(\"master\", new Wercker(env()).getBranch());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/source/DirectorySourceLoaderTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.util.TestIoUtil;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport java.io.File;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class DirectorySourceLoaderTest {\n\n    @Mock\n    private File dirMock;\n\n    @Mock\n    private File fileMock;\n    \n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n    \n    @Test\n    public void testMissingSourceFileFromDirectory() throws Exception {\n        DirectorySourceLoader sourceLoader = new DirectorySourceLoader(folder.getRoot(), folder.getRoot(), \"UTF-8\");\n        assertNull(sourceLoader.load(\"Foo.java\"));\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testInvalidSourceFile() throws Exception {\n        File subFolder = folder.newFolder();\n        DirectorySourceLoader sourceLoader = new DirectorySourceLoader(folder.getRoot(), folder.getRoot(), \"UTF-8\");\n        sourceLoader.load(subFolder.getName());\n    }\n\n    @Test\n    public void testLoadSource() throws Exception {\n        File file = folder.newFile();\n        TestIoUtil.writeFileContent(\"public class Foo {\\r\\n    \\n}\\r\", file);\n        DirectorySourceLoader sourceLoader = new DirectorySourceLoader(folder.getRoot(), folder.getRoot(), \"UTF-8\");\n        Source source = sourceLoader.load(file.getName());\n        assertEquals(file.getName(), source.getName());\n        assertEquals(\"2AC359C9A152FD7CD79C4EB147069224\", source.getDigest());\n        assertEquals(4, source.getCoverage().length);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/source/MultiSourceLoaderTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport java.io.IOException;\n\nimport static org.junit.Assert.assertSame;\nimport static org.mockito.Mockito.when;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class MultiSourceLoaderTest {\n\n    @Mock\n    private SourceLoader sl1;\n    \n    @Mock\n    private SourceLoader sl2;\n    \n    private Source s1 = new Source(\"source\", \"{ 1 }\", \"9A0174D3A5B8D202C6E404601FC260D1\");\n    \n    private Source s2 = new Source(\"source\", \"{ 2 }\", \"849409F24F4BCAAC904F3B142447D65D\");\n    \n    @Test(expected = IOException.class)\n    public void testMissingSource() throws Exception {\n        creaMultiSourceLoader().load(\"source\");\n    }\n    \n    @Test\n    public void testPrimarySource() throws Exception {\n        when(sl1.load(\"source\")).thenReturn(s1);\n        Source source = creaMultiSourceLoader().load(\"source\");\n        assertSame(s1, source);\n    }\n    \n    @Test\n    public void testSecondarySource() throws Exception {\n        when(sl2.load(\"source\")).thenReturn(s2);\n        Source source = creaMultiSourceLoader().load(\"source\");\n        assertSame(s2, source);\n    }\n    \n    private MultiSourceLoader creaMultiSourceLoader() {\n        return new MultiSourceLoader().add(sl1).add(sl2);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/source/ScanSourceLoaderTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.util.TestIoUtil;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport java.io.File;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class ScanSourceLoaderTest {\n\n    @Mock\n    private File dirMock;\n\n    @Mock\n    private File fileMock;\n    \n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n    \n    @Test\n    public void testMissingSourceFileFromDirectory() throws Exception {\n        ScanSourceLoader sourceLoader = new ScanSourceLoader(folder.getRoot(), folder.getRoot(), \"UTF-8\");\n        assertNull(sourceLoader.load(\"Foo.java\"));\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testInvalidSourceFile() throws Exception {\n        File subFolder = folder.newFolder();\n        ScanSourceLoader sourceLoader = new ScanSourceLoader(folder.getRoot(), folder.getRoot(), \"UTF-8\");\n        sourceLoader.load(subFolder.getName());\n    }\n\n    @Test\n    public void testLoadSource() throws Exception {\n        File dir = folder.newFolder(\"level1\", \"level2\", \"level3\");\n        File fileA = new File(dir, \"AFile.java\");\n        File fileB = new File(dir, \"BFile.java\");\n        TestIoUtil.writeFileContent(\"public class Foo {\\r\\n    \\n}\\r\", fileA);\n        TestIoUtil.writeFileContent(\"public class Foo {\\r\\n    \\n}\\r\", fileB);\n        ScanSourceLoader sourceLoader = new ScanSourceLoader(folder.getRoot(), folder.getRoot(), \"UTF-8\");\n        Source sourceA = sourceLoader.load(fileA.getName());\n        assertEquals(\"level1/level2/level3/AFile.java\", sourceA.getName());\n        assertEquals(\"2AC359C9A152FD7CD79C4EB147069224\", sourceA.getDigest());\n        assertEquals(4, sourceA.getCoverage().length);\n        Source sourceB = sourceLoader.load(fileB.getName());\n        assertEquals(\"level1/level2/level3/BFile.java\", sourceB.getName());\n        assertEquals(\"2AC359C9A152FD7CD79C4EB147069224\", sourceB.getDigest());\n        assertEquals(4, sourceB.getCoverage().length);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/source/UniqueSourceCallbackTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.util.TestIoUtil;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.Mockito;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport static org.mockito.Mockito.times;\nimport static org.mockito.Mockito.verify;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class UniqueSourceCallbackTest {\n\n    @Mock\n    private SourceCallback sourceCallbackMock;\n    \n    @Test\n    public void testOnSourceWithUniqueFiles() throws Exception {\n        Source s1 = createSource(\"Foo.java\", \"{\\n  void();\\n}\\n\", 2);\n        Source s2 = createSource(\"Bar.java\", \"{\\n  bar();\\n}\\n\", 2);\n        \n        UniqueSourceCallback cb = createUniqueSourceCallback();\n        cb.onBegin();\n        cb.onSource(s1);\n        cb.onSource(s2);\n        cb.onComplete();\n        verify(sourceCallbackMock).onBegin();\n        verify(sourceCallbackMock, times(2)).onSource(Mockito.any(Source.class));\n        verify(sourceCallbackMock).onComplete();\n    }\n\n    @Test\n    public void testOnSourceWithDuplicateSources() throws Exception {\n        Source s1 = createSource(\"Foo.java\", \"{\\n  void();\\n}\\n\", 2);\n        Source s2 = createSource(\"Foo.java\", \"{\\n  void();\\n}\\n\", 2);\n\n        UniqueSourceCallback cb = createUniqueSourceCallback();\n        cb.onBegin();\n        cb.onSource(s1);\n        cb.onSource(s2);\n        cb.onComplete();\n        verify(sourceCallbackMock).onBegin();\n        verify(sourceCallbackMock, times(1)).onSource(Mockito.any(Source.class));\n        verify(sourceCallbackMock).onComplete();\n    }\n\n    @Test\n    public void testOnSourceWithUniqueSources() throws Exception {\n        Source s1 = createSource(\"Foo.java\", \"{\\n  void();\\n}\\n\", 2);\n        Source s2 = createSource(\"Foo.java\", \"{\\n  void();\\n  func();\\n}\\n\", 2, 3);\n\n        UniqueSourceCallback cb = createUniqueSourceCallback();\n        cb.onBegin();\n        cb.onSource(s1);\n        cb.onSource(s2);\n        cb.onComplete();\n        verify(sourceCallbackMock).onBegin();\n        verify(sourceCallbackMock, times(2)).onSource(Mockito.any(Source.class));\n        verify(sourceCallbackMock).onComplete();\n    }\n\n    private UniqueSourceCallback createUniqueSourceCallback() {\n        return new UniqueSourceCallback(sourceCallbackMock);\n    }\n    \n    private Source createSource(final String name, final String source, final int... relevant) throws Exception {\n        Source s = new Source(name, source, TestIoUtil.getMd5DigestHex(source));\n        for (int i : relevant) {\n            s.addCoverage(i, 1);\n        }\n        return s;\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/source/UrlSourceLoaderTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.source;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.domain.Source;\nimport org.eluder.coveralls.maven.plugin.util.TestIoUtil;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport java.io.File;\nimport java.net.URL;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class UrlSourceLoaderTest {\n\n    @Mock\n    private File dirMock;\n\n    @Mock\n    private File fileMock;\n\n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n    \n    @Test\n    public void testMissingSourceFileFromUrl() throws Exception {\n        UrlSourceLoader sourceLoader = new UrlSourceLoader(folder.getRoot().toURI().toURL(), new URL(\"http://domainthatreallydoesnotexistsdfsmshjsfsj.com\"), \"UTF-8\");\n        assertNull(sourceLoader.load(\"Foo.java\"));\n    }\n\n    @Test\n    public void testLoadSourceFromUrl() throws Exception {\n        String fileName = \"scripts/file.coffee\";\n        URL sourceUrl  = folder.getRoot().toURI().toURL();\n\n        folder.newFolder(\"scripts\");\n        File file = folder.newFile(fileName);\n        TestIoUtil.writeFileContent(\"math =\\n  root:   Math.sqrt\\n  square: square\", file);\n\n        UrlSourceLoader sourceLoader = new UrlSourceLoader(folder.getRoot().toURI().toURL(), sourceUrl, \"UTF-8\");\n        Source source = sourceLoader.load(fileName);\n\n        assertEquals(fileName, source.getName());\n        assertEquals(\"9897A4BB0467180D3C6ACD95475DD77D\", source.getDigest());\n        assertEquals(3, source.getCoverage().length);\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/util/CoverageParsersFactoryTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.apache.maven.model.Build;\nimport org.apache.maven.model.Model;\nimport org.apache.maven.model.Reporting;\nimport org.apache.maven.project.MavenProject;\nimport org.eluder.coveralls.maven.plugin.CoverageParser;\nimport org.eluder.coveralls.maven.plugin.parser.CoberturaParser;\nimport org.eluder.coveralls.maven.plugin.parser.JaCoCoParser;\nimport org.eluder.coveralls.maven.plugin.parser.SagaParser;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\nimport static org.mockito.Mockito.when;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class CoverageParsersFactoryTest {\n\n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n    \n    @Mock\n    private MavenProject projectMock;\n    \n    @Mock\n    private SourceLoader sourceLoaderMock;\n    \n    @Mock\n    private Model modelMock;\n    \n    @Mock\n    private Reporting reportingMock;\n    \n    @Mock\n    private Build buildMock;\n    \n    private File reportingDir;\n    \n    private File targetDir;\n    \n    @Before\n    public void init() throws Exception{\n        reportingDir = folder.newFolder();\n        targetDir = folder.newFolder();\n        when(projectMock.getCollectedProjects()).thenReturn(Collections.<MavenProject>emptyList());\n        when(projectMock.getModel()).thenReturn(modelMock);\n        when(projectMock.getBuild()).thenReturn(buildMock);\n        when(modelMock.getReporting()).thenReturn(reportingMock);\n        when(reportingMock.getOutputDirectory()).thenReturn(reportingDir.getAbsolutePath());\n        when(buildMock.getDirectory()).thenReturn(targetDir.getAbsolutePath());\n    }\n    \n    @Test(expected = IOException.class)\n    public void testCreateEmptyParsers() throws Exception {\n        createCoverageParsersFactory().createParsers();\n    }\n    \n    @Test\n    public void testCreateJaCoCoParser() throws Exception {\n        File jacocoDir = new File(reportingDir, \"jacoco\");\n        jacocoDir.mkdir(); new File(jacocoDir, \"jacoco.xml\").createNewFile();\n        List<CoverageParser> parsers = createCoverageParsersFactory().createParsers();\n        assertEquals(1, parsers.size());\n        assertTrue(JaCoCoParser.class.equals(parsers.get(0).getClass()));\n    }\n    \n    @Test\n    public void testCreateCoberturaParser() throws Exception {\n        File coberturaDir = new File(reportingDir, \"cobertura\");\n        coberturaDir.mkdir(); new File(coberturaDir, \"coverage.xml\").createNewFile();\n        List<CoverageParser> parsers = createCoverageParsersFactory().createParsers();\n        assertEquals(1, parsers.size());\n        assertTrue(CoberturaParser.class.equals(parsers.get(0).getClass()));\n    }\n    \n    @Test\n    public void testCreateSagaParser() throws Exception {\n        File sagaDir = new File(targetDir, \"saga-coverage\");\n        sagaDir.mkdir(); new File(sagaDir, \"total-coverage.xml\").createNewFile();\n        List<CoverageParser> parsers = createCoverageParsersFactory().createParsers();\n        assertEquals(1, parsers.size());\n        assertTrue(SagaParser.class.equals(parsers.get(0).getClass()));\n    }\n    \n    @Test\n    public void testWithJaCoCoReport() throws Exception {\n        File jacocoFile = new File(reportingDir, \"jacoco-report.xml\");\n        jacocoFile.createNewFile();\n        CoverageParsersFactory factory = createCoverageParsersFactory().withJaCoCoReports(Arrays.asList(jacocoFile));\n        List<CoverageParser> parsers = factory.createParsers();\n        assertEquals(1, parsers.size());\n        assertTrue(JaCoCoParser.class.equals(parsers.get(0).getClass()));\n    }\n    \n    @Test\n    public void testWithCoberturaReport() throws Exception {\n        File coberturaFile = new File(reportingDir, \"cobertura-report.xml\");\n        coberturaFile.createNewFile();\n        CoverageParsersFactory factory = createCoverageParsersFactory().withCoberturaReports(Arrays.asList(coberturaFile));\n        List<CoverageParser> parsers = factory.createParsers();\n        assertEquals(1, parsers.size());\n        assertTrue(CoberturaParser.class.equals(parsers.get(0).getClass()));\n    }\n    \n    @Test\n    public void testWithSagaReport() throws Exception {\n        File sagaFile = new File(reportingDir, \"saga-report.xml\");\n        sagaFile.createNewFile();\n        CoverageParsersFactory factory = createCoverageParsersFactory().withSagaReports(Arrays.asList(sagaFile));\n        List<CoverageParser> parsers = factory.createParsers();\n        assertEquals(1, parsers.size());\n        assertTrue(SagaParser.class.equals(parsers.get(0).getClass()));\n    }\n\n    @Test\n    public void testWithRelativeReportDirectory() throws Exception {\n        File coberturaDir = new File(reportingDir, \"customdir\");\n        coberturaDir.mkdir(); new File(coberturaDir, \"coverage.xml\").createNewFile();\n        CoverageParsersFactory factory = createCoverageParsersFactory().withRelativeReportDirs(Arrays.asList(\"customdir\"));\n        List<CoverageParser> parsers = factory.createParsers();\n        assertEquals(1, parsers.size());\n        assertTrue(CoberturaParser.class.equals(parsers.get(0).getClass()));\n    }\n\n    @Test\n    public void testWithRootRelativeReportDirectory() throws Exception {\n        new File(reportingDir, \"coverage.xml\").createNewFile();\n        CoverageParsersFactory factory = createCoverageParsersFactory().withRelativeReportDirs(Arrays.asList(File.separator));\n        List<CoverageParser> parsers = factory.createParsers();\n        assertEquals(1, parsers.size());\n        assertTrue(CoberturaParser.class.equals(parsers.get(0).getClass()));\n    }\n\n    private CoverageParsersFactory createCoverageParsersFactory() {\n        return new CoverageParsersFactory(projectMock, sourceLoaderMock);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/util/ExistingFilesTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.*;\n\nimport java.io.File;\nimport java.util.Arrays;\nimport java.util.Iterator;\n\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\n\npublic class ExistingFilesTest {\n\n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n\n\n    @Test(expected = NullPointerException.class)\n    public void testAddAllForNull() throws Exception {\n        new ExistingFiles().addAll(null);\n    }\n\n    @Test(expected = NullPointerException.class)\n    public void testAddForNull() throws Exception {\n        new ExistingFiles().add(null);\n    }\n    \n    @Test\n    public void testAddForExisting() throws Exception {\n        File f = folder.newFile();\n        Iterator<File> iter = new ExistingFiles().add(f).add(f).iterator();\n        assertSize(iter, 1);\n    }\n    \n    @Test\n    public void testAddForDirectory() throws Exception {\n        File d = folder.newFolder();\n        Iterator<File> iter = new ExistingFiles().add(d).iterator();\n        assertSize(iter, 0);\n    }\n\n    @Test\n    public void testCreateForNull() throws Exception {\n        Iterator<File> iter = ExistingFiles.create(null).iterator();\n        assertSize(iter, 0);\n    }\n    \n    @Test\n    public void testCreateForMultipleFiles() throws Exception {\n        File f1 = folder.newFile();\n        File f2 = folder.newFile();\n        Iterator<File> iter = ExistingFiles.create(Arrays.asList(f1, f2)).iterator();\n        assertSize(iter, 2);\n    }\n    \n    private static void assertSize(Iterator<?> iter, int size) {\n        for (int i = 0; i < size; i++) {\n            iter.next();\n        }\n        assertFalse(iter.hasNext());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/util/Md5DigestInputStreamTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.junit.Test;\n\nimport java.io.ByteArrayInputStream;\n\nimport static org.junit.Assert.assertEquals;\n\npublic class Md5DigestInputStreamTest {\n\n    @Test\n    public void testRead() throws Exception {\n        byte[] data = new byte[] { (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD };\n        try (Md5DigestInputStream is = new Md5DigestInputStream(new ByteArrayInputStream(data))) {\n            assertEquals(0xAA, is.read());\n            assertEquals(0xBB, is.read());\n            assertEquals(0xCC, is.read());\n            assertEquals(0xDD, is.read());\n            assertEquals(-1, is.read());\n            assertEquals(\"CA6FFBF95B47864FD4E73F2601326304\", is.getDigestHex());\n        }\n    }\n\n    @Test\n    public void testReadArray() throws Exception {\n        byte[] data = new byte[] { (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD };\n        try (Md5DigestInputStream is = new Md5DigestInputStream(new ByteArrayInputStream(data))) {\n            byte[] buff = new byte[5];\n            assertEquals(4, is.read(buff));\n            assertEquals(-1, is.read());\n            for (int i = 0; i < data.length; i++) {\n                assertEquals(data[i], buff[i]);\n            }\n            assertEquals(\"CA6FFBF95B47864FD4E73F2601326304\", is.getDigestHex());\n        }\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/util/SourceLoaderFactoryTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.*;\nimport static org.mockito.Mockito.when;\n\nimport java.io.File;\nimport java.util.Arrays;\nimport java.util.Collections;\n\nimport org.apache.maven.project.MavenProject;\nimport org.eluder.coveralls.maven.plugin.source.SourceLoader;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.TemporaryFolder;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class SourceLoaderFactoryTest {\n\n    @Rule\n    public TemporaryFolder folder = new TemporaryFolder();\n    \n    @Mock\n    private MavenProject root;\n    \n    @Mock\n    private MavenProject m1;\n    \n    @Mock\n    private MavenProject m2;\n    \n    private File rootSources;\n    private File m1Sources;\n    private File m2Sources;\n    \n    @Before\n    public void init() throws Exception {\n        rootSources = new File(folder.getRoot(), \"src\");\n        m1Sources = folder.newFolder(\"m1\", \"src\");\n        m2Sources = folder.newFolder(\"m2\", \"src\");\n        when(root.getCollectedProjects()).thenReturn(Arrays.asList(m1, m2));\n        when(m1.getCollectedProjects()).thenReturn(Collections.<MavenProject>emptyList());\n        when(m2.getCollectedProjects()).thenReturn(Collections.<MavenProject>emptyList());\n        when(root.getCompileSourceRoots()).thenReturn(Arrays.asList(rootSources.getAbsolutePath()));\n        when(m1.getCompileSourceRoots()).thenReturn(Arrays.asList(m1Sources.getAbsolutePath()));\n        when(m2.getCompileSourceRoots()).thenReturn(Arrays.asList(m2Sources.getAbsolutePath()));\n    }\n    \n    @Test\n    public void testCreateSourceLoader() throws Exception {\n        SourceLoader sourceLoader = createSourceLoaderFactory(\"UTF-8\").createSourceLoader();\n        assertNotNull(sourceLoader);\n    }\n    \n    @Test\n    public void testCreateSourceLoaderWithAdditionalSourceDirectories() throws Exception {\n        File s1 = new File(folder.getRoot(), \"s1\");\n        File s2 = folder.newFolder(\"s2\");\n        SourceLoader sourceLoader = createSourceLoaderFactory(\"UTF-8\")\n                .withSourceDirectories(Arrays.asList(s1, s2))\n                .createSourceLoader();\n        assertNotNull(sourceLoader);\n    }\n\n    @Test\n    public void testCreateSourceLoaderWithScanForSources() throws Exception {\n        SourceLoader sourceLoader = createSourceLoaderFactory(\"UTF-8\")\n                .withScanForSources( true )\n                .createSourceLoader();\n        assertNotNull(sourceLoader);\n    }\n\n    @Test\n    public void testCreateSourceLoaderInvalidDirectory() throws Exception {\n        File file = new File(folder.getRoot(), \"aFile\");\n        file.createNewFile();\n        SourceLoader sourceLoader = createSourceLoaderFactory(\"UTF-8\")\n                .withSourceDirectories(Arrays.asList(file))\n                .withScanForSources(true)\n                .createSourceLoader();\n        assertNotNull(sourceLoader);\n    }\n\n    private SourceLoaderFactory createSourceLoaderFactory(String sourceEncoding) {\n        return new SourceLoaderFactory(folder.getRoot(), root, sourceEncoding);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/util/TestIoUtil.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.PrintWriter;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.nio.charset.Charset;\nimport java.security.NoSuchAlgorithmException;\nimport org.apache.commons.codec.digest.DigestUtils;\nimport org.codehaus.plexus.util.IOUtil;\n\npublic class TestIoUtil {\n\n    public static void writeFileContent(final String content, final File file) throws FileNotFoundException {\n        PrintWriter writer = new PrintWriter(file);\n        try {\n            writer.write(content);\n        } finally {\n            IOUtil.close(writer);\n        }\n    }\n    \n    public static String readFileContent(final File file) throws IOException {\n        InputStreamReader reader = new InputStreamReader(new FileInputStream(file), Charset.forName(\"UTF-8\"));\n        try {\n            return IOUtil.toString(reader);\n        } finally {\n            IOUtil.close(reader);\n        }\n    }\n    \n    public static File getFile(final String resource) {\n        try {\n            String local = resource;\n            if (local.lastIndexOf(\"/\") > 0) {\n                local = local.substring(local.lastIndexOf('/'));\n            }\n            if (!local.startsWith(\"/\")) {\n                local = \"/\" + local;\n            }\n            return new File(getResourceUrl(local).toURI());\n        } catch (URISyntaxException ex) {\n            throw new IllegalArgumentException(ex);\n        }\n    }\n\n    public static String getMd5DigestHex(final String content) throws NoSuchAlgorithmException {\n        return DigestUtils.md5Hex(content).toUpperCase();\n    }\n\n    private static URL getResourceUrl(final String resource) {\n        return TestIoUtil.class.getResource(resource);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/util/TimestampParserTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.eluder.coveralls.maven.plugin.ProcessingException;\nimport org.junit.Test;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\n\npublic class TimestampParserTest {\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testInvalidFormat() {\n        new TimestampParser(\"scsscdfsd\");\n    }\n\n    @Test\n    public void testParseEpochMillis() throws Exception {\n        String format = TimestampParser.EPOCH_MILLIS;\n        long time = System.currentTimeMillis();\n        Date parsed = new TimestampParser(format).parse(String.valueOf(time));\n\n        assertEquals(time, parsed.getTime());\n    }\n\n    @Test\n    public void testParseSimpleFormat() throws Exception {\n        String format = \"yyyy-MM-dd\";\n        Date parsed = new TimestampParser(format).parse(\"2015-08-20\");\n        String formatted = new SimpleDateFormat(format).format(parsed);\n\n        assertEquals(\"2015-08-20\", formatted);\n    }\n\n    @Test\n    public void testParseDefaultFormat() throws Exception {\n        String format = TimestampParser.DEFAULT_FORMAT;\n        Date parsed = new TimestampParser(null).parse(\"2015-08-20T20:10:00Z\");\n        String formatted = new SimpleDateFormat(format).format(parsed);\n\n        assertEquals(\"2015-08-20T20:10:00Z\", formatted);\n    }\n\n    @Test\n    public void testParseNull() throws Exception {\n        Date parsed = new TimestampParser(null).parse(null);\n\n        assertNull(parsed);\n    }\n\n    @Test(expected = ProcessingException.class)\n    public void testParseInvalidTimestamp() throws Exception {\n        new TimestampParser(null).parse(\"2015-08-20\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/util/UrlUtilsTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.junit.Test;\n\nimport java.net.URI;\nimport java.net.URL;\n\nimport static org.junit.Assert.assertEquals;\n\npublic class UrlUtilsTest {\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testCreateInvalidUrl() throws Exception {\n        UrlUtils.create(\"sdfds\");\n    }\n\n    @Test\n    public void testCreateValidUrl() throws Exception {\n        assertEquals(\"http://example.org\", UrlUtils.create(\"http://example.org\").toURI().toASCIIString());\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testInvalidUrlToUri() throws Exception {\n        UrlUtils.toUri(new URL(\"http://google.com?q=s|r\"));\n    }\n    \n    @Test\n    public void testValidUrlToUri() throws Exception {\n        URI uri = UrlUtils.toUri(new URL(\"http://google.com\"));\n        assertEquals(new URI(\"http://google.com\"), uri);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/util/WildcardsTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.util;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\npublic class WildcardsTest {\n\n    @Test\n    public void testMatchesAgainstNull() throws Exception {\n        assertFalse(Wildcards.matches(null, \"*\"));\n    }\n\n    @Test\n    public void testMatchesAgainstJoker() throws Exception {\n        assertTrue(Wildcards.matches(\"a\", \"?\"));\n    }\n\n    @Test\n    public void testMatchesAgainstStar() throws Exception {\n        assertTrue(Wildcards.matches(\"abc\", \"*\"));\n    }\n\n    @Test\n    public void testMatchesAgainstWildcards() throws Exception {\n        assertTrue(Wildcards.matches(\"abcdefg\", \"a*d??g\"));\n        assertFalse(Wildcards.matches(\"abcdefg\", \"a*d?g?\"));\n    }\n\n    @Test\n    public void testMatchesAgainstText() throws Exception {\n        assertTrue(Wildcards.matches(\"abc\", \"abc\"));\n        assertFalse(Wildcards.matches(\"abc\", \"cba\"));\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/validation/JobValidatorTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.validation;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.hamcrest.Matchers.empty;\nimport static org.hamcrest.Matchers.hasSize;\nimport static org.hamcrest.Matchers.is;\nimport static org.junit.Assert.assertThat;\n\nimport org.eluder.coveralls.maven.plugin.domain.Git;\nimport org.eluder.coveralls.maven.plugin.domain.Git.Head;\nimport org.eluder.coveralls.maven.plugin.domain.Job;\nimport org.eluder.coveralls.maven.plugin.validation.ValidationError.Level;\nimport org.junit.Test;\n\npublic class JobValidatorTest {\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testMissingJob() {\n        new JobValidator(null);\n    }\n    \n    @Test\n    public void testValidateWithoutRepoTokenOrTravis() {\n        ValidationErrors errors = new JobValidator(new Job()).validate();\n        assertThat(errors, hasSize(1));\n        assertThat(errors.get(0).getLevel(), is(Level.ERROR));\n    }\n    \n    @Test\n    public void testValidateWithoutRepoTokenOrTravisForDryRun() {\n        ValidationErrors errors = new JobValidator(new Job().withDryRun(true)).validate();\n        assertThat(errors, hasSize(1));\n        assertThat(errors.get(0).getLevel(), is(Level.WARN));\n    }\n    \n    @Test\n    public void testValidateWithInvalidTravis() {\n        ValidationErrors errors = new JobValidator(new Job().withServiceName(\"travis-ci\")).validate();\n        assertThat(errors, hasSize(1));\n        assertThat(errors.get(0).getLevel(), is(Level.ERROR));\n    }\n    \n    @Test\n    public void testValidateWithRepoToken() {\n        ValidationErrors errors = new JobValidator(new Job().withRepoToken(\"ad3fg5\")).validate();\n        assertThat(errors, is(empty()));\n    }\n    \n    @Test\n    public void testValidateWithTravis() {\n        ValidationErrors errors = new JobValidator(new Job().withServiceName(\"travis-ci\").withServiceJobId(\"123\")).validate();\n        assertThat(errors, is(empty()));\n    }\n    \n    @Test\n    public void testValidateWithoutGitCommitId() {\n        Git git = new Git(null, new Head(null, null, null, null, null, null), null, null);\n        ValidationErrors errors = new JobValidator(new Job().withRepoToken(\"ad3fg5\").withGit(git)).validate();\n        assertThat(errors, hasSize(1));\n        assertThat(errors.get(0).getLevel(), is(Level.ERROR));\n    }\n    \n    @Test\n    public void testValidateWithGit() {\n        Git git = new Git(null, new Head(\"bc23af5\", null, null, null, null, null), null, null);\n        ValidationErrors errors = new JobValidator(new Job().withRepoToken(\"ad3fg5\").withGit(git)).validate();\n        assertThat(errors, is(empty()));\n    }\n\n    @Test\n    public void testValidateWithParallel() {\n        ValidationErrors errors = new JobValidator(new Job().withRepoToken(\"ad3fg5\").withParallel(true)).validate();\n        assertThat(errors, is(empty()));\n    }\n\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/validation/ValidationErrorTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.validation;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.eluder.coveralls.maven.plugin.validation.ValidationError.Level;\nimport org.junit.Test;\n\npublic class ValidationErrorTest {\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testMissingLevel() {\n        new ValidationError(null, \"message\");\n    }\n    \n    @Test(expected = IllegalArgumentException.class)\n    public void testMissingMessage() {\n        new ValidationError(Level.ERROR, null);\n    }\n    \n    @Test\n    public void testToString() {\n        ValidationError error = new ValidationError(Level.WARN, \"message\");\n        assertEquals(\"WARN: message\", error.toString());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/validation/ValidationErrorsTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.validation;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.mockito.Matchers.any;\nimport static org.mockito.Mockito.times;\nimport static org.mockito.Mockito.verify;\n\nimport org.apache.maven.plugin.logging.Log;\nimport org.eluder.coveralls.maven.plugin.validation.ValidationError.Level;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mock;\nimport org.mockito.runners.MockitoJUnitRunner;\n\n@RunWith(MockitoJUnitRunner.class)\npublic class ValidationErrorsTest {\n\n    @Mock\n    private Log logMock;\n    \n    @Test(expected = ValidationException.class)\n    public void testThrowOrInformWithError() {\n        createValidationErrors(new ValidationError(Level.ERROR, \"message\")).throwOrInform(logMock);\n    }\n    \n    @Test\n    public void testThrowOrInformWithWarnings() {\n        createValidationErrors(new ValidationError(Level.WARN, \"error1\"), new ValidationError(Level.WARN, \"error2\")).throwOrInform(logMock);\n        verify(logMock, times(2)).warn(any(CharSequence.class));\n    }\n    \n    private ValidationErrors createValidationErrors(final ValidationError... errors) {\n        ValidationErrors validationErrors = new ValidationErrors();\n        for (ValidationError error : errors) {\n            validationErrors.add(error);\n        }\n        return validationErrors;\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/eluder/coveralls/maven/plugin/validation/ValidationExceptionTest.java",
    "content": "package org.eluder.coveralls.maven.plugin.validation;\n\n/*\n * #[license]\n * coveralls-maven-plugin\n * %%\n * Copyright (C) 2013 - 2016 Tapio Rautonen\n * %%\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n * %[license]\n */\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNull;\nimport static org.junit.Assert.assertSame;\n\nimport org.junit.Test;\n\npublic class ValidationExceptionTest {\n    \n    private static final String MESSAGE = \"message\";\n    private static final RuntimeException CAUSE = new RuntimeException();\n    \n    @Test\n    public void testException() {\n        ValidationException exception = new ValidationException();\n        assertNull(exception.getMessage());\n        assertNull(exception.getCause());\n    }\n    \n    @Test\n    public void testExceptionWithMessage() {\n        ValidationException exception = new ValidationException(MESSAGE);\n        assertEquals(MESSAGE, exception.getMessage());\n        assertNull(exception.getCause());\n    }\n\n    @Test\n    public void testExceptionWithCause() {\n        ValidationException exception = new ValidationException(CAUSE);\n        assertEquals(CAUSE.toString(), exception.getMessage());\n        assertSame(CAUSE, exception.getCause());\n    }\n    \n    @Test\n    public void testExceptionWithMessageAndCause() {\n        ValidationException exception = new ValidationException(MESSAGE, CAUSE);\n        assertEquals(MESSAGE, exception.getMessage());\n        assertSame(CAUSE, exception.getCause());\n\n    }\n}\n"
  },
  {
    "path": "src/test/resources/Components.js",
    "content": "(function() {\n  this.Components = {};\n\n}).call(this);\n"
  },
  {
    "path": "src/test/resources/InnerClassCoverage.java",
    "content": "package org.eluder.coverage.sample;\n\npublic class InnerClassCoverage {\n\n    public void anonymous() {\n        InnerClass i = new InnerClass() {\n            @Override\n            public void run() {\n                System.out.println(\"overridden\");\n            }\n        };\n        i.run();\n    }\n\n    public boolean delegate() {\n        return new InnerClass().isInner();\n    }\n\n    public static class InnerClass {\n\n        public boolean isInner() {\n            return true;\n        }\n\n        public void run() {\n            System.out.println(\"run\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/test/resources/Localization.js",
    "content": "(function() {\n  var Localization;\n\n  Localization = (function() {\n    function Localization(values) {\n      this.values = values;\n    }\n\n    Localization.prototype.byKey = function(key) {\n      return this.values[key];\n    };\n\n    return Localization;\n\n  })();\n\n}).call(this);\n"
  },
  {
    "path": "src/test/resources/PartialCoverage.java",
    "content": "package org.eluder.coverage.sample;\n\npublic class PartialCoverage {\n\n    public void partial(boolean test) {\n        if (test) {\n            System.out.println(\"test\");\n        } else {\n            System.out.println(\"not test\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/test/resources/SimpleCoverage.java",
    "content": "package org.eluder.coverage.sample;\n\npublic class SimpleCoverage {\n\n    public boolean isTested() {\n        return false;\n    }\n\n    public void neverRun() {\n        System.out.println(\"oops\");\n    }\n\n}\n"
  },
  {
    "path": "src/test/resources/cobertura.xml",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE coverage SYSTEM \"http://cobertura.sourceforge.net/xml/coverage-04.dtd\">\n\n<coverage line-rate=\"0.7727272727272727\" branch-rate=\"0.5\" lines-covered=\"17\" lines-valid=\"22\" branches-covered=\"1\" branches-valid=\"2\" complexity=\"1.125\" version=\"2.1.1\" timestamp=\"1440358747916\">\n\t<sources>\n\t\t<source>sample/module1/src/main/java</source>\n\t\t<source>sample/module2/src/main/java</source>\n\t</sources>\n\t<packages>\n\t\t<package name=\"org.eluder.coverage.sample\" line-rate=\"0.7727272727272727\" branch-rate=\"0.5\" complexity=\"1.125\">\n\t\t\t<classes>\n\t\t\t\t<class name=\"org.eluder.coverage.sample.InnerClassCoverage\" filename=\"org/eluder/coverage/sample/InnerClassCoverage.java\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"1.0\">\n\t\t\t\t\t<methods>\n\t\t\t\t\t\t<method name=\"&lt;init&gt;\" signature=\"()V\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"3\" hits=\"2\" branch=\"false\"/>\n\t\t\t\t\t\t\t\t<line number=\"19\" hits=\"2\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t\t<method name=\"anonymous\" signature=\"()V\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"6\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t\t<line number=\"12\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t\t<line number=\"13\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t\t<method name=\"delegate\" signature=\"()Z\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"16\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t</methods>\n\t\t\t\t\t<lines>\n\t\t\t\t\t\t<line number=\"3\" hits=\"2\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"6\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"12\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"13\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"16\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"19\" hits=\"2\" branch=\"false\"/>\n\t\t\t\t\t</lines>\n\t\t\t\t</class>\n\t\t\t\t<class name=\"org.eluder.coverage.sample.InnerClassCoverage$1\" filename=\"org/eluder/coverage/sample/InnerClassCoverage.java\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"1.0\">\n\t\t\t\t\t<methods>\n\t\t\t\t\t\t<method name=\"&lt;init&gt;\" signature=\"(Lorg/eluder/coverage/sample/InnerClassCoverage;)V\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"6\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t\t<method name=\"run\" signature=\"()V\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"9\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t\t<line number=\"10\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t</methods>\n\t\t\t\t\t<lines>\n\t\t\t\t\t\t<line number=\"6\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"9\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"10\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t</lines>\n\t\t\t\t</class>\n\t\t\t\t<class name=\"org.eluder.coverage.sample.InnerClassCoverage$InnerClass\" filename=\"org/eluder/coverage/sample/InnerClassCoverage.java\" line-rate=\"0.5\" branch-rate=\"1.0\" complexity=\"1.0\">\n\t\t\t\t\t<methods>\n\t\t\t\t\t\t<method name=\"&lt;init&gt;\" signature=\"()V\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"19\" hits=\"2\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t\t<method name=\"isInner\" signature=\"()Z\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"22\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t\t<method name=\"run\" signature=\"()V\" line-rate=\"0.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"26\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t\t\t\t<line number=\"27\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t</methods>\n\t\t\t\t\t<lines>\n\t\t\t\t\t\t<line number=\"19\" hits=\"2\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"22\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"26\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"27\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t</lines>\n\t\t\t\t</class>\n\t\t\t\t<class name=\"org.eluder.coverage.sample.PartialCoverage\" filename=\"org/eluder/coverage/sample/PartialCoverage.java\" line-rate=\"0.8\" branch-rate=\"0.5\" complexity=\"2.0\">\n\t\t\t\t\t<methods>\n\t\t\t\t\t\t<method name=\"&lt;init&gt;\" signature=\"()V\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"3\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t\t<method name=\"partial\" signature=\"(Z)V\" line-rate=\"0.75\" branch-rate=\"0.5\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"6\" hits=\"1\" branch=\"true\" condition-coverage=\"50% (1/2)\">\n\t\t\t\t\t\t\t\t\t<conditions>\n\t\t\t\t\t\t\t\t\t\t<condition number=\"0\" type=\"jump\" coverage=\"50%\"/>\n\t\t\t\t\t\t\t\t\t</conditions>\n\t\t\t\t\t\t\t\t</line>\n\t\t\t\t\t\t\t\t<line number=\"7\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t\t<line number=\"9\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t\t\t\t<line number=\"11\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t</methods>\n\t\t\t\t\t<lines>\n\t\t\t\t\t\t<line number=\"3\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"6\" hits=\"1\" branch=\"true\" condition-coverage=\"50% (1/2)\">\n\t\t\t\t\t\t\t<conditions>\n\t\t\t\t\t\t\t\t<condition number=\"0\" type=\"jump\" coverage=\"50%\"/>\n\t\t\t\t\t\t\t</conditions>\n\t\t\t\t\t\t</line>\n\t\t\t\t\t\t<line number=\"7\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"9\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"11\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t</lines>\n\t\t\t\t</class>\n\t\t\t\t<class name=\"org.eluder.coverage.sample.SimpleCoverage\" filename=\"org/eluder/coverage/sample/SimpleCoverage.java\" line-rate=\"0.5\" branch-rate=\"1.0\" complexity=\"1.0\">\n\t\t\t\t\t<methods>\n\t\t\t\t\t\t<method name=\"&lt;init&gt;\" signature=\"()V\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"3\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t\t<method name=\"isTested\" signature=\"()Z\" line-rate=\"1.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"6\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t\t<method name=\"neverRun\" signature=\"()V\" line-rate=\"0.0\" branch-rate=\"1.0\" complexity=\"0\">\n\t\t\t\t\t\t\t<lines>\n\t\t\t\t\t\t\t\t<line number=\"10\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t\t\t\t<line number=\"11\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t\t\t</lines>\n\t\t\t\t\t\t</method>\n\t\t\t\t\t</methods>\n\t\t\t\t\t<lines>\n\t\t\t\t\t\t<line number=\"3\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"6\" hits=\"1\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"10\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t\t<line number=\"11\" hits=\"0\" branch=\"false\"/>\n\t\t\t\t\t</lines>\n\t\t\t\t</class>\n\t\t\t</classes>\n\t\t</package>\n\t</packages>\n</coverage>\n"
  },
  {
    "path": "src/test/resources/jacoco1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><!DOCTYPE report PUBLIC \"-//JACOCO//DTD Report 1.0//EN\" \"report.dtd\"><report name=\"module1\"><sessioninfo id=\"test\" start=\"1440276756076\" dump=\"1440276756482\"/><package name=\"org/eluder/coverage/sample\"><class name=\"org/eluder/coverage/sample/InnerClassCoverage\"><method name=\"&lt;init&gt;\" desc=\"()V\" line=\"3\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"3\"/><counter type=\"LINE\" missed=\"0\" covered=\"2\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"anonymous\" desc=\"()V\" line=\"6\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"8\"/><counter type=\"LINE\" missed=\"0\" covered=\"3\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"delegate\" desc=\"()Z\" line=\"16\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"5\"/><counter type=\"LINE\" missed=\"0\" covered=\"1\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"16\"/><counter type=\"LINE\" missed=\"0\" covered=\"6\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"3\"/><counter type=\"METHOD\" missed=\"0\" covered=\"3\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></class><class name=\"org/eluder/coverage/sample/InnerClassCoverage$InnerClass\"><method name=\"&lt;init&gt;\" desc=\"()V\" line=\"19\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"3\"/><counter type=\"LINE\" missed=\"0\" covered=\"1\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"isInner\" desc=\"()Z\" line=\"22\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"2\"/><counter type=\"LINE\" missed=\"0\" covered=\"1\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"run\" desc=\"()V\" line=\"26\"><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"0\"/><counter type=\"LINE\" missed=\"2\" covered=\"0\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"0\"/><counter type=\"METHOD\" missed=\"1\" covered=\"0\"/></method><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"5\"/><counter type=\"LINE\" missed=\"2\" covered=\"2\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"1\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></class><class name=\"org/eluder/coverage/sample/SimpleCoverage\"><method name=\"&lt;init&gt;\" desc=\"()V\" line=\"3\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"3\"/><counter type=\"LINE\" missed=\"0\" covered=\"1\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"isTested\" desc=\"()Z\" line=\"6\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"2\"/><counter type=\"LINE\" missed=\"0\" covered=\"1\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"neverRun\" desc=\"()V\" line=\"10\"><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"0\"/><counter type=\"LINE\" missed=\"2\" covered=\"0\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"0\"/><counter type=\"METHOD\" missed=\"1\" covered=\"0\"/></method><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"5\"/><counter type=\"LINE\" missed=\"2\" covered=\"2\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"1\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></class><class name=\"org/eluder/coverage/sample/InnerClassCoverage$1\"><method name=\"&lt;init&gt;\" desc=\"(Lorg/eluder/coverage/sample/InnerClassCoverage;)V\" line=\"6\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"6\"/><counter type=\"LINE\" missed=\"0\" covered=\"1\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"run\" desc=\"()V\" line=\"9\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"4\"/><counter type=\"LINE\" missed=\"0\" covered=\"2\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"10\"/><counter type=\"LINE\" missed=\"0\" covered=\"3\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></class><sourcefile name=\"InnerClassCoverage.java\"><line nr=\"3\" mi=\"0\" ci=\"2\" mb=\"0\" cb=\"0\"/><line nr=\"6\" mi=\"0\" ci=\"11\" mb=\"0\" cb=\"0\"/><line nr=\"9\" mi=\"0\" ci=\"3\" mb=\"0\" cb=\"0\"/><line nr=\"10\" mi=\"0\" ci=\"1\" mb=\"0\" cb=\"0\"/><line nr=\"12\" mi=\"0\" ci=\"2\" mb=\"0\" cb=\"0\"/><line nr=\"13\" mi=\"0\" ci=\"1\" mb=\"0\" cb=\"0\"/><line nr=\"16\" mi=\"0\" ci=\"5\" mb=\"0\" cb=\"0\"/><line nr=\"19\" mi=\"0\" ci=\"4\" mb=\"0\" cb=\"0\"/><line nr=\"22\" mi=\"0\" ci=\"2\" mb=\"0\" cb=\"0\"/><line nr=\"26\" mi=\"3\" ci=\"0\" mb=\"0\" cb=\"0\"/><line nr=\"27\" mi=\"1\" ci=\"0\" mb=\"0\" cb=\"0\"/><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"31\"/><counter type=\"LINE\" missed=\"2\" covered=\"9\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"7\"/><counter type=\"METHOD\" missed=\"1\" covered=\"7\"/><counter type=\"CLASS\" missed=\"0\" covered=\"3\"/></sourcefile><sourcefile name=\"SimpleCoverage.java\"><line nr=\"3\" mi=\"0\" ci=\"3\" mb=\"0\" cb=\"0\"/><line nr=\"6\" mi=\"0\" ci=\"2\" mb=\"0\" cb=\"0\"/><line nr=\"10\" mi=\"3\" ci=\"0\" mb=\"0\" cb=\"0\"/><line nr=\"11\" mi=\"1\" ci=\"0\" mb=\"0\" cb=\"0\"/><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"5\"/><counter type=\"LINE\" missed=\"2\" covered=\"2\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"1\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></sourcefile><counter type=\"INSTRUCTION\" missed=\"8\" covered=\"36\"/><counter type=\"LINE\" missed=\"4\" covered=\"11\"/><counter type=\"COMPLEXITY\" missed=\"2\" covered=\"9\"/><counter type=\"METHOD\" missed=\"2\" covered=\"9\"/><counter type=\"CLASS\" missed=\"0\" covered=\"4\"/></package><counter type=\"INSTRUCTION\" missed=\"8\" covered=\"36\"/><counter type=\"LINE\" missed=\"4\" covered=\"11\"/><counter type=\"COMPLEXITY\" missed=\"2\" covered=\"9\"/><counter type=\"METHOD\" missed=\"2\" covered=\"9\"/><counter type=\"CLASS\" missed=\"0\" covered=\"4\"/></report>"
  },
  {
    "path": "src/test/resources/jacoco2-it.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<!--\n  #[license]\n  coveralls-maven-plugin\n  %%\n  Copyright (C) 2013 - 2016 Tapio Rautonen\n  %%\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n  \n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n  \n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n  %[license]\n  -->\n<!DOCTYPE report PUBLIC \"-//JACOCO//DTD Report 1.0//EN\" \"report.dtd\"><report name=\"module2\"><sessioninfo id=\"test\" start=\"1440276758209\" dump=\"1440276758651\"/><package name=\"org/eluder/coverage/sample\"><class name=\"org/eluder/coverage/sample/PartialCoverage\"><method name=\"&lt;init&gt;\" desc=\"()V\" line=\"3\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"3\"/><counter type=\"LINE\" missed=\"0\" covered=\"1\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"partial\" desc=\"(Z)V\" line=\"6\"><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"6\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"3\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"9\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"4\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></class><sourcefile name=\"PartialCoverage.java\"><line nr=\"3\" mi=\"0\" ci=\"3\" mb=\"0\" cb=\"0\"/><line nr=\"6\" mi=\"0\" ci=\"2\" mb=\"1\" cb=\"1\"/><line nr=\"7\" mi=\"4\" ci=\"0\" mb=\"0\" cb=\"0\"/><line nr=\"9\" mi=\"0\" ci=\"3\" mb=\"0\" cb=\"0\"/><line nr=\"11\" mi=\"0\" ci=\"1\" mb=\"0\" cb=\"0\"/><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"9\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"4\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></sourcefile><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"9\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"4\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></package><counter type=\"INSTRUCTION\" missed=\"4\" covered=\"9\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"4\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></report>\n"
  },
  {
    "path": "src/test/resources/jacoco2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><!DOCTYPE report PUBLIC \"-//JACOCO//DTD Report 1.0//EN\" \"report.dtd\"><report name=\"module2\"><sessioninfo id=\"test\" start=\"1408569688470\" dump=\"1408569688965\"/><package name=\"org/eluder/coverage/sample\"><class name=\"org/eluder/coverage/sample/PartialCoverage\"><method name=\"&lt;init&gt;\" desc=\"()V\" line=\"3\"><counter type=\"INSTRUCTION\" missed=\"0\" covered=\"3\"/><counter type=\"LINE\" missed=\"0\" covered=\"1\"/><counter type=\"COMPLEXITY\" missed=\"0\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><method name=\"partial\" desc=\"(Z)V\" line=\"6\"><counter type=\"INSTRUCTION\" missed=\"3\" covered=\"7\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"3\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"1\"/><counter type=\"METHOD\" missed=\"0\" covered=\"1\"/></method><counter type=\"INSTRUCTION\" missed=\"3\" covered=\"10\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"4\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></class><sourcefile name=\"PartialCoverage.java\"><line nr=\"3\" mi=\"0\" ci=\"3\" mb=\"0\" cb=\"0\"/><line nr=\"6\" mi=\"0\" ci=\"2\" mb=\"1\" cb=\"1\"/><line nr=\"7\" mi=\"0\" ci=\"4\" mb=\"0\" cb=\"0\"/><line nr=\"9\" mi=\"3\" ci=\"0\" mb=\"0\" cb=\"0\"/><line nr=\"11\" mi=\"0\" ci=\"1\" mb=\"0\" cb=\"0\"/><counter type=\"INSTRUCTION\" missed=\"3\" covered=\"10\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"4\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></sourcefile><counter type=\"INSTRUCTION\" missed=\"3\" covered=\"10\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"4\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></package><counter type=\"INSTRUCTION\" missed=\"3\" covered=\"10\"/><counter type=\"BRANCH\" missed=\"1\" covered=\"1\"/><counter type=\"LINE\" missed=\"1\" covered=\"4\"/><counter type=\"COMPLEXITY\" missed=\"1\" covered=\"2\"/><counter type=\"METHOD\" missed=\"0\" covered=\"2\"/><counter type=\"CLASS\" missed=\"0\" covered=\"1\"/></report>"
  },
  {
    "path": "src/test/resources/saga.xml",
    "content": "<?xml version=\"1.0\" ?>\n<!DOCTYPE coverage SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-04.dtd'>\n<!-- Generated using saga-core (http://timurstrekalov.github.com/saga/saga-core/) version 1.5.4 -->\n<coverage branch-rate=\"0.0\" branches-covered=\"0\" branches-valid=\"0\" complexity=\"0\" line-rate=\"0.8\" lines-valid=\"10\" lines-covered=\"8\" timestamp=\"1376875707\" version=\"1.9\">\n    <sources>\n        <source>coveralls-maven-plugin/sample/module1</source>\n    </sources>\n    <packages>\n        <package name=\"default\" line-rate=\"0.0\" branch-rate=\"0.0\" complexity=\"0\">\n            <classes>\n                <class name=\"Localization.js\" filename=\"src/Localization.js\" line-rate=\"0.75\" branch-rate=\"0.0\" complexity=\"0\">\n                    <methods />\n                    <lines>\n                        <line number=\"1\" hits=\"1\" branch=\"false\"/>\n                        <line number=\"2\" hits=\"1\" branch=\"false\"/>\n                        <line number=\"4\" hits=\"1\" branch=\"false\"/>\n                        <line number=\"5\" hits=\"1\" branch=\"false\"/>\n                        <line number=\"6\" hits=\"0\" branch=\"false\"/>\n                        <line number=\"9\" hits=\"1\" branch=\"false\"/>\n                        <line number=\"10\" hits=\"0\" branch=\"false\"/>\n                        <line number=\"13\" hits=\"1\" branch=\"false\"/>\n                    </lines>\n                </class>\n                <class name=\"Components.js\" filename=\"src/Components.js\" line-rate=\"1.0\" branch-rate=\"0.0\" complexity=\"0\">\n                    <methods />\n                    <lines>\n                        <line number=\"1\" hits=\"1\" branch=\"false\"/>\n                        <line number=\"2\" hits=\"1\" branch=\"false\"/>\n                    </lines>\n                </class>\n            </classes>\n        </package>\n    </packages>\n</coverage>\n"
  }
]