/// <summary>
        /// Add horrizontal key values to the specified output Row
        /// </summary>
        /// <param name="horizontalPreviousValues">
        /// A map of {key,  previous value of key} 
        /// </param>
        /// <param name="dimension">
        /// The current key
        /// </param>
        /// <param name="outputRow">
        /// The row to add the key values
        /// </param>
        /// <param name="currentValue">
        /// The current value
        /// </param>
        /// <param name="model">
        /// The dataset model
        /// </param>
        private void AddHorrizontalKeyValues(
            IDictionary<string, TableCell> horizontalPreviousValues,
            string dimension,
            TableRow outputRow,
            string currentValue,
            IDataSetModel model,
            IDataReader currentRow)
        {
            TableCell oldCell;
            horizontalPreviousValues.TryGetValue(dimension, out oldCell);

            string oldValue = string.Empty;

            if (oldCell != null &&
                oldCell.Children.Count > 0 &&
                oldCell.Children[0].Children.Count > 0 &&
                oldCell.Children[0].Children[0].Children.Count > 1)
                oldValue = oldCell.Children[0].Children[0].Children[0].SdmxValue;
            else if (oldCell != null)
                oldValue = oldCell.SdmxValue;

            if (oldCell != null && string.Equals(currentValue, oldValue))
            {
                oldCell.ColumnSpan++;
            }
            else
            {

                this._uniqID++;
                Table tb = new Table();
                TableRow _rw = new TableRow();
                Table tb_extra = (this._useSdmxAttr) ? CreateDimensionAttributeTable(dimension, model, currentRow) : null;
                if (tb_extra != null)
                {
                    tb_extra.AddAttribute("ID", this._uniqID + "_dim_info_extra_dialog");
                    tb_extra.AddClass(HtmlClasses.ExtraInfoTable);

                    tb.AddRow(new TableRow(new TableCell(tb_extra)));

                    var tb_btn_extra = new TableCell();
                    tb_btn_extra.AddClass(HtmlClasses.ExtraInfoWrapper);
                    tb_btn_extra.AddAttribute("ID", this._uniqID + "_dim_info");

                    _rw.AddCell(tb_btn_extra);
                }

                string text = this.GetLocalizedName(dimension, currentValue);
                var tb_dim = new TableCell();
                tb_dim.AddClass(HtmlClasses.HorizontalKeyValue);
                tb_dim.SetupDisplayText(currentValue, text, dimension, model.GetDisplayMode(dimension, currentValue), this._enhancedOutput);

                if (dimension == "TIME_PERIOD") tb_dim.AddAttribute("style", "white-space:nowrap");

                _rw.AddCell(tb_dim);

                tb.AddRow(_rw);
                TableCell tb_cell = new TableCell(tb);
                tb_cell.SdmxValue = currentValue;
                outputRow.AddCell(tb_cell);
                horizontalPreviousValues[dimension] = tb_cell;

            }
        }
        /// <summary>
        /// Add vertical key values to the specified output Row
        /// </summary>
        /// <param name="verticalPreviousValues">
        /// A map of {key,  previous value of key} 
        /// </param>
        /// <param name="dimension">
        /// The current key
        /// </param>
        /// <param name="outputRow">
        /// The row to add the key values
        /// </param>
        /// <param name="currentValue">
        /// The current value
        /// </param>
        /// <param name="model">
        /// The dataset model
        /// </param>
        private void AddVerticalKeyValues(
            IDictionary<string, TableCell> verticalPreviousValues,
            string dimension,
            TableRow outputRow,
            string currentValue,
            IDataSetModel model,
            IDataReader currentRow)
        {
            this._uniqID++;
            Table tb = new Table();
            TableRow _rw = new TableRow();
            Table tb_extra = (this._useSdmxAttr) ? CreateDimensionAttributeTable(dimension, model, currentRow) : null;
            if (tb_extra != null)
            {
                tb_extra.AddAttribute("ID", this._uniqID + "_dim_info_extra_dialog");
                tb_extra.AddClass(HtmlClasses.ExtraInfoTable);

                tb.AddRow(new TableRow(new TableCell(tb_extra)));

                var tb_btn_extra = new TableCell();
                tb_btn_extra.AddClass(HtmlClasses.ExtraInfoWrapper);
                tb_btn_extra.AddAttribute("ID", this._uniqID + "_dim_info");

                _rw.AddCell(tb_btn_extra);
            }

            string text = this.GetLocalizedName(dimension, currentValue);
            var tb_dim = new TableCell();
            tb_dim.AddClass(HtmlClasses.VerticalKeyValue);

            if (dimension == "TIME_PERIOD") tb_dim.AddAttribute("style", "white-space:nowrap");

            tb_dim.SetupDisplayText(currentValue, text, dimension, model.GetDisplayMode(dimension, currentValue), this._enhancedOutput);

            _rw.AddCell(tb_dim);
            tb.AddRow(_rw);
            TableCell tb_cell = new TableCell(tb);

            outputRow.AddCell(tb_cell);
            verticalPreviousValues[dimension] = tb_cell;
        }
        /// <summary>
        /// Parse a data row and populate the <see cref="RendererState.CurrentTableRow"/> with the X, Y axis key values and the data
        /// </summary>
        /// <param name="state">
        /// The current state
        /// </param>
        protected virtual void ParseDataRow(RendererState state, object vc = null, object vt = null)
        {
            #region check if something has changed
            state.HorizontalCurrentKeySet = MakeKey(state.Model.HorizontalKeys, state.InputRow);
            if (!string.Equals(state.HorizontalCurrentKeySet, state.HorizontalOldKeySet))
            {
                state.CurrentHorizontalKeySetColumn++;
                state.HorizontalOldKeySet = state.HorizontalCurrentKeySet;

                foreach (TableRow row in state.VerticalKeySetIndex.Values)
                {

                    TableCell emptyMeasure = new TableCell("-");
                    emptyMeasure.AddClass(HtmlClasses.NotMeasure);
                    row.AddElement(emptyMeasure);
                }

                foreach (string dim in state.Model.HorizontalKeys)
                {
                    TableRow horizontalKeyRow = state.HorizontalKeyRows[dim];
                    var currentValue = state.InputRow[dim] as string;

                    this.AddHorrizontalKeyValues(
                        state.VerticalPreviousValuesMap,
                        dim,
                        horizontalKeyRow,
                        currentValue,
                        state.Model,
                        state.InputRow);

                }
            }
            #endregion

            TableRow currentRow;

            state.VerticalCurrentKeySet = MakeKey(state.Model.VerticalKeys, state.InputRow);
            if (!state.VerticalKeySetIndex.TryGetValue(state.VerticalCurrentKeySet, out currentRow))
            {
                state.CurrentTableRow = new TableRow();
                if (state.Model.VerticalKeys.Count == 0 && state.Model.HorizontalKeys.Count > 0)
                {
                    TableCell emptyMeasure = new TableCell("-");
                    emptyMeasure.AddClass(HtmlClasses.NotMeasure);
                    state.CurrentTableRow.AddElement(emptyMeasure);
                }

                state.VerticalKeySetIndex.Add(state.VerticalCurrentKeySet, state.CurrentTableRow);
                state.VerticalOrderedRows.Add(state.CurrentTableRow);

                foreach (string dim in state.Model.VerticalKeys)
                {
                    var currentValue = state.InputRow[dim] as string;
                    this.AddVerticalKeyValues(
                        state.HorizontalPreviousValuesMap,
                        dim,
                        state.CurrentTableRow,
                        currentValue,
                        state.Model,
                        state.InputRow);
                }

                int currentVerticalKeyValueCount = state.CurrentTableRow.Children.Count;
                state.VerticalKeyValueCount.Add(state.VerticalCurrentKeySet, currentVerticalKeyValueCount);

                state.CurrentVerticalKeyValueCount = currentVerticalKeyValueCount;

                for (int i = 0; i < state.CurrentHorizontalKeySetColumn; i++)
                {
                    TableCell emptyMeasure = new TableCell("-");
                    emptyMeasure.AddClass(HtmlClasses.NotMeasure);
                    state.CurrentTableRow.AddElement(emptyMeasure);
                }
            }
            else
            {
                state.CurrentTableRow = currentRow;
                state.CurrentVerticalKeyValueCount = state.VerticalKeyValueCount[state.VerticalCurrentKeySet];
            }

            //var time = state.InputRow[state.Model.KeyFamily.TimeDimension.Id] as string;
            NumberStyles style;
            style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowLeadingSign;

            var val = state.InputRow[state.Model.KeyFamily.PrimaryMeasure.Id] as string;
            if (string.IsNullOrEmpty(val)
                || val == "NaN")
            {
                val = string.Empty;
            }
            else {
                decimal decVal = 0;
                Int32 intVal = 0;
                if (Int32.TryParse(val.ToString(), out intVal))
                {
                    val = intVal.ToString();
                }
                else if (decimal.TryParse(val.ToString(), style, cFrom, out decVal))
                {
                    val = decVal.ToString("F1", cTo);
                }
            }

            TableCell data_cell;
            if (string.IsNullOrEmpty(val))
            {
                data_cell = new TableCell("-");
                data_cell.AddClass(HtmlClasses.NotMeasure);

            }else{

                this._uniqID++;
                Table tb = new Table();
                TableRow _rw = new TableRow();
                // Add table info extra at level observation
                Table tb_extra =
                    (this._useSdmxAttr) ?
                    (!string.IsNullOrEmpty(val)) ?
                        CreateObservationAttribute(state.Model, state.InputRow) : null : null;
                if (tb_extra != null)
                {
                    tb_extra.AddAttribute("ID", this._uniqID + "_info_extra_dialog");
                    tb_extra.AddClass(HtmlClasses.ExtraInfoTable);

                    tb.AddRow(new TableRow(new TableCell(tb_extra)));

                    var tb_btn_extra = new TableCell();
                    tb_btn_extra.AddClass(HtmlClasses.ExtraInfoWrapper);
                    tb_btn_extra.AddAttribute("ID", this._uniqID + "_info");

                    _rw.AddCell(tb_btn_extra);
                }
                /*
                decimal decVal_vc = 0;
                if (vc != null && decimal.TryParse(vc.ToString(), NumberStyles.AllowDecimalPoint, cFrom, out decVal_vc))
                {
                    vc = decVal_vc.ToString("F1", cTo);
                }
                decimal decVal_vt = 0;
                if (vt != null && decimal.TryParse(vt.ToString(), NumberStyles.AllowDecimalPoint, cFrom, out decVal_vt))
                {
                    vt = decVal_vt.ToString("F1", cTo);
                }
                */
                TableCell measure = new TableCell((string.IsNullOrEmpty(val)) ? "-" : val);
                measure.AddClass((string.IsNullOrEmpty(val)) ? HtmlClasses.NotMeasure : HtmlClasses.Measure);
                measure.AddAttribute("data-v", (string.IsNullOrEmpty(val)) ? "-" : val);
                measure.AddAttribute("data-vc", (vc == null) ? "?" : vc.ToString());
                measure.AddAttribute("data-vt", (vt == null) ? "?" : vt.ToString());

                _rw.AddCell(measure);

                tb.AddRow(_rw);

                data_cell = new TableCell(tb);
                data_cell.AddClass(HtmlClasses.ExtraInfoTableValue);

            }

            int column = state.CurrentHorizontalKeySetColumn + state.CurrentVerticalKeyValueCount;
            state.CurrentTableRow.AddAt(data_cell, column);
        }