public synchronized ArticlesIndex getIndex(OperationObserver observer) {
    if (index == null) {
      boolean imported = importFromResource();
      File indexFile = getIndexFile();
      observer.onOperationInfoChanged(OperationObserver.LOADING_CACHE, indexFile.getAbsolutePath());
      if (!indexFile.exists()) {
        log.info("Article index file does not exist:", indexFile);
        index = new ArticlesIndex();
        return index;
      }
      try {
        index = JsonMapper.deserialize(indexFile, ArticlesIndex.class, typeResolver);
        log.info("Article index loaded:", index.getArticlesCount(), "articles");
      } catch (Exception ex) {
        log.error("Article indes loading failed:", ex);
        indexFile.delete();
        return getIndex(observer);
      }
      if (imported) {
        viewed.addAll(index.getArticles());
      } else {
        for (ArticleRef article : index.getArticles()) {
          article.repairTitle();
        }
      }
    }

    return index;
  }
 public synchronized List<ArticleRef> updateIndex(OperationObserver observer) {
   getIndex(observer);
   List<ArticleRef> newArticles;
   try {
     newArticles = TestDe.update(index, observer);
   } catch (ParseException ex1) {
     throw new RuntimeException(ex1);
   }
   File indexFile = getIndexFile();
   observer.onOperationInfoChanged(OperationObserver.SAVING, indexFile.getAbsolutePath());
   try {
     JsonMapper.serialize(index, indexFile);
   } catch (IOException ex) {
     throw new RuntimeException(ex);
   }
   return newArticles;
 }