if (mAllowNegativeAssertions == PR_TRUE) {  PRBool hasNegation = PR_FALSE; for (i = mNext - 1; i >= 0; --i) { nsIRDFDataSource* datasource = (nsIRDFDataSource*) mCompositeDataSource->mDataSources[i];
if (mAllowNegativeAssertions == PR_TRUE) {  PRBool hasNegation = PR_FALSE; for (i = mNext - 1; i >= 0; --i) { nsIRDFDataSource* datasource = mCompositeDataSource->mDataSources[i];
CompositeEnumeratorImpl::HasMoreElements(PRBool* aResult){    NS_PRECONDITION(aResult != nsnull, "null ptr");    if (! aResult)        return NS_ERROR_NULL_POINTER;    nsresult rv;    // If we've already queued up a next target, then yep, there are    // more elements.    if (mResult) {        *aResult = PR_TRUE;        return NS_OK;    }    // Otherwise, we'll need to find a next target, switching cursors    // if necessary.    for ( ; mNext < mCompositeDataSource->mDataSources.Count(); ++mNext) {        if (! mCurrent) {            // We don't have a current enumerator, so create a new one on            // the next data source.            nsIRDFDataSource* datasource =                (nsIRDFDataSource*) mCompositeDataSource->mDataSources[mNext];            rv = GetEnumerator(datasource, &mCurrent);            if (NS_FAILED(rv)) return rv;            if (rv == NS_RDF_NO_VALUE)                continue;            NS_ASSERTION(mCurrent != nsnull, "you're always supposed to return an enumerator from GetEnumerator, punk.");            if (! mCurrent)                continue;        }        do {            PRInt32 i;            PRBool hasMore;            rv = mCurrent->HasMoreElements(&hasMore);            if (NS_FAILED(rv)) return rv;            // Is the current enumerator depleted?            if (! hasMore) {                NS_RELEASE(mCurrent);                break;            }            // Even if the current enumerator has more elements, we still            // need to check that the current element isn't masked by            // a negation in an earlier data source.            // "Peek" ahead and pull out the next target.            nsCOMPtr<nsISupports> result;            rv = mCurrent->GetNext(getter_AddRefs(result));            if (NS_FAILED(rv)) return rv;            rv = result->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) &mResult);            if (NS_FAILED(rv)) return rv;		if (mAllowNegativeAssertions == PR_TRUE)		{			// See if any previous data source negates this			PRBool hasNegation = PR_FALSE;			for (i = mNext - 1; i >= 0; --i)			{				nsIRDFDataSource* datasource =				(nsIRDFDataSource*) mCompositeDataSource->mDataSources[i];				rv = HasNegation(datasource, mResult, &hasNegation);				if (NS_FAILED(rv)) return rv;				if (hasNegation)					break;			}			// if so, we've gotta keep looking			if (hasNegation)			{				NS_RELEASE(mResult);				continue;			}		}	if (mCoalesceDuplicateArcs == PR_TRUE)	{		// Now see if we've returned it once already.		// XXX N.B. performance here...may want to hash if things get large?		PRBool alreadyReturned = PR_FALSE;		for (i = mAlreadyReturned.Count() - 1; i >= 0; --i)		{               			if (mAlreadyReturned[i] == mResult)			{				alreadyReturned = PR_TRUE;				break;			}		}		if (alreadyReturned == PR_TRUE)		{			NS_RELEASE(mResult);			continue;		}	}            // If we get here, then we've really found one. It'll            // remain cached in mResult until GetNext() sucks it out.            *aResult = PR_TRUE;	// Remember that we returned it, so we don't return duplicates.	// XXX I wonder if we should make unique-checking be	// optional. This could get to be pretty expensive (this	// implementation turns iteration into O(n^2)).	if (mCoalesceDuplicateArcs == PR_TRUE)	{		mAlreadyReturned.AppendElement(mResult);		NS_ADDREF(mResult);	}            return NS_OK;        } while (1);    }    // if we get here, there aren't any elements left.    *aResult = PR_FALSE;    return NS_OK;}