public JsonResult GetPosAndNegTagActivity(String iIntervalStart, String iIntervalEnd, String iGranularity, String culture, String scope)
        {
            try
            {
                DateTime intervalStart = DateTime.ParseExact(iIntervalStart, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                DateTime intervalEnd = DateTime.ParseExact(iIntervalEnd, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                intervalEnd = intervalEnd.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

                IEnumerable<WorkingPoint> workingPoints = mEFInterface.GetWorkingPointsForAUser(scope, User.Identity.Name, context);
                Dictionary<DateTime, ChartValue> resultPositiveTagsInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                Dictionary<DateTime, ChartValue> resultNegativeTagsInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                Dictionary<DateTime, ChartValue> resultRemovePositiveTagsInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                Dictionary<DateTime, ChartValue> resultRemoveNegativeTagsInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                foreach (var wp in workingPoints)
                {
                    foreach (var conv in wp.Conversations)
                    {
                        if (!conv.Client.isSupportClient)
                        {
                            if (iGranularity.Equals(Constants.DAY_GRANULARITY))
                            {
                                // Test if conversation had activity in that period.
                                var allMsg = (from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd) select msg).Count();
                                if (allMsg > 0)
                                {
                                    var convEvents = from convEvent in conv.ConversationEvents
                                                     where ((convEvent.EventTypeName.Equals(Constants.POS_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.POS_REMOVE_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_REMOVE_EVENT)) &&
                                                     (convEvent.Date >= intervalStart && convEvent.Date <= intervalEnd))
                                                     group convEvent by new { occurDate = convEvent.Date.Date, eventType = convEvent.EventTypeName }
                                                         into g
                                                         select new { key = g.Key, count = g.Count() };
                                    foreach (var convEvent in convEvents)
                                    {
                                        if (convEvent.key.eventType.Equals(Constants.POS_ADD_EVENT))
                                        {
                                            resultPositiveTagsInterval[convEvent.key.occurDate].value += convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.NEG_ADD_EVENT))
                                        {
                                            resultNegativeTagsInterval[convEvent.key.occurDate].value += convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.POS_REMOVE_EVENT))
                                        {
                                            resultRemovePositiveTagsInterval[convEvent.key.occurDate].value -= convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.NEG_REMOVE_EVENT))
                                        {
                                            resultRemoveNegativeTagsInterval[convEvent.key.occurDate].value -= convEvent.count;
                                        }
                                    }

                                }
                            }
                            else if (iGranularity.Equals(Constants.MONTH_GRANULARITY))
                            {
                                // Test if conversation had activity in that period.
                                var allMsg = (from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd) select msg).Count();
                                if (allMsg > 0)
                                {
                                    var convEvents = from convEvent in conv.ConversationEvents
                                                     where ((convEvent.EventTypeName.Equals(Constants.POS_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.POS_REMOVE_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_REMOVE_EVENT)) &&
                                                     (convEvent.Date >= intervalStart && convEvent.Date <= intervalEnd))
                                                     group convEvent by new { Month = convEvent.Date.Month, Year = convEvent.Date.Year, eventType = convEvent.EventTypeName }
                                                         into g
                                                         select new { key = g.Key, count = g.Count() };
                                    foreach (var convEvent in convEvents)
                                    {
                                        var monthDateTime = new DateTime(convEvent.key.Year, convEvent.key.Month, 1);
                                        if (convEvent.key.eventType.Equals(Constants.POS_ADD_EVENT))
                                        {
                                            if (DateTime.Compare(monthDateTime, intervalStart) < 0)
                                                resultPositiveTagsInterval[intervalStart].value += convEvent.count;
                                            else
                                                resultPositiveTagsInterval[monthDateTime].value += convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.NEG_ADD_EVENT))
                                        {
                                            if (DateTime.Compare(monthDateTime, intervalStart) < 0)
                                                resultNegativeTagsInterval[intervalStart].value += convEvent.count;
                                            else
                                                resultNegativeTagsInterval[monthDateTime].value += convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.POS_REMOVE_EVENT))
                                        {
                                            if (DateTime.Compare(monthDateTime, intervalStart) < 0)
                                                resultRemovePositiveTagsInterval[intervalStart].value -= convEvent.count;
                                            else
                                                resultRemovePositiveTagsInterval[monthDateTime].value -= convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.NEG_REMOVE_EVENT))
                                        {
                                            if (DateTime.Compare(monthDateTime, intervalStart) < 0)
                                                resultRemoveNegativeTagsInterval[intervalStart].value -= convEvent.count;
                                            else
                                                resultRemoveNegativeTagsInterval[monthDateTime].value -= convEvent.count;
                                        }
                                    }
                                }
                            }
                            else if (iGranularity.Equals(Constants.WEEK_GRANULARITY))
                            {
                                // Test if conversation had activity in that period.
                                var allMsg = (from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd) select msg).Count();
                                if (allMsg > 0)
                                {
                                    var convEvents = from convEvent in conv.ConversationEvents
                                                     where ((convEvent.EventTypeName.Equals(Constants.POS_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.POS_REMOVE_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_REMOVE_EVENT)) &&
                                                     (convEvent.Date >= intervalStart && convEvent.Date <= intervalEnd))
                                                     group convEvent by new { firstDayOfTheWeek = FirstDayOfWeekUtility.GetFirstDayOfWeek(convEvent.Date), eventType = convEvent.EventTypeName }
                                                         into g
                                                         select new { key = g.Key, count = g.Count() };
                                    foreach (var convEvent in convEvents)
                                    {
                                        var weekDateTime = convEvent.key.firstDayOfTheWeek;
                                        if (convEvent.key.eventType.Equals(Constants.POS_ADD_EVENT))
                                        {
                                            if (DateTime.Compare(weekDateTime, intervalStart) < 0)
                                                resultPositiveTagsInterval[intervalStart].value += convEvent.count;
                                            else
                                                resultPositiveTagsInterval[weekDateTime].value += convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.NEG_ADD_EVENT))
                                        {
                                            if (DateTime.Compare(weekDateTime, intervalStart) < 0)
                                                resultNegativeTagsInterval[intervalStart].value += convEvent.count;
                                            else
                                                resultNegativeTagsInterval[weekDateTime].value += convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.POS_REMOVE_EVENT))
                                        {
                                            if (DateTime.Compare(weekDateTime, intervalStart) < 0)
                                                resultRemovePositiveTagsInterval[intervalStart].value -= convEvent.count;
                                            else
                                                resultRemovePositiveTagsInterval[weekDateTime].value -= convEvent.count;
                                        }
                                        else if (convEvent.key.eventType.Equals(Constants.NEG_REMOVE_EVENT))
                                        {
                                            if (DateTime.Compare(weekDateTime, intervalStart) < 0)
                                                resultRemoveNegativeTagsInterval[intervalStart].value -= convEvent.count;
                                            else
                                                resultRemoveNegativeTagsInterval[weekDateTime].value -= convEvent.count;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                List<Dictionary<DateTime, ChartValue>> content = new List<Dictionary<DateTime, ChartValue>>();
                content.Add(resultPositiveTagsInterval);
                content.Add(resultNegativeTagsInterval);
                content.Add(resultRemovePositiveTagsInterval);
                content.Add(resultRemoveNegativeTagsInterval);
                RepChartData chartSource = new RepChartData(new RepDataColumn[] {
                    new RepDataColumn("16", Constants.STRING_COLUMN_TYPE, "Date"),
                    new RepDataColumn("17", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepPosFeedbackAdded),
                    new RepDataColumn("18", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepNegFeedbackAdded),
                    new RepDataColumn("19", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepPosFeedbackRemoved),
                    new RepDataColumn("20", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepNegFeedbackRemoved) },
                    PrepareJson(content, Resources.Global.RepConversationsUnit));
                return Json(chartSource, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                logger.Error("GetPosAndNegTagActivity", e);
            }
            return Json("Request failed", JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetPosAndNegTagEvolution(String iIntervalStart, String iIntervalEnd, String iGranularity, String culture, String scope)
        {
            try
            {
                DateTime intervalStart = DateTime.ParseExact(iIntervalStart, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                DateTime intervalEnd = DateTime.ParseExact(iIntervalEnd, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                intervalEnd = intervalEnd.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

                IEnumerable<WorkingPoint> workingPoints = mEFInterface.GetWorkingPointsForAUser(scope, User.Identity.Name, context);
                Dictionary<DateTime, ChartValue> resultPositiveTagsInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                Dictionary<DateTime, ChartValue> resultNegativeTagsInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                int posFeedback = 0;
                int negFeedback = 0;
                int posFeedbackEvolution, negFeedbackEvolution;
                foreach (var wp in workingPoints)
                {
                    foreach (var conv in wp.Conversations)
                    {
                        if (!conv.Client.isSupportClient)
                        {
                            // Test if conversation had activity in that period.
                            var allMsg = (from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd) select msg).Count();
                            if (allMsg > 0)
                            {
                                var pastEvents = (from convEvent in conv.ConversationEvents
                                                  where ((convEvent.EventTypeName.Equals(Constants.POS_ADD_EVENT) ||
                                                  convEvent.EventTypeName.Equals(Constants.NEG_ADD_EVENT) ||
                                                  convEvent.EventTypeName.Equals(Constants.NEG_TO_POS_EVENT) ||
                                                  convEvent.EventTypeName.Equals(Constants.POS_TO_NEG_EVENT)) &&
                                                  convEvent.Date < intervalStart)
                                                  group convEvent by new { eventDate = convEvent.Date, eventType = convEvent.EventTypeName } into g
                                                  select new { key = g.Key, count = g.Count() }).OrderByDescending(c => c.key.eventDate);

                                if (pastEvents.Count() > 0)
                                {
                                    var pastEvent = pastEvents.First();
                                    if (pastEvent.key.eventType.Equals(Constants.POS_ADD_EVENT)) posFeedback += pastEvent.count;
                                    else if (pastEvent.key.eventType.Equals(Constants.NEG_ADD_EVENT)) negFeedback += pastEvent.count;
                                    else if (pastEvent.key.eventType.Equals(Constants.POS_TO_NEG_EVENT)) { negFeedback += pastEvent.count; }
                                    else if (pastEvent.key.eventType.Equals(Constants.NEG_TO_POS_EVENT)) { posFeedback += pastEvent.count; }
                                }
                            }
                        }

                    }
                }
                posFeedbackEvolution = posFeedback;
                negFeedbackEvolution = negFeedback;
                List<EventCounter> allEvents = new List<EventCounter>();

                foreach (var wp in workingPoints)
                {
                    foreach (var conv in wp.Conversations)
                    {
                        if (!conv.Client.isSupportClient)
                        {
                            var allMsg = (from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd) select msg).Count();
                            if (allMsg > 0)
                            {
                                if (iGranularity.Equals(Constants.DAY_GRANULARITY))
                                {

                                    var convEvents = (from convEvent in conv.ConversationEvents
                                                      where ((convEvent.EventTypeName.Equals(Constants.POS_ADD_EVENT) ||
                                                      convEvent.EventTypeName.Equals(Constants.NEG_ADD_EVENT) ||
                                                      convEvent.EventTypeName.Equals(Constants.POS_REMOVE_EVENT) ||
                                                      convEvent.EventTypeName.Equals(Constants.NEG_REMOVE_EVENT) ||
                                                      convEvent.EventTypeName.Equals(Constants.NEG_TO_POS_EVENT) ||
                                                      convEvent.EventTypeName.Equals(Constants.POS_TO_NEG_EVENT)) &&
                                                      convEvent.Date >= intervalStart && convEvent.Date <= intervalEnd)
                                                      group convEvent by new { occurDate = convEvent.Date.Date, eventType = convEvent.EventTypeName } into g
                                                      select new EventCounter(new Event(g.Key.occurDate, g.Key.eventType), g.Count()));
                                    if (convEvents.Count() > 0) allEvents.AddRange(convEvents.ToList<EventCounter>());
                                }
                                else if (iGranularity.Equals(Constants.MONTH_GRANULARITY))
                                {
                                    var convEvents = from convEvent in conv.ConversationEvents
                                                     where ((convEvent.EventTypeName.Equals(Constants.POS_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.POS_REMOVE_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_REMOVE_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_TO_POS_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.POS_TO_NEG_EVENT)) &&
                                                     convEvent.Date >= intervalStart && convEvent.Date <= intervalEnd)
                                                     group convEvent by new { Month = convEvent.Date.Month, Year = convEvent.Date.Year, eventType = convEvent.EventTypeName } into g
                                                     select new EventCounter(new Event((new DateTime(g.Key.Year, g.Key.Month, 1).CompareTo(intervalStart) < 0 ? intervalStart : new DateTime(g.Key.Year, g.Key.Month, 1)), g.Key.eventType), g.Count());
                                    if (convEvents.Count() > 0) allEvents.AddRange(convEvents.ToList<EventCounter>());
                                }
                                else if (iGranularity.Equals(Constants.WEEK_GRANULARITY))
                                {
                                    var convEvents = from convEvent in conv.ConversationEvents
                                                     where ((convEvent.EventTypeName.Equals(Constants.POS_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_ADD_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.POS_REMOVE_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_REMOVE_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.NEG_TO_POS_EVENT) ||
                                                     convEvent.EventTypeName.Equals(Constants.POS_TO_NEG_EVENT)) &&
                                                     convEvent.Date >= intervalStart && convEvent.Date <= intervalEnd)
                                                     group convEvent by new { firstDayOfTheWeek = FirstDayOfWeekUtility.GetFirstDayOfWeek(convEvent.Date), eventType = convEvent.EventTypeName } into g
                                                     select new EventCounter(new Event((g.Key.firstDayOfTheWeek.CompareTo(intervalStart) < 0 ? intervalStart : g.Key.firstDayOfTheWeek), g.Key.eventType), g.Count());
                                    if (convEvents.Count() > 0) allEvents.AddRange(convEvents.ToList<EventCounter>());
                                }
                            }
                        }
                    }
                }

                IEnumerable<EventCounter> allEventsOrdered = allEvents.OrderBy(c => c.eventItem.occurDate);
                foreach (var convEvent in allEventsOrdered)
                {
                    if (convEvent.eventItem.eventType.Equals(Constants.POS_ADD_EVENT)) posFeedbackEvolution += convEvent.counter;
                    else if (convEvent.eventItem.eventType.Equals(Constants.NEG_ADD_EVENT)) negFeedbackEvolution += convEvent.counter;
                    else if (convEvent.eventItem.eventType.Equals(Constants.POS_TO_NEG_EVENT))
                    {
                        negFeedbackEvolution += convEvent.counter;
                        posFeedbackEvolution -= convEvent.counter;
                    }
                    else if (convEvent.eventItem.eventType.Equals(Constants.NEG_TO_POS_EVENT))
                    {
                        posFeedbackEvolution += convEvent.counter;
                        negFeedbackEvolution -= convEvent.counter;
                    }
                    else if (convEvent.eventItem.eventType.Equals(Constants.POS_REMOVE_EVENT)) { posFeedbackEvolution -= convEvent.counter; }
                    else if (convEvent.eventItem.eventType.Equals(Constants.NEG_REMOVE_EVENT)) { negFeedbackEvolution -= convEvent.counter; }
                    resultNegativeTagsInterval[convEvent.eventItem.occurDate].value = negFeedbackEvolution;
                    resultNegativeTagsInterval[convEvent.eventItem.occurDate].changed = true;
                    resultPositiveTagsInterval[convEvent.eventItem.occurDate].value = posFeedbackEvolution;
                    resultPositiveTagsInterval[convEvent.eventItem.occurDate].changed = true;
                }

                if (!resultPositiveTagsInterval[intervalStart].changed)
                    resultPositiveTagsInterval[intervalStart].value = posFeedback;
                if (!resultNegativeTagsInterval[intervalStart].changed)
                    resultNegativeTagsInterval[intervalStart].value = negFeedback;
                if (iGranularity.Equals(Constants.DAY_GRANULARITY))
                {
                    for (var i = intervalStart.AddDays(1); i < intervalEnd; i = i.AddDays(1))
                    {
                        if (!resultPositiveTagsInterval[i].changed)
                            resultPositiveTagsInterval[i].value = resultPositiveTagsInterval[i.AddDays(-1)].value;
                        if (!resultNegativeTagsInterval[i].changed)
                            resultNegativeTagsInterval[i].value = resultNegativeTagsInterval[i.AddDays(-1)].value;

                    }
                }
                else if (iGranularity.Equals(Constants.MONTH_GRANULARITY))
                {
                    DateTime firstDayOfTheMonth = new DateTime(intervalStart.Year, intervalStart.Month, 1);
                    for (var i = firstDayOfTheMonth.AddMonths(1); i < intervalEnd; i = i.AddMonths(1))
                    {
                        if (i.Equals(firstDayOfTheMonth.AddMonths(1)))
                        {
                            if (!resultPositiveTagsInterval[i].changed)
                                resultPositiveTagsInterval[i].value = resultPositiveTagsInterval[intervalStart].value;
                            if (!resultNegativeTagsInterval[i].changed)
                                resultNegativeTagsInterval[i].value = resultNegativeTagsInterval[intervalStart].value;
                        }
                        else
                        {
                            if (!resultPositiveTagsInterval[i].changed)
                                resultPositiveTagsInterval[i].value = resultPositiveTagsInterval[i.AddMonths(-1)].value;
                            if (!resultNegativeTagsInterval[i].changed)
                                resultNegativeTagsInterval[i].value = resultNegativeTagsInterval[i.AddMonths(-1)].value;
                        }
                    }
                }
                else if (iGranularity.Equals(Constants.WEEK_GRANULARITY))
                {

                    Calendar calendar = CultureInfo.CurrentUICulture.Calendar;
                    for (var i = calendar.AddWeeks(FirstDayOfWeekUtility.GetFirstDayOfWeek(intervalStart), 1); i < intervalEnd; i = calendar.AddWeeks(i, 1))
                    {
                        if (i.Equals(calendar.AddWeeks(FirstDayOfWeekUtility.GetFirstDayOfWeek(intervalStart), 1)))
                        {
                            if (!resultPositiveTagsInterval[i].changed)
                                resultPositiveTagsInterval[i].value = resultPositiveTagsInterval[intervalStart].value;
                            if (!resultNegativeTagsInterval[i].changed)
                                resultNegativeTagsInterval[i].value = resultNegativeTagsInterval[intervalStart].value;
                        }
                        else
                        {
                            if (!resultPositiveTagsInterval[i].changed)
                                resultPositiveTagsInterval[i].value = resultPositiveTagsInterval[calendar.AddWeeks(i, -1)].value;
                            if (!resultNegativeTagsInterval[i].changed)
                                resultNegativeTagsInterval[i].value = resultNegativeTagsInterval[calendar.AddWeeks(i, -1)].value;
                        }
                    }
                }

                List<Dictionary<DateTime, ChartValue>> content = new List<Dictionary<DateTime, ChartValue>>();
                content.Add(resultPositiveTagsInterval);
                content.Add(resultNegativeTagsInterval);
                RepChartData chartSource = new RepChartData(new RepDataColumn[] {
                    new RepDataColumn("17", Constants.STRING_COLUMN_TYPE, "Date"),
                    new RepDataColumn("18", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepPositiveFeedback),
                    new RepDataColumn("18", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepNegativeFeedback) },
                    PrepareJson(content, Resources.Global.RepConversationsUnit));
                return Json(chartSource, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                logger.Error("GetPosAndNegTagEvolution", e);
            }
            return Json("Request failed", JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetNoOfConversationsByTagsChartSource(String iIntervalStart, String iIntervalEnd, String iGranularity, String culture, String scope)
        {
            try
            {
                DateTime intervalStart = DateTime.ParseExact(iIntervalStart, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                DateTime intervalEnd = DateTime.ParseExact(iIntervalEnd, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                intervalEnd = intervalEnd.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

                IEnumerable<WorkingPoint> workingPoints = mEFInterface.GetWorkingPointsForAUser(scope, User.Identity.Name, context);

                var tagsHash = GetNoOfConversationsByTags(intervalStart, intervalEnd, iGranularity, scope);

                // Prepare Json result
                var columnCounter = 0;
                var tagInterval = intervalStart.ToShortDateString() + " - " + intervalEnd.ToShortDateString();
                var headerContent = new List<RepDataColumn>();
                var rowContent = new List<RepDataRowCell>();

                rowContent.Add(new RepDataRowCell(tagInterval, tagInterval));
                headerContent.Add(new RepDataColumn(columnCounter.ToString(), "string", "Date"));

                if (tagsHash.Count > 0)
                {
                    foreach (var tagEntry in tagsHash)
                    {
                        ++columnCounter;
                        rowContent.Add(new RepDataRowCell(tagEntry.Value, tagEntry.Value.ToString() + " conversations"));
                        headerContent.Add(new RepDataColumn(columnCounter.ToString(), "number", tagEntry.Key));
                    }
                }
                else
                {
                    rowContent.Add(new RepDataRowCell(0, "No data for this period"));
                    headerContent.Add(new RepDataColumn("15", "number", Resources.Global.RepNoDataToDisplay));
                }

                RepChartData chartSource = new RepChartData(headerContent, new RepDataRow[] { new RepDataRow(rowContent) });
                return Json(chartSource, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                logger.Error("GetNoOfConversationsByTagsChartSource", e);
            }
            return Json("Request failed", JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetNewVsReturningClientsChartSource(String iIntervalStart, String iIntervalEnd, String iGranularity, String culture, String scope)
        {
            try
            {
                DateTime intervalStart = DateTime.ParseExact(iIntervalStart, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                DateTime intervalEnd = DateTime.ParseExact(iIntervalEnd, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                intervalEnd = intervalEnd.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

                IEnumerable<WorkingPoint> workingPoints = mEFInterface.GetWorkingPointsForAUser(scope, User.Identity.Name, context);

                Dictionary<DateTime, ChartValue> resultNewClientsInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                Dictionary<DateTime, ChartValue> resultReturningClientsInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);

                foreach (var wp in workingPoints)
                {
                    if (iGranularity.Equals(Constants.DAY_GRANULARITY))
                    {
                        var newClients = from conv in wp.Conversations where conv.StartTime > intervalStart & conv.StartTime < intervalEnd group conv by conv.StartTime.Date into convGroup select new { date = convGroup.Key, count = convGroup.Count() };
                        foreach (var newClient in newClients)
                        {
                            resultNewClientsInterval[newClient.date].value += newClient.count;
                        }

                        var returningClients = from conv in wp.Conversations where conv.StartTime < intervalStart select (from msg in conv.Messages where msg.TimeReceived > intervalStart & msg.TimeReceived < intervalEnd group conv by new { msg.TimeReceived.Date } into convGroup select new { date = convGroup.Key, count = convGroup.Count() });
                        foreach (var conv in returningClients)
                        {
                            foreach (var day in conv)
                            {
                                DateTime currentDay = day.date.Date;
                                resultReturningClientsInterval[currentDay].value += 1;
                            }
                        }
                    }
                    else if (iGranularity.Equals(Constants.MONTH_GRANULARITY))
                    {
                        var newClients = from conv in wp.Conversations where conv.StartTime > intervalStart & conv.StartTime < intervalEnd group conv by new { conv.StartTime.Month, conv.StartTime.Year } into convGroup select new { date = convGroup.Key, count = convGroup.Count() };
                        foreach (var entry in newClients)
                        {
                            var monthDateTime = new DateTime(entry.date.Year, entry.date.Month, 1);
                            if (DateTime.Compare(monthDateTime, intervalStart) < 0)
                                resultNewClientsInterval[intervalStart].value += entry.count;
                            else
                                resultNewClientsInterval[monthDateTime].value += entry.count;
                        }

                        var returningClients = from conv in wp.Conversations where conv.StartTime < intervalStart select (from msg in conv.Messages where msg.TimeReceived > intervalStart & msg.TimeReceived < intervalEnd group conv by new { msg.TimeReceived.Month, msg.TimeReceived.Year } into convGroup select new { date = convGroup.Key, count = convGroup.Count() });
                        foreach (var conv in returningClients)
                        {
                            foreach (var entry in conv)
                            {
                                var monthDateTime = new DateTime(entry.date.Year, entry.date.Month, 1);
                                if (DateTime.Compare(monthDateTime, intervalStart) < 0)
                                    resultReturningClientsInterval[intervalStart].value += 1;
                                else
                                    resultReturningClientsInterval[monthDateTime].value += 1;

                            }
                        }
                    }
                    else if (iGranularity.Equals(Constants.WEEK_GRANULARITY))
                    {
                        var newClients = from conv in wp.Conversations where conv.StartTime >= intervalStart & conv.StartTime <= intervalEnd group conv by new { firstDayOfTheWeek = FirstDayOfWeekUtility.GetFirstDayOfWeek(conv.StartTime) } into convGroup select new { date = convGroup.Key, count = convGroup.Count() };
                        foreach (var entry in newClients)
                        {
                            var weekDateTime = entry.date.firstDayOfTheWeek;
                            if (DateTime.Compare(weekDateTime, intervalStart) < 0)
                                resultNewClientsInterval[intervalStart].value += entry.count;
                            else
                                resultNewClientsInterval[weekDateTime].value += entry.count;
                        }

                        var returningClients = from conv in wp.Conversations where conv.StartTime < intervalStart select (from msg in conv.Messages where msg.TimeReceived > intervalStart & msg.TimeReceived < intervalEnd group conv by new { firstDayOfTheWeek = FirstDayOfWeekUtility.GetFirstDayOfWeek(msg.TimeReceived) } into convGroup select new { date = convGroup.Key, count = convGroup.Count() });
                        foreach (var conv in returningClients)
                        {
                            foreach (var entry in conv)
                            {
                                var weekDateTime = entry.date.firstDayOfTheWeek;
                                if (DateTime.Compare(weekDateTime, intervalStart) < 0)
                                    resultReturningClientsInterval[intervalStart].value += 1;
                                else
                                    resultReturningClientsInterval[weekDateTime].value += 1;
                            }
                        }
                    }
                }

                List<Dictionary<DateTime, ChartValue>> content = new List<Dictionary<DateTime, ChartValue>>();
                content.Add(resultNewClientsInterval);
                content.Add(resultReturningClientsInterval);

                RepChartData chartSource = new RepChartData(new RepDataColumn[] { new RepDataColumn("17", Constants.STRING_COLUMN_TYPE, "Date"), new RepDataColumn("18", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepNewClientsChart), new RepDataColumn("18", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepReturningClientsChart) }, PrepareJson(content, Resources.Global.RepClientsUnit));
                return Json(chartSource, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                logger.Error("GetNewVsReturningClientsChartSource", e);
            }
            return Json("Request failed", JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetIncomingOutgoingThirdArea(String iIntervalStart, String iIntervalEnd, String culture, String scope)
        {
            try
            {
                DateTime intervalStart = DateTime.ParseExact(iIntervalStart, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                DateTime intervalEnd = DateTime.ParseExact(iIntervalEnd, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                intervalEnd = intervalEnd.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

                IEnumerable<WorkingPoint> workingPoints = mEFInterface.GetWorkingPointsForAUser(scope, User.Identity.Name, context);

                var incomingNoOfSms = ComputeNoOfIncomingSms(intervalStart, intervalEnd, workingPoints);
                var outgoingNoOfSms = ComputeNoOfOutgoingSms(intervalStart, intervalEnd, workingPoints);

                // Prepare Json result
                var row1 = new RepDataRow(new RepDataRowCell[] { new RepDataRowCell(Resources.Global.RepIncomingSmsChart, Resources.Global.RepIncomingSmsChart), new RepDataRowCell(incomingNoOfSms, incomingNoOfSms + " sms") });
                var row2 = new RepDataRow(new RepDataRowCell[] { new RepDataRowCell(Resources.Global.RepOutgoingSmsChart, Resources.Global.RepOutgoingSmsChart), new RepDataRowCell(outgoingNoOfSms, outgoingNoOfSms + " sms") });
                List<RepDataRow> content = new List<RepDataRow>();
                content.Add(row1);
                content.Add(row2);
                RepChartData chartSource = new RepChartData(new RepDataColumn[] { new RepDataColumn("17", Constants.STRING_COLUMN_TYPE, Resources.Global.RepTypeTable), new RepDataColumn("18", Constants.STRING_COLUMN_TYPE, Resources.Global.RepValueTable) }, content);
                return Json(chartSource, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                logger.Error("GetIncomingOutgoingThirdArea", e);
            }
            return Json("Request failed", JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetIncomingOutgoingSmsChartSource(String iIntervalStart, String iIntervalEnd, String iGranularity, String culture, String scope)
        {
            try
            {
                DateTime intervalStart = DateTime.ParseExact(iIntervalStart, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                DateTime intervalEnd = DateTime.ParseExact(iIntervalEnd, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                intervalEnd = intervalEnd.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

                IEnumerable<WorkingPoint> workingPoints = mEFInterface.GetWorkingPointsForAUser(scope, User.Identity.Name, context);
                Dictionary<DateTime, ChartValue> resultIncomingInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                Dictionary<DateTime, ChartValue> resultOutgoingInterval = InitializeInterval(intervalStart, intervalEnd, iGranularity);
                foreach (var wp in workingPoints)
                {
                    var conversations = from conv in wp.Conversations select conv;
                    foreach (var conv in conversations)
                    {
                        if (iGranularity.Equals(Constants.DAY_GRANULARITY))
                        {
                            var msgsTo = from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd & (msg.To == wp.TelNumber || msg.To.StartsWith(wp.ShortID))) group msg by msg.TimeReceived.Date into g select new { date = g.Key, count = g.Count() };
                            foreach (var entry in msgsTo)
                            {
                                resultIncomingInterval[entry.date].value += entry.count;
                            }
                            var msgsFrom = from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd & (msg.From == wp.TelNumber || msg.From.StartsWith(wp.ShortID))) group msg by msg.TimeReceived.Date into g select new { date = g.Key, count = g.Count() };
                            foreach (var entry in msgsFrom)
                            {
                                resultOutgoingInterval[entry.date].value += entry.count;
                            }
                        }
                        else if (iGranularity.Equals(Constants.MONTH_GRANULARITY))
                        {
                            var msgsTo = from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd & (msg.To == wp.TelNumber || msg.To.StartsWith(wp.ShortID))) group msg by new { msg.TimeReceived.Month, msg.TimeReceived.Year } into g select new { date = g.Key, count = g.Count() };
                            var msgsFrom = from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd & (msg.From == wp.TelNumber ||msg.From.StartsWith(wp.ShortID))) group msg by new { msg.TimeReceived.Month, msg.TimeReceived.Year } into g select new { date = g.Key, count = g.Count() };
                            foreach (var entry in msgsTo)
                            {
                                var monthDateTime = new DateTime(entry.date.Year, entry.date.Month, 1);
                                if (DateTime.Compare(monthDateTime, intervalStart) < 0)
                                    resultIncomingInterval[intervalStart].value += entry.count;
                                else
                                    resultIncomingInterval[monthDateTime].value += entry.count;
                            }

                            foreach (var entry in msgsFrom)
                            {
                                var monthDateTime = new DateTime(entry.date.Year, entry.date.Month, 1);
                                if (DateTime.Compare(monthDateTime, intervalStart) < 0)
                                    resultOutgoingInterval[intervalStart].value += entry.count;
                                else
                                    resultOutgoingInterval[monthDateTime].value += entry.count;
                            }
                        }
                        else if (iGranularity.Equals(Constants.WEEK_GRANULARITY))
                        {
                           var msgsTo = from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd & (msg.To == wp.TelNumber || msg.To.StartsWith(wp.ShortID))) group msg by new { firstDayOfTheWeek = FirstDayOfWeekUtility.GetFirstDayOfWeek(msg.TimeReceived) } into g select new { date = g.Key, count = g.Count() };
                           var msgsFrom = from msg in conv.Messages where (msg.TimeReceived >= intervalStart & msg.TimeReceived <= intervalEnd & (msg.From == wp.TelNumber || msg.From.StartsWith(wp.ShortID))) group msg by new { firstDayOfTheWeek = FirstDayOfWeekUtility.GetFirstDayOfWeek(msg.TimeReceived) } into g select new { date = g.Key, count = g.Count() };
                            foreach (var entry in msgsTo)
                            {
                                var weekDateTime = entry.date.firstDayOfTheWeek;
                                if (DateTime.Compare(weekDateTime, intervalStart) < 0)
                                    resultIncomingInterval[intervalStart].value += entry.count;
                                else
                                    resultIncomingInterval[weekDateTime].value += entry.count;
                            }

                            foreach (var entry in msgsFrom)
                            {
                                var weekDateTime = entry.date.firstDayOfTheWeek;
                                if (DateTime.Compare(weekDateTime, intervalStart) < 0)
                                    resultOutgoingInterval[intervalStart].value += entry.count;
                                else
                                    resultOutgoingInterval[weekDateTime].value += entry.count;
                            }
                        }
                    }
                }

                List<Dictionary<DateTime, ChartValue>> content = new List<Dictionary<DateTime, ChartValue>>();
                content.Add(resultIncomingInterval);
                content.Add(resultOutgoingInterval);
                RepChartData chartSource = new RepChartData(new RepDataColumn[] { new RepDataColumn("17", Constants.STRING_COLUMN_TYPE, "Date"), new RepDataColumn("18", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepIncomingSmsChart), new RepDataColumn("18", Constants.NUMBER_COLUMN_TYPE, Resources.Global.RepOutgoingSmsChart) }, PrepareJson(content, Resources.Global.RepSmsUnit));
                return Json(chartSource, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                logger.Error("GetIncomingOutgoingSmsChartSource", e);
            }
            return Json("Request failed", JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetPosNegTransitionsThirdArea(String iIntervalStart, String iIntervalEnd, String culture, String scope)
        {
            DateTime intervalStart = DateTime.ParseExact(iIntervalStart, "yyyy-MM-dd", CultureInfo.InvariantCulture);
            DateTime intervalEnd = DateTime.ParseExact(iIntervalEnd, "yyyy-MM-dd", CultureInfo.InvariantCulture);
            intervalEnd = intervalEnd.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

            KeyAndCount posToNegTransitions = new KeyAndCount(Constants.POS_TO_NEG_EVENT, 0);
            KeyAndCount negToPosTransitions = new KeyAndCount(Constants.NEG_TO_POS_EVENT, 0);
            IEnumerable<WorkingPoint> workingPoints = mEFInterface.GetWorkingPointsForAUser(scope, User.Identity.Name, context);
            foreach (var wp in workingPoints)
            {
                foreach (var conv in wp.Conversations)
                {
                    if (!conv.Client.isSupportClient)
                    {
                        IEnumerable<KeyAndCount> convEvents = from convEvent in conv.ConversationEvents
                                         where ((convEvent.EventTypeName.Equals(Constants.POS_TO_NEG_EVENT) ||
                                         convEvent.EventTypeName.Equals(Constants.NEG_TO_POS_EVENT)) &&
                                         (convEvent.Date >= intervalStart && convEvent.Date <= intervalEnd))
                                         group convEvent by new { eventType = convEvent.EventTypeName }
                                             into g
                                             select new KeyAndCount(g.Key.eventType, g.Count());
                        foreach (var eventType in convEvents)
                        {
                            if (eventType.key.Equals(Constants.POS_TO_NEG_EVENT))
                                posToNegTransitions.count += eventType.count;
                            else if (eventType.key.Equals(Constants.NEG_TO_POS_EVENT))
                                negToPosTransitions.count += eventType.count;
                        }
                    }
                }
            }

            List<RepDataRow> content = new List<RepDataRow>();
            RepDataRow row1 = new RepDataRow(new RepDataRowCell[] { new RepDataRowCell(Resources.Global.RepPosToNegFeedback, Resources.Global.RepPosToNegFeedback), new RepDataRowCell(posToNegTransitions.count, posToNegTransitions.count + " " + Resources.Global.RepPosToNegFeedback) });
            RepDataRow row2 = new RepDataRow(new RepDataRowCell[] { new RepDataRowCell(Resources.Global.RepNegToPosFeedback, Resources.Global.RepNegToPosFeedback), new RepDataRowCell(negToPosTransitions.count, negToPosTransitions.count + " " + Resources.Global.RepNegToPosFeedback) });
            content.Add(row1);
            content.Add(row2);
            RepChartData chartSource = new RepChartData(new RepDataColumn[] { new RepDataColumn("17", Constants.STRING_COLUMN_TYPE, Resources.Global.RepTypeTable), new RepDataColumn("18", Constants.STRING_COLUMN_TYPE, Resources.Global.RepValueTable) }, content);
            return Json(chartSource, JsonRequestBehavior.AllowGet);
        }