private void CargarInferencia()
    {
        TuCuento.Entidades.HistoriaDetalle oDetalle = new TuCuento.Entidades.HistoriaDetalle();
        List<TuCuento.Entidades.Condicion> oLstCond = new List<TuCuento.Entidades.Condicion>();
        TuCuento.Entidades.Condicion oCondicion;
        TuCuento.Entidades.CondicionValPosible oValPosible;
        DropDownList ddlVPosible;

        foreach (GridViewRow grdRow in gvCondiciones.Rows)
        {
            //Obtengo el combo
            ddlVPosible = (DropDownList)(gvCondiciones.Rows[grdRow.RowIndex].Cells[1].FindControl("ddlValPosible"));

            if (Convert.ToInt32(ddlVPosible.SelectedValue) > 0)
            {
                oCondicion = new TuCuento.Entidades.Condicion();
                oValPosible = new TuCuento.Entidades.CondicionValPosible();

                oValPosible.nCod_ValPosible = Convert.ToInt32(ddlVPosible.SelectedValue);
                oValPosible.sOperadorLogico = ddlVPosible.SelectedItem.Text.Substring(0, 2);
                oValPosible.sValor = ddlVPosible.SelectedItem.Text.Substring(2);

                //Obtengo el nCod_Condicion
                oCondicion.nCod_Condicion = Convert.ToInt32(Server.HtmlDecode(grdRow.Cells[0].Text.Trim()));
                oCondicion.sNombre = Server.HtmlDecode(grdRow.Cells[1].Text.Trim());
                oCondicion.lstValPosible = new List<TuCuento.Entidades.CondicionValPosible>();
                oCondicion.lstValPosible.Add(oValPosible);

                oLstCond.Add(oCondicion);
            }
        }

        foreach (ListItem item in lvAccionesInf.Items)
        {
            TuCuento.Entidades.Accion oAccion = new TuCuento.Entidades.Accion();
            oAccion.nCod_Accion = Convert.ToInt32(item.Value);
            oDetalle.Inferencia.Accion.Add(oAccion);
        }

        //oDetalle.Inferencia.Accion.nCod_Accion = Convert.ToInt32(lvAccionesInf.SelectedValue);
        oDetalle.Inferencia.Condiciones = oLstCond;
        oDetalle.nCod_Historia = Convert.ToInt32(HfnCod_Historia.Value);
        oDetalle.nCod_TipoHistoriaDetalle = Funciones.CodigoTipoHistoriaDetalle(Funciones.TipoHistoriaDetalle.Inferencia.ToString());

        if (HfnOrden.Value == "")
        {
            oDetalle.nOrden = lstDetalleHistoria.Count + 1;
            lstDetalleHistoria.Add(oDetalle);
        }
        else
        {
            oDetalle.nOrden = Convert.ToInt32(HfnOrden.Value)+1; //Porque el valor que tome en el hiden es el valor de la lista que comineza por 0
            lstDetalleHistoria[Convert.ToInt32(HfnOrden.Value)] = oDetalle;
        }

    }
    private void CargarListaDetalle(int nCod_Historia)
    {
        DataTable oTabla = TuCuento.Negocio.HistoriaDetalle_NEG.ListarDetalleHistoria(nCod_Historia);

        foreach (DataRow oFila in oTabla.Rows)
        {
            TuCuento.Entidades.HistoriaDetalle oDetalle = new TuCuento.Entidades.HistoriaDetalle();

            oDetalle.nCod_Historia = Convert.ToInt32(oFila["nCod_Historia"].ToString());
            oDetalle.nCod_TipoHistoriaDetalle = Convert.ToInt32(oFila["nCod_TipoHistoriaDetalle"].ToString());
            oDetalle.nOrden = Convert.ToInt32(oFila["nOrden"].ToString());

            Funciones.TipoHistoriaDetalle oTipo = (Funciones.TipoHistoriaDetalle)oDetalle.nCod_TipoHistoriaDetalle;

            if (Funciones.TipoHistoriaDetalle.Texto == oTipo)
            {
                DataTable oTexto = TuCuento.Negocio.HistoriaDetalle_NEG.TraerTexto(oDetalle.nCod_Historia, oDetalle.nOrden);

                oDetalle.Texto.sTexto = oTexto.Rows[0]["sTexto"].ToString();

            }
            else
            {
                TuCuento.Entidades.HistoriaDetInf oInferencia = new TuCuento.Entidades.HistoriaDetInf();
                //Traigo las condiciones
                DataTable oTablaInferencia = TuCuento.Negocio.HistoriaDetalle_NEG.TraerCondiciones(nCod_Historia,oDetalle.nOrden);

                foreach (DataRow oFilaInf in oTablaInferencia.Rows)
                {
                    TuCuento.Entidades.Condicion oCondicion = new TuCuento.Entidades.Condicion();
                    TuCuento.Entidades.CondicionValPosible oValPosible = new TuCuento.Entidades.CondicionValPosible();
                    
                    oCondicion.nCod_Condicion = Convert.ToInt32(oFilaInf["nCod_Condicion"].ToString());
                    oCondicion.sNombre = oFilaInf["sNombreCondicion"].ToString();
                    
                    oValPosible.nCod_ValPosible = Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString());
                    oValPosible.sOperadorLogico = oFilaInf["sOperadorLogico"].ToString().PadRight(2,Convert.ToChar(" "));
                    oValPosible.sValor = oFilaInf["sValor"].ToString();

                    oCondicion.lstValPosible = new List<TuCuento.Entidades.CondicionValPosible>();
                    oCondicion.lstValPosible.Add(oValPosible);

                    oInferencia.Condiciones.Add(oCondicion);
                }

                //Traigo las acciones
                oTablaInferencia = TuCuento.Negocio.HistoriaDetalle_NEG.TraerAccion(nCod_Historia, oDetalle.nOrden);

                foreach (DataRow oFilaInf in oTablaInferencia.Rows)
                {
                    TuCuento.Entidades.Accion oAccion = new TuCuento.Entidades.Accion();
                    oAccion.nCod_Accion = Convert.ToInt32(oFilaInf["nCod_Accion"].ToString());
                    //oInferencia.Accion.nCod_Accion = Convert.ToInt32(oFilaInf["nCod_Accion"].ToString());
                    oInferencia.Accion.Add(oAccion);
                }

                oDetalle.Inferencia = oInferencia;

            }

            lstDetalleHistoria.Add(oDetalle);
        }

    }
    protected void btnAgregar_Click(object sender, EventArgs e)
    {

        if (ValidarValPosible())
        {
            if (HfAccionValPosible.Value == "EDIT")
            {
                //Lo busco en la lista y lo modifico
                foreach (TuCuento.Entidades.CondicionValPosible oValPosible in lstValPosibles)
                {
                    if (oValPosible.nCod_ValPosible == Convert.ToInt32(HfnCod_ValPosible.Value))
                    {
                        oValPosible.sOperadorLogico = ddlOperador.SelectedValue;

                        oValPosible.sValor = this.sValorIngresado;

                        break;
                    }
                }
            }
            else
            {
                TuCuento.Entidades.CondicionValPosible oValPosible = new TuCuento.Entidades.CondicionValPosible();

                oValPosible.nCod_ValPosible = lstValPosibles.Count;
                oValPosible.nCod_ValPosible++;

                oValPosible.sOperadorLogico = ddlOperador.SelectedValue;

                oValPosible.sValor = this.sValorIngresado;

                lstValPosibles.Add(oValPosible);
            }

            gvValPosibles.DataSource = lstValPosibles;
            gvValPosibles.DataBind();

            BlanquearControlesValPosible();
            
        }

    }
    protected void gvDatos_SelectedIndexChanged(object sender, EventArgs e)
    {
        InicializarControles();

        GridViewRow row = gvDatos.SelectedRow;
        HfAccion.Value = "EDIT";
        ddlDominioCond.SelectedValue = Server.HtmlDecode(row.Cells[8].Text.Trim());
        HfnCod_Condicion.Value = Server.HtmlDecode(row.Cells[1].Text.Trim());
        this.txtNombre.Text = Server.HtmlDecode(row.Cells[2].Text.Trim());
        this.txtDescripcion.Text = Server.HtmlDecode(row.Cells[3].Text.Trim());
        this.chkHab.Checked = ((CheckBox)row.FindControl("chkHabGrilla")).Checked;
        ddlEntidad.SelectedValue = Server.HtmlDecode(row.Cells[6].Text.Trim());
        
        CargarComboAtributos();
        Session["cuentoAEditar"] = "SSS";
        Server.Transfer("");
        
        //-------------------------------
        //Pagina destino

        GridViewRow row2 = (GridViewRow)Session["cuentoAEditar"];

        ddlAtributo.SelectedValue = Server.HtmlDecode(row.Cells[7].Text.Trim());

        //Paso los valores posibles a la lista
        DataTable oTabla = TuCuento.Negocio.Condicion_NEG.TraerValoresPosibles(Convert.ToInt32(HfnCod_Condicion.Value));

        foreach (DataRow fila in oTabla.Rows)
        {
            TuCuento.Entidades.CondicionValPosible oValPosible = new TuCuento.Entidades.CondicionValPosible();
            oValPosible.nCod_ValPosible = Convert.ToInt32(fila["nCod_ValPosible"]);
            oValPosible.sOperadorLogico  = fila["sOperadorLogico"].ToString();
            oValPosible.sValor  = fila["sValor"].ToString();
            lstValPosibles.Add(oValPosible);
        }

        gvValPosibles.DataSource = lstValPosibles;
        gvValPosibles.DataBind();

        HabDesCtrl(true);
        txtNombre.Focus();

        //Inhabilito los combos de entidad y atributo
        ddlEntidad.Enabled = false;
        ddlAtributo.Enabled = false;
    }
    protected void btnGenerar_Click(object sender, EventArgs e)
    {
        if (Validar())
        {
            txtTexto.Text = "";

            #region Declaración Variables
            List<TuCuento.Entidades.Condicion> oCondiciones = new List<TuCuento.Entidades.Condicion>();
            DropDownList ddlVPosible;
            string sNombreArchivo = "";
            DataTable oTabla;
            int nCod_EntidadAnt = 0;
            int nCod_Hecho = 0;
            int nCod_TipoAtributo = 0;
            int nCod_Dominio = Convert.ToInt32(HfnCod_Dominio.Value);
            int nCod_Entidad = 0;
            int nCod_Atributo = 0;
            int nCod_Historia = 0;
            string sValor;
            int nValor = 0;
            string sOperador = "";
            DateTime dValor;
            bool bEsta;
            XmlDocument xmlDocTerminos = new XmlDocument();
            XmlDocument xmlDocSalida = new XmlDocument();
            bool bHistoriaPrincipal = true;
            string sAccion;
            MICServicio.MICServicio oServicio = new MICServicio.MICServicio();
            List<MICServicio.Termino> oTermino = new List<MICServicio.Termino>();
            List<MICServicio.Hecho> olstHecho = new List<MICServicio.Hecho>();
            MICServicio.Hecho oHecho = new MICServicio.Hecho();
            MICServicio.Termino unTermino = new MICServicio.Termino();
            string[] sRespuesta;
            int[] nCod_HistoriaPrincipal;
            int nPos = 0;
            int nMaxVector = 200;
            
            #endregion

            #region Recorro la grilla para cargar la lista de condiciones (entidad y atributo) y el valor seleccionado (valores posibles)
            foreach (GridViewRow grdRow in gvCondiciones.Rows)
            {
                TuCuento.Entidades.Condicion oCond = new TuCuento.Entidades.Condicion();
                TuCuento.Entidades.CondicionValPosible oValPos = new TuCuento.Entidades.CondicionValPosible();
                
                oCond.nCod_Entidad = Convert.ToInt32(Server.HtmlDecode(grdRow.Cells[0].Text.Trim()));
                oCond.nCod_Atributo = Convert.ToInt32(Server.HtmlDecode(grdRow.Cells[1].Text.Trim()));

                oCond.lstValPosible = new List<TuCuento.Entidades.CondicionValPosible>();

                //Obtengo el combo
                ddlVPosible = (DropDownList)(gvCondiciones.Rows[grdRow.RowIndex].Cells[1].FindControl("ddlValPosible"));

                oValPos.nCod_ValPosible = Convert.ToInt32(ddlVPosible.SelectedValue);
                
                sValor = ddlVPosible.SelectedItem.Text.Substring(2);
                sOperador = ddlVPosible.SelectedItem.Text.Substring(0, 2);

                //Para asignar el valor veo si es el == sino que tipo de datos es y sobore eso asigno el valor
                if (sOperador == "==")
                    oValPos.sValor = sValor;
                else
                {
                    oTabla = TuCuento.Negocio.Entidad_NEG.TraerAtributos(oCond.nCod_Entidad, oCond.nCod_Atributo, -1);

                    nCod_TipoAtributo = Convert.ToInt32(oTabla.Rows[0]["nCod_TipoAtributo"].ToString());

                    //Si es texto y no es igual a ==, entonces es !=
                    if ((Funciones.TipoDato)nCod_TipoAtributo == Funciones.TipoDato.Texto)
                    {
                        //Agrego el mismo texto pero sin la primer letra
                        oValPos.sValor = sValor.Substring(1);
                    }

                    //Si es número
                    if ((Funciones.TipoDato)nCod_TipoAtributo == Funciones.TipoDato.Número)
                    {
                        nValor = Convert.ToInt32(sValor);
                        
                        switch (sOperador.Trim())
                        {
                            case ">":
                                nValor = nValor + 2;
                                break;
                            case ">=":
                            case "<=":
                                break;
                            case "!=":
                            case "<":
                                nValor = nValor - 2;
                                break;
                        }

                        oValPos.sValor = nValor.ToString();
                    }

                    //Si es fecha
                    if ((Funciones.TipoDato)nCod_TipoAtributo == Funciones.TipoDato.Fecha)
                    {
                        dValor = new DateTime(Convert.ToInt32(sValor.Substring(6, 4)), Convert.ToInt32(sValor.Substring(3, 2)), Convert.ToInt32(sValor.Substring(0, 2)));

                        switch (sOperador.Trim())
                        {
                            case ">":
                                dValor = dValor.AddDays(2);
                                break;
                            case ">=":
                            case "<=":
                                break;
                            case "!=":
                            case "<":
                                dValor = dValor.AddDays(-2);
                                break;
                        }

                        oValPos.sValor = dValor.Day.ToString().PadLeft(2, Convert.ToChar("0")) + "/" + dValor.Month.ToString().PadLeft(2, Convert.ToChar("0")) + "/" + dValor.Year.ToString().PadLeft(4, Convert.ToChar("0"));
                    }

                }
                oCond.lstValPosible.Add(oValPos);

                oCondiciones.Add(oCond);

            }
            #endregion

            #region Completo las entidades y atributos a utilizar

            //Traigo todas las entidades y atributos que son usados en las reglas y completo la lista
            oTabla = TuCuento.Negocio.Condicion_NEG.ListarCondiciones(-1, 1, nCod_Dominio);
            foreach (DataRow oFila in oTabla.Rows)
            {
                nCod_Entidad = Convert.ToInt32(oFila["nCod_Entidad"].ToString());
                nCod_Atributo = Convert.ToInt32(oFila["nCod_Atributo"].ToString());

                bEsta = false;

                //veo que si no esta en la lista
                foreach (TuCuento.Entidades.Condicion oCond in oCondiciones)
                {
                    if (oCond.nCod_Entidad == nCod_Entidad && oCond.nCod_Atributo == nCod_Atributo)
                    {
                        bEsta = true;
                        break;
                    }
                }

                //Si no esta lo agrego a la lista
                if (!bEsta)
                {
                    TuCuento.Entidades.Condicion oCondicionNueva = new TuCuento.Entidades.Condicion();
                    TuCuento.Entidades.CondicionValPosible oValPos = new TuCuento.Entidades.CondicionValPosible();

                    oCondicionNueva.nCod_Entidad = nCod_Entidad;
                    oCondicionNueva.nCod_Atributo = nCod_Atributo;

                    oValPos.sValor = "";

                    //oCondicionNueva.lstValPosible = new List<TuCuento.Entidades.CondicionValPosible>();
                    //oCondicionNueva.lstValPosible.Add(oValPos);

                    oCondiciones.Add(oCondicionNueva);
                }

            }

            #endregion

            //Genero el archivo y llamo al motor de inferencia
            if (TuCuento.Negocio.Cuento_NEG.GenerarCuento(Session.SessionID, Request.PhysicalApplicationPath, nCod_Dominio, HfsDesc_Dominio.Value, lstDetalleHistoria, oCondiciones, ref sNombreArchivo))
            {
                #region Armo la lista de terminos y hechos

                foreach (TuCuento.Entidades.Condicion oCondicion in oCondiciones)
                {

                    if (nCod_EntidadAnt != oCondicion.nCod_Entidad)
                    {
                        if (nCod_EntidadAnt != 0) //Si no es la primera vez que pasa
                        {
                            unTermino.Hecho = olstHecho.ToArray();
                            oTermino.Add(unTermino);
                            unTermino = new MICServicio.Termino();
                            olstHecho = new List<MICServicio.Hecho>();
                        }

                        //Termino-Hechos
                        unTermino.nCodTermino = oCondicion.nCod_Entidad;
                        //Traigo el nombre de la entidad
                        oTabla = TuCuento.Negocio.Entidad_NEG.ListarEntidades(unTermino.nCodTermino, -1);
                        unTermino.sDescTermino = oTabla.Rows[0]["sNombre"].ToString();
                        unTermino.sDescTermino = unTermino.sDescTermino.Replace(" ", "_");
                        nCod_EntidadAnt = oCondicion.nCod_Entidad;
                        nCod_Hecho = 0;
                    }

                    oHecho = new MICServicio.Hecho();

                    nCod_Hecho++;

                    //Traigo los datos del atributo
                    oTabla = TuCuento.Negocio.Entidad_NEG.TraerAtributos(oCondicion.nCod_Entidad, oCondicion.nCod_Atributo, -1);

                    oHecho.nCodHecho = nCod_Hecho;
                    oHecho.sDescHecho = oTabla.Rows[0]["sNombre"].ToString();
                    oHecho.sDescHecho = oHecho.sDescHecho.Replace(" ", "_");
                    oHecho.nCodTipoDato = Convert.ToInt32(oTabla.Rows[0]["nCod_TipoAtributo"].ToString());

                    if (oCondicion.lstValPosible != null)
                    {
                        if (oHecho.nCodTipoDato != 5)
                            oHecho.sValorInicial = oCondicion.lstValPosible[0].sValor;
                        else
                        {
                            if (oCondicion.lstValPosible[0].sValor == "VERDADERO")
                                oHecho.sValorInicial = "true";
                            else
                                oHecho.sValorInicial = "false";
                        }
                    }

                    oHecho.nModificado = 0;

                    olstHecho.Add(oHecho);

                }


                //Agrego el último que paso
                unTermino.Hecho = olstHecho.ToArray();
                oTermino.Add(unTermino);

                #endregion

                #region Levanto el archivo

                FileStream reglaStream = new FileStream(sNombreArchivo, FileMode.Open, FileAccess.Read);
                //Stream reglaStream = UploadFile.PostedFile.InputStream;
                //int reglaLen = UploadFile.PostedFile.ContentLength;
                long reglaLen = reglaStream.Length;
                //string reglaContentType = UploadFile.PostedFile.ContentType;
                BinaryReader reglaBinaria = new BinaryReader(reglaStream);
                
                //byte[] reglaBinaryData = new byte[reglaLen];
                byte[] reglaBinaryData = reglaBinaria.ReadBytes(Convert.ToInt32(reglaLen));

                reglaBinaria.Close();
                //int n = reglaStream.Read(reglaBinaryData,0,reglaLen);
                
                #endregion

                sRespuesta = oServicio.EjecutarRegla(reglaBinaryData, oTermino.ToArray());

                if (sRespuesta[0] == "Ok")
                {
                    #region Proceso el resultado de la regla

                    xmlDocTerminos.LoadXml("<ROOT>" + sRespuesta[1] + "</ROOT>");
                    xmlDocSalida.LoadXml("<ROOT>" + sRespuesta[2] + "</ROOT>");

                    nCod_HistoriaPrincipal = new int[nMaxVector];

                    //Pongo el resultado en el textbox a partir de la lista lstDetalleHistoria
                    for (int nI=0; nI < lstDetalleHistoria.Count;nI++)
                    {
                        bHistoriaPrincipal = true;

                        TuCuento.Entidades.HistoriaDetalle oDetalle = lstDetalleHistoria[nI];

                        //Busco la historia principal, la que no es disparada por ninguna acción
                        foreach (TuCuento.Entidades.HistoriaDetalle oHistoria in lstDetalleHistoria)
                        {
                            
                            foreach (TuCuento.Entidades.Accion oAccion in oHistoria.Inferencia.Accion)
                            {
                                if (oAccion.Historia != null)
                                {
                                    if (oDetalle.nCod_Historia == oAccion.Historia.nCod_Historia)
                                    {
                                        //busco si esta en la lista y lo quito

                                        for (int nII = 0; nII < nPos; nII++)
                                        {
                                            if (nCod_HistoriaPrincipal[nII] == oDetalle.nCod_Historia)
                                                nCod_HistoriaPrincipal[nII] = 0;
                                        }

                                        bHistoriaPrincipal = false;
                                        break;
                                    }
                                }
                            }
                            if (!bHistoriaPrincipal)
                                break;
                    
                        }

                        if (bHistoriaPrincipal)
                        {
                            bool bEstaHistoria = false;
                            
                            for (int nII = 0; nII < nPos; nII++)
                            {
                                if (nCod_HistoriaPrincipal[nII] == oDetalle.nCod_Historia)
                                {
                                    bEstaHistoria = true;
                                    break;
                                }
                            }

                            if (!bEstaHistoria)
                            {
                                //La agrego a la lista de historias a generar el texto
                                nCod_HistoriaPrincipal[nPos] = oDetalle.nCod_Historia;
                                nPos++;
                            }
                        }

                    }

                    //Agrego el texto de la historia al textbox
                    for (int nII = 0; nII < nPos; nII++)
                    {
                        if (nCod_HistoriaPrincipal[nII] != 0)
                            AgregarTexto(nCod_HistoriaPrincipal[nII]);
                    }
                    

                    System.Xml.XmlNodeList oLstAcciones = xmlDocSalida.SelectNodes("./ROOT/Accion");

                    foreach (System.Xml.XmlNode unaAccion in oLstAcciones)
                    {
                        //Obtengo el nombre de la historia a ejecutar
                        sAccion = unaAccion.Attributes["sAccion"].InnerText;

                        sAccion = sAccion.Replace("MIC.ejecuta('", "").Replace("')", "");

                        //Busco el código de la historia
                        oTabla = TuCuento.Negocio.Historia_NEG.ListarHistorias(-1, -1, sAccion, nCod_Dominio);

                        nCod_Historia = Convert.ToInt32(oTabla.Rows[0]["nCod_Historia"].ToString());

                        //Recoorro la lista y agrego el texto
                        foreach (TuCuento.Entidades.HistoriaDetalle oDetalle in lstDetalleHistoria)
                        {
                            if (oDetalle.nCod_Historia == nCod_Historia)
                            {
                                AgregarTexto(nCod_Historia);
                                break;
                            }
                        }

                    }

                    MostrarPanel(2);

                    #endregion

                }
                else
                {
                    Master.MensajeError = "Se produjo un error en la inferencia. Por favor, intente más tardes.";
                }
            }

        }
    }
    private void CargarListaDetalle(int nCod_Historia)
    {
        DataTable oTabla = TuCuento.Negocio.HistoriaDetalle_NEG.ListarDetalleHistoria(nCod_Historia);
        List<TuCuento.Entidades.EntidadAtributo> lstEntidadNoMostrar = new List<TuCuento.Entidades.EntidadAtributo>();
        
        foreach (DataRow oFila in oTabla.Rows)
        {
            TuCuento.Entidades.HistoriaDetalle oDetalle = new TuCuento.Entidades.HistoriaDetalle();

            oDetalle.nCod_Historia = Convert.ToInt32(oFila["nCod_Historia"].ToString());
            oDetalle.nCod_TipoHistoriaDetalle = Convert.ToInt32(oFila["nCod_TipoHistoriaDetalle"].ToString());
            oDetalle.nOrden = Convert.ToInt32(oFila["nOrden"].ToString());

            Funciones.TipoHistoriaDetalle oTipo = (Funciones.TipoHistoriaDetalle)oDetalle.nCod_TipoHistoriaDetalle;

            if (Funciones.TipoHistoriaDetalle.Texto == oTipo)
            {
                DataTable oTexto = TuCuento.Negocio.HistoriaDetalle_NEG.TraerTexto(oDetalle.nCod_Historia, oDetalle.nOrden);

                oDetalle.Texto.sTexto = oTexto.Rows[0]["sTexto"].ToString();

            }
            else
            {
                TuCuento.Entidades.HistoriaDetInf oInferencia = new TuCuento.Entidades.HistoriaDetInf();
                //Traigo las condiciones
                DataTable oTablaInferencia = TuCuento.Negocio.HistoriaDetalle_NEG.TraerCondiciones(nCod_Historia, oDetalle.nOrden);

                foreach (DataRow oFilaInf in oTablaInferencia.Rows)
                {
                    TuCuento.Entidades.Condicion oCondicion = new TuCuento.Entidades.Condicion();
                    TuCuento.Entidades.CondicionValPosible oValPosible = new TuCuento.Entidades.CondicionValPosible();

                    oCondicion.nCod_Condicion = Convert.ToInt32(oFilaInf["nCod_Condicion"].ToString());
                    oCondicion.nCod_Entidad = Convert.ToInt32(oFilaInf["nCod_Entidad"].ToString());
                    oCondicion.nCod_Atributo = Convert.ToInt32(oFilaInf["nCod_Atributo"].ToString());

                    bool bEstaValPosible = false;
                    bool bEstaEntidadAtributo = false;

                    foreach (Inferencia oDato in lstInferencia)
                    {
                        if (oDato.nCod_Entidad == oCondicion.nCod_Entidad && oDato.nCod_Atributo == oCondicion.nCod_Atributo)
                        {
                            bEstaEntidadAtributo = true;
                            foreach (ValPosible oDatoVal in oDato.lstValPosible)
                            {
                                if (oDatoVal.nCod_ValPosible == Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString()))
                                {
                                    bEstaValPosible = true;
                                    break;
                                }
                            }
                            if (!bEstaValPosible)
                            {
                                ValPosible oCValPos = new ValPosible();
                                oCValPos.nCod_ValPosible = Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString());
                                oCValPos.sOperadorLogico = oFilaInf["sOperadorLogico"].ToString();
                                oCValPos.sValor = oFilaInf["sValor"].ToString();

                                if (oDato.lstValPosible == null)
                                {
                                    List<ValPosible> oValPos = new List<ValPosible>();
                                    oValPos.Add(oCValPos);
                                    oDato.lstValPosible = oValPos;
                                }
                                else
                                {
                                    oDato.lstValPosible.Add(oCValPos);
                                }
                                
                            }
                        }
                        if (bEstaEntidadAtributo)
                            break;
                    }

                    
                    if (!bEstaEntidadAtributo)
                    {
                        Inferencia oInf = new Inferencia(oCondicion.nCod_Entidad, oCondicion.nCod_Atributo, oFilaInf["sAtributo"].ToString());
                        List<ValPosible> oValPos = new List<ValPosible>();

                        ValPosible oCValPos = new ValPosible();
                        oCValPos.nCod_ValPosible = Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString());
                        oCValPos.sOperadorLogico = oFilaInf["sOperadorLogico"].ToString();
                        oCValPos.sValor = oFilaInf["sValor"].ToString();
                        oValPos.Add(oCValPos);
                        oInf.lstValPosible = oValPos;

                        lstInferencia.Add(oInf);
                    }
                                    
                    oValPosible.nCod_ValPosible = Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString());
                    oValPosible.sOperadorLogico = oFilaInf["sOperadorLogico"].ToString();
                    oValPosible.sValor = oFilaInf["sValor"].ToString();

                    oCondicion.lstValPosible = new List<TuCuento.Entidades.CondicionValPosible>();
                    oCondicion.lstValPosible.Add(oValPosible);

                    oInferencia.Condiciones.Add(oCondicion);
                }

                //Traigo las acciones
                oTablaInferencia = TuCuento.Negocio.HistoriaDetalle_NEG.TraerAccion(nCod_Historia, oDetalle.nOrden);

                foreach (DataRow oFilaInf in oTablaInferencia.Rows)
                {
                    TuCuento.Entidades.Accion oAccion = new TuCuento.Entidades.Accion();
                    oAccion.nCod_Accion = Convert.ToInt32(oFilaInf["nCod_Accion"].ToString());
                    oAccion.nCod_TipoAccion = Convert.ToInt32(oFilaInf["nCod_TipoAccion"].ToString());

                    //Si modifica un hecho busco cual es el hecho y lo agrego a la lista de hechos que no tengo que mostrar
                    if ((Funciones.TipoAccion)oAccion.nCod_TipoAccion == Funciones.TipoAccion.ModHecho)
                    {
                        DataTable oAccionModHecho = TuCuento.Negocio.Accion_NEG.ListarAcciones(oAccion.nCod_Accion, -1, -1);

                        TuCuento.Entidades.EntidadAtributo oEntAtrr = new TuCuento.Entidades.EntidadAtributo();
                        oEntAtrr.nCod_Entidad = Convert.ToInt32(oAccionModHecho.Rows[0]["nCod_Entidad"].ToString());
                        oEntAtrr.nCod_Atributo = Convert.ToInt32(oAccionModHecho.Rows[0]["nCod_Atributo"].ToString());

                        lstEntidadNoMostrar.Add(oEntAtrr);
                    }
                    else
                    {
                        oAccion.Historia = new TuCuento.Entidades.AccionHistoria();
                        oAccion.Historia.nCod_Historia = Convert.ToInt32(oFilaInf["nCod_HistoriaAccion"].ToString());
                    }

                    oInferencia.Accion.Add(oAccion);
                }

                oDetalle.Inferencia = oInferencia;

            }

            lstDetalleHistoria.Add(oDetalle);
        }

        //Quito las entidades y atributos que van a ser inferidos
        foreach (TuCuento.Entidades.EntidadAtributo oEnt in lstEntidadNoMostrar) 
        {
            foreach (Inferencia oInf in lstInferencia)
            {
                if (oEnt.nCod_Entidad == oInf.nCod_Entidad && oEnt.nCod_Atributo == oInf.nCod_Atributo)
                {
                    lstInferencia.Remove(oInf);
                    break;
                }
            }
        }

    }