private void reconstructRing() {
		FailureDetectorThread.handleMessage("Send Thread: reconstructRing");
		checkFailedServer(); // check the failed servers
		
		// remove failed server from the ring
		for (Integer id: this.failedServer) {
			if(pingPeers.containsKey(id)){
				FailureDetectorThread.handleMessage("server " + id + " is out of ring!");
				pingPeers.remove(id);
			}
		}
		
		// there is no failed server, reconstruct normal ring
		if(failedServer.size() == 0){
			pingPeers.clear();
			int i = 1;
			for (Map.Entry<Integer, String> peer : allPeers.entrySet()){
				if(i++ <= MaxServersToPing)
					pingPeers.put(peer.getKey(), peer.getValue());
			}
			return;
		}
		
		// there is at lease one failure, reconstruct the ring if there is any live server left
		for (Map.Entry<Integer, String> peer : allPeers.entrySet()) {
			int id = peer.getKey();
			if(failedServer.contains(id))
				continue;
			else{
				FailureDetectorThread.handleMessage("server " + id + " is in the ring!");
				pingPeers.put(id, peer.getValue());
				if(pingPeers.size() >= MaxServersToPing)
					return;
			}
		}
		
		// if 3 servers are failed, then exit the application
		if(pingPeers.isEmpty()){
			FailureDetectorThread.handleMessage("EXIT! at least 3 servers are failed!");
			System.exit(-1);
		}
	}