void SipTransactionList::removeOldTransactions(long oldTransaction,
                                               long oldInviteTransaction)
{
    SipTransaction** transactionsToBeDeleted = NULL;
    int deleteCount = 0;
    int busyCount = 0;

#   ifdef TIME_LOG
    OsTimeLog gcTimes;
    gcTimes.addEvent("start");
#   endif

    lock();

    int numTransactions = mTransactions.entries();
    if(numTransactions > 0)
    {
        UtlHashBagIterator iterator(mTransactions);
        SipTransaction* transactionFound = NULL;
        long transTime;


        // Pull all of the transactions to be deleted out of the list
        while((transactionFound = (SipTransaction*) iterator()))
        {
            if(transactionFound->isBusy()) busyCount++;

            transTime = transactionFound->getTimeStamp();
            // Invites need to be kept longer than other transactions
            if(((!transactionFound->isMethod(SIP_INVITE_METHOD) &&
                transTime < oldTransaction) ||
                transTime < oldInviteTransaction) &&
                ! transactionFound->isBusy())
            {
                // Remove it from the list
                mTransactions.removeReference(transactionFound);

                OsSysLog::add(FAC_SIP, PRI_DEBUG, "removing transaction %p\n",transactionFound);

                // Make sure we have a pointer array to hold it
                if(transactionsToBeDeleted == NULL)
                {
                     transactionsToBeDeleted =
                        new SipTransaction*[numTransactions];
                }

                // Put it in the pointer array
                transactionsToBeDeleted[deleteCount] = transactionFound;
                deleteCount++;

                // Make sure the events waiting for the transaction
                // to be available are signaled before we delete
                // any of the transactions or we end up with
                // incomplete transaction trees (i.e. deleted branches)
                transactionFound->signalAllAvailable();
                transactionFound = NULL;
            }
        }
    }

    unlock();

    // We do not need the lock if the transactions have been
    // removed from the list
    if ( deleteCount || busyCount ) // do not log 'doing nothing when nothing to do', even at debug level
    {
        OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipTransactionList::removeOldTransactions deleting %d of %d transactions (%d busy)\n",
                      deleteCount , numTransactions, busyCount);
    }

    // Delete the transactions in the array
    if (transactionsToBeDeleted)
    {
#       ifdef TIME_LOG
        gcTimes.addEvent("start delete");
#       endif

        for(int txIndex = 0; txIndex < deleteCount; txIndex++)
        {
            delete transactionsToBeDeleted[txIndex];
#           ifdef TIME_LOG
            gcTimes.addEvent("transaction deleted");
#           endif
       }

#      ifdef TIME_LOG
       gcTimes.addEvent("finish delete");
#      endif
/*
        while((transactionFound = (SipTransaction*) iterator()))
        {
            transactionFound->stopTimers();
        }
*/
       delete[] transactionsToBeDeleted;
       transactionsToBeDeleted = NULL;
    }

#   ifdef TIME_LOG
    UtlString timeString;
    gcTimes.getLogString(timeString);
    OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipTransactionList::removeOldTransactions "
                  "%s", timeString.data()
                  );
#   endif
}
void SipTransactionList::removeOldTransactions(long oldTransaction,
        long oldInviteTransaction)
{
    SipTransaction** transactionsToBeDeleted = NULL;
    int deleteCount = 0;
    int busyCount = 0;

#   ifdef TIME_LOG
    OsTimeLog gcTimes;
    gcTimes.addEvent("start");
#   endif

    lock();
#   ifdef TIME_LOG
    gcTimes.addEvent("locked");
#   endif

    int numTransactions = mTransactions.entries();
    if(numTransactions > 0)
    {
        UtlHashBagIterator iterator(mTransactions);
        SipTransaction* transactionFound = NULL;
        long transTime;

        // Pull all of the transactions to be deleted out of the list
        while ((transactionFound = (SipTransaction*) iterator()))
        {
            if(transactionFound->isBusy())
            {
                busyCount++;
            }
            else
            {
                transTime = transactionFound->getTimeStamp();

                // Invites need to be kept longer than other transactions
                if ( transTime < (  transactionFound->isMethod(SIP_INVITE_METHOD)
                                    ? oldInviteTransaction
                                    : oldTransaction
                                 )
                   )
                {
#ifdef TRANSACTION_MATCH_DEBUG
                    Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                                               "SipTransactionList::removeOldTransactions "
                                               " removing %p",  transactionFound );
#endif

                    // Remove it from the list
                    mTransactions.removeReference(transactionFound);

                    // Make sure we have a pointer array to hold it
                    if(transactionsToBeDeleted == NULL)
                    {
                        transactionsToBeDeleted = new SipTransaction*[numTransactions];
                    }

                    // Put it in the pointer array
                    transactionsToBeDeleted[deleteCount] = transactionFound;
                    deleteCount++;

                    // Make sure the events waiting for the transaction
                    // to be available are signaled before we delete
                    // any of the transactions or we end up with
                    // incomplete transaction trees (i.e. deleted branches)
                    // :TODO: move to the actual deletion loop so we're not holding the lock? -SDL
                    transactionFound->signalAllAvailable();
                }
            }
        }
    }

#   ifdef TIME_LOG
    gcTimes.addEvent("scan done");
#   endif

    // We do not need the lock now that the transactions have been
    // removed from the list
    unlock();

    if ( deleteCount || busyCount ) // do not log 'doing nothing when nothing to do', even at debug
    {
        Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                                   "SipTransactionList::removeOldTransactions"
                                   " deleting %d of %d transactions (%d busy)",
                                   deleteCount , numTransactions, busyCount
                                  );
    }

    // Delete the transactions in the array
    if (transactionsToBeDeleted)
    {
#      ifdef TIME_LOG
        gcTimes.addEvent("start delete");
#      endif

        for(int txIndex = 0; txIndex < deleteCount; txIndex++)
        {
            delete transactionsToBeDeleted[txIndex];
        }

#      ifdef TIME_LOG
        gcTimes.addEvent("finish delete");
#      endif

        delete[] transactionsToBeDeleted;
    }

#   ifdef TIME_LOG
    UtlString timeString;
    gcTimes.getLogString(timeString);
    Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipTransactionList::removeOldTransactions "
                               "%s", timeString.data()
                              );
#   endif
}