/**
  * Searches for a holder public key certificate and verifies its certification path.
  *
  * @param attrCert the attribute certificate.
  * @param pkixParams The PKIX parameters.
  * @return The certificate path of the holder certificate.
  * @throws AnnotatedException if
  *     <ul>
  *       <li>no public key certificate can be found although holder information is given by an
  *           entity name or a base certificate ID
  *       <li>support classes cannot be created
  *       <li>no certification path for the public key certificate can be built
  *     </ul>
  */
 protected static CertPath processAttrCert1(
     X509AttributeCertificate attrCert, ExtendedPKIXParameters pkixParams)
     throws CertPathValidatorException {
   CertPathBuilderResult result = null;
   // find holder PKCs
   Set holderPKCs = new HashSet();
   if (attrCert.getHolder().getIssuer() != null) {
     X509CertStoreSelector selector = new X509CertStoreSelector();
     selector.setSerialNumber(attrCert.getHolder().getSerialNumber());
     Principal[] principals = attrCert.getHolder().getIssuer();
     for (int i = 0; i < principals.length; i++) {
       try {
         if (principals[i] instanceof X500Principal) {
           selector.setIssuer(((X500Principal) principals[i]).getEncoded());
         }
         holderPKCs.addAll(
             CertPathValidatorUtilities.findCertificates(selector, pkixParams.getStores()));
       } catch (AnnotatedException e) {
         throw new ExtCertPathValidatorException(
             "Public key certificate for attribute certificate cannot be searched.", e);
       } catch (IOException e) {
         throw new ExtCertPathValidatorException("Unable to encode X500 principal.", e);
       }
     }
     if (holderPKCs.isEmpty()) {
       throw new CertPathValidatorException(
           "Public key certificate specified in base certificate ID for attribute certificate cannot be found.");
     }
   }
   if (attrCert.getHolder().getEntityNames() != null) {
     X509CertStoreSelector selector = new X509CertStoreSelector();
     Principal[] principals = attrCert.getHolder().getEntityNames();
     for (int i = 0; i < principals.length; i++) {
       try {
         if (principals[i] instanceof X500Principal) {
           selector.setIssuer(((X500Principal) principals[i]).getEncoded());
         }
         holderPKCs.addAll(
             CertPathValidatorUtilities.findCertificates(selector, pkixParams.getStores()));
       } catch (AnnotatedException e) {
         throw new ExtCertPathValidatorException(
             "Public key certificate for attribute certificate cannot be searched.", e);
       } catch (IOException e) {
         throw new ExtCertPathValidatorException("Unable to encode X500 principal.", e);
       }
     }
     if (holderPKCs.isEmpty()) {
       throw new CertPathValidatorException(
           "Public key certificate specified in entity name for attribute certificate cannot be found.");
     }
   }
   // verify cert paths for PKCs
   ExtendedPKIXBuilderParameters params =
       (ExtendedPKIXBuilderParameters) ExtendedPKIXBuilderParameters.getInstance(pkixParams);
   CertPathValidatorException lastException = null;
   for (Iterator it = holderPKCs.iterator(); it.hasNext(); ) {
     X509CertStoreSelector selector = new X509CertStoreSelector();
     selector.setCertificate((X509Certificate) it.next());
     params.setTargetConstraints(selector);
     CertPathBuilder builder = null;
     try {
       builder = CertPathBuilder.getInstance("PKIX", "BC");
     } catch (NoSuchProviderException e) {
       throw new ExtCertPathValidatorException("Support class could not be created.", e);
     } catch (NoSuchAlgorithmException e) {
       throw new ExtCertPathValidatorException("Support class could not be created.", e);
     }
     try {
       result = builder.build(ExtendedPKIXBuilderParameters.getInstance(params));
     } catch (CertPathBuilderException e) {
       lastException =
           new ExtCertPathValidatorException(
               "Certification path for public key certificate of attribute certificate could not be build.",
               e);
     } catch (InvalidAlgorithmParameterException e) {
       // must be a programming error
       throw new RuntimeException(e.getMessage());
     }
   }
   if (lastException != null) {
     throw lastException;
   }
   return result.getCertPath();
 }