/**
         *
         * Checks a distribution point for revocation information for the
         * certificate <code>attrCert</code>.
         *
         * @param dp The distribution point to consider.
         * @param attrCert The attribute certificate which should be checked.
         * @param paramsPKIX PKIX parameters.
         * @param validDate The date when the certificate revocation status should
         *            be checked.
         * @param issuerCert Certificate to check if it is revoked.
         * @param reasonMask The reasons mask which is already checked.
         * @param certPathCerts The certificates of the certification path to be
         *            checked.
         * @throws Exception if the certificate is revoked or the status
         *             cannot be checked or some error occurs.
         */
        private static void CheckCrl(
            DistributionPoint dp,
            IX509AttributeCertificate attrCert,
            PkixParameters paramsPKIX,
            DateTime validDate,
            X509Certificate issuerCert,
            CertStatus certStatus,
            ReasonsMask reasonMask,
            IList certPathCerts)
        {
            /*
             * 4.3.6 No Revocation Available
             *
             * The noRevAvail extension, defined in [X.509-2000], allows an AC
             * issuer to indicate that no revocation information will be made
             * available for this AC.
             */
            if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
            {
                return;
            }

            DateTime currentDate = DateTime.UtcNow;

            if (validDate.CompareTo(currentDate) > 0)
            {
                throw new Exception("Validation time is in future.");
            }

            // (a)

            /*
             * We always get timely valid CRLs, so there is no step (a) (1).
             * "locally cached" CRLs are assumed to be in getStore(), additional
             * CRLs must be enabled in the ExtendedPkixParameters and are in
             * getAdditionalStore()
             */
            ISet crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert,
                                                                       currentDate, paramsPKIX);
            bool      validCrlFound = false;
            Exception lastException = null;

            IEnumerator crl_iter = crls.GetEnumerator();

            while (crl_iter.MoveNext() &&
                   certStatus.Status == CertStatus.Unrevoked &&
                   !reasonMask.IsAllReasons)
            {
                try
                {
                    X509Crl crl = (X509Crl)crl_iter.Current;

                    // (d)
                    ReasonsMask interimReasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(crl, dp);

                    // (e)

                    /*
                     * The reasons mask is updated at the end, so only valid CRLs
                     * can update it. If this CRL does not contain new reasons it
                     * must be ignored.
                     */
                    if (!interimReasonsMask.HasNewReasons(reasonMask))
                    {
                        continue;
                    }

                    // (f)
                    ISet keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, attrCert,
                                                                     null, null, paramsPKIX, certPathCerts);
                    // (g)
                    AsymmetricKeyParameter pubKey = Rfc3280CertPathUtilities.ProcessCrlG(crl, keys);

                    X509Crl deltaCRL = null;

                    if (paramsPKIX.IsUseDeltasEnabled)
                    {
                        // get delta CRLs
                        ISet deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(
                            currentDate, paramsPKIX, crl);
                        // we only want one valid delta CRL
                        // (h)
                        deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, pubKey);
                    }

                    /*
                     * CRL must be be valid at the current time, not the validation
                     * time. If a certificate is revoked with reason keyCompromise,
                     * cACompromise, it can be used for forgery, also for the past.
                     * This reason may not be contained in older CRLs.
                     */

                    /*
                     * in the chain model signatures stay valid also after the
                     * certificate has been expired, so they do not have to be in
                     * the CRL vality time
                     */
                    if (paramsPKIX.ValidityModel != PkixParameters.ChainValidityModel)
                    {
                        /*
                         * if a certificate has expired, but was revoked, it is not
                         * more in the CRL, so it would be regarded as valid if the
                         * first check is not done
                         */
                        if (attrCert.NotAfter.CompareTo(crl.ThisUpdate) < 0)
                        {
                            throw new Exception(
                                      "No valid CRL for current time found.");
                        }
                    }

                    Rfc3280CertPathUtilities.ProcessCrlB1(dp, attrCert, crl);

                    // (b) (2)
                    Rfc3280CertPathUtilities.ProcessCrlB2(dp, attrCert, crl);

                    // (c)
                    Rfc3280CertPathUtilities.ProcessCrlC(deltaCRL, crl, paramsPKIX);

                    // (i)
                    Rfc3280CertPathUtilities.ProcessCrlI(validDate, deltaCRL,
                                                         attrCert, certStatus, paramsPKIX);

                    // (j)
                    Rfc3280CertPathUtilities.ProcessCrlJ(validDate, crl, attrCert,
                                                         certStatus);

                    // (k)
                    if (certStatus.Status == CrlReason.RemoveFromCrl)
                    {
                        certStatus.Status = CertStatus.Unrevoked;
                    }

                    // update reasons mask
                    reasonMask.AddReasons(interimReasonsMask);
                    validCrlFound = true;
                }
                catch (Exception e)
                {
                    lastException = e;
                }
            }
            if (!validCrlFound)
            {
                throw lastException;
            }
        }