PluginFQNParser { public ExtendedPluginFQN parsePluginFQN(String plugin) throws InfrastructureException { String url; String id; String publisher; String name; String version; URI registryURI = null; Matcher matcher = PLUGIN_PATTERN.matcher(plugin); if (matcher.matches()) { url = matcher.group("url"); id = matcher.group("id"); publisher = matcher.group("publisher"); name = matcher.group("name"); version = matcher.group("version"); } else { throw new InfrastructureException(format(INCORRECT_PLUGIN_FORMAT_TEMPLATE, plugin)); } if (!isNullOrEmpty(url)) { if (isNullOrEmpty(id)) { return new ExtendedPluginFQN(url); } else { try { registryURI = new URI(url); } catch (URISyntaxException e) { throw new InfrastructureException( format( "Plugin registry URL '%s' is invalid. Problematic plugin entry: '%s'", url, plugin)); } } } return new ExtendedPluginFQN(registryURI, id, publisher, name, version); }  Collection<PluginFQN> parsePlugins(Map<String, String> attributes); ExtendedPluginFQN parsePluginFQN(String plugin); ExtendedPluginFQN evaluateFqn(String reference, FileContentProvider fileContentProvider);  }
@Test(dataProvider = "validPluginStringProvider") public void shouldParsePluginOrEditorToExtendedFQN(String plugin, ExtendedPluginFQN expected) throws Exception { ExtendedPluginFQN actual = parser.parsePluginFQN(plugin); assertEquals(actual, expected); }