docs: @Override
      public void recoveryComplete(byte[] serviceData) throws LogClosedException, InternalLogException, LogIncompatibleException
      {
          if (tc.isEntryEnabled())
              Tr.entry(tc, "recoveryComplete", new java.lang.Object[] { RLSUtils.toHexString(serviceData, RLSUtils.MAX_DISPLAY_BYTES), this });
  
          // If this recovery log instance has been marked as incompatible then throw an exception
          // accordingly.
          if (incompatible())
          {
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "recoveryComplete", "LogIncompatibleException");
              throw new LogIncompatibleException();
          }
  
          // If this recovery log instance has experienced a serious internal error then prevent this operation from
          // executing.
          if (failed())
          {
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "recoveryComplete", this);
              throw new InternalLogException(null);
          }
  
          // Check that the log is open.
          if (_logHandle == null)
          {
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "recoveryComplete", "LogClosedException");
              throw new LogClosedException(null);
          }
  
          // Take a copy of the supplied service data to ensure that future changes
          // to it do not effect the recovery log. This is the only point in the
          // code where the service data may be updated. When the log keypointed,
          // the new service data will be written to disk.      
          byte[] serviceDataCopy = null;
  
          if (serviceData != null)
          {
              serviceDataCopy = new byte[serviceData.length];
              System.arraycopy(serviceData, 0, serviceDataCopy, 0, serviceData.length);
          }
  
          try
          {
              // Update the service data held by the logHandle
              _logHandle.setServiceData(serviceDataCopy);
  
              // Now that the service data has been updated, keypoint the log.
              keypoint();
          } catch (LogClosedException exc)
          {
              // In practice this exception is unlikely to occur. We have already checked above that the log is
              // open. It is possible that in a multi-threaded environment this could occur, but its the
              // responsibility of the user of the recovery log service to ensure they do not try and close
              // the log at the same time as calling recoveryComplete. All we can do is re-throw the exception.
              FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.MultiScopeRecoveryLog.recoveryComplete", "785", this);
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "recoveryComplete", exc);
              throw exc;
          } catch (InternalLogException exc)
          {
              FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.MultiScopeRecoveryLog.recoveryComplete", "791", this);
              markFailed(exc); /* @MD19484C */
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "recoveryComplete", exc);
              throw exc;
          } catch (Throwable exc)
          {
              FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.MultiScopeRecoveryLog.recoveryComplete", "798", this);
              markFailed(exc); /* @MD19484C */
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "recoveryComplete", "InternalLogException");
              throw new InternalLogException(exc);
          }
  
          if (tc.isEntryEnabled())
              Tr.exit(tc, "recoveryComplete");
      }