public Map<String, Object> data(IBookCollection<Book> collection) {
    final Map<String, Object> map = new HashMap<String, Object>();
    map.put("generation", myGeneration.getValue());
    map.put("timestamp", System.currentTimeMillis());

    final Book currentBook = collection.getRecentBook(0);
    if (currentBook != null) {
      final String oldHash = myCurrentBookHash.getValue();
      final String newHash = collection.getHash(currentBook, true);
      if (newHash != null && !newHash.equals(oldHash)) {
        myCurrentBookHash.setValue(newHash);
        if (oldHash.length() != 0) {
          myCurrentBookTimestamp.setValue(String.valueOf(System.currentTimeMillis()));
          myServerBook.reset();
        }
      }
      final String currentBookHash = newHash != null ? newHash : oldHash;

      final Map<String, Object> currentBookMap = new HashMap<String, Object>();
      currentBookMap.put("hash", currentBookHash);
      currentBookMap.put("title", currentBook.getTitle());
      try {
        currentBookMap.put("timestamp", Long.parseLong(myCurrentBookTimestamp.getValue()));
      } catch (Exception e) {
      }
      map.put("currentbook", currentBookMap);

      final List<Map<String, Object>> lst = new ArrayList<Map<String, Object>>();
      if (positionOption(currentBookHash).getValue().length() == 0) {
        final Map<String, Object> posMap = positionMap(collection, currentBook);
        if (posMap != null) {
          posMap.put("hash", currentBookHash);
          lst.add(posMap);
        }
      }
      if (!currentBookHash.equals(oldHash) && positionOption(oldHash).getValue().length() == 0) {
        final Map<String, Object> posMap =
            positionMap(collection, collection.getBookByHash(oldHash));
        if (posMap != null) {
          posMap.put("hash", oldHash);
          lst.add(posMap);
        }
      }
      if (lst.size() > 0) {
        map.put("positions", lst);
      }
    }

    System.err.println("DATA = " + map);
    return map;
  }
  public boolean updateFromServer(Map<String, Object> data) {
    System.err.println("RESPONSE = " + data);
    myGeneration.setValue((int) (long) (Long) data.get("generation"));

    final List<Map> positions = (List<Map>) data.get("positions");
    if (positions != null) {
      for (Map<String, Object> map : positions) {
        final ZLTextFixedPosition.WithTimestamp pos = map2Position(map);
        for (String hash : (List<String>) map.get("all_hashes")) {
          savePosition(hash, pos);
        }
      }
    }

    myServerBook.init((Map<String, Object>) data.get("currentbook"));

    return data.size() > 1;
  }
 public ServerBookInfo getServerBookInfo() {
   return myServerBook.getInfo();
 }