/// <summary>
        /// Busca uno o mas hechos que correspondan con los filtros enviados como parámetro.
        /// Si un filtro es nulo entonces no se considera para filtrar al hecho
        /// </summary>
        /// <param name="idConcepto">Identificador del concepto buscad</param>
        /// <param name="entidad">Entidad a considerar del concepto</param>
        /// <param name="unidad">Unidad buscada del hecho</param>
        /// <param name="fechaInicio">Fecha posible de inicio</param>
        /// <param name="fechaFin">Fecha posible de fin</param>
        /// <param name="valoresDimensiones">Valores dimensionales a considerar</param>
        /// <param name="considerarDimensiones">Indica si se deben de considerar o no las dimensiones para buscar un hecho</param>
        /// <returns>Lista de hechos que corresponden con la búsqueda</returns>
        public IList <HechoDto> BuscarHechos(string idConcepto, EntidadDto entidad, UnidadDto unidad, DateTime fechaInicio, DateTime fechaFin, IList <DimensionInfoDto> valoresDimensiones,
                                             bool considerarDimensiones = true)
        {
            IList <HechoDto> hechosResultado = new List <HechoDto>();

            foreach (var listaHechos in HechosPorIdConcepto.Where(x => x.Key.Equals(idConcepto)))
            {
                foreach (var idHecho in listaHechos.Value)
                {
                    var hecho       = HechosPorId[idHecho];
                    var contexto    = ContextosPorId.ContainsKey(hecho.IdContexto) ? ContextosPorId[hecho.IdContexto] : null;
                    var unidadHecho = !String.IsNullOrEmpty(hecho.IdUnidad) && UnidadesPorId.ContainsKey(hecho.IdUnidad) ? UnidadesPorId[hecho.IdUnidad] : null;
                    if (contexto != null)
                    {
                        if (entidad != null)
                        {
                            //Revisar entidad
                            if (!String.IsNullOrEmpty(entidad.EsquemaId) && !entidad.EsquemaId.Equals(contexto.Entidad.EsquemaId))
                            {
                                continue;
                            }
                            if (!String.IsNullOrEmpty(entidad.Id) && !entidad.Id.Equals(contexto.Entidad.Id))
                            {
                                continue;
                            }
                        }
                        //Verificar unidad
                        if (unidad != null && unidadHecho != null && !unidadHecho.EsEquivalente(unidad))
                        {
                            continue;
                        }
                        //Verificar fechas
                        if (contexto.Periodo.Tipo == Period.Instante)
                        {
                            if (!contexto.Periodo.FechaInstante.Equals(fechaFin))
                            {
                                continue;
                            }
                        }
                        else if (contexto.Periodo.Tipo == Period.Duracion)
                        {
                            if (!contexto.Periodo.FechaFin.Equals(fechaFin) || !contexto.Periodo.FechaInicio.Equals(fechaInicio))
                            {
                                continue;
                            }
                        }
                        //Verificar dimensiones
                        if (considerarDimensiones && !contexto.SonDimensionesEquivalentes(valoresDimensiones))
                        {
                            continue;
                        }
                        hechosResultado.Add(hecho);
                    }
                }
            }
            return(hechosResultado);
        }
        /// <summary>
        /// Libera los recursos asociados al documento de instancia
        /// </summary>
        public void Cerrar()
        {
            this.Taxonomia = null;

            if (ContextosPorFecha != null)
            {
                ContextosPorFecha.Clear();
                ContextosPorFecha = null;
            }

            if (EntidadesPorId != null)
            {
                EntidadesPorId.Clear();
                EntidadesPorId = null;
            }

            if (Errores != null)
            {
                Errores.Clear();
                Errores = null;
            }

            if (HechosPorIdContexto != null)
            {
                HechosPorIdContexto.Clear();
                HechosPorIdContexto = null;
            }

            if (HechosPorIdConcepto != null)
            {
                HechosPorIdConcepto.Clear();
                HechosPorIdConcepto = null;
            }

            if (HechosPorIdUnidad != null)
            {
                HechosPorIdUnidad.Clear();
                HechosPorIdUnidad = null;
            }

            if (UnidadesPorId != null)
            {
                UnidadesPorId.Clear();
                UnidadesPorId = null;
            }

            if (ContextosPorId != null)
            {
                foreach (var ctx in ContextosPorId.Values)
                {
                    if (ctx.Entidad != null)
                    {
                        if (ctx.Entidad.ValoresDimension != null)
                        {
                            ctx.Entidad.ValoresDimension.Clear();
                            ctx.Entidad.ValoresDimension = null;
                        }
                        ctx.Entidad = null;
                    }
                    if (ctx.Periodo != null)
                    {
                        ctx.Periodo = null;
                    }
                    if (ctx.ValoresDimension != null)
                    {
                        ctx.ValoresDimension.Clear();
                        ctx.ValoresDimension = null;
                    }
                }
                ContextosPorId.Clear();
                ContextosPorId = null;
            }

            if (HechosPorId != null)
            {
                foreach (var hecho in HechosPorId.Values)
                {
                    LiberarHecho(hecho);
                }
                HechosPorId.Clear();
            }

            if (DtsDocumentoInstancia != null)
            {
                DtsDocumentoInstancia.Clear();
                DtsDocumentoInstancia = null;
            }

            if (estructurasDocumentoInstanciaPorRol != null)
            {
                foreach (var est in estructurasDocumentoInstanciaPorRol.Values)
                {
                    est.Clear();
                }
                estructurasDocumentoInstanciaPorRol.Clear();
            }
        }
        /// <summary>
        /// Importa los datos de un hecho de otro documento de instancia.
        /// Busca unidad o contexto que sea equivalente, de otra forma crea unidades y contextos asociados
        /// </summary>
        /// <param name="hechoImportar">Hecho a importar</param>
        /// <param name="instancia">Documento de instancia orgien del hecho</param>
        /// <returns>ID del hecho importado en le documento de instancia</returns>
        public String ImportarHecho(HechoDto hechoImportar, DocumentoInstanciaXbrlDto instancia)
        {
            String nuevoId = null;

            if (this.Taxonomia.ConceptosPorId.ContainsKey(hechoImportar.IdConcepto))
            {
                nuevoId = "I" + Guid.NewGuid().ToString();
                String idContexto = null;
                String idUnidad   = null;

                if (hechoImportar.IdUnidad != null)
                {
                    UnidadDto unidadOrigen      = instancia.UnidadesPorId[hechoImportar.IdUnidad];
                    var       uniadesNuevoHecho = BuscarUnidades(unidadOrigen.Tipo, Unit.Medida == unidadOrigen.Tipo ?unidadOrigen.Medidas :unidadOrigen.MedidasNumerador, unidadOrigen.MedidasDenominador);
                    if (uniadesNuevoHecho != null && uniadesNuevoHecho.Count > 0)
                    {
                        idUnidad = uniadesNuevoHecho[0].Id;
                    }
                    else
                    {
                        var unidadDestino = new UnidadDto()
                        {
                            Id                 = "UI" + Guid.NewGuid().ToString(),
                            Tipo               = unidadOrigen.Tipo,
                            Medidas            = unidadOrigen.Medidas,
                            MedidasNumerador   = unidadOrigen.MedidasNumerador,
                            MedidasDenominador = unidadOrigen.MedidasDenominador
                        };
                        UnidadesPorId.Add(unidadDestino.Id, unidadDestino);
                        idUnidad = unidadDestino.Id;
                    }
                }

                if (hechoImportar.IdContexto != null)
                {
                    ContextoDto contextoOrigen = instancia.ContextosPorId[hechoImportar.IdContexto];
                    var         valoresDim     = new List <DimensionInfoDto>();
                    if (contextoOrigen.Entidad.ValoresDimension != null)
                    {
                        valoresDim.AddRange(contextoOrigen.Entidad.ValoresDimension);
                    }
                    if (contextoOrigen.ValoresDimension != null)
                    {
                        valoresDim.AddRange(contextoOrigen.ValoresDimension);
                    }

                    var contextos = BuscarContexto(contextoOrigen.Entidad.EsquemaId + ":" + contextoOrigen.Entidad.Id, contextoOrigen.Periodo.Tipo,
                                                   contextoOrigen.Periodo.Tipo == Period.Instante? contextoOrigen.Periodo.FechaInstante:contextoOrigen.Periodo.FechaInicio,
                                                   contextoOrigen.Periodo.Tipo == Period.Instante? contextoOrigen.Periodo.FechaInstante:contextoOrigen.Periodo.FechaFin,
                                                   valoresDim
                                                   );
                    if (contextos != null && contextos.Count > 0)
                    {
                        idContexto = contextos[0].Id;
                        //LogUtil.Info("{contextoOrigen.Entidad.Id: [" + contextoOrigen.Entidad.Id + "], contextoDocumento.Entidad.Id:[" + contextos[0].Entidad.Id + "]}");
                    }
                    else
                    {
                        var contextoDestino = new ContextoDto()
                        {
                            Entidad = new EntidadDto()
                            {
                                ContieneInformacionDimensional = contextoOrigen.Entidad.ContieneInformacionDimensional,
                                EsquemaId = contextoOrigen.Entidad.EsquemaId,
                                Id        = contextoOrigen.Entidad.Id
                            },
                            ContieneInformacionDimensional = contextoOrigen.ContieneInformacionDimensional,
                            Periodo = new PeriodoDto()
                            {
                                Tipo          = contextoOrigen.Periodo.Tipo,
                                FechaInicio   = contextoOrigen.Periodo.FechaInicio,
                                FechaFin      = contextoOrigen.Periodo.FechaFin,
                                FechaInstante = contextoOrigen.Periodo.FechaInstante
                            },
                            ValoresDimension = contextoOrigen.ValoresDimension,
                            Id = "CI" + Guid.NewGuid().ToString()
                        };
                        ContextosPorId[contextoDestino.Id] = contextoDestino;
                        idContexto = contextoDestino.Id;
                    }
                }

                var hechoNuevo = CrearHecho(hechoImportar.IdConcepto, idUnidad, idContexto, nuevoId);
                hechoNuevo.Valor         = hechoImportar.Valor;
                hechoNuevo.ValorNumerico = hechoImportar.ValorNumerico;


                HechosPorId[nuevoId] = hechoNuevo;
                if (!HechosPorIdConcepto.ContainsKey(hechoNuevo.IdConcepto))
                {
                    HechosPorIdConcepto[hechoNuevo.IdConcepto] = new List <String>();
                }
                HechosPorIdConcepto[hechoNuevo.IdConcepto].Add(nuevoId);
            }

            return(nuevoId);
        }