void TimeWarpMatternGVTManager::receiveMatternGVTToken(
    std::unique_ptr<TimeWarpKernelMessage> kmsg) {

    auto msg = unique_cast<TimeWarpKernelMessage, MatternGVTToken>(std::move(kmsg));
    unsigned int process_id = comm_manager_->getID();

    if (process_id == 0) {
        // Initiator received the message
        if ((white_msg_counter_ + msg->count == 0) && (token_iteration_ > 1)) {
            // At this point all white messages are accounted for so we can
            // calculate the GVT now
            gVT_token_pending_ = false;
            sendGVTUpdate(std::min(msg->m_clock, msg->m_send));

            // Reset
            msg_count_ = 0;

        } else {
            // Accumulations
            min_red_msg_timestamp_ = std::min(msg->m_send, min_red_msg_timestamp_);
            global_min_ = infinityVT();
            msg_count_ = 0;

            // Set flags
            need_local_gvt_ = true;
            gVT_token_pending_ = true;
        }

    } else {
        // A node other than the initiator is now receiving a control message
        if (color_ == MatternColor::WHITE) {
            min_red_msg_timestamp_ = infinityVT();
            color_ = MatternColor::RED;
        }

        // Accumulations
        min_red_msg_timestamp_ = std::min(msg->m_send, min_red_msg_timestamp_);
        global_min_ = std::min(global_min_, msg->m_clock);
        msg_count_ = msg->count;

        // Set flags
        need_local_gvt_ = true;
        gVT_token_pending_ = true;
    }
}
void ThreadedMatternGVTManager::receiveKernelMessage(KernelMessage *msg) {
	ASSERT(msg != NULL);
	if (dynamic_cast<MatternGVTMessage *>(msg) != 0) {
		const MatternGVTMessage *gVTMessage =
				dynamic_cast<MatternGVTMessage *>(msg);
		const int count = gVTMessage->getNumMessagesInTransit();

		if (mySimulationManager->getSimulationManagerID() == 0) {
			// Initiator has received the control message.
			// Check to see if the count is zero and this is at least the second
			// round of the token. Continue until the count is 0 and all messages
			// in transit are accounted for.
			if (objectRecord->getTokenIterationNumber() > 1
					&& (objectRecord->getNumberOfWhiteMessages() + count == 0)) {

				// Need to remember the old gvt to compare it to the new.
				const VTime &oldGVT = getGVT();

				// Determine GVT.
				setGVT(
						MIN_FUNC(gVTMessage->getLastScheduledEventTime(),
								gVTMessage->getMinimumTimeStamp()));
				ASSERT(getGVT() >= oldGVT);

				// Send out the GVT update to the other simulation managers and reset to white.
				objectRecord->setTokenIterationNumber(0);
				objectRecord->setNumberOfWhiteMessages(0);
				objectRecord->setColor(WHITE);
				sendGVTUpdate();

				// End of this gvt calculation cycle.
				gVTTokenPending = false;

				// Only output the value and fossil collect when it actually changes.
				if (getGVT() > oldGVT) {
					// Fossil collect now with the new GVT.
					cout << "GVT = " << getGVT() << endl;
                    //mySimulationManager->resetGVTTokenPending();
					mySimulationManager->fossilCollect(getGVT());
				}
			} else {
				// Not yet ready to calculate gvt, send the token around again.
               // cout <<"NUmber of Transit messages "<<count <<endl;
               // cout <<"NUmber of White messages "<<objectRecord->getNumberOfWhiteMessages()<<endl;
                objectRecord->setNumberOfWhiteMessages(
                        objectRecord->getNumberOfWhiteMessages() + count);
				mySimulationManager->setGVTTokenPending();
				mySimulationManager->initiateLocalGVT();
				GVTMessageLastScheduledEventTime =
						gVTMessage->getLastScheduledEventTime().clone();
				GVTMessageMinimumTimeStamp =
						gVTMessage->getMinimumTimeStamp().clone();
                objectRecord->setNumberOfWhiteMessages(0);

			}
		} else {
			// The gvt token has been received by another simulation manager.
			// [a] Set color of this sim mgr to RED; set tMin = positive infinity.
			// [b] Pass on the token to processor(i mod n) + 1.
			if (objectRecord->getColor() == WHITE) {
				objectRecord->resetMinTimeStamp(
						mySimulationManager->getPositiveInfinity());
				objectRecord->setColor(RED);
			}

			// Add the the local white message count to the simulation's white message total.
			objectRecord->setNumberOfWhiteMessages(
					objectRecord->getNumberOfWhiteMessages() + count);
			mySimulationManager->setGVTTokenPending();
			mySimulationManager->initiateLocalGVT();
			GVTMessageLastScheduledEventTime =
					gVTMessage->getLastScheduledEventTime().clone();
			GVTMessageMinimumTimeStamp =
					gVTMessage->getMinimumTimeStamp().clone();
		}
	} else if (dynamic_cast<GVTUpdateMessage *>(msg) != 0) {
		const GVTUpdateMessage *gVTMessage =
				dynamic_cast<GVTUpdateMessage *>(msg);

		const VTime &oldGVT = getGVT();
		setGVT(gVTMessage->getNewGVT());
        //mySimulationManager->resetGVTTokenPending();
		ASSERT(getGVT() >= oldGVT);

		// Only fossil collect if the value has increased.
		if (getGVT() > oldGVT) {
			// Fossil collect now with the new GVT.
			mySimulationManager->fossilCollect(getGVT());
		}

		// VERY IMPORTANT NOTE!!
		// The white message count is not reset here because by the time this
		// simulation manager gets the update token, it may have already received some
		// white messages from another simulation manager that already switched back
		// to white. These need to be taken into account for the next GVT calculation.
		objectRecord->setTokenIterationNumber(0);
		objectRecord->setColor(WHITE);
	} else {
		cerr << "MatternGVTManager::receiveKernelMessage() received"
				<< " unknown (" << msg->getDataType() << ") message type"
				<< endl;
		cerr << "Aborting simulation ..." << endl;
		abort();
	}
	// We are done with this kernel message.
	delete msg;
}