/// <summary>
 /// Valida que el periodo asociado al contexto relacionado con un hecho reportado corresponga según el tipo de periodo indicado para el elemento en la taxonomía.
 /// </summary>
 /// <param name="hecho">el hecho a validar</param>
 private void ValidarContextoDeHecho(Fact hecho)
 {
     if (hecho is FactItem)
     {
         FactItem item = (FactItem)hecho;
         if (((ConceptItem)item.Concepto).TipoPeriodo.Name.Equals(ConceptItem.InstantPeriodType) && item.Contexto.Periodo.Tipo != Period.Instante)
         {
             ManejadorErrores.ManejarError(null, "5.1.1.1 Se encontró un hecho reportado en el documento instancia cuyo tipo de periodo es instante en la taxonomía y el contexto asociado de reporte no es de tipo instante. ", System.Xml.Schema.XmlSeverityType.Error);
         }
         else if (((ConceptItem)item.Concepto).TipoPeriodo.Name.Equals(ConceptItem.DurationPeriodType) && (item.Contexto.Periodo.Tipo == Period.Instante))
         {
             ManejadorErrores.ManejarError(null, "5.1.1.1 Se encontró un hecho reportado en el documento instancia cuyo tipo de periodo es duración en la taxonomía y el contexto asociado de reporte no es de tipo duración. ", System.Xml.Schema.XmlSeverityType.Error);
         }
     }
     else
     {
         FactTuple tuple = (FactTuple)hecho;
         foreach (Fact factTuple in tuple.Hechos)
         {
             ValidarContextoDeHecho(factTuple);
         }
     }
 }
        /// <summary>
        /// Verifica si las tuplas enviadas como parámetro están duplicadas
        /// Todos los elementos dentro de la tupla deben ser s-equals y v-equals y si
        /// tiene otras tuplas anidadas deben ser duplicadas
        /// </summary>
        /// <param name="factTuple">Tupla origen</param>
        /// <param name="tuplaComparar">Tupla con la que se compara</param>
        /// <returns></returns>
        private bool EsTuplaDuplicada(FactTuple factTuple, FactTuple tuplaComparar)
        {
            if (factTuple == tuplaComparar)
            {
                return(false);
            }
            if (!factTuple.Concepto.Id.Equals(tuplaComparar.Concepto.Id))
            {
                return(false);
            }
            if (factTuple.Hechos.Count != tuplaComparar.Hechos.Count)
            {
                return(false);
            }
            if (!factTuple.ParentEqual(tuplaComparar))
            {
                return(false);
            }

            foreach (Fact hechoEnTupla in factTuple.Hechos)
            {
                Boolean equivalenteEncontrado = false;
                foreach (Fact hechoEnTuplaComparar in tuplaComparar.Hechos)
                {
                    //otra tupla
                    if (hechoEnTupla is FactTuple)
                    {
                        if (hechoEnTuplaComparar is FactTuple && EsTuplaDuplicada((FactTuple)hechoEnTupla, (FactTuple)hechoEnTuplaComparar))
                        {
                            equivalenteEncontrado = true;
                            break;
                        }
                    }
                    else if (hechoEnTupla is FactNumericItem) //un numeric item
                    {
                        if (hechoEnTuplaComparar is FactNumericItem &&
                            hechoEnTupla.Concepto == hechoEnTuplaComparar.Concepto &&
                            ((FactNumericItem)hechoEnTupla).ValueEquals((FactNumericItem)hechoEnTuplaComparar))
                        {
                            equivalenteEncontrado = true;
                            break;
                        }
                    }
                    else
                    {
                        //no numeric item
                        if (hechoEnTuplaComparar is FactItem &&
                            hechoEnTupla.Concepto == hechoEnTuplaComparar.Concepto &&
                            ((FactItem)hechoEnTupla).ValueEquals((FactItem)hechoEnTuplaComparar))
                        {
                            equivalenteEncontrado = true;
                            break;
                        }
                    }
                }
                if (!equivalenteEncontrado)
                {
                    //elemento sin match
                    return(false);
                }
            }
            return(true);
        }