code: public static Instance getInstance(String type, Class<?> clazz,
              String algorithm) throws NoSuchAlgorithmException {
          // in the almost all cases, the first service will work
          // avoid taking long path if so
          ProviderList list = Providers.getProviderList();
          Service firstService = list.getService(type, algorithm);
          if (firstService == null) {
              throw new NoSuchAlgorithmException
                      (algorithm + " " + type + " not available");
          }
          NoSuchAlgorithmException failure;
          try {
              return getInstance(firstService, clazz);
          } catch (NoSuchAlgorithmException e) {
              failure = e;
          }
          // if we cannot get the service from the preferred provider,
          // fail over to the next
          for (Service s : list.getServices(type, algorithm)) {
              if (s == firstService) {
                  // do not retry initial failed service
                  continue;
              }
              try {
                  return getInstance(s, clazz);
              } catch (NoSuchAlgorithmException e) {
                  failure = e;
              }
          }
          throw failure;
      }
docs: /*
  For all the getInstance() methods below:
  @param type the type of engine (e.g. MessageDigest)
  @param clazz the Spi class that the implementation must subclass
  (e.g. MessageDigestSpi.class) or null if no superclass check
  is required
  @param algorithm the name of the algorithm (or alias), e.g. MD5
  @param provider the provider (String or Provider object)
  @param param the parameter to pass to the Spi constructor
  (for CertStores)
  
  There are overloaded methods for all the permutations.