/// <summary>
        ///     Apply the given filters to to a property in the cal component.
        /// </summary>
        /// <param name="component">The component where to apply the filters.</param>
        /// <param name="filter">Filters container.</param>
        /// <returns>True if the component pass the filters, false otherwise.</returns>
        private static bool PropertyFilter(this ICalendarComponent component, IXMLTreeStructure filter)
        {
            //take the property where to apply the filter.
            var propName = filter.Attributes["name"];

            //if the comp doesn't has the desired prop return false

            //iterate over the filters, if one is false then
            //returns false

            //this is gonna be use for the ATTENDEE and RRULE
            // properties
            foreach (var propFilter in filter.Children)
            {
                var result = false;
                IComponentProperty        propValue;
                List <IComponentProperty> propMultiValues;
                switch (propFilter.NodeName)
                {
                case "text-match":
                    //have to check this line in each of the cases because the
                    //"is not defined"
                    if (component.Properties.TryGetValue(propName, out propValue))
                    {
                        result = propValue.StringValue.TextMatchFilter(propFilter);
                    }
                    else if (component.MultipleValuesProperties.TryGetValue(propName, out propMultiValues))
                    {
                        result = propMultiValues.Any(x => x.StringValue.TextMatchFilter(propFilter));
                    }

                    if (!result)
                    {
                        return(false);
                    }
                    break;

                case "param-filter":
                    if (component.Properties.TryGetValue(propName, out propValue))
                    {
                        result = propValue.ParamFilter(propFilter);
                    }
                    else if (component.MultipleValuesProperties.TryGetValue(propName, out propMultiValues))
                    {
                        result = propMultiValues.Any(x => x.ParamFilter(propFilter));
                    }
                    if (!result)
                    {
                        return(false);
                    }
                    break;

                case "is-not-defined":
                    //if the component has a single prop with the given na,e
                    // return false
                    if (component.Properties.ContainsKey(propName))
                    {
                        return(false);
                    }
                    //else if contains a multiple property with the given name
                    // returns false
                    if (component.GetMultipleCompProperties(propName) != null)
                    {
                        return(false);
                    }
                    break;

                default:
                    throw new NotImplementedException(
                              $"THe property filter {propFilter.NodeName} is not implemented");
                }
            }
            return(true);
        }
        /// <summary>
        ///     Apply the time filter to the given component as
        ///     defined in 9.9 CALDAV:time-range XML Element.
        /// </summary>
        /// <param name="component">The component where to apply the filter.</param>
        /// <param name="filter">The filter to apply.</param>
        /// <returns>True if the component pass the filter, false otherwise.</returns>
        private static bool ApplyTimeFilter(this ICalendarComponent component, IXMLTreeStructure filter)
        {
            DateTime?start;
            DateTime?end;

            //get the start and time attributes of the filter.
            if (filter.Attributes.ContainsKey("start"))
            {
                filter.Attributes["start"].ToDateTime(out start);
            }
            else //if not then assign infinite
            {
                start = DateTime.MinValue;
            }

            if (filter.Attributes.ContainsKey("end"))
            {
                filter.Attributes["end"].ToDateTime(out end);
            }
            else //if not then assign -infinite
            {
                end = DateTime.MaxValue;
            }

            //Get the DTSTART of the component.
            var compDTSTART = component.GetComponentProperty("DTSTART") == null
                ? DateTime.MaxValue
                : ((IValue <DateTime>)component.GetComponentProperty("DTSTART")).Value;

            //if the component contains RRULES then expand the dts
            IEnumerable <DateTime> expandedDates = null;

            if (component.MultipleValuesProperties.ContainsKey("RRULE"))
            {
                expandedDates = compDTSTART.ExpandTime(component.GetMultipleCompProperties("RRULE").Select(
                                                           x => ((IValue <Recur>)x).Value).ToList());
            }
            if (expandedDates == null)
            {
                expandedDates = new List <DateTime> {
                    compDTSTART
                }
            }
            ;

            if (component is VEvent)
            {
                return(component.ApplyTimeFilterToVEVENT(start.Value, end.Value, expandedDates));
            }
            if (component is VTodo)
            {
                return(component.ApplyTimeFilterToVTODO(start.Value, end.Value, expandedDates));
            }
            if (component is VJournal)
            {
                throw new NotImplementedException("The doesn't support the VJOURNALs yet.");
            }
            if (component is VFreebusy)
            {
                return(component.ApplyTimeFilterToVFREEBUSY(start.Value, end.Value));
            }
            if (component is VAlarm)
            {
                return(component.ApplyTimeFilterToVALARM(start.Value, end.Value));
            }
            return(false);
        }