Adding Aggregators and predcitor to the service
Android.mk is modified to build a static java for whole service

Change-Id: I25b0f55ce9693efb3c59b209d4f0cf5c07c47fe1
diff --git a/bordeaux/learning/Android.mk b/bordeaux/learning/Android.mk
index 86e4209..f61259a 100644
--- a/bordeaux/learning/Android.mk
+++ b/bordeaux/learning/Android.mk
@@ -43,7 +43,8 @@
 
 LOCAL_MODULE_TAGS := samples tests
 
-LOCAL_SRC_FILES :=$(call all-java-files-under, multiclass_pa stochastic_linear_ranker)
+LOCAL_SRC_FILES := $(call all-java-files-under, multiclass_pa stochastic_linear_ranker ) \
+                   $(call all-java-files-under, predictor_histogram)
 
 LOCAL_MODULE :=  bordeaux_learners
 
diff --git a/bordeaux/learning/predictor_histogram/Android.mk b/bordeaux/learning/predictor_histogram/Android.mk
new file mode 100644
index 0000000..1c352f1
--- /dev/null
+++ b/bordeaux/learning/predictor_histogram/Android.mk
@@ -0,0 +1,16 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed 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.
+#
+
+LOCAL_PATH := $(call my-dir)
diff --git a/bordeaux/learning/predictor_histogram/java/android/bordeaux/learning/predictorHist.java b/bordeaux/learning/predictor_histogram/java/android/bordeaux/learning/predictorHist.java
new file mode 100644
index 0000000..7924424
--- /dev/null
+++ b/bordeaux/learning/predictor_histogram/java/android/bordeaux/learning/predictorHist.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.learning;
+
+import java.util.HashMap;
+import java.util.Map;
+import android.util.Log;
+
+/**
+ * A simple impelentation of histograms with sparse enteries using HashMap.
+ * User can push examples or extract probabilites from this histogram.
+ */
+public class predictorHist {
+    private HashMap<String, Integer> mCountHist;
+    private int mSampleCount;
+    String TAG = "PredicrtHist";
+
+    public predictorHist() {
+        mCountHist = new HashMap<String, Integer>();
+        mSampleCount = 0;
+    }
+
+    // reset histogram
+    public void ResetPredictorHist() {
+        mCountHist.clear();
+        mSampleCount = 0;
+    }
+
+    // getters
+    public final HashMap<String, Integer> getHist() {
+        return mCountHist;
+    }
+
+    public int getHistCounts() {
+        return mSampleCount;
+    }
+
+    //setter
+    public void set(HashMap<String, Integer> hist) {
+        ResetPredictorHist();
+        for (Map.Entry<String, Integer> x : hist.entrySet()) {
+            mCountHist.put(x.getKey(), x.getValue());
+            mSampleCount = mSampleCount + x.getValue();
+        }
+    }
+
+    /**
+     * pushes a new example to the histogram
+     */
+    public void pushSample( String fs) {
+        int histValue = 1;
+        if (mCountHist.get(fs) != null )
+            histValue = histValue + mCountHist.get(fs);
+        mCountHist.put(fs,histValue);
+        mSampleCount++;
+    }
+
+    /**
+     * return probabilty of an exmple using the histogram
+     */
+    public float getProbability(String fs) {
+        float res = 0;
+        if (mCountHist.get(fs) != null )
+            res = ((float) mCountHist.get(fs)) / ((float)mSampleCount);
+        return res;
+    }
+}
diff --git a/bordeaux/service/Android.mk b/bordeaux/service/Android.mk
index c49a6d6..f71bc85 100644
--- a/bordeaux/service/Android.mk
+++ b/bordeaux/service/Android.mk
@@ -1,21 +1,24 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_MODULE_TAGS := samples tests
+LOCAL_MODULE_TAGS := optional
 
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_SRC_FILES += \
         src/android/bordeaux/services/IBordeauxServiceCallback.aidl \
+        src/android/bordeaux/services/IAggregatorManager.aidl \
         src/android/bordeaux/services/ILearning_MulticlassPA.aidl \
+        src/android/bordeaux/services/IPredictor.aidl \
         src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl \
-        src/android/bordeaux/services/IBordeauxService.aidl
+        src/android/bordeaux/services/IBordeauxService.aidl \
 
 LOCAL_STATIC_JAVA_LIBRARIES := bordeaux_learners
+LOCAL_JNI_SHARED_LIBRARIES := libbordeaux
+LOCAL_REQUIRED_MODULES := libbordeaux
 
 LOCAL_PACKAGE_NAME := bordeaux
 
