public void send(Message message, Member member){
		Timer timer;
		TimerTask timerTask;
		InetAddress address;
		byte[] data;
		int memberId;
		int sendSequence;
		DatagramPacket sendPacket;
		memberId = member.getId();
		synchronized(_mutex){
            // Check if the message or its sender are new
			if(_nextSendSequence.containsKey(memberId) == false){
				_nextSendSequence.put(memberId, 0);
			}
			if(_timerTable.containsKey(memberId) == false){
				_timerTable.put(memberId, new Hashtable<Integer, Timer>());
			}
			
			if(_cachedMessages.containsKey(memberId) == false){
				_cachedMessages.put(memberId, new Hashtable<Integer, Message>());
			}
			
			if(_cachedRetransmissionTask.containsKey(memberId) == false){
				_cachedRetransmissionTask.put(memberId, new Hashtable<Integer, TimerTask>());
			}
			
			sendSequence = _nextSendSequence.get(memberId);
			try {
				
				message.setSequence(new Integer(sendSequence));

                data =  message.getBytes();
				address = InetAddress.getByName(member._ip);
				sendPacket = new DatagramPacket(data, data.length, address,  member._port);
				timer = new Timer();
				timerTask = new RetransmissionTask(new Integer(sendSequence), member, this);
				_cachedMessages.get(memberId).put(new Integer(sendSequence), message);
				_timerTable.get(memberId).put(new Integer(sendSequence), timer);
				_cachedRetransmissionTask.get(memberId).put(new Integer(sendSequence), timerTask);

                // Only send with some probability
				if (_rand.nextDouble() >= _profile.getDropRate()) {
                    // Delay based on input argument
                    int meanDelay = _profile.getDelay();
                    if (meanDelay != 0) {
                        Timer delayTimer = new Timer();
                        TimerTask delaySender = new DelaySender(sendPacket, _socket);
                        delayTimer.schedule(delaySender, getRandomDelay(meanDelay));
                    }else{
                    	_socket.send(sendPacket);
                    }
                    if(_profile.isDetailMode){
                    	System.out.println(message.getContent().getContent() + " sent");
                    }
				}else{
					if(_profile.isDetailMode){
						System.out.println(message.getContent().getContent() + " dropped");
					}
				}
                // Set up retransmission in case unicast doesn't reach
				timer.schedule(timerTask, EXPIRE_TIME);
				_nextSendSequence.put(memberId, sendSequence + 1);
			}
            catch (IOException e) {
				e.printStackTrace();
			}
        }
	}