ret_val->printout();
                }
                else {
-                       log_error("Could not read data log for device: %s\n", device_id.c_str());
+                       log_error("%s: Could not read data log for device %s. Data not found.\n",
+                               date_param->to_string().c_str(),
+                               device_id.c_str());
                }
        }
        else {
-               log_error("Could not read data log for device: %s\n", device_id.c_str());
+               log_error("%s: Could not read data log for device: %s. Memory allocation error..\n",
+                       date_param->to_string().c_str(),
+                       device_id.c_str());
        }
        delete(store);
        return ret_val;
        ret_val = NULL;
        date    = start_date->clone();
        while(date->before_or_equal_year(end_date)) {
-               data    = get_yearly_summary(date);
-               if (data != NULL) {
-                       if (ret_val == NULL) {
-                               ret_val = new DataRange(data);
-                       }
-                       else {
-                               ret_val->add(data);
+               if (StoreDay::exist_in_year(device_id, date, false)) {
+                       data    = get_yearly_summary(date);
+                       if (data != NULL) {
+                               if (ret_val == NULL) {
+                                       ret_val = new DataRange(data);
+                               }
+                               else {
+                                       ret_val->add(data);
+                               }
+                               delete(data);
                        }
-                       delete(data);
                }
                date->next_year();
        }
        ret_val = NULL;
        date    = start_date->clone();
        while(date->before_or_equal_month(end_date)) {
-               data    = get_monthly_summary(date);
-               if (data != NULL) {
-                       if (ret_val == NULL) {
-                               ret_val = new DataRange(data);
-                       }
-                       else {
-                               ret_val->add(data);
+               if (StoreDay::exist_in_month(device_id, date, false)) {
+                       data    = get_monthly_summary(date);
+                       if (data != NULL) {
+                               if (ret_val == NULL) {
+                                       ret_val = new DataRange(data);
+                               }
+                               else {
+                                       ret_val->add(data);
+                               }
+                               delete(data);
                        }
-                       delete(data);
+                       date->next_month();
                }
-               date->next_month();
        }
        delete(date);
        return ret_val;
        ret_val = NULL;
        date    = start_date->clone();
        while(date->before_or_equal_day(end_date)) {
-               data    = get_daily_summary(date);
-               if (data != NULL) {
-                       if (ret_val == NULL) {
-                               ret_val = new DataRange(data);
-                       }
-                       else {
-                               ret_val->add(data);
+               if (StoreDay::exist(device_id, date, false)) {
+                       data    = get_daily_summary(date);
+                       if (data != NULL) {
+                               if (ret_val == NULL) {
+                                       ret_val = new DataRange(data);
+                               }
+                               else {
+                                       ret_val->add(data);
+                               }
+                               delete(data);
                        }
-                       delete(data);
                }
                date->next_day();
        }
 
 #include <time.h>
 
 namespace plp {
+       /**
+        * DataReader is able to read old data from the device.
+        */
        class DataReader {
                public:
                        DataReader(std::string device_id);
 
        }
 }
 
+bool Date::is_last_day_of_month() {
+       bool ret_val;
+       int days_in_month;
+
+       days_in_month = -1;
+       if ((month > 0) &&
+           (month <= 12)) {
+               days_in_month = CONST__DAYS_PER_MONTH[month - 1];
+               if ((month == 2) &&
+                   (is_leap_year() == true)) {
+                       days_in_month = 29;
+               }
+       }
+       ret_val = (day == days_in_month);
+       //log_debug("ret_val: %d", ret_val);
+       return ret_val;
+}
+
 void Date::next_day() {
        if ((month > 0) &&
            (month <= 12)) {
 
                        virtual ~Date();
                        void printout();
                        bool is_leap_year();
+                       bool is_last_day_of_month();
                        void next_second();
                        void next_min();
                        void next_hour();
 
 using namespace plp;
 
 DeviceData::DeviceData(string id_param, string type_param) : Device(id_param, type_param) {
+       _latest_data    = NULL;
 }
 
 DeviceData::DeviceData(string id_param,
 
        return ret_val;
 }
 
-bool FileUtil::file_exist(const char *file_name_with_path, bool writable) {
+bool FileUtil::file_exist(const char *file_name_with_path,
+                       bool writable) {
        bool ret_val;
        int acl_mode;
 
        return ret_val;
 }
 
+bool FileUtil::dir_exist(const char *dir_name_with_path,
+                       bool writable) {
+       bool ret_val;
+       struct stat st;
+       bool is_dir;
+
+       ret_val = false;
+       if (stat(dir_name_with_path, &st) == 0) {
+               is_dir = S_ISDIR(st.st_mode);
+               if (is_dir == true) {
+                       if (writable == false) {
+                               // check only the read permission
+                               ret_val = ((st.st_mode) & S_IRUSR);
+
+                       }
+                       else {
+                               // check also the write permission
+                               ret_val = ((st.st_mode) & S_IWUSR);
+                       }
+/*
+                       int acl_mode;
+                       if (writable == true) {
+                               acl_mode        = W_OK;
+                       }
+                       else {
+                               acl_mode        = R_OK;
+                       }
+                       if (dir_name_with_path != NULL) {
+                               if (access(dir_name_with_path, acl_mode) == 0) {
+                               }
+                       }
+*/
+               }
+       }
+       return ret_val;
+}
+
 bool FileUtil::mkfile(const char *file_name_with_path, bool writable) {
        bool ret_val;
        string path_name;
 
                         * Check whether file exist with specified access rights
                         */
                        static bool file_exist(const char *file_name_with_path, bool writable);
+                       static bool dir_exist(const char *dir_name_with_path, bool writable);
                        static std::ofstream *open_for_writing(const char *path);
        };
 }
 
 using namespace plp;
 
 namespace plp {
+       /**
+        * This class defines methods for Device which can return and collect data.
+        */
        class SensorDevice : public Device {
                public:
                        SensorDevice(std::string id_param, std::string type_param) : Device(id_param, type_param) {}
                        virtual ~SensorDevice() {}
-                       virtual const DataReader *get_device_data() = 0;
+                       /*
+                        * Returns DataReader class for the device.
+                        */
+                       virtual const DataReader *get_datareader() = 0;
+                       /**
+                        * Returns the unit used by the device data.
+                        */
                        virtual string get_unit() = 0;
+                       /*
+                        * Returns latest data that is available for the device.
+                        */
                        virtual plp::Data *get_data() = 0;
        };
 }
 
                                        res_data        = NULL;
                                        cnt             = 0;
                                        val_cnt         = 0;
+                                       dr              = NULL;
                                        while(cur_date->before(max_date)) {
                                                if (period_type_param == PERIOD_YEARLY) {
                                                        store   = new StoreCache(device_id, cur_date);
                                                        dr      = store->get_mean(PERIOD_MONTHLY);
                                                }
                                                else {
-                                                       store   = new StoreDay(device_id, cur_date);
-                                                       dr      = store->get_mean(PERIOD_DAILY);
+                                                       if (StoreDay::exist(device_id, cur_date, false)) {
+                                                               store   = new StoreDay(device_id, cur_date);
+                                                               dr      = store->get_mean(PERIOD_DAILY);
+                                                       }
+                                                       if (dr == NULL) {
+                                                               // data not found for that day, try to find next date containing data
+                                                               StoreDay::get_next_date_with_data(device_id,
+                                                                                       cur_date,
+                                                                                       max_date);
+                                                               continue;
+                                                       }
                                                }
                                                if (dr != NULL) {
                                                        cur_data        = dr->get_first();
                        case PERIOD_DAILY:
                        case PERIOD_HOURLY:
                        case PERIOD_MINUTELY:
-                       case PERIOD_SECONDLY: {
+                       case PERIOD_SECONDLY:
+                               if (StoreDay::exist(device_id, date, false)) {
                                        StoreDay        *store;
 
                                        store   = new StoreDay(device_id, date);
                                        ret_val = store->get_mean(period_type_param);
-                                       if ((period_type_param != PERIOD_MINUTELY) ||
+                                       if ((ret_val != NULL) &&
+                                           (period_type_param != PERIOD_MINUTELY) &&
                                            (period_type_param != PERIOD_SECONDLY)) {
                                                // no need cache second or minute data
                                                save(fname, ret_val, 4);
                                                        dr      = store->get_sum(PERIOD_MONTHLY);
                                                }
                                                else {
-                                                       store   = new StoreDay(device_id, cur_date);
-                                                       dr      = store->get_sum(PERIOD_DAILY);
+                                                       if (StoreDay::exist(device_id, cur_date, false)) {
+                                                               store   = new StoreDay(device_id, cur_date);
+                                                               dr      = store->get_sum(PERIOD_DAILY);
+                                                       }
+                                                       if (dr == NULL) {
+                                                               // data not found for that day, try to find next date containing data
+                                                               StoreDay::get_next_date_with_data(device_id,
+                                                                                               cur_date,
+                                                                                               max_date);
+                                                               continue;
+                                                       }
                                                }
                                                if (dr != NULL) {
                                                        cur_data        = dr->get_first();
                        case PERIOD_HOURLY:
                        case PERIOD_MINUTELY:
                        case PERIOD_SECONDLY:
-                               store   = new StoreDay(device_id, date);
-                               ret_val = store->get_sum(period_type_param);
-                               if ((period_type_param != PERIOD_MINUTELY) ||
-                                   (period_type_param != PERIOD_SECONDLY)) {
-                                       // no need cache second or minute data
-                                       save(fname, ret_val, 4);
+                               if (StoreDay::exist(device_id, date, false)) {
+                                       store   = new StoreDay(device_id, date);
+                                       ret_val = store->get_sum(period_type_param);
+                                       if ((ret_val != NULL) &&
+                                           (period_type_param != PERIOD_MINUTELY) &&
+                                           (period_type_param != PERIOD_SECONDLY)) {
+                                               // no need cache second or minute data
+                                               save(fname, ret_val, 4);
+                                       }
+                                       delete(store);
                                }
-                               delete(store);
                                break;
                }
        }
                                        Data    *last_data;
                                        Data    *cur_data;
                                        Date    *cur_date;
-                                       Date    *limit_date;
+                                       Date    *max_date;
                                        int     ii;
                                        int     cnt;
 
                                        cur_date        = date->clone();
-                                       limit_date      = date->clone();
-                                       limit_date->next_month();
+                                       max_date        = date->clone();
+                                       max_date->next_month();
                                        first_data      = NULL;
                                        last_data       = NULL;
-                                       while(cur_date->before(limit_date)) {
-                                               store   = new StoreDay(device_id, cur_date);
-                                               if (first_data == NULL) {
-                                                       cur_data        = store->get_oldest_data();
+                                       while(cur_date->before(max_date)) {
+                                               if (StoreDay::exist(device_id,
+                                                               cur_date,
+                                                               false)) {
+                                                       store   = new StoreDay(device_id, cur_date);
+                                                       if (first_data == NULL) {
+                                                               cur_data        = store->get_oldest_data();
+                                                               if (cur_data != NULL) {
+                                                                       first_data      = cur_data->clone();
+                                                                       last_data       = cur_data->clone();
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       cur_data        = store->get_latest_data();
                                                        if (cur_data != NULL) {
-                                                               first_data      = cur_data->clone();
-                                                               last_data       = cur_data->clone();
-                                                               delete(cur_data);
+                                                               if (last_data != NULL) {
+                                                                       delete(last_data);
+                                                               }
+                                                               last_data       = cur_data;
                                                        }
+                                                       delete(store);
+                                                       cur_date->next_day();
                                                }
-                                               cur_data        = store->get_latest_data();
-                                               if (cur_data != NULL) {
-                                                       if (last_data != NULL) {
-                                                               delete(last_data);
-                                                       }
-                                                       last_data       = cur_data;
+                                               else {
+                                                       // data not found for that day, try to find next date containing data
+                                                       StoreDay::get_next_date_with_data(device_id,
+                                                                               cur_date,
+                                                                               max_date);
                                                }
-                                               delete(store);
-                                               cur_date->next_day();
                                        }
                                        delete(cur_date);
-                                       delete(limit_date);
+                                       delete(max_date);
                                        if (first_data != NULL) {
                                                if (last_data == NULL) {
                                                        last_data       = first_data->clone();
                        case PERIOD_HOURLY:
                        case PERIOD_MINUTELY:
                        case PERIOD_SECONDLY:
-                               store   = new StoreDay(device_id, date);
-                               ret_val = store->get_delta(period_type_param);
-                               if ((period_type_param != PERIOD_MINUTELY) ||
-                                   (period_type_param != PERIOD_SECONDLY)) {
-                                       // no need cache second or minute data
-                                       save(fname, ret_val, 4);
+                               if (StoreDay::exist(device_id, date, false)) {
+                                       store   = new StoreDay(device_id, date);
+                                       ret_val = store->get_delta(period_type_param);
+                                       if ((period_type_param != PERIOD_MINUTELY) ||
+                                           (period_type_param != PERIOD_SECONDLY)) {
+                                               // no need cache second or minute data
+                                               save(fname, ret_val, 4);
+                                       }
+                                       delete(store);
                                }
-                               delete(store);
                                break;
                }
        }
                                                        dr      = store->get_max(PERIOD_MONTHLY);
                                                }
                                                else {
-                                                       store   = new StoreDay(device_id, cur_date);
-                                                       dr      = store->get_max(PERIOD_DAILY);
+                                                       if (StoreDay::exist(device_id, cur_date, false)) {
+                                                               store   = new StoreDay(device_id, cur_date);
+                                                               dr      = store->get_max(PERIOD_DAILY);
+                                                       }
+                                                       else {
+                                                               StoreDay::get_next_date_with_data(device_id,
+                                                                                               cur_date,
+                                                                                               max_date);
+                                                               continue;
+                                                       }
                                                }
                                                if (dr != NULL) {
                                                        cur_data        = dr->get_first();
                        case PERIOD_HOURLY:
                        case PERIOD_MINUTELY:
                        case PERIOD_SECONDLY:
-                               store   = new StoreDay(device_id, date);
-                               ret_val = store->get_max(period_type_param);
-                               if ((period_type_param != PERIOD_MINUTELY) ||
-                                   (period_type_param != PERIOD_SECONDLY)) {
-                                       // no need cache second or minute data
-                                       save(fname, ret_val, 4);
+                               if (StoreDay::exist(device_id, date, false)) {
+                                       store   = new StoreDay(device_id, date);
+                                       ret_val = store->get_max(period_type_param);
+                                       if ((period_type_param != PERIOD_MINUTELY) ||
+                                           (period_type_param != PERIOD_SECONDLY)) {
+                                               // no need cache second or minute data
+                                               save(fname, ret_val, 4);
+                                       }
+                                       delete(store);
                                }
-                               delete(store);
                                break;
                }
        }
                                                        dr      = store->get_min(PERIOD_MONTHLY);
                                                }
                                                else {
-                                                       store   = new StoreDay(device_id, cur_date);
-                                                       dr      = store->get_min(PERIOD_DAILY);
+                                                       if (StoreDay::exist(device_id, cur_date, false)) {
+                                                               store   = new StoreDay(device_id, cur_date);
+                                                               dr      = store->get_min(PERIOD_DAILY);
+                                                       }
+                                                       else {
+                                                               StoreDay::get_next_date_with_data(device_id,
+                                                                                               cur_date,
+                                                                                               max_date);
+                                                               continue;
+                                                       }
                                                }
                                                if (dr != NULL) {
                                                        cur_data        = dr->get_first();
                        case PERIOD_HOURLY:
                        case PERIOD_MINUTELY:
                        case PERIOD_SECONDLY:
-                               store   = new StoreDay(device_id, date);
-                               ret_val = store->get_min(period_type_param);
-                               if ((period_type_param != PERIOD_MINUTELY) ||
-                                   (period_type_param != PERIOD_SECONDLY)) {
-                                       // no need cache second or minute data
-                                       save(fname, ret_val, 4);
+                               if (StoreDay::exist(device_id, date, false)) {
+                                       store   = new StoreDay(device_id, date);
+                                       ret_val = store->get_min(period_type_param);
+                                       if ((period_type_param != PERIOD_MINUTELY) ||
+                                           (period_type_param != PERIOD_SECONDLY)) {
+                                               // no need cache second or minute data
+                                               save(fname, ret_val, 4);
+                                       }
+                                       delete(store);
                                }
-                               delete(store);
                                break;
                }
        }
        }
 }
 
-Data *StoreCache::get_oldest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) {
+Data *StoreCache::get_oldest_data(Date *date_param,
+                       string device_id_param,
+                       EnumSummaryPeriod period_type_param) {
        int             size;
        unsigned int    ii;
        string          year_dr;
        return ret_val;
 }
 
-Data *StoreCache::get_latest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) {
+Data *StoreCache::get_latest_data(Date *date_param,
+                       string device_id_param,
+                       EnumSummaryPeriod period_type_param) {
        int             ii;
        string          mon_dr;
        vector<string>  mon_vcr;
 
        }
 }
 
-string StoreDay::get_dir_name(string device_id, Date *date_time_param) {
+string StoreDay::get_year_dir_name(string device_id,
+                               Date *date_time_param) {
+       string  ret_val;
+       char    buffer[10];
+       string  bd_name;
+
+       snprintf(buffer, 10, "%d", date_time_param->year);
+       bd_name = DeviceConfig::get_base_dir_name();
+       bd_name = FileUtil::concat_paths(bd_name, device_id);
+       ret_val = bd_name + "/" + buffer;
+       return ret_val;
+}
+
+string StoreDay::get_dir_name(string device_id,
+                       Date *date_time_param) {
        string  ret_val;
        char    buffer[30];
        string  bd_name;
        return ret_val;
 }
 
-string StoreDay::get_file_name(string device_id, Date *date_time_param) {
+string StoreDay::get_file_name(string device_id,
+                       Date *date_time_param) {
        string  ret_val;
        string  fname;
        char    buffer[30];
 
-       snprintf(buffer, 30, "%d-%02d-%02d", date_time_param->year, date_time_param->month, date_time_param->day);
+       snprintf(buffer,
+               30,
+               "%d-%02d-%02d",
+               date_time_param->year,
+               date_time_param->month,
+               date_time_param->day);
        fname   = buffer;
        fname   = fname + DATAFILE_SUFFIX;
        ret_val = get_dir_name(device_id, date_time_param);
        return Store::load(store_fname);
 }
 
-bool StoreDay::exist(string fname_param) {
+bool StoreDay::exist(string fname_param, bool writable) {
+       bool    ret_val;
+       ret_val = FileUtil::file_exist(fname_param.c_str(), writable);
+       return ret_val;
+}
+
+bool StoreDay::exist(string dev_id_param,
+               Date *date,
+               bool writable) {
+       bool    ret_val;
+       string  f_name;
+
+       f_name  = get_file_name(dev_id_param, date);
+       ret_val = FileUtil::file_exist(f_name.c_str(), writable);
+       return ret_val;
+}
+
+bool StoreDay::exist_in_month(string dev_id_param,
+                       Date *date,
+                       bool writable) {
+       string  dirname;
+       bool    ret_val;
+
+       dirname = StoreDay::get_dir_name(dev_id_param, date);
+       ret_val = FileUtil::dir_exist(dirname.c_str(), writable);
+       return ret_val;
+}
+
+bool StoreDay::exist_in_year(string dev_id_param,
+                       Date *date,
+                       bool writable) {
+       string  dirname;
        bool    ret_val;
-       ret_val = (access(fname_param.c_str(), F_OK) == 0);
+
+       dirname = StoreDay::get_year_dir_name(dev_id_param, date);
+       ret_val = FileUtil::dir_exist(dirname.c_str(), writable);
        return ret_val;
 }
 
-bool StoreDay::exist() {
-       return exist(store_fname);
+bool StoreDay::exist(bool writable) {
+       return exist(store_fname, writable);
 }
 
 static int get_summary_period_as_freq_seconds(EnumSummaryPeriod period_type_param) {
        Date            date;
        DataRange       *ret_val;
        int             frq_sec;
+       bool            succ;
 
-       ret_val = new DataRange();
+       ret_val = NULL;
        calc    = NULL;
        limit_d = NULL;
        frq_sec = get_summary_period_as_freq_seconds(period_type_param);
        if (store_data == NULL) {
-               load();
+               succ    = load();
        }
-       if (store_data != NULL) {
+       if ((succ == true) &&
+           (store_data != NULL)) {
                row_count       = store_data->get_count();
                if (row_count > 0) {
                        col_count       = store_data->get_data_item_value_count();
                        if (col_count > 0) {
+                               ret_val = new DataRange();
                                for (ii = 0; ii < row_count; ii++) {
                                        data    = store_data->get(ii);
                                        if (data != NULL) {
                                                        limit_d->sec    = 0;
                                                        limit_d->inc_seconds(frq_sec);
                                                }
-                                               else {
-                                                       date    = data->get_date();
-                                                       if ((ii <= (row_count -1)) &&
-                                                           ((frq_sec == -1) || (date.before(limit_d)))) {
-                                                               for (jj = 0; jj < col_count; jj++) {
-                                                                       calc->value_arr[jj]     = calc->value_arr[jj] + data->value_arr[jj];
-                                                               }
+                                               date    = data->get_date();
+                                               if ((ii <= (row_count -1)) &&
+                                                   ((frq_sec == -1) || (date.before(limit_d)))) {
+                                                       for (jj = 0; jj < col_count; jj++) {
+                                                               calc->value_arr[jj]     = calc->value_arr[jj] + data->value_arr[jj];
                                                        }
-                                                       if ((ii >= (row_count -1)) ||
-                                                           ((frq_sec != -1) && (date.before(limit_d) == false))) {
-                                                               ret_val->add(calc);
-                                                               delete(calc);
-                                                               calc    = data->clone();
-                                                               if (limit_d != NULL) {
-                                                                       delete(limit_d);
-                                                               }
-                                                               limit_d         = data->get_date().clone();
-                                                               limit_d->min    = 0;
-                                                               limit_d->sec    = 0;
-                                                               limit_d->inc_seconds(frq_sec);
+                                               }
+                                               if ((ii >= (row_count -1)) ||
+                                                   ((frq_sec != -1) && (date.before(limit_d) == false))) {
+                                                       ret_val->add(calc);
+                                                       delete(calc);
+                                                       calc    = data->clone();
+                                                       if (limit_d != NULL) {
+                                                               delete(limit_d);
                                                        }
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       limit_d->sec    = 0;
+                                                       limit_d->inc_seconds(frq_sec);
                                                }
                                                delete(data);
                                        }
        Date            date;
        DataRange       *ret_val;
        int             frq_sec;
+       bool            succ;
 
-       ret_val = new DataRange();
+       ret_val = NULL;
        calc    = NULL;
        limit_d = NULL;
        d_count = 1;
        frq_sec = get_summary_period_as_freq_seconds(period_type_param);
        if (store_data == NULL) {
-               load();
+               succ    = load();
        }
-       if (store_data != NULL) {
+       if ((succ == true) &&
+           (store_data != NULL)) {
                row_count       = store_data->get_count();
                if (row_count > 0) {
                        col_count       = store_data->get_data_item_value_count();
                        if (col_count > 0) {
+                               ret_val = new DataRange();
                                for (ii = 0; ii < row_count; ii++) {
                                        data    = store_data->get(ii);
                                        if (data != NULL) {
                                                        limit_d->sec    = 0;
                                                        limit_d->inc_seconds(frq_sec);
                                                }
-                                               else {
-                                                       date    = data->get_date();
-                                                       if ((ii <= (row_count -1)) &&
-                                                           ((frq_sec == -1) || (date.before(limit_d)))) {
-                                                               for (jj = 0; jj < col_count; jj++) {
-                                                                       calc->value_arr[jj]     = calc->value_arr[jj] + data->value_arr[jj];
-                                                               }
-                                                               d_count++;
+                                               date    = data->get_date();
+                                               if ((ii <= (row_count -1)) &&
+                                                   ((frq_sec == -1) || (date.before(limit_d)))) {
+                                                       for (jj = 0; jj < col_count; jj++) {
+                                                               calc->value_arr[jj]     = calc->value_arr[jj] + data->value_arr[jj];
                                                        }
-                                                       if ((ii >= (row_count -1)) ||
-                                                           ((frq_sec != -1) && (date.before(limit_d) == false))) {
-                                                               for (jj = 0; jj < col_count; jj++) {
-                                                                       calc->value_arr[jj]     = calc->value_arr[jj] / d_count;
-                                                               }
-                                                               ret_val->add(calc);
-                                                               delete(calc);
-                                                               d_count         = 1;
-                                                               calc            = data->clone();
-                                                               if (limit_d != NULL) {
-                                                                       delete(limit_d);
-                                                               }
-                                                               limit_d         = data->get_date().clone();
-                                                               limit_d->min    = 0;
-                                                               limit_d->sec    = 0;
-                                                               limit_d->inc_seconds(frq_sec);
+                                                       d_count++;
+                                               }
+                                               if ((ii >= (row_count -1)) ||
+                                                   ((frq_sec != -1) && (date.before(limit_d) == false))) {
+                                                       for (jj = 0; jj < col_count; jj++) {
+                                                               calc->value_arr[jj]     = calc->value_arr[jj] / d_count;
                                                        }
+                                                       ret_val->add(calc);
+                                                       delete(calc);
+                                                       d_count         = 1;
+                                                       calc            = data->clone();
+                                                       if (limit_d != NULL) {
+                                                               delete(limit_d);
+                                                       }
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       limit_d->sec    = 0;
+                                                       limit_d->inc_seconds(frq_sec);
                                                }
                                                delete(data);
                                        }
        Date            date;
        DataRange       *ret_val;
        int             frq_sec;
+       bool            succ;
 
-       ret_val = new DataRange();
+       ret_val = NULL;
        calc1   = NULL;
        calc2   = NULL;
        limit_d = NULL;
        frq_sec = get_summary_period_as_freq_seconds(period_type_param);
        if (store_data == NULL) {
-               load();
+               succ    = load();
        }
-       if (store_data != NULL) {
+       if ((succ == true) &&
+           (store_data != NULL)) {
                row_count       = store_data->get_count();
                if (row_count > 0) {
                        col_count       = store_data->get_data_item_value_count();
                        if (col_count > 0) {
+                               ret_val = new DataRange();
                                for (ii = 0; ii < row_count; ii++) {
                                        data    = store_data->get(ii);
                                        if (data != NULL) {
                                                        }
                                                        calc2           = NULL;
                                                }
-                                               else {
-                                                       date    = data->get_date();
-                                                       if ((ii <= (row_count -1)) &&
-                                                           ((frq_sec == -1) || (date.before(limit_d)))) {
-                                                               if (calc2 != NULL) {
-                                                                       delete(calc2);
-                                                               }
-                                                               calc2   = data->clone();
-                                                       }
-                                                       if ((ii >= (row_count -1)) ||
-                                                           ((frq_sec != -1) && (date.before(limit_d) == false))) {
-                                                               if (calc2 == NULL) {
-                                                                       calc2   = calc1->clone();
-                                                               }
-                                                               for (jj = 0; jj < col_count; jj++) {
-                                                                       calc2->value_arr[jj]    = calc2->value_arr[jj] - calc1->value_arr[jj];
-                                                               }
-                                                               ret_val->add(calc2);
-                                                               delete(calc1);
-                                                               calc1   = data->clone();
+                                               date    = data->get_date();
+                                               if ((ii <= (row_count -1)) &&
+                                                   ((frq_sec == -1) || (date.before(limit_d)))) {
+                                                       if (calc2 != NULL) {
                                                                delete(calc2);
-                                                               calc2   = NULL;
-                                                               if (limit_d != NULL) {
-                                                                       delete(limit_d);
-                                                               }
-                                                               limit_d         = data->get_date().clone();
-                                                               limit_d->min    = 0;
-                                                               limit_d->sec    = 0;
-                                                               limit_d->inc_seconds(frq_sec);
                                                        }
+                                                       calc2   = data->clone();
+                                               }
+                                               if ((ii >= (row_count -1)) ||
+                                                   ((frq_sec != -1) && (date.before(limit_d) == false))) {
+                                                       if (calc2 == NULL) {
+                                                               calc2   = calc1->clone();
+                                                       }
+                                                       for (jj = 0; jj < col_count; jj++) {
+                                                               calc2->value_arr[jj]    = calc2->value_arr[jj] - calc1->value_arr[jj];
+                                                       }
+                                                       ret_val->add(calc2);
+                                                       delete(calc1);
+                                                       calc1   = data->clone();
+                                                       delete(calc2);
+                                                       calc2   = NULL;
+                                                       if (limit_d != NULL) {
+                                                               delete(limit_d);
+                                                       }
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       limit_d->sec    = 0;
+                                                       limit_d->inc_seconds(frq_sec);
                                                }
                                                delete(data);
                                        }
        Date            date;
        DataRange       *ret_val;
        int             frq_sec;
+       bool            succ;
 
-       ret_val = new DataRange();
+       ret_val = NULL;
        calc    = NULL;
        limit_d = NULL;
        frq_sec = get_summary_period_as_freq_seconds(period_type_param);
        if (store_data == NULL) {
-               load();
+               succ    = load();
        }
-       if (store_data != NULL) {
+       if ((succ == true) &&
+           (store_data != NULL)) {
                row_count       = store_data->get_count();
                if (row_count > 0) {
                        col_count       = store_data->get_data_item_value_count();
                        if (col_count > 0) {
+                               ret_val = new DataRange();
                                for (ii = 0; ii < row_count; ii++) {
                                        data    = store_data->get(ii);
                                        if (data != NULL) {
                                                        limit_d->sec    = 0;
                                                        limit_d->inc_seconds(frq_sec);
                                                }
-                                               else {
-                                                       date    = data->get_date();
-                                                       if ((ii <= (row_count -1)) &&
-                                                           ((frq_sec == -1) || (date.before(limit_d)))) {
-                                                               int changed = 0;
-                                                               if (max == true) {
-                                                                       for (jj = 0; jj < col_count; jj++) {
-                                                                               if (calc->value_arr[jj] < data->value_arr[jj]) {
-                                                                                       calc->value_arr[jj]     = data->value_arr[jj];
-                                                                                       changed = 1;
-                                                                               }
+                                               date    = data->get_date();
+                                               if ((ii <= (row_count -1)) &&
+                                                   ((frq_sec == -1) || (date.before(limit_d)))) {
+                                                       int changed = 0;
+                                                       if (max == true) {
+                                                               for (jj = 0; jj < col_count; jj++) {
+                                                                       if (calc->value_arr[jj] < data->value_arr[jj]) {
+                                                                               calc->value_arr[jj]     = data->value_arr[jj];
+                                                                               changed = 1;
                                                                        }
                                                                }
-                                                               else {
-                                                                       for (jj = 0; jj < col_count; jj++) {
-                                                                               if (data->value_arr[jj] < calc->value_arr[jj]) {
-                                                                                       calc->value_arr[jj]     = data->value_arr[jj];
-                                                                                       changed = 1;
-                                                                               }
+                                                       }
+                                                       else {
+                                                               for (jj = 0; jj < col_count; jj++) {
+                                                                       if (data->value_arr[jj] < calc->value_arr[jj]) {
+                                                                               calc->value_arr[jj]     = data->value_arr[jj];
+                                                                               changed = 1;
                                                                        }
                                                                }
-                                                               if (changed == 1) {
-                                                                       Date new_date;
+                                                       }
+                                                       if (changed == 1) {
+                                                               Date new_date;
 
-                                                                       new_date        = data->get_date();
-                                                                       calc->set_date(&new_date);
-                                                               }
+                                                               new_date        = data->get_date();
+                                                               calc->set_date(&new_date);
                                                        }
-                                                       if ((ii >= (row_count -1)) ||
-                                                           ((frq_sec != -1) && (date.before(limit_d) == false))) {
-                                                               ret_val->add(calc);
-                                                               delete(calc);
-                                                               calc    = data->clone();
-                                                               if (limit_d != NULL) {
-                                                                       delete(limit_d);
-                                                               }
-                                                               limit_d         = data->get_date().clone();
-                                                               limit_d->min    = 0;
-                                                               limit_d->sec    = 0;
-                                                               limit_d->inc_seconds(frq_sec);
+                                               }
+                                               if ((ii >= (row_count -1)) ||
+                                                   ((frq_sec != -1) && (date.before(limit_d) == false))) {
+                                                       ret_val->add(calc);
+                                                       delete(calc);
+                                                       calc    = data->clone();
+                                                       if (limit_d != NULL) {
+                                                               delete(limit_d);
                                                        }
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       limit_d->sec    = 0;
+                                                       limit_d->inc_seconds(frq_sec);
                                                }
                                                delete(data);
                                        }
        }
        return ret_val;
 }
+
+bool StoreDay::data_day_scan_days_in_month(string dev_id_param,
+                               Date *new_date,
+                               Date *max_date) {
+       bool    ret_val;
+       string  fname;
+
+       ret_val = false;
+       while((ret_val == false) &&
+             (new_date->before(max_date))) {
+               new_date->next_day();
+               fname   = get_file_name(dev_id_param, new_date);
+               if (exist(fname, false) == true) {
+                       ret_val = true;
+                       break;
+               }
+               if (new_date->is_last_day_of_month() == true) {
+                       break;
+               }
+       }
+       return ret_val;
+}
+
+bool StoreDay::data_day_scan_month_in_year(string dev_id_param,
+                               Date *new_date,
+                               Date *max_date) {
+       bool    ret_val;
+
+       ret_val = false;
+       // next scan months dir existence under the first year
+       while((ret_val == false) &&
+             (new_date->before(max_date))) {
+               new_date->next_month();
+               if (exist_in_month(dev_id_param,
+                               new_date,
+                               false)) {
+                       ret_val = data_day_scan_days_in_month(dev_id_param,
+                                                       new_date,
+                                                       max_date);
+                       if (ret_val == true)
+                               break;
+               }
+               if (new_date->month == 12)
+                       break;
+       }
+       return ret_val;
+}
+
+bool StoreDay::data_day_scan_years(string dev_id_param,
+                       Date *new_date,
+                       Date *max_date) {
+       bool    ret_val;
+
+       ret_val = false;
+       while((ret_val == false) &&
+             (new_date->before(max_date))) {
+               new_date->next_year();
+               if (exist_in_year(dev_id_param,
+                               new_date,
+                               false)) {
+                       ret_val = data_day_scan_month_in_year(dev_id_param,
+                                                       new_date,
+                                                       max_date);
+                       if (ret_val == true)
+                               break;
+               }
+       }
+       return ret_val;
+}
+
+bool StoreDay::get_next_date_with_data(std::string dev_id_param,
+                               plp::Date *next_date,
+                               plp::Date *max_date) {
+       bool    ret_val;
+       Date    *new_date;
+       string  fname;
+       string  dirname;
+
+       new_date        = next_date->clone();
+       // scan first dates in current month
+       ret_val         = data_day_scan_days_in_month(dev_id_param,
+                                               new_date,
+                                               max_date);
+       if (ret_val == false) {
+               ret_val = data_day_scan_month_in_year(dev_id_param,
+                                               new_date,
+                                               max_date);
+               if (ret_val == false) {
+                       ret_val = data_day_scan_years(dev_id_param,
+                                               new_date,
+                                               max_date);
+               }
+       }
+       if (ret_val == true)
+               new_date->copy(next_date);
+       else
+               max_date->copy(next_date);
+       delete(new_date);
+       return ret_val;
+}
 
                        /*
                         * Checks whether store file exist.
                         */
-                       bool exist();
+                       bool exist(bool writable);
+                       static bool exist(std::string dev_id,
+                                       plp::Date *date,
+                                       bool writable);
+                       static bool exist_in_month(string device_id,
+                                               Date *date,
+                                               bool writable);
+                       static bool exist_in_year(string device_id,
+                                               Date *date,
+                                               bool writable);
+                       static bool get_next_date_with_data(std::string device_id,
+                                                       plp::Date *next_date,
+                                                       plp::Date *max_date);
                protected:
                        std::string     store_fname;
                        bool load();
                        plp::DataRange *get_max_or_min(EnumSummaryPeriod period_type_param, bool max);
                        static std::string get_dir_name(std::string device_id,
                                                        plp::Date *date_time_param);
+                       static std::string get_year_dir_name(std::string device_id,
+                                                       plp::Date *date_time_param);
                        static std::string get_file_name(std::string device_id,
                                                        plp::Date *date_time_param);
                        plp::DataRange *get_oldest_and_latest_data(std::string fname_param);
-                       bool exist(std::string fname_param);
+                       /**
+                        * Check whether the given file exist and has either read or write permissions.
+                        */
+                       static bool exist(std::string fname_param, bool writable);
+                       /**
+                        * Go through days in month to find out whether daily data file exist.
+                        *
+                        * If data is not found, false is returned and last scanned date is set to next_date.
+                        * If data is found true is returned and date is set to next_date.
+                        */
+                       static bool data_day_scan_days_in_month(string dev_id_param,
+                                                       Date *next_date,
+                                                       Date *max_date);
+                       /**
+                        * Go through month dir in year to find out first date with data
+                        * after the given date.
+                        *
+                        * If data is not found, false is returned and last scanned date is set to next_date.
+                        * If data is found true is returned and date is set to next_date.
+                        */
+                       static bool data_day_scan_month_in_year(string dev_id_param,
+                                                       Date *next_date,
+                                                       Date *max_date);
+                       /**
+                        * Go through year and month directories to find out first date with data
+                        * after the given date.
+                        *
+                        * If data is not found, false is returned and last scanned date is set to next_date.
+                        * If data is found true is returned and date is set to next_date.
+                        */
+                       static bool data_day_scan_years(string dev_id_param,
+                                               Date *next_date,
+                                               Date *max_date);
        };
 }