// Path: r4j/src/org/r4j/protocol/AppendRequest.java
// public class AppendRequest {
// 
// 	private long index;
// 	private long leaderTerm;
// 	private long logTerm;
// 	private long previousIndex;
// 	private long previousTerm;
// 	private long commitIndex;
// 	private Object payload;
// 	private transient MessageChannel clientChannel;
// 	
// 	public AppendRequest() {
// 		super();
// 	}
// 
// 	public AppendRequest(long logTerm, long index, long leaderTerm, long previousIndex,
// 			long previousTerm, long commitIndex, Object payload) {
// 		super();
// 		this.logTerm = logTerm;
// 		this.index = index;
// 		this.leaderTerm = leaderTerm;
// 		this.previousIndex = previousIndex;
// 		this.previousTerm = previousTerm;
// 		this.commitIndex = commitIndex;
// 		this.payload = payload;
// 	}
// 
// 	public AppendRequest(long logTerm, long index, long leaderTerm, long previousIndex,
// 			long previousTerm, long commitIndex, Object payload,
// 			MessageChannel clientChannel) {
// 		super();
// 		this.logTerm = logTerm;
// 		this.index = index;
// 		this.leaderTerm = leaderTerm;
// 		this.previousIndex = previousIndex;
// 		this.previousTerm = previousTerm;
// 		this.commitIndex = commitIndex;
// 		this.payload = payload;
// 		this.clientChannel = clientChannel;
// 	}
// 
// 	public long getIndex() {
// 		return index;
// 	}
// 
// 	public long getLeaderTerm() {
// 		return leaderTerm;
// 	}
// 
// 	public long getLogTerm() {
// 		return logTerm;
// 	}
// 
// 	public long getPreviousIndex() {
// 		return previousIndex;
// 	}
// 
// 	public long getPreviousTerm() {
// 		return previousTerm;
// 	}
// 
// 	public long getCommitIndex() {
// 		return commitIndex;
// 	}
// 
// 	public Object getPayload() {
// 		return payload;
// 	}
// 
// 	@JsonIgnore
// 	public MessageChannel getClientChannel() {
// 		return clientChannel;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "AppendRequest [index=" + index + ", term=" + leaderTerm
// 				+ ", previousIndex=" + previousIndex + ", previousTerm="
// 				+ previousTerm + ", commitIndex=" + commitIndex + ", "
// 				+ (payload != null ? "payload=" + payload : "") + "]";
// 	}
// 
// 	
// }
// 
// Path: r4j/src/org/r4j/protocol/AppendResponse.java
// public class AppendResponse {
// 	
// 	private long currentTerm;
// 	
// 	private boolean success;
// 
// 	private long entryIndex;
// 	
// 	private long entryTerm; 
// 	
// 	
// 	public AppendResponse(long currentTerm, boolean success, long entryIndex,
// 			long entryTerm) {
// 		super();
// 		this.currentTerm = currentTerm;
// 		this.success = success;
// 		this.entryIndex = entryIndex;
// 		this.entryTerm = entryTerm;
// 	}
// 
// 	public AppendResponse() {
// 		super();
// 	}
// 
// 	public long getCurrentTerm() {
// 		return currentTerm;
// 	}
// 
// 	public void setCurrentTerm(long term) {
// 		this.currentTerm = term;
// 	}
// 
// 	public boolean isSuccess() {
// 		return success;
// 	}
// 
// 	public void setSuccess(boolean success) {
// 		this.success = success;
// 	}
// 
// 	public long getEntryIndex() {
// 		return entryIndex;
// 	}
// 
// 	public long getEntryTerm() {
// 		return entryTerm;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "AppendResponse [currentTerm=" + currentTerm + ", success="
// 				+ success + ", entryIndex=" + entryIndex + ", entryTerm="
// 				+ entryTerm + "]";
// 	}
// 	
// 
// 	
// 
// }
// 
// Path: r4j/src/org/r4j/protocol/MessageChannel.java
// public interface MessageChannel {
// 
// 	public void send(Raft source, Object o);
// 	
// }


import java.util.ArrayList;
import java.util.List;
import org.r4j.protocol.AppendRequest;
import org.r4j.protocol.AppendResponse;
import org.r4j.protocol.MessageChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

	public Term getTerm() {
		return term;
	}

	public void handleClientRequest(MessageChannel channel, Object event) {
		if (role == Role.LEADER) {
			AppendRequest req = new AppendRequest(term.getCurrent(),
					log.getLastIndex()+1, 
					term.getCurrent(), 
					log.getLastIndex(), 
					log.getLastTerm(), 
					log.getLastCommitIndex(), 
					event, 
					channel);
			
			if (!log.append(req)) {
				//problem with statemachine
				throw new IllegalStateException("Log didn't accept new entry: " + req + ": " + log);
			}
			for (ClusterMember m : members) {
				if (m.getNextIndex() == req.getIndex()) {
					m.setNextIndex(m.getNextIndex()+1);//increment optimistically to minimize retries
					m.getChannel().send(this, req);
				}
			}
		} else {
			throw new NotLeaderException();//TODO add redirect leader
		}
	}


