private IParser <char, XElement> Element(
            Func <string, bool> name,
            IParser <char, IEnumerable <XAttribute> > attributes,
            IParser <char, IEnumerable <XObject> > content)
        {
            Contract.Requires(name != null);
            Contract.Requires(attributes != null);
            Contract.Requires(content != null);
            Contract.Ensures(Contract.Result <IParser <char, XElement> >() != null);

#if !SILVERLIGHT || WINDOWS_PHONE
            var parser = element(name, attributes, Comment.NoneOrMore().And(content));
#else
            var parser = element(name, attributes, Comment.Cast <char, XComment, XObject>().NoneOrMore().And(content));
#endif

            Contract.Assume(parser != null);

            return(parser);
        }
        // IParser is not covariant on TResult in Silverlight because IEnumerable<T> is not covariant on T.
        private IParser <char, IEnumerable <XObject> > Content(
            IEnumerable <IParser <char, XObject> > content)
        {
            Contract.Requires(content != null);
            Contract.Ensures(Contract.Result <IParser <char, IEnumerable <XObject> > >() != null);

            var contentList = content.ToList();

            var contentWithComments = new List <IParser <char, IEnumerable <XObject> > >(contentList.Count);

            foreach (var item in contentList)
            {
                Contract.Assume(item != null);

                contentWithComments.Add(Comment.Cast <char, XComment, XObject>().Maybe().And(item));
            }

            IParser <char, IEnumerable <XObject> > result;

            if (contentWithComments.Count == 0)
            {
                result =
                    from noContent in Content(
                        text => text.Where(node => node.Value.Trim().Length > 0),
                        includeComments: false)                           // excluding comments actually allows them because of .None()
                    .None()
                    from _ in InsignificantWhiteSpace
                    from comments in comment.NoneOrMore()
                    from __ in InsignificantWhiteSpace
                    select comments.Cast <XObject>();
            }
            else
            {
                result = contentWithComments.All();
            }

            return(result);
        }