// Path: java/src/main/java/kanzi/Event.java
// public class Event
// {
//    public enum Type
//    {
//       COMPRESSION_START,
//       DECOMPRESSION_START,
//       BEFORE_TRANSFORM,
//       AFTER_TRANSFORM,
//       BEFORE_ENTROPY,
//       AFTER_ENTROPY,
//       COMPRESSION_END,
//       DECOMPRESSION_END,
//       AFTER_HEADER_DECODING
//    }
// 
//    private final int id;
//    private final long size;
//    private final int hash;
//    private final Type type;
//    private final boolean hashing;
//    private final long time;
//    private final String msg;
// 
// 
//    public Event(Type type, int id, long size)
//    {
//       this(type, id, size, 0, false);
//    }
// 
// 
//    public Event(Type type, int id, String msg)
//    {
//       this(type, id, msg, 0);
//    }
// 
// 
//    public Event(Type type, int id, String msg, long time)
//    {
//       this.id = id;
//       this.size = 0L;
//       this.hash = 0;
//       this.hashing = false;
//       this.type = type;
//       this.time = (time > 0) ? time : System.nanoTime();
//       this.msg = msg;
//    }
// 
// 
//    public Event(Type type, int id, long size, int hash, boolean hashing)
//    {
//       this(type, id, size, hash, hashing, 0);
//    }
// 
// 
//    public Event(Type type, int id, long size, int hash, boolean hashing, long time)
//    {
//       this.id = id;
//       this.size = size;
//       this.hash = hash;
//       this.hashing = hashing;
//       this.type = type;
//       this.time = (time > 0) ? time : System.nanoTime();
//       this.msg = null;
//    }
// 
// 
//    public int getId()
//    {
//       return this.id;
//    }
// 
// 
//    public long getSize()
//    {
//       return this.size;
//    }
// 
// 
//    public long getTime()
//    {
//       return this.time;
//    }
// 
// 
//    public Integer getHash()
//    {
//       return (this.hashing == false) ? null : this.hash;
//    }
// 
// 
//    public Type getType()
//    {
//       return this.type;
//    }
// 
// 
//    @Override
//    public String toString()
//    {
//       if (this.msg != null)
//          return this.msg;
// 
//       StringBuilder sb = new StringBuilder(200);
//       sb.append("{ \"type\":\"").append(this.getType()).append("\"");
// 
//       if (this.id >= 0)
//          sb.append(", \"id\":").append(this.getId());
// 
//       sb.append(", \"size\":").append(this.getSize());
//       sb.append(", \"time\":").append(this.getTime());
// 
//       if (this.hashing == true)
//          sb.append(", \"hash\":").append(Integer.toHexString(this.getHash()));
// 
//       sb.append(" }");
//       return sb.toString();
//    }
// }
// 
// Path: java/src/main/java/kanzi/Listener.java
// public interface Listener
// {
//    public void processEvent(Event evt);
// }


