public static Map<String, MavenArtifact> getWebappDependencies() throws IOException {
		// list dependencies in WEB-INF/lib
		// and read names, urls, licences in META-INF/maven/.../pom.xml from jar files when available
		final Map<String, MavenArtifact> webappDependencies = getWebappDependenciesFromWebInfLib();

		// when pom.xml not available in some jar files,
		// list all dependencies in webapp's pom.xml if it exists or in the other dependencies' pom.xml,
		// including transitive dependencies
		final List<MavenArtifact> allDependencies = new ArrayList<>(
				getWebappDependenciesFromPomXml());
		for (final MavenArtifact dependency : webappDependencies.values()) {
			if (dependency != null && !dependency.isContained(allDependencies)) {
				allDependencies.add(dependency);
				for (final MavenArtifact transitiveDependency : dependency.getAllDependencies()) {
					if (!transitiveDependency.isContained(allDependencies)) {
						allDependencies.add(transitiveDependency);
					}
				}
			}
		}
		// in order to complete names, urls, licences from all dependencies and parents
		for (final Map.Entry<String, MavenArtifact> entry : webappDependencies.entrySet()) {
			if (entry.getValue() == null) {
				final String jarFileName = entry.getKey();
				for (final MavenArtifact dependency : allDependencies) {
					if (jarFileName.startsWith(
							dependency.getArtifactId() + '-' + dependency.getVersion())) {
						entry.setValue(dependency);
						break;
					}
				}
			}
		}
		return webappDependencies;
	}
@Test
	public void testGetWebappDependencies() throws IOException {
		final ServletContext context = createNiceMock(ServletContext.class);
		final String javamelodyDir = "/META-INF/maven/net.bull.javamelody/";
		final String webapp = javamelodyDir + "javamelody-test-webapp/";
		expect(context.getResourcePaths("/META-INF/maven/"))
				.andReturn(Collections.singleton(javamelodyDir)).anyTimes();
		expect(context.getResourcePaths(javamelodyDir)).andReturn(Collections.singleton(webapp))
				.anyTimes();
		final IAnswer<InputStream> answer = () -> getClass().getResourceAsStream("/pom.xml");
		expect(context.getResourceAsStream(webapp + "pom.xml")).andAnswer(answer).anyTimes();
		final Set<String> dependencies = new LinkedHashSet<>(List
				.of("/WEB-INF/lib/jrobin-1.5.9.jar", "/WEB-INF/lib/javamelody-core-1.65.0.jar"));
		expect(context.getResourcePaths("/WEB-INF/lib/")).andReturn(dependencies).anyTimes();
		final URL jrobinJar = RrdGraph.class.getProtectionDomain().getCodeSource().getLocation();
		expect(context.getResource("/WEB-INF/lib/jrobin-1.5.9.jar")).andReturn(jrobinJar)
				.anyTimes();
		expect(context.getMajorVersion()).andReturn(5).anyTimes();
		expect(context.getMinorVersion()).andReturn(0).anyTimes();
		replay(context);
		Parameters.initialize(context);
		final Map<String, MavenArtifact> webappDependencies = MavenArtifact.getWebappDependencies();
		assertFalse("getWebappDependencies", webappDependencies.isEmpty());
		verify(context);
		for (final MavenArtifact dependency : webappDependencies.values()) {
			if (dependency != null) {
				assertNotNull("groupId", dependency.getGroupId());
				assertNotNull("artifactId", dependency.getArtifactId());
				assertNotNull("version", dependency.getVersion());
				if ("jrobin".equals(dependency.getArtifactId())) {
					assertNotNull("name", dependency.getName());
					assertNotNull("url", dependency.getUrl());
					assertNotNull("licenseUrlsByName", dependency.getLicenseUrlsByName());
					assertNotNull("allDependencies", dependency.getAllDependencies());
					assertNotNull("toString", dependency.toString());
				}
			}
		}
	}