code: public Map<String,VersionNumber> parseRequestedPlugins(InputStream configXml) throws IOException {
          final Map<String,VersionNumber> requestedPlugins = new TreeMap<>();
          try {
              SAXParserFactory.newInstance().newSAXParser().parse(configXml, new DefaultHandler() {
                  @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                      String plugin = attributes.getValue("plugin");
                      if (plugin == null) {
                          return;
                      }
                      if (!plugin.matches("[^@]+@[^@]+")) {
                          throw new SAXException("Malformed plugin attribute: " + plugin);
                      }
                      int at = plugin.indexOf('@');
                      String shortName = plugin.substring(0, at);
                      VersionNumber existing = requestedPlugins.get(shortName);
                      VersionNumber requested = new VersionNumber(plugin.substring(at + 1));
                      if (existing == null || existing.compareTo(requested) < 0) {
                          requestedPlugins.put(shortName, requested);
                      }
                  }
  
                  @Override public InputSource resolveEntity(String publicId, String systemId) throws IOException,
                          SAXException {
                      return RestrictiveEntityResolver.INSTANCE.resolveEntity(publicId, systemId);
                  }
  
              });
          } catch (SAXException x) {
              throw new IOException("Failed to parse XML",x);
          } catch (ParserConfigurationException e) {
              throw new AssertionError(e); // impossible since we don't tweak XMLParser
          }
          return requestedPlugins;
      }
docs: Parses configuration XML files and picks up references to XML files.