public DeserializedSessionContainer sessionFromSerializedData(String id, byte[] data)
      throws IOException {
    log.trace("Deserializing session " + id + " from Redis");

    if (Arrays.equals(NULL_SESSION, data)) {
      log.error(
          "Encountered serialized session "
              + id
              + " with data equal to NULL_SESSION. This is a bug.");
      throw new IOException("Serialized session data was equal to NULL_SESSION");
    }

    RedisSession session = null;
    SessionSerializationMetadata metadata = new SessionSerializationMetadata();

    try {
      session = (RedisSession) createEmptySession();

      serializer.deserializeInto(data, session, metadata);

      session.setId(id);
      session.setNew(false);
      session.setMaxInactiveInterval(getMaxInactiveInterval());
      session.access();
      session.setValid(true);
      session.resetDirtyTracking();

      if (log.isTraceEnabled()) {
        log.trace("Session Contents [" + id + "]:");
        Enumeration en = session.getAttributeNames();
        while (en.hasMoreElements()) {
          log.trace("  " + en.nextElement());
        }
      }
    } catch (ClassNotFoundException ex) {
      log.fatal("Unable to deserialize into session", ex);
      throw new IOException("Unable to deserialize into session", ex);
    }

    return new DeserializedSessionContainer(session, metadata);
  }