/*
 *  Copyright (c) 2016 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
package org.wso2.msf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Map;

/**
 * This session manager persists sessions in the local file system.
 */
public class PersistentSessionManager extends AbstractSessionManager {
    public PersistentSessionManager() {
        File file = new File(".tmp");
        if (!file.exists() && !file.mkdirs()) {
            throw new IllegalStateException("Cannot create .tmp directory");
        }
    }

    @Override
    public void loadSessions(Map<String, Session> sessions) {
        String path = Paths.get(".tmp").toString();
        if (!new File(path).exists()) {
            return;
        }
        Arrays.stream(new File(path).listFiles()).forEach(file -> {
            Session session = readSession(file.getName());
            sessions.put(session.getId(), session);
        });
    }

    @Override
    public Session readSession(String sessionId) {
        String path = Paths.get(".tmp", sessionId).toString();
        if (!new File(path).exists()) {
            return null;
        }
        try (FileInputStream fis = new FileInputStream(path);
             ObjectInputStream ois = new ObjectInputStream(fis);) {

            Session session = (Session) ois.readObject();
            session.setManager(this);
            return session;
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException("Cannot read session " + sessionId, e);
        }
    }

    @Override
    public void saveSession(Session session) {
        try (FileOutputStream fout = new FileOutputStream(Paths.get(".tmp", session.getId()).toString());
             ObjectOutputStream oos = new ObjectOutputStream(fout)) {
            oos.writeObject(session);
            oos.reset();
            oos.flush();
            oos.close();
        } catch (IOException e) {
            throw new RuntimeException("Cannot save session " + session.getId(), e);
        }
    }

    @Override
    public void deleteSession(Session session) {
        String pathname = Paths.get(".tmp", session.getId()).toString();
        if (!new File(pathname).delete()) {
            throw new IllegalStateException("File " + pathname + " deletion failed");
        }
    }

    @Override
    public void updateSession(Session session) {
        saveSession(session);
    }
}

@@ -703,16 +703,74 @@
 msf4j;%0A%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A
 import j
@@ -1167,16 +1167,171 @@
 nager %7B%0A
+    private static final Logger log = LoggerFactory.getLogger(PersistentSessionManager.class);%0A    private static final String SESSION_DIR = %22.sessions%22;%0A%0A
     publ
@@ -1375,20 +1375,19 @@
    File 
-file
+dir
  = new F
@@ -1390,22 +1390,27 @@
 ew File(
-%22.tmp%22
+SESSION_DIR
 );%0A     
@@ -1417,20 +1417,19 @@
    if (!
-file
+dir
 .exists(
@@ -1434,20 +1434,19 @@
 s() && !
-file
+dir
 .mkdirs(
@@ -1632,49 +1632,39 @@
     
-String path = Paths.get(%22.tmp%22).toString(
+File dir = new File(SESSION_DIR
 );%0A 
@@ -1671,38 +1671,27 @@
        if (!
-new File(path)
+dir
 .exists()) %7B
@@ -1713,32 +1713,90 @@
 turn;%0A        %7D%0A
+        String path = Paths.get(SESSION_DIR).toString();%0A%0A
         Arrays.s
@@ -1829,16 +1829,27 @@
 iles()).
+parallel().
 forEach(
@@ -1913,24 +1913,350 @@
 getName());%0A
+%0A            // Delete expired session files%0A            if (System.currentTimeMillis() - session.getLastAccessedTime() %3E=%0A                    session.getMaxInactiveInterval() * 60 * 1000 && !file.delete()) %7B%0A                log.warn(%22Couldn't delete expired session file %22 + file.getAbsolutePath());%0A            %7D else %7B%0A    
             
@@ -2287,32 +2287,46 @@
 Id(), session);%0A
+            %7D%0A
         %7D);%0A    
@@ -2417,38 +2417,43 @@
 ath = Paths.get(
-%22.tmp%22
+SESSION_DIR
 , sessionId).toS
@@ -3067,38 +3067,43 @@
 tream(Paths.get(
-%22.tmp%22
+SESSION_DIR
 , session.getId(
@@ -3230,83 +3230,8 @@
 n);%0A
-            oos.reset();%0A            oos.flush();%0A            oos.close();%0A
     
@@ -3465,14 +3465,19 @@
 get(
-%22.tmp%22
+SESSION_DIR
 , se

Remove session files of expired sessions