private <T extends AbstractEdmEntityImpl, G extends MongoTermList<T>> boolean migratePhaseOne(
      JacksonDBCollection<G, String> termListColl_source,
      JacksonDBCollection<MongoTerm, String> termColl_source,
      JacksonDBCollection<G, String> termListColl_target,
      JacksonDBCollection<MongoTerm, String> termColl_target,
      ContextualCategory contextualCategory,
      String termCollection)
      throws UnknownHostException {
    int skip = 0;
    int counter = 0;
    while (true) {
      try {
        DBCursor<G> curs =
            termListColl_source
                .find(new BasicDBObject("entityType", contextualCategory.getEntityClass()))
                .skip(skip);
        curs.addOption(com.mongodb.Bytes.QUERYOPTION_NOTIMEOUT);

        while (curs.hasNext()) {
          long nextSequence = nextSequence(contextualCategory);
          counter++;

          G termList = curs.next();
          String newCodeUri =
              String.format(
                  "http://data.europeana.eu/%s/base" + "/%d",
                  contextualCategory.getLabel(), nextSequence);
          String oldCodeUri = termList.getCodeUri();

          MongoCodeLookup lookup = new MongoCodeLookup();
          lookup.setCodeUri(newCodeUri);
          lookup.setOriginalCodeUri(oldCodeUri);
          lookupColl_target.insert(lookup);

          lookupCodeUri.put(newCodeUri, oldCodeUri);
          lookupOriginalCodeUri.put(oldCodeUri, newCodeUri);
        }
        curs.close();
        break;
      } catch (Exception e) {
        e.printStackTrace();
        initialiseConnections();

        skip = counter - 1;
        continue;
      }
    }
    return true;
  }
  private <T extends AbstractEdmEntityImpl, G extends MongoTermList<T>> boolean migratePhaseTwo(
      JacksonDBCollection<MongoTerm, String> termColl_source,
      JacksonDBCollection<MongoTerm, String> termColl_target,
      ContextualCategory contextualCategory,
      int skip)
      throws UnknownHostException {
    int counter = 0;
    int interval = 0;
    while (true) {
      try {

        DBCursor<MongoTerm> termCurs = termColl_source.find().skip(skip);
        termCurs.addOption(com.mongodb.Bytes.QUERYOPTION_NOTIMEOUT);
        while (termCurs.hasNext()) {
          MongoTerm term = termCurs.next();
          counter++;
          interval++;
          if (interval == 1000) {
            System.out.println(
                String.format("Phase 2 (%s): %d ", contextualCategory.getEntityClass(), counter));
            interval = 0;
          }

          term.setId(null);
          String codeUri = lookupOriginalCodeUri(term.getCodeUri());

          if (codeUri != null) {
            term.setCodeUri(codeUri);
            try {
              termColl_target.insert(term);

            } catch (DuplicateKeyException me) {
              // do nothing
              // System.out.println("Duplicate:" +
              // term.toString());
              continue;
            }
          }
        }
        termCurs.close();
        break;
      } catch (Exception e) {
        e.printStackTrace();
        initialiseConnections();
        counter--;
        skip = counter;
        continue;
      }
    }
    return true;
  }
  private <
          T extends AbstractEdmEntityImpl,
          G extends MongoTermList<T>,
          H extends AbstractRepresentationMigration<T>>
      boolean migratePhaseThree(
          JacksonDBCollection<G, String> termListColl_source,
          JacksonDBCollection<G, String> termListColl_target,
          H representationMagrition,
          ContextualCategory contextualCategory,
          int skip)
          throws UnknownHostException {
    int counter = 0;
    int interval = 0;
    while (true) {
      try {

        DBCursor<G> curs =
            termListColl_source
                .find(new BasicDBObject("entityType", contextualCategory.getEntityClass()))
                .skip(skip);
        curs.addOption(com.mongodb.Bytes.QUERYOPTION_NOTIMEOUT);

        while (curs.hasNext()) {
          G termList = curs.next();
          counter++;
          interval++;
          if (interval == 1000) {
            System.out.println(
                String.format("Phase 3 (%s): %d ", contextualCategory.getEntityClass(), counter));
            interval = 0;
          }

          String originalUri = termList.getCodeUri();
          String codeUri = lookupOriginalCodeUri(termList.getCodeUri());
          termList.setCodeUri(codeUri);
          termList.setId(null);

          String parent = termList.getParent();

          if (StringUtils.isNotBlank(parent)) {

            String parentCodeUri = lookupOriginalCodeUri(parent);
            if (parentCodeUri == null) {
              termList.setParent(null);
            } else {
              termList.setParent(parentCodeUri);
            }
          }

          T representation = termList.getRepresentation();
          representationMagrition.migrateRepresentation(codeUri, originalUri, representation);
          termList.setOwlSameAs(((PlaceImpl) representation).getOwlSameAs());
          try {
            termListColl_target.insert(termList);

          } catch (DuplicateKeyException me) {
            continue;
          }
        }
        curs.close();
        break;
      } catch (Exception e) {
        e.printStackTrace();
        initialiseConnections();
        counter--;
        skip = counter;
        continue;
      }
    }
    return true;
  }