Inheritance: Terradue.GeoJson.Feature.FeatureCollection, IOpenSearchResultCollection
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            FeatureCollectionResult fc = new FeatureCollectionResult();

            JToken jsont = serializer.Deserialize<JToken>(reader);

            if (jsont.SelectToken("id") != null)
                fc.Id = jsont.SelectToken("id").ToString();
            if (jsont.SelectToken("properties") != null)
                GenericFunctions.ImportProperties(jsont.SelectToken("properties"), fc);

            var featureConverter = new FeatureResultJsonConverter();
            if (jsont.SelectToken("features") != null) {
                var featuresObject = jsont.SelectTokens("features").Children();
                var features = featuresObject.Select(featureO => featureConverter.ReadJson(featureO.CreateReader(), typeof(FeatureResult), featureO, serializer)).Cast<FeatureResult>().ToList();
                fc.FeatureResults = features;
            }

            return fc;
        }
        public FeatureCollectionResult ImportResults(IOpenSearchResultCollection results)
        {
            if (results == null)
                throw new ArgumentNullException("results");

            FeatureCollectionResult fc = new FeatureCollectionResult();
            fc.Properties = new Dictionary<string, object>();

            NameValueCollection namespaces = null;
            XmlNamespaceManager xnsm = null;
            string prefix = "";

            List<XmlElement> elements = new List<XmlElement>();
            foreach (var element in results.ElementExtensions) {
                elements.Add(element.GetObject<XmlElement>());
            }

            if (options.KeepNamespaces) {

                // Initialize namespaces
                namespaces = new NameValueCollection();
                namespaces.Set("", "http://geojson.org/ns#");
                namespaces.Set("atom", "http://www.w3.org/2005/Atom");
                foreach (var elem in results.ElementExtensions) {
                    XmlReader reader = elem.GetReader();
                    XmlDocument doc = new XmlDocument();
                    doc.Load(reader);
                    xnsm = new XmlNamespaceManager(doc.NameTable);
                    foreach (var names in xnsm.GetNamespacesInScope(XmlNamespaceScope.All)) {
                        namespaces.Set(names.Key, names.Value);
                    }
                }
                fc.Properties.Add("@namespaces", namespaces);
                prefix = "atom:";
            }

            fc.Properties = fc.Properties.Concat(util.ImportXmlDocument(elements.ToArray(), ref namespaces)).ToDictionary(x => x.Key, x => x.Value);

            if (results.Date != null && fc.Properties.ContainsKey(prefix + "updated") == null)
                fc.Properties.Add(prefix + "updated", results.Date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"));

            if (results.Links != null && results.Links.Count > 0) {
                fc.Links = results.Links;
            }

            if (options.KeepNamespaces == true && fc.Properties.ContainsKey("dc:identifier") == null) {
                namespaces.Set("dc", "http://purl.org/dc/elements/1.1/");
                fc.Properties.Add("dc:identifier", results.Identifier);
            }
            if (options.KeepNamespaces == false && fc.Properties.ContainsKey("identifier") == null) {
                fc.Properties.Add("identifier", results.Identifier);
            }

            if (results.Items != null) {
                foreach (var item in results.Items) {
                    fc.FeatureResults.Add(ImportItem(item));
                }
            }

            return fc;
        }
        public static FeatureCollectionResult FromOpenSearchResultCollection(IOpenSearchResultCollection results)
        {
            if (results == null)
                throw new ArgumentNullException("results");

            FeatureCollectionResult fc = new FeatureCollectionResult();

            fc.ElementExtensions = new SyndicationElementExtensionCollection(results.ElementExtensions);

            if (results.Links != null && results.Links.Count > 0) {
                fc.Links = results.Links;
            }

            fc.authors = results.Authors;
            fc.categories = results.Categories;
            fc.LastUpdatedTime = results.LastUpdatedTime;
            fc.Title = results.Title;
            fc.TotalResults = results.TotalResults;
            fc.OpenSearchable = results.OpenSearchable;

            if (results.Items != null) {
                foreach (var item in results.Items) {
                    fc.FeatureResults.Add(FeatureResult.FromOpenSearchResultItem(item));
                }
            }

            return fc;
        }
        public FeatureCollectionResult ImportFeed(SyndicationFeed feed)
        {
            if (feed == null)
                throw new ArgumentNullException("feed");

            FeatureCollectionResult fc = new FeatureCollectionResult();

            NameValueCollection namespaces = null;
            XmlNamespaceManager xnsm = null;
            string prefix = "";

            if (options.KeepNamespaces) {

                // Initialize namespaces
                namespaces = new NameValueCollection();
                namespaces.Set("", "http://geojson.org/ns#");
                namespaces.Set("atom", "http://www.w3.org/2005/Atom");
                XmlReader reader = feed.ElementExtensions.GetReaderAtElementExtensions();
                xnsm = new XmlNamespaceManager(reader.NameTable);
                foreach (var names in xnsm.GetNamespacesInScope(XmlNamespaceScope.All)) {
                    namespaces.Set(names.Key, names.Value);
                }
                fc.Properties.Add("@namespaces", namespaces);
                prefix = "atom:";
            }

            // Import Feed
            if (feed != null) {
                if ((feed.Authors != null) && (feed.Authors.Count > 0)) {
                    object[] authors = new object[feed.Authors.Count];
                    fc.Properties.Add(prefix + "authors", authors);
                    for (int i = 0; i < feed.Authors.Count; i++) {
                        Dictionary<string,object> author = new Dictionary<string, object>();
                        author.Add(prefix + "name", feed.Authors[i].Name);
                        author.Add(prefix + "email", feed.Authors[i].Email);
                        author.Add(prefix + "uri", feed.Authors[i].Uri);
                        author = author.Concat(util.ImportAttributeExtensions(feed.Authors[i].AttributeExtensions, namespaces, xnsm)).ToDictionary(x => x.Key, x => x.Value);
                        author = author.Concat(util.ImportElementExtensions(feed.Authors[i].ElementExtensions, namespaces)).ToDictionary(x => x.Key, x => x.Value);
                        authors[i] = author;
                    }
                }
                if (feed.BaseUri != null) {
                    fc.Properties.Add(prefix + "uri", feed.BaseUri.ToString());
                }
                if ((feed.Categories != null) && (feed.Categories.Count > 0)) {
                    object[] categories = new object[feed.Categories.Count];
                    fc.Properties.Add(prefix + "categories", categories);
                    for (int i = 0; i < feed.Categories.Count; i++) {
                        Dictionary<string,object> category = new Dictionary<string, object>();
                        category.Add(prefix + "name", feed.Categories[i].Name);
                        category.Add(prefix + "label", feed.Categories[i].Label);
                        category.Add(prefix + "scheme", feed.Categories[i].Scheme);
                        category = category.Union(util.ImportAttributeExtensions(feed.Categories[i].AttributeExtensions, namespaces, xnsm)).ToDictionary(x => x.Key, x => x.Value);
                        category = category.Union(util.ImportElementExtensions(feed.Categories[i].ElementExtensions, namespaces)).ToDictionary(x => x.Key, x => x.Value);
                        categories[i] = category;
                    }
                }
                if ((feed.Contributors != null) && (feed.Contributors.Count > 0)) {
                    object[] contributors = new object[feed.Contributors.Count];
                    fc.Properties.Add(prefix + "categories", contributors);
                    for (int i = 0; i < feed.Contributors.Count; i++) {
                        Dictionary<string,object> contributor = new Dictionary<string, object>();
                        contributor.Add(prefix + "name", feed.Contributors[i].Name);
                        contributor.Add(prefix + "email", feed.Contributors[i].Email);
                        contributor.Add(prefix + "uri", feed.Contributors[i].Uri);
                        contributor = contributor.Union(util.ImportAttributeExtensions(feed.Contributors[i].AttributeExtensions, namespaces, xnsm)).ToDictionary(x => x.Key, x => x.Value);
                        contributor = contributor.Union(util.ImportElementExtensions(feed.Contributors[i].ElementExtensions, namespaces)).ToDictionary(x => x.Key, x => x.Value);
                        contributors[i] = contributor;
                    }
                }
                if (feed.Copyright != null) {
                    fc.Properties.Add(prefix + "rights", feed.Copyright.Text);
                }
                if (feed.Description != null) {
                    fc.Properties.Add(prefix + "content", feed.Description.Text);
                }
                if (feed.Generator != null) {
                    fc.Properties.Add(prefix + "generator", feed.Generator);
                }
                fc.Properties.Add(prefix + "id", feed.Id);
                if (feed.ImageUrl != null)
                    fc.Properties.Add(prefix + "logo", feed.ImageUrl.ToString());
                if (feed.Language != null)
                    fc.Properties.Add(prefix + "language", feed.Language);
                if (feed.LastUpdatedTime != null)
                    fc.Properties.Add(prefix + "updated", feed.LastUpdatedTime);
                if ((feed.Links != null) && (feed.Links.Count > 0)) {
                    fc.Links = feed.Links;
                }
                if (feed.Title != null)
                    fc.Properties.Add(prefix + "title", feed.Title);

                if (feed.Items != null) {
                    foreach (var item in feed.Items) {
                        fc.FeatureResults.Add(ImportItem(item));
                    }
                }

                return fc;

            }
            return null;
        }
        public static void ImportProperties(JToken propObject, FeatureCollectionResult fc)
        {
            foreach (var child in propObject.Children<JProperty>()) {

                if (child.Path == "properties.authors") {
                    foreach (var linkObject in child.Values())
                        fc.Authors.Add(SyndicationPersonFromJTokenList(linkObject));
                    continue;
                }

                if (child.Path == "properties.contirbutors") {
                    foreach (var linkObject in child.Values())
                        fc.Contributors.Add(SyndicationPersonFromJTokenList(linkObject));
                    continue;
                }

                if (child.Path == "properties.title") {
                    fc.Title = GenericFunctions.TryTextSyndicationContent(child);
                    continue;
                }

                if (child.Path == "properties.links") {
                    foreach (var linkObject in child.Values())
                        fc.Links.Add(SyndicationLinkFromJTokenList(linkObject));
                    continue;
                }

                if (child.Path == "properties.updated") {
                    fc.LastUpdatedTime = child.Values().First().Value<DateTime>();
                    continue;
                }

                if (child.Path == "properties.title") {
                    fc.Title = GenericFunctions.TryTextSyndicationContent(child);
                    continue;
                }

                if (child.Path == "properties.copyright") {
                    fc.Copyright = GenericFunctions.TryTextSyndicationContent(child);
                    continue;
                }

                try {
                    if (child.Value.Type == JTokenType.Array) {
                        foreach (var child1 in child.Value) {
                            var xmlReader = JsonConvert.DeserializeXNode("{" + child.Name + ":" + child1.ToString() + "}").CreateReader();
                            fc.ElementExtensions.Add(new SyndicationElementExtension(xmlReader));
                        }
                    } else {
                        var xmlReader = JsonConvert.DeserializeXNode("{" + child.ToString() + "}").CreateReader();
                        fc.ElementExtensions.Add(new SyndicationElementExtension(xmlReader));
                    }
                } catch (Exception) {
                }

            }
        }
        public static Dictionary<string, object> ExportProperties(FeatureCollectionResult fc)
        {
            // Start with an empty NameValueCollection
            Dictionary <string,object> properties = new Dictionary<string, object>();

            if (fc.Links != null && fc.Links.Count > 0) {
                properties["links"] = GenericFunctions.LinksToProperties(fc.Links);
            }
            if (fc.LastUpdatedTime.Ticks != 0)
                properties["updated"] = fc.LastUpdatedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ");
            if (fc.Title != null)
                properties["title"] = fc.Title.Text;

            if (fc.Authors != null && fc.Authors.Count > 0) {
                List<object> authors = new List<object>();
                foreach (var author in fc.Authors) {
                    Dictionary<string,object> authord = GenericFunctions.ExportSyndicationElementExtensions(author.ElementExtensions);
                    authord.Add("email", author.Email);
                    authord.Add("name", author.Name);
                    if (author.Uri != null)
                        authord.Add("uri", author.Uri.ToString());

                    authors.Add(authord);
                }
                properties["authors"] = authors;
            }

            if (fc.Categories != null && fc.Categories.Count > 0) {
                List<object> categories = new List<object>();
                foreach (var category in fc.Categories) {
                    Dictionary<string,object> cat = GenericFunctions.ExportSyndicationElementExtensions(category.ElementExtensions);
                    cat.Add("@term", category.Name);
                    cat.Add("@label", category.Label);
                    cat.Add("@scheme", category.Scheme);

                    categories.Add(cat);
                }
                properties["categories"] = categories;
            }

            if (fc.Copyright != null) {
                properties["copyright"] = fc.Copyright.Text;
            }

            var exts = GenericFunctions.ExportSyndicationElementExtensions(fc.ElementExtensions);

            properties = properties.Concat(exts).ToDictionary(x => x.Key, x => x.Value);

            return properties;
        }