-LOCAL_SDK_VERSION := current
 
 include $(BUILD_PACKAGE)
 
@@ -29,13 +32,15 @@
 LOCAL_SRC_FILES += \
         src/android/bordeaux/services/IntFloat.java \
         src/android/bordeaux/services/StringFloat.java \
+        src/android/bordeaux/services/StringString.java \
         src/android/bordeaux/services/BordeauxClassifier.java \
         src/android/bordeaux/services/BordeauxRanker.java \
+        src/android/bordeaux/services/BordeauxPredictor.java \
+        src/android/bordeaux/services/BordeauxAggregatorManager.java \
         src/android/bordeaux/services/BordeauxManagerService.java \
-        src/android/bordeaux/services/IBordeauxLearner.java \
-        src/android/bordeaux/services/Learning_StochasticLinearRanker.java \
-        src/android/bordeaux/services/StochasticLinearRankerWithPrior.java \
         src/android/bordeaux/services/IBordeauxServiceCallback.aidl \
+        src/android/bordeaux/services/IAggregatorManager.aidl \
+        src/android/bordeaux/services/IPredictor.aidl \
         src/android/bordeaux/services/ILearning_MulticlassPA.aidl \
         src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl \
         src/android/bordeaux/services/IBordeauxService.aidl \
@@ -47,5 +52,29 @@
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
+## Building the whole Bordeaux service
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += \
+        src/android/bordeaux/services/IBordeauxServiceCallback.aidl \
+        src/android/bordeaux/services/IAggregatorManager.aidl \
+        src/android/bordeaux/services/ILearning_MulticlassPA.aidl \
+        src/android/bordeaux/services/IPredictor.aidl \
+        src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl \
+        src/android/bordeaux/services/IBordeauxService.aidl \
+
+LOCAL_STATIC_JAVA_LIBRARIES := bordeaux_learners
+LOCAL_JNI_SHARED_LIBRARIES := libbordeaux
+
+LOCAL_JAVA_RESOURCE_DIRS := res
+LOCAL_MODULE := bordeaux_whole_service
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
 # Use the folloing include to make our test apk.
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/bordeaux/service/src/android/bordeaux/services/Aggregator.java b/bordeaux/service/src/android/bordeaux/services/Aggregator.java
new file mode 100644
index 0000000..a5aced0
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/Aggregator.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import java.util.Map;
+
+abstract class Aggregator {
+    protected AggregatorManager mAggregatorManager;
+    public void setManager(AggregatorManager m) {
+        mAggregatorManager = m;
+    }
+    abstract public String[] getListOfFeatures();
+    abstract public Map<String,String> getFeatureValue(String featureName);
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java b/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
new file mode 100644
index 0000000..42ccf9f
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+
+import android.bordeaux.services.StringString;
+import android.content.Context;
+import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ArrayList;
+
+class AggregatorManager extends IAggregatorManager.Stub  {
+    private final String TAG = "AggregatorMnager";
+    private static HashMap<String, Aggregator> sFeatureMap;
+    private static AggregatorManager mManager = null;
+
+    private AggregatorManager() {
+        sFeatureMap = new HashMap<String, Aggregator>();
+    }
+
+    public static AggregatorManager getInstance() {
+        if (mManager == null )
+            mManager = new AggregatorManager();
+        return mManager;
+    }
+
+    public String[] getListOfFeatures() {
+        String[] s = new String[sFeatureMap.size()];
+        int i = 0;
+        for (Map.Entry<String, Aggregator> x : sFeatureMap.entrySet()) {
+           s[i] = x.getKey();
+           i++;
+        }
+        return s;
+    }
+
+    public void registerAggregator(Aggregator agg, AggregatorManager m) {
+        agg.setManager(m);
+        String[] fl = agg.getListOfFeatures();
+        for ( int i  = 0; i< fl.length; i ++)
+            sFeatureMap.put(fl[i], agg);
+    }
+
+    public ArrayList<StringString> getData(String dataName) {
+        return getList(getDataMap(dataName));
+    }
+
+    public Map<String, String> getDataMap(String dataName) {
+        if (sFeatureMap.get(dataName) != null)
+            return sFeatureMap.get(dataName).getFeatureValue(dataName);
+        else
+            Log.e(TAG, "There is no feature called " + dataName);
+        return null;
+    }
+
+    private ArrayList<StringString> getList(final Map<String, String> sample) {
+        ArrayList<StringString> StringString_sample = new ArrayList<StringString>();
+        for (Map.Entry<String, String> x : sample.entrySet()) {
+           StringString v = new StringString();
+           v.key = x.getKey();
+           v.value = x.getValue();
+           StringString_sample.add(v);
+        }
+        return StringString_sample;
+    }
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java b/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
new file mode 100644
index 0000000..a26e9cd
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import android.bordeaux.services.IAggregatorManager;
+import android.bordeaux.services.StringString;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/** AggregatorManger for Learning framework.
+ */
+public class BordeauxAggregatorManager {
+    static final String TAG = "BordeauxAggregatorManager";
+    static final String AggregatorManager_NOTAVAILABLE = "AggregatorManager not Available";
+    private Context mContext;
+    private IAggregatorManager mAggregatorManager;
+
+    public boolean retrieveAggregatorManager() {
+        if (mAggregatorManager == null)
+            mAggregatorManager = BordeauxManagerService.getAggregatorManager(mContext);
+        if (mAggregatorManager == null) {
+            Log.e(TAG, AggregatorManager_NOTAVAILABLE);
+            return false;
+        }
+        return true;
+    }
+
+    public BordeauxAggregatorManager (Context context) {
+        mContext = context;
+        mAggregatorManager = BordeauxManagerService.getAggregatorManager(mContext);
+    }
+
+    public Map<String, String> GetData(final String dataName) {
+        if (!retrieveAggregatorManager())
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        try {
+            return getMap(mAggregatorManager.getData(dataName));
+        } catch (RemoteException e) {
+            Log.e(TAG,"Exception in Getting " + dataName);
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        }
+    }
+
+    private Map<String, String> getMap(final List<StringString> sample) {
+        HashMap<String, String> m = new HashMap<String, String>();
+        for (int i =0; i < sample.size(); i++)
+            m.put(sample.get(i).key, sample.get(i).value);
+        return (Map) m;
+    }
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxManagerService.java b/bordeaux/service/src/android/bordeaux/services/BordeauxManagerService.java
index e136ca6..65ffdda 100644
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxManagerService.java
+++ b/bordeaux/service/src/android/bordeaux/services/BordeauxManagerService.java
@@ -44,6 +44,8 @@
     static private final String TAG = "BordeauxMangerService";
     static private IBordeauxService mService = null;
     static private ILearning_StochasticLinearRanker mRanker = null;
+    static private IAggregatorManager mAggregatorManager = null;
+    static private IPredictor mPredictor = null;
     static private ILearning_MulticlassPA mClassifier = null;
     static private boolean mStarted = false;
 
@@ -72,6 +74,33 @@
         return mService;
     }
 
+    static public synchronized IAggregatorManager getAggregatorManager(Context context) {
+        if (mService == null) {
+            bindServices(context);
+            return null;
+        }
+        try {
+            mAggregatorManager = IAggregatorManager.Stub.asInterface(
+                    mService.getAggregatorManager());
+        } catch (RemoteException e) {
+            mAggregatorManager = null;
+        }
+        return mAggregatorManager;
+    }
+
+    static public synchronized IPredictor getPredictor(Context context, String name) {
+        if (mService == null) {
+            bindServices(context);
+            return null;
+        }
+        try {
+            mPredictor = IPredictor.Stub.asInterface(mService.getPredictor(name));
+        } catch (RemoteException e) {
+            mPredictor = null;
+        }
+        return mPredictor;
+    }
+
     static public synchronized ILearning_StochasticLinearRanker
             getRanker(Context context, String name) {
         if (mService == null) {
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxPredictor.java b/bordeaux/service/src/android/bordeaux/services/BordeauxPredictor.java
new file mode 100644
index 0000000..cd0e57e
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/BordeauxPredictor.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import android.bordeaux.services.IPredictor;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Predictor for the Learning framework.
+ */
+public class BordeauxPredictor {
+    static final String TAG = "BordeauxPredictor";
+    static final String PREDICTOR_NOTAVAILABLE = "Predictor is not available.";
+    private Context mContext;
+    private String mName;
+    private IPredictor mPredictor;
+
+    public boolean retrievePredictor() {
+        if (mPredictor == null)
+            mPredictor = BordeauxManagerService.getPredictor(mContext, mName);
+        if (mPredictor == null) {
+            Log.e(TAG, PREDICTOR_NOTAVAILABLE);
+            return false;
+        }
+        return true;
+    }
+
+    public BordeauxPredictor(Context context) {
+        mContext = context;
+        mName = "defaultPredictor";
+        mPredictor = BordeauxManagerService.getPredictor(context, mName);
+    }
+
+    public BordeauxPredictor(Context context, String name) {
+        mContext = context;
+        mName = name;
+        mPredictor = BordeauxManagerService.getPredictor(context, mName);
+    }
+
+    public boolean reset() {
+        if (!retrievePredictor()){
+            Log.e(TAG, PREDICTOR_NOTAVAILABLE);
+            return false;
+        }
+        try {
+            mPredictor.ResetPredictor();
+            return true;
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    public void pushSample(String s) {
+        if (!retrievePredictor())
+            throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
+        try {
+            mPredictor.pushNewSample(s);
+        } catch (RemoteException e) {
+            Log.e(TAG,"Exception: pushing a new example");
+            throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
+        }
+    }
+
+    public float getProbability(String s) {
+        if (!retrievePredictor())
+            throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
+        try {
+            return mPredictor.getSampleProbability(s);
+        } catch (RemoteException e) {
+            Log.e(TAG,"Exception: getting sample probability");
+            throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
+        }
+    }
+
+    public boolean setParameter(String key, String value) {
+        if (!retrievePredictor())
+            throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
+        try {
+            return mPredictor.setPredictorParameter(key, value);
+        } catch (RemoteException e) {
+            Log.e(TAG,"Exception: setting predictor parameter");
+            throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
+        }
+    }
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxRanker.java b/bordeaux/service/src/android/bordeaux/services/BordeauxRanker.java
index 1977ce1..1ae5fcb 100644
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxRanker.java
+++ b/bordeaux/service/src/android/bordeaux/services/BordeauxRanker.java
@@ -132,7 +132,7 @@
         try {
             return mRanker.SetModelParameter(key, value);
         } catch (RemoteException e) {
-            Log.e(TAG,"Exception: scoring the sample with prior.");
+            Log.e(TAG,"Exception: Setting Parameter");
             throw new RuntimeException(RANKER_NOTAVAILABLE);
         }
     }
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxService.java b/bordeaux/service/src/android/bordeaux/services/BordeauxService.java
index 84a6df0..16bb78f 100644
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxService.java
+++ b/bordeaux/service/src/android/bordeaux/services/BordeauxService.java
@@ -39,7 +39,7 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import android.bordeaux.R;
+//import android.bordeaux.R;
 import android.util.Log;
 
 import java.io.*;
@@ -64,12 +64,24 @@
     NotificationManager mNotificationManager;
 
     BordeauxSessionManager mSessionManager;
+    AggregatorManager mAggregatorManager;
+    TimeStatsAggregator mTimeStatsAggregator;
+    LocationStatsAggregator mLocationStatsAggregator;
+    MotionStatsAggregator mMotionStatsAggregator;
 
     @Override
     public void onCreate() {
         Log.i(TAG, "Bordeaux service created.");
-        mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+        //mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
         mSessionManager = new BordeauxSessionManager(this);
+        mMotionStatsAggregator = new MotionStatsAggregator();
+        mLocationStatsAggregator = new LocationStatsAggregator();
+        mTimeStatsAggregator = new TimeStatsAggregator();
+        mAggregatorManager = AggregatorManager.getInstance();
+        mAggregatorManager.registerAggregator(mMotionStatsAggregator, mAggregatorManager);
+        mAggregatorManager.registerAggregator(mLocationStatsAggregator, mAggregatorManager);
+        mAggregatorManager.registerAggregator(mTimeStatsAggregator, mAggregatorManager);
+        //Log.i(TAG, "Bordeaux aggregators were registered");
 
         // Display a notification about us starting.
         // TODO: don't display the notification after the service is
@@ -84,10 +96,10 @@
         mSessionManager.saveSessions();
 
         // Cancel the persistent notification.
-        mNotificationManager.cancel(R.string.remote_service_started);
+        //mNotificationManager.cancel(R.string.remote_service_started);
 
         // Tell the user we stopped.
-        Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();
+        //Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();
 
         // Unregister all callbacks.
         mCallbacks.kill();
@@ -131,6 +143,14 @@
             return getLearningSession(Learning_StochasticLinearRanker.class, name);
         }
 
+        public IBinder getPredictor(String name) {
+            return getLearningSession(Predictor.class, name);
+        }
+
+        public IBinder getAggregatorManager() {
+            return (IBinder) mAggregatorManager;
+        }
+
         public void registerCallback(IBordeauxServiceCallback cb) {
             if (cb != null) mCallbacks.register(cb);
         }
@@ -151,7 +171,7 @@
      * automatically by the system).
      */
     private void showNotification() {
-        // In this sample, we'll use the same text for the ticker and the expanded notification
+        /*// In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(R.string.remote_service_started);
 
         // The PendingIntent to launch our activity if the user selects this notification
@@ -170,7 +190,7 @@
         Notification notification = builder.getNotification();
         // Send the notification.
         // We use a string id because it is a unique number.  We use it later to cancel.
-        mNotificationManager.notify(R.string.remote_service_started, notification);
+        mNotificationManager.notify(R.string.remote_service_started, notification); */
     }
 
 }
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxSessionStorage.java b/bordeaux/service/src/android/bordeaux/services/BordeauxSessionStorage.java
index 89aa370..9979d84 100644
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxSessionStorage.java
+++ b/bordeaux/service/src/android/bordeaux/services/BordeauxSessionStorage.java
@@ -116,13 +116,18 @@
         Cursor cursor = mDbSessions.query(true, SESSION_TABLE,
                 new String[]{COLUMN_KEY, COLUMN_CLASS, COLUMN_MODEL, COLUMN_TIME},
                 COLUMN_KEY + "=\"" + key + "\"", null, null, null, null, null);
-        if (cursor == null) return null;
-        if (cursor.getCount() == 0) return null;
+        if ((cursor == null) | (cursor.getCount() == 0)) {
+            cursor.close();
+            return null;
+        }
         if (cursor.getCount() > 1) {
+            cursor.close();
             throw new RuntimeException("Unexpected duplication in session table for key:" + key);
         }
         cursor.moveToFirst();
-        return getSessionFromCursor(cursor);
+        BordeauxSessionManager.Session s = getSessionFromCursor(cursor);
+        cursor.close();
+        return s;
     }
 
     void getAllSessions(ConcurrentHashMap<String, BordeauxSessionManager.Session> sessions) {
diff --git a/bordeaux/service/src/android/bordeaux/services/FeatureAssembly.java b/bordeaux/service/src/android/bordeaux/services/FeatureAssembly.java
new file mode 100644
index 0000000..8dae57c
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/FeatureAssembly.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import android.os.IBinder;
+import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Iterator;
+import android.bordeaux.services.AggregatorManager;
+import android.bordeaux.services.Aggregator;
+import java.io.Serializable;
+
+public class FeatureAssembly {
+    private static final String TAG = "FeatureAssembly";
+    private List<String> mPossibleFeatures;
+    private HashSet<String> mUseFeatures;
+    private AggregatorManager mAggregatorManager;
+
+    public FeatureAssembly() {
+        mAggregatorManager = AggregatorManager.getInstance();
+        mPossibleFeatures = Arrays.asList(mAggregatorManager.getListOfFeatures());
+        mUseFeatures = new HashSet<String>();
+    }
+
+    public boolean registerFeature(String s) {
+        boolean res = mPossibleFeatures.contains(s);
+        if (res){
+            if (!mUseFeatures.contains(s))
+                mUseFeatures.add(s);
+        }
+        return res;
+    }
+
+    public Set<String> getUsedFeatures() {
+        return (Set) mUseFeatures;
+    }
+
+    public String augmentFeatureInputString(String s) {
+        String fs = s;
+        Iterator itr = mUseFeatures.iterator();
+        while(itr.hasNext()) {
+            String f = (String) itr.next();
+            fs = fs + "+" + mAggregatorManager.getDataMap(f).get(f);
+        }
+        return fs;
+    }
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl b/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
new file mode 100644
index 0000000..65028be
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import android.bordeaux.services.StringString;
+
+interface IAggregatorManager {
+    List<StringString> getData(in String dataName);
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/IBordeauxService.aidl b/bordeaux/service/src/android/bordeaux/services/IBordeauxService.aidl
index 059d62e..4aa4f08 100644
--- a/bordeaux/service/src/android/bordeaux/services/IBordeauxService.aidl
+++ b/bordeaux/service/src/android/bordeaux/services/IBordeauxService.aidl
@@ -31,6 +31,12 @@
     */
     IBinder getClassifier(String name);
 
+    /* Request to access AggregatorManager
+    */
+    IBinder getAggregatorManager();
+    /* Request a Predictor
+    */
+    IBinder getPredictor(String name);
     /**
      * Often you want to allow a service to call back to its clients.
      * This shows how to do so, by registering a callback interface with
diff --git a/bordeaux/service/src/android/bordeaux/services/IPredictor.aidl b/bordeaux/service/src/android/bordeaux/services/IPredictor.aidl
new file mode 100644
index 0000000..d2f6036
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/IPredictor.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+interface IPredictor {
+    boolean setPredictorParameter( in String s, in String f );
+    void pushNewSample(in String s);
+    void ResetPredictor();
+    float getSampleProbability(in String s);
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/Learning_StochasticLinearRanker.java b/bordeaux/service/src/android/bordeaux/services/Learning_StochasticLinearRanker.java
index ab51f94..c648bd2 100644
--- a/bordeaux/service/src/android/bordeaux/services/Learning_StochasticLinearRanker.java
+++ b/bordeaux/service/src/android/bordeaux/services/Learning_StochasticLinearRanker.java
@@ -112,7 +112,6 @@
             objStream.writeObject(model);
             //return byteStream.toByteArray();
             byte[] bytes = byteStream.toByteArray();
-            Log.i(TAG, "getModel: " + bytes);
             return bytes;
         } catch (IOException e) {
             throw new RuntimeException("Can't get model");
@@ -128,7 +127,6 @@
             if (mLearningSlRanker == null)
                 mLearningSlRanker = new StochasticLinearRankerWithPrior();
             boolean res = mLearningSlRanker.loadModel(model);
-            Log.i(TAG, "LoadModel: " + modelData);
             return res;
         } catch (IOException e) {
             throw new RuntimeException("Can't load model");
diff --git a/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java b/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java
new file mode 100644
index 0000000..6294df8
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
+
+class LocationStatsAggregator extends Aggregator {
+    final String TAG = "LocationStatsAggregator";
+    public static final String CURRENT_LOCATION = "Current Location";
+    public String[] getListOfFeatures(){
+        String [] list = new String[1];
+        list[0] = CURRENT_LOCATION;
+        return list;
+    }
+    public Map<String,String> getFeatureValue(String featureName) {
+        HashMap<String,String> m = new HashMap<String,String>();
+        if (featureName.equals(CURRENT_LOCATION))
+            m.put(CURRENT_LOCATION, "Here");  //TODO put location resutls here
+        else
+            Log.e(TAG, "There is no Location feature called " + featureName);
+        return (Map) m;
+    }
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/MotionStatsAggregator.java b/bordeaux/service/src/android/bordeaux/services/MotionStatsAggregator.java
new file mode 100644
index 0000000..c9344fd
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/MotionStatsAggregator.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
+
+class MotionStatsAggregator extends Aggregator {
+    final String TAG = "MotionStatsAggregator";
+    public static final String CURRENT_MOTION = "Current Motion";
+    public String[] getListOfFeatures(){
+        String [] list = new String[1];
+        list[0] = CURRENT_MOTION;
+        return list;
+    }
+    public Map<String,String> getFeatureValue(String featureName) {
+        HashMap<String,String> m = new HashMap<String,String>();
+        if (featureName.equals(CURRENT_MOTION))
+            m.put(CURRENT_MOTION,"Running"); //TODO maybe use clustering for user motion
+        else
+            Log.e(TAG, "There is no motion feature called " + featureName);
+        return (Map) m;
+    }
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/Predictor.java b/bordeaux/service/src/android/bordeaux/services/Predictor.java
new file mode 100644
index 0000000..8bfd82e
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/Predictor.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import android.os.IBinder;
+import android.util.Log;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.io.Serializable;
+import java.io.*;
+import java.lang.Boolean;
+import android.bordeaux.services.FeatureAssembly;
+import android.bordeaux.learning.predictorHist;
+
+/**
+ * This is interface to implement Prediction based on histogram that
+ * uses predictor_histogram from learnerning section
+ */
+public class Predictor extends IPredictor.Stub
+        implements IBordeauxLearner {
+    private ModelChangeCallback modelChangeCallback = null;
+    private final String TAG = "Predictor";
+    private final String SET_EXPIRE_TIME = "SetExpireTime";
+    private final String USE_HISTORY = "Use History";
+    private final String SET_FEATURE = "Set Feature";
+    private long mExpireTime = 3 * 60;
+    private long mLastSampleTime = 0;
+    private boolean mUseHistoryFlag = false;
+    private final String NEW_START = "New Start";
+
+    static public class Model implements Serializable {
+        public HashMap<String, Integer> countHistogram = new HashMap<String, Integer>();
+        public HashSet<String> usedFeatures = new HashSet<String>();
+        public int sampleCounts;
+        public boolean useHistoryFlag;
+        public long expireTime;
+        public long lastSampleTime;
+    }
+
+    private predictorHist mPredictorHist = new predictorHist();
+    private String mLastSample = NEW_START;
+    public FeatureAssembly mFeatureAssembly = new FeatureAssembly();
+
+    /**
+     * Reset the Predictor
+     */
+    public void ResetPredictor(){
+        printModel(getPredictionModel());
+        mPredictorHist.ResetPredictorHist();
+        mUseHistoryFlag = false;
+        mLastSampleTime = 0;
+        mLastSample = NEW_START;
+        mFeatureAssembly = new FeatureAssembly();
+        printModel(getPredictionModel());
+        if (modelChangeCallback != null) {
+            modelChangeCallback.modelChanged(this);
+        }
+    }
+
+    /**
+     * Augment input string with buildin features such as time, location
+     */
+    private String buildDataPoint(String sampleName) {
+        String fs = mFeatureAssembly.augmentFeatureInputString(sampleName);
+        if (mUseHistoryFlag) {
+             if (((System.currentTimeMillis()- mLastSampleTime)/1000) > mExpireTime) {
+                 mLastSample  = NEW_START;
+             }
+             fs = fs + "+" + mLastSample;
+        }
+        return fs;
+    }
+
+    /**
+     * Input is a sampleName e.g.action name. This input is then augmented with requested build-in
+     * features such as time and location to create sampleFeatures. The sampleFeatures is then
+     * pushed to the histogram
+     */
+    public void pushNewSample(String sampleName) {
+        String sampleFeatures = buildDataPoint(sampleName);
+        mLastSample = sampleName;
+        mLastSampleTime = System.currentTimeMillis();
+        mPredictorHist.pushSample(sampleFeatures);
+        if (modelChangeCallback != null) {
+            modelChangeCallback.modelChanged(this);
+        }
+        //printModel(getPredictionModel());
+    }
+
+    /**
+     * return probabilty of an exmple using the histogram
+     */
+    public float getSampleProbability(String sampleName) {
+        String sampleFeatures = buildDataPoint(sampleName);
+        return mPredictorHist.getProbability(sampleFeatures);
+    }
+
+    /**
+     * Set parameters for 1) using History in probability estimations e.g. consider the last event
+     * and 2) featureAssembly e.g. time and location.
+     */
+    public boolean setPredictorParameter(String s, String f) {
+        boolean res = false;
+        if (s.equals(USE_HISTORY)) {
+            if (f.equals("true")){
+                mUseHistoryFlag = true;
+                res = true;
+            }
+            else if (f.equals("false")) {
+                mUseHistoryFlag = false;
+                res = true;
+            }
+        } else if (s.equals(SET_EXPIRE_TIME)) {
+            mExpireTime = Long.valueOf(f);
+            res = true;
+        } else if (s.equals(SET_FEATURE)) {
+            res = mFeatureAssembly.registerFeature(f);
+        }
+        if (!res)
+            Log.e(TAG,"Setting parameter " + s + " with " + f + " is not valid");
+        return res;
+    }
+
+    public Model getPredictionModel() {
+        Model m = new Model();
+        m.countHistogram.putAll(mPredictorHist.getHist());
+        m.sampleCounts = mPredictorHist.getHistCounts();
+        m.expireTime = mExpireTime;
+        m.usedFeatures = (HashSet) mFeatureAssembly.getUsedFeatures();
+        m.useHistoryFlag = mUseHistoryFlag;
+        m.lastSampleTime = mLastSampleTime;
+        return m;
+    }
+
+    public boolean loadModel(Model m) {
+        //Log.i(TAG,"on loadModel");
+        //printModel(m);
+        mPredictorHist = new predictorHist();
+        mPredictorHist.set(m.countHistogram);
+        mExpireTime = m.expireTime;
+        mUseHistoryFlag = m.useHistoryFlag;
+        mLastSampleTime = m.lastSampleTime;
+        mFeatureAssembly = new FeatureAssembly();
+        boolean res = false;
+        Iterator itr = m.usedFeatures.iterator();
+        while(itr.hasNext()) {
+            res = res & mFeatureAssembly.registerFeature((String) itr.next());
+        }
+        return res;
+    }
+
+    public void printModel(Model m) {
+        Log.i(TAG,"histogram is : " + m.countHistogram.toString());
+        Log.i(TAG,"number of counts in histogram is : " + m.sampleCounts);
+        Log.i(TAG,"ExpireTime time is : " + m.expireTime);
+        Log.i(TAG,"useHistoryFlag is : " + m.useHistoryFlag);
+        Log.i(TAG,"used features are : " + m.usedFeatures.toString());
+    }
+
+    // Beginning of the IBordeauxLearner Interface implementation
+    public byte [] getModel() {
+        Model model = getPredictionModel();
+        //Log.i(TAG,"on getModel");
+        printModel(model);
+        try {
+            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+            ObjectOutputStream objStream = new ObjectOutputStream(byteStream);
+            objStream.writeObject(model);
+            byte[] bytes = byteStream.toByteArray();
+            //Log.i(TAG, "getModel: " + bytes);
+            return bytes;
+        } catch (IOException e) {
+            throw new RuntimeException("Can't get model");
+        }
+    }
+
+    public boolean setModel(final byte [] modelData) {
+        //Log.i(TAG,"on setModel");
+        try {
+            ByteArrayInputStream input = new ByteArrayInputStream(modelData);
+            ObjectInputStream objStream = new ObjectInputStream(input);
+            Model model = (Model) objStream.readObject();
+            boolean res = loadModel(model);
+            //Log.i(TAG, "LoadModel: " + modelData);
+            return res;
+        } catch (IOException e) {
+            throw new RuntimeException("Can't load model");
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Learning class not found");
+        }
+    }
+
+    public IBinder getBinder() {
+        return this;
+    }
+
+    public void setModelChangeCallback(ModelChangeCallback callback) {
+        modelChangeCallback = callback;
+    }
+    // End of IBordeauxLearner Interface implemenation
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/StringString.aidl b/bordeaux/service/src/android/bordeaux/services/StringString.aidl
new file mode 100644
index 0000000..3cb89b9
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/StringString.aidl
@@ -0,0 +1,3 @@
+package android.bordeaux.services;
+
+parcelable StringString;
diff --git a/bordeaux/service/src/android/bordeaux/services/StringString.java b/bordeaux/service/src/android/bordeaux/services/StringString.java
new file mode 100644
index 0000000..109462e
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/StringString.java
@@ -0,0 +1,41 @@
+package android.bordeaux.services;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public final class StringString implements Parcelable {
+    public String key;
+    public String value;
+
+    public static final Parcelable.Creator<StringString>
+                        CREATOR = new Parcelable.Creator<StringString>() {
+        public StringString createFromParcel(Parcel in) {
+            return new StringString(in);
+        }
+
+        public StringString[] newArray(int size) {
+            return new StringString[size];
+        }
+    };
+
+    public StringString() {
+    }
+
+    private StringString(Parcel in) {
+        readFromParcel(in);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(key);
+        out.writeString(value);
+    }
+
+    public void readFromParcel(Parcel in) {
+        key  = in.readString();
+        value = in.readString();
+    }
+}
diff --git a/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java b/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java
new file mode 100644
index 0000000..8626189
--- /dev/null
+++ b/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 android.bordeaux.services;
+
+import java.util.Date;
+import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
+
+class TimeStatsAggregator extends Aggregator {
+    final String TAG = "TimeStatsAggregator";
+    public static final String CURRENT_TIME = "Current Time";
+    final String EARLY_MORNING = "EarlyMorning";
+    final String MORNING = "Morning";
+    final String NOON = "Noon";
+    final String AFTERNOON = "AfterNoon";
+    final String NIGHT = "Night";
+    final String LATE_NIGHT = "LateNight";
+
+    public String[] getListOfFeatures(){
+        String [] list = new String[1];
+        list[0] = CURRENT_TIME;
+        return list;
+    }
+
+    public Map<String,String> getFeatureValue(String featureName) {
+        HashMap<String,String> m = new HashMap<String,String>();
+        if (featureName.equals(CURRENT_TIME))
+            m.put(CURRENT_TIME, getCurrentTimeLabel());
+        else
+            Log.e(TAG, "There is no Time feature called " + featureName);
+        return (Map) m;
+    }
+
+    private String getCurrentTimeLabel(){
+        Date  d = new Date(System.currentTimeMillis());
+        String t = "";  //TODO maybe learn thresholds
+        int h = d.getHours();
+        if ((h > 5) & (h <= 7) )
+            t = EARLY_MORNING;
+        else if ((h > 7) & (h <= 11) )
+            t = MORNING;
+        else if ((h > 11) & (h <= 15))
+            t = NOON;
+        else if ((h > 15) & (h <= 20))
+            t = AFTERNOON;
+        else if ((h > 20) & (h <= 24))
+            t = NIGHT;
+        else if ((h > 0) & (h <= 5))
+            t = LATE_NIGHT;
+        return t;
+    }
+}