// Path: r4j/src/org/r4j/protocol/AppendRequest.java
// public class AppendRequest {
// 
// 	private long index;
// 	private long leaderTerm;
// 	private long logTerm;
// 	private long previousIndex;
// 	private long previousTerm;
// 	private long commitIndex;
// 	private Object payload;
// 	private transient MessageChannel clientChannel;
// 	
// 	public AppendRequest() {
// 		super();
// 	}
// 
// 	public AppendRequest(long logTerm, long index, long leaderTerm, long previousIndex,
// 			long previousTerm, long commitIndex, Object payload) {
// 		super();
// 		this.logTerm = logTerm;
// 		this.index = index;
// 		this.leaderTerm = leaderTerm;
// 		this.previousIndex = previousIndex;
// 		this.previousTerm = previousTerm;
// 		this.commitIndex = commitIndex;
// 		this.payload = payload;
// 	}
// 
// 	public AppendRequest(long logTerm, long index, long leaderTerm, long previousIndex,
// 			long previousTerm, long commitIndex, Object payload,
// 			MessageChannel clientChannel) {
// 		super();
// 		this.logTerm = logTerm;
// 		this.index = index;
// 		this.leaderTerm = leaderTerm;
// 		this.previousIndex = previousIndex;
// 		this.previousTerm = previousTerm;
// 		this.commitIndex = commitIndex;
// 		this.payload = payload;
// 		this.clientChannel = clientChannel;
// 	}
// 
// 	public long getIndex() {
// 		return index;
// 	}
// 
// 	public long getLeaderTerm() {
// 		return leaderTerm;
// 	}
// 
// 	public long getLogTerm() {
// 		return logTerm;
// 	}
// 
// 	public long getPreviousIndex() {
// 		return previousIndex;
// 	}
// 
// 	public long getPreviousTerm() {
// 		return previousTerm;
// 	}
// 
// 	public long getCommitIndex() {
// 		return commitIndex;
// 	}
// 
// 	public Object getPayload() {
// 		return payload;
// 	}
// 
// 	@JsonIgnore
// 	public MessageChannel getClientChannel() {
// 		return clientChannel;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "AppendRequest [index=" + index + ", term=" + leaderTerm
// 				+ ", previousIndex=" + previousIndex + ", previousTerm="
// 				+ previousTerm + ", commitIndex=" + commitIndex + ", "
// 				+ (payload != null ? "payload=" + payload : "") + "]";
// 	}
// 
// 	
// }
// 
// Path: r4j/src/org/r4j/protocol/AppendResponse.java
// public class AppendResponse {
// 	
// 	private long currentTerm;
// 	
// 	private boolean success;
// 
// 	private long entryIndex;
// 	
// 	private long entryTerm; 
// 	
// 	
// 	public AppendResponse(long currentTerm, boolean success, long entryIndex,
// 			long entryTerm) {
// 		super();
// 		this.currentTerm = currentTerm;
// 		this.success = success;
// 		this.entryIndex = entryIndex;
// 		this.entryTerm = entryTerm;
// 	}
// 
// 	public AppendResponse() {
// 		super();
// 	}
// 
// 	public long getCurrentTerm() {
// 		return currentTerm;
// 	}
// 
// 	public void setCurrentTerm(long term) {
// 		this.currentTerm = term;
// 	}
// 
// 	public boolean isSuccess() {
// 		return success;
// 	}
// 
// 	public void setSuccess(boolean success) {
// 		this.success = success;
// 	}
// 
// 	public long getEntryIndex() {
// 		return entryIndex;
// 	}
// 
// 	public long getEntryTerm() {
// 		return entryTerm;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "AppendResponse [currentTerm=" + currentTerm + ", success="
// 				+ success + ", entryIndex=" + entryIndex + ", entryTerm="
// 				+ entryTerm + "]";
// 	}
// 	
// 
// 	
// 
// }
// 
// Path: r4j/src/org/r4j/protocol/MessageChannel.java
// public interface MessageChannel {
// 
// 	public void send(Raft source, Object o);
// 	
// }


// Path: r4j/src/org/r4j/Raft.java
import java.util.ArrayList;
import java.util.List;
import org.r4j.protocol.AppendRequest;
import org.r4j.protocol.AppendResponse;
import org.r4j.protocol.MessageChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

	public Term getTerm() {
		return term;
	}

	public void handleClientRequest(MessageChannel channel, Object event) {
		if (role == Role.LEADER) {
			AppendRequest req = new AppendRequest(term.getCurrent(),
					log.getLastIndex()+1, 
					term.getCurrent(), 
					log.getLastIndex(), 
					log.getLastTerm(), 
					log.getLastCommitIndex(), 
					event, 
					channel);
			
			if (!log.append(req)) {
				//problem with statemachine
				throw new IllegalStateException("Log didn't accept new entry: " + req + ": " + log);
			}
			for (ClusterMember m : members) {
				if (m.getNextIndex() == req.getIndex()) {
					m.setNextIndex(m.getNextIndex()+1);//increment optimistically to minimize retries
					m.getChannel().send(this, req);
				}
			}
		} else {
			throw new NotLeaderException();//TODO add redirect leader
		}
	}


	public void handleResponse(ClusterMember member, AppendResponse event) {
