docs: public SIMessageHandle restoreFromBytes(byte[] data)
        throws IllegalArgumentException {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(tc, "restoreFromBytes");
  
      // Minimum valid length is an array with a short version number, integer (of value 0) for uuid length
      // and long for value.  Any byte [] shorter than this is invalid for restoration.
      int minValidArrayLength = ArrayUtil.SHORT_SIZE + ArrayUtil.INT_SIZE + ArrayUtil.LONG_SIZE;
  
      if ((data == null))
      {
        String exString = nls.getFormattedMessage("NULL_HANDLE_PASSED_FOR_RESTORE_CWSIF0032",
            new Object[] {"NULL"},
            "JsMessageHandleRestorer.restoreFromBytes called with NULL.");
  
        IllegalArgumentException e = new IllegalArgumentException(exString);
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc, "restoreFromBytes called with NULL, throwing IllegalArgumentException");
        throw e;
      }
      else if (data.length < minValidArrayLength)
      {
        String exString = nls.getFormattedMessage("RESTORE_FROM_BYTES_ARRAY_TOO_SHORT_CWSIF0033"
            ,null
            ,"Array length was shorter than the minimum valid array length.");
  
        IllegalArgumentException e = new IllegalArgumentException(exString);
  
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        {
          String formattedBytes = SibTr.formatBytes(data,0,data.length);
          SibTr.debug(tc, "Throwing IllegalArgumentException : " + exString, formattedBytes);
        }
        throw e;
      }
  
      int offset = 0;
  
      // Read the Version number
      short vNumber = ArrayUtil.readShort(data, offset);
      offset += ArrayUtil.SHORT_SIZE;
  
      // 1 is the only valid versionNumber at the moment
      if (vNumber != 1)
      {
  
  
        String exString = nls.getFormattedMessage("RESTORE_FROM_BYTES_UNKNOWN_VERSION_NUMBER_CWSIF0034"
            ,null
            ,"Unknown version information detected in MessageHandle : "+vNumber);
  
        IllegalArgumentException e = new IllegalArgumentException(exString);
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        {
          String formattedBytes = SibTr.formatBytes(data,0,data.length);
          SibTr.debug (tc, "Throwing IllegalArgumentException : " + exString, formattedBytes);
        }
        throw e;
      }
  
      int uuidLength = ArrayUtil.readInt(data, offset);
      offset += ArrayUtil.INT_SIZE;
  
      // the data array should contain the short version num, int uuid length, the uuid and long 'value'
      // so, uuid length must be (data.length - (short + int + long) )
      //                                        (short + int + long = minValidArrayLength)
      // We do not need to externalise exactly what sums we are doing to check things - just tell
      // them that something isn't right.
  
      if (uuidLength != (data.length - minValidArrayLength) )
      {
  
  
        String exString = nls.getFormattedMessage("RESTORE_FROM_BYTES_INTERNAL_LENGTH_CHECK_FAIL_CWSIF0035"
            ,null
            ,"Invalid data passed to in restoreFromBytes. Internal length checks do not match.");
  
        IllegalArgumentException e = new IllegalArgumentException(exString);
  
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        {
          String formattedBytes = SibTr.formatBytes(data,0,data.length);
          SibTr.debug(tc, "Throwing IllegalArgumentException : " + exString, formattedBytes);
        }
        throw e;
      }
  
      JsMessageHandle handle = null;
  
      if (uuidLength == 0)
      {
        // there is no uuid, leave the uuid as null and construct the handle with just a value
        long value = ArrayUtil.readLong(data, offset);
        handle = new JsMessageHandleImpl(value);
      }
      else
      {
        // read the uuid bytes in and construct a SIBUuid8 from it
        // then construct the handle
        byte [] uuidBytes = ArrayUtil.readBytes(data, offset, uuidLength);
        offset += uuidLength;
        SIBUuid8 uuid = new SIBUuid8(uuidBytes);
        long value = ArrayUtil.readLong(data, offset);
        handle = new JsMessageHandleImpl(uuid, Long.valueOf(value));
      }
  
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(tc, "restoreFromBytes", handle);
      return handle;
    }