Program: 36801
Project: 36801
Buggy source:
/** 
 * Returns an array containing all installed providers that satisfy the specified* selection criteria, or null if no such providers have been installed. The returned providers are ordered according to their <a href= "#insertProviderAt(java.security.Provider, int)">preference order</a>. <p>The selection criteria are represented by a map. Each map entry represents a selection criterion. A provider is selected iff it satisfies all selection criteria. The key for any entry in such a map must be in one of the following two formats: <ul> <li> <i>&lt;crypto_service>.&lt;algorithm_or_type></i> <p> The cryptographic service name must not contain any dots. <p> The value associated with the key must be an empty string. <p> A provider satisfies this selection criterion iff the provider implements the specified algorithm or type for the specified cryptographic service. <li>  <i>&lt;crypto_service>.&lt;algorithm_or_type> &lt;attribute_name></i> <p> The cryptographic service name must not contain any dots. There must be one or more space charaters between the <i>&lt;algorithm_or_type></i> and the <i>&lt;attribute_name></i>. <p> The value associated with the key must be a non-empty string. A provider satisfies this selection criterion iff the provider implements the specified algorithm or type for the specified cryptographic service and its implementation meets the constraint expressed by the specified attribute name/value pair. </ul> <p> See the <a href= "../../../technotes/guides/security/StandardNames.html"> Java Cryptography Architecture Standard Algorithm Name Documentation</a> for information about standard cryptographic service names, standard algorithm names and standard attribute names.
 * @param filter the criteria for selectingproviders. The filter is case-insensitive.
 * @return all the installed providers that satisfy the selectioncriteria, or null if no such providers have been installed.
 * @throws InvalidParameterException if the filter is not in the required format
 * @throws NullPointerException if filter is null
 * @see #getProviders(java.lang.String)
 * @since 1.3
 */
public static Provider[] getProviders(Map<String,String> filter){
  Provider[] allProviders=Security.getProviders();
  Set<String> keySet=filter.keySet();
  LinkedHashSet<Provider> candidates=new LinkedHashSet<>(5);
  if ((keySet == null) || (allProviders == null)) {
    return allProviders;
  }
  boolean firstSearch=true;
  for (Iterator<String> ite=keySet.iterator(); ite.hasNext(); ) {
    String key=ite.next();
    String value=filter.get(key);
    LinkedHashSet<Provider> newCandidates=getAllQualifyingCandidates(key,value,allProviders);
    if (firstSearch) {
      candidates=newCandidates;
      firstSearch=false;
    }
    if ((newCandidates != null) && !newCandidates.isEmpty()) {
      for (Iterator<Provider> cansIte=candidates.iterator(); cansIte.hasNext(); ) {
        Provider prov=cansIte.next();
        if (!newCandidates.contains(prov)) {
          cansIte.remove();
        }
      }
    }
 else {
      candidates=null;
      break;
    }
  }
  if ((candidates == null) || (candidates.isEmpty()))   return null;
  Object[] candidatesArray=candidates.toArray();
  Provider[] result=new Provider[candidatesArray.length];
  for (int i=0; i < result.length; i++) {
    result[i]=(Provider)candidatesArray[i];
  }
  return result;
}

Fixed version (ground truth):
/** 
 * Returns an array containing all installed providers that satisfy the specified* selection criteria, or null if no such providers have been installed. The returned providers are ordered according to their  {@linkplain #insertProviderAt(java.security.Provider,int) preference order}. <p>The selection criteria are represented by a map. Each map entry represents a selection criterion. A provider is selected iff it satisfies all selection criteria. The key for any entry in such a map must be in one of the following two formats: <ul> <li> <i>  {@literal <crypto_service>.<algorithm_or_type>}</i> <p> The cryptographic service name must not contain any dots. <p> The value associated with the key must be an empty string. <p> A provider satisfies this selection criterion iff the provider implements the specified algorithm or type for the specified cryptographic service. <li>  <i>  {@literal <crypto_service>}.  {@literal <algorithm_or_type> <attribute_name>}</i> <p> The cryptographic service name must not contain any dots. There must be one or more space charaters between the <i>  {@literal <algorithm_or_type>}</i> and the <i>  {@literal <attribute_name>}</i>. <p> The value associated with the key must be a non-empty string. A provider satisfies this selection criterion iff the provider implements the specified algorithm or type for the specified cryptographic service and its implementation meets the constraint expressed by the specified attribute name/value pair. </ul> <p> See the <a href= "../../../technotes/guides/security/StandardNames.html"> Java Cryptography Architecture Standard Algorithm Name Documentation</a> for information about standard cryptographic service names, standard algorithm names and standard attribute names.
 * @param filter the criteria for selectingproviders. The filter is case-insensitive.
 * @return all the installed providers that satisfy the selectioncriteria, or null if no such providers have been installed.
 * @throws InvalidParameterException if the filter is not in the required format
 * @throws NullPointerException if filter is null
 * @see #getProviders(java.lang.String)
 * @since 1.3
 */
public static Provider[] getProviders(Map<String,String> filter){
  Provider[] allProviders=Security.getProviders();
  Set<String> keySet=filter.keySet();
  LinkedHashSet<Provider> candidates=new LinkedHashSet<>(5);
  if ((keySet == null) || (allProviders == null)) {
    return allProviders;
  }
  boolean firstSearch=true;
  for (Iterator<String> ite=keySet.iterator(); ite.hasNext(); ) {
    String key=ite.next();
    String value=filter.get(key);
    LinkedHashSet<Provider> newCandidates=getAllQualifyingCandidates(key,value,allProviders);
    if (firstSearch) {
      candidates=newCandidates;
      firstSearch=false;
    }
    if ((newCandidates != null) && !newCandidates.isEmpty()) {
      for (Iterator<Provider> cansIte=candidates.iterator(); cansIte.hasNext(); ) {
        Provider prov=cansIte.next();
        if (!newCandidates.contains(prov)) {
          cansIte.remove();
        }
      }
    }
 else {
      candidates=null;
      break;
    }
  }
  if ((candidates == null) || (candidates.isEmpty()))   return null;
  Object[] candidatesArray=candidates.toArray();
  Provider[] result=new Provider[candidatesArray.length];
  for (int i=0; i < result.length; i++) {
    result[i]=(Provider)candidatesArray[i];
  }
  return result;
}