@Override
	public boolean handleMessage(IPMessage msg)
	{
		GossipMessage gossip_msg = (GossipMessage) msg;

		System.out.println("------------------Receive GossipMessage-" + gossip_msg.toString() + " -------------");

		/*
		 *	Replica i discards gossip message m from replica j if m.ts <= j's timestamp in ts_table
		 */
		int gossip_sender_replica = gossip_msg.getRid();

		MultipartTimestamp gossip_msg_ts = gossip_msg.getReplicaTs();
		MultipartTimestamp gossip_sender_latest_rep_ts = new MultipartTimestamp(
				Replica.INSTANCE.getTsTable().getReplicaTs(gossip_msg.getRid()));

		if(gossip_msg_ts.compareTo(gossip_sender_latest_rep_ts) <= 0)
			return true;

		/*
		 * (1) Add the new information in the gossip message to the replica's log
		 */
		Logs replica_logs = Replica.INSTANCE.getLogs();
		Logs gossip_logs = gossip_msg.getLogs();
		MultipartTimestamp rep_ts = Replica.INSTANCE.getRepTs();
		replica_logs.merge(gossip_logs, rep_ts);

		/*
		 * (2) Merge the replica's timestamp with the timestamp in the message
		 */
		rep_ts.merge(gossip_msg_ts);

		/*
		 * (3) Insert all the update records that are ready to be added to the value into the set comp
		*/
		HashMap<MessageGid, LogRecord> comp = this.constructComputationSet();

		/*
		 * (4) Compute the new value of the object
		 */
		this.compute(comp);

		/**
		 * (5) Update ts_table
		 */
		Replica.INSTANCE.getTsTable().setReplicaTs(gossip_sender_replica, gossip_msg_ts);

		/**
		 * (6) Discards update records from the log if they have been received by all replicas
		 */
		LogRecord log_record = null;

		for (Iterator<Map.Entry<MessageGid, LogRecord>> iter = replica_logs.get_log_map().entrySet().iterator();
				iter.hasNext(); )
		{
			log_record = iter.next().getValue();
			if (Replica.INSTANCE.getTsTable().isKnown(log_record))
				iter.remove();
		}

		/**
		 * (7) Added: processing the blocked {@link QueryMessage}s
		 * @see {@link QueryMessageHandler}
		 */
		QueryMessage query_msg = null;
		for (Iterator<Map.Entry<MessageGid, QueryMessage>> iter = Replica.INSTANCE.getQueryMessageWaitingQueue().entrySet().iterator();
				iter.hasNext(); )
		{
			query_msg = iter.next().getValue();
			if (new QueryMessageHandler().handleMessage(query_msg))
			{
				// TODO: delete dependency on it
				Replica.INSTANCE.removeDepsOn(query_msg.getMsgGid());
				
				// this {@link QueryMessage} has been executed.
				iter.remove();
			}
		}
		
		return true;
	}