//In Datagrid tabs the tab title looks like this : Cars.sav(DatasetN), where N is any integer.
        //So here DatasetN is the object in memory that is dataframe( or similar).
        //Cars.sav is just extra info about the Dataset you tried to open. This extra info could be a disk filename
        // or it could also be just a memory object name if memory object name is different from 'DatasetN' style of naming
        // eg.. mydf(mydf) , Dataset1(Dataset1), Cars.sav(Dataset2), mydata.rdata(Dataset3)
        // in above example mydf, Dataset1 Dataset2, Dataset3 , all R objects exists in R memory.

        //Wrong way of naming would look something like this : mydf(Dataset1)
        // mydf is not a disk file, so lets assume it may be R dataframe obj in memory, but then we always put memory object
        // name within round brackets, so, if (Dataset1) is a memory object, the extra info 'mydf' does not make sense.
        //So 'mydf' should be named as 'Dataset1' instead.
        //Right thing would be either one of two mydf(mydf) or Dataset1(Dataset1) for non-disk datasets

        public DataSource OpenDataframe(string dframename, string sheetname, string fname = "") //13Feb2014
        {
            UAReturn   datasrc = null;
            DataSource ds      = null;

            if (!isDatasetNew(dframename /*+ sheetname*/)) // if data.frame with same name already loaded in C1DataGrid
            {
                string filename = _datasourcenames[dframename /*+ sheetname*/];
                //////////    datasrc = new UAReturn();
                //////////    datasrc = _analyticService.DataFrameLoad(filename, dframename, sheetname);
                //////////    //////////////
                //////////    if (datasrc == null)
                //////////    {
                //////////        logService.WriteToLogLevel("Could not open: " + filename, LogLevelEnum.Error);
                //////////        return null;
                //////////    }
                //////////    else if (datasrc != null && datasrc.Datasource == null)
                //////////    {
                //////////        if (datasrc.Error != null && datasrc.Error.Length > 0)
                //////////        {
                //////////            logService.WriteToLogLevel("Could not refresh/open: " + filename + ".\n" + datasrc.Error, LogLevelEnum.Error);
                //////////        }
                //////////        else
                //////////            logService.WriteToLogLevel("Could not refresh/open: " + dframename + ".\nInvalid format OR issue related to R.Net server.", LogLevelEnum.Error);

                //////////        DataSource dsnull = new DataSource() { Message = datasrc.Error };
                //////////        return dsnull;
                //////////    }

                //////////    datasrc.CommandString = "Refresh Dataframe";
                try
                {
                    if (_datasources.Keys.Contains(filename + sheetname))
                    {
                        ds = _datasources[filename + sheetname];
                    }
                    else //no need to check if it exists as we alreay checked if its new dataset or not in code above
                    {
                        ds = _datasources[_datasourcenames[dframename /*+ sheetname*/].Trim() + sheetname];
                    }

                    //So by now we know we know that Dataset name is same.
                    //And new one already overwrote old data.frame in memory.



                    //Now we need to figure out if the disk filename is same or not
                    //if same no issue. If different then we need to replace old with new filename
                    #region Overwrite with new filename if Filename is different from old one
                    //if ( !filename.ToLower().Equals(fname)) //fname.Length > 0 && filename.Length > 0 &&
                    //{
                    //    //remove old keys in _datasources _datasourcenames
                    //    if (_datasources.Keys.Contains(filename + sheetname)) //Check if dataset is already loaded in the grid
                    //    {
                    //        _datasources.Remove(filename + sheetname);//Remove old
                    //        //_datasources.Add(dsourceName.FileName + sheetname, dsourceName);///Replace ds with new one

                    //        //5Mar2014 No need to do following but we can still do it
                    //        _datasourcenames.Remove(dframename /*+ sheetname*/);
                    //        //_datasourcenames.Add(dsourceName.Name + sheetname, dsourceName.FileName);
                    //    }
                    //}

                    //update ds. if new filename then overwrite old. if blank then use DatasetNN for filename
                    if (fname.Trim().Length > 0)
                    {
                        ds.FileName = fname;
                    }
                    else
                    {
                        // ds.FileName = dframename;
                        ds.SheetName = UtilFunctions.GetSheetname(ds);
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    logService.WriteToLogLevel("Error getting existing DataSource handle", LogLevelEnum.Fatal);
                }
                string existingDatasetname = ds.Name;

                //20Oct2016 save a copy for using in 'if' below
                DataSource ds_for_cleanup = ds;

                ds = Refresh(ds);

                if (ds == null)//20Oct2016 Making UI grid NULL
                {
                    ds                  = new DataSource();
                    ds.Variables        = new List <DataSourceVariable>();//making it blank
                    ds.FileName         = ds_for_cleanup.FileName;
                    ds.Name             = ds_for_cleanup.Name;
                    ds.SheetName        = UtilFunctions.GetSheetname(ds_for_cleanup);
                    ds.DecimalCharacter = ds_for_cleanup.DecimalCharacter;
                    ds.FieldSeparator   = ds_for_cleanup.FieldSeparator;
                    ds.HasHeader        = ds_for_cleanup.HasHeader;
                    ds.IsBasketData     = ds_for_cleanup.IsBasketData;
                    UIController        = LifetimeService.Instance.Container.Resolve <IUIController>();
                    UIController.RefreshBothGrids(ds);
                    //here I can also close before or after above line(whereever works)
                    //Close(ds_for_cleanup);

                    //Generating the message for null dataset
                    CommandRequest msg = new CommandRequest();
                    msg.CommandSyntax = ds_for_cleanup.Name + " been set to NULL. The reason may be, running some analysis or command on the dataset.";
                    //string title = "NULL Dataset.";
                    //if (msg != null && title != null)//16May2013
                    //    SendToOutputWindow(title, msg.CommandSyntax);
                    logService.WriteToLogLevel(msg.CommandSyntax, LogLevelEnum.Error);
                }
            }
            else // Its New Data.Frame .
            {
                string datasetname = "Dataset" + SessionDatasetCounter;//dframename;// //(_datasources.Keys.Count + 1);//can also be filename without path and extention

                //15Jun2015 dframename exists in memory so use that name for datagrid tab name enclosed in round brackets (Dataset1) or (df1)
                if (!dframename.Equals(datasetname)) //df2 and Dataset2
                {
                    datasetname = dframename;
                    //use df2 for both because df2 exists in R memory
                    //no need to increament the SessionDatasetCounter as when you try to open a disk file it will have (Dataset2)
                    // as name and it will not clash with the (df2) name.
                    //incrementing may not harm but there is no need to increment.

                    //ELSE dframename.Equals(datasetname) like both are say "Dataset2"
                    // use (Dataset2) for both because Dataset2 exists in memory
                    //Also increament the SessionDatasetCounter in this case because now later
                    //when you open Dataset from disk is should have name Dataset3 and not Dataset2
                }
                if (fname.ToLower().EndsWith(".rdata") || fname.ToLower().EndsWith(".rda"))
                {
                    dframename = fname; //pass RData filename
                }
                datasrc = _analyticService.DataFrameLoad(dframename, datasetname, "");

                if (datasrc == null)
                {
                    logService.WriteToLogLevel("Could not open: " + dframename, LogLevelEnum.Error);
                    return(null);
                }
                else if (datasrc != null && datasrc.Datasource == null)
                {
                    if (datasrc.Error != null && datasrc.Error.Length > 0)
                    {
                        logService.WriteToLogLevel("Could not open: " + dframename + ".\n" + datasrc.Error, LogLevelEnum.Error);
                    }
                    else
                    {
                        logService.WriteToLogLevel("Could not open: " + dframename + ".\nInvalid format OR issue related to R.Net server.", LogLevelEnum.Error);
                    }

                    DataSource dsnull = new DataSource()
                    {
                        Message = datasrc.Error
                    };
                    return(dsnull);
                }

                datasrc.CommandString = "Open Dataset";//21Oct2013
                ds = datasrc.Datasource.ToClientDataSource();

                if (ds != null)//03Dec2012
                {
                    //_datasources.Add(ds.FileName, ds);///key filename
                    if (!_datasources.ContainsKey(ds.FileName + ds.SheetName))             //for avoiding crash
                    {
                        _datasources.Add(ds.FileName + ds.SheetName, ds);                  ///key filename
                    }
                    if (!_datasourcenames.ContainsKey(datasetname))                        //for avoiding crash
                    {
                        _datasourcenames.Add(datasetname /*+ ds.SheetName*/, ds.FileName); //5Mar2014
                    }
                }
                ///incrementing dataset counter //// 15Jun2015
                /// if the name of the Dataset created in syntax matches to the Dataset name generated for UI grid.
                if (dframename.Equals(datasetname))
                {
                    SessionDatasetCounter++;
                }
            }
            if (fname.Length == 0)
            {
                ds.Extension = "";
                ds.FileName  = "";
            }
//04Nov2014. Dont show "Open Dataset" before subset command title.   SendToOutput(datasrc);
            return(ds);
        }
        public DataSource Refresh(DataSource dsourceName)                                            //25Mar2013
        {
            string sheetname = dsourceName.SheetName != null ? dsourceName.SheetName : string.Empty; // BugId #JM12Apr16
            //filename = filename.ToLower();
            //if (_datasources.Keys.Contains(filename.ToLower()))
            //    return _datasources[filename];
            //string datasetname = "Dataset" + SessionDatasetCounter;
            UAReturn datasrc = _analyticService.DataSourceRefresh(dsourceName.Name, dsourceName.FileName, sheetname);

            if (datasrc == null)
            {
                //25Oct2016 If key is found then you must update the dictionary(with empty vars and rowcount) when dataset becomes NULL
                dsourceName.Variables = new List <DataSourceVariable>();
                dsourceName.RowCount  = 0;
                if (_datasources.Keys.Contains(dsourceName.FileName + sheetname))        //Check if dataset is already loaded in the grid
                {
                    _datasources.Remove(dsourceName.FileName + sheetname);               //Remove old
                    if (!_datasources.ContainsKey(dsourceName.FileName + sheetname))     //for avoiding crash
                    {
                        _datasources.Add(dsourceName.FileName + sheetname, dsourceName); ///Replace ds with new one
                    }
                    //5Mar2014 No need to do following but we can still do it
                    _datasourcenames.Remove(dsourceName.Name /*+ sheetname*/);
                    if (!_datasourcenames.ContainsKey(dsourceName.Name))//for avoiding crash
                    {
                        _datasourcenames.Add(dsourceName.Name /*+sheetname*/, dsourceName.FileName);
                    }
                }

                logService.WriteToLogLevel("Could not open:" + dsourceName.FileName + ".Invalid format OR issue related to R.Net server.", LogLevelEnum.Error);
                return(null);
            }
            DataSource ds = datasrc.Datasource.ToClientDataSource();

            //CSV-Options
            ds.DecimalCharacter = dsourceName.DecimalCharacter;
            ds.FieldSeparator   = dsourceName.FieldSeparator;
            ds.HasHeader        = dsourceName.HasHeader;
            ds.IsBasketData     = dsourceName.IsBasketData;

            ds.SheetName     = UtilFunctions.GetSheetname(dsourceName); //fix for Excel dataset becomes null and reload from disk does not work
            ds.isUnprocessed = dsourceName.isUnprocessed;               //for new dataset

            if (ds != null)                                             //03Dec2012
            {
                //03jun2018 _datasources.Remove(dsourceName.FileName + sheetname);//Remove old
                _datasources.Remove(_datasourcenames[dsourceName.Name] + sheetname);//Remove old
                //////if (ds.FileName.Equals(ds.Name))//its a memory dataframe. Sheetname should be blank
                //////{
                //////    sheetname = "";
                //////}
                if (!_datasources.ContainsKey(ds.FileName + sheetname)) //for avoiding crash
                {
                    _datasources.Add(ds.FileName + sheetname, ds);      ///Replace ds with new one //25Oct2016 added sheetname
                }
                //5Mar2014 No need to do following but we can still do it
                _datasourcenames.Remove(ds.Name /*+ sheetname*/);
                if (!_datasourcenames.ContainsKey(ds.Name))                     //for avoiding crash
                {
                    _datasourcenames.Add(ds.Name /*+ sheetname*/, ds.FileName); //25Oct2016 added sheetname
                }
            }

            //Fix for 'Data > Reload Dataset from File' crash, when run on excel dataset. Missing sheetname was causing the problem.
            //This fix needed modification in few locations. So here is BugID for easy search #JM12Apr16
            //////ds.SheetName = sheetname;
            ///incrementing dataset counter //// 14Feb2013
            //SessionDatasetCounter++;

            return(ds);
        }
        ////Send executed command to output window. So, user will know what he executed
        //protected override void SendToOutputWindow(string command, string title)//13Dec2013
        //{
        //    #region Get Active output Window
        //    //////// Active output window ///////
        //    OutputWindowContainer owc = (LifetimeService.Instance.Container.Resolve<IOutputWindowContainer>()) as OutputWindowContainer;
        //    OutputWindow ow = owc.ActiveOutputWindow as OutputWindow; //get currently active window
        //    #endregion
        //    ow.AddMessage(command, title);
        //}

        public bool OpenDataframe(string dframename, string fname)
        {
            initGlobalObjects();
            AdvancedLogging = AdvancedLoggingService.AdvLog;//08Aug2016

            Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();

            if (!AreDefaultRPackagesLoaded())
            {
                stopwatch.Stop();
                return(false);
            }
            stopwatch.Stop();

            long elapsed = stopwatch.ElapsedMilliseconds;

            if (AdvancedLogging)
            {
                logService.WriteToLogLevel("PERFORMANCE:Are Req Package loaded: Time taken: " + elapsed, LogLevelEnum.Info);
            }

            BSkyMouseBusyHandler.ShowMouseBusy();// ShowProgressbar_old();//ShowStatusProgressbar();//29Oct2014

            bool       isSuccess = false;
            string     filename = null, sheetname = null;
            DataSource tempds = controller.GetActiveDocument();

            if (tempds != null)
            {
                filename = tempds.FileName;
                //For Excel
                sheetname = UtilFunctions.GetSheetname(tempds);
            }
            if (filename == null)
            {
                filename = string.Empty;
            }
            if (sheetname == null)
            {
                sheetname = string.Empty;
            }
            // if dataset was already loaded last time then this time we want to refresh it
            bool isDatasetNew = service.isDatasetNew(dframename /*+ sheetname*/);

            try
            {
                stopwatch.Restart();
                if (fname.Length == 0)
                {
                    /// It is difficult to diffeneretiate between
                    ///(1) BSkyLoadRefreshDataframe(housing) which is a part of 'Compute' analysis on housing dataset and
                    ///(2) BSkyLoadRefreshDataframe(housing) which is a part of 'Aggregate to dataset' on iris dataset.
                    /// Ideally, first one should keep the Housing.Rdata filename in DataSource as well as on TabItem
                    /// TabItem should be "Housing.RData(housing)"
                    /// And the second on should replace the Housing.Rdata filename in Datasource and TabItem with
                    /// 'housing'. TabItem should be "housing(housing)"
                    ///
                    ///Since we do not have a way to differentiate the two loadRefresh so A.R. and A.D. decided to
                    ///leave the filename in DataSource as well as on TabItem in both cases.
                    if (isDatasetNew)//new dataset may not have filename so R dataset obj name(DatasetX or mydf) is used.
                    {
                        fname = dframename;
                    }
                    else
                    {
                        fname = service.FindDataSourceFromDatasetname(dframename).FileName;//filename;//existing dataframe should retain original filename.
                    }
                }
                if (!(fname.ToLower().EndsWith(".xls") || fname.ToLower().EndsWith(".xlsx")))
                {
                    sheetname = string.Empty;
                }
                DataSource ds = service.OpenDataframe(dframename, sheetname, fname);
                //ds.FileName = fname;
                stopwatch.Stop();
                elapsed = stopwatch.ElapsedMilliseconds;
                if (AdvancedLogging)
                {
                    logService.WriteToLogLevel("PERFORMANCE:Open Dataset in R: Time taken: " + elapsed, LogLevelEnum.Info);
                }

                string errormsg = string.Empty;

                if (ds != null && ds.Message != null && ds.Message.Length > 0) //message that is related to error
                {
                    errormsg = "\n" + ds.Message;
                    ds       = null;                      //making it null so that we do execute further
                }
                if (ds != null && ds.Variables.Count > 0) //07Aug2016 added count condition to not open dataset if there are no variables //03Dec2012
                {
                    logService.WriteToLogLevel("Start Loading Dataframe: " + ds.Name, LogLevelEnum.Info);
                    if (isDatasetNew)
                    {
                        stopwatch.Restart();
                        controller.Load_Dataframe(ds);
                        stopwatch.Stop();
                        elapsed = stopwatch.ElapsedMilliseconds;
                        if (AdvancedLogging)
                        {
                            logService.WriteToLogLevel("PERFORMANCE:Grid loading: Time taken: " + elapsed, LogLevelEnum.Info);
                        }
                    }
                    else
                    {
                        stopwatch.Restart();
                        controller.RefreshBothGrids(ds);//23Jul2015 .RefreshGrids(ds);//.RefreshDataSet(ds);
                        stopwatch.Stop();
                        elapsed = stopwatch.ElapsedMilliseconds;
                        if (AdvancedLogging)
                        {
                            logService.WriteToLogLevel("PERFORMANCE:Grid loading: Time taken: " + elapsed, LogLevelEnum.Info);
                        }
                        ActivateDatagrid(ds);
                    }
                    //ds.Changed = true; // keep track of change made, so that it can prompt for saving while closing dataset tab.
                    logService.WriteToLogLevel("Finished Loading Dataframe: " + ds.Name, LogLevelEnum.Info);
                    //recentfiles.AddXMLItem(dframename);//adding to XML file for recent docs
                    isSuccess = true;
                }
                else
                {
                    BSkyMouseBusyHandler.HideMouseBusy();// HideProgressbar_old();

                    //MessageBox.Show(appwindow, "Unable to open '" + dframename + "'..." +
                    //    "\nReasons could be one or more of the following:" +
                    //    "\n1. Not a data frame object." +
                    //    "\n2. File format not supported (or corrupt file or duplicate column names)." +
                    //    "\n3. Dataframe does not have row(s) or column(s)." +
                    //    "\n4. R.Net server from the old session still running (use task manager to kill it)." +
                    //    "\n5. Some issue on R side (like: required library not loaded, incorrect syntax).",
                    //    "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
                    //SendToOutputWindow("Error Opening Dataset.(probably not a data frame)", dframename + errormsg);

                    MessageBox.Show(appwindow, BSky.GlobalResources.Properties.Resources.cantopen + " '" + dframename + "'" +
                                    "\n" + BSky.GlobalResources.Properties.Resources.reasonsAre +
                                    "\n" + BSky.GlobalResources.Properties.Resources.NotDataframe2 +
                                    "\n" + BSky.GlobalResources.Properties.Resources.FormatNotSupported2 +
                                    "\n" + BSky.GlobalResources.Properties.Resources.NoRowsColsPresent +
                                    "\n" + BSky.GlobalResources.Properties.Resources.OldSessionRunning2 +
                                    "\n" + BSky.GlobalResources.Properties.Resources.RSideIssue2,
                                    BSky.GlobalResources.Properties.Resources.warning, MessageBoxButton.OK, MessageBoxImage.Warning);
                    SendToOutputWindow(BSky.GlobalResources.Properties.Resources.ErrOpeningDataset2, dframename + errormsg);
                }
            }
            catch (Exception ex)
            {
                logService.WriteToLogLevel("Error:" + ex.Message, LogLevelEnum.Error);
            }
            finally
            {
                //18OCt2013 move up for using in msg box   Window1 appwindow = LifetimeService.Instance.Container.Resolve<Window1>();//for refeshing recent files list
                //appwindow.RefreshRecent();
                BSkyMouseBusyHandler.HideMouseBusy();// HideProgressbar_old();//HideStatusProgressbar();//29Oct2014
            }

            //if (isSuccess)
            //{
            //08Apr2015 bring main window in front after file open, instead of output window
            //Window1 window = LifetimeService.Instance.Container.Resolve<Window1>();
            //window.Activate();
            //}
            return(isSuccess);
        }