// This is a good implementation. Dots all the i's, so to speak.
// client-side.
// The basket ONLY stores closing numbers, so this means "harvest 'em all."
//
void OTBasket::HarvestClosingNumbers(OTPseudonym & theNym, const OTIdentifier & theServerID, const bool bSave/*=true*/)
{
    const OTString strServerID(theServerID);
    bool bNeedToSave = false;

    // *************************************************************************
    // The SUB-CURRENCIES first...
    //
    const unsigned int nCount = static_cast<unsigned int>(this->Count());

    for (unsigned int i = 0; i < nCount; i++)
    {
        BasketItem * pRequestItem = this->At(i);
        OT_ASSERT(NULL != pRequestItem);
        // --------------------------------
        const long lClosingTransNo = pRequestItem->lClosingTransactionNo;
        // --------------------------------

        // This function will only "add it back" if it was really there in the first place.
        // (Verifies it is on issued list first, before adding to available list.)
        //
        const bool bClawedBack = theNym.ClawbackTransactionNumber(theServerID, lClosingTransNo, false); // bSave=false

        if (bClawedBack)
            bNeedToSave = true;
//		else
//			OTLog::vError("OTBasket::HarvestClosingNumbers: Number (%ld) failed as issued. (Thus didn't bother 'adding it back'.)\n",
//						  lClosingTransNo);
    } // for
    // *************************************************************************
    // Then the BASKET currency itself...
    //
    const long lClosingTransNo = this->GetClosingNum();
    // --------------------------------

    // This function will only "add it back" if it was really there in the first place.
    // (Verifies it is on issued list first, before adding to available list.)
    //
    const bool bClawedBack = theNym.ClawbackTransactionNumber(theServerID, lClosingTransNo, false); // bSave=false

    if (bClawedBack)
        bNeedToSave = true;

    // *************************************************************************
    // Until I put this down here, there were subtle cases where the Nym wouldn't get saved.
    // Therefore another vote for my "dirty instances" theory.
    //
    if (bSave && bNeedToSave)
    {
        OTPseudonym * pSignerNym = &theNym;// probably unnecessary.
        theNym.SaveSignedNymfile(*pSignerNym);
    }
}
// You usually wouldn't want to use this, since if the transaction failed, the opening number
// is already burned and gone. But there might be cases where it's not, and you want to retrieve it.
// So I added this function.
//
void OTAgreement::HarvestOpeningNumber(OTPseudonym & theNym)
{
    // since we overrode the parent, we give it a chance to harvest also.
    // IF theNym is the original sender, the opening number will be harvested
    // inside this call.
    //
    OTCronItem::HarvestOpeningNumber(theNym);

    // The Nym is the original recipient. (If Compares true).
    // IN CASES where GetTransactionNum() isn't already burned, we can harvest it here.
    //
    if (theNym.CompareID(GetRecipientUserID()))
    {
        // This function will only "add it back" if it was really there in the first place.
        // (Verifies it is on issued list first, before adding to available list.)
        //
        theNym.ClawbackTransactionNumber(GetServerID(), GetRecipientOpeningNum(), true); //bSave=true
    }
    
    // NOTE: if the message failed (transaction never actually ran) then the sender AND recipient
    // can both reclaim their opening numbers. But if the message SUCCEEDED and the transaction FAILED,
    // then only the recipient can claim his opening number -- the sender's is already burned. So then,
    // what if you mistakenly call this function and pass the sender, when that number is already burned?
    // There's nothing this function can do, because we have no way of telling, from inside here,
    // whether the message succeeded or not, and whether the transaction succeeded or not. Therefore,
    // ==> we MUST rely on the CALLER to know this, and to avoid calling this function in the first place, 
    // if he's sitting on a sender with a failed transaction.
}
// Used for adding transaction numbers back to a Nym, after deciding not to use this agreement
// or failing in trying to use it. Client side.
//
void OTAgreement::HarvestClosingNumbers(OTPseudonym & theNym)
{
    // Since we overrode the parent, we give it a chance to harvest also.
    // If theNym is the sender, then his closing numbers will be harvested
    // inside here. But what if the transaction was a success? The numbers
    // will still be harvested, since they are still on the sender's issued
    // list, but they should not have been harvested, regardless, since the
    // transaction was a success and the server therefore has them marked as
    // "used." So clearly you cannot just blindly call this function unless
    // you know beforehand whether the message and transaction were a success.
    //
    OTCronItem::HarvestClosingNumbers(theNym);

    // The Nym is the original recipient. (If Compares true).
	// FYI, if Nym is the original sender, then the above call will handle him.
	//
    // GetTransactionNum() is burned, but we can harvest the closing
    // numbers from the "Closing" list, which is only for the sender's numbers.
    // Subclasses will have to override this function for recipients, etc.
    //
    if (theNym.CompareID(GetRecipientUserID()))
    {
        for (int i = 0; i < GetRecipientCountClosingNumbers(); i++)
        {
            // This function will only "add it back" if it was really there in the first place.
            // (Verifies it is on issued list first, before adding to available list.)
            //
            const bool bClawedBack = 
                theNym.ClawbackTransactionNumber(GetServerID(), 
                                                 GetRecipientClosingTransactionNoAt(i), 
                                                 (i == (GetRecipientCountClosingNumbers()-1) ? true : false)); // bSave=true only on the last iteration.
			if (!bClawedBack)
            {
//				OTLog::vError("OTAgreement::HarvestClosingNumbers: Number (%ld) failed as issued. (Thus didn't bother 'adding it back'.)\n",
//							  GetRecipientClosingTransactionNoAt(i));
            }
        }
    }
}