import kanzi.Event;
import java.io.PrintStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import kanzi.Listener;
   private final Map<Integer, BlockInfo> map;
   private final Event.Type[] thresholds;
   private final Type type;
   private final int level;


   public InfoPrinter(int infoLevel, Type type, PrintStream ps)
   {
      if (ps == null)
         throw new NullPointerException("Invalid null print stream parameter");

      this.ps = ps;
      this.level = infoLevel;
      this.type = type;
      this.map = new ConcurrentHashMap<Integer, BlockInfo>();
      this.thresholds = (type == Type.ENCODING) ?
              new Event.Type[]
              {
                 Event.Type.COMPRESSION_START,
                 Event.Type.BEFORE_TRANSFORM,
                 Event.Type.AFTER_TRANSFORM,
                 Event.Type.BEFORE_ENTROPY,
                 Event.Type.AFTER_ENTROPY,
                 Event.Type.COMPRESSION_END
              } :
              new Event.Type[]
              {
                 Event.Type.DECOMPRESSION_START,
                 Event.Type.BEFORE_ENTROPY,
                 Event.Type.AFTER_ENTROPY,
// Path: java/src/main/java/kanzi/Event.java
// public class Event
// {
//    public enum Type
//    {
//       COMPRESSION_START,
//       DECOMPRESSION_START,
//       BEFORE_TRANSFORM,
//       AFTER_TRANSFORM,
//       BEFORE_ENTROPY,
//       AFTER_ENTROPY,
//       COMPRESSION_END,
//       DECOMPRESSION_END,
//       AFTER_HEADER_DECODING
//    }
// 
//    private final int id;
//    private final long size;
//    private final int hash;
//    private final Type type;
//    private final boolean hashing;
//    private final long time;
//    private final String msg;
// 
// 
//    public Event(Type type, int id, long size)
//    {
//       this(type, id, size, 0, false);
//    }
// 
// 
//    public Event(Type type, int id, String msg)
//    {
//       this(type, id, msg, 0);
//    }
// 
// 
//    public Event(Type type, int id, String msg, long time)
//    {
//       this.id = id;
//       this.size = 0L;
//       this.hash = 0;
//       this.hashing = false;
//       this.type = type;
//       this.time = (time > 0) ? time : System.nanoTime();
//       this.msg = msg;
//    }
// 
// 
//    public Event(Type type, int id, long size, int hash, boolean hashing)
//    {
//       this(type, id, size, hash, hashing, 0);
//    }
// 
// 
//    public Event(Type type, int id, long size, int hash, boolean hashing, long time)
//    {
//       this.id = id;
//       this.size = size;
//       this.hash = hash;
//       this.hashing = hashing;
//       this.type = type;
//       this.time = (time > 0) ? time : System.nanoTime();
//       this.msg = null;
//    }
// 
// 
//    public int getId()
//    {
//       return this.id;
//    }
// 
// 
//    public long getSize()
//    {
//       return this.size;
//    }
// 
// 
//    public long getTime()
//    {
//       return this.time;
//    }
// 
// 
//    public Integer getHash()
//    {
//       return (this.hashing == false) ? null : this.hash;
//    }
// 
// 
//    public Type getType()
//    {
//       return this.type;
//    }
// 
// 
//    @Override
//    public String toString()
//    {
//       if (this.msg != null)
//          return this.msg;
// 
//       StringBuilder sb = new StringBuilder(200);
//       sb.append("{ \"type\":\"").append(this.getType()).append("\"");
// 
//       if (this.id >= 0)
//          sb.append(", \"id\":").append(this.getId());
// 
//       sb.append(", \"size\":").append(this.getSize());
//       sb.append(", \"time\":").append(this.getTime());
// 
//       if (this.hashing == true)
//          sb.append(", \"hash\":").append(Integer.toHexString(this.getHash()));
// 
//       sb.append(" }");
//       return sb.toString();
//    }
// }
// 
// Path: java/src/main/java/kanzi/Listener.java
// public interface Listener
// {
//    public void processEvent(Event evt);
// }


// Path: java/src/main/java/kanzi/app/InfoPrinter.java
import kanzi.Event;
import java.io.PrintStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import kanzi.Listener;

   private final Map<Integer, BlockInfo> map;
   private final Event.Type[] thresholds;
   private final Type type;
   private final int level;


   public InfoPrinter(int infoLevel, Type type, PrintStream ps)
   {
      if (ps == null)
         throw new NullPointerException("Invalid null print stream parameter");

      this.ps = ps;
      this.level = infoLevel;
      this.type = type;
      this.map = new ConcurrentHashMap<Integer, BlockInfo>();
      this.thresholds = (type == Type.ENCODING) ?
              new Event.Type[]
              {
                 Event.Type.COMPRESSION_START,
                 Event.Type.BEFORE_TRANSFORM,
                 Event.Type.AFTER_TRANSFORM,
                 Event.Type.BEFORE_ENTROPY,
                 Event.Type.AFTER_ENTROPY,
                 Event.Type.COMPRESSION_END
              } :
              new Event.Type[]
              {
                 Event.Type.DECOMPRESSION_START,
                 Event.Type.BEFORE_ENTROPY,
                 Event.Type.AFTER_ENTROPY,
                 Event.Type.BEFORE_TRANSFORM,