// Path: beetle-core/src/main/java/com/xing/beetle/util/ExceptionSupport.java
// @FunctionalInterface
// public interface BiConsumer<T, U> extends java.util.function.BiConsumer<T, U> {
//   @Override
//   default void accept(T t, U u) {
//     try {
//       acceptChecked(t, u);
//     } catch (Throwable e) {
//       sneakyThrow(e);
//     }
//   }
// 
//   void acceptChecked(T t, U u) throws Throwable;
// }


import com.rabbitmq.client.*;
import static com.xing.beetle.util.ExceptionSupport.BiConsumer;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Predicate;
package com.xing.beetle.amqp;




/**
 * MsgDeliveryTagMapping maps external delivery tags from (possibly) multiple AMQP channels to a
 * contiguous list of synthetic delivery tags that are presented to the wrapped plain AMQP Consumer.
 *
 * <p>Ensures that message results (N)ACK/REJECT invoked by the consumer arrive at the correct
 * channel with the matching external delivery tag.
 */
public class MsgDeliveryTagMapping {

  private interface MsgResponse {
    Void apply(MsgResult msgResult, boolean multiple, boolean requeue, Predicate<Channel> when)
        throws IOException;
  }

  /**
   * MsgResult applies the result of the message processing to the channels by either (N)ACKing or
   * REJECTing the message.
   */
  private enum MsgResult {
    /**
     * ACK the message.
     *
     * @param channel channel
     * @param deliveryTag deliveryTag of message in channel
     * @param multiple apply to all messages up to the given delivery tag
     * @param requeue not applicable for ACKs
     * @throws IOException
     */
    ACK {
      @Override
      Void invoke(Channel channel, long deliveryTag, boolean multiple, boolean requeue)
          throws IOException {
        channel.basicAck(deliveryTag, multiple);
// Path: beetle-core/src/main/java/com/xing/beetle/util/ExceptionSupport.java
// @FunctionalInterface
// public interface BiConsumer<T, U> extends java.util.function.BiConsumer<T, U> {
//   @Override
//   default void accept(T t, U u) {
//     try {
//       acceptChecked(t, u);
//     } catch (Throwable e) {
//       sneakyThrow(e);
//     }
//   }
// 
//   void acceptChecked(T t, U u) throws Throwable;
// }


// Path: beetle-core/src/main/java/com/xing/beetle/amqp/MsgDeliveryTagMapping.java
import com.rabbitmq.client.*;
import static com.xing.beetle.util.ExceptionSupport.BiConsumer;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Predicate;

package com.xing.beetle.amqp;




/**
 * MsgDeliveryTagMapping maps external delivery tags from (possibly) multiple AMQP channels to a
 * contiguous list of synthetic delivery tags that are presented to the wrapped plain AMQP Consumer.
 *
 * <p>Ensures that message results (N)ACK/REJECT invoked by the consumer arrive at the correct
 * channel with the matching external delivery tag.
 */
public class MsgDeliveryTagMapping {

  private interface MsgResponse {
    Void apply(MsgResult msgResult, boolean multiple, boolean requeue, Predicate<Channel> when)
        throws IOException;
  }

  /**
   * MsgResult applies the result of the message processing to the channels by either (N)ACKing or
   * REJECTing the message.
   */
  private enum MsgResult {
    /**
     * ACK the message.
     *
     * @param channel channel
     * @param deliveryTag deliveryTag of message in channel
     * @param multiple apply to all messages up to the given delivery tag
     * @param requeue not applicable for ACKs
     * @throws IOException
     */
    ACK {
      @Override
      Void invoke(Channel channel, long deliveryTag, boolean multiple, boolean requeue)
          throws IOException {
        channel.basicAck(deliveryTag, multiple);
        return null;