int TopologyWorldState::printWorldStateInfo (void) 
{
    // Prints information about local node, like subscriptions, alive neighbors, dead peers, etc
    _m.lock (141);
    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "=========================================================================\n");
    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     PRINT WORLD STATE INFO\n");
    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     Node id: %s\n", _pDisService->getNodeId());
    if ((_pLocalNodeInfo->getConsolidatedSubscriptions())->getCount() == 0) {
        checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     No subscribed groups\n");
    } else {
        _pLocalNodeInfo->printAllSubscribedGroups();
        // Print subscribing clients
        checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     SUBSCRIBING CLIENTS:\n");
        DArray<uint16> *pSubClients = _pLocalNodeInfo->getAllSubscribingClients();
        for (int j = 0; j <= pSubClients->getHighestIndex(); j++) {
            checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     SUB CLIENT N.%d:\n", (*pSubClients)[j]);
            SubscriptionList *pSubsForClient = _pLocalNodeInfo->getSubscriptionListForClient ((*pSubClients)[j]);
            _pLocalNodeInfo->releaseLocalNodeInfo();
            if (pSubsForClient && pSubsForClient->getCount() != 0) {
                for (StringHashtable<Subscription>::Iterator i = pSubsForClient->getIterator(); !i.end(); i.nextElement()) {
                    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     SUBSCRIPTION:\n");
                    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     groupname %s\n", i.getKey());
                    Subscription *pS = i.getValue();
                    pS->printInfo();                
                }
            }
        }
        // Print local consolidated subscriptions
        checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     LOCAL CONSOLIDATED SUBSCRIPTIONS:\n");
        SubscriptionList *pSubscriptions = _pLocalNodeInfo->getConsolidatedSubscriptions();
        for (StringHashtable<Subscription>::Iterator i = pSubscriptions->getIterator(); !i.end(); i.nextElement()) {
            checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     SUBSCRIPTION:\n");
            checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     groupname %s\n", i.getKey());
            Subscription *pS = i.getValue();
            pS->printInfo();   
        }
    }
    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "-------------------------------------------------------------------------\n");
    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     %d ACTIVE NEIGHBORS\n", _pLocalNodeInfo->getCount());
    for (StringHashtable<Thing>::Iterator iNeighbors = _pLocalNodeInfo->getAllElements(); !iNeighbors.end(); iNeighbors.nextElement()) {
        checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "-------------------------------------------------------------------------\n");
        RemoteNodeInfo *pRNI = (RemoteNodeInfo *) iNeighbors.getValue();
        pRNI->printRemoteNodeInfo();
    }
    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "-------------------------------------------------------------------------\n");
    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "     %d DEAD PEERS\n", _deadPeers.getCount());
    for (StringHashtable<RemoteNodeInfo>::Iterator iDead = _deadPeers.getAllElements(); !iDead.end(); iDead.nextElement()) {
        checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "-------------------------------------------------------------------------\n");
        RemoteNodeInfo *pRNI = (RemoteNodeInfo *) iDead.getValue();
        pRNI->printRemoteNodeInfo();
    }
    checkAndLogMsg ("TopologyWorldState::printWorldStateInfo", Logger::L_Info, "=========================================================================\n");
    _m.unlock (141);
    return 0;
}
int TopologyWorldState::updateSubscriptionState (StringHashtable<SubscriptionList> *pSubscriptionsTable, StringHashtable<uint32> *pNodesTable)
{
    // Updates the remote subscriptions with the pSubscriptionsTable and pNodesTable info
    _m.lock (131);
    for (StringHashtable<uint32>::Iterator iterator = pNodesTable->getAllElements(); !iterator.end(); iterator.nextElement()) {
        if (0 != stricmp (_pDisService->getNodeId(), iterator.getKey())) {
            RemoteNodeInfo * pRNI = (RemoteNodeInfo*) retrieveNodeInfo (iterator.getKey());
            if (pRNI) {
                uint32 *pui32RemoteSeqId = iterator.getValue();
                uint32 *pui32LocalSeqId = _subscriptionStateTable.get (iterator.getKey());
                if (!pui32LocalSeqId) {
                    pui32LocalSeqId = new uint32();
                }
                if ((*pui32RemoteSeqId) > (*pui32LocalSeqId)) {
                    pRNI->unsubscribeAll();
                    (*pui32LocalSeqId) = (*pui32RemoteSeqId);
                    _subscriptionStateTable.put (iterator.getKey(), pui32LocalSeqId);
                    continue;
                }
            }
        }
        pNodesTable->remove (iterator.getKey());
    }
    // Update _ui16SubscriptionStateCRC
    _crc.reset();
    for (StringHashtable<uint32>::Iterator iterator = _subscriptionStateTable.getAllElements(); !iterator.end(); iterator.nextElement()) {
        _crc.update ((const char *) iterator.getKey());
        _crc.update32 (iterator.getValue());
    }
    _ui16SubscriptionStateCRC = _crc.getChecksum();
    for (StringHashtable<SubscriptionList>::Iterator subIterator = pSubscriptionsTable->getAllElements(); !subIterator.end(); subIterator.nextElement()) {
        const char * nodeId = subIterator.getKey();
        if (pNodesTable->get (nodeId) != NULL) {
            SubscriptionList *pSubs = subIterator.getValue();
            RemoteNodeInfo * pRNI = (RemoteNodeInfo*) retrieveNodeInfo (nodeId);
            if (pRNI == NULL) {
                _m.unlock (131);
                return 0;
            }
            // Add subscriptions to pRNI
            for (StringHashtable<Subscription>::Iterator i = pSubs->getIterator(); !i.end(); i.nextElement()) {
                Subscription *pSub = i.getValue();
                Subscription *pSubAux = pSub->clone();
                pRNI->subscribe(i.getKey(), pSubAux);
            }
            SubscriptionList *pSubscriptions =  pRNI->getRemoteSubscriptionsCopy();
            sendSubscriptionStateMsg (pSubscriptions, nodeId, pNodesTable->get (nodeId));
        }
    }
    delete pSubscriptionsTable;
    pSubscriptionsTable = NULL;
    delete pNodesTable;
    pNodesTable = NULL;
    _m.unlock (131);
    return 0;
}