class PluginsMetadataGenerator implements MetadataGenerator {
    private static final String PLUGIN_DESCRIPTOR_LOCATION = "META-INF/maven/plugin.xml";

    private final Map<Object, PluginsMetadata> processedPlugins;

    private final Date timestamp;

    PluginsMetadataGenerator(RepositorySystemSession session, InstallRequest request) {
        this(session, request.getMetadata());
    }

    PluginsMetadataGenerator(RepositorySystemSession session, DeployRequest request) {
        this(session, request.getMetadata());
    }

    private PluginsMetadataGenerator(RepositorySystemSession session, Collection<? extends Metadata> metadatas) {
        this.processedPlugins = new LinkedHashMap<>();
        this.timestamp = (Date) ConfigUtils.getObject(session, new Date(), "maven.startTime");

        /*
         * NOTE: This should be considered a quirk to support interop with Maven's legacy ArtifactDeployer which
         * processes one artifact at a time and hence cannot associate the artifacts from the same project to use the
         * same version index. Allowing the caller to pass in metadata from a previous deployment allows to re-establish
         * the association between the artifacts of the same project.
         */
        for (Iterator<? extends Metadata> it = metadatas.iterator(); it.hasNext(); ) {
            Metadata metadata = it.next();
            if (metadata instanceof PluginsMetadata) {
                it.remove();
                PluginsMetadata pluginMetadata = (PluginsMetadata) metadata;
                processedPlugins.put(pluginMetadata.getGroupId(), pluginMetadata);
            }
        }
    }

    @Override
    public Collection<? extends Metadata> prepare(Collection<? extends Artifact> artifacts) {
        return Collections.emptyList();
    }

    @Override
    public Artifact transformArtifact(Artifact artifact) {
        return artifact;
    }

    @Override
    public Collection<? extends Metadata> finish(Collection<? extends Artifact> artifacts) {<FILL_FUNCTION_BODY>}

    private PluginInfo extractPluginInfo(Artifact artifact) {
        // sanity: jar, no classifier and file exists
        if (artifact != null
                && "jar".equals(artifact.getExtension())
                && "".equals(artifact.getClassifier())
                && artifact.getPath() != null) {
            Path artifactPath = artifact.getPath();
            if (Files.isRegularFile(artifactPath)) {
                try (JarFile artifactJar = new JarFile(artifactPath.toFile(), false)) {
                    ZipEntry pluginDescriptorEntry = artifactJar.getEntry(PLUGIN_DESCRIPTOR_LOCATION);

                    if (pluginDescriptorEntry != null) {
                        try (InputStream is = artifactJar.getInputStream(pluginDescriptorEntry)) {
                            // Note: using DOM instead of use of
                            // org.apache.maven.plugin.descriptor.PluginDescriptor
                            // as it would pull in dependency on:
                            // - maven-plugin-api (for model)
                            // - Plexus Container (for model supporting classes and exceptions)
                            XmlNode root = XmlNodeBuilder.build(is, null);
                            String groupId = root.getChild("groupId").getValue();
                            String artifactId = root.getChild("artifactId").getValue();
                            String goalPrefix = root.getChild("goalPrefix").getValue();
                            String name = root.getChild("name").getValue();
                            return new PluginInfo(groupId, artifactId, goalPrefix, name);
                        }
                    }
                } catch (Exception e) {
                    // here we can have: IO. ZIP or Plexus Conf Ex: but we should not interfere with user intent
                }
            }
        }
        return null;
    }
}

        LinkedHashMap<String, PluginsMetadata> plugins = new LinkedHashMap<>();
        for (Artifact artifact : artifacts) {
            PluginInfo pluginInfo = extractPluginInfo(artifact);
            if (pluginInfo != null) {
                String key = pluginInfo.groupId;
                if (processedPlugins.get(key) == null) {
                    PluginsMetadata pluginMetadata = plugins.get(key);
                    if (pluginMetadata == null) {
                        pluginMetadata = new PluginsMetadata(pluginInfo, timestamp);
                        plugins.put(key, pluginMetadata);
                    }
                }
            }
        }
        return plugins.values();
    
<no_super_class>