/// <summary>
        /// This method sets SortedDictionaries for all columns & numeric columns
        /// </summary>
        /// <param name="dictNumericColumns">SortedDictionary of all numeric 
        /// columns</param>
        /// <param name="dictAllColumns">SortedDictionary of all coulmns
        /// except GUID column</param>
        /// <param name="metaDataDetails">metedata details containg column details</param>
        private static void GetColumnDictionariesForChart(
            IDictionary<string, string> dictNumericColumns,
            IDictionary<string, string> dictAllColumns,
            EntitySetDetails metaDataDetails)
        {
            //  Fill the dictionary objects
            //  Add watermarking element
            dictAllColumns.Add(UIConstants.DBPC_SelectOneText, "X");
            //  Add watermarking element
            dictNumericColumns.Add(UIConstants.DBPC_SelectOneText, "X");
            //  Add other elements
            foreach (System.Data.DataColumn col in metaDataDetails.DetailsTable.Columns)
            {
                // If any Numeric Type
                if (col.DataType.FullName.Contains("Double") ||
                    col.DataType.FullName.Contains("Int") ||
                    col.DataType.FullName.Contains("Byte") ||
                    col.DataType.FullName.Contains("Single"))
                {
                    // Add colname and type
                    dictNumericColumns.Add(col.Caption.ToString(),
                        col.DataType.FullName + "^" + col.Caption.ToString());
                }

                // If not Guid type
                if (col.DataType.FullName != "System.Guid")
                {
                    // Add colname and type
                    dictAllColumns.Add(col.Caption, col.DataType.FullName
                        + "^" + col.Caption.ToString());
                }
            }
        }
        public ActionResult RunButtonClicked(string container, string entitySet, string filter)
        {
            filter = string.IsNullOrEmpty(filter) ? null : filter.Trim().Equals(UIConstants.DBPC_NoFilterText) ? null : filter.Trim();

            // Hide error labels
            HideError();

            SetURLs(container, entitySet, filter);

            // Create an instance of class EntitySetDetails
            EntitySetDetails result = new EntitySetDetails();

            // Get the EntitySetDetails
            try
            {
                result = EntitySetDetailsRepository.GetBrowserData(container, entitySet, filter, Convert.ToInt32(UIConstants.DBPC_EntityDetailsTableSize, CultureInfo.InvariantCulture), null, null, false, 0);

                // Page Load is like clicking the Run button automatically
                // so we just set the value to ButtonClicked.Run
                SetPagingAndBind(result, ButtonClicked.Run, null);

                viewDataModel.Container = container;

                viewDataModel.EntitySetName = entitySet;

                viewDataModel.FilterText = filter;

                ViewData.Model = viewDataModel;

                // returns the PatialView to load DataView
                return PartialView("DataView", ViewData.Model);
            }
            catch (WebException ex)
            {
                ShowServiceError(ex);

                ViewData.Model = viewDataModel;

                // returns the PatialView to load Error
                return PartialView("ErrorView", ViewData.Model);

            }
            catch (Exception)
            {
                ShowUnexpectedError();

                ViewData.Model = viewDataModel;

                // returns the PatialView to load Error
                return PartialView("ErrorView", ViewData.Model);
            }
        }
        /// <summary>
        /// This method handles CSV format conversion
        /// </summary>
        /// <param name="fullEntitySetDetails">EnititySet details to be converted into CSV format</param>
        /// <returns>returns stack of ContinuationTokenStack of
        /// current session</returns>
        private static string ConvertToCsv(EntitySetDetails fullEntitySetDetails)
        {
            try
            {
                StringBuilder sbAllEntities = new StringBuilder();

                foreach (DataColumn col in fullEntitySetDetails.DetailsTable.Columns)
                {
                    sbAllEntities.Append(col.Caption);
                    sbAllEntities.Append(",");
                }
                sbAllEntities.Remove(sbAllEntities.Length - 1, 1);
                sbAllEntities.Append(Environment.NewLine);

                foreach (DataRow row in fullEntitySetDetails.DetailsTable.Rows)
                {
                    foreach (DataColumn col in fullEntitySetDetails.DetailsTable.Columns)
                    {
                        if (!string.IsNullOrEmpty(row[col].ToString()))
                        {
                            row[col] = row[col].ToString().Replace(',', ' ');
                            row[col] = row[col].ToString().Replace('\n', ' ');
                            sbAllEntities.Append(row[col].ToString());
                        }
                        else
                        {
                            try
                            {
                                row[col] = string.Empty;
                                sbAllEntities.Append(row[col].ToString());
                            }
                            catch
                            { }
                        }
                        sbAllEntities.Append(",");
                    }
                    sbAllEntities.Remove(sbAllEntities.Length - 1, 1);
                    sbAllEntities.Append(Environment.NewLine);
                }

                return sbAllEntities.ToString();
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// This method sets the paging and binds the details table
        /// </summary>
        /// <param name="entitySetDetails">object of type EntitySetDetails</param>
        /// <param name="buttonClicked">value of the type ButtonClicked</param>
        /// <param name="stack">Stack used for storing ContinuationTokens</param>
        private void SetPagingAndBind(EntitySetDetails entitySetDetails,
            ButtonClicked buttonClicked, Stack<ContinuationToken> stack)
        {
            // Initially disable both ViewData
            viewDataModel.NextEnable = false;
            viewDataModel.PrevEnable = false;

            // If data exists in the DetailsTable
            if (entitySetDetails.DetailsTable.Rows.Count != 0)
            {
                switch (buttonClicked)
                {
                    // Run
                    case ButtonClicked.Run:
                        // Add code to disable Previous Link
                        viewDataModel.PrevEnable = false;

                        stack = new Stack<ContinuationToken>();

                        // If NextPartitionKey and NextRowKey exists
                        if (!string.IsNullOrEmpty(entitySetDetails.NextPartitionKey) &&
                            !string.IsNullOrEmpty(entitySetDetails.NextRowKey))
                        {
                            var nextContinuationToken = new ContinuationToken
                            {
                                NextPartitionKey = entitySetDetails.NextPartitionKey,
                                NextRowKey = entitySetDetails.NextRowKey,
                                Skip = entitySetDetails.Skip
                            };

                            // push the ContinuationToken
                            stack.Push(nextContinuationToken);

                            // Add code to enable Next Link
                            viewDataModel.NextEnable = true;
                        }

                        if (stack.Count == 0)
                        {
                            // Add code to disable Next Link
                            viewDataModel.NextEnable = false;
                        }
                        break;

                    // Previous
                    case ButtonClicked.Previous:
                        if (stack.Count == 1)
                        {
                            // Add code to disable Previous Link
                            viewDataModel.PrevEnable = false;
                        }
                        else
                        {
                            // Add code to enable Previous Link
                            viewDataModel.PrevEnable = true;
                        }

                        // Add code to enable Next Link
                        viewDataModel.NextEnable = true;

                        break;

                    // Next
                    case ButtonClicked.Next:
                        // If NextPartitionKey and NextRowKey exists
                        if (!string.IsNullOrEmpty(entitySetDetails.NextPartitionKey) &&
                            !string.IsNullOrEmpty(entitySetDetails.NextRowKey))
                        {
                            var nextContinuationToken = new ContinuationToken
                            {
                                NextPartitionKey = entitySetDetails.NextPartitionKey,
                                NextRowKey = entitySetDetails.NextRowKey,
                                Skip = entitySetDetails.Skip
                            };

                            // push the ContinuationToken
                            stack.Push(nextContinuationToken);

                            // Add code to enable Next Link
                            viewDataModel.NextEnable = true;

                            // Add code to enable Previous Link
                            viewDataModel.PrevEnable = true;
                        }
                        else
                        {
                            // The else condition means there are no more pages of data.
                            // The PreviousLink click handler ALWAYS throws away what
                            // is on top of the stack.  Therefore, we add a bogus token.
                            stack.Push(new ContinuationToken
                            {
                                NextPartitionKey = "X",
                                NextRowKey = "X"
                            });

                            // Add code to enable Previous Link
                            viewDataModel.PrevEnable = true;

                            // Add code to disable Next Link
                            viewDataModel.NextEnable = false;
                        }
                        break;
                }

                if (Session["ContinuationTokenStack"] != null)
                    Session.Remove("ContinuationTokenStack");

                Session.Add("ContinuationTokenStack", stack);

                viewDataModel.TableBrowserData = entitySetDetails.DetailsTable;
            }
            else
            {
                ShowError(UIConstants.DBPC_ErrorZeroResults,
                    UIConstants.DBPC_ErrorChkQuery);
            }
        }
        /// <summary>
        /// This method loads Pie Chart
        /// </summary>
        /// <param name="metaDataDetails">This object contains
        /// column details of entitySets.</param>
        private void LoadPieChart(EntitySetDetails metaDataDetails)
        {
            // Create an instance of type SortedDictionary<string, Type>
            // to store numeric columns for y-axis column combo-box
            SortedDictionary<string, string> dictNumericColumns =
                new SortedDictionary<string, string>();

            // Create an instance of type SortedDictionary<string, Type>
            // to store ALL columns except GUID type for X-axis column combo-box
            SortedDictionary<string, string> dictAllColumns =
                new SortedDictionary<string, string>();

            //  Fill the dictionary objects
            GetColumnDictionariesForChart(dictNumericColumns, dictAllColumns, metaDataDetails);

            FillPieChartColumnComboBoxes(dictNumericColumns, dictAllColumns);

            FillPieChartDateComboBox();

            SetPieChartOptionsAndOtherParams();

            // Load PieChart Languages
            SetPieChartViewLanguages();

            // Set initially keyvalue list to null
            viewDataModel.Chart = null;
        }
        /// <summary>
        /// This method returns Full data for the passed criterias
        /// </summary>
        /// <param name="container">container alias</param>
        /// <param name="entitySet">entity set name</param>
        /// <param name="filter">filter criteria</param>
        /// <returns>returns full data in EntitySetDetials object</returns>
        private EntitySetDetails GetFullData(string container, string entitySet, string filter)
        {
            // Fetch the full data in fullEntitySetDetails
            // To get full details, set isFullData parameter to true.
            EntitySetDetails cachedObject = null;
            if (HttpContext.Session["ChartData"] != null)
            {
                cachedObject = HttpContext.Session["ChartData"] as EntitySetDetails;
            }

            string cachedFilter = HttpContext.Session["ChartFilter"] == null ? null :
                HttpContext.Session["ChartFilter"].ToString().Trim();

            // Check if data available in cache
            if (cachedObject != null && cachedObject.ContainerAlias == container &&
                (cachedObject).EntitySetName == entitySet && cachedFilter == filter)
            {
                // Get data from cache
                return cachedObject;
            }
            else
            {
                // Create an object of class EntitySetDetails to get full
                // details of the selected EntitySet
                EntitySetDetails fullEntitySetDetails = new EntitySetDetails();

                // Get data from service and insert it to cache
                // 1000 is the max results Azure Table Storage allows per query
                fullEntitySetDetails = EntitySetDetailsRepository.GetBrowserData(
                                            container,
                                            entitySet,
                                            filter == UIConstants.DBPC_NoFilterText ? null : filter,
                                            1000,
                                            null,
                                            null,
                                            true,
                                            0);

                if (HttpContext.Session["ChartData"] != null)
                    HttpContext.Session.Remove("ChartData");
                if (HttpContext.Session["ChartFilter"] != null)
                    HttpContext.Session.Remove("ChartFilter");

                HttpContext.Session.Add("ChartData", fullEntitySetDetails);
                if (filter == null)
                    filter = UIConstants.DBPC_NoFilterText;
                HttpContext.Session.Add("ChartFilter", filter);

                return fullEntitySetDetails;
            }
        }
        /// <summary>
        /// Fetches the EntitySetDetails and returns EntitySetDetails object
        /// XML format will be different depending on tableName parameter.
        /// </summary>
        /// <param name="container">Container: Alias</param>
        /// <param name="tableName">EntitySetName</param>
        /// <param name="filter">Filter Parameters</param>
        /// <param name="pageSize">PageSize - For Paging Purpose</param>
        /// <param name="nextPartitionKey">Next Partition Key - 
        /// For Paging Purpose</param>
        /// <param name="nextRowKey">Next Row Key - For Paging Purpose</param>
        /// <param name="isFullData">true if required full data else false</param>
        /// <returns>returns an object of EntitySetDetails</returns>
        internal static EntitySetDetails GetBrowserData(string container,
            string tableName, string filter, int pageSize, string nextPartitionKey,
            string nextRowKey, bool isFullData, int skip)
        {
            // Declare object of class EntitySetDetails
            EntitySetDetails entitySetDetails = null;

            // Validatie the parameters
            if ((!String.IsNullOrEmpty(container)) &&
                !(String.IsNullOrEmpty(tableName))
               && pageSize > 0)
            {

                // Create an instance of class Storage
                IsdkStorageProviderInterface storage = Helper.ServiceObject;

                // Define entitySetDetails
                entitySetDetails = new EntitySetDetails();

                // Set the properties of entitySetDetails object
                entitySetDetails.ContainerAlias = container;
                entitySetDetails.EntitySetName = tableName;

                // Set the filter
                string tableNameFilter = "entityset eq '" + tableName + "'";

                //sl-king
                //TODO make this a reusable code (find all sfdgsdfgsdfgd)
                EntitySet es = EntitySetRepository.GetEntitySet(container, tableName);
                //since this is OData address looks like this .../service/category/entityset
                //metadata is at address .../service/category/$metadata
                string realUri = es.DataSvcLink;

                //first get rid of ?option1=...&option2=....
                var uriParts = realUri.Split('?');
                realUri = uriParts[0];
                if (realUri[realUri.Length - 1] != '/')//if it's not / terminated, let's terminate it
                    realUri = realUri + "/";

                string metadataUri = realUri;
                uriParts = metadataUri.Split('/');
                metadataUri = uriParts[0];
                for (int i = 1; i < uriParts.Length - 2; i++)
                {
                    metadataUri += "/" + uriParts[i];
                }
                metadataUri += "/$metadata";

                // Fetches the data from Azure Table Storage
                XElement metaDataXML = storage.GetMetadata(metadataUri, container, tableName);//, tableNameFilter);

                // Remove the unnecessary columns

                //sl-king: why is this done twice??? see GetMetaData
                var entityType = metaDataXML.Element("EntityType");
                var propertyMetaData = entityType.Elements("Property");//properties");
                //properties.Elements("entityset").Remove();
                //properties.Elements("entitykind").Remove();

                // Set the column list
                //var propertyMetaData = metaDataXML.Elements("Property");//Elements("properties").First().Elements();//properties

                // Add the column names in the detailsTable of the object entitySetDetails
                foreach (var property in propertyMetaData)
                {
                    if (property.Attribute("Name").Value.ToLower() == "partitionkey" ||
                            property.Attribute("Name").Value.ToLower() == "rowkey" ||
                            property.Attribute("Name").Value.ToLower() == "timestamp")
                        continue;

                    string sName = property.Attribute("Name").Value;
                    if (sName == "entityid")//property.Name
                    {
                        entitySetDetails.DetailsTable.Columns.Add(sName, Type.GetType("System.Guid"));
                    }
                    else
                    {
                        string sType = property.Attribute("Type").Value;
                        sType = sType.Replace("Edm.", "System.");

                        entitySetDetails.DetailsTable.Columns.Add(sName, Type.GetType(sType));//property.Value));
                    }
                }

                // Get the browser data
                XElement browserDataXML = null;
                if (isFullData == false)
                {
                    browserDataXML = storage.GetData(realUri, container, tableName,
                             filter, pageSize, nextPartitionKey, nextRowKey, skip);

                    int read = browserDataXML.Elements("entry").Count();
                    //for now let's just reuse the old mechanism with dummy values
                    if (read == pageSize)
                    {
                        entitySetDetails.NextPartitionKey = "dummypartitionkey";
                        entitySetDetails.NextRowKey = "dummyrowkey";
                    }
                    else
                    {
                        entitySetDetails.NextPartitionKey = "";
                        entitySetDetails.NextRowKey = "";
                    }
                    entitySetDetails.Skip += skip + read;

                    // set the properties of entitySetDetails object depending on the
                    // fetched results
                    //entitySetDetails.NextPartitionKey =
                    //     browserDataXML.Attribute("nextPartitionKey").Value;

                    //entitySetDetails.NextRowKey =
                    //     browserDataXML.Attribute("nextRowKey").Value;

                    //entitySetDetails.CurrentPartitionKey =
                    //     browserDataXML.Attribute("currentPartitionKey").Value;

                    //entitySetDetails.CurrentRowKey =
                    //     browserDataXML.Attribute("currentRowKey").Value;
                }
                else
                {
                    browserDataXML = storage.GetData(realUri, container, tableName, filter);
                }

                // validate the XElement
                if (browserDataXML != null)
                {
                    // for each XML node, fetch the internal details

                    foreach (var element in browserDataXML.Elements("entry"))//properties"))
                    {
                        try
                        {
                            XElement content = element.Element("content");
                            XElement props = content.Element("properties");
                            // Get the row list for each elements
                            DataRow row = entitySetDetails.DetailsTable.NewRow();

                            // Add each cell in the row
                            foreach (var cell in props.Elements())//element.Elements()
                            {
                                try
                                {
                                    row[cell.Name.ToString()] = cell.Value.ToString();
                                }
                                catch (Exception) { } //To handle the wrong cells
                            }

                            // Add the newly created row in the table
                            entitySetDetails.DetailsTable.Rows.Add(row);
                        }
                        catch (Exception)
                        {
                            // To handle the wrong rows
                        }
                    }
                }
            }

            // Return entitySetDetails
            return entitySetDetails;
        }
        /// <summary>
        /// This method gives the meta data for the given container & entitySet
        /// </summary>
        /// <param name="container">Container: Alias</param>
        /// <param name="tableName">EntitySetName</param>
        /// <returns>returns an object of EntitySetDetails</returns>
        internal static EntitySetDetails GetMetaData(string container,
            string tableName)
        {
            // Declare object of class EntitySetDetails
            EntitySetDetails entitySetDetails = null;

            // Validatie the parameters
            if ((!String.IsNullOrEmpty(container)) &&
                !(String.IsNullOrEmpty(tableName)))
            {

                // Create an instance of class Storage
                IsdkStorageProviderInterface storage = Helper.ServiceObject;

                // Define entitySetDetails
                entitySetDetails = new EntitySetDetails();

                // Set the properties of entitySetDetails object
                entitySetDetails.ContainerAlias = container;
                entitySetDetails.EntitySetName = tableName;

                // Set the filter
                string tableNameFilter = "entityset eq '" + tableName + "'";

                //sl-king
                //TODO make this a reusable code (find all sfdgsdfgsdfgd)
                EntitySet es = EntitySetRepository.GetEntitySet(container, tableName);
                //since this is OData address looks like this .../service/category/entityset
                //metadata is at address .../service/category/$metadata
                string metadataUri = es.DataSvcLink;

                //first get rid of ?option1=...&option2=....
                var uriParts = metadataUri.Split('?');
                metadataUri = uriParts[0];
                if (metadataUri[metadataUri.Length - 1] != '/')//if it's not / terminated, let's terminate it
                    metadataUri = metadataUri + "/";

                uriParts = metadataUri.Split('/');
                metadataUri = uriParts[0];
                for (int i = 1; i < uriParts.Length - 2; i++)
                {
                    metadataUri += "/" + uriParts[i];
                }
                metadataUri += "/$metadata";

                // Fetches the data from Azure Table Storage
                XElement metaDataXML = storage.GetMetadata(metadataUri, container, tableName);//, tableNameFilter);

                //sl-king: why is this done twice??? see GetBrowserData
                // Remove the unnecessary columns
                var properties = metaDataXML.Element("EntityType");//Elements("properties");
                properties.Elements("Key").Remove();
                //properties.Elements("entityset").Remove();
                //properties.Elements("entitykind").Remove();

                // Set the column list
                var propertyMetaData = properties.Elements();// metaDataXML.Elements("properties").First().Elements();

                // Add the column names in the detailsTable of the object entitySetDetails
                foreach (var property in propertyMetaData)
                {
                    //sl-king: we tryed to get rid of these in GetData, but Azure XML is different from OGDI's
                    if (property.Attribute("Name").Value.ToLower() == "partitionkey" ||
                            property.Attribute("Name").Value.ToLower() == "rowkey" ||
                            property.Attribute("Name").Value.ToLower() == "timestamp")
                        continue;

                    string sName = property.Attribute("Name").Value;
                    if (sName == "entityid")//.Name == "entityid")
                    {
                        entitySetDetails.DetailsTable.Columns.Add(property.Name.ToString(),
                            Type.GetType("System.Guid"));
                    }
                    else
                    {
                        string sType = property.Attribute("Type").Value;
                        sType = sType.Replace("Edm.", "System.");

                        entitySetDetails.DetailsTable.Columns.Add(sName, Type.GetType(sType));//property.Name.ToString(), property.Value));
                    }
                }
            }

            return entitySetDetails;
        }