@Override
 public List<Object> deserializeKeyAndValue(byte[] key, byte[] value) {
   Long ts = converter.toNanoseconds(Bytes.toLong(key));
   byte[] packetHeaderized = PcapHelper.addPacketHeader(ts, value, endianness);
   byte[] globalHeaderized = PcapHelper.addGlobalHeader(packetHeaderized, endianness);
   return new Values(ImmutableList.of(new LongWritable(ts), new BytesWritable(globalHeaderized)));
 }
 public Iterable<String> getPaths(FileSystem fs, Path basePath, long begin, long end)
     throws IOException {
   List<String> ret = new ArrayList<>();
   Iterator<Path> files = listFiles(fs, basePath).iterator();
   /*
   The trick here is that we need a trailing left endpoint, because we only capture the start of the
   timeseries kept in the file.
    */
   boolean isFirst = true;
   Path leftEndpoint = files.hasNext() ? files.next() : null;
   if (leftEndpoint == null) {
     return ret;
   }
   {
     Long ts = PcapHelper.getTimestamp(leftEndpoint.getName());
     if (ts != null
         && Long.compareUnsigned(ts, begin) >= 0
         && Long.compareUnsigned(ts, end) <= 0) {
       ret.add(leftEndpoint.toString());
       isFirst = false;
     }
   }
   while (files.hasNext()) {
     Path p = files.next();
     Long ts = PcapHelper.getTimestamp(p.getName());
     if (ts != null
         && Long.compareUnsigned(ts, begin) >= 0
         && Long.compareUnsigned(ts, end) <= 0) {
       if (isFirst && leftEndpoint != null) {
         ret.add(leftEndpoint.toString());
       }
       if (isFirst) {
         isFirst = false;
       }
       ret.add(p.toString());
     } else {
       leftEndpoint = p;
     }
   }
   if (LOG.isDebugEnabled()) {
     LOG.debug("Including files " + Joiner.on(",").join(ret));
   }
   return ret;
 }
 private Stream<PacketInfo> filteredPacketInfo(BytesWritable value) throws IOException {
   return PcapHelper.toPacketInfo(value.copyBytes()).stream().filter(filter);
 }