if (!c && !usage->anyUsage) {
if (!cp && !usage->anyUsage) {
NSSCertificate_BuildChain(  NSSCertificate *c,  NSSTime *timeOpt,  NSSUsage *usage,  NSSPolicies *policiesOpt,  NSSCertificate **rvOpt,  PRUint32 rvLimit, /* zero for no limit */  NSSArena *arenaOpt,  PRStatus *statusOpt){    PRStatus nssrv;    nssList *chain;    NSSItem *issuerID;    NSSCertificate **rvChain;    NSSTrustDomain *td;    NSSCryptoContext *cc;    nssDecodedCert *dc;    cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */    td = NSSCertificate_GetTrustDomain(c);#ifdef NSS_3_4_CODE    if (!td) {	td = STAN_GetDefaultTrustDomain();    }#endif    chain = nssList_Create(NULL, PR_FALSE);    nssList_Add(chain, c);    if (statusOpt) *statusOpt = PR_SUCCESS;    if (rvLimit == 1) goto finish;    while (!nssItem_Equal(&c->subject, &c->issuer, &nssrv)) {	dc = nssCertificate_GetDecoding(c);	issuerID = dc->getIssuerIdentifier(dc);	if (issuerID) {	    c = find_issuer_cert_for_identifier(c, issuerID);	    nss_ZFreeIf(issuerID);	    if (!c) {		nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);		if (statusOpt) *statusOpt = PR_FAILURE;		goto finish;	    }	} else {	    NSSDER *issuer = &c->issuer;#ifdef NSS_3_4_CODE	    PRBool tmpca = usage->nss3lookingForCA;	    usage->nss3lookingForCA = PR_TRUE;#endif	    c = NULL;	    if (cc) {		c = NSSCryptoContext_FindBestCertificateBySubject(cc,		                                                  issuer,		                                                  timeOpt,		                                                  usage,		                                                  policiesOpt);		/* Mimic functionality from CERT_FindCertIssuer.  If a matching		 * cert (based on trust & usage) cannot be found, just take the		 * newest cert with the correct subject.		 */		if (!c && !usage->anyUsage) {		    usage->anyUsage = PR_TRUE;		    c = NSSCryptoContext_FindBestCertificateBySubject(cc,		                                                  issuer,		                                                  timeOpt,		                                                  usage,		                                                  policiesOpt);		    usage->anyUsage = PR_FALSE;		}	    }	    if (!c) {		c = NSSTrustDomain_FindBestCertificateBySubject(td,		                                                issuer,		                                                timeOpt,		                                                usage,		                                                policiesOpt);	    }	    /* Mimic functionality from CERT_FindCertIssuer.  If a matching	     * cert (based on trust & usage) cannot be found, just take the	     * newest cert with the correct subject.	     */	    if (!c && !usage->anyUsage) {		usage->anyUsage = PR_TRUE;		c = NSSTrustDomain_FindBestCertificateBySubject(td,		                                                issuer,		                                                timeOpt,		                                                usage,		                                                policiesOpt);		usage->anyUsage = PR_FALSE;	    }#ifdef NSS_3_4_CODE	    usage->nss3lookingForCA = tmpca;#endif	    if (!c) {		nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);		if (statusOpt) *statusOpt = PR_FAILURE;		goto finish;	    }	}	nssList_Add(chain, c);	if (nssList_Count(chain) == rvLimit) goto finish;    }finish:    if (rvOpt) {	rvChain = rvOpt;    } else {	rvLimit = nssList_Count(chain);	rvChain = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvLimit + 1);    }    nssList_GetArray(chain, (void **)rvChain, rvLimit);    nssList_Destroy(chain);    /* XXX now, the question is, cache all certs in the chain? */    return rvChain;}