Program: 5042
Project: 5042
Buggy source:
/** 
 * Get all plugin classes of the given type and name that extend the given parent artifact. Results are returned as a map from plugin artifact to plugins in that artifact.
 * @param parentArtifactRange the parent artifact range to find plugins for
 * @param type the type of plugin to look for
 * @param name the name of the plugin to look for
 * @param pluginRange the predicate for the plugins
 * @param limit the limit number of the result
 * @param order the order of the result
 * @return an unmodifiable map of plugin artifact to plugin classes of the given type and name, accessible by thegiven artifact. The map will never be null, and will never be empty.
 * @throws PluginNotExistsException if no plugin with the given type and name exists in the namespace
 * @throws IOException if there was an exception reading metadata from the metastore
 */
public SortedMap<ArtifactDescriptor,PluginClass> getPluginClasses(final NamespaceId namespace,final ArtifactRange parentArtifactRange,final String type,final String name,@Nullable final Predicate<co.cask.cdap.proto.id.ArtifactId> pluginRange,final int limit,final ArtifactSortOrder order) throws IOException, ArtifactNotFoundException, PluginNotExistsException {
  try {
    SortedMap<ArtifactDescriptor,PluginClass> result=Transactions.execute(transactional,new TxCallable<SortedMap<ArtifactDescriptor,PluginClass>>(){
      @Override public SortedMap<ArtifactDescriptor,PluginClass> call(      DatasetContext context) throws Exception {
        Table metaTable=getMetaTable(context);
        List<ArtifactDetail> parentArtifactDetails=getArtifacts(metaTable,parentArtifactRange,limit,null);
        if (parentArtifactDetails.isEmpty()) {
          throw new ArtifactNotFoundException(parentArtifactRange.getNamespace(),parentArtifactRange.getName());
        }
        SortedMap<ArtifactDescriptor,PluginClass> plugins=order == ArtifactSortOrder.DESC ? new TreeMap<ArtifactDescriptor,PluginClass>(Collections.<ArtifactDescriptor>reverseOrder()) : new TreeMap<ArtifactDescriptor,PluginClass>();
        List<Id.Artifact> parentArtifacts=new ArrayList<>();
        for (        ArtifactDetail parentArtifactDetail : parentArtifactDetails) {
          Id.Artifact parentArtifactId=Id.Artifact.from(namespace.toId(),parentArtifactDetail.getDescriptor().getArtifactId());
          parentArtifacts.add(parentArtifactId);
          Set<PluginClass> parentPlugins=parentArtifactDetail.getMeta().getClasses().getPlugins();
          for (          PluginClass pluginClass : parentPlugins) {
            if (pluginClass.getName().equals(name) && pluginClass.getType().equals(type)) {
              plugins.put(parentArtifactDetail.getDescriptor(),pluginClass);
              break;
            }
          }
        }
        PluginKey pluginKey=new PluginKey(parentArtifactRange.getNamespace().toId(),parentArtifactRange.getName(),type,name);
        Row row=metaTable.get(pluginKey.getRowKey());
        if (!row.isEmpty()) {
          addPluginsInRangeToMap(namespace,parentArtifacts,row.getColumns(),plugins,pluginRange,limit);
        }
        return Collections.unmodifiableSortedMap(plugins);
      }
    }
);
    if (result.isEmpty()) {
      throw new PluginNotExistsException(parentArtifactRange.getNamespace().toId(),type,name);
    }
    return result;
  }
 catch (  TransactionFailureException e) {
    throw Transactions.propagate(e,IOException.class,ArtifactNotFoundException.class);
  }
}

Fixed version (ground truth):
/** 
 * Get all plugin classes of the given type and name that extend the given parent artifact. Results are returned as a map from plugin artifact to plugins in that artifact.
 * @param parentArtifactRange the parent artifact range to find plugins for
 * @param type the type of plugin to look for
 * @param name the name of the plugin to look for
 * @param pluginRange the predicate for the plugins
 * @param limit the limit number of the result
 * @param order the order of the result
 * @return an unmodifiable map of plugin artifact to plugin classes of the given type and name, accessible by thegiven artifact. The map will never be null, and will never be empty.
 * @throws PluginNotExistsException if no plugin with the given type and name exists in the namespace
 * @throws IOException if there was an exception reading metadata from the metastore
 */
public SortedMap<ArtifactDescriptor,PluginClass> getPluginClasses(final NamespaceId namespace,final ArtifactRange parentArtifactRange,final String type,final String name,@Nullable final Predicate<co.cask.cdap.proto.id.ArtifactId> pluginRange,final int limit,final ArtifactSortOrder order) throws IOException, ArtifactNotFoundException, PluginNotExistsException {
  try {
    SortedMap<ArtifactDescriptor,PluginClass> result=Transactions.execute(transactional,new TxCallable<SortedMap<ArtifactDescriptor,PluginClass>>(){
      @Override public SortedMap<ArtifactDescriptor,PluginClass> call(      DatasetContext context) throws Exception {
        Table metaTable=getMetaTable(context);
        List<ArtifactDetail> parentArtifactDetails=getArtifacts(metaTable,parentArtifactRange,Integer.MAX_VALUE,null);
        if (parentArtifactDetails.isEmpty()) {
          throw new ArtifactNotFoundException(parentArtifactRange.getNamespace(),parentArtifactRange.getName());
        }
        SortedMap<ArtifactDescriptor,PluginClass> plugins=order == ArtifactSortOrder.DESC ? new TreeMap<ArtifactDescriptor,PluginClass>(Collections.<ArtifactDescriptor>reverseOrder()) : new TreeMap<ArtifactDescriptor,PluginClass>();
        List<Id.Artifact> parentArtifacts=new ArrayList<>();
        for (        ArtifactDetail parentArtifactDetail : parentArtifactDetails) {
          Id.Artifact parentArtifactId=Id.Artifact.from(namespace.toId(),parentArtifactDetail.getDescriptor().getArtifactId());
          parentArtifacts.add(parentArtifactId);
          Set<PluginClass> parentPlugins=parentArtifactDetail.getMeta().getClasses().getPlugins();
          for (          PluginClass pluginClass : parentPlugins) {
            if (pluginClass.getName().equals(name) && pluginClass.getType().equals(type)) {
              plugins.put(parentArtifactDetail.getDescriptor(),pluginClass);
              break;
            }
          }
        }
        PluginKey pluginKey=new PluginKey(parentArtifactRange.getNamespace().toId(),parentArtifactRange.getName(),type,name);
        Row row=metaTable.get(pluginKey.getRowKey());
        if (!row.isEmpty()) {
          addPluginsInRangeToMap(namespace,parentArtifacts,row.getColumns(),plugins,pluginRange,limit);
        }
        return Collections.unmodifiableSortedMap(plugins);
      }
    }
);
    if (result.isEmpty()) {
      throw new PluginNotExistsException(parentArtifactRange.getNamespace().toId(),type,name);
    }
    return result;
  }
 catch (  TransactionFailureException e) {
    throw Transactions.propagate(e,IOException.class,ArtifactNotFoundException.class);
  }
}