@Override
 public final D scan(I container, String path, Scope scope, Scanner scanner) throws IOException {
   ScannerContext context = scanner.getContext();
   D containerDescriptor = getContainerDescriptor(container, context);
   String containerPath = getContainerPath(container, path);
   containerDescriptor.setFileName(containerPath);
   LOGGER.info("Entering {}", containerPath);
   ContainerFileResolver fileResolverStrategy = new ContainerFileResolver(containerDescriptor);
   context.push(FileResolver.class, fileResolverStrategy);
   enterContainer(container, containerDescriptor, scanner.getContext());
   Stopwatch stopwatch = Stopwatch.createStarted();
   try {
     Iterable<? extends E> entries = getEntries(container);
     for (E entry : entries) {
       String relativePath = getRelativePath(container, entry);
       try (Resource resource = getEntry(container, entry)) {
         LOGGER.debug("Scanning {}", relativePath);
         FileDescriptor descriptor = scanner.scan(resource, relativePath, scope);
         fileResolverStrategy.put(relativePath, descriptor);
       }
     }
   } finally {
     leaveContainer(container, containerDescriptor, scanner.getContext());
     context.pop(FileResolver.class);
   }
   fileResolverStrategy.flush();
   LOGGER.info(
       "Leaving {} ({} entries, {} ms)",
       containerPath,
       fileResolverStrategy.size(),
       stopwatch.elapsed(MILLISECONDS));
   return containerDescriptor;
 }
 /**
  * Create the descriptor and set base information.
  *
  * @param model The model.
  * @param scanner The scanner.
  * @return The descriptor.
  */
 protected MavenPomDescriptor createMavenPomDescriptor(Model model, Scanner scanner) {
   ScannerContext context = scanner.getContext();
   MavenPomDescriptor pomDescriptor = context.peek(MavenPomDescriptor.class);
   pomDescriptor.setName(model.getName());
   pomDescriptor.setGroupId(model.getGroupId());
   pomDescriptor.setArtifactId(model.getArtifactId());
   pomDescriptor.setPackaging(model.getPackaging());
   pomDescriptor.setVersion(model.getVersion());
   String pomFqn = getFullyQualifiedName(model);
   pomDescriptor.setFullQualifiedName(pomFqn);
   Coordinates artifactCoordinates = new ModelCoordinates(model);
   MavenArtifactDescriptor artifact =
       getArtifactResolver(context).resolve(artifactCoordinates, context);
   // if the pom describes itself as artifact then the returned artifact
   // descriptor must be used as pom descriptor (the old instance is
   // invalidated due to adding labels)
   if (MavenPomDescriptor.class.isAssignableFrom(artifact.getClass())) {
     pomDescriptor = MavenPomDescriptor.class.cast(artifact);
   }
   pomDescriptor.getDescribes().add(artifact);
   return pomDescriptor;
 }
 /** {@inheritDoc} */
 @Override
 public MavenPomDescriptor scan(Model model, String path, Scope scope, Scanner scanner)
     throws IOException {
   MavenPomDescriptor pomDescriptor = createMavenPomDescriptor(model, scanner);
   ScannerContext scannerContext = scanner.getContext();
   Store store = scannerContext.getStore();
   addParent(pomDescriptor, model, scannerContext);
   addProfiles(pomDescriptor, model, scannerContext);
   addProperties(pomDescriptor, model.getProperties(), store);
   addModules(pomDescriptor, model.getModules(), store);
   addManagedDependencies(
       pomDescriptor,
       model.getDependencyManagement(),
       scannerContext,
       PomManagesDependencyDescriptor.class);
   addDependencies(
       pomDescriptor, model.getDependencies(), PomDependsOnDescriptor.class, scannerContext);
   addManagedPlugins(pomDescriptor, model.getBuild(), scannerContext);
   addPlugins(pomDescriptor, model.getBuild(), scannerContext);
   addLicenses(pomDescriptor, model, store);
   return pomDescriptor;
 }
 /**
  * Adds information about artifact dependencies.
  *
  * @param dependent The dependent to add artifacts as dependencies
  * @param dependencies The dependencies information.
  * @param scannerContext The scanner context
  */
 private <P extends MavenDependentDescriptor, D extends BaseDependencyDescriptor>
     void addDependencies(
         P dependent,
         List<Dependency> dependencies,
         Class<D> dependencyType,
         ScannerContext scannerContext) {
   for (Dependency dependency : dependencies) {
     MavenArtifactDescriptor dependencyArtifactDescriptor =
         getMavenArtifactDescriptor(dependency, scannerContext);
     D dependencyDescriptor =
         scannerContext.getStore().create(dependent, dependencyType, dependencyArtifactDescriptor);
     dependencyDescriptor.setOptional(dependency.isOptional());
     dependencyDescriptor.setScope(dependency.getScope());
   }
 }
 /**
  * Adds information about profile dependencies.
  *
  * @param profileDescriptor The descriptor for the current profile.
  * @param dependencies The dependencies information.
  * @param scannerContext The scanner context.
  */
 private void addProfileDependencies(
     MavenProfileDescriptor profileDescriptor,
     List<Dependency> dependencies,
     ScannerContext scannerContext) {
   for (Dependency dependency : dependencies) {
     MavenArtifactDescriptor dependencyArtifactDescriptor =
         getMavenArtifactDescriptor(dependency, scannerContext);
     ProfileDependsOnDescriptor profileDependsOnDescriptor =
         scannerContext
             .getStore()
             .create(
                 profileDescriptor,
                 ProfileDependsOnDescriptor.class,
                 dependencyArtifactDescriptor);
     profileDependsOnDescriptor.setOptional(dependency.isOptional());
     profileDependsOnDescriptor.setScope(dependency.getScope());
   }
 }
 /**
  * Adds information about defined profile.
  *
  * @param pomDescriptor The descriptor for the current POM.
  * @param model The Maven Model.
  * @param scannerContext The scanner context.
  */
 private void addProfiles(
     MavenPomDescriptor pomDescriptor, Model model, ScannerContext scannerContext) {
   List<Profile> profiles = model.getProfiles();
   Store store = scannerContext.getStore();
   for (Profile profile : profiles) {
     MavenProfileDescriptor mavenProfileDescriptor = store.create(MavenProfileDescriptor.class);
     pomDescriptor.getProfiles().add(mavenProfileDescriptor);
     mavenProfileDescriptor.setId(profile.getId());
     addProperties(mavenProfileDescriptor, profile.getProperties(), store);
     addModules(mavenProfileDescriptor, profile.getModules(), store);
     addPlugins(mavenProfileDescriptor, profile.getBuild(), scannerContext);
     addManagedPlugins(mavenProfileDescriptor, profile.getBuild(), scannerContext);
     addManagedDependencies(
         mavenProfileDescriptor,
         profile.getDependencyManagement(),
         scannerContext,
         ProfileManagesDependencyDescriptor.class);
     addProfileDependencies(mavenProfileDescriptor, profile.getDependencies(), scannerContext);
     addActivation(mavenProfileDescriptor, profile.getActivation(), store);
   }
 }
 /**
  * Create plugin descriptors for the given plugins.
  *
  * @param plugins The plugins.
  * @param context The scanner context.
  * @return The plugin descriptors.
  */
 private List<MavenPluginDescriptor> createMavenPluginDescriptors(
     List<Plugin> plugins, ScannerContext context) {
   Store store = context.getStore();
   List<MavenPluginDescriptor> pluginDescriptors = new ArrayList<>();
   for (Plugin plugin : plugins) {
     MavenPluginDescriptor mavenPluginDescriptor = store.create(MavenPluginDescriptor.class);
     MavenArtifactDescriptor artifactDescriptor =
         getArtifactResolver(context).resolve(new PluginCoordinates(plugin), context);
     mavenPluginDescriptor.setArtifact(artifactDescriptor);
     mavenPluginDescriptor.setInherited(plugin.isInherited());
     addDependencies(
         mavenPluginDescriptor,
         plugin.getDependencies(),
         PluginDependsOnDescriptor.class,
         context);
     addPluginExecutions(mavenPluginDescriptor, plugin, store);
     addConfiguration(mavenPluginDescriptor, (Xpp3Dom) plugin.getConfiguration(), store);
     pluginDescriptors.add(mavenPluginDescriptor);
   }
   return pluginDescriptors;
 }
 /**
  * Acquires the artifact resolver from the scanner context.
  *
  * @param context The scanner context.
  * @return The artifact resolver from the context or the default one if none is available.
  */
 private ArtifactResolver getArtifactResolver(ScannerContext context) {
   return context.peekOrDefault(ArtifactResolver.class, defaultArtifactResolver);
 }