// Path: sailfish-kernel/src/main/java/sailfish/remoting/exceptions/ExceptionCode.java
// public enum ExceptionCode {
//     BAD_PACKAGE,
//     RESPONSE_TIMEOUT,
//     WRITE_TIMEOUT,
//     EXCHANGER_NOT_AVAILABLE,
//     UNFINISHED_REQUEST,
//     CHANNEL_WRITE_FAIL,
//     DEFAULT,
//     ;
// }
// 
// Path: sailfish-kernel/src/main/java/sailfish/remoting/exceptions/SailfishException.java
// public class SailfishException extends Exception {
// 
//     /**  */
//     private static final long serialVersionUID = 1L;
//     private ExceptionCode     errorCode;
// 
//     public SailfishException(String message) {
//         super(message);
//     }
//     
//     public SailfishException(Throwable cause){
//         super(cause);
//     }
// 
//     public SailfishException(ExceptionCode errorCode, String message) {
//         super(message(errorCode, message));
//         this.errorCode = errorCode;
//     }
// 
//     public SailfishException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public SailfishException(ExceptionCode errorCode, String message, Throwable cause) {
//         super(message(errorCode, message), cause);
//         this.errorCode = errorCode;
//     }
// 
//     private static String message(ExceptionCode errorCode, String message) {
//         if(null == errorCode){
//             errorCode = ExceptionCode.DEFAULT;
//         }
//         String prefix = "[errorCode:" + errorCode.toString() + "]";
//         return StrUtils.isBlank(message) ? prefix : prefix + ", "+ message;
//     }
// 
//     public ExceptionCode code() {
//         return errorCode;
//     }
// 
//     public RemoteSailfishException toRemoteException() {
//         return new RemoteSailfishException(errorCode, getMessage(), getCause());
//     }
//     
//     /**
//      * exception for remote peer
//      */
//     class RemoteSailfishException extends SailfishException{
//         private static final long serialVersionUID = 1L;
//         public RemoteSailfishException(ExceptionCode errorCode, String message, Throwable cause) {
//             super(errorCode, message, cause);
//         }
//     }
// }


import java.util.concurrent.atomic.AtomicInteger;
import sailfish.remoting.exceptions.ExceptionCode;
import sailfish.remoting.exceptions.SailfishException;
				return channels[0];
			}
			
			int arrayIndex = 0;
			int currentIndex = idx.getAndIncrement();
			for (int i = 0; i < channels.length; i++) {
				ExchangeChannel currentChannel = channels[arrayIndex = ((currentIndex++) & channels.length - 1)];
				if (null != currentChannel && currentChannel.isAvailable()) {
					if (null != deadChannels[arrayIndex]) {
						deadChannels[arrayIndex] = null;
					}
					return currentChannel;
				}
				deadChannels[arrayIndex] = currentChannel;
			}
			throw new SailfishException(ExceptionCode.EXCHANGER_NOT_AVAILABLE, "exchanger is not available!");
		}
	}

	private static final class GenericExchangeChannelChooser implements ExchangeChannelChooser {
		private final AtomicInteger idx = new AtomicInteger();
		private final ExchangeChannel[] channels;
		private final ExchangeChannel[] deadChannels;

		GenericExchangeChannelChooser(ExchangeChannel[] channels, ExchangeChannel[] deadChannels) {
			this.channels = channels;
			this.deadChannels = deadChannels;
		}

		@Override
// Path: sailfish-kernel/src/main/java/sailfish/remoting/exceptions/ExceptionCode.java
// public enum ExceptionCode {
//     BAD_PACKAGE,
//     RESPONSE_TIMEOUT,
//     WRITE_TIMEOUT,
//     EXCHANGER_NOT_AVAILABLE,
//     UNFINISHED_REQUEST,
//     CHANNEL_WRITE_FAIL,
//     DEFAULT,
//     ;
// }
// 
// Path: sailfish-kernel/src/main/java/sailfish/remoting/exceptions/SailfishException.java
// public class SailfishException extends Exception {
// 
//     /**  */
//     private static final long serialVersionUID = 1L;
//     private ExceptionCode     errorCode;
// 
//     public SailfishException(String message) {
//         super(message);
//     }
//     
//     public SailfishException(Throwable cause){
//         super(cause);
//     }
// 
//     public SailfishException(ExceptionCode errorCode, String message) {
//         super(message(errorCode, message));
//         this.errorCode = errorCode;
//     }
// 
//     public SailfishException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public SailfishException(ExceptionCode errorCode, String message, Throwable cause) {
//         super(message(errorCode, message), cause);
//         this.errorCode = errorCode;
//     }
// 
//     private static String message(ExceptionCode errorCode, String message) {
//         if(null == errorCode){
//             errorCode = ExceptionCode.DEFAULT;
//         }
//         String prefix = "[errorCode:" + errorCode.toString() + "]";
//         return StrUtils.isBlank(message) ? prefix : prefix + ", "+ message;
//     }
// 
//     public ExceptionCode code() {
//         return errorCode;
//     }
// 
//     public RemoteSailfishException toRemoteException() {
//         return new RemoteSailfishException(errorCode, getMessage(), getCause());
//     }
//     
//     /**
//      * exception for remote peer
//      */
//     class RemoteSailfishException extends SailfishException{
//         private static final long serialVersionUID = 1L;
//         public RemoteSailfishException(ExceptionCode errorCode, String message, Throwable cause) {
//             super(errorCode, message, cause);
//         }
//     }
// }


// Path: sailfish-kernel/src/main/java/sailfish/remoting/channel/DefaultExchangeChannelChooserFactory.java
import java.util.concurrent.atomic.AtomicInteger;
import sailfish.remoting.exceptions.ExceptionCode;
import sailfish.remoting.exceptions.SailfishException;

				return channels[0];
			}
			
			int arrayIndex = 0;
			int currentIndex = idx.getAndIncrement();
			for (int i = 0; i < channels.length; i++) {
				ExchangeChannel currentChannel = channels[arrayIndex = ((currentIndex++) & channels.length - 1)];
				if (null != currentChannel && currentChannel.isAvailable()) {
					if (null != deadChannels[arrayIndex]) {
						deadChannels[arrayIndex] = null;
					}
					return currentChannel;
				}
				deadChannels[arrayIndex] = currentChannel;
			}
			throw new SailfishException(ExceptionCode.EXCHANGER_NOT_AVAILABLE, "exchanger is not available!");
		}
	}

	private static final class GenericExchangeChannelChooser implements ExchangeChannelChooser {
		private final AtomicInteger idx = new AtomicInteger();
		private final ExchangeChannel[] channels;
		private final ExchangeChannel[] deadChannels;

		GenericExchangeChannelChooser(ExchangeChannel[] channels, ExchangeChannel[] deadChannels) {
			this.channels = channels;
			this.deadChannels = deadChannels;
		}

		@Override
		public ExchangeChannel next() throws SailfishException {