@Override
 public void write(Excerpt excerpt, Date date) {
   int pos = excerpt.position();
   excerpt.writeUnsignedByte(0);
   excerpt.append(date.getTime());
   excerpt.writeUnsignedByte(pos, excerpt.position() - 1 - pos);
 }
 @Override
 public byte[] read(Excerpt excerpt) {
   int len = (int) excerpt.readStopBit();
   byte[] bytes = new byte[len];
   excerpt.read(bytes);
   return bytes;
 }
    @Override
    public void run() {
      try {
        long index = readIndex(socket);
        Excerpt excerpt = chronicle.createExcerpt();
        ByteBuffer bb = TcpUtil.createBuffer(1, chronicle); // minimum size
        while (!closed) {
          while (!excerpt.index(index)) pause(delayNS);
          int size = excerpt.capacity();
          int remaining = size + TcpUtil.HEADER_SIZE;

          bb.clear();
          bb.putLong(index);
          bb.putInt(size);
          while (remaining > 0) {
            int size2 = Math.min(remaining, bb.capacity());
            bb.limit(size2);
            excerpt.read(bb);
            bb.flip();
            remaining -= bb.remaining();
            IOTools.writeAll(socket, bb);
          }
          if (bb.remaining() > 0) throw new EOFException("Failed to send index=" + index);
          index++;
        }
      } catch (IOException e) {
        if (!closed) logger.log(Level.INFO, "Connect " + socket + " died", e);
      }
    }
  @Override
  public synchronized void transfer(Integer from, Integer to, int amount) {
    accounts.get(from).transfer(-amount);
    accounts.get(to).transfer(amount);

    excerpt.startExcerpt(12);
    excerpt.writeInt(from);
    excerpt.writeInt(to);
    excerpt.writeInt(amount);
    excerpt.finish();
  }
  @Override
  public Page read(long key, @Nullable PageReadTrx pageReadTrx) throws SirixIOException {
    try {
      // Read page from excerpt.
      final boolean opened = mExcerpt.index(key);
      assert opened : "Index couldn't be opened!";
      final int dataLength = mExcerpt.readInt();
      final byte[] page = new byte[dataLength];
      mExcerpt.read(page);
      mExcerpt.finish();

      // Perform byte operations.
      final DataInputStream input =
          new DataInputStream(mByteHandler.deserialize(new ByteArrayInputStream(page)));

      // Return reader required to instantiate and deserialize page.
      return PagePersistenter.deserializePage(input, pageReadTrx);
    } catch (final IOException e) {
      throw new SirixIOException(e);
    }
  }
 @Override
 public void close() throws SirixIOException {
   mExcerpt.close();
 }
    @Override
    public void run() {
      try {
        long index = readIndex(socket);
        Excerpt excerpt = chronicle.createExcerpt();
        ByteBuffer bb = TcpUtil.createBuffer(1, chronicle); // minimum size
        long sendInSync = 0;
        boolean first = true;
        OUTER:
        while (!closed) {
          while (!excerpt.index(index)) {
            //                        System.out.println("Waiting for " + index);
            long now = System.currentTimeMillis();
            if (sendInSync <= now && !first) {
              bb.clear();
              bb.putInt(IN_SYNC_LEN);
              bb.flip();
              while (bb.remaining() > 0 && socket.write(bb) > 0) {
                doNothing();
              }
              sendInSync = now + HEARTBEAT_INTERVAL_MS;
            }
            pause();
            if (closed) break OUTER;
          }
          //                    System.out.println("Writing " + index);
          final int size = excerpt.capacity();
          int remaining;

          bb.clear();
          if (first) {
            //                        System.out.println("wi " + index);
            bb.putLong(index);
            first = false;
            remaining = size + TcpUtil.HEADER_SIZE;
          } else {
            remaining = size + 4;
          }
          bb.putInt(size);
          // for large objects send one at a time.
          if (size > bb.capacity() / 2) {
            while (remaining > 0) {
              int size2 = Math.min(remaining, bb.capacity());
              bb.limit(size2);
              excerpt.read(bb);
              bb.flip();
              //                        System.out.println("w " + ChronicleTools.asString(bb));
              remaining -= bb.remaining();
              while (bb.remaining() > 0 && socket.write(bb) > 0) {
                doNothing();
              }
            }
          } else {
            bb.limit(remaining);
            excerpt.read(bb);
            int count = 1;
            while (excerpt.index(index + 1) && count++ < MAX_MESSAGE) {
              if (excerpt.remaining() + 4 >= bb.capacity() - bb.position()) break;
              // if there is free space, copy another one.
              int size2 = excerpt.capacity();
              //                            System.out.println("W+ "+size);
              bb.limit(bb.position() + size2 + 4);
              bb.putInt(size2);
              excerpt.read(bb);

              index++;
            }

            bb.flip();
            //                        System.out.println("W " + size + " wb " + bb);
            while (bb.remaining() > 0 && socket.write(bb) > 0) {
              doNothing();
            }
          }
          if (bb.remaining() > 0) throw new EOFException("Failed to send index=" + index);
          index++;
          sendInSync = 0;
          //                    if (index % 20000 == 0)
          //                        System.out.println(System.currentTimeMillis() + ": wrote " +
          // index);
        }
      } catch (IOException e) {
        if (!closed) {
          String msg = e.getMessage();
          if (msg != null
              && (msg.contains("reset by peer")
                  || msg.contains("Broken pipe")
                  || msg.contains("was aborted by")))
            logger.log(Level.INFO, "Connect " + socket + " closed from the other end " + e);
          else logger.log(Level.INFO, "Connect " + socket + " died", e);
        }
      }
    }
 @Override
 public Date parse(Excerpt excerpt, StopCharTester tester) {
   return lookupDate(excerpt.readLong());
 }
 @Override
 public Date read(Excerpt excerpt) {
   excerpt.readUTF(sb);
   long time = parseLong(sb);
   return lookupDate(time);
 }
 @Override
 public byte[] parse(Excerpt excerpt, StopCharTester tester) {
   return excerpt.parseUTF(tester).getBytes(Charset.forName("UTF-8"));
 }
 @Override
 public void write(Excerpt excerpt, byte[] bytes) {
   excerpt.writeStopBit(bytes.length);
   excerpt.write(bytes);
 }