/**
  * @param id the session id
  * @param allowExpired if true, will also include expired sessions that have not been deleted. If
  *     false, will ensure expired sessions are not returned.
  * @return
  */
 private RedisSession getSession(String id, boolean allowExpired) {
   Map<Object, Object> entries = getSessionBoundHashOperations(id).entries();
   if (entries.isEmpty()) {
     return null;
   }
   MapSession loaded = new MapSession();
   loaded.setId(id);
   for (Map.Entry<Object, Object> entry : entries.entrySet()) {
     String key = (String) entry.getKey();
     if (CREATION_TIME_ATTR.equals(key)) {
       loaded.setCreationTime((Long) entry.getValue());
     } else if (MAX_INACTIVE_ATTR.equals(key)) {
       loaded.setMaxInactiveIntervalInSeconds((Integer) entry.getValue());
     } else if (LAST_ACCESSED_ATTR.equals(key)) {
       loaded.setLastAccessedTime((Long) entry.getValue());
     } else if (key.startsWith(SESSION_ATTR_PREFIX)) {
       loaded.setAttribute(key.substring(SESSION_ATTR_PREFIX.length()), entry.getValue());
     }
   }
   if (!allowExpired && loaded.isExpired()) {
     return null;
   }
   RedisSession result = new RedisSession(loaded);
   result.originalLastAccessTime =
       loaded.getLastAccessedTime()
           + TimeUnit.SECONDS.toMillis(loaded.getMaxInactiveIntervalInSeconds());
   result.setLastAccessedTime(System.currentTimeMillis());
   return result;
 }
 public void removeAttribute(String attributeName) {
   cached.removeAttribute(attributeName);
   delta.put(getSessionAttrNameKey(attributeName), null);
 }
 public void setAttribute(String attributeName, Object attributeValue) {
   cached.setAttribute(attributeName, attributeValue);
   delta.put(getSessionAttrNameKey(attributeName), attributeValue);
 }
 public Set<String> getAttributeNames() {
   return cached.getAttributeNames();
 }
 public Object getAttribute(String attributeName) {
   return cached.getAttribute(attributeName);
 }
 public int getMaxInactiveIntervalInSeconds() {
   return cached.getMaxInactiveIntervalInSeconds();
 }
 public void setMaxInactiveIntervalInSeconds(int interval) {
   cached.setMaxInactiveIntervalInSeconds(interval);
   delta.put(MAX_INACTIVE_ATTR, getMaxInactiveIntervalInSeconds());
 }
 public long getLastAccessedTime() {
   return cached.getLastAccessedTime();
 }
 public String getId() {
   return cached.getId();
 }
 public long getCreationTime() {
   return cached.getCreationTime();
 }
 public boolean isExpired() {
   return cached.isExpired();
 }
 public void setLastAccessedTime(long lastAccessedTime) {
   cached.setLastAccessedTime(lastAccessedTime);
   delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime());
 }