/**
   * Reserves files (with the given fileID) in the specified journal, and places a {@link
   * FileWrapperJournal} in place to store messages while synchronization is going on.
   *
   * @param packet
   * @throws Exception
   * @return if the incoming packet indicates the synchronization is finished then return an
   *     acknowledgement otherwise return an empty response
   */
  private ReplicationResponseMessageV2 handleStartReplicationSynchronization(
      final ReplicationStartSyncMessage packet) throws Exception {
    ReplicationResponseMessageV2 replicationResponseMessage = new ReplicationResponseMessageV2();
    if (activation.isRemoteBackupUpToDate()) {
      throw ActiveMQMessageBundle.BUNDLE.replicationBackupUpToDate();
    }

    synchronized (this) {
      if (!started) return replicationResponseMessage;

      if (packet.isSynchronizationFinished()) {
        finishSynchronization(packet.getNodeID());
        replicationResponseMessage.setSynchronizationIsFinishedAcknowledgement(true);
        return replicationResponseMessage;
      }

      switch (packet.getDataType()) {
        case LargeMessages:
          for (long msgID : packet.getFileIds()) {
            createLargeMessage(msgID, true);
          }
          break;
        case JournalBindings:
        case JournalMessages:
          if (wantedFailBack && !packet.isServerToFailBack()) {
            ActiveMQServerLogger.LOGGER.autoFailBackDenied();
          }

          final JournalContent journalContent =
              SyncDataType.getJournalContentType(packet.getDataType());
          final Journal journal = journalsHolder.get(journalContent);

          if (packet.getNodeID() != null) {
            // At the start of replication, we still do not know which is the nodeID that the live
            // uses.
            // This is the point where the backup gets this information.
            backupQuorum.liveIDSet(packet.getNodeID());
          }
          Map<Long, JournalSyncFile> mapToFill = filesReservedForSync.get(journalContent);

          for (Entry<Long, JournalFile> entry :
              journal.createFilesForBackupSync(packet.getFileIds()).entrySet()) {
            mapToFill.put(entry.getKey(), new JournalSyncFile(entry.getValue()));
          }
          FileWrapperJournal syncJournal = new FileWrapperJournal(journal);
          registerJournal(journalContent.typeByte, syncJournal);
          break;
        default:
          throw ActiveMQMessageBundle.BUNDLE.replicationUnhandledDataType();
      }
    }

    return replicationResponseMessage;
  }
  public void compareJournalInformation(final JournalLoadInformation[] journalInformation)
      throws ActiveMQException {
    if (!activation.isRemoteBackupUpToDate()) {
      throw ActiveMQMessageBundle.BUNDLE.journalsNotInSync();
    }

    if (journalLoadInformation == null
        || journalLoadInformation.length != journalInformation.length) {
      throw ActiveMQMessageBundle.BUNDLE.replicationTooManyJournals();
    }

    for (int i = 0; i < journalInformation.length; i++) {
      if (!journalInformation[i].equals(journalLoadInformation[i])) {
        ActiveMQServerLogger.LOGGER.journalcomparisonMismatch(
            journalParametersToString(journalInformation));
        throw ActiveMQMessageBundle.BUNDLE.replicationTooManyJournals();
      }
    }
  }