From 3ee912354a5d67377e86b2f8f7ee1db440175acd Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sat, 18 Nov 2023 22:03:47 +0100
Subject: [PATCH 01/18] CODE RUB: Clean up

---
 PlanetDotnet/Infrastructure/CombinedFeedSource.cs | 10 +++++-----
 PlanetDotnet/LoadFeedsFunction.cs                 | 12 ++++++------
 PlanetDotnetAuthors/AuthorsLoader.cs              |  6 +++---
 PlanetDotnetAuthors/Models/Author.cs              |  4 ++--
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/PlanetDotnet/Infrastructure/CombinedFeedSource.cs b/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
index 7e77cb3..61b204f 100644
--- a/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
+++ b/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
@@ -1,8 +1,3 @@
-using Microsoft.Extensions.Logging;
-using PlanetDotnet.Extensions;
-using PlanetDotnetAuthors.Models;
-using Polly;
-using Polly.Retry;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -12,6 +7,11 @@
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
 using System.Xml;
+using Microsoft.Extensions.Logging;
+using PlanetDotnet.Extensions;
+using PlanetDotnetAuthors.Models;
+using Polly;
+using Polly.Retry;
 
 namespace PlanetDotnet.Infrastructure
 {
diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
index 3b8b51e..00451f0 100644
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -1,15 +1,15 @@
-using Azure.Storage.Blobs;
-using Azure.Storage.Blobs.Models;
-using Microsoft.Azure.WebJobs;
-using Microsoft.Extensions.Logging;
-using PlanetDotnet.Infrastructure;
-using PlanetDotnetAuthors;
 using System;
 using System.IO;
 using System.Linq;
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
 using System.Xml;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
+using Microsoft.Azure.WebJobs;
+using Microsoft.Extensions.Logging;
+using PlanetDotnet.Infrastructure;
+using PlanetDotnetAuthors;
 
 namespace PlanetDotnet
 {
diff --git a/PlanetDotnetAuthors/AuthorsLoader.cs b/PlanetDotnetAuthors/AuthorsLoader.cs
index 3648351..031840f 100644
--- a/PlanetDotnetAuthors/AuthorsLoader.cs
+++ b/PlanetDotnetAuthors/AuthorsLoader.cs
@@ -1,11 +1,11 @@
-using Newtonsoft.Json;
-using PlanetDotnetAuthors.Models;
-using System;
+using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Reflection;
 using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PlanetDotnetAuthors.Models;
 
 namespace PlanetDotnetAuthors
 {
diff --git a/PlanetDotnetAuthors/Models/Author.cs b/PlanetDotnetAuthors/Models/Author.cs
index 0d1e683..6634bc5 100644
--- a/PlanetDotnetAuthors/Models/Author.cs
+++ b/PlanetDotnetAuthors/Models/Author.cs
@@ -1,7 +1,7 @@
-using Newtonsoft.Json;
-using System;
+using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
+using Newtonsoft.Json;
 
 namespace PlanetDotnetAuthors.Models
 {

From b2fd4b18a92060e0353274101e43dfe32e124b25 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sat, 18 Nov 2023 22:07:46 +0100
Subject: [PATCH 02/18] CODE RUB: Clean up

---
 Authors/AlejandroRuiz.json                    |  19 --
 Authors/AnbuMani27.json                       |  19 --
 Authors/Cheesebaron.json                      |  19 --
 Authors/DamianMehers.json                     |  19 --
 Authors/DanRigby.json                         |  19 --
 Authors/JesseLiberty.json                     |  19 --
 Authors/JoeM-RP.json                          |  19 --
 Authors/JonDouglas.json                       |  19 --
 Authors/JuuCustodio.json                      |  19 --
 Authors/LeomarisReyes.json                    |  19 --
 Authors/LetsCreateSeries.json                 |  19 --
 Authors/MarcBruins.json                       |  19 --
 Authors/MartinZikmund.json                    |  19 --
 Authors/Martynnw.json                         |  19 --
 Authors/MergeConflictFM.json                  |  19 --
 Authors/PieEatingNinjas.json                  |  19 --
 Authors/Prin53.json                           |  19 --
 Authors/Pujolsluis.json                       |  19 --
 Authors/ReactiveUI.json                       |  19 --
 Authors/Sankra.json                           |  19 --
 Authors/StefanRiedmann.json                   |  19 --
 Authors/TheFo2sh.json                         |  19 --
 Authors/TheXamarinShow.json                   |  19 --
 Authors/TomSoderling.json                     |  19 --
 Authors/UdaraAlwis.json                       |  19 --
 Authors/VicenteGuzman.json                    |  19 --
 Authors/XamarinPodcast.json                   |  19 --
 Authors/acaliaro.json                         |  19 --
 Authors/ahoefling.json                        |  19 --
 Authors/akamud.json                           |  19 --
 Authors/alexsorokoletov.json                  |  19 --
 Authors/almirvuk.json                         |  19 --
 Authors/andreas-nesheim.json                  |  19 --
 Authors/aritchie.json                         |  19 --
 Authors/asfend.json                           |  19 --
 Authors/aspnetde.json                         |  19 --
 Authors/balivo.json                           |  19 --
 Authors/banditoth.json                        |  19 --
 Authors/basdecort.json                        |  19 --
 Authors/bbenetskyy.json                       |  19 --
 Authors/brminnick.json                        |  19 --
 Authors/canbilgin.json                        |  19 --
 Authors/chamons.json                          |  19 --
 Authors/char0394.json                         |  19 --
 Authors/cjlotz.json                           |  19 --
 Authors/codemillmatt.json                     |  19 --
 Authors/crswlls.json                          |  19 --
 Authors/damienaicheh.json                     |  19 --
 Authors/damiendoumer.json                     |  19 --
 Authors/danielcauser.json                     |  19 --
 Authors/danielmonettelli.json                 |  20 --
 Authors/dansiegel.json                        |  19 --
 Authors/davidbritch.json                      |  21 --
 Authors/dhindrik.json                         |  19 --
 Authors/divikiran.json                        |  19 --
 Authors/dylanberry.json                       |  19 --
 Authors/egbakou.json                          |  19 --
 Authors/elbrinner.json                        |  19 --
 Authors/felipebaltazar.json                   |  19 --
 Authors/filipoff2.json                        |  19 --
 Authors/framinosona.json                      |  19 --
 Authors/gonemobilecast.json                   |  19 --
 Authors/gptucci.json                          |  19 --
 Authors/gshackles.json                        |  19 --
 Authors/hnabbasi.json                         |  19 --
 Authors/ionixjunior.json                      |  19 --
 Authors/jamesmontemagno.json                  |  19 --
 Authors/jesulink2514.json                     |  20 --
 Authors/jfversluis.json                       |  19 --
 Authors/jgiacomini.json                       |  19 --
 Authors/jimbobbennett.json                    |  19 --
 Authors/johnthiriet.json                      |  19 --
 Authors/jssuthahar.json                       |  19 --
 Authors/jsuarezruiz.json                      |  19 --
 Authors/jtaubensee.json                       |  19 --
 Authors/kent_boogaart.json                    |  19 --
 Authors/kphillpotts.json                      |  19 --
 Authors/kwlothrop.json                        |  19 --
 Authors/logeshpalani98.json                   |  19 --
 Authors/luismts.json                          |  20 --
 Authors/mallibone.json                        |  19 --
 Authors/marcofolio.json                       |  19 --
 Authors/marcusts.json                         |  19 --
 Authors/markolazic88.json                     |  19 --
 Authors/martijn00.json                        |  19 --
 Authors/mattleibow.json                       |  19 --
 Authors/mfractor.json                         |  19 --
 Authors/mike-grant.json                       |  19 --
 Authors/mindofai.json                         |  19 --
 Authors/mkieres.json                          |  19 --
 Authors/msiccdev.json                         |  19 --
 Authors/nickrandolph.json                     |  19 --
 Authors/nigelferrissey.json                   |  19 --
 Authors/officialdoniald.json                  |  19 --
 Authors/peterfoot.json                        |  19 --
 Authors/ramonesteban78.json                   |  19 --
 Authors/rdavisau.json                         |  19 --
 Authors/rdelrosario.json                      |  19 --
 Authors/redth.json                            |  19 --
 Authors/ricardoprestes.json                   |  19 --
 Authors/rid00z.json                           |  19 --
 Authors/robintschroeder.json                  |  19 --
 Authors/roubachof.json                        |  19 --
 Authors/saamerm.json                          |  19 --
 Authors/sact1909.json                         |  19 --
 Authors/samirgcofficial.json                  |  19 --
 Authors/shirshov.json                         |  19 --
 Authors/smstuebe.json                         |  19 --
 Authors/sthewissen.json                       |  19 --
 Authors/stvansolano.json                      |  19 --
 Authors/susairajs.json                        |  19 --
 Authors/syncfusion.json                       |  19 --
 Authors/tbertuzzi.json                        |  19 --
 Authors/telerik.json                          |  19 --
 Authors/trailheadtechnology.json              |  19 --
 Authors/vulcanlee.json                        |  19 --
 Authors/willsb.json                           |  19 --
 Authors/winstongubantes.json                  |  19 --
 Authors/wislon.json                           |  19 --
 Authors/xablu.json                            |  19 --
 Authors/xamarin.json                          |  19 --
 Authors/xamarinhowto.json                     |  19 --
 Authors/yuv4ik.json                           |  20 --
 PlanetDotnet.sln                              |  23 --
 .../Extensions/SyndicationItemExtensions.cs   |  48 ----
 .../Infrastructure/CombinedFeedSource.cs      | 213 ------------------
 PlanetDotnet/LoadFeedsFunction.cs             |  87 -------
 PlanetDotnet/PlanetDotnet.csproj              |  24 --
 .../Properties/serviceDependencies.json       |   8 -
 .../Properties/serviceDependencies.local.json |   8 -
 PlanetDotnet/host.json                        |  11 -
 PlanetDotnet/local.settings.json              |  12 -
 PlanetDotnetAuthors/AuthorsLoader.cs          |  36 ---
 PlanetDotnetAuthors/Models/Author.cs          |  40 ----
 PlanetDotnetAuthors/Models/GeoPosition.cs     |  20 --
 .../PlanetDotnetAuthors.csproj                |  16 --
 author-schema.json                            |  88 --------
 137 files changed, 2977 deletions(-)
 delete mode 100644 Authors/AlejandroRuiz.json
 delete mode 100644 Authors/AnbuMani27.json
 delete mode 100644 Authors/Cheesebaron.json
 delete mode 100644 Authors/DamianMehers.json
 delete mode 100644 Authors/DanRigby.json
 delete mode 100644 Authors/JesseLiberty.json
 delete mode 100644 Authors/JoeM-RP.json
 delete mode 100644 Authors/JonDouglas.json
 delete mode 100644 Authors/JuuCustodio.json
 delete mode 100644 Authors/LeomarisReyes.json
 delete mode 100644 Authors/LetsCreateSeries.json
 delete mode 100644 Authors/MarcBruins.json
 delete mode 100644 Authors/MartinZikmund.json
 delete mode 100644 Authors/Martynnw.json
 delete mode 100644 Authors/MergeConflictFM.json
 delete mode 100644 Authors/PieEatingNinjas.json
 delete mode 100644 Authors/Prin53.json
 delete mode 100644 Authors/Pujolsluis.json
 delete mode 100644 Authors/ReactiveUI.json
 delete mode 100644 Authors/Sankra.json
 delete mode 100644 Authors/StefanRiedmann.json
 delete mode 100644 Authors/TheFo2sh.json
 delete mode 100644 Authors/TheXamarinShow.json
 delete mode 100644 Authors/TomSoderling.json
 delete mode 100644 Authors/UdaraAlwis.json
 delete mode 100644 Authors/VicenteGuzman.json
 delete mode 100644 Authors/XamarinPodcast.json
 delete mode 100644 Authors/acaliaro.json
 delete mode 100644 Authors/ahoefling.json
 delete mode 100644 Authors/akamud.json
 delete mode 100644 Authors/alexsorokoletov.json
 delete mode 100644 Authors/almirvuk.json
 delete mode 100644 Authors/andreas-nesheim.json
 delete mode 100644 Authors/aritchie.json
 delete mode 100644 Authors/asfend.json
 delete mode 100644 Authors/aspnetde.json
 delete mode 100644 Authors/balivo.json
 delete mode 100644 Authors/banditoth.json
 delete mode 100644 Authors/basdecort.json
 delete mode 100644 Authors/bbenetskyy.json
 delete mode 100644 Authors/brminnick.json
 delete mode 100644 Authors/canbilgin.json
 delete mode 100644 Authors/chamons.json
 delete mode 100644 Authors/char0394.json
 delete mode 100644 Authors/cjlotz.json
 delete mode 100644 Authors/codemillmatt.json
 delete mode 100644 Authors/crswlls.json
 delete mode 100644 Authors/damienaicheh.json
 delete mode 100644 Authors/damiendoumer.json
 delete mode 100644 Authors/danielcauser.json
 delete mode 100644 Authors/danielmonettelli.json
 delete mode 100644 Authors/dansiegel.json
 delete mode 100644 Authors/davidbritch.json
 delete mode 100644 Authors/dhindrik.json
 delete mode 100644 Authors/divikiran.json
 delete mode 100644 Authors/dylanberry.json
 delete mode 100644 Authors/egbakou.json
 delete mode 100644 Authors/elbrinner.json
 delete mode 100644 Authors/felipebaltazar.json
 delete mode 100644 Authors/filipoff2.json
 delete mode 100644 Authors/framinosona.json
 delete mode 100644 Authors/gonemobilecast.json
 delete mode 100644 Authors/gptucci.json
 delete mode 100644 Authors/gshackles.json
 delete mode 100644 Authors/hnabbasi.json
 delete mode 100644 Authors/ionixjunior.json
 delete mode 100644 Authors/jamesmontemagno.json
 delete mode 100644 Authors/jesulink2514.json
 delete mode 100644 Authors/jfversluis.json
 delete mode 100644 Authors/jgiacomini.json
 delete mode 100644 Authors/jimbobbennett.json
 delete mode 100644 Authors/johnthiriet.json
 delete mode 100644 Authors/jssuthahar.json
 delete mode 100644 Authors/jsuarezruiz.json
 delete mode 100644 Authors/jtaubensee.json
 delete mode 100644 Authors/kent_boogaart.json
 delete mode 100644 Authors/kphillpotts.json
 delete mode 100644 Authors/kwlothrop.json
 delete mode 100644 Authors/logeshpalani98.json
 delete mode 100644 Authors/luismts.json
 delete mode 100644 Authors/mallibone.json
 delete mode 100644 Authors/marcofolio.json
 delete mode 100644 Authors/marcusts.json
 delete mode 100644 Authors/markolazic88.json
 delete mode 100644 Authors/martijn00.json
 delete mode 100644 Authors/mattleibow.json
 delete mode 100644 Authors/mfractor.json
 delete mode 100644 Authors/mike-grant.json
 delete mode 100644 Authors/mindofai.json
 delete mode 100644 Authors/mkieres.json
 delete mode 100644 Authors/msiccdev.json
 delete mode 100644 Authors/nickrandolph.json
 delete mode 100644 Authors/nigelferrissey.json
 delete mode 100644 Authors/officialdoniald.json
 delete mode 100644 Authors/peterfoot.json
 delete mode 100644 Authors/ramonesteban78.json
 delete mode 100644 Authors/rdavisau.json
 delete mode 100644 Authors/rdelrosario.json
 delete mode 100644 Authors/redth.json
 delete mode 100644 Authors/ricardoprestes.json
 delete mode 100644 Authors/rid00z.json
 delete mode 100644 Authors/robintschroeder.json
 delete mode 100644 Authors/roubachof.json
 delete mode 100644 Authors/saamerm.json
 delete mode 100644 Authors/sact1909.json
 delete mode 100644 Authors/samirgcofficial.json
 delete mode 100644 Authors/shirshov.json
 delete mode 100644 Authors/smstuebe.json
 delete mode 100644 Authors/sthewissen.json
 delete mode 100644 Authors/stvansolano.json
 delete mode 100644 Authors/susairajs.json
 delete mode 100644 Authors/syncfusion.json
 delete mode 100644 Authors/tbertuzzi.json
 delete mode 100644 Authors/telerik.json
 delete mode 100644 Authors/trailheadtechnology.json
 delete mode 100644 Authors/vulcanlee.json
 delete mode 100644 Authors/willsb.json
 delete mode 100644 Authors/winstongubantes.json
 delete mode 100644 Authors/wislon.json
 delete mode 100644 Authors/xablu.json
 delete mode 100644 Authors/xamarin.json
 delete mode 100644 Authors/xamarinhowto.json
 delete mode 100644 Authors/yuv4ik.json
 delete mode 100644 PlanetDotnet/Extensions/SyndicationItemExtensions.cs
 delete mode 100644 PlanetDotnet/Infrastructure/CombinedFeedSource.cs
 delete mode 100644 PlanetDotnet/LoadFeedsFunction.cs
 delete mode 100644 PlanetDotnet/PlanetDotnet.csproj
 delete mode 100644 PlanetDotnet/Properties/serviceDependencies.json
 delete mode 100644 PlanetDotnet/Properties/serviceDependencies.local.json
 delete mode 100644 PlanetDotnet/host.json
 delete mode 100644 PlanetDotnet/local.settings.json
 delete mode 100644 PlanetDotnetAuthors/AuthorsLoader.cs
 delete mode 100644 PlanetDotnetAuthors/Models/Author.cs
 delete mode 100644 PlanetDotnetAuthors/Models/GeoPosition.cs
 delete mode 100644 PlanetDotnetAuthors/PlanetDotnetAuthors.csproj
 delete mode 100644 author-schema.json

diff --git a/Authors/AlejandroRuiz.json b/Authors/AlejandroRuiz.json
deleted file mode 100644
index 3c57034..0000000
--- a/Authors/AlejandroRuiz.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Alejandro",
-  "lastName": "Ruiz",
-  "tagOrBio": "Alejandro Ruiz is a Xamarin MVP, C# & Open Source Lover",
-  "stateOrRegion": "Guadalajara, Mexico",
-  "emailAddress": "alejandro@alejandroruizvarela.com",
-  "webSite": "https://alejandroruizvarela.blogspot.mx",
-  "feedUris": [
-    "https://alejandroruizvarela.blogspot.mx/rss.xml"
-  ],
-  "twitterHandle": "alejandroruizva",
-  "gravatarHash": "35d0fff7dbc133e9fe2075aa14205a57",
-  "githubHandle": "AlejandroRuiz",
-  "position": {
-    "lat": 20.66682,
-    "lon": -103.39182
-  },
-  "languageCode": "es"
-}
\ No newline at end of file
diff --git a/Authors/AnbuMani27.json b/Authors/AnbuMani27.json
deleted file mode 100644
index 6927891..0000000
--- a/Authors/AnbuMani27.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Anbu",
-  "lastName": "Mani",
-  "tagOrBio": "is a Microsoft MVP who Blogger, Speaker, Founder & Organizer of XMonkeys360 Community – India.",
-  "emailAddress": "anbumani@xmonkeys360.com",
-  "twitterHandle": "anbu_mani27",
-  "gravatarHash": "f97650474e4aa5b9609a28dcfdb052d4",
-  "stateOrRegion": "Chennai, India",
-  "webSite": "https://www.xmonkeys360.com/",
-  "position": {
-    "lat": 12.902749,
-    "lon": 80.190846
-  },
-  "feedUris": [
-    "https://xmonkeys360.com/feed/"
-  ],
-  "githubHandle": "AnbuMani27",
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/Cheesebaron.json b/Authors/Cheesebaron.json
deleted file mode 100644
index f218416..0000000
--- a/Authors/Cheesebaron.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "feedUris": [
-    "https://blog.ostebaronen.dk/feed.xml"
-  ],
-  "firstName": "Tomasz",
-  "lastName": "Cielecki",
-  "stateOrRegion": "Copenhagen, Denmark",
-  "emailAddress": "tomasz@ostebaronen.dk",
-  "tagOrBio": "Open Source all the things!",
-  "webSite": "https://blog.ostebaronen.dk",
-  "twitterHandle": "Cheesebaron",
-  "githubHandle": "Cheesebaron",
-  "gravatarHash": "f780d57997526876b0625e517c1e0884",
-  "position": {
-    "lat": 55.8019193,
-    "lon": 12.523124
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/DamianMehers.json b/Authors/DamianMehers.json
deleted file mode 100644
index 78a0e5d..0000000
--- a/Authors/DamianMehers.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Damian",
-  "lastName": "Mehers",
-  "tagOrBio": "Independent Xamarin Developer",
-  "stateOrRegion": "Geneva, Switzerland",
-  "emailAddress": "damian@mehers.com",
-  "twitterHandle": "DamianMehers",
-  "gravatarHash": "d77613f4e20bfcae401a6bf0018a83d1",
-  "githubHandle": "DamianMehers",
-  "position": {
-    "lat": 46.3635288,
-    "lon": 6.1860801
-  },
-  "webSite": "https://damian.fyi/",
-  "feedUris": [
-    "https://damian.fyi/feed/Xamarin.xml"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/DanRigby.json b/Authors/DanRigby.json
deleted file mode 100644
index 7284a50..0000000
--- a/Authors/DanRigby.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Dan",
-  "lastName": "Rigby",
-  "tagOrBio": "is a Technical Solutions Professional",
-  "stateOrRegion": "Raleigh, North Carolina",
-  "emailAddress": "Dan.Rigby@Microsoft.com",
-  "twitterHandle": "DanRigby",
-  "githubHandle": "DanRigby",
-  "gravatarHash": "f025f772418fbcfd3a1e15a74bf0f8a4",
-  "position": {
-    "lat": 35.77959,
-    "lon": -78.638179
-  },
-  "webSite": "https://danrigby.com/",
-  "feedUris": [
-    "https://feeds.feedburner.com/DanRigby"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/JesseLiberty.json b/Authors/JesseLiberty.json
deleted file mode 100644
index 52dadc4..0000000
--- a/Authors/JesseLiberty.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Jesse",
-  "lastName": "Liberty",
-  "tagOrBio": "See http://jesseliberty.me",
-  "stateOrRegion": "Massachusetts",
-  "emailAddress": "jesseliberty@gmail.com",
-  "twitterHandle": "jesseliberty",
-  "gravatarHash": "78d5b6609fe5a80ce67e9f971833a6c3",
-  "githubHandle": "JesseLiberty",
-  "position": {
-    "lat": 42.4703963,
-    "lon": -71.4477468
-  },
-  "webSite": "http://jesseliberty.me",
-  "feedUris": [
-    "https://feeds.feedburner.com/JesseLiberty-SilverlightGeek"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/JoeM-RP.json b/Authors/JoeM-RP.json
deleted file mode 100644
index 0b3c109..0000000
--- a/Authors/JoeM-RP.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Joe",
-  "lastName": "Meyer",
-  "stateOrRegion": "Chicago, IL",
-  "twitterHandle": "iwritecodesmtms",
-  "emailAddress": "joseph.w.meyer@live.com",
-  "tagOrBio": "I write code sometimes",
-  "gravatarHash": "1431dd2c4749b0a178c7a3130e71831e",
-  "webSite": "https://iwritecodesometimes.net",
-  "githubHandle": "JoeM-RP",
-  "position": {
-    "lat": 41.92,
-    "lon": -87.65
-  },
-  "feedUris": [
-    "https://iwritecodesometimes.net/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/JonDouglas.json b/Authors/JonDouglas.json
deleted file mode 100644
index 98a9585..0000000
--- a/Authors/JonDouglas.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Jon",
-  "lastName": "Douglas",
-  "tagOrBio": "",
-  "stateOrRegion": "Utah",
-  "emailAddress": "",
-  "twitterHandle": "_jondouglas",
-  "webSite": "https://www.jon-douglas.com/",
-  "feedUris": [
-    "https://www.jon-douglas.com/atom.xml"
-  ],
-  "gravatarHash": "83d67df0b9e002d1c55a2786aeeb0c1b",
-  "githubHandle": "JonDouglas",
-  "position": {
-    "lat": 39.32098,
-    "lon": -111.093731
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/JuuCustodio.json b/Authors/JuuCustodio.json
deleted file mode 100644
index 1b6ac4d..0000000
--- a/Authors/JuuCustodio.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Juliano",
-  "lastName": "Custódio",
-  "stateOrRegion": "Alphaville - Barueri, Brasil",
-  "twitterHandle": "JuuCustodio",
-  "githubHandle": "JuuCustodio",
-  "tagOrBio": "Solutions Architect, Blogger and Speaker",
-  "emailAddress": "juliano.custodio@hotmail.com.br",
-  "gravatarHash": "71de9936f2ffbc93e9918066479331f1",
-  "position": {
-    "lat": -23.4880831,
-    "lon": -46.8496769
-  },
-  "webSite": "https://www.julianocustodio.com",
-  "feedUris": [
-    "https://julianocustodio.com/tag/xamarin/rss/"
-  ],
-  "languageCode": "pt"
-}
\ No newline at end of file
diff --git a/Authors/LeomarisReyes.json b/Authors/LeomarisReyes.json
deleted file mode 100644
index 1b7b9fd..0000000
--- a/Authors/LeomarisReyes.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Leomaris",
-  "lastName": "Reyes",
-  "tagOrBio": "is a software engineer",
-  "stateOrRegion": "Dominican Republic",
-  "emailAddress": "reyes.leomaris@gmail.com",
-  "twitterHandle": "leomarisreyes11",
-  "gravatarHash": "ae78e84a683611c7b72c9ba829c125e0",
-  "githubHandle": "LeomarisReyes",
-  "position": {
-    "lat": 18.47088,
-    "lon": -69.911525
-  },
-  "webSite": "https://askxammy.com/",
-  "feedUris": [
-    "https://askxammy.com/feed"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/LetsCreateSeries.json b/Authors/LetsCreateSeries.json
deleted file mode 100644
index af8fdcd..0000000
--- a/Authors/LetsCreateSeries.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "LetsCreateSeries",
-  "lastName": "",
-  "stateOrRegion": "United States",
-  "emailAddress": "letscreate.roblox@gmail.com",
-  "tagOrBio": "Create Mobile Apps using Xamarin.Forms",
-  "webSite": "https://letscreateseries.com",
-  "twitterHandle": "LetsCre8Series",
-  "githubHandle": "LetsCreateSeries",
-  "gravatarHash": "10793693ff507eda06ff02e9855e774f",
-  "feedUris": [
-    "https://letscreateseries.com/rss"
-  ],
-  "position": {
-    "lat": 40.6331,
-    "lon": 89.3985
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/MarcBruins.json b/Authors/MarcBruins.json
deleted file mode 100644
index 917537f..0000000
--- a/Authors/MarcBruins.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Marc",
-  "lastName": "Bruins",
-  "tagOrBio": "is a native iOS/Android developer who fell in love with Xamarin",
-  "emailAddress": "marc@marcbruins.nl",
-  "twitterHandle": "MarcBruins",
-  "gravatarHash": "3795d2031be87499f76f6336ec5a3a45",
-  "stateOrRegion": "Utrecht, Netherlands",
-  "webSite": "https://www.marcbruins.nl",
-  "githubHandle": "MarcBruins",
-  "position": {
-    "lat": 53.219384,
-    "lon": 6.566502
-  },
-  "feedUris": [
-    "https://www.marcbruins.nl/feed.xml"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/MartinZikmund.json b/Authors/MartinZikmund.json
deleted file mode 100644
index 4d154cb..0000000
--- a/Authors/MartinZikmund.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Martin",
-  "lastName": "Zikmund",
-  "stateOrRegion": "Prague, Czech Republic",
-  "emailAddress": "martinzikmund@sphereline.com",
-  "tagOrBio": "is a mobile + cloud solutions developer, Microsoftie, Geocacher, regular squash player, foodie and Insanity & P90X fan",
-  "webSite": "https://blog.mzikmund.com/",
-  "twitterHandle": "MZetko",
-  "githubHandle": "MartinZikmund",
-  "gravatarHash": "d1a45c7ba013fbc3e9044ff6461f6acd",
-  "position": {
-    "lat": 50.124017,
-    "lon": 14.451934
-  },
-  "languageCode": "en",
-  "feedUris": [
-    "https://blog.mzikmund.com/feed/?lang=en_us"
-  ]
-}
\ No newline at end of file
diff --git a/Authors/Martynnw.json b/Authors/Martynnw.json
deleted file mode 100644
index 0109f64..0000000
--- a/Authors/Martynnw.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Martyn",
-  "lastName": "Wiggins",
-  "tagOrBio": "Mobile Developer, Mountain Biker, Wannabe Adventurer",
-  "stateOrRegion": "Nottingham",
-  "emailAddress": "Martynnw@gmail.com",
-  "twitterHandle": "Martynnw",
-  "gravatarHash": "bf974dae53bdbf5018fbbbf928db0f4e",
-  "githubHandle": "Martynnw",
-  "position": {
-    "lat": 52.95,
-    "lon": -1.133333
-  },
-  "webSite": "https://martynnw.wordpress.com",
-  "feedUris": [
-    "https://martynnw.wordpress.com/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/MergeConflictFM.json b/Authors/MergeConflictFM.json
deleted file mode 100644
index 7dc4a35..0000000
--- a/Authors/MergeConflictFM.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Merge",
-  "lastName": "Conflict",
-  "stateOrRegion": "Seattle, WA",
-  "emailAddress": "mergeconflictfm@gmail.com",
-  "tagOrBio": "is a weekly development podcast hosted by Frank Krueger and James Montemagno.",
-  "webSite": "http://mergeconflict.fm",
-  "feedUris": [
-    "https://feeds.fireside.fm/mergeconflict/rss"
-  ],
-  "twitterHandle": "MergeConflictFM",
-  "gravatarHash": "24527eb9b29a8adbfc4155db4044dd3c",
-  "githubHandle": "",
-  "position": {
-    "lat": 47.60621,
-    "lon": -122.332071
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/PieEatingNinjas.json b/Authors/PieEatingNinjas.json
deleted file mode 100644
index eb0aa47..0000000
--- a/Authors/PieEatingNinjas.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Pieter",
-  "lastName": "Nijs",
-  "tagOrBio": "Senior .NET Software Engineer & Competence Leader Mobile @ Ordina Belgium. Passionate about programming, especially .NET, C#, XAML, Xamarin and UWP.",
-  "stateOrRegion": "Hasselt, Belgium",
-  "emailAddress": "pieternijs@live.be",
-  "twitterHandle": "nijspieter",
-  "gravatarHash": "61c9184b95820bdbbcd51764f3b9fb6e",
-  "githubHandle": "PieEatingNinjas",
-  "position": {
-    "lat": 50.93,
-    "lon": 5.3375
-  },
-  "webSite": "https://blog.pieeatingninjas.be/",
-  "feedUris": [
-    "https://blog.pieeatingninjas.be/feed/rss"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/Prin53.json b/Authors/Prin53.json
deleted file mode 100644
index 1d84a38..0000000
--- a/Authors/Prin53.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Denys",
-  "lastName": "Fiediaiev",
-  "stateOrRegion": "Ukraine",
-  "emailAddress": "fiediaiev@sbyte.dev",
-  "tagOrBio": "is a mobile developer specializing in Xamarin technology",
-  "webSite": "https://medium.com/@prin53",
-  "twitterHandle": "sbytedev",
-  "githubHandle": "Prin53",
-  "gravatarHash": "0d5df57543a53231787d7a34a9b79cd6",
-  "feedUris": [
-    "https://medium.com/feed/@prin53"
-  ],
-  "position": {
-    "lat": 50.4547,
-    "lon": 30.5238
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/Pujolsluis.json b/Authors/Pujolsluis.json
deleted file mode 100644
index bcac998..0000000
--- a/Authors/Pujolsluis.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Luis",
-  "lastName": "Pujols",
-  "stateOrRegion": "United States",
-  "emailAddress": "luispujolso@gmail.com",
-  "tagOrBio": "is a Software Engineer with a passion for Mobile Development and Software Architecture. Co-organizer of the .NET Community in the Dominican Republic and a Xamarin Lover.",
-  "webSite": "https://www.pujolsluis.com/",
-  "twitterHandle": "Pujolsluis1",
-  "githubHandle": "Pujolsluis",
-  "gravatarHash": "c91c0d654f4f06ca6e7a7e54699de85d",
-  "feedUris": [
-    "https://www.pujolsluis.com/rss"
-  ],
-  "position": {
-    "lat": 26.0203048,
-    "lon": -80.115093
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/ReactiveUI.json b/Authors/ReactiveUI.json
deleted file mode 100644
index 2547b64..0000000
--- a/Authors/ReactiveUI.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "ReactiveUI",
-  "lastName": "",
-  "stateOrRegion": "Internet",
-  "emailAddress": "hello@reactiveui.net",
-  "tagOrBio": "An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms",
-  "webSite": "https://reactiveui.net/",
-  "feedUris": [
-    "https://reactiveui.net/rss"
-  ],
-  "twitterHandle": "ReactiveXUI",
-  "gravatarHash": "",
-  "githubHandle": "ReactiveUI",
-  "position": {
-    "lat": -13.6981464,
-    "lon": 37.3979239
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/Sankra.json b/Authors/Sankra.json
deleted file mode 100644
index 5beca40..0000000
--- a/Authors/Sankra.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Runar Ovesen",
-  "lastName": "Hjerpbakk",
-  "tagOrBio": "Passionate, empathic and experienced developer, software architect and manager. My love for C# is only surpassed by my love for Xamarin and iOS.",
-  "stateOrRegion": "Trondheim, Norway",
-  "emailAddress": "runar@hjerpbakk.com",
-  "twitterHandle": "hjerpbakk",
-  "gravatarHash": "62b1d11eafee92745a51971d6cc21f85",
-  "githubHandle": "Sankra",
-  "position": {
-    "lat": 63.4305,
-    "lon": 10.3951
-  },
-  "webSite": "https://hjerpbakk.com/",
-  "feedUris": [
-    "https://hjerpbakk.com/feed.xml"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/StefanRiedmann.json b/Authors/StefanRiedmann.json
deleted file mode 100644
index 3e8cbb3..0000000
--- a/Authors/StefanRiedmann.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Stefan",
-  "githubHandle": "StefanRiedmann",
-  "lastName": "Riedmann",
-  "tagOrBio": "Growing software",
-  "stateOrRegion": "Mendoza, Argentina and Gemünden, Germany",
-  "emailAddress": "stefan.riedmann@ciclosoftware.com",
-  "twitterHandle": "CicloSoftware",
-  "webSite": "https://www.ciclosoftware.com",
-  "feedUris": [
-    "https://www.ciclosoftware.com/feed/"
-  ],
-  "gravatarHash": "2781a55d04634584326bedfe08660537",
-  "position": {
-    "lat": -32.8886904,
-    "lon": -68.8481432
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/TheFo2sh.json b/Authors/TheFo2sh.json
deleted file mode 100644
index bb08f0e..0000000
--- a/Authors/TheFo2sh.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Ahmed",
-  "lastName": "Fouad",
-  "stateOrRegion": "Vienna, Austria",
-  "emailAddress": "ahmed.fouad.net@hotmail.com",
-  "tagOrBio": "software engineer with 10 years experience with the .NET Framework living in Vienna, Austria.",
-  "webSite": "https://itnext.com/@csharpwriter",
-  "feedUris": [
-    "https://medium.com/feed/@csharpwriter"
-  ],
-  "twitterHandle": "MCC_Ahmed",
-  "gravatarHash": "5727eb3df565991947d90ed140962472",
-  "githubHandle": "TheFo2sh",
-  "position": {
-    "lat": 48.20849,
-    "lon": 16.37208
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/TheXamarinShow.json b/Authors/TheXamarinShow.json
deleted file mode 100644
index a52665a..0000000
--- a/Authors/TheXamarinShow.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "The Xamarin",
-  "lastName": "Show",
-  "stateOrRegion": "Channel 9",
-  "emailAddress": "",
-  "tagOrBio": "is a Weekly Developer Show for Xamarin Developers",
-  "webSite": "http://xamarinshow.com",
-  "feedUris": [
-    "https://channel9.msdn.com/Shows/XamarinShow/feed"
-  ],
-  "twitterHandle": "TheXamarinShow",
-  "gravatarHash": "7a0c7da0279b4e90439e780fa01924e0",
-  "githubHandle": "",
-  "position": {
-    "lat": 47.645136,
-    "lon": -122.130939
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/TomSoderling.json b/Authors/TomSoderling.json
deleted file mode 100644
index 823a6bc..0000000
--- a/Authors/TomSoderling.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Tom",
-  "lastName": "Soderling",
-  "stateOrRegion": "Minneapolis, MN",
-  "emailAddress": "",
-  "tagOrBio": "is a Sr. Mobile Developer, speaker, and open source contributor",
-  "twitterHandle": "tomsoderling",
-  "gravatarHash": "dd103f377899fc63b0b88c5bb62b15bd",
-  "position": {
-    "lat": 44.986656,
-    "lon": -93.258133
-  },
-  "webSite": "https://tomsoderling.github.io",
-  "feedUris": [
-    "https://tomsoderling.github.io/feed.xml"
-  ],
-  "githubHandle": "TomSoderling",
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/UdaraAlwis.json b/Authors/UdaraAlwis.json
deleted file mode 100644
index 0297db2..0000000
--- a/Authors/UdaraAlwis.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Udara",
-  "lastName": "Alwis",
-  "tagOrBio": "A mobile dev enthusiast. Xamarin Certified Developer in Singapore.",
-  "stateOrRegion": "Singapore",
-  "emailAddress": "udara.robotics@gmail.com",
-  "twitterHandle": "Udara_Alwis",
-  "gravatarHash": "125c4aaed98f2a88207dac78c17dd344",
-  "githubHandle": "UdaraAlwis",
-  "position": {
-    "lat": 1.284433,
-    "lon": 103.859609
-  },
-  "webSite": "https://theconfuzedsourcecode.wordpress.com/",
-  "feedUris": [
-    "https://theconfuzedsourcecode.wordpress.com/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/VicenteGuzman.json b/Authors/VicenteGuzman.json
deleted file mode 100644
index 7944023..0000000
--- a/Authors/VicenteGuzman.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Vicente",
-  "lastName": "Guzman",
-  "tagOrBio": "Vicente Guzman is a Community Member / Microsoft rMVP / Software Engineer",
-  "stateOrRegion": "Ciudad de México",
-  "emailAddress": "luciomsp@geeks.ms",
-  "webSite": "https://vicenteguzman.mx/",
-  "feedUris": [
-    "https://vicenteguzman.mx/feed/"
-  ],
-  "twitterHandle": "luciomsp",
-  "gravatarHash": "72cce778aac0d6066a14225e90c30874",
-  "githubHandle": "VicenteGuzman",
-  "position": {
-    "lat": 19.432608,
-    "lon": -99.133209
-  },
-  "languageCode": "es"
-}
\ No newline at end of file
diff --git a/Authors/XamarinPodcast.json b/Authors/XamarinPodcast.json
deleted file mode 100644
index 2c6728d..0000000
--- a/Authors/XamarinPodcast.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "The Xamarin",
-  "lastName": "Podcast",
-  "stateOrRegion": "Internet",
-  "emailAddress": "hello@xamarin.com",
-  "tagOrBio": "is the official Xamarin podcast discussing all things Xamarin!",
-  "webSite": "http://www.xamarinpodcast.com",
-  "feedUris": [
-    "https://feeds.fireside.fm/xamarinpodcast/rss"
-  ],
-  "twitterHandle": "XamarinPodcast",
-  "gravatarHash": "70148d964bb389d42547834e1062c886",
-  "githubHandle": "",
-  "position": {
-    "lat": -1337.0,
-    "lon": 42.0
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/acaliaro.json b/Authors/acaliaro.json
deleted file mode 100644
index 4899ee5..0000000
--- a/Authors/acaliaro.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Alessandro",
-  "lastName": "Caliaro",
-  "tagOrBio": "I like Xamarin Forms and I like help other people to understand it",
-  "emailAddress": "acaliaro@libero.it",
-  "twitterHandle": "acaliaro",
-  "gravatarHash": "a7466eb1c467806f77bc692a4745d0f9",
-  "stateOrRegion": "Lissone, Italy",
-  "webSite": "https://acaliaro.wordpress.com",
-  "githubHandle": "acaliaro",
-  "position": {
-    "lat": 45.632783,
-    "lon": 9.227265
-  },
-  "feedUris": [
-    "https://acaliaro.wordpress.com/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/ahoefling.json b/Authors/ahoefling.json
deleted file mode 100644
index eb8adee..0000000
--- a/Authors/ahoefling.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Andrew",
-  "lastName": "Hoefling",
-  "stateOrRegion": "New York, United States",
-  "emailAddress": "andrew@hoefling.me",
-  "tagOrBio": "Microsoft MVP (Developer Technologies) Open Source developer who loves integrating Xamarin with other platforms",
-  "webSite": "https://www.andrewhoefling.com/",
-  "twitterHandle": "andrew_hoefling",
-  "githubHandle": "ahoefling",
-  "gravatarHash": "beab68478a5128e634590af5e4f01941",
-  "feedUris": [
-    "https://www.andrewhoefling.com/feed.xml?category=xamarin&uno-platform"
-  ],
-  "position": {
-    "lat": 43.156578,
-    "lon": -77.608849
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/akamud.json b/Authors/akamud.json
deleted file mode 100644
index ca11d7b..0000000
--- a/Authors/akamud.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Mahmoud",
-  "lastName": "Ali",
-  "stateOrRegion": "São Paulo, Brasil",
-  "emailAddress": "muddibr@gmail.com",
-  "tagOrBio": "Microsoft MVP",
-  "webSite": "https://www.lambda3.com.br/blog",
-  "twitterHandle": "akamud",
-  "githubHandle": "akamud",
-  "gravatarHash": "fc093b379c830c8105f8d15d9261a144",
-  "feedUris": [
-    "https://www.lambda3.com.br/feed/"
-  ],
-  "position": {
-    "lat": -23.552339,
-    "lon": -46.661393
-  },
-  "languageCode": "pt"
-}
\ No newline at end of file
diff --git a/Authors/alexsorokoletov.json b/Authors/alexsorokoletov.json
deleted file mode 100644
index 5687f73..0000000
--- a/Authors/alexsorokoletov.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Alexandr",
-  "lastName": "Sorokoletov",
-  "tagOrBio": "when he's not developing mobile applications enjoys snowboarding, kitesurfing and travel",
-  "stateOrRegion": "Washington, D.C.",
-  "emailAddress": "",
-  "twitterHandle": "AlexSorokoletov",
-  "githubHandle": "alexsorokoletov",
-  "position": {
-    "lat": 38.905147,
-    "lon": -77.065189
-  },
-  "webSite": "https://sorokoletov.com",
-  "feedUris": [
-    "https://sorokoletov.com/atom.xml"
-  ],
-  "gravatarHash": "b07fef8827dd03655303751e2fd5ca95",
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/almirvuk.json b/Authors/almirvuk.json
deleted file mode 100644
index 7bae938..0000000
--- a/Authors/almirvuk.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Almir",
-  "lastName": "Vuk",
-  "tagOrBio": "Software Development Engineer & Microsoft MVP, crafting apps with ASP.NET Core and Xamarin",
-  "stateOrRegion": "Mostar, Bosnia and Herzegovina",
-  "emailAddress": "almir.vuk@outlook.com",
-  "twitterHandle": "almirvuk",
-  "gravatarHash": "d58b6fd6c2d9f949345e8d14d203a4b2",
-  "webSite": "https://almirvuk.com/",
-  "feedUris": [
-    "https://almirvuk.com/rss/"
-  ],
-  "githubHandle": "almirvuk",
-  "position": {
-    "lat": 43.3395522,
-    "lon": 17.7862211
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/andreas-nesheim.json b/Authors/andreas-nesheim.json
deleted file mode 100644
index 92955da..0000000
--- a/Authors/andreas-nesheim.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Andreas",
-  "lastName": "Nesheim",
-  "stateOrRegion": "Norway",
-  "emailAddress": "andreas.aronsen.nesheim@gmail.com",
-  "tagOrBio": ".NET developer with a passion for Xamarin, Azure DevOps and .NET Core.",
-  "webSite": "https://www.andreasnesheim.no/",
-  "twitterHandle": "AndreasNesheim",
-  "githubHandle": "andreas-nesheim",
-  "gravatarHash": "3f1d141d2809114debffb23277e91e3e",
-  "feedUris": [
-    "https://andreasnesheim.no/feed"
-  ],
-  "position": {
-    "lat": 58.9540147,
-    "lon": 5.7259639
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/aritchie.json b/Authors/aritchie.json
deleted file mode 100644
index cb30817..0000000
--- a/Authors/aritchie.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Allan",
-  "lastName": "Ritchie",
-  "stateOrRegion": "Toronto, Canada",
-  "emailAddress": "allan.ritchie@gmail.com",
-  "tagOrBio": "",
-  "webSite": "https://allancritchie.net",
-  "twitterHandle": "allanritchie911",
-  "githubHandle": "aritchie",
-  "gravatarHash": "5f22bd04ca38ed4d0a5225d0825e0726",
-  "position": {
-    "lat": 43.6425701,
-    "lon": -79.3892455
-  },
-  "languageCode": "en",
-  "feedUris": [
-    "https://allancritchie.net/xamarin.rss"
-  ]
-}
\ No newline at end of file
diff --git a/Authors/asfend.json b/Authors/asfend.json
deleted file mode 100644
index 6a7e94c..0000000
--- a/Authors/asfend.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Asfend Yar",
-  "lastName": "Hamid",
-  "stateOrRegion": "Lahore, Pakistan",
-  "emailAddress": "asfend@hotmail.com",
-  "tagOrBio": "is a Technical Trainer, Author at Udemy and Passionate Community Member as well as Software Engineer",
-  "webSite": "https://xamarinui.blogspot.com/",
-  "feedUris": [
-    "https://xamarinui.blogspot.com/feeds/posts/default"
-  ],
-  "twitterHandle": "asfend",
-  "gravatarHash": "1aa9a7436eec5ad5d0418a385d1bdbe0",
-  "githubHandle": "asfend",
-  "position": {
-    "lat": 31.5712,
-    "lon": 74.3646
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/aspnetde.json b/Authors/aspnetde.json
deleted file mode 100644
index 190d444..0000000
--- a/Authors/aspnetde.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Thomas",
-  "lastName": "Bandt",
-  "stateOrRegion": "Munich, Germany",
-  "position": {
-    "lat": 48.1485869,
-    "lon": 11.5353743
-  },
-  "emailAddress": "",
-  "webSite": "https://thomasbandt.com/",
-  "tagOrBio": "Developer & Entrepreneur of Passion",
-  "twitterHandle": "asp_net",
-  "githubHandle": "aspnetde",
-  "gravatarHash": "32860557b42ace0afa72704e466e34f1",
-  "feedUris": [
-    "https://thomasbandt.com/feed"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/balivo.json b/Authors/balivo.json
deleted file mode 100644
index 19c993f..0000000
--- a/Authors/balivo.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Jefferson",
-  "lastName": "Balivo",
-  "stateOrRegion": "Jaú, São Paulo, Brazil",
-  "emailAddress": "jefferson@balivo.com.br",
-  "tagOrBio": "Xamarin Enthusiast, Technical Lead and Cross Platform Architect, Multi-Plataform Technical Audience Contributor (MTAC), Technical Writer and Speaker",
-  "webSite": "https://balivo.com.br/",
-  "twitterHandle": "jbalivo",
-  "githubHandle": "balivo",
-  "gravatarHash": "e5a95c365e8f06786d6439474bc733df",
-  "feedUris": [
-    "https://balivo.com.br/rss"
-  ],
-  "position": {
-    "lat": -22.2997067,
-    "lon": -48.5931324
-  },
-  "languageCode": "pt"
-}
\ No newline at end of file
diff --git a/Authors/banditoth.json b/Authors/banditoth.json
deleted file mode 100644
index cca99ea..0000000
--- a/Authors/banditoth.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "András",
-  "lastName": "Tóth",
-  "tagOrBio": "also known as banditoth | Xamarin && C# .NET developer from Hungary.",
-  "stateOrRegion": "Budapest, Hungary",
-  "emailAddress": "",
-  "twitterHandle": "",
-  "githubHandle": "banditoth",
-  "position": {
-    "lat": 47.497913,
-    "lon": 19.040236
-  },
-  "webSite": "https://www.banditoth.hu",
-  "feedUris": [
-    "https://www.banditoth.hu/feed/"
-  ],
-  "gravatarHash": "e11e3fd93c1cc4db5ec6f309bac0ff4d",
-  "languageCode": "hu"
-}
\ No newline at end of file
diff --git a/Authors/basdecort.json b/Authors/basdecort.json
deleted file mode 100644
index 2ef14fa..0000000
--- a/Authors/basdecort.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Bas",
-  "lastName": "de Cort",
-  "stateOrRegion": "Tilburg, The Netherlands",
-  "emailAddress": "",
-  "tagOrBio": "is a mobile developer with a great passion for Xamarin 🙉",
-  "webSite": "https://www.basdecort.com",
-  "twitterHandle": "basdecort",
-  "githubHandle": "basdecort",
-  "gravatarHash": "9cabafd38c21d9df358f7532ffa39153",
-  "position": {
-    "lat": 52.040222799999995,
-    "lon": 5.5349002999999994
-  },
-  "feedUris": [
-    "https://www.basdecort.com/rss"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/bbenetskyy.json b/Authors/bbenetskyy.json
deleted file mode 100644
index 4d0d0ce..0000000
--- a/Authors/bbenetskyy.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Bohdan",
-  "lastName": "Benetskyi",
-  "stateOrRegion": "Rzeszow, Poland",
-  "emailAddress": "benetskyybogdan@gmail.com",
-  "tagOrBio": "Xamarin Software Developer, co-organizer of Xamarin Local Events in Rzeszow, Local CSS at Xamarin Advocate",
-  "webSite": "https://medium.com/@benetskyybogdan/",
-  "twitterHandle": "bbenetskyy",
-  "githubHandle": "bbenetskyy",
-  "gravatarHash": "8bfa7db9239c2969b79468a58c8dd066",
-  "feedUris": [
-    "https://medium.com/feed/@benetskyybogdan/"
-  ],
-  "position": {
-    "lat": 50.041187,
-    "lon": 21.999121
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/brminnick.json b/Authors/brminnick.json
deleted file mode 100644
index 0359af3..0000000
--- a/Authors/brminnick.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Brandon",
-  "lastName": "Minnick",
-  "stateOrRegion": "San Francisco, CA",
-  "emailAddress": "brandon@codetraveler.io",
-  "tagOrBio": "works as a Developer Advocate at Microsoft. Formerly a Customer Success Engineer at Xamarin (before the Microsoft Acquisition), Brandon has a loves helping developers make 5-star apps!",
-  "webSite": "https://codetraveler.io",
-  "twitterHandle": "TheCodeTraveler",
-  "githubHandle": "brminnick",
-  "gravatarHash": "e03e28629383def59c31d54fb8bb3982",
-  "position": {
-    "lat": 37.77669,
-    "lon": -122.416644
-  },
-  "languageCode": "en",
-  "feedUris": [
-    "https://codetraveler.io/tag/xamarin/rss"
-  ]
-}
\ No newline at end of file
diff --git a/Authors/canbilgin.json b/Authors/canbilgin.json
deleted file mode 100644
index 2ddfddf..0000000
--- a/Authors/canbilgin.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Can",
-  "lastName": "Bilgin",
-  "tagOrBio": "Seasoned microsoft stack developer with passion for mobile development. Microsoft MVP for Windows Platform Development",
-  "stateOrRegion": "Sarajevo",
-  "emailAddress": "can_bilgin@hotmail.com",
-  "twitterHandle": "can_bilgin",
-  "gravatarHash": "3659d530c25e6188f7ef4c98ed100dc8",
-  "webSite": "https://canbilgin.wordpress.com/",
-  "feedUris": [
-    "https://canbilgin.wordpress.com/feed/"
-  ],
-  "githubHandle": "canbilgin",
-  "position": {
-    "lat": 43.8938256,
-    "lon": 18.3129519
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/chamons.json b/Authors/chamons.json
deleted file mode 100644
index e26f390..0000000
--- a/Authors/chamons.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Chris",
-  "lastName": "Hamons",
-  "tagOrBio": "is the lead engineer for Xamarin.Mac",
-  "stateOrRegion": "Austin, Texas",
-  "emailAddress": "chris.hamons@xamarin.com",
-  "twitterHandle": "IfErrThrowBrick",
-  "webSite": "https://medium.com/@donblas",
-  "feedUris": [
-    "https://medium.com/feed/@donblas"
-  ],
-  "gravatarHash": "8fb3e7f07ea1386cefe1326b48e0e21a",
-  "githubHandle": "chamons",
-  "position": {
-    "lat": 30.267153,
-    "lon": -97.743061
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/char0394.json b/Authors/char0394.json
deleted file mode 100644
index f153a93..0000000
--- a/Authors/char0394.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Charlin",
-  "lastName": "Agramonte",
-  "tagOrBio": "Software Engineer",
-  "stateOrRegion": "Dominican Republic",
-  "emailAddress": "charlin@crossgeeks.com",
-  "twitterHandle": "Chard003",
-  "gravatarHash": "7db2bb2eed17e8df7e78b0d5461d90b0",
-  "githubHandle": "char0394",
-  "position": {
-    "lat": 18.4735438,
-    "lon": -69.9456919
-  },
-  "webSite": "https://xamgirl.com/",
-  "feedUris": [
-    "https://xamgirl.com/rss"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/cjlotz.json b/Authors/cjlotz.json
deleted file mode 100644
index 2a640c6..0000000
--- a/Authors/cjlotz.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Carel",
-  "lastName": "Lotz",
-  "tagOrBio": "is a Software Architect/Developer that loves to code",
-  "stateOrRegion": "Cape Town, South Africa",
-  "emailAddress": "carel.lotz@gmail.com",
-  "twitterHandle": "cjlotz",
-  "githubHandle": "cjlotz",
-  "gravatarHash": "0f692990601721c06f141f4fe860685e",
-  "position": {
-    "lat": -33.89635,
-    "lon": 18.70199
-  },
-  "webSite": "https://cjlotz.github.io",
-  "feedUris": [
-    "https://cjlotz.github.io/feed.xml"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/codemillmatt.json b/Authors/codemillmatt.json
deleted file mode 100644
index 8b8e421..0000000
--- a/Authors/codemillmatt.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "feedUris": [
-    "https://codemilltech.com/feed/"
-  ],
-  "firstName": "Matthew",
-  "lastName": "Soucoup",
-  "stateOrRegion": "Madison, WI",
-  "emailAddress": "msoucoup@codemilltech.com",
-  "tagOrBio": "",
-  "webSite": "https://codemilltech.com",
-  "twitterHandle": "codemillmatt",
-  "gravatarHash": "df69069a0bffd2dae5a8700a1bef7bfd",
-  "githubHandle": "codemillmatt",
-  "position": {
-    "lat": 43.073052,
-    "lon": -89.40123
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/crswlls.json b/Authors/crswlls.json
deleted file mode 100644
index 5f8fd20..0000000
--- a/Authors/crswlls.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Chris",
-  "lastName": "Williams",
-  "tagOrBio": "",
-  "emailAddress": "",
-  "twitterHandle": "crswlls",
-  "gravatarHash": "21e379df7ba9c57f167188e2fcb7dd75",
-  "stateOrRegion": "Bristol, UK",
-  "webSite": "https://crswlls.wordpress.com",
-  "feedUris": [
-    "https://crswlls.wordpress.com/rss/"
-  ],
-  "githubHandle": "",
-  "position": {
-    "lat": 30.267153,
-    "lon": -97.743061
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/damienaicheh.json b/Authors/damienaicheh.json
deleted file mode 100644
index 5459dfb..0000000
--- a/Authors/damienaicheh.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Damien",
-  "lastName": "Aicheh",
-  "stateOrRegion": "Rennes, France",
-  "emailAddress": "",
-  "tagOrBio": "is a passionate mobile developer also interrested about Azure, Azure DevOps and.NET Core.",
-  "webSite": "https://damienaicheh.github.io/",
-  "twitterHandle": "damienaicheh",
-  "githubHandle": "damienaicheh",
-  "gravatarHash": "b5cf688a9aa81b3ef752ecda4366a8e9",
-  "feedUris": [
-    "https://damienaicheh.github.io/feed.xml"
-  ],
-  "position": {
-    "lat": 48.1113036,
-    "lon": -1.6801598
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/damiendoumer.json b/Authors/damiendoumer.json
deleted file mode 100644
index 30a269c..0000000
--- a/Authors/damiendoumer.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Damien",
-  "lastName": "Doumer",
-  "stateOrRegion": "Douala, Cameroon",
-  "emailAddress": "damientohin@gmail.com",
-  "tagOrBio": "Fresh .Net developer, who loves mobile app development.",
-  "webSite": "https://doumer.me/",
-  "feedUris": [
-    "https://doumer.me/feed/"
-  ],
-  "twitterHandle": "Damien_Doumer",
-  "gravatarHash": "ecdd93df62c61daa04da17967f82d08d",
-  "githubHandle": "damiendoumer",
-  "position": {
-    "lat": 4.07316844239285,
-    "lon": 9.6842408186165585
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/danielcauser.json b/Authors/danielcauser.json
deleted file mode 100644
index e7c0f22..0000000
--- a/Authors/danielcauser.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Daniel",
-  "lastName": "Causer",
-  "stateOrRegion": "Toronto, Canada",
-  "emailAddress": "danielcauser@gmail.com",
-  "tagOrBio": "is a Xamarin Certified Developer fan of Xamarin and Mobile Development.",
-  "webSite": "https://causerexception.com/",
-  "twitterHandle": "danielcauser",
-  "githubHandle": "danielcauser",
-  "gravatarHash": "2666956714a2c2d48c480a6bddac4071",
-  "feedUris": [
-    "https://causerexception.com/feed"
-  ],
-  "position": {
-    "lat": 43.653103,
-    "lon": -79.383851
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/danielmonettelli.json b/Authors/danielmonettelli.json
deleted file mode 100644
index 668e204..0000000
--- a/Authors/danielmonettelli.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "firstName": "Daniel Angel",
-  "lastName": "Monettelli L.",
-  "tagOrBio": "is a Software Engineer, Videoblogger, Xamarin Mobile Developer & UI/UX Architect.",
-  "stateOrRegion": "Arequipa, Perú",
-  "emailAddress": "danielmonetelli@hotmail.com",
-  "webSite": "https://danielmonettelli.github.io",
-  "feedUris": [
-    "https://danielmonettelli.github.io/feed.xml",
-    "https://www.youtube.com/feeds/videos.xml?channel_id=UCTAlbAORoFvAHj7jA4DLSFQ"
-  ],
-  "twitterHandle": "DanielMonetelli",
-  "gravatarHash": "4b3d0e60019ad8fe1e4d7cd5c8850efb",
-  "githubHandle": "danielmonettelli",
-  "position": {
-    "lat": -16.4042643,
-    "lon": -71.5486383
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/dansiegel.json b/Authors/dansiegel.json
deleted file mode 100644
index b626148..0000000
--- a/Authors/dansiegel.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Dan",
-  "lastName": "Siegel",
-  "stateOrRegion": "San Diego, CA",
-  "emailAddress": "dsiegel@avantipoint.com",
-  "tagOrBio": "is a Mobile App Consultant and Founder of AvantiPoint. He is an author of several OSS libraries, a maintainer of the Prism Library and a DevOps champion.",
-  "webSite": "https://dansiegel.net",
-  "feedUris": [
-    "https://dansiegel.net/syndication.axd"
-  ],
-  "twitterHandle": "DanJSiegel",
-  "gravatarHash": "b65a519785f69fbe7236dd0fd6396094",
-  "githubHandle": "dansiegel",
-  "position": {
-    "lat": 32.726308,
-    "lon": -117.177746
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/davidbritch.json b/Authors/davidbritch.json
deleted file mode 100644
index bda68ed..0000000
--- a/Authors/davidbritch.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "firstName": "David",
-  "lastName": "Britch",
-  "Title": "Senior Developer/Writer",
-  "stateOrRegion": "UK",
-  "emailAddress": "",
-  "twitterHandle": "britchdavid",
-  "gravatarHash": "0ddca71a03a3591203b4a748fcdfb47a",
-  "Started": "2015-06-08T00:00:00",
-  "tagOrBio": "",
-  "githubHandle": "davidbritch",
-  "position": {
-    "lat": 53.4793,
-    "lon": -2.2479
-  },
-  "webSite": "https://www.davidbritch.com",
-  "feedUris": [
-    "https://www.davidbritch.com/rss.xml"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/dhindrik.json b/Authors/dhindrik.json
deleted file mode 100644
index 5a103ec..0000000
--- a/Authors/dhindrik.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Daniel",
-  "lastName": "Hindrikes",
-  "stateOrRegion": "Borlänge, Sweden",
-  "emailAddress": "daniel@hindrikes.se",
-  "tagOrBio": "is an architect and developer using Xamarin and Azure. Working as a Ninja at tretton37. Also recording \"The Code Behind\" podcast!",
-  "webSite": "https://danielhindrikes.se",
-  "twitterHandle": "hindrikes",
-  "githubHandle": "dhindrik",
-  "gravatarHash": "054db2cfd79654ec5d92e20c180f2d72",
-  "feedUris": [
-    "https://danielhindrikes.se/index.php/feed/"
-  ],
-  "position": {
-    "lat": 60.48604,
-    "lon": 15.43391
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/divikiran.json b/Authors/divikiran.json
deleted file mode 100644
index 870131c..0000000
--- a/Authors/divikiran.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Divikiran",
-  "lastName": "Ravela",
-  "stateOrRegion": "Melbourne, Australia",
-  "emailAddress": "divikiran1@gmail.com",
-  "tagOrBio": "Xamarin Consultant/Tech Lead",
-  "webSite": "https://xamlabs.com/",
-  "twitterHandle": "",
-  "githubHandle": "divikiran",
-  "gravatarHash": "",
-  "feedUris": [
-    "https://xamlabs.com/feed/"
-  ],
-  "position": {
-    "lat": -37.8135511,
-    "lon": 144.9637748
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/dylanberry.json b/Authors/dylanberry.json
deleted file mode 100644
index 808d8fd..0000000
--- a/Authors/dylanberry.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Dylan",
-  "lastName": "Berry",
-  "tagOrBio": "Genetically Predisposed Programmer",
-  "stateOrRegion": "Toronto, Canada",
-  "emailAddress": "dylanberry@gmail.com",
-  "twitterHandle": "dylbot9000",
-  "gravatarHash": "8ef85938904ff43397d50caa9b0eebed",
-  "githubHandle": "dylanberry",
-  "position": {
-    "lat": 43.653493,
-    "lon": -79.384095
-  },
-  "webSite": "https://www.dylanberry.com/",
-  "feedUris": [
-    "https://www.dylanberry.com/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/egbakou.json b/Authors/egbakou.json
deleted file mode 100644
index 886bb70..0000000
--- a/Authors/egbakou.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Kodjo Laurent",
-  "lastName": "Egbakou",
-  "stateOrRegion": "Lome, Togo",
-  "emailAddress": "laurent@lioncoding.com",
-  "tagOrBio": "is C#/.Net/Xamarin developer who learns and shares.",
-  "webSite": "https://lioncoding.com/",
-  "twitterHandle": "lioncoding",
-  "githubHandle": "egbakou",
-  "gravatarHash": "6e26a030d3b9495872b58d922bd86157",
-  "feedUris": [
-    "https://lioncoding.com/feed.xml"
-  ],
-  "position": {
-    "lat": 6.2030129,
-    "lon": 1.1918434
-  },
-  "languageCode": "fr"
-}
\ No newline at end of file
diff --git a/Authors/elbrinner.json b/Authors/elbrinner.json
deleted file mode 100644
index 615211b..0000000
--- a/Authors/elbrinner.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Elbrinner",
-  "lastName": "da Silva Fernandes",
-  "stateOrRegion": "Madrid , Spain",
-  "emailAddress": "elbrinner@elbrinner.com",
-  "tagOrBio": "is a Xamarin consultant in everis Spain and organizer of the meetup group Xamarin Madrid.",
-  "webSite": "https://www.elbrinner.com/",
-  "twitterHandle": "elbrinner",
-  "githubHandle": "elbrinner",
-  "gravatarHash": "15e64690c0e4d5b2c692e9fc7de5e768",
-  "feedUris": [
-    "https://www.elbrinner.com/rss"
-  ],
-  "position": {
-    "lat": 40.416775,
-    "lon": -3.70379
-  },
-  "languageCode": "es"
-}
\ No newline at end of file
diff --git a/Authors/felipebaltazar.json b/Authors/felipebaltazar.json
deleted file mode 100644
index 7ca680e..0000000
--- a/Authors/felipebaltazar.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Felipe",
-  "lastName": "Baltazar",
-  "tagOrBio": "Xamarin 🐒, ApnetCore 🌐, Windows 💻, Nerd 🤓, Gamer 🎮 and Father 👨‍👩‍👦",
-  "stateOrRegion": "Rio Grande do sul, Brasil",
-  "emailAddress": "felipe.dasilvabaltazar@gmail.com",
-  "twitterHandle": "FelippeBaltazar",
-  "githubHandle": "felipebaltazar",
-  "gravatarHash": "c4deac62305f590fbda80209628afd0e",
-  "position": {
-    "lat": -29.940163,
-    "lon": -51.088751
-  },
-  "webSite": "https://medium.com/@felipedasilvabaltazar",
-  "feedUris": [
-    "https://medium.com/feed/@felipedasilvabaltazar"
-  ],
-  "languageCode": "pt"
-}
\ No newline at end of file
diff --git a/Authors/filipoff2.json b/Authors/filipoff2.json
deleted file mode 100644
index e3c9525..0000000
--- a/Authors/filipoff2.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Boguslaw",
-  "lastName": "Blonski",
-  "tagOrBio": "Generalist who is pragmatic and has delivered real code to real users in a variety of shapes.",
-  "stateOrRegion": "Lezajsk, Poland",
-  "emailAddress": "boguslawblonski@gmail.com",
-  "twitterHandle": "filipoff",
-  "gravatarHash": "d48c54ac95492ddadfc221b646d4c612",
-  "webSite": "https://medium.com/@boguslawblonski",
-  "feedUris": [
-    "https://medium.com/feed/@boguslawblonski/"
-  ],
-  "githubHandle": "filipoff2",
-  "position": {
-    "lat": 50.2684647,
-    "lon": 22.3819053
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/framinosona.json b/Authors/framinosona.json
deleted file mode 100644
index 4580e19..0000000
--- a/Authors/framinosona.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Francois",
-  "lastName": "Raminosona",
-  "stateOrRegion": "Norway",
-  "emailAddress": "framinosona@hotmail.fr",
-  "tagOrBio": "Passionate Xamarin/Microsoft technologies developer",
-  "webSite": "https://blog.francois.raminosona.com/",
-  "feedUris": [
-    "https://blog.francois.raminosona.com/tag/xamarin/rss/"
-  ],
-  "twitterHandle": "framinosona",
-  "gravatarHash": "b3b91b8d4bd1e716982eef6e5228c92f",
-  "githubHandle": "framinosona",
-  "position": {
-    "lat": 58.9720089,
-    "lon": 5.7363974
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/gonemobilecast.json b/Authors/gonemobilecast.json
deleted file mode 100644
index 290ca54..0000000
--- a/Authors/gonemobilecast.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Gone",
-  "lastName": "Mobile",
-  "stateOrRegion": "Internet",
-  "emailAddress": "hello@gonemobile.io",
-  "tagOrBio": "is a development podcast focused on mobile development hosted by Jon Dick and Greg Shackles.",
-  "webSite": "http://gonemobile.io",
-  "feedUris": [
-    "https://feed.gonemobile.io/"
-  ],
-  "twitterHandle": "gonemobilecast",
-  "position": {
-    "lat": 51.253775,
-    "lon": -85.323214
-  },
-  "gravatarHash": "cb611c5ecd9a53b2af53a9d50d83c3c5",
-  "githubHandle": "",
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/gptucci.json b/Authors/gptucci.json
deleted file mode 100644
index f9af534..0000000
--- a/Authors/gptucci.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "webSite": "https://www.informaticapressapochista.com/it",
-  "firstName": "Giampaolo",
-  "lastName": "Tucci",
-  "stateOrRegion": "Italia",
-  "emailAddress": "g.tucci@informaticapressapochista.com",
-  "tagOrBio": "L'IT come non l'avete mai letta",
-  "gravatarHash": "a8846caf48c8ccc9850ff201c1e2ad1d",
-  "feedUris": [
-    "https://www.informaticapressapochista.com/it/?format=feed&type=rss"
-  ],
-  "twitterHandle": "GiampaoloTUCCI",
-  "githubHandle": "gptucci",
-  "position": {
-    "lat": 44.40138,
-    "lon": 8.93419
-  },
-  "languageCode": "it"
-}
\ No newline at end of file
diff --git a/Authors/gshackles.json b/Authors/gshackles.json
deleted file mode 100644
index 4a18581..0000000
--- a/Authors/gshackles.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Greg",
-  "lastName": "Shackles",
-  "tagOrBio": "knows a thing (or two) about mobile testing",
-  "emailAddress": "greg@gregshackles.com",
-  "twitterHandle": "gshackles",
-  "gravatarHash": "6d7b45031bf22823060849d494343a8c",
-  "stateOrRegion": "New York, NY",
-  "webSite": "https://gregshackles.com",
-  "feedUris": [
-    "https://gregshackles.com/rss/"
-  ],
-  "githubHandle": "gshackles",
-  "position": {
-    "lat": 40.712784,
-    "lon": -74.005941
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/hnabbasi.json b/Authors/hnabbasi.json
deleted file mode 100644
index ebcee56..0000000
--- a/Authors/hnabbasi.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Hussain",
-  "lastName": "Abbasi",
-  "stateOrRegion": "Houston, Texas",
-  "emailAddress": "hnabbasi@outlook.com",
-  "tagOrBio": "is a Blogger, Mobile Architect, and founder of intelliAbb.com. More at HussainAbbasi.com",
-  "webSite": "https://www.intelliabb.com/",
-  "twitterHandle": "HussainNAbbasi",
-  "githubHandle": "hnabbasi",
-  "gravatarHash": "6f415af725ae2d6b5b912a7e93b105b9",
-  "feedUris": [
-    "https://www.intelliabb.com/feed"
-  ],
-  "position": {
-    "lat": 29.7656,
-    "lon": -95.3681
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/ionixjunior.json b/Authors/ionixjunior.json
deleted file mode 100644
index 8d190e5..0000000
--- a/Authors/ionixjunior.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Ione",
-  "lastName": "Souza Junior",
-  "tagOrBio": "",
-  "stateOrRegion": "Blumenau, Brasil",
-  "emailAddress": "junior@ionixjunior.com.br",
-  "twitterHandle": "ionixjunior",
-  "githubHandle": "ionixjunior",
-  "gravatarHash": "790726f5b5613d61926dea2e2efd4da1",
-  "position": {
-    "lat": -26.914236,
-    "lon": -49.068776
-  },
-  "webSite": "https://www.ionixjunior.com.br",
-  "feedUris": [
-    "https://www.ionixjunior.com.br/rss"
-  ],
-  "languageCode": "pt"
-}
\ No newline at end of file
diff --git a/Authors/jamesmontemagno.json b/Authors/jamesmontemagno.json
deleted file mode 100644
index a95e11c..0000000
--- a/Authors/jamesmontemagno.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "James",
-  "lastName": "Montemagno",
-  "stateOrRegion": "Seattle, WA",
-  "emailAddress": "",
-  "tagOrBio": "is a Principal Program Manager for Mobile Developer Tools",
-  "webSite": "https://montemagno.com",
-  "feedUris": [
-    "https://montemagno.com/rss"
-  ],
-  "twitterHandle": "JamesMontemagno",
-  "gravatarHash": "5df4d86308e585c879c19e5f909d8bfe",
-  "githubHandle": "jamesmontemagno",
-  "position": {
-    "lat": 47.654177,
-    "lon": -122.35
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/jesulink2514.json b/Authors/jesulink2514.json
deleted file mode 100644
index 3bc5320..0000000
--- a/Authors/jesulink2514.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "firstName": "Jesús",
-  "lastName": "Angulo",
-  "stateOrRegion": "Lima",
-  "emailAddress": "jesus.angulo@outlook.com",
-  "tagOrBio": "Microsoft MVP | Certified Xamarin Mobile Developer",
-  "webSite": "https://somostechies.com",
-  "twitterHandle": "jesulink2514",
-  "githubHandle": "jesulink2514",
-  "gravatarHash": "63359672e0ecb75e7ed261a358bf0478",
-  "feedUris": [
-    "https://somostechies.com/rss/",
-    "https://www.youtube.com/feeds/videos.xml?channel_id=UCnqaA_ArZIT0nytKMAiurzw"
-  ],
-  "position": {
-    "lat": -12.0896427,
-    "lon": -77.0060778
-  },
-  "languageCode": "es"
-}
\ No newline at end of file
diff --git a/Authors/jfversluis.json b/Authors/jfversluis.json
deleted file mode 100644
index 7544e9f..0000000
--- a/Authors/jfversluis.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Gerald",
-  "lastName": "Versluis",
-  "stateOrRegion": "The Netherlands",
-  "emailAddress": "gerald@verslu.is",
-  "tagOrBio": "Software Engineer at Microsoft on the Xamarin.Forms team",
-  "webSite": "https://blog.verslu.is/",
-  "feedUris": [
-    "https://blog.verslu.is/feed/"
-  ],
-  "twitterHandle": "jfversluis",
-  "gravatarHash": "f9d4d4211d7956ce3e07e83df0889731",
-  "githubHandle": "jfversluis",
-  "position": {
-    "lat": 50.889039,
-    "lon": 5.853717
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/jgiacomini.json b/Authors/jgiacomini.json
deleted file mode 100644
index 104c5a0..0000000
--- a/Authors/jgiacomini.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Jérôme",
-  "lastName": "Giacomini",
-  "stateOrRegion": "Paris, France",
-  "emailAddress": "jerome.giacomini@gmail.com",
-  "tagOrBio": "is a Xamarin Enthusiast, co-author of a book on Xamarin",
-  "webSite": "https://jeromegiacomini.net/Blog/",
-  "twitterHandle": "jeromegiacomini",
-  "githubHandle": "jgiacomini",
-  "gravatarHash": "95e63961669a22586a1236fd6a7a494d",
-  "feedUris": [
-    "https://jeromegiacomini.net/Blog/feed/"
-  ],
-  "position": {
-    "lat": 48.8704842,
-    "lon": 2.3449646
-  },
-  "languageCode": "fr"
-}
\ No newline at end of file
diff --git a/Authors/jimbobbennett.json b/Authors/jimbobbennett.json
deleted file mode 100644
index d97112e..0000000
--- a/Authors/jimbobbennett.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Jim",
-  "lastName": "Bennett",
-  "tagOrBio": "is the author of Xamarin in Action and a all-round nice guy",
-  "stateOrRegion": "Auckland, New Zealand",
-  "emailAddress": "jim@jimbobbennett.io",
-  "twitterHandle": "jimbobbennett",
-  "webSite": "https://jimbobbennett.io/",
-  "feedUris": [
-    "https://www.jimbobbennett.io/rss"
-  ],
-  "gravatarHash": "",
-  "githubHandle": "",
-  "position": {
-    "lat": -36.84846,
-    "lon": 174.763332
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/johnthiriet.json b/Authors/johnthiriet.json
deleted file mode 100644
index 21ab90a..0000000
--- a/Authors/johnthiriet.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "John",
-  "lastName": "Thiriet",
-  "stateOrRegion": "Paris, France",
-  "emailAddress": "johnthiriet@protonmail.com",
-  "tagOrBio": "is a Mobility Technical Manager, Trainer, Microsoft MVP, Xamarin MVP",
-  "webSite": "https://johnthiriet.com/",
-  "feedUris": [
-    "https://johnthiriet.com/feed.xml"
-  ],
-  "twitterHandle": "johnthiriet",
-  "gravatarHash": "ed92222c19a155a929d9f2c12d39c3f4",
-  "githubHandle": "johnthiriet",
-  "position": {
-    "lat": 48.875485,
-    "lon": 2.311039
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/jssuthahar.json b/Authors/jssuthahar.json
deleted file mode 100644
index 5195a63..0000000
--- a/Authors/jssuthahar.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Suthahar",
-  "lastName": "Jegatheesan",
-  "tagOrBio": "insatiable desire to keep learning keeps the dynamic blogger. I take keen interest in sharing my knowledge and solving my readers’ technology-related problems.",
-  "emailAddress": "",
-  "twitterHandle": "jssuthahar",
-  "gravatarHash": "2a34ebf4e9c4dca84eb7feee7217568f",
-  "stateOrRegion": "Bangalore, India",
-  "webSite": "https://www.msdevbuild.com/",
-  "position": {
-    "lat": 12.971599,
-    "lon": 77.594563
-  },
-  "feedUris": [
-    "https://www.msdevbuild.com/feeds/posts/default"
-  ],
-  "githubHandle": "jssuthahar",
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/jsuarezruiz.json b/Authors/jsuarezruiz.json
deleted file mode 100644
index 3361ef1..0000000
--- a/Authors/jsuarezruiz.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "feedUris": [
-    "https://javiersuarezruiz.wordpress.com/feed/"
-  ],
-  "firstName": "Javier",
-  "lastName": "Suarez",
-  "stateOrRegion": "Seville, Spain",
-  "emailAddress": "javiersuarezruiz@hotmail.com",
-  "tagOrBio": "is a passionate software developer from Spain who enjoys learning, talk and help others",
-  "webSite": "https://javiersuarezruiz.wordpress.com",
-  "twitterHandle": "jsuarezruiz",
-  "gravatarHash": "",
-  "position": {
-    "lat": 37.389092,
-    "lon": -5.984459
-  },
-  "githubHandle": "jsuarezruiz",
-  "languageCode": "es"
-}
\ No newline at end of file
diff --git a/Authors/jtaubensee.json b/Authors/jtaubensee.json
deleted file mode 100644
index 22f5cbb..0000000
--- a/Authors/jtaubensee.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "John",
-  "lastName": "Taubensee",
-  "stateOrRegion": "Chicago, IL",
-  "emailAddress": "",
-  "tagOrBio": "is a developer focused on Microsoft technologies. Microsoft Azure alumni",
-  "webSite": "https://taubensee.net",
-  "feedUris": [
-    "https://taubensee.net/rss"
-  ],
-  "twitterHandle": "jtaubensee",
-  "gravatarHash": "151bc535ca1581cb451eb4df1672b018",
-  "githubHandle": "jtaubensee",
-  "position": {
-    "lat": 41.8778143,
-    "lon": -87.6349955
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/kent_boogaart.json b/Authors/kent_boogaart.json
deleted file mode 100644
index 42a1b1f..0000000
--- a/Authors/kent_boogaart.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Kent",
-  "lastName": "Boogaart",
-  "stateOrRegion": "Australia",
-  "emailAddress": "kent.boogaart@gmail.com",
-  "tagOrBio": "is a freelance software engineer working mainly in the mobile space",
-  "webSite": "https://kent-boogaart.com/",
-  "feedUris": [
-    "https://kent-boogaart.com/atom.xml"
-  ],
-  "twitterHandle": "kent_boogaart",
-  "gravatarHash": "",
-  "githubHandle": "",
-  "position": {
-    "lat": -35.0004451,
-    "lon": 138.3309978
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/kphillpotts.json b/Authors/kphillpotts.json
deleted file mode 100644
index c501dad..0000000
--- a/Authors/kphillpotts.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Kym",
-  "lastName": "Phillpotts",
-  "tagOrBio": "is one of the Xamarin University instructors",
-  "stateOrRegion": "Melbourne, Australia",
-  "emailAddress": "kphillpotts@gmail.com",
-  "twitterHandle": "kphillpotts",
-  "gravatarHash": "3218e66502c6f0836dfd0f02f210ba0b",
-  "webSite": "https://kymphillpotts.com/",
-  "feedUris": [
-    "https://kymphillpotts.com/feed"
-  ],
-  "githubHandle": "kphillpotts",
-  "position": {
-    "lat": -37.813628,
-    "lon": 144.963058
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/kwlothrop.json b/Authors/kwlothrop.json
deleted file mode 100644
index 8f89f76..0000000
--- a/Authors/kwlothrop.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Kerry W.",
-  "lastName": "Lothrop",
-  "tagOrBio": "",
-  "stateOrRegion": "Frankfurt, Germany",
-  "emailAddress": "",
-  "twitterHandle": "kwlothrop",
-  "webSite": "https://kerry.lothrop.de/",
-  "feedUris": [
-    "https://kerry.lothrop.de/en/feed/"
-  ],
-  "gravatarHash": "250241b2800a1de895a75ce039bcfef4",
-  "githubHandle": "",
-  "position": {
-    "lat": 50.1307615,
-    "lon": 8.568736
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/logeshpalani98.json b/Authors/logeshpalani98.json
deleted file mode 100644
index 4263567..0000000
--- a/Authors/logeshpalani98.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Logesh",
-  "lastName": "Palani",
-  "stateOrRegion": "Thiruvannamalai,Tamil Nadu,  India",
-  "emailAddress": "logesh.01@hotmail.com",
-  "tagOrBio": "Keep Learning,.. and Keep Practicing,...",
-  "webSite": "https://logeshpalani.blogspot.com/",
-  "twitterHandle": "logeshpalani98",
-  "githubHandle": "logeshpalani98",
-  "gravatarHash": "14fd9ec21509b468c84abbed2e47384e",
-  "feedUris": [
-    "https://logeshpalani.blogspot.com/feeds/posts/default"
-  ],
-  "position": {
-    "lat": 12.527056,
-    "lon": 79.098382
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/luismts.json b/Authors/luismts.json
deleted file mode 100644
index 8e24113..0000000
--- a/Authors/luismts.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "firstName": "Luis",
-  "lastName": "Matos",
-  "stateOrRegion": "Dominican Republic",
-  "twitterHandle": "luismatosluna",
-  "emailAddress": "hello@luismts.com",
-  "tagOrBio": "Software Engineer, Entrepreneur",
-  "gravatarHash": "ac9ac28f6b1e05a310d622b37e8bc4be",
-  "webSite": "https://www.luismts.com/",
-  "feedUris": [
-    "https://www.luismts.com/feed/",
-    "https://www.luismts.com/es/feed/"
-  ],
-  "githubHandle": "luismts",
-  "position": {
-    "lat": 18.4900563,
-    "lon": -69.8962411
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/mallibone.json b/Authors/mallibone.json
deleted file mode 100644
index 49de03a..0000000
--- a/Authors/mallibone.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Mark",
-  "lastName": "Allibone",
-  "stateOrRegion": "Zurich, Switzerland",
-  "emailAddress": "",
-  "tagOrBio": "is a Microsoft MVP who blogs, talks, coaches and develops all around mobile development.",
-  "webSite": "https://mallibone.com",
-  "twitterHandle": "mallibone",
-  "githubHandle": "mallibone",
-  "gravatarHash": "4fa14971da4fafb96830960bc7c6733d",
-  "feedUris": [
-    "https://mallibone.com/feed/"
-  ],
-  "position": {
-    "lat": 47.5056381,
-    "lon": 8.7241297
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/marcofolio.json b/Authors/marcofolio.json
deleted file mode 100644
index b109554..0000000
--- a/Authors/marcofolio.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Marco",
-  "lastName": "Kuiper",
-  "tagOrBio": "is a Code monkey, incurably optimistic, loves great design and passionate about Xamarin.",
-  "stateOrRegion": "The Netherlands",
-  "emailAddress": "",
-  "twitterHandle": "marcofolio",
-  "gravatarHash": "5982941cf85cecc8254ec2a4f1c812ff",
-  "githubHandle": "marcofolio",
-  "position": {
-    "lat": 51.987642,
-    "lon": 5.904598
-  },
-  "webSite": "https://www.marcofolio.net/",
-  "feedUris": [
-    "https://feeds2.feedburner.com/marcofolio"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/marcusts.json b/Authors/marcusts.json
deleted file mode 100644
index 5380b47..0000000
--- a/Authors/marcusts.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Stephen",
-  "lastName": "Marcus",
-  "stateOrRegion": "Orange County, California",
-  "emailAddress": "marcus@marcusts.com",
-  "tagOrBio": "Certified Xamarin mobile app developer",
-  "webSite": "https://www.marcusts.com",
-  "feedUris": [
-    "https://www.marcusts.com/category/Xamarin/feed/"
-  ],
-  "twitterHandle": "",
-  "gravatarHash": "a64074b2ab0ac9b5a27379670b259d6d",
-  "githubHandle": "marcusts",
-  "position": {
-    "lat": 33.6423,
-    "lon": -117.6977
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/markolazic88.json b/Authors/markolazic88.json
deleted file mode 100644
index baa1fe1..0000000
--- a/Authors/markolazic88.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Marko",
-  "lastName": "Lazić",
-  "tagOrBio": "Software engineer, tech enthusiast, passionate traveler. 4+ years of active development in Xamarin.Forms",
-  "stateOrRegion": "Belgrade, Serbia",
-  "emailAddress": "marko.lazic88@gmail.com",
-  "twitterHandle": "markolazic88",
-  "gravatarHash": "5645586a7d29654e9b296b1409107014",
-  "webSite": "https://markolazic.com/",
-  "feedUris": [
-    "https://markolazic.com/feed/"
-  ],
-  "githubHandle": "markolazic88",
-  "position": {
-    "lat": 44.7866,
-    "lon": 20.4489
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/martijn00.json b/Authors/martijn00.json
deleted file mode 100644
index 576f3c1..0000000
--- a/Authors/martijn00.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Martijn",
-  "lastName": "van Dijk",
-  "stateOrRegion": "Amsterdam, Netherlands",
-  "emailAddress": "mhvdijk@gmail.com",
-  "tagOrBio": "is working at Baseflow.com on Apps and MvvmCross",
-  "webSite": "https://medium.com/@martijn00",
-  "feedUris": [
-    "https://medium.com/feed/@martijn00"
-  ],
-  "twitterHandle": "mhvdijk",
-  "gravatarHash": "22155f520ab611cf04f76762556ca3f5",
-  "githubHandle": "martijn00",
-  "position": {
-    "lat": 52.370216,
-    "lon": 4.895168
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/mattleibow.json b/Authors/mattleibow.json
deleted file mode 100644
index 2ee085e..0000000
--- a/Authors/mattleibow.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Matthew",
-  "lastName": "Leibowitz",
-  "tagOrBio": "An all-round software guy. I live and breathe C# and .NET on any platform.",
-  "emailAddress": "mattleibow@live.com",
-  "twitterHandle": "mattleibow",
-  "githubHandle": "mattleibow",
-  "gravatarHash": "365da45bdc71334831f228aff805738f",
-  "stateOrRegion": "Cape Town, South Africa",
-  "position": {
-    "lat": -34.02231,
-    "lon": 18.46716
-  },
-  "webSite": "https://dotnetdevaddict.co.za",
-  "feedUris": [
-    "https://dotnetdevaddict.co.za/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/mfractor.json b/Authors/mfractor.json
deleted file mode 100644
index 7dd9d23..0000000
--- a/Authors/mfractor.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "MFractor",
-  "lastName": "",
-  "stateOrRegion": "Brisbane, Australia",
-  "emailAddress": "matthew@mfractor.com",
-  "tagOrBio": "is a powerful productivity tool for Xamarin Developers.",
-  "webSite": "https://www.mfractor.com/",
-  "twitterHandle": "mfractor",
-  "githubHandle": "mfractor",
-  "gravatarHash": "35bac056166a67222ddcd48b57113a32",
-  "feedUris": [
-    "https://www.mfractor.com/blogs/news.atom"
-  ],
-  "position": {
-    "lat": -27.470125,
-    "lon": 153.021072
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/mike-grant.json b/Authors/mike-grant.json
deleted file mode 100644
index 667d7c9..0000000
--- a/Authors/mike-grant.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Mike",
-  "lastName": "Grant",
-  "stateOrRegion": "Leicestershire, England",
-  "emailAddress": "",
-  "tagOrBio": "Software Engineer",
-  "webSite": "https://www.mikegrant.org.uk",
-  "gravatarHash": "06c34ad3fb10ef6786a043c4522b6a5b",
-  "feedUris": [
-    "https://mikegrant.org.uk/feeds/Xamarin.Forms.xml"
-  ],
-  "twitterHandle": "mike_grant_",
-  "githubHandle": "mike-grant",
-  "position": {
-    "lat": 52.663878,
-    "lon": -1.3052377
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/mindofai.json b/Authors/mindofai.json
deleted file mode 100644
index 846d691..0000000
--- a/Authors/mindofai.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Bryan Anthony",
-  "lastName": "Garcia",
-  "stateOrRegion": "Manila, Philippines",
-  "githubHandle": "mindofai",
-  "twitterHandle": "mindofai",
-  "emailAddress": "bryananthonygarcia@live.com",
-  "tagOrBio": "Mobile .NET Developer who enjoys learning and writing about Mobile .NET stuff and has passion for football. Co-leads Mobile .NET Developers - Philippines",
-  "gravatarHash": "29e1cdab06c48322805220e33556c20c",
-  "webSite": "https://mindofai.github.io/",
-  "position": {
-    "lat": 14.668896,
-    "lon": 120.947204
-  },
-  "feedUris": [
-    "https://mindofai.github.io/feed.xml"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/mkieres.json b/Authors/mkieres.json
deleted file mode 100644
index f64ed2a..0000000
--- a/Authors/mkieres.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "emailAddress": "mikolaj.kieres@progrunning.net",
-  "languageCode": "en",
-  "feedUris": [
-    "https://progrunning.net/rss/"
-  ],
-  "firstName": "Mikolaj",
-  "githubHandle": "mkieres",
-  "gravatarHash": "",
-  "lastName": "Kieres",
-  "position": {
-    "lat": -33.826623,
-    "lon": 151.195031
-  },
-  "tagOrBio": "Mobile development adventurer",
-  "stateOrRegion": "Sydney, Australia",
-  "twitterHandle": "mikolajkieres",
-  "webSite": "https://progrunning.net"
-}
\ No newline at end of file
diff --git a/Authors/msiccdev.json b/Authors/msiccdev.json
deleted file mode 100644
index f003737..0000000
--- a/Authors/msiccdev.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Marco",
-  "lastName": "Siccardi",
-  "tagOrBio": "cross platform developer, writing software for Desktop, Mobiles and IOT",
-  "stateOrRegion": "Switzerland",
-  "emailAddress": "msiccdev@hotmail.com",
-  "twitterHandle": "msicc",
-  "gravatarHash": "67aaa7c3b6357dbccc1167a70b0c73e3",
-  "githubHandle": "msiccdev",
-  "position": {
-    "lat": 47.4683,
-    "lon": 8.75727
-  },
-  "webSite": "https://msicc.net/category/devstories/xamarin/",
-  "feedUris": [
-    "https://msicc.net/category/devstories/xamarin/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/nickrandolph.json b/Authors/nickrandolph.json
deleted file mode 100644
index d3febff..0000000
--- a/Authors/nickrandolph.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Nick",
-  "lastName": "Randolph",
-  "stateOrRegion": "Sydney, Australia",
-  "emailAddress": "nick@builttoroam.com",
-  "tagOrBio": "Microsoft MVP and maintainer of @MvvmCross. Co-founder, Tech Lead at Built to Roam (@btroam), special forces in cross platform app and cloud solutions.",
-  "webSite": "https://builttoroam.com",
-  "feedUris": [
-    "https://nicksnettravels.builttoroam.com/syndication.axd"
-  ],
-  "twitterHandle": "thenickrandolph",
-  "gravatarHash": "",
-  "githubHandle": "nickrandolph",
-  "position": {
-    "lat": -33.839559,
-    "lon": 151.2112434
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/nigelferrissey.json b/Authors/nigelferrissey.json
deleted file mode 100644
index e893dd6..0000000
--- a/Authors/nigelferrissey.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Nigel",
-  "lastName": "Ferrissey",
-  "tagOrBio": "Mobile and front-end developer, Xamarin specialist",
-  "emailAddress": "n_ferrissey@hotmail.com",
-  "twitterHandle": "nferrissey",
-  "gravatarHash": "106ec2de3e2ea4e88e9fc431974f5d53",
-  "stateOrRegion": "Brisbane, Australia",
-  "webSite": "https://xamarininsider.com",
-  "feedUris": [
-    "https://xamarininsider.com/rss/"
-  ],
-  "githubHandle": "nigelferrissey",
-  "position": {
-    "lat": -27.469657,
-    "lon": 153.025241
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/officialdoniald.json b/Authors/officialdoniald.json
deleted file mode 100644
index 0b845e1..0000000
--- a/Authors/officialdoniald.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Bence",
-  "lastName": "Lenart",
-  "tagOrBio": "Xamarin developer and blogger.",
-  "stateOrRegion": "Szeged, Hungary",
-  "emailAddress": "bence960206@gmail.com",
-  "webSite": "ttps://officialdoniald.com",
-  "feedUris": [
-    "https://officialdoniald.com/feed"
-  ],
-  "twitterHandle": "officialdoniald",
-  "gravatarHash": "4e467fcdbb65da5080d215bf303c442a",
-  "githubHandle": "officialdoniald",
-  "position": {
-    "lat": 46.231222,
-    "lon": 20.119167
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/peterfoot.json b/Authors/peterfoot.json
deleted file mode 100644
index d9d9ca7..0000000
--- a/Authors/peterfoot.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Peter",
-  "lastName": "Foot",
-  "stateOrRegion": "United Kingdom",
-  "emailAddress": "peter@peterfoot.net",
-  "twitterHandle": "peterfoot",
-  "webSite": "https://inthehand.com/blog/",
-  "feedUris": [
-    "https://inthehand.com/category/xamarin/feed/"
-  ],
-  "gravatarHash": "fa15aeeccc4b23e8a4677aeacb65b7bb",
-  "tagOrBio": "develops Xamarin and Windows applications at In The Hand Ltd",
-  "githubHandle": "peterfoot",
-  "position": {
-    "lat": 52.76872,
-    "lon": -2.37825
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/ramonesteban78.json b/Authors/ramonesteban78.json
deleted file mode 100644
index 25bc0d4..0000000
--- a/Authors/ramonesteban78.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Ramon",
-  "lastName": "Esteban",
-  "tagOrBio": "Freelance Xamarin developer",
-  "stateOrRegion": "Malaga, Spain",
-  "emailAddress": "wantedforcode@outlook.com",
-  "twitterHandle": "ramonesteban78",
-  "gravatarHash": "2fc49c3e9095aece416ad4e147fa1452",
-  "githubHandle": "ramonesteban78",
-  "position": {
-    "lat": 36.5126395,
-    "lon": -4.6483388
-  },
-  "webSite": "https://ramonesteban78.github.io/",
-  "feedUris": [
-    "https://ramonesteban78.github.io/feed.xml"
-  ],
-  "languageCode": "es"
-}
\ No newline at end of file
diff --git a/Authors/rdavisau.json b/Authors/rdavisau.json
deleted file mode 100644
index 51ef775..0000000
--- a/Authors/rdavisau.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "feedUris": [
-    "https://ryandavis.io/rss/"
-  ],
-  "firstName": "Ryan",
-  "lastName": "Davis",
-  "stateOrRegion": "Brisbane, Australia",
-  "emailAddress": "ryandavis.au@gmail.com",
-  "tagOrBio": "knows how to 🎉",
-  "webSite": "https://ryandavis.io",
-  "twitterHandle": "rdavis_au",
-  "githubHandle": "rdavisau",
-  "gravatarHash": "d351762ec451e252b20ff860dfcded91d351762ec451e252b20ff860dfcded91",
-  "position": {
-    "lat": -27.469771,
-    "lon": 153.025124
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/rdelrosario.json b/Authors/rdelrosario.json
deleted file mode 100644
index 4b067dd..0000000
--- a/Authors/rdelrosario.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Rendy",
-  "lastName": "Del Rosario",
-  "tagOrBio": "is a senior software developer with a passion for mobile development using Xamarin platform",
-  "stateOrRegion": "Dominican Republic",
-  "emailAddress": "rendy@crossgeeks.com",
-  "twitterHandle": "rdelrosario",
-  "gravatarHash": "4bece0ce1c33e65177110bcb95688c68",
-  "githubHandle": "rdelrosario",
-  "position": {
-    "lat": 18.486058,
-    "lon": -69.931212
-  },
-  "webSite": "https://xamboy.com/",
-  "feedUris": [
-    "https://xamboy.com/rss"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/redth.json b/Authors/redth.json
deleted file mode 100644
index 61f6a67..0000000
--- a/Authors/redth.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Jon",
-  "lastName": "Dick",
-  "tagOrBio": "",
-  "emailAddress": "jondick@gmail.com",
-  "twitterHandle": "redth",
-  "gravatarHash": "ad73e52d7e4d89e904e7c4cfd91fc2b9",
-  "stateOrRegion": "Ontario, Canada",
-  "webSite": "https://redth.codes",
-  "feedUris": [
-    "https://redth.codes/feed/"
-  ],
-  "githubHandle": "redth",
-  "position": {
-    "lat": 51.253775,
-    "lon": -85.323214
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/ricardoprestes.json b/Authors/ricardoprestes.json
deleted file mode 100644
index 902978e..0000000
--- a/Authors/ricardoprestes.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Ricardo",
-  "lastName": "Prestes",
-  "stateOrRegion": "Cornélio Procópio, Brasil",
-  "emailAddress": "ricardo.logan@hotmail.com",
-  "tagOrBio": "Tech lead mobile developer, Burger Monkeys Co-founder",
-  "webSite": "https://oficinadologan.wordpress.com/",
-  "twitterHandle": "ricardo_prestes",
-  "githubHandle": "ricardoprestes",
-  "gravatarHash": "9802e38d5bd2cd85db8b0720d5feed29",
-  "feedUris": [
-    "https://oficinadologan.wordpress.com/rss"
-  ],
-  "position": {
-    "lat": -23.194571,
-    "lon": -50.7795215
-  },
-  "languageCode": "pt"
-}
\ No newline at end of file
diff --git a/Authors/rid00z.json b/Authors/rid00z.json
deleted file mode 100644
index eab1205..0000000
--- a/Authors/rid00z.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Michael",
-  "lastName": "Ridland",
-  "stateOrRegion": "Sydney, Australia",
-  "emailAddress": "michael@xam-consulting.com",
-  "tagOrBio": "Xamarin Contractor/Consultant | Founder XAM Consulting (xam-consulting.com) | Creator of FreshMvvm",
-  "webSite": "https://michaelridland.com",
-  "feedUris": [
-    "https://michaelridland.com/feed/"
-  ],
-  "twitterHandle": "rid00z",
-  "gravatarHash": "3c07e56045d18f4f290eb4983031309d",
-  "githubHandle": "rid00z",
-  "position": {
-    "lat": -25.348875,
-    "lon": 131.035
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/robintschroeder.json b/Authors/robintschroeder.json
deleted file mode 100644
index abbcb44..0000000
--- a/Authors/robintschroeder.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Robin",
-  "lastName": "Schroeder",
-  "tagOrBio": "Xamarin.Forms/UWP Software Consultant at MSCTek",
-  "stateOrRegion": "Illinois",
-  "emailAddress": "robin@msctek.com",
-  "twitterHandle": "RTSchroeder",
-  "gravatarHash": "1754cd9eee726fd3a5252a4718cbf108",
-  "githubHandle": "robintschroeder",
-  "position": {
-    "lat": 41.9136926,
-    "lon": -88.3148351
-  },
-  "webSite": "https://msctek.com/",
-  "feedUris": [
-    "https://www.msctek.com/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/roubachof.json b/Authors/roubachof.json
deleted file mode 100644
index cdddf25..0000000
--- a/Authors/roubachof.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Jean-Marie",
-  "lastName": "Alfonsi",
-  "tagOrBio": "is a singing software engineer who travels at the speed light and wanna make a supersonic man out of you.",
-  "stateOrRegion": "Paris, France",
-  "emailAddress": "jm.alfonsi@gmail.com",
-  "twitterHandle": "Piskariov",
-  "gravatarHash": "2a30d8bc59e2ccb6e83bb498d519394a",
-  "webSite": "https://www.sharpnado.com/",
-  "feedUris": [
-    "https://www.sharpnado.com/rss/"
-  ],
-  "githubHandle": "roubachof",
-  "position": {
-    "lat": 48.8588377,
-    "lon": 2.2770206
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/saamerm.json b/Authors/saamerm.json
deleted file mode 100644
index 592393a..0000000
--- a/Authors/saamerm.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "feedUris": [
-    "https://medium.com/feed/@prototypemakers"
-  ],
-  "firstName": "Saamer",
-  "lastName": "Mansoor",
-  "stateOrRegion": "Toronto, Canada",
-  "emailAddress": "i@saamer.me",
-  "tagOrBio": "Top 5% Xamarin StackOverflow, Freelancer, Trainer",
-  "webSite": "https://medium.com/@prototypemakers",
-  "twitterHandle": "saamerm",
-  "githubHandle": "saamerm",
-  "gravatarHash": "66887acb0b76f2d3059255a1c53a3b22",
-  "position": {
-    "lat": 43.639728,
-    "lon": -79.380099
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/sact1909.json b/Authors/sact1909.json
deleted file mode 100644
index 0e3de8b..0000000
--- a/Authors/sact1909.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Steven",
-  "lastName": "Checo",
-  "stateOrRegion": "United States",
-  "emailAddress": "steven.checo.19@gmail.com",
-  "tagOrBio": "is a C# ASP.Net and Xamarin Developer, I'd preferd back-end but I get along with the Front-End, I love help others with code and build new things with friends, I ♥ C#",
-  "webSite": "https://checox.com",
-  "twitterHandle": "steven1909",
-  "githubHandle": "sact1909",
-  "gravatarHash": "47ad7178de588bb9a0b5922a5c1364c8",
-  "feedUris": [
-    "https://checox.com/feed/"
-  ],
-  "position": {
-    "lat": 40.837222,
-    "lon": -73.886111
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/samirgcofficial.json b/Authors/samirgcofficial.json
deleted file mode 100644
index c55fd76..0000000
--- a/Authors/samirgcofficial.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Samir",
-  "lastName": "GC",
-  "tagOrBio": ".net lover, xamarin mobile developer | XamarinGuy Show Host | Trainer | Instructor",
-  "stateOrRegion": "Kathmandu/Nepal",
-  "emailAddress": "samirgcofficial@gmail.com",
-  "twitterHandle": "xamaringuy",
-  "githubHandle": "samirgcofficial",
-  "position": {
-    "lat": 27.700769,
-    "lon": 85.30014
-  },
-  "webSite": "https://xamaringuyshow.com/",
-  "feedUris": [
-    "https://xamaringuyshow.com/feed/"
-  ],
-  "gravatarHash": "4b0b695b7711b0184ab2049e33f2cfd7",
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/shirshov.json b/Authors/shirshov.json
deleted file mode 100644
index 9de2a03..0000000
--- a/Authors/shirshov.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Alex",
-  "lastName": "Shirshov",
-  "stateOrRegion": "Sydney, Australia",
-  "emailAddress": "shirshov@gmail.com",
-  "tagOrBio": "Software Craftsman",
-  "webSite": "https://omnitalented.com",
-  "twitterHandle": "omnitalented",
-  "githubHandle": "shirshov",
-  "gravatarHash": "",
-  "position": {
-    "lat": -33.88236,
-    "lon": 151.206588
-  },
-  "languageCode": "en",
-  "feedUris": [
-    "https://omnitalented.com/rss-xamarin.xml"
-  ]
-}
\ No newline at end of file
diff --git a/Authors/smstuebe.json b/Authors/smstuebe.json
deleted file mode 100644
index 86aad08..0000000
--- a/Authors/smstuebe.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Sven-Michael",
-  "lastName": "Stübe",
-  "tagOrBio": "loves the cross platform approach, develops Xamarin plugins and organizes Xamarin Pizza & Beer Meetups in Munich",
-  "stateOrRegion": "Munich, Germany",
-  "emailAddress": "",
-  "twitterHandle": "stuebe2k14",
-  "webSite": "https://smstuebe.de/",
-  "feedUris": [
-    "https://smstuebe.de/feed.xml"
-  ],
-  "githubHandle": "smstuebe",
-  "gravatarHash": "08b73d0a58fc120a8cc8dc561d83b3d6",
-  "position": {
-    "lat": 48.1373831,
-    "lon": 11.5063151
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/sthewissen.json b/Authors/sthewissen.json
deleted file mode 100644
index 539b113..0000000
--- a/Authors/sthewissen.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Steven",
-  "lastName": "Thewissen",
-  "stateOrRegion": "The Netherlands",
-  "emailAddress": "",
-  "tagOrBio": " is a Xamarin Developer with a knack for Photoshop and a passion for soccer and cycling. He is also in love with his Xbox One",
-  "webSite": "https://www.thewissen.io/",
-  "feedUris": [
-    "https://www.thewissen.io/feed/"
-  ],
-  "twitterHandle": "devnl",
-  "gravatarHash": "9f698e6f515cb54dbda305034b6823fc",
-  "position": {
-    "lat": 50.889039,
-    "lon": 5.853717
-  },
-  "githubHandle": "sthewissen",
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/stvansolano.json b/Authors/stvansolano.json
deleted file mode 100644
index 28e2fee..0000000
--- a/Authors/stvansolano.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Esteban",
-  "lastName": "Solano",
-  "stateOrRegion": "Cartago, Costa Rica",
-  "emailAddress": "stvansolano@outlook.com",
-  "tagOrBio": "is a passionate software community guy from Costa Rica who enjoys learning, talk and help others to learn C# and Xamarin",
-  "webSite": "https://stvansolano.github.io/",
-  "feedUris": [
-    "https://stvansolano.github.io/atom.xml"
-  ],
-  "twitterHandle": "stvansolano",
-  "gravatarHash": "d02d96057c4cd905d60d14549b00db0d",
-  "githubHandle": "stvansolano",
-  "position": {
-    "lat": 9.9322992,
-    "lon": -84.0815271
-  },
-  "languageCode": "es"
-}
\ No newline at end of file
diff --git a/Authors/susairajs.json b/Authors/susairajs.json
deleted file mode 100644
index 5a9d688..0000000
--- a/Authors/susairajs.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Delpin",
-  "lastName": "Susai Raj",
-  "stateOrRegion": "Chennai, India",
-  "emailAddress": "susairajs@outlook.com",
-  "tagOrBio": "Code with Monkeys",
-  "webSite": "https://xamarinmonkeys.blogspot.com/",
-  "twitterHandle": "susairajs18",
-  "githubHandle": "susairajs",
-  "gravatarHash": "3408967b9598e7bb107baf15d5a15454",
-  "feedUris": [
-    "https://xamarinmonkeys.blogspot.com/feeds/posts/default"
-  ],
-  "position": {
-    "lat": 13.0783995,
-    "lon": 80.2886684
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/syncfusion.json b/Authors/syncfusion.json
deleted file mode 100644
index f5deb50..0000000
--- a/Authors/syncfusion.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Syncfusion",
-  "lastName": "",
-  "stateOrRegion": "North Carolina, USA",
-  "emailAddress": "info@syncfusion.com",
-  "tagOrBio": "Syncfusion provides the best third-party UI components for Xamarin, Xamarin.Android and Xamarin.iOS",
-  "webSite": "https://www.syncfusion.com/xamarin-ui-controls",
-  "feedUris": [
-    "https://www.syncfusion.com/blogs/feed"
-  ],
-  "twitterHandle": "Syncfusion",
-  "gravatarHash": "4291ef07481d300471113dbd4b4aabc2",
-  "githubHandle": "syncfusion",
-  "position": {
-    "lat": 35.855361,
-    "lon": -78.815751
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/tbertuzzi.json b/Authors/tbertuzzi.json
deleted file mode 100644
index cc1c04b..0000000
--- a/Authors/tbertuzzi.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Thiago",
-  "lastName": "Bertuzzi",
-  "tagOrBio": "Web and Mobile Developer, Blogger, Speaker",
-  "stateOrRegion": "São Paulo, Brasil",
-  "emailAddress": "thiago.bertuzzi@gmail.com",
-  "twitterHandle": "tbertuzzi",
-  "githubHandle": "tbertuzzi",
-  "gravatarHash": "82d95125be475913cdc7a7fe319d0133",
-  "position": {
-    "lat": -23.5834337,
-    "lon": -46.6672048
-  },
-  "webSite": "https://medium.com/@bertuzzi/",
-  "feedUris": [
-    "https://medium.com/feed/@bertuzzi"
-  ],
-  "languageCode": "pt"
-}
\ No newline at end of file
diff --git a/Authors/telerik.json b/Authors/telerik.json
deleted file mode 100644
index a4ca310..0000000
--- a/Authors/telerik.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Telerik",
-  "lastName": "",
-  "stateOrRegion": "Global",
-  "emailAddress": "telerikxamarinteam@progress.com",
-  "tagOrBio": "Progress Telerik UI libraries equip .NET ninjas with a full arsenal of weapons to help you create beautiful, modern and future-proof applications quickly and intuitively.",
-  "webSite": "https://www.telerik.com/",
-  "twitterHandle": "telerik",
-  "githubHandle": "telerik",
-  "gravatarHash": "",
-  "feedUris": [
-    "https://feeds.telerik.com/blogs"
-  ],
-  "position": {
-    "lat": 42.512778,
-    "lon": -71.2515
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/trailheadtechnology.json b/Authors/trailheadtechnology.json
deleted file mode 100644
index c613eed..0000000
--- a/Authors/trailheadtechnology.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Trailhead Technology",
-  "lastName": "",
-  "stateOrRegion": "Jenison, MI",
-  "twitterHandle": "@TrailheadTec",
-  "emailAddress": "info@trailheadtechnology.com",
-  "tagOrBio": "",
-  "gravatarHash": "0d6c200b64336790495f110332e1d7be",
-  "webSite": "https://www.trailheadtechnology.com/",
-  "feedUris": [
-    "https://trailheadtechnology.com/feed"
-  ],
-  "githubHandle": "trailheadtechnology",
-  "position": {
-    "lat": 42.921436,
-    "lon": -85.806578
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/vulcanlee.json b/Authors/vulcanlee.json
deleted file mode 100644
index 0067461..0000000
--- a/Authors/vulcanlee.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Vulcan",
-  "lastName": "Lee",
-  "stateOrRegion": "Taipei, Taiwan",
-  "twitterHandle": "vulcanlee",
-  "emailAddress": "vulcan.lee@gmail.com",
-  "tagOrBio": "Vulcan Lee is a Microsoft MVP who develops Xamarin at Doggy Ltd",
-  "gravatarHash": "f5de84ba365a15a05748624c07e70075",
-  "webSite": "https://mylabtw.blogspot.com/",
-  "feedUris": [
-    "https://mylabtw.blogspot.com/feeds/posts/default?alt=rss"
-  ],
-  "githubHandle": "vulcanlee",
-  "position": {
-    "lat": 25.043847,
-    "lon": 121.525645
-  },
-  "languageCode": "zh"
-}
\ No newline at end of file
diff --git a/Authors/willsb.json b/Authors/willsb.json
deleted file mode 100644
index 16de042..0000000
--- a/Authors/willsb.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "William",
-  "lastName": "Barbosa",
-  "stateOrRegion": "Santos, Brasil",
-  "twitterHandle": "willdotnet",
-  "githubHandle": "willsb",
-  "tagOrBio": "Microsoft MVP, Blogger, Speaker, Monkey Nights Co-founder/Host and MvvmCross contributor",
-  "emailAddress": "heytherewill@gmail.com",
-  "gravatarHash": "e47d219e8ee5d6dd5a44940dc26585c4",
-  "position": {
-    "lat": -23.954821,
-    "lon": -46.3247136
-  },
-  "webSite": "https://willsb.github.io",
-  "feedUris": [
-    "https://medium.com/feed/@heytherewill"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/winstongubantes.json b/Authors/winstongubantes.json
deleted file mode 100644
index 0fd50d0..0000000
--- a/Authors/winstongubantes.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Winston",
-  "lastName": "Gubantes",
-  "tagOrBio": "a Xamarin Developer at Gluon Consulting",
-  "stateOrRegion": "Davao City, Philippines",
-  "emailAddress": "winston.gubantes@gmail.com",
-  "twitterHandle": "tony_fear",
-  "gravatarHash": "9e1aea174237384361fc260b33559d05",
-  "githubHandle": "winstongubantes",
-  "position": {
-    "lat": 7.1066271,
-    "lon": 125.6294976
-  },
-  "webSite": "https://winstongubantes.blogspot.com/",
-  "feedUris": [
-    "https://winstongubantes.blogspot.com/feeds/posts/default?alt=rss"
-  ],
-  "languageCode": "es"
-}
\ No newline at end of file
diff --git a/Authors/wislon.json b/Authors/wislon.json
deleted file mode 100644
index 6e7fe33..0000000
--- a/Authors/wislon.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "John",
-  "lastName": "Wilson",
-  "stateOrRegion": "Brisbane, Australia",
-  "emailAddress": "wislon@hotmail.com",
-  "tagOrBio": "Head of Mobile, Tech Lead, Xamarin Specialist",
-  "webSite": "https://blog.wislon.io/",
-  "feedUris": [
-    "https://blog.wislon.io/atom.xml"
-  ],
-  "twitterHandle": "wislon",
-  "gravatarHash": "86c9d925c04b4c79c98bfc839d949e15",
-  "githubHandle": "wislon",
-  "position": {
-    "lat": -27.3812513,
-    "lon": 152.7130138
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/xablu.json b/Authors/xablu.json
deleted file mode 100644
index 0d8e711..0000000
--- a/Authors/xablu.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Xablu",
-  "lastName": "",
-  "stateOrRegion": "Amsterdam, the Netherlands",
-  "emailAddress": "hello@xablu.com",
-  "tagOrBio": "a 100% pure Xamarin company.",
-  "webSite": "https://www.xablu.com/",
-  "twitterHandle": "xabluhq",
-  "githubHandle": "xablu",
-  "gravatarHash": "508b1a99bb81e09c189e7487ecb69167",
-  "feedUris": [
-    "https://www.xablu.com/tag/planet-xamarin/feed/"
-  ],
-  "position": {
-    "lat": 52.3702,
-    "lon": 4.8952
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/xamarin.json b/Authors/xamarin.json
deleted file mode 100644
index 5ef90a8..0000000
--- a/Authors/xamarin.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "The Xamarin",
-  "lastName": "Blog",
-  "stateOrRegion": "Internet",
-  "emailAddress": "hello@xamarin.com",
-  "tagOrBio": "is your official source for Xamarin developer news.",
-  "webSite": "https://blog.xamarin.com",
-  "feedUris": [
-    "https://devblogs.microsoft.com/xamarin/feed/"
-  ],
-  "twitterHandle": "xamarinhq",
-  "gravatarHash": "70148d964bb389d42547834e1062c886",
-  "githubHandle": "xamarin",
-  "position": {
-    "lat": 37.77493,
-    "lon": -122.419416
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/xamarinhowto.json b/Authors/xamarinhowto.json
deleted file mode 100644
index 8b56c33..0000000
--- a/Authors/xamarinhowto.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "firstName": "Matt",
-  "lastName": "Crombie",
-  "tagOrBio": "Senior Xamarin Mobile Consultant/Architect",
-  "stateOrRegion": "Brisbane, Australia",
-  "emailAddress": "matt@xamarinhowto.com",
-  "twitterHandle": "xamarinhowto",
-  "gravatarHash": "3f1200c50911032b3558b7c0fc29c847",
-  "githubHandle": "xamarinhowto",
-  "position": {
-    "lat": -27.46845,
-    "lon": 153.024184
-  },
-  "webSite": "https://xamarinhowto.com/",
-  "feedUris": [
-    "https://xamarinhowto.com/feed/"
-  ],
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/Authors/yuv4ik.json b/Authors/yuv4ik.json
deleted file mode 100644
index 0055a33..0000000
--- a/Authors/yuv4ik.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "firstName": "Evgeny",
-  "lastName": "Zborovsky",
-  "stateOrRegion": "Estonia",
-  "emailAddress": "yuv4ik@gmail.com",
-  "tagOrBio": "blogs, speaks, helps others and is an enthusiastic Xamarin developer.",
-  "webSite": "https://evgenyzborovsky.com/",
-  "feedUris": [
-    "https://evgenyzborovsky.com/tag/xamarin-forms/feed/",
-    "https://evgenyzborovsky.com/tag/xamarin/feed/"
-  ],
-  "twitterHandle": "ezborovsky",
-  "gravatarHash": "b8a0ab8445fafb38afdf26cb976df32f",
-  "githubHandle": "yuv4ik",
-  "position": {
-    "lat": 58.3750372,
-    "lon": 26.6625567
-  },
-  "languageCode": "en"
-}
\ No newline at end of file
diff --git a/PlanetDotnet.sln b/PlanetDotnet.sln
index 0ecf4f3..7d9a35a 100644
--- a/PlanetDotnet.sln
+++ b/PlanetDotnet.sln
@@ -3,30 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio Version 17
 VisualStudioVersion = 17.4.32804.182
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanetDotnet", "PlanetDotnet\PlanetDotnet.csproj", "{591E633A-5665-4D84-B4B6-02B627699AC4}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8FA44784-F2C3-4749-9272-38F4D8EA9398}"
-	ProjectSection(SolutionItems) = preProject
-		author-schema.json = author-schema.json
-	EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanetDotnetAuthors", "PlanetDotnetAuthors\PlanetDotnetAuthors.csproj", "{57C40CD9-62CF-48D2-9A5E-C4CDD1CE6082}"
-EndProject
 Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{591E633A-5665-4D84-B4B6-02B627699AC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{591E633A-5665-4D84-B4B6-02B627699AC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{591E633A-5665-4D84-B4B6-02B627699AC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{591E633A-5665-4D84-B4B6-02B627699AC4}.Release|Any CPU.Build.0 = Release|Any CPU
-		{57C40CD9-62CF-48D2-9A5E-C4CDD1CE6082}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{57C40CD9-62CF-48D2-9A5E-C4CDD1CE6082}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{57C40CD9-62CF-48D2-9A5E-C4CDD1CE6082}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{57C40CD9-62CF-48D2-9A5E-C4CDD1CE6082}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
diff --git a/PlanetDotnet/Extensions/SyndicationItemExtensions.cs b/PlanetDotnet/Extensions/SyndicationItemExtensions.cs
deleted file mode 100644
index 5cb476d..0000000
--- a/PlanetDotnet/Extensions/SyndicationItemExtensions.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Linq;
-using System.ServiceModel.Syndication;
-
-namespace PlanetDotnet.Extensions
-{
-    public static class SyndicationItemExtensions
-    {
-        public static bool ApplyDefaultFilter(this SyndicationItem item)
-        {
-            if (item == null)
-                return false;
-
-            var hasXamarinCategory = false;
-            var hasXamarinKeywords = false;
-
-            if (item.Categories.Count > 0)
-            {
-                hasXamarinCategory = item.Categories.Any(category =>
-                    category.Name.ToLowerInvariant().Contains("xamarin"));
-            }
-
-            if (item.ElementExtensions.Count > 0)
-            {
-                var element = item.ElementExtensions.FirstOrDefault(e => e.OuterName == "keywords");
-                if (element != null)
-                {
-                    var keywords = element.GetObject<string>();
-                    hasXamarinKeywords = keywords.ToLowerInvariant().Contains("xamarin");
-                }
-            }
-
-            var hasXamarinTitle = item.Title?.Text.ToLowerInvariant().Contains("xamarin") ?? false;
-
-            return hasXamarinTitle || hasXamarinCategory || hasXamarinKeywords;
-        }
-
-        public static string ToHtml(this SyndicationContent content)
-        {
-            var textSyndicationContent = content as TextSyndicationContent;
-            if (textSyndicationContent != null)
-            {
-                return textSyndicationContent.Text;
-            }
-
-            return content.ToString();
-        }
-    }
-}
\ No newline at end of file
diff --git a/PlanetDotnet/Infrastructure/CombinedFeedSource.cs b/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
deleted file mode 100644
index 61b204f..0000000
--- a/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
+++ /dev/null
@@ -1,213 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.ServiceModel.Syndication;
-using System.Threading.Tasks;
-using System.Xml;
-using Microsoft.Extensions.Logging;
-using PlanetDotnet.Extensions;
-using PlanetDotnetAuthors.Models;
-using Polly;
-using Polly.Retry;
-
-namespace PlanetDotnet.Infrastructure
-{
-    public class CombinedFeedSource
-    {
-        private static HttpClient _httpClient;
-        private static AsyncRetryPolicy _retryPolicy;
-        private readonly IEnumerable<Author> _authors;
-        private readonly ILogger _logger;
-        private readonly string _rssFeedTitle;
-        private readonly string _rssFeedDescription;
-        private readonly string _rssFeedUrl;
-        private readonly string _rssFeedImageUrl;
-
-        public CombinedFeedSource(
-            IEnumerable<Author> authors,
-            ILogger logger,
-            string rssFeedTitle,
-            string rssFeedDescription,
-            string rssFeedUrl,
-            string rssFeedImageUrl)
-        {
-            EnsureHttpClient();
-
-            if (_retryPolicy == null)
-            {
-                // retry policy with max 2 retries, delay by x*x^1.2 where x is retry attempt
-                // this will ensure we don't retry too quickly
-                _retryPolicy = Policy.Handle<FeedReadFailedException>()
-                    .WaitAndRetryAsync(2, retry => TimeSpan.FromSeconds(retry * Math.Pow(1.2, retry)));
-            }
-
-            _authors = authors;
-            _logger = logger;
-            _rssFeedTitle = rssFeedTitle;
-            _rssFeedDescription = rssFeedDescription;
-            _rssFeedUrl = rssFeedUrl;
-            _rssFeedImageUrl = rssFeedImageUrl;
-        }
-
-        private void EnsureHttpClient()
-        {
-            if (_httpClient == null)
-            {
-                _httpClient = new HttpClient();
-                _httpClient.DefaultRequestHeaders.UserAgent.Add(
-                    new ProductInfoHeaderValue("PlanetDotnet", $"{GetType().Assembly.GetName().Version}"));
-                _httpClient.Timeout = TimeSpan.FromSeconds(15);
-
-                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
-            }
-        }
-
-        public async Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageCode = "mixed")
-        {
-            IEnumerable<Author> tamarins;
-            if (languageCode == null || languageCode == "mixed") // use all tamarins
-            {
-                tamarins = _authors;
-            }
-            else
-            {
-                tamarins = _authors.Where(t => t.FeedLanguageCode == languageCode);
-            }
-
-            var feedTasks = tamarins.SelectMany(t => TryReadFeeds(t)).ToArray();
-
-            _logger?.LogInformation($"Loading feed for language: {languageCode} for {feedTasks.Length} authors");
-
-            var syndicationItems = await Task.WhenAll(feedTasks).ConfigureAwait(false);
-            var combinedFeed = GetCombinedFeed(syndicationItems.SelectMany(f => f), languageCode, tamarins, numberOfItems);
-            return combinedFeed;
-        }
-
-        private IEnumerable<Task<IEnumerable<SyndicationItem>>> TryReadFeeds(Author tamarin)
-        {
-            return tamarin.FeedUris.Select(uri => TryReadFeed(tamarin, uri.AbsoluteUri));
-        }
-
-        private async Task<IEnumerable<SyndicationItem>> TryReadFeed(Author tamarin, string feedUri)
-        {
-            try
-            {
-                return await _retryPolicy.ExecuteAsync(context => ReadFeed(feedUri), new Context(feedUri)).ConfigureAwait(false);
-            }
-            catch (FeedReadFailedException ex)
-            {
-                _logger.LogError(ex, $"{tamarin.FirstName} {tamarin.LastName}'s feed of {ex.Data["FeedUri"]} failed to load.");
-            }
-
-            return new SyndicationItem[0];
-        }
-
-        private async Task<IEnumerable<SyndicationItem>> ReadFeed(string feedUri)
-        {
-            HttpResponseMessage response;
-            try
-            {
-                _logger?.LogInformation($"Loading feed {feedUri}");
-                response = await _httpClient.GetAsync(feedUri).ConfigureAwait(false);
-                if (response.IsSuccessStatusCode)
-                {
-                    using var feedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
-                    using var reader = XmlReader.Create(feedStream);
-                    var feed = SyndicationFeed.Load(reader);
-                    var filteredItems = feed.Items
-                        .Where(item => item.ApplyDefaultFilter());
-
-                    return filteredItems;
-                }
-            }
-            catch (HttpRequestException hex)
-            {
-                throw new FeedReadFailedException("Loading remote syndication feed failed", hex)
-                    .WithData("FeedUri", feedUri);
-            }
-            catch (WebException ex)
-            {
-                throw new FeedReadFailedException("Loading remote syndication feed timed out", ex)
-                    .WithData("FeedUri", feedUri);
-            }
-            catch (XmlException ex)
-            {
-                throw new FeedReadFailedException("Failed parsing remote syndication feed", ex)
-                    .WithData("FeedUri", feedUri);
-            }
-            catch (TaskCanceledException ex)
-            {
-                throw new FeedReadFailedException("Reading feed timed out", ex)
-                    .WithData("FeedUri", feedUri);
-            }
-            catch (OperationCanceledException opcex)
-            {
-                throw new FeedReadFailedException("Reading feed timed out", opcex)
-                    .WithData("FeedUri", feedUri);
-            }
-
-            throw new FeedReadFailedException("Loading remote syndication feed failed.")
-                .WithData("FeedUri", feedUri)
-                .WithData("HttpStatusCode", (int)response.StatusCode);
-        }
-
-        private SyndicationFeed GetCombinedFeed(IEnumerable<SyndicationItem> items, string languageCode,
-            IEnumerable<Author> tamarins, int? numberOfItems)
-        {
-            DateTimeOffset GetMaxTime(SyndicationItem item)
-            {
-                return new[] { item.PublishDate.UtcDateTime, item.LastUpdatedTime.UtcDateTime }.Max();
-            }
-
-            var orderedItems = items
-                .Where(item =>
-                    GetMaxTime(item) <= DateTimeOffset.UtcNow)
-                .OrderByDescending(item => GetMaxTime(item));
-
-            var feed = new SyndicationFeed(
-                _rssFeedTitle,
-                _rssFeedDescription,
-                new Uri(_rssFeedUrl),
-                numberOfItems.HasValue ? orderedItems.Take(numberOfItems.Value) : orderedItems)
-            {
-                ImageUrl = new Uri(_rssFeedImageUrl),
-                Copyright = new TextSyndicationContent("The copyright for each post is retained by its author."),
-                Language = languageCode,
-                LastUpdatedTime = DateTimeOffset.UtcNow
-            };
-
-            foreach (var tamarin in tamarins)
-            {
-                feed.Contributors.Add(new SyndicationPerson(
-                    tamarin.EmailAddress, $"{tamarin.FirstName} {tamarin.LastName}", tamarin.WebSite.ToString()));
-            }
-
-            return feed;
-        }
-    }
-
-    public class FeedReadFailedException : Exception
-    {
-        public FeedReadFailedException(string message)
-            : base(message)
-        {
-        }
-
-        public FeedReadFailedException(string message, Exception inner)
-            : base(message, inner)
-        {
-        }
-    }
-
-    internal static class ExceptionExtensions
-    {
-        public static TException WithData<TException>(this TException exception, string key, object value) where TException : Exception
-        {
-            exception.Data[key] = value;
-            return exception;
-        }
-    }
-}
\ No newline at end of file
diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
deleted file mode 100644
index 00451f0..0000000
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.ServiceModel.Syndication;
-using System.Threading.Tasks;
-using System.Xml;
-using Azure.Storage.Blobs;
-using Azure.Storage.Blobs.Models;
-using Microsoft.Azure.WebJobs;
-using Microsoft.Extensions.Logging;
-using PlanetDotnet.Infrastructure;
-using PlanetDotnetAuthors;
-
-namespace PlanetDotnet
-{
-    public static class LoadFeedsFunction
-    {
-        [FunctionName("LoadFeedsFunction")]
-        public static async Task Run(
-            [TimerTrigger("0 0 */1 * * *", RunOnStartup = true)] TimerInfo myTimer,
-            ILogger log)
-        {
-            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
-
-            var rssFeedTitle = GetEnvironmentVariable("RssFeedTitle");
-            var rssFeedDescription = GetEnvironmentVariable("RssFeedDescription");
-            var rssFeedUrl = GetEnvironmentVariable("RssFeedUrl");
-            var rssFeedImageUrl = GetEnvironmentVariable("RssFeedImageUrl");
-
-            var authors = await AuthorsLoader.GetAllAuthors();
-            var languages = authors.Select(author => author.FeedLanguageCode).Distinct().ToList();
-            languages.Add("mixed");
-            var feedSource =
-                new CombinedFeedSource(
-                    authors,
-                    log,
-                    rssFeedTitle,
-                    rssFeedDescription,
-                    rssFeedUrl,
-                    rssFeedImageUrl);
-
-            var blobConnectString = GetEnvironmentVariable("FeedBlobStorage");
-            var container = new BlobContainerClient(blobConnectString, "feeds");
-            await container.CreateIfNotExistsAsync();
-            await container.SetAccessPolicyAsync(PublicAccessType.Blob);
-
-            foreach (var language in languages)
-            {
-                log.LogInformation($"Loading {language} combined author feed");
-                var feed = await feedSource.LoadFeed(null, language);
-                using var stream = await SerializeFeed(feed);
-                await UploadBlob(container, stream, language, log);
-            }
-        }
-
-        private static async Task UploadBlob(BlobContainerClient container, Stream feedStream, string language, ILogger log)
-        {
-            var feedName = $"feed.{language}.rss";
-            var blob = container.GetBlobClient(feedName);
-            await blob.UploadAsync(feedStream, overwrite: true);
-
-            log.LogInformation($"Uploaded {feedName} to {blob.Uri}");
-        }
-
-        private static async Task<Stream> SerializeFeed(SyndicationFeed feed)
-        {
-            var memoryStream = new MemoryStream();
-            using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
-            {
-                Async = true
-            });
-
-            var rssFormatter = new Rss20FeedFormatter(feed);
-            rssFormatter.WriteTo(xmlWriter);
-            await xmlWriter.FlushAsync();
-
-            memoryStream.Seek(0, SeekOrigin.Begin);
-
-            return memoryStream;
-        }
-
-        private static string GetEnvironmentVariable(string name)
-        {
-            return Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
-        }
-    }
-}
diff --git a/PlanetDotnet/PlanetDotnet.csproj b/PlanetDotnet/PlanetDotnet.csproj
deleted file mode 100644
index 1f7ca27..0000000
--- a/PlanetDotnet/PlanetDotnet.csproj
+++ /dev/null
@@ -1,24 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-  <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
-    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
-  </PropertyGroup>
-  <ItemGroup>
-    <PackageReference Include="Azure.Storage.Blobs" Version="12.6.0" />
-    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.9" />
-    <PackageReference Include="Polly" Version="7.2.1" />
-    <PackageReference Include="System.ServiceModel.Syndication" Version="4.7.0" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\PlanetDotnetAuthors\PlanetDotnetAuthors.csproj" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Update="host.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Update="local.settings.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
-    </None>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/PlanetDotnet/Properties/serviceDependencies.json b/PlanetDotnet/Properties/serviceDependencies.json
deleted file mode 100644
index fcc92d1..0000000
--- a/PlanetDotnet/Properties/serviceDependencies.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "dependencies": {
-    "storage1": {
-      "type": "storage",
-      "connectionId": "AzureWebJobsStorage"
-    }
-  }
-}
\ No newline at end of file
diff --git a/PlanetDotnet/Properties/serviceDependencies.local.json b/PlanetDotnet/Properties/serviceDependencies.local.json
deleted file mode 100644
index 155d87e..0000000
--- a/PlanetDotnet/Properties/serviceDependencies.local.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "dependencies": {
-    "storage1": {
-      "type": "storage.emulator",
-      "connectionId": "AzureWebJobsStorage"
-    }
-  }
-}
\ No newline at end of file
diff --git a/PlanetDotnet/host.json b/PlanetDotnet/host.json
deleted file mode 100644
index bb3b8da..0000000
--- a/PlanetDotnet/host.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-    "version": "2.0",
-    "logging": {
-        "applicationInsights": {
-            "samplingExcludedTypes": "Request",
-            "samplingSettings": {
-                "isEnabled": true
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/PlanetDotnet/local.settings.json b/PlanetDotnet/local.settings.json
deleted file mode 100644
index 6f0b5a7..0000000
--- a/PlanetDotnet/local.settings.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "IsEncrypted": false,
-  "Values": {
-    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
-    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
-    "RssFeedTitle": "Planet Xamarin",
-    "RssFeedDescription": "An aggregated feed from the Xamarin community",
-    "RssFeedUrl": "https://www.planetxamarin.com/feed",
-    "RssFeedImageUrl": "https://www.planetxamarin.com/Content/Logo.png",
-    "FeedBlobStorage": ""
-  }
-}
\ No newline at end of file
diff --git a/PlanetDotnetAuthors/AuthorsLoader.cs b/PlanetDotnetAuthors/AuthorsLoader.cs
deleted file mode 100644
index 031840f..0000000
--- a/PlanetDotnetAuthors/AuthorsLoader.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Threading.Tasks;
-using Newtonsoft.Json;
-using PlanetDotnetAuthors.Models;
-
-namespace PlanetDotnetAuthors
-{
-    public static class AuthorsLoader
-    {
-        public static async Task<IEnumerable<Author>> GetAllAuthors()
-        {
-            var assembly = Assembly.GetExecutingAssembly();
-            var resourceNames = assembly.GetManifestResourceNames();
-            var authorsResourceNames = resourceNames.Where(res =>
-                res.StartsWith("PlanetDotnetAuthors", StringComparison.OrdinalIgnoreCase) &&
-                res.EndsWith(".json", StringComparison.OrdinalIgnoreCase));
-
-            var authorsTasks = authorsResourceNames.Select(name => ReadAuthor(assembly, name));
-            var authors = await Task.WhenAll(authorsTasks).ConfigureAwait(false);
-            return authors;
-        }
-
-        private static async Task<Author> ReadAuthor(Assembly assembly, string authorResourceName)
-        {
-            using var stream = assembly.GetManifestResourceStream(authorResourceName);
-            using var reader = new StreamReader(stream);
-            var json = await reader.ReadToEndAsync().ConfigureAwait(false);
-            var author = JsonConvert.DeserializeObject<Author>(json);
-            return author;
-        }
-    }
-}
diff --git a/PlanetDotnetAuthors/Models/Author.cs b/PlanetDotnetAuthors/Models/Author.cs
deleted file mode 100644
index 6634bc5..0000000
--- a/PlanetDotnetAuthors/Models/Author.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using Newtonsoft.Json;
-
-namespace PlanetDotnetAuthors.Models
-{
-    public class Author
-    {
-        [JsonProperty("firstName", Required = Required.DisallowNull)]
-        public string FirstName { get; set; }
-        [JsonProperty("lastName", Required = Required.DisallowNull)]
-        public string LastName { get; set; }
-        [JsonProperty("stateOrRegion", Required = Required.DisallowNull)]
-        public string StateOrRegion { get; set; }
-        [EmailAddress]
-        [JsonProperty("emailAddress", Required = Required.Always)]
-        public string EmailAddress { get; set; }
-        [JsonProperty("tagOrBio", Required = Required.DisallowNull)]
-        public string ShortBioOrTagLine { get; set; }
-        [Url]
-        [JsonProperty("webSite", Required = Required.Always)]
-        public Uri WebSite { get; set; }
-        [JsonProperty("twitterHandle", Required = Required.DisallowNull)]
-        public string TwitterHandle { get; set; }
-        [JsonProperty("githubHandle", Required = Required.Always)]
-        public string GitHubHandle { get; set; }
-        [JsonProperty("gravatarHash", Required = Required.DisallowNull)]
-        public string GravatarHash { get; set; }
-        [JsonProperty("feedUris", Required = Required.Always)]
-        public IEnumerable<Uri> FeedUris { get; set; }
-        [JsonProperty("position", Required = Required.DisallowNull)]
-        public GeoPosition Position { get; set; }
-
-        // In ISO 639-1, lowercase, 2 letters
-        // https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
-        [JsonProperty("languageCode", Required = Required.Always)]
-        public string FeedLanguageCode { get; set; }
-    }
-}
diff --git a/PlanetDotnetAuthors/Models/GeoPosition.cs b/PlanetDotnetAuthors/Models/GeoPosition.cs
deleted file mode 100644
index ccc81c2..0000000
--- a/PlanetDotnetAuthors/Models/GeoPosition.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Newtonsoft.Json;
-
-namespace PlanetDotnetAuthors.Models
-{
-    public class GeoPosition
-    {
-        public static GeoPosition Empty = new GeoPosition(-1337, 42);
-
-        [JsonProperty("lat", Required = Required.Always)]
-        public double Lat { get; }
-        [JsonProperty("lon", Required = Required.Always)]
-        public double Lng { get; }
-
-        public GeoPosition(double lat, double lng)
-        {
-            Lat = lat;
-            Lng = lng;
-        }
-    }
-}
diff --git a/PlanetDotnetAuthors/PlanetDotnetAuthors.csproj b/PlanetDotnetAuthors/PlanetDotnetAuthors.csproj
deleted file mode 100644
index cb36460..0000000
--- a/PlanetDotnetAuthors/PlanetDotnetAuthors.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
-    <LangVersion>latest</LangVersion>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
-    <PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <EmbeddedResource Include="..\Authors\*.json" />
-  </ItemGroup>
-</Project>
diff --git a/author-schema.json b/author-schema.json
deleted file mode 100644
index 4388d1e..0000000
--- a/author-schema.json
+++ /dev/null
@@ -1,88 +0,0 @@
-{
-  {
-    "definitions": {
-      "GeoPosition": {
-        "type": "object",
-        "properties": {
-          "lat": {
-            "type": "number"
-          },
-          "lon": {
-            "type": "number"
-          }
-        },
-        "required": [
-          "lat",
-          "lon"
-        ]
-      }
-    },
-    "type": "object",
-    "properties": {
-      "firstName": {
-        "description": "Author First Name",
-        "type": "string"
-      },
-      "lastName": {
-        "description": "Author Last Name",
-        "type": "string"
-      },
-      "stateOrRegion": {
-        "description": "Author State or Region",
-        "type": "string"
-      },
-      "emailAddress": {
-        "description": "E-mail address",
-        "type": "string",
-        "format": "email"
-      },
-      "tagOrBio": {
-        "description": "Tagline or bio",
-        "type": "string"
-      },
-      "webSite": {
-        "description": "Author Web Site",
-        "type": "string",
-        "format": "uri"
-      },
-      "feedUris": {
-        "description": "Feed URIs",
-        "type": "array",
-        "items": {
-          "type": [
-            "string",
-            "null"
-          ],
-          "format": "uri"
-        }
-      },
-      "twitterHandle": {
-        "description": "Author Twitter Handle",
-        "type": "string"
-      },
-      "gravatarHash": {
-        "description": "Author Gravatar Hash",
-        "type": "string"
-      },
-      "githubHandle": {
-        "description": "Author GitHub Handle",
-        "type": "string"
-      },
-      "position": {
-        "description": "Author GeoPosition",
-        "$ref": "#/definitions/GeoPosition"
-      },
-      "languageCode": {
-        "description": "Feed Language Code. ISO 639-1 format.",
-        "type": "string"
-      }
-    },
-    "required": [
-      "emailAddress",
-      "webSite",
-      "feedUris",
-      "githubHandle",
-      "languageCode"
-    ]
-  }
-}
\ No newline at end of file

From 0629df002a4e4dfdb94199479b2bb3c136f0387d Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sat, 18 Nov 2023 22:27:36 +0100
Subject: [PATCH 03/18] INFRA: Initialize Project

---
 .editorconfig                                 |  26 ++
 PlanetDotnet.sln                              |  12 +
 PlanetDotnet/.gitignore                       | 264 ++++++++++++++++++
 PlanetDotnet/LoadFeedsFunction.cs             |  40 +++
 PlanetDotnet/PlanetDotnet.csproj              |  22 ++
 PlanetDotnet/Properties/launchSettings.json   |   9 +
 .../Properties/serviceDependencies.json       |  11 +
 .../Properties/serviceDependencies.local.json |  11 +
 PlanetDotnet/Startup.cs                       |  17 ++
 PlanetDotnet/host.json                        |  12 +
 10 files changed, 424 insertions(+)
 create mode 100644 .editorconfig
 create mode 100644 PlanetDotnet/.gitignore
 create mode 100644 PlanetDotnet/LoadFeedsFunction.cs
 create mode 100644 PlanetDotnet/PlanetDotnet.csproj
 create mode 100644 PlanetDotnet/Properties/launchSettings.json
 create mode 100644 PlanetDotnet/Properties/serviceDependencies.json
 create mode 100644 PlanetDotnet/Properties/serviceDependencies.local.json
 create mode 100644 PlanetDotnet/Startup.cs
 create mode 100644 PlanetDotnet/host.json

diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..660f3ad
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,26 @@
+# To learn more about .editorconfig see https://aka.ms/editorconfigdocs
+
+# C# or VB files
+[*.{cs,vb}]
+guidelines = 120
+
+#### Core EditorConfig Options ####
+
+#Formatting - header template
+file_header_template = ---------------------------------------------------------------\nCopyright (c) 2023 Planet Dotnet. All rights reserved.\nLicensed under the MIT License.\nSee License.txt in the project root for license information.\n---------------------------------------------------------------
+
+# Indentation and spacing
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = false
+
+#### .NET Coding Conventions ####
+
+# Organize usings
+dotnet_sort_system_directives_first = true
+dotnet_separate_import_directive_groups = false
+
diff --git a/PlanetDotnet.sln b/PlanetDotnet.sln
index 7d9a35a..1eec153 100644
--- a/PlanetDotnet.sln
+++ b/PlanetDotnet.sln
@@ -3,7 +3,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio Version 17
 VisualStudioVersion = 17.4.32804.182
 MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanetDotnet", "PlanetDotnet\PlanetDotnet.csproj", "{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}"
+EndProject
 Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
diff --git a/PlanetDotnet/.gitignore b/PlanetDotnet/.gitignore
new file mode 100644
index 0000000..ff5b00c
--- /dev/null
+++ b/PlanetDotnet/.gitignore
@@ -0,0 +1,264 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# Azure Functions localsettings file
+local.settings.json
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
\ No newline at end of file
diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
new file mode 100644
index 0000000..8d9b79a
--- /dev/null
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -0,0 +1,40 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+
+namespace PlanetDotnet
+{
+    public static class LoadFeedsFunction
+    {
+        [FunctionName("LoadFeedsFunction")]
+        public static async Task<IActionResult> Run(
+            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
+            ILogger log)
+        {
+            log.LogInformation("C# HTTP trigger function processed a request.");
+
+            string name = req.Query["name"];
+
+            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
+            dynamic data = JsonConvert.DeserializeObject(requestBody);
+            name = name ?? data?.name;
+
+            string responseMessage = string.IsNullOrEmpty(name)
+                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
+                : $"Hello, {name}. This HTTP triggered function executed successfully.";
+
+            return new OkObjectResult(responseMessage);
+        }
+    }
+}
diff --git a/PlanetDotnet/PlanetDotnet.csproj b/PlanetDotnet/PlanetDotnet.csproj
new file mode 100644
index 0000000..8b0fb18
--- /dev/null
+++ b/PlanetDotnet/PlanetDotnet.csproj
@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net6.0</TargetFramework>
+    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
+  </PropertyGroup>
+  <ItemGroup>
+    <None Remove=".gitignore" />
+  </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
+    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.2.0" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Update="host.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Update="local.settings.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
+    </None>
+  </ItemGroup>
+</Project>
diff --git a/PlanetDotnet/Properties/launchSettings.json b/PlanetDotnet/Properties/launchSettings.json
new file mode 100644
index 0000000..7076a81
--- /dev/null
+++ b/PlanetDotnet/Properties/launchSettings.json
@@ -0,0 +1,9 @@
+{
+  "profiles": {
+    "PlanetDotnet": {
+      "commandName": "Project",
+      "commandLineArgs": "--port 7287",
+      "launchBrowser": false
+    }
+  }
+}
\ No newline at end of file
diff --git a/PlanetDotnet/Properties/serviceDependencies.json b/PlanetDotnet/Properties/serviceDependencies.json
new file mode 100644
index 0000000..df4dcc9
--- /dev/null
+++ b/PlanetDotnet/Properties/serviceDependencies.json
@@ -0,0 +1,11 @@
+{
+  "dependencies": {
+    "appInsights1": {
+      "type": "appInsights"
+    },
+    "storage1": {
+      "type": "storage",
+      "connectionId": "AzureWebJobsStorage"
+    }
+  }
+}
\ No newline at end of file
diff --git a/PlanetDotnet/Properties/serviceDependencies.local.json b/PlanetDotnet/Properties/serviceDependencies.local.json
new file mode 100644
index 0000000..b804a28
--- /dev/null
+++ b/PlanetDotnet/Properties/serviceDependencies.local.json
@@ -0,0 +1,11 @@
+{
+  "dependencies": {
+    "appInsights1": {
+      "type": "appInsights.sdk"
+    },
+    "storage1": {
+      "type": "storage.emulator",
+      "connectionId": "AzureWebJobsStorage"
+    }
+  }
+}
\ No newline at end of file
diff --git a/PlanetDotnet/Startup.cs b/PlanetDotnet/Startup.cs
new file mode 100644
index 0000000..779de6d
--- /dev/null
+++ b/PlanetDotnet/Startup.cs
@@ -0,0 +1,17 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using Microsoft.Azure.Functions.Extensions.DependencyInjection;
+
+[assembly: FunctionsStartup(typeof(PlanetDotnet.Startup))]
+namespace PlanetDotnet
+{
+    public class Startup : FunctionsStartup
+    {
+        public override void Configure(IFunctionsHostBuilder builder)
+        { }
+    }
+}
diff --git a/PlanetDotnet/host.json b/PlanetDotnet/host.json
new file mode 100644
index 0000000..ee5cf5f
--- /dev/null
+++ b/PlanetDotnet/host.json
@@ -0,0 +1,12 @@
+{
+    "version": "2.0",
+    "logging": {
+        "applicationInsights": {
+            "samplingSettings": {
+                "isEnabled": true,
+                "excludedTypes": "Request"
+            },
+            "enableLiveMetricsFilters": true
+        }
+    }
+}
\ No newline at end of file

From 52d0c7efe83653d10f4d6710d076b0e8b9ca827f Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sat, 18 Nov 2023 22:30:12 +0100
Subject: [PATCH 04/18] INFRA: Initialize Unit Tests Project

---
 PlanetDotnet.Tests.Unit/DeleteMe.cs           | 16 ++++++++++
 .../PlanetDotnet.Tests.Unit.csproj            | 29 +++++++++++++++++++
 PlanetDotnet.sln                              |  6 ++++
 3 files changed, 51 insertions(+)
 create mode 100644 PlanetDotnet.Tests.Unit/DeleteMe.cs
 create mode 100644 PlanetDotnet.Tests.Unit/PlanetDotnet.Tests.Unit.csproj

diff --git a/PlanetDotnet.Tests.Unit/DeleteMe.cs b/PlanetDotnet.Tests.Unit/DeleteMe.cs
new file mode 100644
index 0000000..bdf1bb0
--- /dev/null
+++ b/PlanetDotnet.Tests.Unit/DeleteMe.cs
@@ -0,0 +1,16 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using Xunit;
+
+namespace PlanetDotnet.Tests.Unit
+{
+    public class DeleteMe
+    {
+        [Fact]
+        public void ShouldBeTrue() => Assert.True(true);
+    }
+}
\ No newline at end of file
diff --git a/PlanetDotnet.Tests.Unit/PlanetDotnet.Tests.Unit.csproj b/PlanetDotnet.Tests.Unit/PlanetDotnet.Tests.Unit.csproj
new file mode 100644
index 0000000..8180b84
--- /dev/null
+++ b/PlanetDotnet.Tests.Unit/PlanetDotnet.Tests.Unit.csproj
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net7.0</TargetFramework>
+    <ImplicitUsings>disable</ImplicitUsings>
+    <Nullable>disable</Nullable>
+
+    <IsPackable>false</IsPackable>
+    <IsTestProject>true</IsTestProject>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
+    <PackageReference Include="xunit" Version="2.4.2" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+    <PackageReference Include="coverlet.collector" Version="3.2.0">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\PlanetDotnet\PlanetDotnet.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/PlanetDotnet.sln b/PlanetDotnet.sln
index 1eec153..aa0ae85 100644
--- a/PlanetDotnet.sln
+++ b/PlanetDotnet.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.4.32804.182
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanetDotnet", "PlanetDotnet\PlanetDotnet.csproj", "{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanetDotnet.Tests.Unit", "PlanetDotnet.Tests.Unit\PlanetDotnet.Tests.Unit.csproj", "{ED070F5D-3C55-4E8F-B23A-381E09931D1C}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
 		{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{AA1CF7A0-FF81-40FA-ABB2-519AF44C2460}.Release|Any CPU.Build.0 = Release|Any CPU
+		{ED070F5D-3C55-4E8F-B23A-381E09931D1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{ED070F5D-3C55-4E8F-B23A-381E09931D1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{ED070F5D-3C55-4E8F-B23A-381E09931D1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{ED070F5D-3C55-4E8F-B23A-381E09931D1C}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

From 32ea601dfa70279bb928772f2bfc843a48e3f9a8 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sat, 18 Nov 2023 22:47:37 +0100
Subject: [PATCH 05/18] INFRA: Initialize Authors Project

---
 Authors/AlejandroRuiz.json                    | 19 ++++++++
 Authors/AnbuMani27.json                       | 19 ++++++++
 Authors/Cheesebaron.json                      | 19 ++++++++
 Authors/DamianMehers.json                     | 19 ++++++++
 Authors/DanRigby.json                         | 19 ++++++++
 Authors/JesseLiberty.json                     | 19 ++++++++
 Authors/JoeM-RP.json                          | 19 ++++++++
 Authors/JonDouglas.json                       | 19 ++++++++
 Authors/JuuCustodio.json                      | 19 ++++++++
 Authors/LeomarisReyes.json                    | 19 ++++++++
 Authors/LetsCreateSeries.json                 | 19 ++++++++
 Authors/MarcBruins.json                       | 19 ++++++++
 Authors/MartinZikmund.json                    | 19 ++++++++
 Authors/Martynnw.json                         | 19 ++++++++
 Authors/MergeConflictFM.json                  | 19 ++++++++
 Authors/PieEatingNinjas.json                  | 19 ++++++++
 Authors/Prin53.json                           | 19 ++++++++
 Authors/Pujolsluis.json                       | 19 ++++++++
 Authors/ReactiveUI.json                       | 19 ++++++++
 Authors/Sankra.json                           | 19 ++++++++
 Authors/StefanRiedmann.json                   | 19 ++++++++
 Authors/TheFo2sh.json                         | 19 ++++++++
 Authors/TheXamarinShow.json                   | 19 ++++++++
 Authors/TomSoderling.json                     | 19 ++++++++
 Authors/UdaraAlwis.json                       | 19 ++++++++
 Authors/VicenteGuzman.json                    | 19 ++++++++
 Authors/XamarinPodcast.json                   | 19 ++++++++
 Authors/acaliaro.json                         | 19 ++++++++
 Authors/ahoefling.json                        | 19 ++++++++
 Authors/akamud.json                           | 19 ++++++++
 Authors/alexsorokoletov.json                  | 19 ++++++++
 Authors/almirvuk.json                         | 19 ++++++++
 Authors/andreas-nesheim.json                  | 19 ++++++++
 Authors/aritchie.json                         | 19 ++++++++
 Authors/asfend.json                           | 19 ++++++++
 Authors/aspnetde.json                         | 19 ++++++++
 Authors/balivo.json                           | 19 ++++++++
 Authors/banditoth.json                        | 19 ++++++++
 Authors/basdecort.json                        | 19 ++++++++
 Authors/bbenetskyy.json                       | 19 ++++++++
 Authors/brminnick.json                        | 19 ++++++++
 Authors/canbilgin.json                        | 19 ++++++++
 Authors/chamons.json                          | 19 ++++++++
 Authors/char0394.json                         | 19 ++++++++
 Authors/cjlotz.json                           | 19 ++++++++
 Authors/codemillmatt.json                     | 19 ++++++++
 Authors/crswlls.json                          | 19 ++++++++
 Authors/damienaicheh.json                     | 19 ++++++++
 Authors/damiendoumer.json                     | 19 ++++++++
 Authors/danielcauser.json                     | 19 ++++++++
 Authors/danielmonettelli.json                 | 20 ++++++++
 Authors/dansiegel.json                        | 19 ++++++++
 Authors/davidbritch.json                      | 21 +++++++++
 Authors/dhindrik.json                         | 19 ++++++++
 Authors/divikiran.json                        | 19 ++++++++
 Authors/dylanberry.json                       | 19 ++++++++
 Authors/egbakou.json                          | 19 ++++++++
 Authors/elbrinner.json                        | 19 ++++++++
 Authors/felipebaltazar.json                   | 19 ++++++++
 Authors/filipoff2.json                        | 19 ++++++++
 Authors/framinosona.json                      | 19 ++++++++
 Authors/gonemobilecast.json                   | 19 ++++++++
 Authors/gptucci.json                          | 19 ++++++++
 Authors/gshackles.json                        | 19 ++++++++
 Authors/hnabbasi.json                         | 19 ++++++++
 Authors/ionixjunior.json                      | 19 ++++++++
 Authors/jamesmontemagno.json                  | 19 ++++++++
 Authors/jesulink2514.json                     | 20 ++++++++
 Authors/jfversluis.json                       | 19 ++++++++
 Authors/jgiacomini.json                       | 19 ++++++++
 Authors/jimbobbennett.json                    | 19 ++++++++
 Authors/johnthiriet.json                      | 19 ++++++++
 Authors/jssuthahar.json                       | 19 ++++++++
 Authors/jsuarezruiz.json                      | 19 ++++++++
 Authors/jtaubensee.json                       | 19 ++++++++
 Authors/kent_boogaart.json                    | 19 ++++++++
 Authors/kphillpotts.json                      | 19 ++++++++
 Authors/kwlothrop.json                        | 19 ++++++++
 Authors/logeshpalani98.json                   | 19 ++++++++
 Authors/luismts.json                          | 20 ++++++++
 Authors/mabroukmahdhi.json                    | 19 ++++++++
 Authors/mallibone.json                        | 19 ++++++++
 Authors/marcofolio.json                       | 19 ++++++++
 Authors/marcusts.json                         | 19 ++++++++
 Authors/markolazic88.json                     | 19 ++++++++
 Authors/martijn00.json                        | 19 ++++++++
 Authors/mattleibow.json                       | 19 ++++++++
 Authors/mfractor.json                         | 19 ++++++++
 Authors/mike-grant.json                       | 19 ++++++++
 Authors/mindofai.json                         | 19 ++++++++
 Authors/mkieres.json                          | 19 ++++++++
 Authors/msiccdev.json                         | 19 ++++++++
 Authors/nickrandolph.json                     | 19 ++++++++
 Authors/nigelferrissey.json                   | 19 ++++++++
 Authors/officialdoniald.json                  | 19 ++++++++
 Authors/peterfoot.json                        | 19 ++++++++
 Authors/ramonesteban78.json                   | 19 ++++++++
 Authors/rdavisau.json                         | 19 ++++++++
 Authors/rdelrosario.json                      | 19 ++++++++
 Authors/redth.json                            | 19 ++++++++
 Authors/ricardoprestes.json                   | 19 ++++++++
 Authors/rid00z.json                           | 19 ++++++++
 Authors/robintschroeder.json                  | 19 ++++++++
 Authors/roubachof.json                        | 19 ++++++++
 Authors/saamerm.json                          | 19 ++++++++
 Authors/sact1909.json                         | 19 ++++++++
 Authors/samirgcofficial.json                  | 19 ++++++++
 Authors/shirshov.json                         | 19 ++++++++
 Authors/smstuebe.json                         | 19 ++++++++
 Authors/sthewissen.json                       | 19 ++++++++
 Authors/stvansolano.json                      | 19 ++++++++
 Authors/susairajs.json                        | 19 ++++++++
 Authors/syncfusion.json                       | 19 ++++++++
 Authors/tbertuzzi.json                        | 19 ++++++++
 Authors/telerik.json                          | 19 ++++++++
 Authors/trailheadtechnology.json              | 19 ++++++++
 Authors/vulcanlee.json                        | 19 ++++++++
 Authors/willsb.json                           | 19 ++++++++
 Authors/winstongubantes.json                  | 19 ++++++++
 Authors/wislon.json                           | 19 ++++++++
 Authors/xablu.json                            | 19 ++++++++
 Authors/xamarin.json                          | 19 ++++++++
 Authors/xamarinhowto.json                     | 19 ++++++++
 Authors/yuv4ik.json                           | 20 ++++++++
 PlanetDotnet.Authors/Models/Authors/Author.cs | 47 +++++++++++++++++++
 .../Models/GeoPositions/GeoPosition.cs        | 26 ++++++++++
 .../PlanetDotnet.Authors.csproj               | 17 +++++++
 PlanetDotnet.sln                              |  6 +++
 128 files changed, 2458 insertions(+)
 create mode 100644 Authors/AlejandroRuiz.json
 create mode 100644 Authors/AnbuMani27.json
 create mode 100644 Authors/Cheesebaron.json
 create mode 100644 Authors/DamianMehers.json
 create mode 100644 Authors/DanRigby.json
 create mode 100644 Authors/JesseLiberty.json
 create mode 100644 Authors/JoeM-RP.json
 create mode 100644 Authors/JonDouglas.json
 create mode 100644 Authors/JuuCustodio.json
 create mode 100644 Authors/LeomarisReyes.json
 create mode 100644 Authors/LetsCreateSeries.json
 create mode 100644 Authors/MarcBruins.json
 create mode 100644 Authors/MartinZikmund.json
 create mode 100644 Authors/Martynnw.json
 create mode 100644 Authors/MergeConflictFM.json
 create mode 100644 Authors/PieEatingNinjas.json
 create mode 100644 Authors/Prin53.json
 create mode 100644 Authors/Pujolsluis.json
 create mode 100644 Authors/ReactiveUI.json
 create mode 100644 Authors/Sankra.json
 create mode 100644 Authors/StefanRiedmann.json
 create mode 100644 Authors/TheFo2sh.json
 create mode 100644 Authors/TheXamarinShow.json
 create mode 100644 Authors/TomSoderling.json
 create mode 100644 Authors/UdaraAlwis.json
 create mode 100644 Authors/VicenteGuzman.json
 create mode 100644 Authors/XamarinPodcast.json
 create mode 100644 Authors/acaliaro.json
 create mode 100644 Authors/ahoefling.json
 create mode 100644 Authors/akamud.json
 create mode 100644 Authors/alexsorokoletov.json
 create mode 100644 Authors/almirvuk.json
 create mode 100644 Authors/andreas-nesheim.json
 create mode 100644 Authors/aritchie.json
 create mode 100644 Authors/asfend.json
 create mode 100644 Authors/aspnetde.json
 create mode 100644 Authors/balivo.json
 create mode 100644 Authors/banditoth.json
 create mode 100644 Authors/basdecort.json
 create mode 100644 Authors/bbenetskyy.json
 create mode 100644 Authors/brminnick.json
 create mode 100644 Authors/canbilgin.json
 create mode 100644 Authors/chamons.json
 create mode 100644 Authors/char0394.json
 create mode 100644 Authors/cjlotz.json
 create mode 100644 Authors/codemillmatt.json
 create mode 100644 Authors/crswlls.json
 create mode 100644 Authors/damienaicheh.json
 create mode 100644 Authors/damiendoumer.json
 create mode 100644 Authors/danielcauser.json
 create mode 100644 Authors/danielmonettelli.json
 create mode 100644 Authors/dansiegel.json
 create mode 100644 Authors/davidbritch.json
 create mode 100644 Authors/dhindrik.json
 create mode 100644 Authors/divikiran.json
 create mode 100644 Authors/dylanberry.json
 create mode 100644 Authors/egbakou.json
 create mode 100644 Authors/elbrinner.json
 create mode 100644 Authors/felipebaltazar.json
 create mode 100644 Authors/filipoff2.json
 create mode 100644 Authors/framinosona.json
 create mode 100644 Authors/gonemobilecast.json
 create mode 100644 Authors/gptucci.json
 create mode 100644 Authors/gshackles.json
 create mode 100644 Authors/hnabbasi.json
 create mode 100644 Authors/ionixjunior.json
 create mode 100644 Authors/jamesmontemagno.json
 create mode 100644 Authors/jesulink2514.json
 create mode 100644 Authors/jfversluis.json
 create mode 100644 Authors/jgiacomini.json
 create mode 100644 Authors/jimbobbennett.json
 create mode 100644 Authors/johnthiriet.json
 create mode 100644 Authors/jssuthahar.json
 create mode 100644 Authors/jsuarezruiz.json
 create mode 100644 Authors/jtaubensee.json
 create mode 100644 Authors/kent_boogaart.json
 create mode 100644 Authors/kphillpotts.json
 create mode 100644 Authors/kwlothrop.json
 create mode 100644 Authors/logeshpalani98.json
 create mode 100644 Authors/luismts.json
 create mode 100644 Authors/mabroukmahdhi.json
 create mode 100644 Authors/mallibone.json
 create mode 100644 Authors/marcofolio.json
 create mode 100644 Authors/marcusts.json
 create mode 100644 Authors/markolazic88.json
 create mode 100644 Authors/martijn00.json
 create mode 100644 Authors/mattleibow.json
 create mode 100644 Authors/mfractor.json
 create mode 100644 Authors/mike-grant.json
 create mode 100644 Authors/mindofai.json
 create mode 100644 Authors/mkieres.json
 create mode 100644 Authors/msiccdev.json
 create mode 100644 Authors/nickrandolph.json
 create mode 100644 Authors/nigelferrissey.json
 create mode 100644 Authors/officialdoniald.json
 create mode 100644 Authors/peterfoot.json
 create mode 100644 Authors/ramonesteban78.json
 create mode 100644 Authors/rdavisau.json
 create mode 100644 Authors/rdelrosario.json
 create mode 100644 Authors/redth.json
 create mode 100644 Authors/ricardoprestes.json
 create mode 100644 Authors/rid00z.json
 create mode 100644 Authors/robintschroeder.json
 create mode 100644 Authors/roubachof.json
 create mode 100644 Authors/saamerm.json
 create mode 100644 Authors/sact1909.json
 create mode 100644 Authors/samirgcofficial.json
 create mode 100644 Authors/shirshov.json
 create mode 100644 Authors/smstuebe.json
 create mode 100644 Authors/sthewissen.json
 create mode 100644 Authors/stvansolano.json
 create mode 100644 Authors/susairajs.json
 create mode 100644 Authors/syncfusion.json
 create mode 100644 Authors/tbertuzzi.json
 create mode 100644 Authors/telerik.json
 create mode 100644 Authors/trailheadtechnology.json
 create mode 100644 Authors/vulcanlee.json
 create mode 100644 Authors/willsb.json
 create mode 100644 Authors/winstongubantes.json
 create mode 100644 Authors/wislon.json
 create mode 100644 Authors/xablu.json
 create mode 100644 Authors/xamarin.json
 create mode 100644 Authors/xamarinhowto.json
 create mode 100644 Authors/yuv4ik.json
 create mode 100644 PlanetDotnet.Authors/Models/Authors/Author.cs
 create mode 100644 PlanetDotnet.Authors/Models/GeoPositions/GeoPosition.cs
 create mode 100644 PlanetDotnet.Authors/PlanetDotnet.Authors.csproj

diff --git a/Authors/AlejandroRuiz.json b/Authors/AlejandroRuiz.json
new file mode 100644
index 0000000..3c57034
--- /dev/null
+++ b/Authors/AlejandroRuiz.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Alejandro",
+  "lastName": "Ruiz",
+  "tagOrBio": "Alejandro Ruiz is a Xamarin MVP, C# & Open Source Lover",
+  "stateOrRegion": "Guadalajara, Mexico",
+  "emailAddress": "alejandro@alejandroruizvarela.com",
+  "webSite": "https://alejandroruizvarela.blogspot.mx",
+  "feedUris": [
+    "https://alejandroruizvarela.blogspot.mx/rss.xml"
+  ],
+  "twitterHandle": "alejandroruizva",
+  "gravatarHash": "35d0fff7dbc133e9fe2075aa14205a57",
+  "githubHandle": "AlejandroRuiz",
+  "position": {
+    "lat": 20.66682,
+    "lon": -103.39182
+  },
+  "languageCode": "es"
+}
\ No newline at end of file
diff --git a/Authors/AnbuMani27.json b/Authors/AnbuMani27.json
new file mode 100644
index 0000000..6927891
--- /dev/null
+++ b/Authors/AnbuMani27.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Anbu",
+  "lastName": "Mani",
+  "tagOrBio": "is a Microsoft MVP who Blogger, Speaker, Founder & Organizer of XMonkeys360 Community – India.",
+  "emailAddress": "anbumani@xmonkeys360.com",
+  "twitterHandle": "anbu_mani27",
+  "gravatarHash": "f97650474e4aa5b9609a28dcfdb052d4",
+  "stateOrRegion": "Chennai, India",
+  "webSite": "https://www.xmonkeys360.com/",
+  "position": {
+    "lat": 12.902749,
+    "lon": 80.190846
+  },
+  "feedUris": [
+    "https://xmonkeys360.com/feed/"
+  ],
+  "githubHandle": "AnbuMani27",
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/Cheesebaron.json b/Authors/Cheesebaron.json
new file mode 100644
index 0000000..f218416
--- /dev/null
+++ b/Authors/Cheesebaron.json
@@ -0,0 +1,19 @@
+{
+  "feedUris": [
+    "https://blog.ostebaronen.dk/feed.xml"
+  ],
+  "firstName": "Tomasz",
+  "lastName": "Cielecki",
+  "stateOrRegion": "Copenhagen, Denmark",
+  "emailAddress": "tomasz@ostebaronen.dk",
+  "tagOrBio": "Open Source all the things!",
+  "webSite": "https://blog.ostebaronen.dk",
+  "twitterHandle": "Cheesebaron",
+  "githubHandle": "Cheesebaron",
+  "gravatarHash": "f780d57997526876b0625e517c1e0884",
+  "position": {
+    "lat": 55.8019193,
+    "lon": 12.523124
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/DamianMehers.json b/Authors/DamianMehers.json
new file mode 100644
index 0000000..78a0e5d
--- /dev/null
+++ b/Authors/DamianMehers.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Damian",
+  "lastName": "Mehers",
+  "tagOrBio": "Independent Xamarin Developer",
+  "stateOrRegion": "Geneva, Switzerland",
+  "emailAddress": "damian@mehers.com",
+  "twitterHandle": "DamianMehers",
+  "gravatarHash": "d77613f4e20bfcae401a6bf0018a83d1",
+  "githubHandle": "DamianMehers",
+  "position": {
+    "lat": 46.3635288,
+    "lon": 6.1860801
+  },
+  "webSite": "https://damian.fyi/",
+  "feedUris": [
+    "https://damian.fyi/feed/Xamarin.xml"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/DanRigby.json b/Authors/DanRigby.json
new file mode 100644
index 0000000..7284a50
--- /dev/null
+++ b/Authors/DanRigby.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Dan",
+  "lastName": "Rigby",
+  "tagOrBio": "is a Technical Solutions Professional",
+  "stateOrRegion": "Raleigh, North Carolina",
+  "emailAddress": "Dan.Rigby@Microsoft.com",
+  "twitterHandle": "DanRigby",
+  "githubHandle": "DanRigby",
+  "gravatarHash": "f025f772418fbcfd3a1e15a74bf0f8a4",
+  "position": {
+    "lat": 35.77959,
+    "lon": -78.638179
+  },
+  "webSite": "https://danrigby.com/",
+  "feedUris": [
+    "https://feeds.feedburner.com/DanRigby"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/JesseLiberty.json b/Authors/JesseLiberty.json
new file mode 100644
index 0000000..52dadc4
--- /dev/null
+++ b/Authors/JesseLiberty.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Jesse",
+  "lastName": "Liberty",
+  "tagOrBio": "See http://jesseliberty.me",
+  "stateOrRegion": "Massachusetts",
+  "emailAddress": "jesseliberty@gmail.com",
+  "twitterHandle": "jesseliberty",
+  "gravatarHash": "78d5b6609fe5a80ce67e9f971833a6c3",
+  "githubHandle": "JesseLiberty",
+  "position": {
+    "lat": 42.4703963,
+    "lon": -71.4477468
+  },
+  "webSite": "http://jesseliberty.me",
+  "feedUris": [
+    "https://feeds.feedburner.com/JesseLiberty-SilverlightGeek"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/JoeM-RP.json b/Authors/JoeM-RP.json
new file mode 100644
index 0000000..0b3c109
--- /dev/null
+++ b/Authors/JoeM-RP.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Joe",
+  "lastName": "Meyer",
+  "stateOrRegion": "Chicago, IL",
+  "twitterHandle": "iwritecodesmtms",
+  "emailAddress": "joseph.w.meyer@live.com",
+  "tagOrBio": "I write code sometimes",
+  "gravatarHash": "1431dd2c4749b0a178c7a3130e71831e",
+  "webSite": "https://iwritecodesometimes.net",
+  "githubHandle": "JoeM-RP",
+  "position": {
+    "lat": 41.92,
+    "lon": -87.65
+  },
+  "feedUris": [
+    "https://iwritecodesometimes.net/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/JonDouglas.json b/Authors/JonDouglas.json
new file mode 100644
index 0000000..98a9585
--- /dev/null
+++ b/Authors/JonDouglas.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Jon",
+  "lastName": "Douglas",
+  "tagOrBio": "",
+  "stateOrRegion": "Utah",
+  "emailAddress": "",
+  "twitterHandle": "_jondouglas",
+  "webSite": "https://www.jon-douglas.com/",
+  "feedUris": [
+    "https://www.jon-douglas.com/atom.xml"
+  ],
+  "gravatarHash": "83d67df0b9e002d1c55a2786aeeb0c1b",
+  "githubHandle": "JonDouglas",
+  "position": {
+    "lat": 39.32098,
+    "lon": -111.093731
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/JuuCustodio.json b/Authors/JuuCustodio.json
new file mode 100644
index 0000000..1b6ac4d
--- /dev/null
+++ b/Authors/JuuCustodio.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Juliano",
+  "lastName": "Custódio",
+  "stateOrRegion": "Alphaville - Barueri, Brasil",
+  "twitterHandle": "JuuCustodio",
+  "githubHandle": "JuuCustodio",
+  "tagOrBio": "Solutions Architect, Blogger and Speaker",
+  "emailAddress": "juliano.custodio@hotmail.com.br",
+  "gravatarHash": "71de9936f2ffbc93e9918066479331f1",
+  "position": {
+    "lat": -23.4880831,
+    "lon": -46.8496769
+  },
+  "webSite": "https://www.julianocustodio.com",
+  "feedUris": [
+    "https://julianocustodio.com/tag/xamarin/rss/"
+  ],
+  "languageCode": "pt"
+}
\ No newline at end of file
diff --git a/Authors/LeomarisReyes.json b/Authors/LeomarisReyes.json
new file mode 100644
index 0000000..1b7b9fd
--- /dev/null
+++ b/Authors/LeomarisReyes.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Leomaris",
+  "lastName": "Reyes",
+  "tagOrBio": "is a software engineer",
+  "stateOrRegion": "Dominican Republic",
+  "emailAddress": "reyes.leomaris@gmail.com",
+  "twitterHandle": "leomarisreyes11",
+  "gravatarHash": "ae78e84a683611c7b72c9ba829c125e0",
+  "githubHandle": "LeomarisReyes",
+  "position": {
+    "lat": 18.47088,
+    "lon": -69.911525
+  },
+  "webSite": "https://askxammy.com/",
+  "feedUris": [
+    "https://askxammy.com/feed"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/LetsCreateSeries.json b/Authors/LetsCreateSeries.json
new file mode 100644
index 0000000..af8fdcd
--- /dev/null
+++ b/Authors/LetsCreateSeries.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "LetsCreateSeries",
+  "lastName": "",
+  "stateOrRegion": "United States",
+  "emailAddress": "letscreate.roblox@gmail.com",
+  "tagOrBio": "Create Mobile Apps using Xamarin.Forms",
+  "webSite": "https://letscreateseries.com",
+  "twitterHandle": "LetsCre8Series",
+  "githubHandle": "LetsCreateSeries",
+  "gravatarHash": "10793693ff507eda06ff02e9855e774f",
+  "feedUris": [
+    "https://letscreateseries.com/rss"
+  ],
+  "position": {
+    "lat": 40.6331,
+    "lon": 89.3985
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/MarcBruins.json b/Authors/MarcBruins.json
new file mode 100644
index 0000000..917537f
--- /dev/null
+++ b/Authors/MarcBruins.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Marc",
+  "lastName": "Bruins",
+  "tagOrBio": "is a native iOS/Android developer who fell in love with Xamarin",
+  "emailAddress": "marc@marcbruins.nl",
+  "twitterHandle": "MarcBruins",
+  "gravatarHash": "3795d2031be87499f76f6336ec5a3a45",
+  "stateOrRegion": "Utrecht, Netherlands",
+  "webSite": "https://www.marcbruins.nl",
+  "githubHandle": "MarcBruins",
+  "position": {
+    "lat": 53.219384,
+    "lon": 6.566502
+  },
+  "feedUris": [
+    "https://www.marcbruins.nl/feed.xml"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/MartinZikmund.json b/Authors/MartinZikmund.json
new file mode 100644
index 0000000..4d154cb
--- /dev/null
+++ b/Authors/MartinZikmund.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Martin",
+  "lastName": "Zikmund",
+  "stateOrRegion": "Prague, Czech Republic",
+  "emailAddress": "martinzikmund@sphereline.com",
+  "tagOrBio": "is a mobile + cloud solutions developer, Microsoftie, Geocacher, regular squash player, foodie and Insanity & P90X fan",
+  "webSite": "https://blog.mzikmund.com/",
+  "twitterHandle": "MZetko",
+  "githubHandle": "MartinZikmund",
+  "gravatarHash": "d1a45c7ba013fbc3e9044ff6461f6acd",
+  "position": {
+    "lat": 50.124017,
+    "lon": 14.451934
+  },
+  "languageCode": "en",
+  "feedUris": [
+    "https://blog.mzikmund.com/feed/?lang=en_us"
+  ]
+}
\ No newline at end of file
diff --git a/Authors/Martynnw.json b/Authors/Martynnw.json
new file mode 100644
index 0000000..0109f64
--- /dev/null
+++ b/Authors/Martynnw.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Martyn",
+  "lastName": "Wiggins",
+  "tagOrBio": "Mobile Developer, Mountain Biker, Wannabe Adventurer",
+  "stateOrRegion": "Nottingham",
+  "emailAddress": "Martynnw@gmail.com",
+  "twitterHandle": "Martynnw",
+  "gravatarHash": "bf974dae53bdbf5018fbbbf928db0f4e",
+  "githubHandle": "Martynnw",
+  "position": {
+    "lat": 52.95,
+    "lon": -1.133333
+  },
+  "webSite": "https://martynnw.wordpress.com",
+  "feedUris": [
+    "https://martynnw.wordpress.com/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/MergeConflictFM.json b/Authors/MergeConflictFM.json
new file mode 100644
index 0000000..7dc4a35
--- /dev/null
+++ b/Authors/MergeConflictFM.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Merge",
+  "lastName": "Conflict",
+  "stateOrRegion": "Seattle, WA",
+  "emailAddress": "mergeconflictfm@gmail.com",
+  "tagOrBio": "is a weekly development podcast hosted by Frank Krueger and James Montemagno.",
+  "webSite": "http://mergeconflict.fm",
+  "feedUris": [
+    "https://feeds.fireside.fm/mergeconflict/rss"
+  ],
+  "twitterHandle": "MergeConflictFM",
+  "gravatarHash": "24527eb9b29a8adbfc4155db4044dd3c",
+  "githubHandle": "",
+  "position": {
+    "lat": 47.60621,
+    "lon": -122.332071
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/PieEatingNinjas.json b/Authors/PieEatingNinjas.json
new file mode 100644
index 0000000..eb0aa47
--- /dev/null
+++ b/Authors/PieEatingNinjas.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Pieter",
+  "lastName": "Nijs",
+  "tagOrBio": "Senior .NET Software Engineer & Competence Leader Mobile @ Ordina Belgium. Passionate about programming, especially .NET, C#, XAML, Xamarin and UWP.",
+  "stateOrRegion": "Hasselt, Belgium",
+  "emailAddress": "pieternijs@live.be",
+  "twitterHandle": "nijspieter",
+  "gravatarHash": "61c9184b95820bdbbcd51764f3b9fb6e",
+  "githubHandle": "PieEatingNinjas",
+  "position": {
+    "lat": 50.93,
+    "lon": 5.3375
+  },
+  "webSite": "https://blog.pieeatingninjas.be/",
+  "feedUris": [
+    "https://blog.pieeatingninjas.be/feed/rss"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/Prin53.json b/Authors/Prin53.json
new file mode 100644
index 0000000..1d84a38
--- /dev/null
+++ b/Authors/Prin53.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Denys",
+  "lastName": "Fiediaiev",
+  "stateOrRegion": "Ukraine",
+  "emailAddress": "fiediaiev@sbyte.dev",
+  "tagOrBio": "is a mobile developer specializing in Xamarin technology",
+  "webSite": "https://medium.com/@prin53",
+  "twitterHandle": "sbytedev",
+  "githubHandle": "Prin53",
+  "gravatarHash": "0d5df57543a53231787d7a34a9b79cd6",
+  "feedUris": [
+    "https://medium.com/feed/@prin53"
+  ],
+  "position": {
+    "lat": 50.4547,
+    "lon": 30.5238
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/Pujolsluis.json b/Authors/Pujolsluis.json
new file mode 100644
index 0000000..bcac998
--- /dev/null
+++ b/Authors/Pujolsluis.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Luis",
+  "lastName": "Pujols",
+  "stateOrRegion": "United States",
+  "emailAddress": "luispujolso@gmail.com",
+  "tagOrBio": "is a Software Engineer with a passion for Mobile Development and Software Architecture. Co-organizer of the .NET Community in the Dominican Republic and a Xamarin Lover.",
+  "webSite": "https://www.pujolsluis.com/",
+  "twitterHandle": "Pujolsluis1",
+  "githubHandle": "Pujolsluis",
+  "gravatarHash": "c91c0d654f4f06ca6e7a7e54699de85d",
+  "feedUris": [
+    "https://www.pujolsluis.com/rss"
+  ],
+  "position": {
+    "lat": 26.0203048,
+    "lon": -80.115093
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/ReactiveUI.json b/Authors/ReactiveUI.json
new file mode 100644
index 0000000..2547b64
--- /dev/null
+++ b/Authors/ReactiveUI.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "ReactiveUI",
+  "lastName": "",
+  "stateOrRegion": "Internet",
+  "emailAddress": "hello@reactiveui.net",
+  "tagOrBio": "An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms",
+  "webSite": "https://reactiveui.net/",
+  "feedUris": [
+    "https://reactiveui.net/rss"
+  ],
+  "twitterHandle": "ReactiveXUI",
+  "gravatarHash": "",
+  "githubHandle": "ReactiveUI",
+  "position": {
+    "lat": -13.6981464,
+    "lon": 37.3979239
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/Sankra.json b/Authors/Sankra.json
new file mode 100644
index 0000000..5beca40
--- /dev/null
+++ b/Authors/Sankra.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Runar Ovesen",
+  "lastName": "Hjerpbakk",
+  "tagOrBio": "Passionate, empathic and experienced developer, software architect and manager. My love for C# is only surpassed by my love for Xamarin and iOS.",
+  "stateOrRegion": "Trondheim, Norway",
+  "emailAddress": "runar@hjerpbakk.com",
+  "twitterHandle": "hjerpbakk",
+  "gravatarHash": "62b1d11eafee92745a51971d6cc21f85",
+  "githubHandle": "Sankra",
+  "position": {
+    "lat": 63.4305,
+    "lon": 10.3951
+  },
+  "webSite": "https://hjerpbakk.com/",
+  "feedUris": [
+    "https://hjerpbakk.com/feed.xml"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/StefanRiedmann.json b/Authors/StefanRiedmann.json
new file mode 100644
index 0000000..3e8cbb3
--- /dev/null
+++ b/Authors/StefanRiedmann.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Stefan",
+  "githubHandle": "StefanRiedmann",
+  "lastName": "Riedmann",
+  "tagOrBio": "Growing software",
+  "stateOrRegion": "Mendoza, Argentina and Gemünden, Germany",
+  "emailAddress": "stefan.riedmann@ciclosoftware.com",
+  "twitterHandle": "CicloSoftware",
+  "webSite": "https://www.ciclosoftware.com",
+  "feedUris": [
+    "https://www.ciclosoftware.com/feed/"
+  ],
+  "gravatarHash": "2781a55d04634584326bedfe08660537",
+  "position": {
+    "lat": -32.8886904,
+    "lon": -68.8481432
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/TheFo2sh.json b/Authors/TheFo2sh.json
new file mode 100644
index 0000000..bb08f0e
--- /dev/null
+++ b/Authors/TheFo2sh.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Ahmed",
+  "lastName": "Fouad",
+  "stateOrRegion": "Vienna, Austria",
+  "emailAddress": "ahmed.fouad.net@hotmail.com",
+  "tagOrBio": "software engineer with 10 years experience with the .NET Framework living in Vienna, Austria.",
+  "webSite": "https://itnext.com/@csharpwriter",
+  "feedUris": [
+    "https://medium.com/feed/@csharpwriter"
+  ],
+  "twitterHandle": "MCC_Ahmed",
+  "gravatarHash": "5727eb3df565991947d90ed140962472",
+  "githubHandle": "TheFo2sh",
+  "position": {
+    "lat": 48.20849,
+    "lon": 16.37208
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/TheXamarinShow.json b/Authors/TheXamarinShow.json
new file mode 100644
index 0000000..a52665a
--- /dev/null
+++ b/Authors/TheXamarinShow.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "The Xamarin",
+  "lastName": "Show",
+  "stateOrRegion": "Channel 9",
+  "emailAddress": "",
+  "tagOrBio": "is a Weekly Developer Show for Xamarin Developers",
+  "webSite": "http://xamarinshow.com",
+  "feedUris": [
+    "https://channel9.msdn.com/Shows/XamarinShow/feed"
+  ],
+  "twitterHandle": "TheXamarinShow",
+  "gravatarHash": "7a0c7da0279b4e90439e780fa01924e0",
+  "githubHandle": "",
+  "position": {
+    "lat": 47.645136,
+    "lon": -122.130939
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/TomSoderling.json b/Authors/TomSoderling.json
new file mode 100644
index 0000000..823a6bc
--- /dev/null
+++ b/Authors/TomSoderling.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Tom",
+  "lastName": "Soderling",
+  "stateOrRegion": "Minneapolis, MN",
+  "emailAddress": "",
+  "tagOrBio": "is a Sr. Mobile Developer, speaker, and open source contributor",
+  "twitterHandle": "tomsoderling",
+  "gravatarHash": "dd103f377899fc63b0b88c5bb62b15bd",
+  "position": {
+    "lat": 44.986656,
+    "lon": -93.258133
+  },
+  "webSite": "https://tomsoderling.github.io",
+  "feedUris": [
+    "https://tomsoderling.github.io/feed.xml"
+  ],
+  "githubHandle": "TomSoderling",
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/UdaraAlwis.json b/Authors/UdaraAlwis.json
new file mode 100644
index 0000000..0297db2
--- /dev/null
+++ b/Authors/UdaraAlwis.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Udara",
+  "lastName": "Alwis",
+  "tagOrBio": "A mobile dev enthusiast. Xamarin Certified Developer in Singapore.",
+  "stateOrRegion": "Singapore",
+  "emailAddress": "udara.robotics@gmail.com",
+  "twitterHandle": "Udara_Alwis",
+  "gravatarHash": "125c4aaed98f2a88207dac78c17dd344",
+  "githubHandle": "UdaraAlwis",
+  "position": {
+    "lat": 1.284433,
+    "lon": 103.859609
+  },
+  "webSite": "https://theconfuzedsourcecode.wordpress.com/",
+  "feedUris": [
+    "https://theconfuzedsourcecode.wordpress.com/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/VicenteGuzman.json b/Authors/VicenteGuzman.json
new file mode 100644
index 0000000..7944023
--- /dev/null
+++ b/Authors/VicenteGuzman.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Vicente",
+  "lastName": "Guzman",
+  "tagOrBio": "Vicente Guzman is a Community Member / Microsoft rMVP / Software Engineer",
+  "stateOrRegion": "Ciudad de México",
+  "emailAddress": "luciomsp@geeks.ms",
+  "webSite": "https://vicenteguzman.mx/",
+  "feedUris": [
+    "https://vicenteguzman.mx/feed/"
+  ],
+  "twitterHandle": "luciomsp",
+  "gravatarHash": "72cce778aac0d6066a14225e90c30874",
+  "githubHandle": "VicenteGuzman",
+  "position": {
+    "lat": 19.432608,
+    "lon": -99.133209
+  },
+  "languageCode": "es"
+}
\ No newline at end of file
diff --git a/Authors/XamarinPodcast.json b/Authors/XamarinPodcast.json
new file mode 100644
index 0000000..2c6728d
--- /dev/null
+++ b/Authors/XamarinPodcast.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "The Xamarin",
+  "lastName": "Podcast",
+  "stateOrRegion": "Internet",
+  "emailAddress": "hello@xamarin.com",
+  "tagOrBio": "is the official Xamarin podcast discussing all things Xamarin!",
+  "webSite": "http://www.xamarinpodcast.com",
+  "feedUris": [
+    "https://feeds.fireside.fm/xamarinpodcast/rss"
+  ],
+  "twitterHandle": "XamarinPodcast",
+  "gravatarHash": "70148d964bb389d42547834e1062c886",
+  "githubHandle": "",
+  "position": {
+    "lat": -1337.0,
+    "lon": 42.0
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/acaliaro.json b/Authors/acaliaro.json
new file mode 100644
index 0000000..4899ee5
--- /dev/null
+++ b/Authors/acaliaro.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Alessandro",
+  "lastName": "Caliaro",
+  "tagOrBio": "I like Xamarin Forms and I like help other people to understand it",
+  "emailAddress": "acaliaro@libero.it",
+  "twitterHandle": "acaliaro",
+  "gravatarHash": "a7466eb1c467806f77bc692a4745d0f9",
+  "stateOrRegion": "Lissone, Italy",
+  "webSite": "https://acaliaro.wordpress.com",
+  "githubHandle": "acaliaro",
+  "position": {
+    "lat": 45.632783,
+    "lon": 9.227265
+  },
+  "feedUris": [
+    "https://acaliaro.wordpress.com/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/ahoefling.json b/Authors/ahoefling.json
new file mode 100644
index 0000000..eb8adee
--- /dev/null
+++ b/Authors/ahoefling.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Andrew",
+  "lastName": "Hoefling",
+  "stateOrRegion": "New York, United States",
+  "emailAddress": "andrew@hoefling.me",
+  "tagOrBio": "Microsoft MVP (Developer Technologies) Open Source developer who loves integrating Xamarin with other platforms",
+  "webSite": "https://www.andrewhoefling.com/",
+  "twitterHandle": "andrew_hoefling",
+  "githubHandle": "ahoefling",
+  "gravatarHash": "beab68478a5128e634590af5e4f01941",
+  "feedUris": [
+    "https://www.andrewhoefling.com/feed.xml?category=xamarin&uno-platform"
+  ],
+  "position": {
+    "lat": 43.156578,
+    "lon": -77.608849
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/akamud.json b/Authors/akamud.json
new file mode 100644
index 0000000..ca11d7b
--- /dev/null
+++ b/Authors/akamud.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Mahmoud",
+  "lastName": "Ali",
+  "stateOrRegion": "São Paulo, Brasil",
+  "emailAddress": "muddibr@gmail.com",
+  "tagOrBio": "Microsoft MVP",
+  "webSite": "https://www.lambda3.com.br/blog",
+  "twitterHandle": "akamud",
+  "githubHandle": "akamud",
+  "gravatarHash": "fc093b379c830c8105f8d15d9261a144",
+  "feedUris": [
+    "https://www.lambda3.com.br/feed/"
+  ],
+  "position": {
+    "lat": -23.552339,
+    "lon": -46.661393
+  },
+  "languageCode": "pt"
+}
\ No newline at end of file
diff --git a/Authors/alexsorokoletov.json b/Authors/alexsorokoletov.json
new file mode 100644
index 0000000..5687f73
--- /dev/null
+++ b/Authors/alexsorokoletov.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Alexandr",
+  "lastName": "Sorokoletov",
+  "tagOrBio": "when he's not developing mobile applications enjoys snowboarding, kitesurfing and travel",
+  "stateOrRegion": "Washington, D.C.",
+  "emailAddress": "",
+  "twitterHandle": "AlexSorokoletov",
+  "githubHandle": "alexsorokoletov",
+  "position": {
+    "lat": 38.905147,
+    "lon": -77.065189
+  },
+  "webSite": "https://sorokoletov.com",
+  "feedUris": [
+    "https://sorokoletov.com/atom.xml"
+  ],
+  "gravatarHash": "b07fef8827dd03655303751e2fd5ca95",
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/almirvuk.json b/Authors/almirvuk.json
new file mode 100644
index 0000000..7bae938
--- /dev/null
+++ b/Authors/almirvuk.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Almir",
+  "lastName": "Vuk",
+  "tagOrBio": "Software Development Engineer & Microsoft MVP, crafting apps with ASP.NET Core and Xamarin",
+  "stateOrRegion": "Mostar, Bosnia and Herzegovina",
+  "emailAddress": "almir.vuk@outlook.com",
+  "twitterHandle": "almirvuk",
+  "gravatarHash": "d58b6fd6c2d9f949345e8d14d203a4b2",
+  "webSite": "https://almirvuk.com/",
+  "feedUris": [
+    "https://almirvuk.com/rss/"
+  ],
+  "githubHandle": "almirvuk",
+  "position": {
+    "lat": 43.3395522,
+    "lon": 17.7862211
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/andreas-nesheim.json b/Authors/andreas-nesheim.json
new file mode 100644
index 0000000..92955da
--- /dev/null
+++ b/Authors/andreas-nesheim.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Andreas",
+  "lastName": "Nesheim",
+  "stateOrRegion": "Norway",
+  "emailAddress": "andreas.aronsen.nesheim@gmail.com",
+  "tagOrBio": ".NET developer with a passion for Xamarin, Azure DevOps and .NET Core.",
+  "webSite": "https://www.andreasnesheim.no/",
+  "twitterHandle": "AndreasNesheim",
+  "githubHandle": "andreas-nesheim",
+  "gravatarHash": "3f1d141d2809114debffb23277e91e3e",
+  "feedUris": [
+    "https://andreasnesheim.no/feed"
+  ],
+  "position": {
+    "lat": 58.9540147,
+    "lon": 5.7259639
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/aritchie.json b/Authors/aritchie.json
new file mode 100644
index 0000000..cb30817
--- /dev/null
+++ b/Authors/aritchie.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Allan",
+  "lastName": "Ritchie",
+  "stateOrRegion": "Toronto, Canada",
+  "emailAddress": "allan.ritchie@gmail.com",
+  "tagOrBio": "",
+  "webSite": "https://allancritchie.net",
+  "twitterHandle": "allanritchie911",
+  "githubHandle": "aritchie",
+  "gravatarHash": "5f22bd04ca38ed4d0a5225d0825e0726",
+  "position": {
+    "lat": 43.6425701,
+    "lon": -79.3892455
+  },
+  "languageCode": "en",
+  "feedUris": [
+    "https://allancritchie.net/xamarin.rss"
+  ]
+}
\ No newline at end of file
diff --git a/Authors/asfend.json b/Authors/asfend.json
new file mode 100644
index 0000000..6a7e94c
--- /dev/null
+++ b/Authors/asfend.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Asfend Yar",
+  "lastName": "Hamid",
+  "stateOrRegion": "Lahore, Pakistan",
+  "emailAddress": "asfend@hotmail.com",
+  "tagOrBio": "is a Technical Trainer, Author at Udemy and Passionate Community Member as well as Software Engineer",
+  "webSite": "https://xamarinui.blogspot.com/",
+  "feedUris": [
+    "https://xamarinui.blogspot.com/feeds/posts/default"
+  ],
+  "twitterHandle": "asfend",
+  "gravatarHash": "1aa9a7436eec5ad5d0418a385d1bdbe0",
+  "githubHandle": "asfend",
+  "position": {
+    "lat": 31.5712,
+    "lon": 74.3646
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/aspnetde.json b/Authors/aspnetde.json
new file mode 100644
index 0000000..190d444
--- /dev/null
+++ b/Authors/aspnetde.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Thomas",
+  "lastName": "Bandt",
+  "stateOrRegion": "Munich, Germany",
+  "position": {
+    "lat": 48.1485869,
+    "lon": 11.5353743
+  },
+  "emailAddress": "",
+  "webSite": "https://thomasbandt.com/",
+  "tagOrBio": "Developer & Entrepreneur of Passion",
+  "twitterHandle": "asp_net",
+  "githubHandle": "aspnetde",
+  "gravatarHash": "32860557b42ace0afa72704e466e34f1",
+  "feedUris": [
+    "https://thomasbandt.com/feed"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/balivo.json b/Authors/balivo.json
new file mode 100644
index 0000000..19c993f
--- /dev/null
+++ b/Authors/balivo.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Jefferson",
+  "lastName": "Balivo",
+  "stateOrRegion": "Jaú, São Paulo, Brazil",
+  "emailAddress": "jefferson@balivo.com.br",
+  "tagOrBio": "Xamarin Enthusiast, Technical Lead and Cross Platform Architect, Multi-Plataform Technical Audience Contributor (MTAC), Technical Writer and Speaker",
+  "webSite": "https://balivo.com.br/",
+  "twitterHandle": "jbalivo",
+  "githubHandle": "balivo",
+  "gravatarHash": "e5a95c365e8f06786d6439474bc733df",
+  "feedUris": [
+    "https://balivo.com.br/rss"
+  ],
+  "position": {
+    "lat": -22.2997067,
+    "lon": -48.5931324
+  },
+  "languageCode": "pt"
+}
\ No newline at end of file
diff --git a/Authors/banditoth.json b/Authors/banditoth.json
new file mode 100644
index 0000000..cca99ea
--- /dev/null
+++ b/Authors/banditoth.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "András",
+  "lastName": "Tóth",
+  "tagOrBio": "also known as banditoth | Xamarin && C# .NET developer from Hungary.",
+  "stateOrRegion": "Budapest, Hungary",
+  "emailAddress": "",
+  "twitterHandle": "",
+  "githubHandle": "banditoth",
+  "position": {
+    "lat": 47.497913,
+    "lon": 19.040236
+  },
+  "webSite": "https://www.banditoth.hu",
+  "feedUris": [
+    "https://www.banditoth.hu/feed/"
+  ],
+  "gravatarHash": "e11e3fd93c1cc4db5ec6f309bac0ff4d",
+  "languageCode": "hu"
+}
\ No newline at end of file
diff --git a/Authors/basdecort.json b/Authors/basdecort.json
new file mode 100644
index 0000000..2ef14fa
--- /dev/null
+++ b/Authors/basdecort.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Bas",
+  "lastName": "de Cort",
+  "stateOrRegion": "Tilburg, The Netherlands",
+  "emailAddress": "",
+  "tagOrBio": "is a mobile developer with a great passion for Xamarin 🙉",
+  "webSite": "https://www.basdecort.com",
+  "twitterHandle": "basdecort",
+  "githubHandle": "basdecort",
+  "gravatarHash": "9cabafd38c21d9df358f7532ffa39153",
+  "position": {
+    "lat": 52.040222799999995,
+    "lon": 5.5349002999999994
+  },
+  "feedUris": [
+    "https://www.basdecort.com/rss"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/bbenetskyy.json b/Authors/bbenetskyy.json
new file mode 100644
index 0000000..4d0d0ce
--- /dev/null
+++ b/Authors/bbenetskyy.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Bohdan",
+  "lastName": "Benetskyi",
+  "stateOrRegion": "Rzeszow, Poland",
+  "emailAddress": "benetskyybogdan@gmail.com",
+  "tagOrBio": "Xamarin Software Developer, co-organizer of Xamarin Local Events in Rzeszow, Local CSS at Xamarin Advocate",
+  "webSite": "https://medium.com/@benetskyybogdan/",
+  "twitterHandle": "bbenetskyy",
+  "githubHandle": "bbenetskyy",
+  "gravatarHash": "8bfa7db9239c2969b79468a58c8dd066",
+  "feedUris": [
+    "https://medium.com/feed/@benetskyybogdan/"
+  ],
+  "position": {
+    "lat": 50.041187,
+    "lon": 21.999121
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/brminnick.json b/Authors/brminnick.json
new file mode 100644
index 0000000..0359af3
--- /dev/null
+++ b/Authors/brminnick.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Brandon",
+  "lastName": "Minnick",
+  "stateOrRegion": "San Francisco, CA",
+  "emailAddress": "brandon@codetraveler.io",
+  "tagOrBio": "works as a Developer Advocate at Microsoft. Formerly a Customer Success Engineer at Xamarin (before the Microsoft Acquisition), Brandon has a loves helping developers make 5-star apps!",
+  "webSite": "https://codetraveler.io",
+  "twitterHandle": "TheCodeTraveler",
+  "githubHandle": "brminnick",
+  "gravatarHash": "e03e28629383def59c31d54fb8bb3982",
+  "position": {
+    "lat": 37.77669,
+    "lon": -122.416644
+  },
+  "languageCode": "en",
+  "feedUris": [
+    "https://codetraveler.io/tag/xamarin/rss"
+  ]
+}
\ No newline at end of file
diff --git a/Authors/canbilgin.json b/Authors/canbilgin.json
new file mode 100644
index 0000000..2ddfddf
--- /dev/null
+++ b/Authors/canbilgin.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Can",
+  "lastName": "Bilgin",
+  "tagOrBio": "Seasoned microsoft stack developer with passion for mobile development. Microsoft MVP for Windows Platform Development",
+  "stateOrRegion": "Sarajevo",
+  "emailAddress": "can_bilgin@hotmail.com",
+  "twitterHandle": "can_bilgin",
+  "gravatarHash": "3659d530c25e6188f7ef4c98ed100dc8",
+  "webSite": "https://canbilgin.wordpress.com/",
+  "feedUris": [
+    "https://canbilgin.wordpress.com/feed/"
+  ],
+  "githubHandle": "canbilgin",
+  "position": {
+    "lat": 43.8938256,
+    "lon": 18.3129519
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/chamons.json b/Authors/chamons.json
new file mode 100644
index 0000000..e26f390
--- /dev/null
+++ b/Authors/chamons.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Chris",
+  "lastName": "Hamons",
+  "tagOrBio": "is the lead engineer for Xamarin.Mac",
+  "stateOrRegion": "Austin, Texas",
+  "emailAddress": "chris.hamons@xamarin.com",
+  "twitterHandle": "IfErrThrowBrick",
+  "webSite": "https://medium.com/@donblas",
+  "feedUris": [
+    "https://medium.com/feed/@donblas"
+  ],
+  "gravatarHash": "8fb3e7f07ea1386cefe1326b48e0e21a",
+  "githubHandle": "chamons",
+  "position": {
+    "lat": 30.267153,
+    "lon": -97.743061
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/char0394.json b/Authors/char0394.json
new file mode 100644
index 0000000..f153a93
--- /dev/null
+++ b/Authors/char0394.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Charlin",
+  "lastName": "Agramonte",
+  "tagOrBio": "Software Engineer",
+  "stateOrRegion": "Dominican Republic",
+  "emailAddress": "charlin@crossgeeks.com",
+  "twitterHandle": "Chard003",
+  "gravatarHash": "7db2bb2eed17e8df7e78b0d5461d90b0",
+  "githubHandle": "char0394",
+  "position": {
+    "lat": 18.4735438,
+    "lon": -69.9456919
+  },
+  "webSite": "https://xamgirl.com/",
+  "feedUris": [
+    "https://xamgirl.com/rss"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/cjlotz.json b/Authors/cjlotz.json
new file mode 100644
index 0000000..2a640c6
--- /dev/null
+++ b/Authors/cjlotz.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Carel",
+  "lastName": "Lotz",
+  "tagOrBio": "is a Software Architect/Developer that loves to code",
+  "stateOrRegion": "Cape Town, South Africa",
+  "emailAddress": "carel.lotz@gmail.com",
+  "twitterHandle": "cjlotz",
+  "githubHandle": "cjlotz",
+  "gravatarHash": "0f692990601721c06f141f4fe860685e",
+  "position": {
+    "lat": -33.89635,
+    "lon": 18.70199
+  },
+  "webSite": "https://cjlotz.github.io",
+  "feedUris": [
+    "https://cjlotz.github.io/feed.xml"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/codemillmatt.json b/Authors/codemillmatt.json
new file mode 100644
index 0000000..8b8e421
--- /dev/null
+++ b/Authors/codemillmatt.json
@@ -0,0 +1,19 @@
+{
+  "feedUris": [
+    "https://codemilltech.com/feed/"
+  ],
+  "firstName": "Matthew",
+  "lastName": "Soucoup",
+  "stateOrRegion": "Madison, WI",
+  "emailAddress": "msoucoup@codemilltech.com",
+  "tagOrBio": "",
+  "webSite": "https://codemilltech.com",
+  "twitterHandle": "codemillmatt",
+  "gravatarHash": "df69069a0bffd2dae5a8700a1bef7bfd",
+  "githubHandle": "codemillmatt",
+  "position": {
+    "lat": 43.073052,
+    "lon": -89.40123
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/crswlls.json b/Authors/crswlls.json
new file mode 100644
index 0000000..5f8fd20
--- /dev/null
+++ b/Authors/crswlls.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Chris",
+  "lastName": "Williams",
+  "tagOrBio": "",
+  "emailAddress": "",
+  "twitterHandle": "crswlls",
+  "gravatarHash": "21e379df7ba9c57f167188e2fcb7dd75",
+  "stateOrRegion": "Bristol, UK",
+  "webSite": "https://crswlls.wordpress.com",
+  "feedUris": [
+    "https://crswlls.wordpress.com/rss/"
+  ],
+  "githubHandle": "",
+  "position": {
+    "lat": 30.267153,
+    "lon": -97.743061
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/damienaicheh.json b/Authors/damienaicheh.json
new file mode 100644
index 0000000..5459dfb
--- /dev/null
+++ b/Authors/damienaicheh.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Damien",
+  "lastName": "Aicheh",
+  "stateOrRegion": "Rennes, France",
+  "emailAddress": "",
+  "tagOrBio": "is a passionate mobile developer also interrested about Azure, Azure DevOps and.NET Core.",
+  "webSite": "https://damienaicheh.github.io/",
+  "twitterHandle": "damienaicheh",
+  "githubHandle": "damienaicheh",
+  "gravatarHash": "b5cf688a9aa81b3ef752ecda4366a8e9",
+  "feedUris": [
+    "https://damienaicheh.github.io/feed.xml"
+  ],
+  "position": {
+    "lat": 48.1113036,
+    "lon": -1.6801598
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/damiendoumer.json b/Authors/damiendoumer.json
new file mode 100644
index 0000000..30a269c
--- /dev/null
+++ b/Authors/damiendoumer.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Damien",
+  "lastName": "Doumer",
+  "stateOrRegion": "Douala, Cameroon",
+  "emailAddress": "damientohin@gmail.com",
+  "tagOrBio": "Fresh .Net developer, who loves mobile app development.",
+  "webSite": "https://doumer.me/",
+  "feedUris": [
+    "https://doumer.me/feed/"
+  ],
+  "twitterHandle": "Damien_Doumer",
+  "gravatarHash": "ecdd93df62c61daa04da17967f82d08d",
+  "githubHandle": "damiendoumer",
+  "position": {
+    "lat": 4.07316844239285,
+    "lon": 9.6842408186165585
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/danielcauser.json b/Authors/danielcauser.json
new file mode 100644
index 0000000..e7c0f22
--- /dev/null
+++ b/Authors/danielcauser.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Daniel",
+  "lastName": "Causer",
+  "stateOrRegion": "Toronto, Canada",
+  "emailAddress": "danielcauser@gmail.com",
+  "tagOrBio": "is a Xamarin Certified Developer fan of Xamarin and Mobile Development.",
+  "webSite": "https://causerexception.com/",
+  "twitterHandle": "danielcauser",
+  "githubHandle": "danielcauser",
+  "gravatarHash": "2666956714a2c2d48c480a6bddac4071",
+  "feedUris": [
+    "https://causerexception.com/feed"
+  ],
+  "position": {
+    "lat": 43.653103,
+    "lon": -79.383851
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/danielmonettelli.json b/Authors/danielmonettelli.json
new file mode 100644
index 0000000..668e204
--- /dev/null
+++ b/Authors/danielmonettelli.json
@@ -0,0 +1,20 @@
+{
+  "firstName": "Daniel Angel",
+  "lastName": "Monettelli L.",
+  "tagOrBio": "is a Software Engineer, Videoblogger, Xamarin Mobile Developer & UI/UX Architect.",
+  "stateOrRegion": "Arequipa, Perú",
+  "emailAddress": "danielmonetelli@hotmail.com",
+  "webSite": "https://danielmonettelli.github.io",
+  "feedUris": [
+    "https://danielmonettelli.github.io/feed.xml",
+    "https://www.youtube.com/feeds/videos.xml?channel_id=UCTAlbAORoFvAHj7jA4DLSFQ"
+  ],
+  "twitterHandle": "DanielMonetelli",
+  "gravatarHash": "4b3d0e60019ad8fe1e4d7cd5c8850efb",
+  "githubHandle": "danielmonettelli",
+  "position": {
+    "lat": -16.4042643,
+    "lon": -71.5486383
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/dansiegel.json b/Authors/dansiegel.json
new file mode 100644
index 0000000..b626148
--- /dev/null
+++ b/Authors/dansiegel.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Dan",
+  "lastName": "Siegel",
+  "stateOrRegion": "San Diego, CA",
+  "emailAddress": "dsiegel@avantipoint.com",
+  "tagOrBio": "is a Mobile App Consultant and Founder of AvantiPoint. He is an author of several OSS libraries, a maintainer of the Prism Library and a DevOps champion.",
+  "webSite": "https://dansiegel.net",
+  "feedUris": [
+    "https://dansiegel.net/syndication.axd"
+  ],
+  "twitterHandle": "DanJSiegel",
+  "gravatarHash": "b65a519785f69fbe7236dd0fd6396094",
+  "githubHandle": "dansiegel",
+  "position": {
+    "lat": 32.726308,
+    "lon": -117.177746
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/davidbritch.json b/Authors/davidbritch.json
new file mode 100644
index 0000000..bda68ed
--- /dev/null
+++ b/Authors/davidbritch.json
@@ -0,0 +1,21 @@
+{
+  "firstName": "David",
+  "lastName": "Britch",
+  "Title": "Senior Developer/Writer",
+  "stateOrRegion": "UK",
+  "emailAddress": "",
+  "twitterHandle": "britchdavid",
+  "gravatarHash": "0ddca71a03a3591203b4a748fcdfb47a",
+  "Started": "2015-06-08T00:00:00",
+  "tagOrBio": "",
+  "githubHandle": "davidbritch",
+  "position": {
+    "lat": 53.4793,
+    "lon": -2.2479
+  },
+  "webSite": "https://www.davidbritch.com",
+  "feedUris": [
+    "https://www.davidbritch.com/rss.xml"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/dhindrik.json b/Authors/dhindrik.json
new file mode 100644
index 0000000..5a103ec
--- /dev/null
+++ b/Authors/dhindrik.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Daniel",
+  "lastName": "Hindrikes",
+  "stateOrRegion": "Borlänge, Sweden",
+  "emailAddress": "daniel@hindrikes.se",
+  "tagOrBio": "is an architect and developer using Xamarin and Azure. Working as a Ninja at tretton37. Also recording \"The Code Behind\" podcast!",
+  "webSite": "https://danielhindrikes.se",
+  "twitterHandle": "hindrikes",
+  "githubHandle": "dhindrik",
+  "gravatarHash": "054db2cfd79654ec5d92e20c180f2d72",
+  "feedUris": [
+    "https://danielhindrikes.se/index.php/feed/"
+  ],
+  "position": {
+    "lat": 60.48604,
+    "lon": 15.43391
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/divikiran.json b/Authors/divikiran.json
new file mode 100644
index 0000000..870131c
--- /dev/null
+++ b/Authors/divikiran.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Divikiran",
+  "lastName": "Ravela",
+  "stateOrRegion": "Melbourne, Australia",
+  "emailAddress": "divikiran1@gmail.com",
+  "tagOrBio": "Xamarin Consultant/Tech Lead",
+  "webSite": "https://xamlabs.com/",
+  "twitterHandle": "",
+  "githubHandle": "divikiran",
+  "gravatarHash": "",
+  "feedUris": [
+    "https://xamlabs.com/feed/"
+  ],
+  "position": {
+    "lat": -37.8135511,
+    "lon": 144.9637748
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/dylanberry.json b/Authors/dylanberry.json
new file mode 100644
index 0000000..808d8fd
--- /dev/null
+++ b/Authors/dylanberry.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Dylan",
+  "lastName": "Berry",
+  "tagOrBio": "Genetically Predisposed Programmer",
+  "stateOrRegion": "Toronto, Canada",
+  "emailAddress": "dylanberry@gmail.com",
+  "twitterHandle": "dylbot9000",
+  "gravatarHash": "8ef85938904ff43397d50caa9b0eebed",
+  "githubHandle": "dylanberry",
+  "position": {
+    "lat": 43.653493,
+    "lon": -79.384095
+  },
+  "webSite": "https://www.dylanberry.com/",
+  "feedUris": [
+    "https://www.dylanberry.com/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/egbakou.json b/Authors/egbakou.json
new file mode 100644
index 0000000..886bb70
--- /dev/null
+++ b/Authors/egbakou.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Kodjo Laurent",
+  "lastName": "Egbakou",
+  "stateOrRegion": "Lome, Togo",
+  "emailAddress": "laurent@lioncoding.com",
+  "tagOrBio": "is C#/.Net/Xamarin developer who learns and shares.",
+  "webSite": "https://lioncoding.com/",
+  "twitterHandle": "lioncoding",
+  "githubHandle": "egbakou",
+  "gravatarHash": "6e26a030d3b9495872b58d922bd86157",
+  "feedUris": [
+    "https://lioncoding.com/feed.xml"
+  ],
+  "position": {
+    "lat": 6.2030129,
+    "lon": 1.1918434
+  },
+  "languageCode": "fr"
+}
\ No newline at end of file
diff --git a/Authors/elbrinner.json b/Authors/elbrinner.json
new file mode 100644
index 0000000..615211b
--- /dev/null
+++ b/Authors/elbrinner.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Elbrinner",
+  "lastName": "da Silva Fernandes",
+  "stateOrRegion": "Madrid , Spain",
+  "emailAddress": "elbrinner@elbrinner.com",
+  "tagOrBio": "is a Xamarin consultant in everis Spain and organizer of the meetup group Xamarin Madrid.",
+  "webSite": "https://www.elbrinner.com/",
+  "twitterHandle": "elbrinner",
+  "githubHandle": "elbrinner",
+  "gravatarHash": "15e64690c0e4d5b2c692e9fc7de5e768",
+  "feedUris": [
+    "https://www.elbrinner.com/rss"
+  ],
+  "position": {
+    "lat": 40.416775,
+    "lon": -3.70379
+  },
+  "languageCode": "es"
+}
\ No newline at end of file
diff --git a/Authors/felipebaltazar.json b/Authors/felipebaltazar.json
new file mode 100644
index 0000000..7ca680e
--- /dev/null
+++ b/Authors/felipebaltazar.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Felipe",
+  "lastName": "Baltazar",
+  "tagOrBio": "Xamarin 🐒, ApnetCore 🌐, Windows 💻, Nerd 🤓, Gamer 🎮 and Father 👨‍👩‍👦",
+  "stateOrRegion": "Rio Grande do sul, Brasil",
+  "emailAddress": "felipe.dasilvabaltazar@gmail.com",
+  "twitterHandle": "FelippeBaltazar",
+  "githubHandle": "felipebaltazar",
+  "gravatarHash": "c4deac62305f590fbda80209628afd0e",
+  "position": {
+    "lat": -29.940163,
+    "lon": -51.088751
+  },
+  "webSite": "https://medium.com/@felipedasilvabaltazar",
+  "feedUris": [
+    "https://medium.com/feed/@felipedasilvabaltazar"
+  ],
+  "languageCode": "pt"
+}
\ No newline at end of file
diff --git a/Authors/filipoff2.json b/Authors/filipoff2.json
new file mode 100644
index 0000000..e3c9525
--- /dev/null
+++ b/Authors/filipoff2.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Boguslaw",
+  "lastName": "Blonski",
+  "tagOrBio": "Generalist who is pragmatic and has delivered real code to real users in a variety of shapes.",
+  "stateOrRegion": "Lezajsk, Poland",
+  "emailAddress": "boguslawblonski@gmail.com",
+  "twitterHandle": "filipoff",
+  "gravatarHash": "d48c54ac95492ddadfc221b646d4c612",
+  "webSite": "https://medium.com/@boguslawblonski",
+  "feedUris": [
+    "https://medium.com/feed/@boguslawblonski/"
+  ],
+  "githubHandle": "filipoff2",
+  "position": {
+    "lat": 50.2684647,
+    "lon": 22.3819053
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/framinosona.json b/Authors/framinosona.json
new file mode 100644
index 0000000..4580e19
--- /dev/null
+++ b/Authors/framinosona.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Francois",
+  "lastName": "Raminosona",
+  "stateOrRegion": "Norway",
+  "emailAddress": "framinosona@hotmail.fr",
+  "tagOrBio": "Passionate Xamarin/Microsoft technologies developer",
+  "webSite": "https://blog.francois.raminosona.com/",
+  "feedUris": [
+    "https://blog.francois.raminosona.com/tag/xamarin/rss/"
+  ],
+  "twitterHandle": "framinosona",
+  "gravatarHash": "b3b91b8d4bd1e716982eef6e5228c92f",
+  "githubHandle": "framinosona",
+  "position": {
+    "lat": 58.9720089,
+    "lon": 5.7363974
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/gonemobilecast.json b/Authors/gonemobilecast.json
new file mode 100644
index 0000000..290ca54
--- /dev/null
+++ b/Authors/gonemobilecast.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Gone",
+  "lastName": "Mobile",
+  "stateOrRegion": "Internet",
+  "emailAddress": "hello@gonemobile.io",
+  "tagOrBio": "is a development podcast focused on mobile development hosted by Jon Dick and Greg Shackles.",
+  "webSite": "http://gonemobile.io",
+  "feedUris": [
+    "https://feed.gonemobile.io/"
+  ],
+  "twitterHandle": "gonemobilecast",
+  "position": {
+    "lat": 51.253775,
+    "lon": -85.323214
+  },
+  "gravatarHash": "cb611c5ecd9a53b2af53a9d50d83c3c5",
+  "githubHandle": "",
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/gptucci.json b/Authors/gptucci.json
new file mode 100644
index 0000000..f9af534
--- /dev/null
+++ b/Authors/gptucci.json
@@ -0,0 +1,19 @@
+{
+  "webSite": "https://www.informaticapressapochista.com/it",
+  "firstName": "Giampaolo",
+  "lastName": "Tucci",
+  "stateOrRegion": "Italia",
+  "emailAddress": "g.tucci@informaticapressapochista.com",
+  "tagOrBio": "L'IT come non l'avete mai letta",
+  "gravatarHash": "a8846caf48c8ccc9850ff201c1e2ad1d",
+  "feedUris": [
+    "https://www.informaticapressapochista.com/it/?format=feed&type=rss"
+  ],
+  "twitterHandle": "GiampaoloTUCCI",
+  "githubHandle": "gptucci",
+  "position": {
+    "lat": 44.40138,
+    "lon": 8.93419
+  },
+  "languageCode": "it"
+}
\ No newline at end of file
diff --git a/Authors/gshackles.json b/Authors/gshackles.json
new file mode 100644
index 0000000..4a18581
--- /dev/null
+++ b/Authors/gshackles.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Greg",
+  "lastName": "Shackles",
+  "tagOrBio": "knows a thing (or two) about mobile testing",
+  "emailAddress": "greg@gregshackles.com",
+  "twitterHandle": "gshackles",
+  "gravatarHash": "6d7b45031bf22823060849d494343a8c",
+  "stateOrRegion": "New York, NY",
+  "webSite": "https://gregshackles.com",
+  "feedUris": [
+    "https://gregshackles.com/rss/"
+  ],
+  "githubHandle": "gshackles",
+  "position": {
+    "lat": 40.712784,
+    "lon": -74.005941
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/hnabbasi.json b/Authors/hnabbasi.json
new file mode 100644
index 0000000..ebcee56
--- /dev/null
+++ b/Authors/hnabbasi.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Hussain",
+  "lastName": "Abbasi",
+  "stateOrRegion": "Houston, Texas",
+  "emailAddress": "hnabbasi@outlook.com",
+  "tagOrBio": "is a Blogger, Mobile Architect, and founder of intelliAbb.com. More at HussainAbbasi.com",
+  "webSite": "https://www.intelliabb.com/",
+  "twitterHandle": "HussainNAbbasi",
+  "githubHandle": "hnabbasi",
+  "gravatarHash": "6f415af725ae2d6b5b912a7e93b105b9",
+  "feedUris": [
+    "https://www.intelliabb.com/feed"
+  ],
+  "position": {
+    "lat": 29.7656,
+    "lon": -95.3681
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/ionixjunior.json b/Authors/ionixjunior.json
new file mode 100644
index 0000000..8d190e5
--- /dev/null
+++ b/Authors/ionixjunior.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Ione",
+  "lastName": "Souza Junior",
+  "tagOrBio": "",
+  "stateOrRegion": "Blumenau, Brasil",
+  "emailAddress": "junior@ionixjunior.com.br",
+  "twitterHandle": "ionixjunior",
+  "githubHandle": "ionixjunior",
+  "gravatarHash": "790726f5b5613d61926dea2e2efd4da1",
+  "position": {
+    "lat": -26.914236,
+    "lon": -49.068776
+  },
+  "webSite": "https://www.ionixjunior.com.br",
+  "feedUris": [
+    "https://www.ionixjunior.com.br/rss"
+  ],
+  "languageCode": "pt"
+}
\ No newline at end of file
diff --git a/Authors/jamesmontemagno.json b/Authors/jamesmontemagno.json
new file mode 100644
index 0000000..a95e11c
--- /dev/null
+++ b/Authors/jamesmontemagno.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "James",
+  "lastName": "Montemagno",
+  "stateOrRegion": "Seattle, WA",
+  "emailAddress": "",
+  "tagOrBio": "is a Principal Program Manager for Mobile Developer Tools",
+  "webSite": "https://montemagno.com",
+  "feedUris": [
+    "https://montemagno.com/rss"
+  ],
+  "twitterHandle": "JamesMontemagno",
+  "gravatarHash": "5df4d86308e585c879c19e5f909d8bfe",
+  "githubHandle": "jamesmontemagno",
+  "position": {
+    "lat": 47.654177,
+    "lon": -122.35
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/jesulink2514.json b/Authors/jesulink2514.json
new file mode 100644
index 0000000..3bc5320
--- /dev/null
+++ b/Authors/jesulink2514.json
@@ -0,0 +1,20 @@
+{
+  "firstName": "Jesús",
+  "lastName": "Angulo",
+  "stateOrRegion": "Lima",
+  "emailAddress": "jesus.angulo@outlook.com",
+  "tagOrBio": "Microsoft MVP | Certified Xamarin Mobile Developer",
+  "webSite": "https://somostechies.com",
+  "twitterHandle": "jesulink2514",
+  "githubHandle": "jesulink2514",
+  "gravatarHash": "63359672e0ecb75e7ed261a358bf0478",
+  "feedUris": [
+    "https://somostechies.com/rss/",
+    "https://www.youtube.com/feeds/videos.xml?channel_id=UCnqaA_ArZIT0nytKMAiurzw"
+  ],
+  "position": {
+    "lat": -12.0896427,
+    "lon": -77.0060778
+  },
+  "languageCode": "es"
+}
\ No newline at end of file
diff --git a/Authors/jfversluis.json b/Authors/jfversluis.json
new file mode 100644
index 0000000..7544e9f
--- /dev/null
+++ b/Authors/jfversluis.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Gerald",
+  "lastName": "Versluis",
+  "stateOrRegion": "The Netherlands",
+  "emailAddress": "gerald@verslu.is",
+  "tagOrBio": "Software Engineer at Microsoft on the Xamarin.Forms team",
+  "webSite": "https://blog.verslu.is/",
+  "feedUris": [
+    "https://blog.verslu.is/feed/"
+  ],
+  "twitterHandle": "jfversluis",
+  "gravatarHash": "f9d4d4211d7956ce3e07e83df0889731",
+  "githubHandle": "jfversluis",
+  "position": {
+    "lat": 50.889039,
+    "lon": 5.853717
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/jgiacomini.json b/Authors/jgiacomini.json
new file mode 100644
index 0000000..104c5a0
--- /dev/null
+++ b/Authors/jgiacomini.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Jérôme",
+  "lastName": "Giacomini",
+  "stateOrRegion": "Paris, France",
+  "emailAddress": "jerome.giacomini@gmail.com",
+  "tagOrBio": "is a Xamarin Enthusiast, co-author of a book on Xamarin",
+  "webSite": "https://jeromegiacomini.net/Blog/",
+  "twitterHandle": "jeromegiacomini",
+  "githubHandle": "jgiacomini",
+  "gravatarHash": "95e63961669a22586a1236fd6a7a494d",
+  "feedUris": [
+    "https://jeromegiacomini.net/Blog/feed/"
+  ],
+  "position": {
+    "lat": 48.8704842,
+    "lon": 2.3449646
+  },
+  "languageCode": "fr"
+}
\ No newline at end of file
diff --git a/Authors/jimbobbennett.json b/Authors/jimbobbennett.json
new file mode 100644
index 0000000..d97112e
--- /dev/null
+++ b/Authors/jimbobbennett.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Jim",
+  "lastName": "Bennett",
+  "tagOrBio": "is the author of Xamarin in Action and a all-round nice guy",
+  "stateOrRegion": "Auckland, New Zealand",
+  "emailAddress": "jim@jimbobbennett.io",
+  "twitterHandle": "jimbobbennett",
+  "webSite": "https://jimbobbennett.io/",
+  "feedUris": [
+    "https://www.jimbobbennett.io/rss"
+  ],
+  "gravatarHash": "",
+  "githubHandle": "",
+  "position": {
+    "lat": -36.84846,
+    "lon": 174.763332
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/johnthiriet.json b/Authors/johnthiriet.json
new file mode 100644
index 0000000..21ab90a
--- /dev/null
+++ b/Authors/johnthiriet.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "John",
+  "lastName": "Thiriet",
+  "stateOrRegion": "Paris, France",
+  "emailAddress": "johnthiriet@protonmail.com",
+  "tagOrBio": "is a Mobility Technical Manager, Trainer, Microsoft MVP, Xamarin MVP",
+  "webSite": "https://johnthiriet.com/",
+  "feedUris": [
+    "https://johnthiriet.com/feed.xml"
+  ],
+  "twitterHandle": "johnthiriet",
+  "gravatarHash": "ed92222c19a155a929d9f2c12d39c3f4",
+  "githubHandle": "johnthiriet",
+  "position": {
+    "lat": 48.875485,
+    "lon": 2.311039
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/jssuthahar.json b/Authors/jssuthahar.json
new file mode 100644
index 0000000..5195a63
--- /dev/null
+++ b/Authors/jssuthahar.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Suthahar",
+  "lastName": "Jegatheesan",
+  "tagOrBio": "insatiable desire to keep learning keeps the dynamic blogger. I take keen interest in sharing my knowledge and solving my readers’ technology-related problems.",
+  "emailAddress": "",
+  "twitterHandle": "jssuthahar",
+  "gravatarHash": "2a34ebf4e9c4dca84eb7feee7217568f",
+  "stateOrRegion": "Bangalore, India",
+  "webSite": "https://www.msdevbuild.com/",
+  "position": {
+    "lat": 12.971599,
+    "lon": 77.594563
+  },
+  "feedUris": [
+    "https://www.msdevbuild.com/feeds/posts/default"
+  ],
+  "githubHandle": "jssuthahar",
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/jsuarezruiz.json b/Authors/jsuarezruiz.json
new file mode 100644
index 0000000..3361ef1
--- /dev/null
+++ b/Authors/jsuarezruiz.json
@@ -0,0 +1,19 @@
+{
+  "feedUris": [
+    "https://javiersuarezruiz.wordpress.com/feed/"
+  ],
+  "firstName": "Javier",
+  "lastName": "Suarez",
+  "stateOrRegion": "Seville, Spain",
+  "emailAddress": "javiersuarezruiz@hotmail.com",
+  "tagOrBio": "is a passionate software developer from Spain who enjoys learning, talk and help others",
+  "webSite": "https://javiersuarezruiz.wordpress.com",
+  "twitterHandle": "jsuarezruiz",
+  "gravatarHash": "",
+  "position": {
+    "lat": 37.389092,
+    "lon": -5.984459
+  },
+  "githubHandle": "jsuarezruiz",
+  "languageCode": "es"
+}
\ No newline at end of file
diff --git a/Authors/jtaubensee.json b/Authors/jtaubensee.json
new file mode 100644
index 0000000..22f5cbb
--- /dev/null
+++ b/Authors/jtaubensee.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "John",
+  "lastName": "Taubensee",
+  "stateOrRegion": "Chicago, IL",
+  "emailAddress": "",
+  "tagOrBio": "is a developer focused on Microsoft technologies. Microsoft Azure alumni",
+  "webSite": "https://taubensee.net",
+  "feedUris": [
+    "https://taubensee.net/rss"
+  ],
+  "twitterHandle": "jtaubensee",
+  "gravatarHash": "151bc535ca1581cb451eb4df1672b018",
+  "githubHandle": "jtaubensee",
+  "position": {
+    "lat": 41.8778143,
+    "lon": -87.6349955
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/kent_boogaart.json b/Authors/kent_boogaart.json
new file mode 100644
index 0000000..42a1b1f
--- /dev/null
+++ b/Authors/kent_boogaart.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Kent",
+  "lastName": "Boogaart",
+  "stateOrRegion": "Australia",
+  "emailAddress": "kent.boogaart@gmail.com",
+  "tagOrBio": "is a freelance software engineer working mainly in the mobile space",
+  "webSite": "https://kent-boogaart.com/",
+  "feedUris": [
+    "https://kent-boogaart.com/atom.xml"
+  ],
+  "twitterHandle": "kent_boogaart",
+  "gravatarHash": "",
+  "githubHandle": "",
+  "position": {
+    "lat": -35.0004451,
+    "lon": 138.3309978
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/kphillpotts.json b/Authors/kphillpotts.json
new file mode 100644
index 0000000..c501dad
--- /dev/null
+++ b/Authors/kphillpotts.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Kym",
+  "lastName": "Phillpotts",
+  "tagOrBio": "is one of the Xamarin University instructors",
+  "stateOrRegion": "Melbourne, Australia",
+  "emailAddress": "kphillpotts@gmail.com",
+  "twitterHandle": "kphillpotts",
+  "gravatarHash": "3218e66502c6f0836dfd0f02f210ba0b",
+  "webSite": "https://kymphillpotts.com/",
+  "feedUris": [
+    "https://kymphillpotts.com/feed"
+  ],
+  "githubHandle": "kphillpotts",
+  "position": {
+    "lat": -37.813628,
+    "lon": 144.963058
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/kwlothrop.json b/Authors/kwlothrop.json
new file mode 100644
index 0000000..8f89f76
--- /dev/null
+++ b/Authors/kwlothrop.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Kerry W.",
+  "lastName": "Lothrop",
+  "tagOrBio": "",
+  "stateOrRegion": "Frankfurt, Germany",
+  "emailAddress": "",
+  "twitterHandle": "kwlothrop",
+  "webSite": "https://kerry.lothrop.de/",
+  "feedUris": [
+    "https://kerry.lothrop.de/en/feed/"
+  ],
+  "gravatarHash": "250241b2800a1de895a75ce039bcfef4",
+  "githubHandle": "",
+  "position": {
+    "lat": 50.1307615,
+    "lon": 8.568736
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/logeshpalani98.json b/Authors/logeshpalani98.json
new file mode 100644
index 0000000..4263567
--- /dev/null
+++ b/Authors/logeshpalani98.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Logesh",
+  "lastName": "Palani",
+  "stateOrRegion": "Thiruvannamalai,Tamil Nadu,  India",
+  "emailAddress": "logesh.01@hotmail.com",
+  "tagOrBio": "Keep Learning,.. and Keep Practicing,...",
+  "webSite": "https://logeshpalani.blogspot.com/",
+  "twitterHandle": "logeshpalani98",
+  "githubHandle": "logeshpalani98",
+  "gravatarHash": "14fd9ec21509b468c84abbed2e47384e",
+  "feedUris": [
+    "https://logeshpalani.blogspot.com/feeds/posts/default"
+  ],
+  "position": {
+    "lat": 12.527056,
+    "lon": 79.098382
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/luismts.json b/Authors/luismts.json
new file mode 100644
index 0000000..8e24113
--- /dev/null
+++ b/Authors/luismts.json
@@ -0,0 +1,20 @@
+{
+  "firstName": "Luis",
+  "lastName": "Matos",
+  "stateOrRegion": "Dominican Republic",
+  "twitterHandle": "luismatosluna",
+  "emailAddress": "hello@luismts.com",
+  "tagOrBio": "Software Engineer, Entrepreneur",
+  "gravatarHash": "ac9ac28f6b1e05a310d622b37e8bc4be",
+  "webSite": "https://www.luismts.com/",
+  "feedUris": [
+    "https://www.luismts.com/feed/",
+    "https://www.luismts.com/es/feed/"
+  ],
+  "githubHandle": "luismts",
+  "position": {
+    "lat": 18.4900563,
+    "lon": -69.8962411
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/mabroukmahdhi.json b/Authors/mabroukmahdhi.json
new file mode 100644
index 0000000..78d0165
--- /dev/null
+++ b/Authors/mabroukmahdhi.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Mabrouk",
+  "lastName": "Mahdhi",
+  "stateOrRegion": "Darmstadt, Germany",
+  "emailAddress": "contact@mahdhi.com",
+  "tagOrBio": "is a Senior Technical Consultant who blogs, talks and develops all around mobile and web development.",
+  "webSite": "https://mahdhi.com",
+  "twitterHandle": "mabrouk_mahdhi",
+  "githubHandle": "mabroukmahdhi",
+  "gravatarHash": "1f5b179abb9b9f8a34a4a9799e205c96",
+  "feedUris": [
+    "https://medium.com/feed/@mabroukmahdhi"
+  ],
+  "position": {  
+    "lat": 49.873207,
+    "lon": 8.650779
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/mallibone.json b/Authors/mallibone.json
new file mode 100644
index 0000000..49de03a
--- /dev/null
+++ b/Authors/mallibone.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Mark",
+  "lastName": "Allibone",
+  "stateOrRegion": "Zurich, Switzerland",
+  "emailAddress": "",
+  "tagOrBio": "is a Microsoft MVP who blogs, talks, coaches and develops all around mobile development.",
+  "webSite": "https://mallibone.com",
+  "twitterHandle": "mallibone",
+  "githubHandle": "mallibone",
+  "gravatarHash": "4fa14971da4fafb96830960bc7c6733d",
+  "feedUris": [
+    "https://mallibone.com/feed/"
+  ],
+  "position": {
+    "lat": 47.5056381,
+    "lon": 8.7241297
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/marcofolio.json b/Authors/marcofolio.json
new file mode 100644
index 0000000..b109554
--- /dev/null
+++ b/Authors/marcofolio.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Marco",
+  "lastName": "Kuiper",
+  "tagOrBio": "is a Code monkey, incurably optimistic, loves great design and passionate about Xamarin.",
+  "stateOrRegion": "The Netherlands",
+  "emailAddress": "",
+  "twitterHandle": "marcofolio",
+  "gravatarHash": "5982941cf85cecc8254ec2a4f1c812ff",
+  "githubHandle": "marcofolio",
+  "position": {
+    "lat": 51.987642,
+    "lon": 5.904598
+  },
+  "webSite": "https://www.marcofolio.net/",
+  "feedUris": [
+    "https://feeds2.feedburner.com/marcofolio"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/marcusts.json b/Authors/marcusts.json
new file mode 100644
index 0000000..5380b47
--- /dev/null
+++ b/Authors/marcusts.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Stephen",
+  "lastName": "Marcus",
+  "stateOrRegion": "Orange County, California",
+  "emailAddress": "marcus@marcusts.com",
+  "tagOrBio": "Certified Xamarin mobile app developer",
+  "webSite": "https://www.marcusts.com",
+  "feedUris": [
+    "https://www.marcusts.com/category/Xamarin/feed/"
+  ],
+  "twitterHandle": "",
+  "gravatarHash": "a64074b2ab0ac9b5a27379670b259d6d",
+  "githubHandle": "marcusts",
+  "position": {
+    "lat": 33.6423,
+    "lon": -117.6977
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/markolazic88.json b/Authors/markolazic88.json
new file mode 100644
index 0000000..baa1fe1
--- /dev/null
+++ b/Authors/markolazic88.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Marko",
+  "lastName": "Lazić",
+  "tagOrBio": "Software engineer, tech enthusiast, passionate traveler. 4+ years of active development in Xamarin.Forms",
+  "stateOrRegion": "Belgrade, Serbia",
+  "emailAddress": "marko.lazic88@gmail.com",
+  "twitterHandle": "markolazic88",
+  "gravatarHash": "5645586a7d29654e9b296b1409107014",
+  "webSite": "https://markolazic.com/",
+  "feedUris": [
+    "https://markolazic.com/feed/"
+  ],
+  "githubHandle": "markolazic88",
+  "position": {
+    "lat": 44.7866,
+    "lon": 20.4489
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/martijn00.json b/Authors/martijn00.json
new file mode 100644
index 0000000..576f3c1
--- /dev/null
+++ b/Authors/martijn00.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Martijn",
+  "lastName": "van Dijk",
+  "stateOrRegion": "Amsterdam, Netherlands",
+  "emailAddress": "mhvdijk@gmail.com",
+  "tagOrBio": "is working at Baseflow.com on Apps and MvvmCross",
+  "webSite": "https://medium.com/@martijn00",
+  "feedUris": [
+    "https://medium.com/feed/@martijn00"
+  ],
+  "twitterHandle": "mhvdijk",
+  "gravatarHash": "22155f520ab611cf04f76762556ca3f5",
+  "githubHandle": "martijn00",
+  "position": {
+    "lat": 52.370216,
+    "lon": 4.895168
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/mattleibow.json b/Authors/mattleibow.json
new file mode 100644
index 0000000..2ee085e
--- /dev/null
+++ b/Authors/mattleibow.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Matthew",
+  "lastName": "Leibowitz",
+  "tagOrBio": "An all-round software guy. I live and breathe C# and .NET on any platform.",
+  "emailAddress": "mattleibow@live.com",
+  "twitterHandle": "mattleibow",
+  "githubHandle": "mattleibow",
+  "gravatarHash": "365da45bdc71334831f228aff805738f",
+  "stateOrRegion": "Cape Town, South Africa",
+  "position": {
+    "lat": -34.02231,
+    "lon": 18.46716
+  },
+  "webSite": "https://dotnetdevaddict.co.za",
+  "feedUris": [
+    "https://dotnetdevaddict.co.za/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/mfractor.json b/Authors/mfractor.json
new file mode 100644
index 0000000..7dd9d23
--- /dev/null
+++ b/Authors/mfractor.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "MFractor",
+  "lastName": "",
+  "stateOrRegion": "Brisbane, Australia",
+  "emailAddress": "matthew@mfractor.com",
+  "tagOrBio": "is a powerful productivity tool for Xamarin Developers.",
+  "webSite": "https://www.mfractor.com/",
+  "twitterHandle": "mfractor",
+  "githubHandle": "mfractor",
+  "gravatarHash": "35bac056166a67222ddcd48b57113a32",
+  "feedUris": [
+    "https://www.mfractor.com/blogs/news.atom"
+  ],
+  "position": {
+    "lat": -27.470125,
+    "lon": 153.021072
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/mike-grant.json b/Authors/mike-grant.json
new file mode 100644
index 0000000..667d7c9
--- /dev/null
+++ b/Authors/mike-grant.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Mike",
+  "lastName": "Grant",
+  "stateOrRegion": "Leicestershire, England",
+  "emailAddress": "",
+  "tagOrBio": "Software Engineer",
+  "webSite": "https://www.mikegrant.org.uk",
+  "gravatarHash": "06c34ad3fb10ef6786a043c4522b6a5b",
+  "feedUris": [
+    "https://mikegrant.org.uk/feeds/Xamarin.Forms.xml"
+  ],
+  "twitterHandle": "mike_grant_",
+  "githubHandle": "mike-grant",
+  "position": {
+    "lat": 52.663878,
+    "lon": -1.3052377
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/mindofai.json b/Authors/mindofai.json
new file mode 100644
index 0000000..846d691
--- /dev/null
+++ b/Authors/mindofai.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Bryan Anthony",
+  "lastName": "Garcia",
+  "stateOrRegion": "Manila, Philippines",
+  "githubHandle": "mindofai",
+  "twitterHandle": "mindofai",
+  "emailAddress": "bryananthonygarcia@live.com",
+  "tagOrBio": "Mobile .NET Developer who enjoys learning and writing about Mobile .NET stuff and has passion for football. Co-leads Mobile .NET Developers - Philippines",
+  "gravatarHash": "29e1cdab06c48322805220e33556c20c",
+  "webSite": "https://mindofai.github.io/",
+  "position": {
+    "lat": 14.668896,
+    "lon": 120.947204
+  },
+  "feedUris": [
+    "https://mindofai.github.io/feed.xml"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/mkieres.json b/Authors/mkieres.json
new file mode 100644
index 0000000..f64ed2a
--- /dev/null
+++ b/Authors/mkieres.json
@@ -0,0 +1,19 @@
+{
+  "emailAddress": "mikolaj.kieres@progrunning.net",
+  "languageCode": "en",
+  "feedUris": [
+    "https://progrunning.net/rss/"
+  ],
+  "firstName": "Mikolaj",
+  "githubHandle": "mkieres",
+  "gravatarHash": "",
+  "lastName": "Kieres",
+  "position": {
+    "lat": -33.826623,
+    "lon": 151.195031
+  },
+  "tagOrBio": "Mobile development adventurer",
+  "stateOrRegion": "Sydney, Australia",
+  "twitterHandle": "mikolajkieres",
+  "webSite": "https://progrunning.net"
+}
\ No newline at end of file
diff --git a/Authors/msiccdev.json b/Authors/msiccdev.json
new file mode 100644
index 0000000..f003737
--- /dev/null
+++ b/Authors/msiccdev.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Marco",
+  "lastName": "Siccardi",
+  "tagOrBio": "cross platform developer, writing software for Desktop, Mobiles and IOT",
+  "stateOrRegion": "Switzerland",
+  "emailAddress": "msiccdev@hotmail.com",
+  "twitterHandle": "msicc",
+  "gravatarHash": "67aaa7c3b6357dbccc1167a70b0c73e3",
+  "githubHandle": "msiccdev",
+  "position": {
+    "lat": 47.4683,
+    "lon": 8.75727
+  },
+  "webSite": "https://msicc.net/category/devstories/xamarin/",
+  "feedUris": [
+    "https://msicc.net/category/devstories/xamarin/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/nickrandolph.json b/Authors/nickrandolph.json
new file mode 100644
index 0000000..d3febff
--- /dev/null
+++ b/Authors/nickrandolph.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Nick",
+  "lastName": "Randolph",
+  "stateOrRegion": "Sydney, Australia",
+  "emailAddress": "nick@builttoroam.com",
+  "tagOrBio": "Microsoft MVP and maintainer of @MvvmCross. Co-founder, Tech Lead at Built to Roam (@btroam), special forces in cross platform app and cloud solutions.",
+  "webSite": "https://builttoroam.com",
+  "feedUris": [
+    "https://nicksnettravels.builttoroam.com/syndication.axd"
+  ],
+  "twitterHandle": "thenickrandolph",
+  "gravatarHash": "",
+  "githubHandle": "nickrandolph",
+  "position": {
+    "lat": -33.839559,
+    "lon": 151.2112434
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/nigelferrissey.json b/Authors/nigelferrissey.json
new file mode 100644
index 0000000..e893dd6
--- /dev/null
+++ b/Authors/nigelferrissey.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Nigel",
+  "lastName": "Ferrissey",
+  "tagOrBio": "Mobile and front-end developer, Xamarin specialist",
+  "emailAddress": "n_ferrissey@hotmail.com",
+  "twitterHandle": "nferrissey",
+  "gravatarHash": "106ec2de3e2ea4e88e9fc431974f5d53",
+  "stateOrRegion": "Brisbane, Australia",
+  "webSite": "https://xamarininsider.com",
+  "feedUris": [
+    "https://xamarininsider.com/rss/"
+  ],
+  "githubHandle": "nigelferrissey",
+  "position": {
+    "lat": -27.469657,
+    "lon": 153.025241
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/officialdoniald.json b/Authors/officialdoniald.json
new file mode 100644
index 0000000..0b845e1
--- /dev/null
+++ b/Authors/officialdoniald.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Bence",
+  "lastName": "Lenart",
+  "tagOrBio": "Xamarin developer and blogger.",
+  "stateOrRegion": "Szeged, Hungary",
+  "emailAddress": "bence960206@gmail.com",
+  "webSite": "ttps://officialdoniald.com",
+  "feedUris": [
+    "https://officialdoniald.com/feed"
+  ],
+  "twitterHandle": "officialdoniald",
+  "gravatarHash": "4e467fcdbb65da5080d215bf303c442a",
+  "githubHandle": "officialdoniald",
+  "position": {
+    "lat": 46.231222,
+    "lon": 20.119167
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/peterfoot.json b/Authors/peterfoot.json
new file mode 100644
index 0000000..d9d9ca7
--- /dev/null
+++ b/Authors/peterfoot.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Peter",
+  "lastName": "Foot",
+  "stateOrRegion": "United Kingdom",
+  "emailAddress": "peter@peterfoot.net",
+  "twitterHandle": "peterfoot",
+  "webSite": "https://inthehand.com/blog/",
+  "feedUris": [
+    "https://inthehand.com/category/xamarin/feed/"
+  ],
+  "gravatarHash": "fa15aeeccc4b23e8a4677aeacb65b7bb",
+  "tagOrBio": "develops Xamarin and Windows applications at In The Hand Ltd",
+  "githubHandle": "peterfoot",
+  "position": {
+    "lat": 52.76872,
+    "lon": -2.37825
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/ramonesteban78.json b/Authors/ramonesteban78.json
new file mode 100644
index 0000000..25bc0d4
--- /dev/null
+++ b/Authors/ramonesteban78.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Ramon",
+  "lastName": "Esteban",
+  "tagOrBio": "Freelance Xamarin developer",
+  "stateOrRegion": "Malaga, Spain",
+  "emailAddress": "wantedforcode@outlook.com",
+  "twitterHandle": "ramonesteban78",
+  "gravatarHash": "2fc49c3e9095aece416ad4e147fa1452",
+  "githubHandle": "ramonesteban78",
+  "position": {
+    "lat": 36.5126395,
+    "lon": -4.6483388
+  },
+  "webSite": "https://ramonesteban78.github.io/",
+  "feedUris": [
+    "https://ramonesteban78.github.io/feed.xml"
+  ],
+  "languageCode": "es"
+}
\ No newline at end of file
diff --git a/Authors/rdavisau.json b/Authors/rdavisau.json
new file mode 100644
index 0000000..51ef775
--- /dev/null
+++ b/Authors/rdavisau.json
@@ -0,0 +1,19 @@
+{
+  "feedUris": [
+    "https://ryandavis.io/rss/"
+  ],
+  "firstName": "Ryan",
+  "lastName": "Davis",
+  "stateOrRegion": "Brisbane, Australia",
+  "emailAddress": "ryandavis.au@gmail.com",
+  "tagOrBio": "knows how to 🎉",
+  "webSite": "https://ryandavis.io",
+  "twitterHandle": "rdavis_au",
+  "githubHandle": "rdavisau",
+  "gravatarHash": "d351762ec451e252b20ff860dfcded91d351762ec451e252b20ff860dfcded91",
+  "position": {
+    "lat": -27.469771,
+    "lon": 153.025124
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/rdelrosario.json b/Authors/rdelrosario.json
new file mode 100644
index 0000000..4b067dd
--- /dev/null
+++ b/Authors/rdelrosario.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Rendy",
+  "lastName": "Del Rosario",
+  "tagOrBio": "is a senior software developer with a passion for mobile development using Xamarin platform",
+  "stateOrRegion": "Dominican Republic",
+  "emailAddress": "rendy@crossgeeks.com",
+  "twitterHandle": "rdelrosario",
+  "gravatarHash": "4bece0ce1c33e65177110bcb95688c68",
+  "githubHandle": "rdelrosario",
+  "position": {
+    "lat": 18.486058,
+    "lon": -69.931212
+  },
+  "webSite": "https://xamboy.com/",
+  "feedUris": [
+    "https://xamboy.com/rss"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/redth.json b/Authors/redth.json
new file mode 100644
index 0000000..61f6a67
--- /dev/null
+++ b/Authors/redth.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Jon",
+  "lastName": "Dick",
+  "tagOrBio": "",
+  "emailAddress": "jondick@gmail.com",
+  "twitterHandle": "redth",
+  "gravatarHash": "ad73e52d7e4d89e904e7c4cfd91fc2b9",
+  "stateOrRegion": "Ontario, Canada",
+  "webSite": "https://redth.codes",
+  "feedUris": [
+    "https://redth.codes/feed/"
+  ],
+  "githubHandle": "redth",
+  "position": {
+    "lat": 51.253775,
+    "lon": -85.323214
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/ricardoprestes.json b/Authors/ricardoprestes.json
new file mode 100644
index 0000000..902978e
--- /dev/null
+++ b/Authors/ricardoprestes.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Ricardo",
+  "lastName": "Prestes",
+  "stateOrRegion": "Cornélio Procópio, Brasil",
+  "emailAddress": "ricardo.logan@hotmail.com",
+  "tagOrBio": "Tech lead mobile developer, Burger Monkeys Co-founder",
+  "webSite": "https://oficinadologan.wordpress.com/",
+  "twitterHandle": "ricardo_prestes",
+  "githubHandle": "ricardoprestes",
+  "gravatarHash": "9802e38d5bd2cd85db8b0720d5feed29",
+  "feedUris": [
+    "https://oficinadologan.wordpress.com/rss"
+  ],
+  "position": {
+    "lat": -23.194571,
+    "lon": -50.7795215
+  },
+  "languageCode": "pt"
+}
\ No newline at end of file
diff --git a/Authors/rid00z.json b/Authors/rid00z.json
new file mode 100644
index 0000000..eab1205
--- /dev/null
+++ b/Authors/rid00z.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Michael",
+  "lastName": "Ridland",
+  "stateOrRegion": "Sydney, Australia",
+  "emailAddress": "michael@xam-consulting.com",
+  "tagOrBio": "Xamarin Contractor/Consultant | Founder XAM Consulting (xam-consulting.com) | Creator of FreshMvvm",
+  "webSite": "https://michaelridland.com",
+  "feedUris": [
+    "https://michaelridland.com/feed/"
+  ],
+  "twitterHandle": "rid00z",
+  "gravatarHash": "3c07e56045d18f4f290eb4983031309d",
+  "githubHandle": "rid00z",
+  "position": {
+    "lat": -25.348875,
+    "lon": 131.035
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/robintschroeder.json b/Authors/robintschroeder.json
new file mode 100644
index 0000000..abbcb44
--- /dev/null
+++ b/Authors/robintschroeder.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Robin",
+  "lastName": "Schroeder",
+  "tagOrBio": "Xamarin.Forms/UWP Software Consultant at MSCTek",
+  "stateOrRegion": "Illinois",
+  "emailAddress": "robin@msctek.com",
+  "twitterHandle": "RTSchroeder",
+  "gravatarHash": "1754cd9eee726fd3a5252a4718cbf108",
+  "githubHandle": "robintschroeder",
+  "position": {
+    "lat": 41.9136926,
+    "lon": -88.3148351
+  },
+  "webSite": "https://msctek.com/",
+  "feedUris": [
+    "https://www.msctek.com/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/roubachof.json b/Authors/roubachof.json
new file mode 100644
index 0000000..cdddf25
--- /dev/null
+++ b/Authors/roubachof.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Jean-Marie",
+  "lastName": "Alfonsi",
+  "tagOrBio": "is a singing software engineer who travels at the speed light and wanna make a supersonic man out of you.",
+  "stateOrRegion": "Paris, France",
+  "emailAddress": "jm.alfonsi@gmail.com",
+  "twitterHandle": "Piskariov",
+  "gravatarHash": "2a30d8bc59e2ccb6e83bb498d519394a",
+  "webSite": "https://www.sharpnado.com/",
+  "feedUris": [
+    "https://www.sharpnado.com/rss/"
+  ],
+  "githubHandle": "roubachof",
+  "position": {
+    "lat": 48.8588377,
+    "lon": 2.2770206
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/saamerm.json b/Authors/saamerm.json
new file mode 100644
index 0000000..592393a
--- /dev/null
+++ b/Authors/saamerm.json
@@ -0,0 +1,19 @@
+{
+  "feedUris": [
+    "https://medium.com/feed/@prototypemakers"
+  ],
+  "firstName": "Saamer",
+  "lastName": "Mansoor",
+  "stateOrRegion": "Toronto, Canada",
+  "emailAddress": "i@saamer.me",
+  "tagOrBio": "Top 5% Xamarin StackOverflow, Freelancer, Trainer",
+  "webSite": "https://medium.com/@prototypemakers",
+  "twitterHandle": "saamerm",
+  "githubHandle": "saamerm",
+  "gravatarHash": "66887acb0b76f2d3059255a1c53a3b22",
+  "position": {
+    "lat": 43.639728,
+    "lon": -79.380099
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/sact1909.json b/Authors/sact1909.json
new file mode 100644
index 0000000..0e3de8b
--- /dev/null
+++ b/Authors/sact1909.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Steven",
+  "lastName": "Checo",
+  "stateOrRegion": "United States",
+  "emailAddress": "steven.checo.19@gmail.com",
+  "tagOrBio": "is a C# ASP.Net and Xamarin Developer, I'd preferd back-end but I get along with the Front-End, I love help others with code and build new things with friends, I ♥ C#",
+  "webSite": "https://checox.com",
+  "twitterHandle": "steven1909",
+  "githubHandle": "sact1909",
+  "gravatarHash": "47ad7178de588bb9a0b5922a5c1364c8",
+  "feedUris": [
+    "https://checox.com/feed/"
+  ],
+  "position": {
+    "lat": 40.837222,
+    "lon": -73.886111
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/samirgcofficial.json b/Authors/samirgcofficial.json
new file mode 100644
index 0000000..c55fd76
--- /dev/null
+++ b/Authors/samirgcofficial.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Samir",
+  "lastName": "GC",
+  "tagOrBio": ".net lover, xamarin mobile developer | XamarinGuy Show Host | Trainer | Instructor",
+  "stateOrRegion": "Kathmandu/Nepal",
+  "emailAddress": "samirgcofficial@gmail.com",
+  "twitterHandle": "xamaringuy",
+  "githubHandle": "samirgcofficial",
+  "position": {
+    "lat": 27.700769,
+    "lon": 85.30014
+  },
+  "webSite": "https://xamaringuyshow.com/",
+  "feedUris": [
+    "https://xamaringuyshow.com/feed/"
+  ],
+  "gravatarHash": "4b0b695b7711b0184ab2049e33f2cfd7",
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/shirshov.json b/Authors/shirshov.json
new file mode 100644
index 0000000..9de2a03
--- /dev/null
+++ b/Authors/shirshov.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Alex",
+  "lastName": "Shirshov",
+  "stateOrRegion": "Sydney, Australia",
+  "emailAddress": "shirshov@gmail.com",
+  "tagOrBio": "Software Craftsman",
+  "webSite": "https://omnitalented.com",
+  "twitterHandle": "omnitalented",
+  "githubHandle": "shirshov",
+  "gravatarHash": "",
+  "position": {
+    "lat": -33.88236,
+    "lon": 151.206588
+  },
+  "languageCode": "en",
+  "feedUris": [
+    "https://omnitalented.com/rss-xamarin.xml"
+  ]
+}
\ No newline at end of file
diff --git a/Authors/smstuebe.json b/Authors/smstuebe.json
new file mode 100644
index 0000000..86aad08
--- /dev/null
+++ b/Authors/smstuebe.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Sven-Michael",
+  "lastName": "Stübe",
+  "tagOrBio": "loves the cross platform approach, develops Xamarin plugins and organizes Xamarin Pizza & Beer Meetups in Munich",
+  "stateOrRegion": "Munich, Germany",
+  "emailAddress": "",
+  "twitterHandle": "stuebe2k14",
+  "webSite": "https://smstuebe.de/",
+  "feedUris": [
+    "https://smstuebe.de/feed.xml"
+  ],
+  "githubHandle": "smstuebe",
+  "gravatarHash": "08b73d0a58fc120a8cc8dc561d83b3d6",
+  "position": {
+    "lat": 48.1373831,
+    "lon": 11.5063151
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/sthewissen.json b/Authors/sthewissen.json
new file mode 100644
index 0000000..539b113
--- /dev/null
+++ b/Authors/sthewissen.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Steven",
+  "lastName": "Thewissen",
+  "stateOrRegion": "The Netherlands",
+  "emailAddress": "",
+  "tagOrBio": " is a Xamarin Developer with a knack for Photoshop and a passion for soccer and cycling. He is also in love with his Xbox One",
+  "webSite": "https://www.thewissen.io/",
+  "feedUris": [
+    "https://www.thewissen.io/feed/"
+  ],
+  "twitterHandle": "devnl",
+  "gravatarHash": "9f698e6f515cb54dbda305034b6823fc",
+  "position": {
+    "lat": 50.889039,
+    "lon": 5.853717
+  },
+  "githubHandle": "sthewissen",
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/stvansolano.json b/Authors/stvansolano.json
new file mode 100644
index 0000000..28e2fee
--- /dev/null
+++ b/Authors/stvansolano.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Esteban",
+  "lastName": "Solano",
+  "stateOrRegion": "Cartago, Costa Rica",
+  "emailAddress": "stvansolano@outlook.com",
+  "tagOrBio": "is a passionate software community guy from Costa Rica who enjoys learning, talk and help others to learn C# and Xamarin",
+  "webSite": "https://stvansolano.github.io/",
+  "feedUris": [
+    "https://stvansolano.github.io/atom.xml"
+  ],
+  "twitterHandle": "stvansolano",
+  "gravatarHash": "d02d96057c4cd905d60d14549b00db0d",
+  "githubHandle": "stvansolano",
+  "position": {
+    "lat": 9.9322992,
+    "lon": -84.0815271
+  },
+  "languageCode": "es"
+}
\ No newline at end of file
diff --git a/Authors/susairajs.json b/Authors/susairajs.json
new file mode 100644
index 0000000..5a9d688
--- /dev/null
+++ b/Authors/susairajs.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Delpin",
+  "lastName": "Susai Raj",
+  "stateOrRegion": "Chennai, India",
+  "emailAddress": "susairajs@outlook.com",
+  "tagOrBio": "Code with Monkeys",
+  "webSite": "https://xamarinmonkeys.blogspot.com/",
+  "twitterHandle": "susairajs18",
+  "githubHandle": "susairajs",
+  "gravatarHash": "3408967b9598e7bb107baf15d5a15454",
+  "feedUris": [
+    "https://xamarinmonkeys.blogspot.com/feeds/posts/default"
+  ],
+  "position": {
+    "lat": 13.0783995,
+    "lon": 80.2886684
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/syncfusion.json b/Authors/syncfusion.json
new file mode 100644
index 0000000..f5deb50
--- /dev/null
+++ b/Authors/syncfusion.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Syncfusion",
+  "lastName": "",
+  "stateOrRegion": "North Carolina, USA",
+  "emailAddress": "info@syncfusion.com",
+  "tagOrBio": "Syncfusion provides the best third-party UI components for Xamarin, Xamarin.Android and Xamarin.iOS",
+  "webSite": "https://www.syncfusion.com/xamarin-ui-controls",
+  "feedUris": [
+    "https://www.syncfusion.com/blogs/feed"
+  ],
+  "twitterHandle": "Syncfusion",
+  "gravatarHash": "4291ef07481d300471113dbd4b4aabc2",
+  "githubHandle": "syncfusion",
+  "position": {
+    "lat": 35.855361,
+    "lon": -78.815751
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/tbertuzzi.json b/Authors/tbertuzzi.json
new file mode 100644
index 0000000..cc1c04b
--- /dev/null
+++ b/Authors/tbertuzzi.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Thiago",
+  "lastName": "Bertuzzi",
+  "tagOrBio": "Web and Mobile Developer, Blogger, Speaker",
+  "stateOrRegion": "São Paulo, Brasil",
+  "emailAddress": "thiago.bertuzzi@gmail.com",
+  "twitterHandle": "tbertuzzi",
+  "githubHandle": "tbertuzzi",
+  "gravatarHash": "82d95125be475913cdc7a7fe319d0133",
+  "position": {
+    "lat": -23.5834337,
+    "lon": -46.6672048
+  },
+  "webSite": "https://medium.com/@bertuzzi/",
+  "feedUris": [
+    "https://medium.com/feed/@bertuzzi"
+  ],
+  "languageCode": "pt"
+}
\ No newline at end of file
diff --git a/Authors/telerik.json b/Authors/telerik.json
new file mode 100644
index 0000000..a4ca310
--- /dev/null
+++ b/Authors/telerik.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Telerik",
+  "lastName": "",
+  "stateOrRegion": "Global",
+  "emailAddress": "telerikxamarinteam@progress.com",
+  "tagOrBio": "Progress Telerik UI libraries equip .NET ninjas with a full arsenal of weapons to help you create beautiful, modern and future-proof applications quickly and intuitively.",
+  "webSite": "https://www.telerik.com/",
+  "twitterHandle": "telerik",
+  "githubHandle": "telerik",
+  "gravatarHash": "",
+  "feedUris": [
+    "https://feeds.telerik.com/blogs"
+  ],
+  "position": {
+    "lat": 42.512778,
+    "lon": -71.2515
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/trailheadtechnology.json b/Authors/trailheadtechnology.json
new file mode 100644
index 0000000..c613eed
--- /dev/null
+++ b/Authors/trailheadtechnology.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Trailhead Technology",
+  "lastName": "",
+  "stateOrRegion": "Jenison, MI",
+  "twitterHandle": "@TrailheadTec",
+  "emailAddress": "info@trailheadtechnology.com",
+  "tagOrBio": "",
+  "gravatarHash": "0d6c200b64336790495f110332e1d7be",
+  "webSite": "https://www.trailheadtechnology.com/",
+  "feedUris": [
+    "https://trailheadtechnology.com/feed"
+  ],
+  "githubHandle": "trailheadtechnology",
+  "position": {
+    "lat": 42.921436,
+    "lon": -85.806578
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/vulcanlee.json b/Authors/vulcanlee.json
new file mode 100644
index 0000000..0067461
--- /dev/null
+++ b/Authors/vulcanlee.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Vulcan",
+  "lastName": "Lee",
+  "stateOrRegion": "Taipei, Taiwan",
+  "twitterHandle": "vulcanlee",
+  "emailAddress": "vulcan.lee@gmail.com",
+  "tagOrBio": "Vulcan Lee is a Microsoft MVP who develops Xamarin at Doggy Ltd",
+  "gravatarHash": "f5de84ba365a15a05748624c07e70075",
+  "webSite": "https://mylabtw.blogspot.com/",
+  "feedUris": [
+    "https://mylabtw.blogspot.com/feeds/posts/default?alt=rss"
+  ],
+  "githubHandle": "vulcanlee",
+  "position": {
+    "lat": 25.043847,
+    "lon": 121.525645
+  },
+  "languageCode": "zh"
+}
\ No newline at end of file
diff --git a/Authors/willsb.json b/Authors/willsb.json
new file mode 100644
index 0000000..16de042
--- /dev/null
+++ b/Authors/willsb.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "William",
+  "lastName": "Barbosa",
+  "stateOrRegion": "Santos, Brasil",
+  "twitterHandle": "willdotnet",
+  "githubHandle": "willsb",
+  "tagOrBio": "Microsoft MVP, Blogger, Speaker, Monkey Nights Co-founder/Host and MvvmCross contributor",
+  "emailAddress": "heytherewill@gmail.com",
+  "gravatarHash": "e47d219e8ee5d6dd5a44940dc26585c4",
+  "position": {
+    "lat": -23.954821,
+    "lon": -46.3247136
+  },
+  "webSite": "https://willsb.github.io",
+  "feedUris": [
+    "https://medium.com/feed/@heytherewill"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/winstongubantes.json b/Authors/winstongubantes.json
new file mode 100644
index 0000000..0fd50d0
--- /dev/null
+++ b/Authors/winstongubantes.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Winston",
+  "lastName": "Gubantes",
+  "tagOrBio": "a Xamarin Developer at Gluon Consulting",
+  "stateOrRegion": "Davao City, Philippines",
+  "emailAddress": "winston.gubantes@gmail.com",
+  "twitterHandle": "tony_fear",
+  "gravatarHash": "9e1aea174237384361fc260b33559d05",
+  "githubHandle": "winstongubantes",
+  "position": {
+    "lat": 7.1066271,
+    "lon": 125.6294976
+  },
+  "webSite": "https://winstongubantes.blogspot.com/",
+  "feedUris": [
+    "https://winstongubantes.blogspot.com/feeds/posts/default?alt=rss"
+  ],
+  "languageCode": "es"
+}
\ No newline at end of file
diff --git a/Authors/wislon.json b/Authors/wislon.json
new file mode 100644
index 0000000..6e7fe33
--- /dev/null
+++ b/Authors/wislon.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "John",
+  "lastName": "Wilson",
+  "stateOrRegion": "Brisbane, Australia",
+  "emailAddress": "wislon@hotmail.com",
+  "tagOrBio": "Head of Mobile, Tech Lead, Xamarin Specialist",
+  "webSite": "https://blog.wislon.io/",
+  "feedUris": [
+    "https://blog.wislon.io/atom.xml"
+  ],
+  "twitterHandle": "wislon",
+  "gravatarHash": "86c9d925c04b4c79c98bfc839d949e15",
+  "githubHandle": "wislon",
+  "position": {
+    "lat": -27.3812513,
+    "lon": 152.7130138
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/xablu.json b/Authors/xablu.json
new file mode 100644
index 0000000..0d8e711
--- /dev/null
+++ b/Authors/xablu.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Xablu",
+  "lastName": "",
+  "stateOrRegion": "Amsterdam, the Netherlands",
+  "emailAddress": "hello@xablu.com",
+  "tagOrBio": "a 100% pure Xamarin company.",
+  "webSite": "https://www.xablu.com/",
+  "twitterHandle": "xabluhq",
+  "githubHandle": "xablu",
+  "gravatarHash": "508b1a99bb81e09c189e7487ecb69167",
+  "feedUris": [
+    "https://www.xablu.com/tag/planet-xamarin/feed/"
+  ],
+  "position": {
+    "lat": 52.3702,
+    "lon": 4.8952
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/xamarin.json b/Authors/xamarin.json
new file mode 100644
index 0000000..5ef90a8
--- /dev/null
+++ b/Authors/xamarin.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "The Xamarin",
+  "lastName": "Blog",
+  "stateOrRegion": "Internet",
+  "emailAddress": "hello@xamarin.com",
+  "tagOrBio": "is your official source for Xamarin developer news.",
+  "webSite": "https://blog.xamarin.com",
+  "feedUris": [
+    "https://devblogs.microsoft.com/xamarin/feed/"
+  ],
+  "twitterHandle": "xamarinhq",
+  "gravatarHash": "70148d964bb389d42547834e1062c886",
+  "githubHandle": "xamarin",
+  "position": {
+    "lat": 37.77493,
+    "lon": -122.419416
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/xamarinhowto.json b/Authors/xamarinhowto.json
new file mode 100644
index 0000000..8b56c33
--- /dev/null
+++ b/Authors/xamarinhowto.json
@@ -0,0 +1,19 @@
+{
+  "firstName": "Matt",
+  "lastName": "Crombie",
+  "tagOrBio": "Senior Xamarin Mobile Consultant/Architect",
+  "stateOrRegion": "Brisbane, Australia",
+  "emailAddress": "matt@xamarinhowto.com",
+  "twitterHandle": "xamarinhowto",
+  "gravatarHash": "3f1200c50911032b3558b7c0fc29c847",
+  "githubHandle": "xamarinhowto",
+  "position": {
+    "lat": -27.46845,
+    "lon": 153.024184
+  },
+  "webSite": "https://xamarinhowto.com/",
+  "feedUris": [
+    "https://xamarinhowto.com/feed/"
+  ],
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/Authors/yuv4ik.json b/Authors/yuv4ik.json
new file mode 100644
index 0000000..0055a33
--- /dev/null
+++ b/Authors/yuv4ik.json
@@ -0,0 +1,20 @@
+{
+  "firstName": "Evgeny",
+  "lastName": "Zborovsky",
+  "stateOrRegion": "Estonia",
+  "emailAddress": "yuv4ik@gmail.com",
+  "tagOrBio": "blogs, speaks, helps others and is an enthusiastic Xamarin developer.",
+  "webSite": "https://evgenyzborovsky.com/",
+  "feedUris": [
+    "https://evgenyzborovsky.com/tag/xamarin-forms/feed/",
+    "https://evgenyzborovsky.com/tag/xamarin/feed/"
+  ],
+  "twitterHandle": "ezborovsky",
+  "gravatarHash": "b8a0ab8445fafb38afdf26cb976df32f",
+  "githubHandle": "yuv4ik",
+  "position": {
+    "lat": 58.3750372,
+    "lon": 26.6625567
+  },
+  "languageCode": "en"
+}
\ No newline at end of file
diff --git a/PlanetDotnet.Authors/Models/Authors/Author.cs b/PlanetDotnet.Authors/Models/Authors/Author.cs
new file mode 100644
index 0000000..da6a3af
--- /dev/null
+++ b/PlanetDotnet.Authors/Models/Authors/Author.cs
@@ -0,0 +1,47 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using Newtonsoft.Json;
+using PlanetDotnet.Authors.Models.GeoPositions;
+
+namespace PlanetDotnet.Authors.Models.Authors
+{
+    public class Author
+    {
+        [JsonProperty("firstName", Required = Required.DisallowNull)]
+        public string FirstName { get; set; }
+        [JsonProperty("lastName", Required = Required.DisallowNull)]
+        public string LastName { get; set; }
+        [JsonProperty("stateOrRegion", Required = Required.DisallowNull)]
+        public string StateOrRegion { get; set; }
+        [EmailAddress]
+        [JsonProperty("emailAddress", Required = Required.Always)]
+        public string EmailAddress { get; set; }
+        [JsonProperty("tagOrBio", Required = Required.DisallowNull)]
+        public string ShortBioOrTagLine { get; set; }
+        [Url]
+        [JsonProperty("webSite", Required = Required.Always)]
+        public Uri WebSite { get; set; }
+        [JsonProperty("twitterHandle", Required = Required.DisallowNull)]
+        public string TwitterHandle { get; set; }
+        [JsonProperty("githubHandle", Required = Required.Always)]
+        public string GitHubHandle { get; set; }
+        [JsonProperty("gravatarHash", Required = Required.DisallowNull)]
+        public string GravatarHash { get; set; }
+        [JsonProperty("feedUris", Required = Required.Always)]
+        public IEnumerable<Uri> FeedUris { get; set; }
+        [JsonProperty("position", Required = Required.DisallowNull)]
+        public GeoPosition Position { get; set; }
+
+        // In ISO 639-1, lowercase, 2 letters
+        // https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+        [JsonProperty("languageCode", Required = Required.Always)]
+        public string FeedLanguageCode { get; set; }
+    }
+}
diff --git a/PlanetDotnet.Authors/Models/GeoPositions/GeoPosition.cs b/PlanetDotnet.Authors/Models/GeoPositions/GeoPosition.cs
new file mode 100644
index 0000000..e5f6204
--- /dev/null
+++ b/PlanetDotnet.Authors/Models/GeoPositions/GeoPosition.cs
@@ -0,0 +1,26 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using Newtonsoft.Json;
+
+namespace PlanetDotnet.Authors.Models.GeoPositions
+{
+    public class GeoPosition
+    {
+        public static GeoPosition Empty = new GeoPosition(-1337, 42);
+
+        [JsonProperty("lat", Required = Required.Always)]
+        public double Lat { get; }
+        [JsonProperty("lon", Required = Required.Always)]
+        public double Lng { get; }
+
+        public GeoPosition(double lat, double lng)
+        {
+            Lat = lat;
+            Lng = lng;
+        }
+    }
+}
diff --git a/PlanetDotnet.Authors/PlanetDotnet.Authors.csproj b/PlanetDotnet.Authors/PlanetDotnet.Authors.csproj
new file mode 100644
index 0000000..6b825fc
--- /dev/null
+++ b/PlanetDotnet.Authors/PlanetDotnet.Authors.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netstandard2.1</TargetFramework>
+    <Nullable>disable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
+    <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
+  </ItemGroup>
+
+	<ItemGroup>
+		<EmbeddedResource Include="..\Authors\*.json" />
+	</ItemGroup>
+
+</Project>
diff --git a/PlanetDotnet.sln b/PlanetDotnet.sln
index aa0ae85..aaba29e 100644
--- a/PlanetDotnet.sln
+++ b/PlanetDotnet.sln
@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanetDotnet", "PlanetDotne
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanetDotnet.Tests.Unit", "PlanetDotnet.Tests.Unit\PlanetDotnet.Tests.Unit.csproj", "{ED070F5D-3C55-4E8F-B23A-381E09931D1C}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanetDotnet.Authors", "PlanetDotnet.Authors\PlanetDotnet.Authors.csproj", "{0518A91D-95CA-4C21-BACF-E1E7E56D8754}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
 		{ED070F5D-3C55-4E8F-B23A-381E09931D1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{ED070F5D-3C55-4E8F-B23A-381E09931D1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{ED070F5D-3C55-4E8F-B23A-381E09931D1C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0518A91D-95CA-4C21-BACF-E1E7E56D8754}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{0518A91D-95CA-4C21-BACF-E1E7E56D8754}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0518A91D-95CA-4C21-BACF-E1E7E56D8754}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{0518A91D-95CA-4C21-BACF-E1E7E56D8754}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

From 75e93a1075c50bb196c453c1a4149fa19b9e2d2e Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sat, 18 Nov 2023 22:49:57 +0100
Subject: [PATCH 06/18] FOUNDATIONS: Get All Authors

---
 .../Services/AuthorService.cs                 | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 PlanetDotnet.Authors/Services/AuthorService.cs

diff --git a/PlanetDotnet.Authors/Services/AuthorService.cs b/PlanetDotnet.Authors/Services/AuthorService.cs
new file mode 100644
index 0000000..095b5fc
--- /dev/null
+++ b/PlanetDotnet.Authors/Services/AuthorService.cs
@@ -0,0 +1,42 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PlanetDotnet.Authors.Models.Authors;
+
+namespace PlanetDotnet.Authors.Services
+{
+    public static class AuthorService
+    {
+        public static async Task<IEnumerable<Author>> GetAllAuthors()
+        {
+            var assembly = Assembly.GetExecutingAssembly();
+            var resourceNames = assembly.GetManifestResourceNames();
+            var authorsResourceNames = resourceNames.Where(res =>
+                res.StartsWith("PlanetDotnet.Authors", StringComparison.OrdinalIgnoreCase) &&
+                res.EndsWith(".json", StringComparison.OrdinalIgnoreCase));
+
+            var authorsTasks = authorsResourceNames.Select(name => ReadAuthor(assembly, name));
+            var authors = await Task.WhenAll(authorsTasks).ConfigureAwait(false);
+            return authors;
+        }
+
+        private static async Task<Author> ReadAuthor(Assembly assembly, string authorResourceName)
+        {
+            using var stream = assembly.GetManifestResourceStream(authorResourceName);
+            using var reader = new StreamReader(stream);
+            var json = await reader.ReadToEndAsync().ConfigureAwait(false);
+            var author = JsonConvert.DeserializeObject<Author>(json);
+            return author;
+        }
+    }
+}

From 5110b567c0deac526ff47980b6fa749913aa3ab1 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sat, 18 Nov 2023 23:41:28 +0100
Subject: [PATCH 07/18] FUNCTIONS: Load Feed

---
 .../Extensions/SyndicationItemExtensions.cs   |  55 +++++
 .../Infrastructure/CombinedFeedSource.cs      | 219 ++++++++++++++++++
 PlanetDotnet/LoadFeedsFunction.cs             |  90 +++++--
 PlanetDotnet/PlanetDotnet.csproj              |   6 +
 4 files changed, 355 insertions(+), 15 deletions(-)
 create mode 100644 PlanetDotnet/Extensions/SyndicationItemExtensions.cs
 create mode 100644 PlanetDotnet/Infrastructure/CombinedFeedSource.cs

diff --git a/PlanetDotnet/Extensions/SyndicationItemExtensions.cs b/PlanetDotnet/Extensions/SyndicationItemExtensions.cs
new file mode 100644
index 0000000..716ba08
--- /dev/null
+++ b/PlanetDotnet/Extensions/SyndicationItemExtensions.cs
@@ -0,0 +1,55 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.Linq;
+using System.ServiceModel.Syndication;
+
+namespace PlanetDotnet.Extensions
+{
+    public static class SyndicationItemExtensions
+    {
+        public static bool ApplyDefaultFilter(this SyndicationItem item)
+        {
+            if (item == null)
+                return false;
+
+            var hasXamarinCategory = false;
+            var hasXamarinKeywords = false;
+
+            if (item.Categories.Count > 0)
+            {
+                hasXamarinCategory = item.Categories.Any(category =>
+                    category.Name.ToLowerInvariant().Contains("xamarin"));
+            }
+
+            if (item.ElementExtensions.Count > 0)
+            {
+                var element = item.ElementExtensions.FirstOrDefault(e => e.OuterName == "keywords");
+                if (element != null)
+                {
+                    var keywords = element.GetObject<string>();
+                    hasXamarinKeywords = keywords.ToLowerInvariant().Contains("xamarin");
+                }
+            }
+
+            var hasXamarinTitle = item.Title?.Text.ToLowerInvariant().Contains("xamarin") ?? false;
+
+            return hasXamarinTitle || hasXamarinCategory || hasXamarinKeywords;
+        }
+
+        public static string ToHtml(this SyndicationContent content)
+        {
+            var textSyndicationContent = content as TextSyndicationContent;
+            if (textSyndicationContent != null)
+            {
+                return textSyndicationContent.Text;
+            }
+
+            return content.ToString();
+        }
+    }
+
+}
diff --git a/PlanetDotnet/Infrastructure/CombinedFeedSource.cs b/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
new file mode 100644
index 0000000..3b9d9e3
--- /dev/null
+++ b/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
@@ -0,0 +1,219 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.ServiceModel.Syndication;
+using System.Threading.Tasks;
+using System.Xml;
+using Microsoft.Extensions.Logging;
+using PlanetDotnet.Authors.Models.Authors;
+using PlanetDotnet.Extensions;
+using Polly;
+using Polly.Retry;
+
+namespace PlanetDotnet.Infrastructure
+{
+    public class CombinedFeedSource
+    {
+        private static HttpClient _httpClient;
+        private static AsyncRetryPolicy _retryPolicy;
+        private readonly IEnumerable<Author> _authors;
+        private readonly ILogger _logger;
+        private readonly string _rssFeedTitle;
+        private readonly string _rssFeedDescription;
+        private readonly string _rssFeedUrl;
+        private readonly string _rssFeedImageUrl;
+
+        public CombinedFeedSource(
+            IEnumerable<Author> authors,
+            ILogger logger,
+            string rssFeedTitle,
+            string rssFeedDescription,
+            string rssFeedUrl,
+            string rssFeedImageUrl)
+        {
+            EnsureHttpClient();
+
+            if (_retryPolicy == null)
+            {
+                // retry policy with max 2 retries, delay by x*x^1.2 where x is retry attempt
+                // this will ensure we don't retry too quickly
+                _retryPolicy = Policy.Handle<FeedReadFailedException>()
+                    .WaitAndRetryAsync(2, retry => TimeSpan.FromSeconds(retry * Math.Pow(1.2, retry)));
+            }
+
+            _authors = authors;
+            _logger = logger;
+            _rssFeedTitle = rssFeedTitle;
+            _rssFeedDescription = rssFeedDescription;
+            _rssFeedUrl = rssFeedUrl;
+            _rssFeedImageUrl = rssFeedImageUrl;
+        }
+
+        private void EnsureHttpClient()
+        {
+            if (_httpClient == null)
+            {
+                _httpClient = new HttpClient();
+                _httpClient.DefaultRequestHeaders.UserAgent.Add(
+                    new ProductInfoHeaderValue("PlanetDotnet", $"{GetType().Assembly.GetName().Version}"));
+                _httpClient.Timeout = TimeSpan.FromSeconds(15);
+
+                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
+            }
+        }
+
+        public async Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageCode = "mixed")
+        {
+            IEnumerable<Author> tamarins;
+            if (languageCode == null || languageCode == "mixed") // use all tamarins
+            {
+                tamarins = _authors;
+            }
+            else
+            {
+                tamarins = _authors.Where(t => t.FeedLanguageCode == languageCode);
+            }
+
+            var feedTasks = tamarins.SelectMany(t => TryReadFeeds(t)).ToArray();
+
+            _logger?.LogInformation($"Loading feed for language: {languageCode} for {feedTasks.Length} authors");
+
+            var syndicationItems = await Task.WhenAll(feedTasks).ConfigureAwait(false);
+            var combinedFeed = GetCombinedFeed(syndicationItems.SelectMany(f => f), languageCode, tamarins, numberOfItems);
+            return combinedFeed;
+        }
+
+        private IEnumerable<Task<IEnumerable<SyndicationItem>>> TryReadFeeds(Author tamarin)
+        {
+            return tamarin.FeedUris.Select(uri => TryReadFeed(tamarin, uri.AbsoluteUri));
+        }
+
+        private async Task<IEnumerable<SyndicationItem>> TryReadFeed(Author tamarin, string feedUri)
+        {
+            try
+            {
+                return await _retryPolicy.ExecuteAsync(context => ReadFeed(feedUri), new Context(feedUri)).ConfigureAwait(false);
+            }
+            catch (FeedReadFailedException ex)
+            {
+                _logger.LogError(ex, $"{tamarin.FirstName} {tamarin.LastName}'s feed of {ex.Data["FeedUri"]} failed to load.");
+            }
+
+            return new SyndicationItem[0];
+        }
+
+        private async Task<IEnumerable<SyndicationItem>> ReadFeed(string feedUri)
+        {
+            HttpResponseMessage response;
+            try
+            {
+                _logger?.LogInformation($"Loading feed {feedUri}");
+                response = await _httpClient.GetAsync(feedUri).ConfigureAwait(false);
+                if (response.IsSuccessStatusCode)
+                {
+                    using var feedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+                    using var reader = XmlReader.Create(feedStream);
+                    var feed = SyndicationFeed.Load(reader);
+                    var filteredItems = feed.Items
+                        .Where(item => item.ApplyDefaultFilter());
+
+                    return filteredItems;
+                }
+            }
+            catch (HttpRequestException hex)
+            {
+                throw new FeedReadFailedException("Loading remote syndication feed failed", hex)
+                    .WithData("FeedUri", feedUri);
+            }
+            catch (WebException ex)
+            {
+                throw new FeedReadFailedException("Loading remote syndication feed timed out", ex)
+                    .WithData("FeedUri", feedUri);
+            }
+            catch (XmlException ex)
+            {
+                throw new FeedReadFailedException("Failed parsing remote syndication feed", ex)
+                    .WithData("FeedUri", feedUri);
+            }
+            catch (TaskCanceledException ex)
+            {
+                throw new FeedReadFailedException("Reading feed timed out", ex)
+                    .WithData("FeedUri", feedUri);
+            }
+            catch (OperationCanceledException opcex)
+            {
+                throw new FeedReadFailedException("Reading feed timed out", opcex)
+                    .WithData("FeedUri", feedUri);
+            }
+
+            throw new FeedReadFailedException("Loading remote syndication feed failed.")
+                .WithData("FeedUri", feedUri)
+                .WithData("HttpStatusCode", (int)response.StatusCode);
+        }
+
+        private SyndicationFeed GetCombinedFeed(IEnumerable<SyndicationItem> items, string languageCode,
+            IEnumerable<Author> tamarins, int? numberOfItems)
+        {
+            DateTimeOffset GetMaxTime(SyndicationItem item)
+            {
+                return new[] { item.PublishDate.UtcDateTime, item.LastUpdatedTime.UtcDateTime }.Max();
+            }
+
+            var orderedItems = items
+                .Where(item =>
+                    GetMaxTime(item) <= DateTimeOffset.UtcNow)
+                .OrderByDescending(item => GetMaxTime(item));
+
+            var feed = new SyndicationFeed(
+                _rssFeedTitle,
+                _rssFeedDescription,
+                new Uri(_rssFeedUrl),
+                numberOfItems.HasValue ? orderedItems.Take(numberOfItems.Value) : orderedItems)
+            {
+                ImageUrl = new Uri(_rssFeedImageUrl),
+                Copyright = new TextSyndicationContent("The copyright for each post is retained by its author."),
+                Language = languageCode,
+                LastUpdatedTime = DateTimeOffset.UtcNow
+            };
+
+            foreach (var tamarin in tamarins)
+            {
+                feed.Contributors.Add(new SyndicationPerson(
+                    tamarin.EmailAddress, $"{tamarin.FirstName} {tamarin.LastName}", tamarin.WebSite.ToString()));
+            }
+
+            return feed;
+        }
+    }
+
+    public class FeedReadFailedException : Exception
+    {
+        public FeedReadFailedException(string message)
+            : base(message)
+        {
+        }
+
+        public FeedReadFailedException(string message, Exception inner)
+            : base(message, inner)
+        {
+        }
+    }
+
+    internal static class ExceptionExtensions
+    {
+        public static TException WithData<TException>(this TException exception, string key, object value) where TException : Exception
+        {
+            exception.Data[key] = value;
+            return exception;
+        }
+    }
+}
diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
index 8d9b79a..e919852 100644
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -4,37 +4,97 @@
 // See License.txt in the project root for license information.
 // ---------------------------------------------------------------
 
+using System;
 using System.IO;
+using System.Linq;
+using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
+using System.Xml;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
 using Microsoft.Azure.WebJobs;
-using Microsoft.Azure.WebJobs.Extensions.Http;
 using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
+using PlanetDotnet.Authors.Services;
+using PlanetDotnet.Infrastructure;
 
 namespace PlanetDotnet
 {
     public static class LoadFeedsFunction
     {
         [FunctionName("LoadFeedsFunction")]
-        public static async Task<IActionResult> Run(
-            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
+        public static async Task Run(
+            [TimerTrigger("0 0 */1 * * *", RunOnStartup = true)] TimerInfo myTimer,
             ILogger log)
         {
-            log.LogInformation("C# HTTP trigger function processed a request.");
+            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
 
-            string name = req.Query["name"];
+            var rssFeedTitle = GetEnvironmentVariable("RssFeedTitle");
+            var rssFeedDescription = GetEnvironmentVariable("RssFeedDescription");
+            var rssFeedUrl = GetEnvironmentVariable("RssFeedUrl");
+            var rssFeedImageUrl = GetEnvironmentVariable("RssFeedImageUrl");
 
-            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
-            dynamic data = JsonConvert.DeserializeObject(requestBody);
-            name = name ?? data?.name;
+            var authors = await AuthorService.GetAllAuthors();
+            var languages = authors.Select(author => author.FeedLanguageCode).Distinct().ToList();
+            languages.Add("mixed");
+            var feedSource =
+                new CombinedFeedSource(
+                    authors,
+                    log,
+                    rssFeedTitle,
+                    rssFeedDescription,
+                    rssFeedUrl,
+                    rssFeedImageUrl);
 
-            string responseMessage = string.IsNullOrEmpty(name)
-                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
-                : $"Hello, {name}. This HTTP triggered function executed successfully.";
+            var blobConnectString = GetEnvironmentVariable("FeedBlobStorage");
+            var container = new BlobContainerClient(blobConnectString, "feeds");
+            await container.CreateIfNotExistsAsync();
+            await container.SetAccessPolicyAsync(PublicAccessType.Blob);
 
-            return new OkObjectResult(responseMessage);
+            foreach (var language in languages)
+            {
+                try
+                {
+                    log.LogInformation($"Loading {language} combined author feed");
+                    var feed = await feedSource.LoadFeed(null, language);
+                    using var stream = await SerializeFeed(feed);
+                    await UploadBlob(container, stream, language, log);
+                }
+                catch (Exception ex)
+                {
+                    log.LogError(ex, ex.Message);
+                }
+            }
+        }
+
+        private static async Task UploadBlob(BlobContainerClient container, Stream feedStream, string language, ILogger log)
+        {
+            var feedName = $"feed.{language}.rss";
+            var blob = container.GetBlobClient(feedName);
+            await blob.UploadAsync(feedStream, overwrite: true);
+
+            log.LogInformation($"Uploaded {feedName} to {blob.Uri}");
+        }
+
+        private static async Task<Stream> SerializeFeed(SyndicationFeed feed)
+        {
+            var memoryStream = new MemoryStream();
+            using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
+            {
+                Async = true
+            });
+
+            var rssFormatter = new Rss20FeedFormatter(feed);
+            rssFormatter.WriteTo(xmlWriter);
+            await xmlWriter.FlushAsync();
+
+            memoryStream.Seek(0, SeekOrigin.Begin);
+
+            return memoryStream;
+        }
+
+        private static string GetEnvironmentVariable(string name)
+        {
+            return Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
         }
     }
 }
diff --git a/PlanetDotnet/PlanetDotnet.csproj b/PlanetDotnet/PlanetDotnet.csproj
index 8b0fb18..69d5a8c 100644
--- a/PlanetDotnet/PlanetDotnet.csproj
+++ b/PlanetDotnet/PlanetDotnet.csproj
@@ -7,8 +7,14 @@
     <None Remove=".gitignore" />
   </ItemGroup>
   <ItemGroup>
+    <PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
     <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
     <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.2.0" />
+    <PackageReference Include="Polly" Version="8.2.0" />
+    <PackageReference Include="System.ServiceModel.Syndication" Version="8.0.0" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\PlanetDotnet.Authors\PlanetDotnet.Authors.csproj" />
   </ItemGroup>
   <ItemGroup>
     <None Update="host.json">

From 2903e3ad898a34889d6d0e994b843191b2036f93 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sat, 18 Nov 2023 23:57:26 +0100
Subject: [PATCH 08/18] BROKERS: Read Feed

---
 PlanetDotnet/Brokers/Feeds/FeedBroker.cs  | 32 +++++++++++++++++++++++
 PlanetDotnet/Brokers/Feeds/IFeedBroker.cs | 17 ++++++++++++
 2 files changed, 49 insertions(+)
 create mode 100644 PlanetDotnet/Brokers/Feeds/FeedBroker.cs
 create mode 100644 PlanetDotnet/Brokers/Feeds/IFeedBroker.cs

diff --git a/PlanetDotnet/Brokers/Feeds/FeedBroker.cs b/PlanetDotnet/Brokers/Feeds/FeedBroker.cs
new file mode 100644
index 0000000..9bd9ccc
--- /dev/null
+++ b/PlanetDotnet/Brokers/Feeds/FeedBroker.cs
@@ -0,0 +1,32 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Net.Http;
+using System.ServiceModel.Syndication;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace PlanetDotnet.Brokers.Feeds
+{
+    public class FeedBroker : IFeedBroker
+    {
+        private readonly HttpClient httpClient;
+
+        public FeedBroker(HttpClient httpClient) =>
+            this.httpClient = httpClient;
+
+        public async ValueTask<IEnumerable<SyndicationItem>> ReadFeedAsync(string feedUri)
+        {
+            var response = await httpClient.GetAsync(feedUri).ConfigureAwait(false);
+            using var feedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+            using var reader = XmlReader.Create(feedStream);
+            var feed = SyndicationFeed.Load(reader);
+
+            return feed.Items;
+        }
+    }
+}
diff --git a/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs b/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs
new file mode 100644
index 0000000..d02dc52
--- /dev/null
+++ b/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs
@@ -0,0 +1,17 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.ServiceModel.Syndication;
+using System.Threading.Tasks;
+
+namespace PlanetDotnet.Brokers.Feeds
+{
+    public interface IFeedBroker
+    {
+        ValueTask<IEnumerable<SyndicationItem>> ReadFeedAsync(string feedUri);
+    }
+}

From 0dd64c55156423d222e62396788b2300cc485191 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sun, 19 Nov 2023 01:10:31 +0100
Subject: [PATCH 09/18] BROKERS: GetAllAuthors

---
 PlanetDotnet/Brokers/Authors/AuthorBroker.cs  | 19 ++++
 PlanetDotnet/Brokers/Authors/IAuthorBroker.cs | 17 ++++
 .../Brokers/DateTimes/DateTimeBroker.cs       | 10 ++
 .../Brokers/DateTimes/IDateTimeBroker.cs      |  9 ++
 PlanetDotnet/Brokers/Feeds/FeedBroker.cs      |  7 +-
 PlanetDotnet/Brokers/Feeds/IFeedBroker.cs     |  3 +-
 .../Brokers/Loggings/ILoggingBroker.cs        | 14 +++
 .../Brokers/Loggings/LoggingBroker.cs         | 31 ++++++
 PlanetDotnet/Services/Feeds/FeedService.cs    | 98 +++++++++++++++++++
 PlanetDotnet/Services/Feeds/IFeedService.cs   | 17 ++++
 PlanetDotnet/Startup.cs                       | 16 ++-
 11 files changed, 234 insertions(+), 7 deletions(-)
 create mode 100644 PlanetDotnet/Brokers/Authors/AuthorBroker.cs
 create mode 100644 PlanetDotnet/Brokers/Authors/IAuthorBroker.cs
 create mode 100644 PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs
 create mode 100644 PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs
 create mode 100644 PlanetDotnet/Brokers/Loggings/ILoggingBroker.cs
 create mode 100644 PlanetDotnet/Brokers/Loggings/LoggingBroker.cs
 create mode 100644 PlanetDotnet/Services/Feeds/FeedService.cs
 create mode 100644 PlanetDotnet/Services/Feeds/IFeedService.cs

diff --git a/PlanetDotnet/Brokers/Authors/AuthorBroker.cs b/PlanetDotnet/Brokers/Authors/AuthorBroker.cs
new file mode 100644
index 0000000..ad3d674
--- /dev/null
+++ b/PlanetDotnet/Brokers/Authors/AuthorBroker.cs
@@ -0,0 +1,19 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using PlanetDotnet.Authors.Models.Authors;
+using PlanetDotnet.Authors.Services;
+
+namespace PlanetDotnet.Brokers.Authors
+{
+    public class AuthorBroker : IAuthorBroker
+    {
+        public async ValueTask<IEnumerable<Author>> GetAllAuthorsAsync() =>
+           await AuthorService.GetAllAuthors();
+    }
+}
diff --git a/PlanetDotnet/Brokers/Authors/IAuthorBroker.cs b/PlanetDotnet/Brokers/Authors/IAuthorBroker.cs
new file mode 100644
index 0000000..f7dfafb
--- /dev/null
+++ b/PlanetDotnet/Brokers/Authors/IAuthorBroker.cs
@@ -0,0 +1,17 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using PlanetDotnet.Authors.Models.Authors;
+
+namespace PlanetDotnet.Brokers.Authors
+{
+    public interface IAuthorBroker
+    {
+        ValueTask<IEnumerable<Author>> GetAllAuthorsAsync();
+    }
+}
diff --git a/PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs b/PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs
new file mode 100644
index 0000000..1a91c52
--- /dev/null
+++ b/PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace PlanetDotnet.Brokers.DateTimes
+{
+    public class DateTimeBroker : IDateTimeBroker
+    {
+        public DateTimeOffset GetCurrentDateTimeOffset() =>
+            DateTimeOffset.UtcNow;
+    }
+}
\ No newline at end of file
diff --git a/PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs b/PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs
new file mode 100644
index 0000000..d771b78
--- /dev/null
+++ b/PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace PlanetDotnet.Brokers.DateTimes
+{
+    public interface IDateTimeBroker
+    {
+        DateTimeOffset GetCurrentDateTimeOffset();
+    }
+}
\ No newline at end of file
diff --git a/PlanetDotnet/Brokers/Feeds/FeedBroker.cs b/PlanetDotnet/Brokers/Feeds/FeedBroker.cs
index 9bd9ccc..d05fc13 100644
--- a/PlanetDotnet/Brokers/Feeds/FeedBroker.cs
+++ b/PlanetDotnet/Brokers/Feeds/FeedBroker.cs
@@ -4,7 +4,6 @@
 // See License.txt in the project root for license information.
 // ---------------------------------------------------------------
 
-using System.Collections.Generic;
 using System.Net.Http;
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
@@ -12,21 +11,21 @@
 
 namespace PlanetDotnet.Brokers.Feeds
 {
-    public class FeedBroker : IFeedBroker
+    internal class FeedBroker : IFeedBroker
     {
         private readonly HttpClient httpClient;
 
         public FeedBroker(HttpClient httpClient) =>
             this.httpClient = httpClient;
 
-        public async ValueTask<IEnumerable<SyndicationItem>> ReadFeedAsync(string feedUri)
+        public async ValueTask<SyndicationFeed> ReadFeedAsync(string feedUri)
         {
             var response = await httpClient.GetAsync(feedUri).ConfigureAwait(false);
             using var feedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
             using var reader = XmlReader.Create(feedStream);
             var feed = SyndicationFeed.Load(reader);
 
-            return feed.Items;
+            return feed;
         }
     }
 }
diff --git a/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs b/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs
index d02dc52..aa48450 100644
--- a/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs
+++ b/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs
@@ -4,7 +4,6 @@
 // See License.txt in the project root for license information.
 // ---------------------------------------------------------------
 
-using System.Collections.Generic;
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
 
@@ -12,6 +11,6 @@ namespace PlanetDotnet.Brokers.Feeds
 {
     public interface IFeedBroker
     {
-        ValueTask<IEnumerable<SyndicationItem>> ReadFeedAsync(string feedUri);
+        ValueTask<SyndicationFeed> ReadFeedAsync(string feedUri);
     }
 }
diff --git a/PlanetDotnet/Brokers/Loggings/ILoggingBroker.cs b/PlanetDotnet/Brokers/Loggings/ILoggingBroker.cs
new file mode 100644
index 0000000..bb02432
--- /dev/null
+++ b/PlanetDotnet/Brokers/Loggings/ILoggingBroker.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace PlanetDotnet.Brokers.Loggings
+{
+    public interface ILoggingBroker
+    {
+        void LogInformation(string message);
+        void LogTrace(string message);
+        void LogDebug(string message);
+        void LogWarning(string message);
+        void LogError(Exception exception);
+        void LogCritical(Exception exception);
+    }
+}
diff --git a/PlanetDotnet/Brokers/Loggings/LoggingBroker.cs b/PlanetDotnet/Brokers/Loggings/LoggingBroker.cs
new file mode 100644
index 0000000..d5a6695
--- /dev/null
+++ b/PlanetDotnet/Brokers/Loggings/LoggingBroker.cs
@@ -0,0 +1,31 @@
+using System;
+using Microsoft.Extensions.Logging;
+
+namespace PlanetDotnet.Brokers.Loggings
+{
+    public class LoggingBroker : ILoggingBroker
+    {
+        private readonly ILogger<LoggingBroker> logger;
+
+        public LoggingBroker(ILogger<LoggingBroker> logger) =>
+            this.logger = logger;
+
+        public void LogInformation(string message) =>
+            this.logger.LogInformation(message);
+
+        public void LogTrace(string message) =>
+            this.logger.LogTrace(message);
+
+        public void LogDebug(string message) =>
+            this.logger.LogDebug(message);
+
+        public void LogWarning(string message) =>
+            this.logger.LogWarning(message);
+
+        public void LogError(Exception exception) =>
+            this.logger.LogError(exception.Message, exception);
+
+        public void LogCritical(Exception exception) =>
+            this.logger.LogCritical(exception, exception.Message);
+    }
+}
diff --git a/PlanetDotnet/Services/Feeds/FeedService.cs b/PlanetDotnet/Services/Feeds/FeedService.cs
new file mode 100644
index 0000000..6086b99
--- /dev/null
+++ b/PlanetDotnet/Services/Feeds/FeedService.cs
@@ -0,0 +1,98 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.ServiceModel.Syndication;
+using System.Threading.Tasks;
+using PlanetDotnet.Brokers.Authors;
+using PlanetDotnet.Brokers.DateTimes;
+using PlanetDotnet.Brokers.Feeds;
+using PlanetDotnet.Brokers.Loggings;
+
+namespace PlanetDotnet.Services.Feeds
+{
+    internal partial class FeedService : IFeedService
+    {
+        private readonly IFeedBroker feedBroker;
+        private readonly IAuthorBroker authorBroker;
+        private readonly IDateTimeBroker dateTimeBroker;
+        private readonly ILoggingBroker loggingBroker;
+
+        private const string RssFeedTitleKey = "RssFeedTitle";
+        private const string RssFeedDescriptionKey = "RssFeedDescription";
+        private const string RssFeedUrlKey = "RssFeedUrl";
+        private const string RssFeedImageUrlKey = "RssFeedImageUrl";
+
+        public FeedService(
+            IFeedBroker feedBroker,
+            IAuthorBroker authorBroker,
+            IDateTimeBroker dateTimeBroker,
+            ILoggingBroker loggingBroker)
+        {
+            this.feedBroker = feedBroker;
+            this.authorBroker = authorBroker;
+            this.dateTimeBroker = dateTimeBroker;
+            this.loggingBroker = loggingBroker;
+        }
+
+        public async ValueTask<SyndicationFeed> CombineFeedsAsync()
+        {
+            var authors = await this.authorBroker.GetAllAuthorsAsync();
+
+            var feedItems = new List<SyndicationItem>();
+
+            foreach (var author in authors)
+            {
+                foreach (var feedUri in author.FeedUris)
+                {
+                    var feed = await this.feedBroker.ReadFeedAsync(feedUri.AbsoluteUri);
+
+                    feedItems.AddRange(feed.Items);
+                }
+            }
+
+            return CreateCombinedFeed(
+                items: feedItems,
+                lastUpdate: this.dateTimeBroker.GetCurrentDateTimeOffset());
+        }
+
+        private static SyndicationFeed CreateCombinedFeed(
+            List<SyndicationItem> items,
+            DateTimeOffset lastUpdate,
+            string languageCode = "mixed")
+        {
+            var rssFeedTitle = Environment.GetEnvironmentVariable(
+                variable: RssFeedTitleKey,
+                target: EnvironmentVariableTarget.Process);
+
+            var rssFeedDescription = Environment.GetEnvironmentVariable(
+                 variable: RssFeedDescriptionKey,
+                 target: EnvironmentVariableTarget.Process);
+
+            var rssFeedUrl = Environment.GetEnvironmentVariable(
+                variable: RssFeedUrlKey,
+                target: EnvironmentVariableTarget.Process);
+
+            var rssFeedImageUrl = Environment.GetEnvironmentVariable(
+                variable: RssFeedImageUrlKey,
+                target: EnvironmentVariableTarget.Process);
+
+            var feed = new SyndicationFeed(
+                title: rssFeedTitle,
+                description: rssFeedDescription,
+                feedAlternateLink: new Uri(rssFeedUrl),
+                items: items);
+
+            feed.ImageUrl = new Uri(rssFeedImageUrl);
+            feed.Copyright = new TextSyndicationContent("The copyright for each post is retained by its author.");
+            feed.Language = languageCode;
+            feed.LastUpdatedTime = lastUpdate;
+
+            return feed;
+        }
+    }
+}
diff --git a/PlanetDotnet/Services/Feeds/IFeedService.cs b/PlanetDotnet/Services/Feeds/IFeedService.cs
new file mode 100644
index 0000000..bdc8eb1
--- /dev/null
+++ b/PlanetDotnet/Services/Feeds/IFeedService.cs
@@ -0,0 +1,17 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.ServiceModel.Syndication;
+using System.Threading.Tasks;
+
+namespace PlanetDotnet.Services.Feeds
+{
+    public interface IFeedService
+    {
+        ValueTask<SyndicationFeed> CombineFeedsAsync();
+        ValueTask<SyndicationFeed> CombineFeedsAsync();
+    }
+}
diff --git a/PlanetDotnet/Startup.cs b/PlanetDotnet/Startup.cs
index 779de6d..eca6692 100644
--- a/PlanetDotnet/Startup.cs
+++ b/PlanetDotnet/Startup.cs
@@ -5,6 +5,13 @@
 // ---------------------------------------------------------------
 
 using Microsoft.Azure.Functions.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using PlanetDotnet.Brokers.Authors;
+using PlanetDotnet.Brokers.DateTimes;
+using PlanetDotnet.Brokers.Feeds;
+using PlanetDotnet.Brokers.Loggings;
+using PlanetDotnet.Services.Feeds;
 
 [assembly: FunctionsStartup(typeof(PlanetDotnet.Startup))]
 namespace PlanetDotnet
@@ -12,6 +19,13 @@ namespace PlanetDotnet
     public class Startup : FunctionsStartup
     {
         public override void Configure(IFunctionsHostBuilder builder)
-        { }
+        {
+            builder.Services.AddScoped<ILogger, Logger<LoggingBroker>>();
+            builder.Services.AddScoped<ILoggingBroker, LoggingBroker>();
+            builder.Services.AddScoped<IDateTimeBroker, DateTimeBroker>();
+            builder.Services.AddScoped<IAuthorBroker, AuthorBroker>();
+            builder.Services.AddScoped<IFeedBroker, FeedBroker>();
+            builder.Services.AddScoped<IFeedService, FeedService>();
+        }
     }
 }

From 9ba3c0628e9cec40ec98fb43e39d47ecc526e60d Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sun, 19 Nov 2023 01:38:32 +0100
Subject: [PATCH 10/18] BROKERS: SerializeFeed

---
 .../Serializations/ISerializationBroker.cs    | 18 +++++++++
 .../Serializations/SerializationBroker.cs     | 38 +++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 PlanetDotnet/Brokers/Serializations/ISerializationBroker.cs
 create mode 100644 PlanetDotnet/Brokers/Serializations/SerializationBroker.cs

diff --git a/PlanetDotnet/Brokers/Serializations/ISerializationBroker.cs b/PlanetDotnet/Brokers/Serializations/ISerializationBroker.cs
new file mode 100644
index 0000000..815fcb4
--- /dev/null
+++ b/PlanetDotnet/Brokers/Serializations/ISerializationBroker.cs
@@ -0,0 +1,18 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.IO;
+using System.ServiceModel.Syndication;
+using System.Threading.Tasks;
+
+namespace PlanetDotnet.Brokers.Serializations
+{
+    public interface ISerializationBroker
+    {
+        ValueTask<Stream> SerializeFeedAsync(SyndicationFeed feed);
+        ValueTask<SyndicationFeed> DeserializeFeedAsync(Stream feedStream);
+    }
+}
diff --git a/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs b/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs
new file mode 100644
index 0000000..b03465e
--- /dev/null
+++ b/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs
@@ -0,0 +1,38 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.IO;
+using System.ServiceModel.Syndication;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace PlanetDotnet.Brokers.Serializations
+{
+    internal class SerializationBroker : ISerializationBroker
+    {
+        public ValueTask<SyndicationFeed> DeserializeFeedAsync(Stream feedStream)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public async ValueTask<Stream> SerializeFeedAsync(SyndicationFeed feed)
+        {
+            var memoryStream = new MemoryStream();
+            using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
+            {
+                Async = true
+            });
+
+            var rssFormatter = new Rss20FeedFormatter(feed);
+            rssFormatter.WriteTo(xmlWriter);
+            await xmlWriter.FlushAsync();
+
+            memoryStream.Seek(0, SeekOrigin.Begin);
+
+            return memoryStream;
+        }
+    }
+}

From 9123a4ab99dd70d3ecc382aaf84b8dab12c4369c Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Sun, 19 Nov 2023 03:17:41 +0100
Subject: [PATCH 11/18] FUNCTIONS: Load Feeds

---
 .../Serializations/ISerializationBroker.cs    |  2 +-
 .../Serializations/SerializationBroker.cs     | 13 ++-
 .../Brokers/Storages/IStorageBroker.cs        | 17 ++++
 .../Brokers/Storages/StorageBroker.cs         | 50 ++++++++++
 PlanetDotnet/LoadFeedsFunction.cs             | 83 +++--------------
 PlanetDotnet/Services/Feeds/FeedService.cs    | 91 +++++++++++++++++--
 PlanetDotnet/Services/Feeds/IFeedService.cs   |  5 +-
 PlanetDotnet/Startup.cs                       |  7 +-
 PlanetDotnet/host.json                        | 21 +++--
 9 files changed, 194 insertions(+), 95 deletions(-)
 create mode 100644 PlanetDotnet/Brokers/Storages/IStorageBroker.cs
 create mode 100644 PlanetDotnet/Brokers/Storages/StorageBroker.cs

diff --git a/PlanetDotnet/Brokers/Serializations/ISerializationBroker.cs b/PlanetDotnet/Brokers/Serializations/ISerializationBroker.cs
index 815fcb4..65a601d 100644
--- a/PlanetDotnet/Brokers/Serializations/ISerializationBroker.cs
+++ b/PlanetDotnet/Brokers/Serializations/ISerializationBroker.cs
@@ -13,6 +13,6 @@ namespace PlanetDotnet.Brokers.Serializations
     public interface ISerializationBroker
     {
         ValueTask<Stream> SerializeFeedAsync(SyndicationFeed feed);
-        ValueTask<SyndicationFeed> DeserializeFeedAsync(Stream feedStream);
+        SyndicationFeed DeserializeFeed(Stream feedStream);
     }
 }
diff --git a/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs b/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs
index b03465e..6a4256a 100644
--- a/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs
+++ b/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs
@@ -4,6 +4,7 @@
 // See License.txt in the project root for license information.
 // ---------------------------------------------------------------
 
+using System;
 using System.IO;
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
@@ -13,9 +14,17 @@ namespace PlanetDotnet.Brokers.Serializations
 {
     internal class SerializationBroker : ISerializationBroker
     {
-        public ValueTask<SyndicationFeed> DeserializeFeedAsync(Stream feedStream)
+        public SyndicationFeed DeserializeFeed(Stream feedStream)
         {
-            throw new System.NotImplementedException();
+            feedStream.Position = 0;
+            using var xmlReader = XmlReader.Create(feedStream, new XmlReaderSettings
+            {
+                Async = true
+            });
+
+            var feed = SyndicationFeed.Load(xmlReader);
+
+            return feed;
         }
 
         public async ValueTask<Stream> SerializeFeedAsync(SyndicationFeed feed)
diff --git a/PlanetDotnet/Brokers/Storages/IStorageBroker.cs b/PlanetDotnet/Brokers/Storages/IStorageBroker.cs
new file mode 100644
index 0000000..6294a48
--- /dev/null
+++ b/PlanetDotnet/Brokers/Storages/IStorageBroker.cs
@@ -0,0 +1,17 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.IO;
+using System.Threading.Tasks;
+
+namespace PlanetDotnet.Brokers.Storages
+{
+    public interface IStorageBroker
+    {
+        ValueTask UploadBlobAsync(string language, Stream content);
+        ValueTask<Stream> ReadBlobAsync(string language);
+    }
+}
diff --git a/PlanetDotnet/Brokers/Storages/StorageBroker.cs b/PlanetDotnet/Brokers/Storages/StorageBroker.cs
new file mode 100644
index 0000000..b2bc85a
--- /dev/null
+++ b/PlanetDotnet/Brokers/Storages/StorageBroker.cs
@@ -0,0 +1,50 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Azure.Storage.Blobs;
+
+namespace PlanetDotnet.Brokers.Storages
+{
+    public class StorageBroker : IStorageBroker
+    {
+        private readonly BlobContainerClient blobContainerClient;
+        private const string BlobContainerName = "feeds";
+        private const string FeedBlobStorageKey = "FeedBlobStorage";
+        private const string BlobName = "newfeed.{0}.rss";
+
+        public StorageBroker()
+        {
+            var blobConnectString = Environment.GetEnvironmentVariable(
+                variable: FeedBlobStorageKey,
+                target: EnvironmentVariableTarget.Process);
+
+            this.blobContainerClient = new BlobContainerClient(
+                connectionString: blobConnectString,
+                blobContainerName: BlobContainerName);
+        }
+
+        public async ValueTask UploadBlobAsync(string language, Stream content)
+        {
+            var blobName = string.Format(BlobName, language);
+
+            var blobClient = this.blobContainerClient.GetBlobClient(blobName);
+
+            await blobClient.UploadAsync(content, overwrite: true);
+        }
+
+        public async ValueTask<Stream> ReadBlobAsync(string language)
+        {
+            var blobName = string.Format(BlobName, language);
+            var blobClient = this.blobContainerClient.GetBlobClient(blobName);
+
+            var response = await blobClient.DownloadAsync();
+            return response.Value.Content;
+        }
+    }
+}
diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
index e919852..9abc778 100644
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -5,96 +5,35 @@
 // ---------------------------------------------------------------
 
 using System;
-using System.IO;
 using System.Linq;
-using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
-using System.Xml;
 using Azure.Storage.Blobs;
 using Azure.Storage.Blobs.Models;
 using Microsoft.Azure.WebJobs;
 using Microsoft.Extensions.Logging;
 using PlanetDotnet.Authors.Services;
 using PlanetDotnet.Infrastructure;
+using PlanetDotnet.Services.Feeds;
 
 namespace PlanetDotnet
 {
-    public static class LoadFeedsFunction
+    public class LoadFeedsFunction
     {
+        private readonly IFeedService feedService;
+
+        public LoadFeedsFunction(IFeedService feedService) =>
+            this.feedService = feedService;
+
         [FunctionName("LoadFeedsFunction")]
-        public static async Task Run(
+        public async Task Run(
             [TimerTrigger("0 0 */1 * * *", RunOnStartup = true)] TimerInfo myTimer,
             ILogger log)
         {
-            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
-
-            var rssFeedTitle = GetEnvironmentVariable("RssFeedTitle");
-            var rssFeedDescription = GetEnvironmentVariable("RssFeedDescription");
-            var rssFeedUrl = GetEnvironmentVariable("RssFeedUrl");
-            var rssFeedImageUrl = GetEnvironmentVariable("RssFeedImageUrl");
+            log.LogInformation($"Load feeds Timer trigger function executed at: {DateTime.Now}");
 
-            var authors = await AuthorService.GetAllAuthors();
-            var languages = authors.Select(author => author.FeedLanguageCode).Distinct().ToList();
-            languages.Add("mixed");
-            var feedSource =
-                new CombinedFeedSource(
-                    authors,
-                    log,
-                    rssFeedTitle,
-                    rssFeedDescription,
-                    rssFeedUrl,
-                    rssFeedImageUrl);
+            await this.feedService.LoadFeedAsync();
 
-            var blobConnectString = GetEnvironmentVariable("FeedBlobStorage");
-            var container = new BlobContainerClient(blobConnectString, "feeds");
-            await container.CreateIfNotExistsAsync();
-            await container.SetAccessPolicyAsync(PublicAccessType.Blob);
-
-            foreach (var language in languages)
-            {
-                try
-                {
-                    log.LogInformation($"Loading {language} combined author feed");
-                    var feed = await feedSource.LoadFeed(null, language);
-                    using var stream = await SerializeFeed(feed);
-                    await UploadBlob(container, stream, language, log);
-                }
-                catch (Exception ex)
-                {
-                    log.LogError(ex, ex.Message);
-                }
-            }
-        }
-
-        private static async Task UploadBlob(BlobContainerClient container, Stream feedStream, string language, ILogger log)
-        {
-            var feedName = $"feed.{language}.rss";
-            var blob = container.GetBlobClient(feedName);
-            await blob.UploadAsync(feedStream, overwrite: true);
-
-            log.LogInformation($"Uploaded {feedName} to {blob.Uri}");
-        }
-
-        private static async Task<Stream> SerializeFeed(SyndicationFeed feed)
-        {
-            var memoryStream = new MemoryStream();
-            using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
-            {
-                Async = true
-            });
-
-            var rssFormatter = new Rss20FeedFormatter(feed);
-            rssFormatter.WriteTo(xmlWriter);
-            await xmlWriter.FlushAsync();
-
-            memoryStream.Seek(0, SeekOrigin.Begin);
-
-            return memoryStream;
-        }
-
-        private static string GetEnvironmentVariable(string name)
-        {
-            return Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
+            log.LogInformation($"Load feeds Finished at: {DateTime.Now}");
         }
     }
 }
diff --git a/PlanetDotnet/Services/Feeds/FeedService.cs b/PlanetDotnet/Services/Feeds/FeedService.cs
index 6086b99..b479100 100644
--- a/PlanetDotnet/Services/Feeds/FeedService.cs
+++ b/PlanetDotnet/Services/Feeds/FeedService.cs
@@ -6,12 +6,17 @@
 
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
+using PlanetDotnet.Authors.Models.Authors;
 using PlanetDotnet.Brokers.Authors;
 using PlanetDotnet.Brokers.DateTimes;
 using PlanetDotnet.Brokers.Feeds;
 using PlanetDotnet.Brokers.Loggings;
+using PlanetDotnet.Brokers.Serializations;
+using PlanetDotnet.Brokers.Storages;
 
 namespace PlanetDotnet.Services.Feeds
 {
@@ -21,6 +26,8 @@ internal partial class FeedService : IFeedService
         private readonly IAuthorBroker authorBroker;
         private readonly IDateTimeBroker dateTimeBroker;
         private readonly ILoggingBroker loggingBroker;
+        private readonly ISerializationBroker serializationBroker;
+        private readonly IStorageBroker storageBroker;
 
         private const string RssFeedTitleKey = "RssFeedTitle";
         private const string RssFeedDescriptionKey = "RssFeedDescription";
@@ -31,38 +38,95 @@ public FeedService(
             IFeedBroker feedBroker,
             IAuthorBroker authorBroker,
             IDateTimeBroker dateTimeBroker,
-            ILoggingBroker loggingBroker)
+            ILoggingBroker loggingBroker,
+            ISerializationBroker serializationBroker,
+            IStorageBroker storageBroker)
         {
             this.feedBroker = feedBroker;
             this.authorBroker = authorBroker;
             this.dateTimeBroker = dateTimeBroker;
             this.loggingBroker = loggingBroker;
+            this.serializationBroker = serializationBroker;
+            this.storageBroker = storageBroker;
         }
 
-        public async ValueTask<SyndicationFeed> CombineFeedsAsync()
+        public async ValueTask<SyndicationFeed> GetMixedFeedAsync()
         {
             var authors = await this.authorBroker.GetAllAuthorsAsync();
 
+            return await GetCombinedFeedsAsync(authors, language: "mixed");
+        }
+
+        public async ValueTask LoadFeedAsync()
+        {
+            var authors = await this.authorBroker.GetAllAuthorsAsync();
+
+            this.loggingBroker.LogInformation($"Found {authors.Count()} author(s) globally...");
+
+            var languages = authors.Select(author => author.FeedLanguageCode).Distinct().ToList();
+
+            this.loggingBroker.LogInformation($"Available languages: {string.Join(",", languages)}.");
+
+            foreach (var language in languages)
+            {
+                var languageAuthors = authors.Where(author =>
+                    author.FeedLanguageCode == language);
+
+                this.loggingBroker.LogInformation($"{authors.Count()} author(s) are writing in '{language}'...");
+
+                var feed = await GetCombinedFeedsAsync(languageAuthors, language);
+
+                var content = await this.serializationBroker.SerializeFeedAsync(feed);
+
+                this.loggingBroker.LogInformation($"Blob for '{language}' is uploading...");
+
+                await this.storageBroker.UploadBlobAsync(language, content);
+
+                this.loggingBroker.LogInformation($"Blob for '{language}' feed was uploaded successfully.");
+            }
+        }
+
+        public async ValueTask<SyndicationFeed> RetrieveFeedAsync(string language)
+        {
+            var content = await this.storageBroker.ReadBlobAsync(language);
+
+            return this.serializationBroker.DeserializeFeed(content);
+        }
+
+        private async ValueTask<SyndicationFeed> GetCombinedFeedsAsync(
+            IEnumerable<Author> authors,
+            string language)
+        {
             var feedItems = new List<SyndicationItem>();
 
             foreach (var author in authors)
             {
                 foreach (var feedUri in author.FeedUris)
                 {
-                    var feed = await this.feedBroker.ReadFeedAsync(feedUri.AbsoluteUri);
-
-                    feedItems.AddRange(feed.Items);
+                    try
+                    {
+                        var feed = await this.feedBroker.ReadFeedAsync(feedUri.AbsoluteUri);
+
+                        feedItems.AddRange(feed.Items);
+                    }
+                    catch (Exception ex)
+                    {
+                        this.loggingBroker.LogError(ex);
+                    }
                 }
             }
 
-            return CreateCombinedFeed(
+            return CreateFeedInstance(
                 items: feedItems,
-                lastUpdate: this.dateTimeBroker.GetCurrentDateTimeOffset());
+                lastUpdate: this.dateTimeBroker.GetCurrentDateTimeOffset(),
+                constributers: authors,
+                languageCode: language);
         }
 
-        private static SyndicationFeed CreateCombinedFeed(
+        private static SyndicationFeed CreateFeedInstance(
             List<SyndicationItem> items,
             DateTimeOffset lastUpdate,
+            IEnumerable<Author> constributers,
             string languageCode = "mixed")
         {
             var rssFeedTitle = Environment.GetEnvironmentVariable(
@@ -92,7 +156,18 @@ private static SyndicationFeed CreateCombinedFeed(
             feed.Language = languageCode;
             feed.LastUpdatedTime = lastUpdate;
 
+            foreach (var constributer in constributers)
+            {
+                var item = new SyndicationPerson(
+                    email: constributer.EmailAddress,
+                    name: $"{constributer.FirstName} {constributer.LastName}",
+                    uri: constributer.WebSite.ToString());
+
+                feed.Contributors.Add(item);
+            }
+
             return feed;
         }
+
     }
 }
diff --git a/PlanetDotnet/Services/Feeds/IFeedService.cs b/PlanetDotnet/Services/Feeds/IFeedService.cs
index bdc8eb1..df30fe1 100644
--- a/PlanetDotnet/Services/Feeds/IFeedService.cs
+++ b/PlanetDotnet/Services/Feeds/IFeedService.cs
@@ -11,7 +11,8 @@ namespace PlanetDotnet.Services.Feeds
 {
     public interface IFeedService
     {
-        ValueTask<SyndicationFeed> CombineFeedsAsync();
-        ValueTask<SyndicationFeed> CombineFeedsAsync();
+        ValueTask<SyndicationFeed> GetMixedFeedAsync();
+        ValueTask LoadFeedAsync();
+        ValueTask<SyndicationFeed> RetrieveFeedAsync(string language); 
     }
 }
diff --git a/PlanetDotnet/Startup.cs b/PlanetDotnet/Startup.cs
index eca6692..4c615ee 100644
--- a/PlanetDotnet/Startup.cs
+++ b/PlanetDotnet/Startup.cs
@@ -11,6 +11,8 @@
 using PlanetDotnet.Brokers.DateTimes;
 using PlanetDotnet.Brokers.Feeds;
 using PlanetDotnet.Brokers.Loggings;
+using PlanetDotnet.Brokers.Serializations;
+using PlanetDotnet.Brokers.Storages;
 using PlanetDotnet.Services.Feeds;
 
 [assembly: FunctionsStartup(typeof(PlanetDotnet.Startup))]
@@ -20,9 +22,12 @@ public class Startup : FunctionsStartup
     {
         public override void Configure(IFunctionsHostBuilder builder)
         {
-            builder.Services.AddScoped<ILogger, Logger<LoggingBroker>>();
+            builder.Services.AddLogging();
+            builder.Services.AddScoped<ILogger<LoggingBroker>, Logger<LoggingBroker>>();
             builder.Services.AddScoped<ILoggingBroker, LoggingBroker>();
             builder.Services.AddScoped<IDateTimeBroker, DateTimeBroker>();
+            builder.Services.AddScoped<ISerializationBroker, SerializationBroker>();
+            builder.Services.AddScoped<IStorageBroker, StorageBroker>();
             builder.Services.AddScoped<IAuthorBroker, AuthorBroker>();
             builder.Services.AddScoped<IFeedBroker, FeedBroker>();
             builder.Services.AddScoped<IFeedService, FeedService>();
diff --git a/PlanetDotnet/host.json b/PlanetDotnet/host.json
index ee5cf5f..24ef1a8 100644
--- a/PlanetDotnet/host.json
+++ b/PlanetDotnet/host.json
@@ -1,12 +1,15 @@
 {
-    "version": "2.0",
-    "logging": {
-        "applicationInsights": {
-            "samplingSettings": {
-                "isEnabled": true,
-                "excludedTypes": "Request"
-            },
-            "enableLiveMetricsFilters": true
-        }
+  "version": "2.0",
+  "logging": {
+    "applicationInsights": {
+      "samplingSettings": {
+        "isEnabled": true,
+        "excludedTypes": "Request"
+      },
+      "enableLiveMetricsFilters": true
     }
+  },
+  "logLevel": {
+    "PlanetDotnet.Brokers.Loggings.LoggingBroker": "Information"
+  }
 }
\ No newline at end of file

From db036a5f438f490cd26b4398165cb01cabacedcc Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Wed, 29 Nov 2023 00:10:15 +0100
Subject: [PATCH 12/18] FOUNDATIONS: Combined Feed

---
 PlanetDotnet/Brokers/Feeds/FeedBroker.cs      |  10 +-
 PlanetDotnet/Brokers/Feeds/IFeedBroker.cs     |   2 +-
 .../Brokers/Loggings/ILoggingBroker.cs        |   7 +
 .../Brokers/Loggings/LoggingBroker.cs         |   9 +
 .../Brokers/Storages/IStorageBroker.cs        |   1 +
 .../Brokers/Storages/StorageBroker.cs         |   9 +-
 .../Extensions/ExceptionExtensions.cs         |  23 ++
 .../Infrastructure/CombinedFeedSource.cs      | 219 ------------------
 PlanetDotnet/LoadFeedsFunction.cs             | 105 ++++++++-
 .../Feeds/Exceptions/FailedFeedException.cs   |  21 ++
 .../CombinedFeeds/CombinedFeedService.cs      | 213 +++++++++++++++++
 .../ICombinedFeedService.cs}                  |   8 +-
 PlanetDotnet/Services/Feeds/FeedService.cs    | 173 --------------
 PlanetDotnet/Startup.cs                       |   4 +-
 PlanetDotnet/host.json                        |   6 +-
 15 files changed, 396 insertions(+), 414 deletions(-)
 create mode 100644 PlanetDotnet/Extensions/ExceptionExtensions.cs
 delete mode 100644 PlanetDotnet/Infrastructure/CombinedFeedSource.cs
 create mode 100644 PlanetDotnet/Models/Feeds/Exceptions/FailedFeedException.cs
 create mode 100644 PlanetDotnet/Services/CombinedFeeds/CombinedFeedService.cs
 rename PlanetDotnet/Services/{Feeds/IFeedService.cs => CombinedFeeds/ICombinedFeedService.cs} (61%)
 delete mode 100644 PlanetDotnet/Services/Feeds/FeedService.cs

diff --git a/PlanetDotnet/Brokers/Feeds/FeedBroker.cs b/PlanetDotnet/Brokers/Feeds/FeedBroker.cs
index d05fc13..94ad3c9 100644
--- a/PlanetDotnet/Brokers/Feeds/FeedBroker.cs
+++ b/PlanetDotnet/Brokers/Feeds/FeedBroker.cs
@@ -18,11 +18,17 @@ internal class FeedBroker : IFeedBroker
         public FeedBroker(HttpClient httpClient) =>
             this.httpClient = httpClient;
 
-        public async ValueTask<SyndicationFeed> ReadFeedAsync(string feedUri)
+        public async Task<SyndicationFeed> ReadFeedAsync(string feedUri)
         {
             var response = await httpClient.GetAsync(feedUri).ConfigureAwait(false);
             using var feedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
-            using var reader = XmlReader.Create(feedStream);
+
+            var settings = new XmlReaderSettings
+            {
+                DtdProcessing = DtdProcessing.Parse
+            };
+
+            using var reader = XmlReader.Create(feedStream, settings);
             var feed = SyndicationFeed.Load(reader);
 
             return feed;
diff --git a/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs b/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs
index aa48450..8da0272 100644
--- a/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs
+++ b/PlanetDotnet/Brokers/Feeds/IFeedBroker.cs
@@ -11,6 +11,6 @@ namespace PlanetDotnet.Brokers.Feeds
 {
     public interface IFeedBroker
     {
-        ValueTask<SyndicationFeed> ReadFeedAsync(string feedUri);
+        Task<SyndicationFeed> ReadFeedAsync(string feedUri);
     }
 }
diff --git a/PlanetDotnet/Brokers/Loggings/ILoggingBroker.cs b/PlanetDotnet/Brokers/Loggings/ILoggingBroker.cs
index bb02432..485f6a2 100644
--- a/PlanetDotnet/Brokers/Loggings/ILoggingBroker.cs
+++ b/PlanetDotnet/Brokers/Loggings/ILoggingBroker.cs
@@ -1,3 +1,9 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
 using System;
 
 namespace PlanetDotnet.Brokers.Loggings
@@ -9,6 +15,7 @@ public interface ILoggingBroker
         void LogDebug(string message);
         void LogWarning(string message);
         void LogError(Exception exception);
+        void LogError(Exception exception, string message);
         void LogCritical(Exception exception);
     }
 }
diff --git a/PlanetDotnet/Brokers/Loggings/LoggingBroker.cs b/PlanetDotnet/Brokers/Loggings/LoggingBroker.cs
index d5a6695..5dd375e 100644
--- a/PlanetDotnet/Brokers/Loggings/LoggingBroker.cs
+++ b/PlanetDotnet/Brokers/Loggings/LoggingBroker.cs
@@ -1,3 +1,9 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
 using System;
 using Microsoft.Extensions.Logging;
 
@@ -25,6 +31,9 @@ public void LogWarning(string message) =>
         public void LogError(Exception exception) =>
             this.logger.LogError(exception.Message, exception);
 
+        public void LogError(Exception exception, string message) =>
+            this.logger.LogError(exception, message);
+
         public void LogCritical(Exception exception) =>
             this.logger.LogCritical(exception, exception.Message);
     }
diff --git a/PlanetDotnet/Brokers/Storages/IStorageBroker.cs b/PlanetDotnet/Brokers/Storages/IStorageBroker.cs
index 6294a48..d52d8d4 100644
--- a/PlanetDotnet/Brokers/Storages/IStorageBroker.cs
+++ b/PlanetDotnet/Brokers/Storages/IStorageBroker.cs
@@ -11,6 +11,7 @@ namespace PlanetDotnet.Brokers.Storages
 {
     public interface IStorageBroker
     {
+        ValueTask InitializeAsync();
         ValueTask UploadBlobAsync(string language, Stream content);
         ValueTask<Stream> ReadBlobAsync(string language);
     }
diff --git a/PlanetDotnet/Brokers/Storages/StorageBroker.cs b/PlanetDotnet/Brokers/Storages/StorageBroker.cs
index b2bc85a..19424d9 100644
--- a/PlanetDotnet/Brokers/Storages/StorageBroker.cs
+++ b/PlanetDotnet/Brokers/Storages/StorageBroker.cs
@@ -8,6 +8,7 @@
 using System.IO;
 using System.Threading.Tasks;
 using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
 
 namespace PlanetDotnet.Brokers.Storages
 {
@@ -16,7 +17,7 @@ public class StorageBroker : IStorageBroker
         private readonly BlobContainerClient blobContainerClient;
         private const string BlobContainerName = "feeds";
         private const string FeedBlobStorageKey = "FeedBlobStorage";
-        private const string BlobName = "newfeed.{0}.rss";
+        private const string BlobName = "feed.{0}.rss";
 
         public StorageBroker()
         {
@@ -29,6 +30,12 @@ public StorageBroker()
                 blobContainerName: BlobContainerName);
         }
 
+        public async ValueTask InitializeAsync()
+        {
+            await this.blobContainerClient.CreateIfNotExistsAsync();
+            await this.blobContainerClient.SetAccessPolicyAsync(PublicAccessType.Blob);
+        }
+
         public async ValueTask UploadBlobAsync(string language, Stream content)
         {
             var blobName = string.Format(BlobName, language);
diff --git a/PlanetDotnet/Extensions/ExceptionExtensions.cs b/PlanetDotnet/Extensions/ExceptionExtensions.cs
new file mode 100644
index 0000000..5ce0dbc
--- /dev/null
+++ b/PlanetDotnet/Extensions/ExceptionExtensions.cs
@@ -0,0 +1,23 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+
+namespace PlanetDotnet.Extensions
+{
+    internal static class ExceptionExtensions
+    {
+        public static TException WithData<TException>(
+            this TException exception, 
+            string key, 
+            object value) 
+            where TException : Exception
+        {
+            exception.Data[key] = value;
+            return exception;
+        }
+    }
+}
diff --git a/PlanetDotnet/Infrastructure/CombinedFeedSource.cs b/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
deleted file mode 100644
index 3b9d9e3..0000000
--- a/PlanetDotnet/Infrastructure/CombinedFeedSource.cs
+++ /dev/null
@@ -1,219 +0,0 @@
-// ---------------------------------------------------------------
-// Copyright (c) 2023 Planet Dotnet. All rights reserved.
-// Licensed under the MIT License.
-// See License.txt in the project root for license information.
-// ---------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.ServiceModel.Syndication;
-using System.Threading.Tasks;
-using System.Xml;
-using Microsoft.Extensions.Logging;
-using PlanetDotnet.Authors.Models.Authors;
-using PlanetDotnet.Extensions;
-using Polly;
-using Polly.Retry;
-
-namespace PlanetDotnet.Infrastructure
-{
-    public class CombinedFeedSource
-    {
-        private static HttpClient _httpClient;
-        private static AsyncRetryPolicy _retryPolicy;
-        private readonly IEnumerable<Author> _authors;
-        private readonly ILogger _logger;
-        private readonly string _rssFeedTitle;
-        private readonly string _rssFeedDescription;
-        private readonly string _rssFeedUrl;
-        private readonly string _rssFeedImageUrl;
-
-        public CombinedFeedSource(
-            IEnumerable<Author> authors,
-            ILogger logger,
-            string rssFeedTitle,
-            string rssFeedDescription,
-            string rssFeedUrl,
-            string rssFeedImageUrl)
-        {
-            EnsureHttpClient();
-
-            if (_retryPolicy == null)
-            {
-                // retry policy with max 2 retries, delay by x*x^1.2 where x is retry attempt
-                // this will ensure we don't retry too quickly
-                _retryPolicy = Policy.Handle<FeedReadFailedException>()
-                    .WaitAndRetryAsync(2, retry => TimeSpan.FromSeconds(retry * Math.Pow(1.2, retry)));
-            }
-
-            _authors = authors;
-            _logger = logger;
-            _rssFeedTitle = rssFeedTitle;
-            _rssFeedDescription = rssFeedDescription;
-            _rssFeedUrl = rssFeedUrl;
-            _rssFeedImageUrl = rssFeedImageUrl;
-        }
-
-        private void EnsureHttpClient()
-        {
-            if (_httpClient == null)
-            {
-                _httpClient = new HttpClient();
-                _httpClient.DefaultRequestHeaders.UserAgent.Add(
-                    new ProductInfoHeaderValue("PlanetDotnet", $"{GetType().Assembly.GetName().Version}"));
-                _httpClient.Timeout = TimeSpan.FromSeconds(15);
-
-                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
-            }
-        }
-
-        public async Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageCode = "mixed")
-        {
-            IEnumerable<Author> tamarins;
-            if (languageCode == null || languageCode == "mixed") // use all tamarins
-            {
-                tamarins = _authors;
-            }
-            else
-            {
-                tamarins = _authors.Where(t => t.FeedLanguageCode == languageCode);
-            }
-
-            var feedTasks = tamarins.SelectMany(t => TryReadFeeds(t)).ToArray();
-
-            _logger?.LogInformation($"Loading feed for language: {languageCode} for {feedTasks.Length} authors");
-
-            var syndicationItems = await Task.WhenAll(feedTasks).ConfigureAwait(false);
-            var combinedFeed = GetCombinedFeed(syndicationItems.SelectMany(f => f), languageCode, tamarins, numberOfItems);
-            return combinedFeed;
-        }
-
-        private IEnumerable<Task<IEnumerable<SyndicationItem>>> TryReadFeeds(Author tamarin)
-        {
-            return tamarin.FeedUris.Select(uri => TryReadFeed(tamarin, uri.AbsoluteUri));
-        }
-
-        private async Task<IEnumerable<SyndicationItem>> TryReadFeed(Author tamarin, string feedUri)
-        {
-            try
-            {
-                return await _retryPolicy.ExecuteAsync(context => ReadFeed(feedUri), new Context(feedUri)).ConfigureAwait(false);
-            }
-            catch (FeedReadFailedException ex)
-            {
-                _logger.LogError(ex, $"{tamarin.FirstName} {tamarin.LastName}'s feed of {ex.Data["FeedUri"]} failed to load.");
-            }
-
-            return new SyndicationItem[0];
-        }
-
-        private async Task<IEnumerable<SyndicationItem>> ReadFeed(string feedUri)
-        {
-            HttpResponseMessage response;
-            try
-            {
-                _logger?.LogInformation($"Loading feed {feedUri}");
-                response = await _httpClient.GetAsync(feedUri).ConfigureAwait(false);
-                if (response.IsSuccessStatusCode)
-                {
-                    using var feedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
-                    using var reader = XmlReader.Create(feedStream);
-                    var feed = SyndicationFeed.Load(reader);
-                    var filteredItems = feed.Items
-                        .Where(item => item.ApplyDefaultFilter());
-
-                    return filteredItems;
-                }
-            }
-            catch (HttpRequestException hex)
-            {
-                throw new FeedReadFailedException("Loading remote syndication feed failed", hex)
-                    .WithData("FeedUri", feedUri);
-            }
-            catch (WebException ex)
-            {
-                throw new FeedReadFailedException("Loading remote syndication feed timed out", ex)
-                    .WithData("FeedUri", feedUri);
-            }
-            catch (XmlException ex)
-            {
-                throw new FeedReadFailedException("Failed parsing remote syndication feed", ex)
-                    .WithData("FeedUri", feedUri);
-            }
-            catch (TaskCanceledException ex)
-            {
-                throw new FeedReadFailedException("Reading feed timed out", ex)
-                    .WithData("FeedUri", feedUri);
-            }
-            catch (OperationCanceledException opcex)
-            {
-                throw new FeedReadFailedException("Reading feed timed out", opcex)
-                    .WithData("FeedUri", feedUri);
-            }
-
-            throw new FeedReadFailedException("Loading remote syndication feed failed.")
-                .WithData("FeedUri", feedUri)
-                .WithData("HttpStatusCode", (int)response.StatusCode);
-        }
-
-        private SyndicationFeed GetCombinedFeed(IEnumerable<SyndicationItem> items, string languageCode,
-            IEnumerable<Author> tamarins, int? numberOfItems)
-        {
-            DateTimeOffset GetMaxTime(SyndicationItem item)
-            {
-                return new[] { item.PublishDate.UtcDateTime, item.LastUpdatedTime.UtcDateTime }.Max();
-            }
-
-            var orderedItems = items
-                .Where(item =>
-                    GetMaxTime(item) <= DateTimeOffset.UtcNow)
-                .OrderByDescending(item => GetMaxTime(item));
-
-            var feed = new SyndicationFeed(
-                _rssFeedTitle,
-                _rssFeedDescription,
-                new Uri(_rssFeedUrl),
-                numberOfItems.HasValue ? orderedItems.Take(numberOfItems.Value) : orderedItems)
-            {
-                ImageUrl = new Uri(_rssFeedImageUrl),
-                Copyright = new TextSyndicationContent("The copyright for each post is retained by its author."),
-                Language = languageCode,
-                LastUpdatedTime = DateTimeOffset.UtcNow
-            };
-
-            foreach (var tamarin in tamarins)
-            {
-                feed.Contributors.Add(new SyndicationPerson(
-                    tamarin.EmailAddress, $"{tamarin.FirstName} {tamarin.LastName}", tamarin.WebSite.ToString()));
-            }
-
-            return feed;
-        }
-    }
-
-    public class FeedReadFailedException : Exception
-    {
-        public FeedReadFailedException(string message)
-            : base(message)
-        {
-        }
-
-        public FeedReadFailedException(string message, Exception inner)
-            : base(message, inner)
-        {
-        }
-    }
-
-    internal static class ExceptionExtensions
-    {
-        public static TException WithData<TException>(this TException exception, string key, object value) where TException : Exception
-        {
-            exception.Data[key] = value;
-            return exception;
-        }
-    }
-}
diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
index 9abc778..3aab4ee 100644
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -5,24 +5,35 @@
 // ---------------------------------------------------------------
 
 using System;
+using System.Globalization;
+using System.IO;
 using System.Linq;
+using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
-using Azure.Storage.Blobs;
-using Azure.Storage.Blobs.Models;
+using System.Xml;
 using Microsoft.Azure.WebJobs;
 using Microsoft.Extensions.Logging;
-using PlanetDotnet.Authors.Services;
-using PlanetDotnet.Infrastructure;
-using PlanetDotnet.Services.Feeds;
+using PlanetDotnet.Brokers.Authors;
+using PlanetDotnet.Brokers.Storages;
+using PlanetDotnet.Services.CombinedFeeds;
 
 namespace PlanetDotnet
 {
     public class LoadFeedsFunction
     {
-        private readonly IFeedService feedService;
+        private readonly ICombinedFeedService feedService;
+        private readonly IStorageBroker storageBroker;
+        private readonly IAuthorBroker authorBroker;
 
-        public LoadFeedsFunction(IFeedService feedService) =>
+        public LoadFeedsFunction(
+            ICombinedFeedService feedService,
+            IStorageBroker storageBroker,
+            IAuthorBroker authorBroker)
+        {
             this.feedService = feedService;
+            this.storageBroker = storageBroker;
+            this.authorBroker = authorBroker;
+        }
 
         [FunctionName("LoadFeedsFunction")]
         public async Task Run(
@@ -31,9 +42,87 @@ public async Task Run(
         {
             log.LogInformation($"Load feeds Timer trigger function executed at: {DateTime.Now}");
 
-            await this.feedService.LoadFeedAsync();
+            try
+            {
+                await this.storageBroker.InitializeAsync();
+
+                var authors = await this.authorBroker.GetAllAuthorsAsync();
+
+                var languages = authors.Select(author => author.FeedLanguageCode).Distinct().ToList();
+
+                var mainCulture = CultureInfo.CurrentCulture;
 
+                foreach (var language in languages)
+                {
+                    try
+                    {
+                        CultureInfo.CurrentCulture = new CultureInfo(language);
+                        log.LogInformation($"Loading {language} combined author feed");
+                        var feed = await feedService.LoadFeed(null, language);
+                        using var stream = await SerializeFeed(feed);
+                        await this.storageBroker.UploadBlobAsync(language, stream);
+                    }
+                    catch (Exception ex)
+                    {
+                        log.LogError(ex, "error");
+                    }
+                }
+
+                CultureInfo.CurrentCulture = mainCulture;
+            }
+            catch (Exception ex)
+            {
+                log.LogError(ex, "error");
+            }
             log.LogInformation($"Load feeds Finished at: {DateTime.Now}");
         }
+
+        private static async Task<Stream> SerializeFeed(SyndicationFeed feed)
+        {
+            FixInvalidLastUpdatedTime(feed);
+
+            var memoryStream = new MemoryStream();
+            using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
+            {
+                Async = true
+            });
+
+            var rssFormatter = new Rss20FeedFormatter(feed);
+            rssFormatter.WriteTo(xmlWriter);
+            await xmlWriter.FlushAsync();
+
+            memoryStream.Seek(0, SeekOrigin.Begin);
+
+            return memoryStream;
+        }
+
+        private static void FixInvalidLastUpdatedTime(SyndicationFeed feed)
+        {
+            foreach (var item in feed.Items)
+            {
+                // Check if both PublishDate and LastUpdatedTime are invalid
+                if (item.PublishDate == DateTimeOffset.MinValue && item.LastUpdatedTime == DateTimeOffset.MinValue)
+                {
+                    item.PublishDate = DateTimeOffset.UtcNow;
+                    item.LastUpdatedTime = DateTimeOffset.UtcNow;
+                }
+                else
+                {
+                    // If only PublishDate is invalid, set it to LastUpdatedTime
+                    if (item.PublishDate == DateTimeOffset.MinValue)
+                    {
+                        item.PublishDate = item.LastUpdatedTime;
+                    }
+
+                    // If only LastUpdatedTime is invalid, set it to PublishDate
+                    if (item.LastUpdatedTime == DateTimeOffset.MinValue)
+                    {
+                        item.LastUpdatedTime = item.PublishDate;
+                    }
+                }
+            }
+        }
+
     }
+
 }
diff --git a/PlanetDotnet/Models/Feeds/Exceptions/FailedFeedException.cs b/PlanetDotnet/Models/Feeds/Exceptions/FailedFeedException.cs
new file mode 100644
index 0000000..0bf9409
--- /dev/null
+++ b/PlanetDotnet/Models/Feeds/Exceptions/FailedFeedException.cs
@@ -0,0 +1,21 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+
+namespace PlanetDotnet.Models.Feeds.Exceptions
+{
+    public class FailedFeedException : Exception
+    {
+        public FailedFeedException(string message)
+            : base(message)
+        { }
+
+        public FailedFeedException(string message, Exception inner)
+            : base(message, inner)
+        { }
+    }
+}
diff --git a/PlanetDotnet/Services/CombinedFeeds/CombinedFeedService.cs b/PlanetDotnet/Services/CombinedFeeds/CombinedFeedService.cs
new file mode 100644
index 0000000..f7789e0
--- /dev/null
+++ b/PlanetDotnet/Services/CombinedFeeds/CombinedFeedService.cs
@@ -0,0 +1,213 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.ServiceModel.Syndication;
+using System.Threading.Tasks;
+using System.Xml;
+using PlanetDotnet.Authors.Models.Authors;
+using PlanetDotnet.Brokers.Authors;
+using PlanetDotnet.Brokers.Loggings;
+using PlanetDotnet.Extensions;
+using PlanetDotnet.Models.Feeds.Exceptions;
+using Polly;
+using Polly.Retry;
+
+namespace PlanetDotnet.Services.CombinedFeeds
+{
+    public class CombinedFeedService : ICombinedFeedService
+    {
+        private readonly HttpClient httpClient;
+        private readonly AsyncRetryPolicy _retryPolicy;
+        private readonly IAuthorBroker authorBroker;
+        private readonly ILoggingBroker loggingBroker;
+
+        private const string RssFeedTitleKey = "RssFeedTitle";
+        private const string RssFeedDescriptionKey = "RssFeedDescription";
+        private const string RssFeedUrlKey = "RssFeedUrl";
+        private const string RssFeedImageUrlKey = "RssFeedImageUrl";
+
+        public CombinedFeedService(
+            IAuthorBroker authorBroker,
+            ILoggingBroker loggingBroker,
+            HttpClient httpClient)
+        {
+            this.httpClient = httpClient;
+            EnsureHttpClient();
+
+            _retryPolicy ??= Policy.Handle<FailedFeedException>()
+                .WaitAndRetryAsync(2, retry => TimeSpan.FromSeconds(retry * Math.Pow(1.2, retry)));
+
+            this.authorBroker = authorBroker;
+            this.loggingBroker = loggingBroker;
+        }
+
+        private void EnsureHttpClient()
+        {
+            this.httpClient.DefaultRequestHeaders.UserAgent.Add(
+                new ProductInfoHeaderValue("PlanetDotnet", $"{GetType().Assembly.GetName().Version}"));
+
+            this.httpClient.Timeout = TimeSpan.FromSeconds(15);
+
+            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
+        }
+
+        public async Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageCode = "mixed")
+        {
+            var authors = await this.authorBroker.GetAllAuthorsAsync();
+
+            IEnumerable<Author> languageAuthors;
+            if (languageCode == null || languageCode == "mixed") // use all tamarins
+            {
+                languageAuthors = authors;
+            }
+            else
+            {
+                languageAuthors = authors.Where(t => t.FeedLanguageCode == languageCode);
+            }
+
+            var feedTasks = languageAuthors.SelectMany(t => TryReadFeeds(t)).ToArray();
+
+            this.loggingBroker.LogInformation($"Loading feed for language: {languageCode} for {feedTasks.Length} authors");
+
+            var syndicationItems = await Task.WhenAll(feedTasks).ConfigureAwait(false);
+            var combinedFeed = GetCombinedFeed(syndicationItems.SelectMany(f => f), languageCode, languageAuthors, numberOfItems);
+            return combinedFeed;
+        }
+
+        private IEnumerable<Task<IEnumerable<SyndicationItem>>> TryReadFeeds(Author tamarin)
+        {
+            return tamarin.FeedUris.Select(uri => TryReadFeed(tamarin, uri.AbsoluteUri));
+        }
+
+        private async Task<IEnumerable<SyndicationItem>> TryReadFeed(Author tamarin, string feedUri)
+        {
+            try
+            {
+                return await _retryPolicy.ExecuteAsync(context => ReadFeed(feedUri), new Context(feedUri)).ConfigureAwait(false);
+            }
+            catch (FailedFeedException ex)
+            {
+                this.loggingBroker.LogError(ex, $"{tamarin.FirstName} {tamarin.LastName}'s feed of {ex.Data["FeedUri"]} failed to load.");
+            }
+
+            return Array.Empty<SyndicationItem>();
+        }
+
+        private async Task<IEnumerable<SyndicationItem>> ReadFeed(string feedUri)
+        {
+            HttpResponseMessage response;
+            try
+            {
+                this.loggingBroker.LogInformation($"Loading feed {feedUri}");
+
+                response = await httpClient.GetAsync(feedUri).ConfigureAwait(false);
+
+                if (response.IsSuccessStatusCode)
+                {
+                    using var feedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+                    using var reader = XmlReader.Create(feedStream);
+                    var feed = SyndicationFeed.Load(reader);
+                    var filteredItems = feed.Items;
+
+                    return filteredItems;
+                }
+            }
+            catch (HttpRequestException hex)
+            {
+                throw new FailedFeedException("Loading remote syndication feed failed", hex)
+                    .WithData("FeedUri", feedUri);
+            }
+            catch (WebException ex)
+            {
+                throw new FailedFeedException("Loading remote syndication feed timed out", ex)
+                    .WithData("FeedUri", feedUri);
+            }
+            catch (XmlException ex)
+            {
+                throw new FailedFeedException("Failed parsing remote syndication feed", ex)
+                    .WithData("FeedUri", feedUri);
+            }
+            catch (TaskCanceledException ex)
+            {
+                throw new FailedFeedException("Reading feed timed out", ex)
+                    .WithData("FeedUri", feedUri);
+            }
+            catch (OperationCanceledException opcex)
+            {
+                throw new FailedFeedException("Reading feed timed out", opcex)
+                    .WithData("FeedUri", feedUri);
+            }
+
+            throw new FailedFeedException("Loading remote syndication feed failed.")
+                .WithData("FeedUri", feedUri)
+                .WithData("HttpStatusCode", (int)response.StatusCode);
+        }
+
+        private SyndicationFeed GetCombinedFeed(IEnumerable<SyndicationItem> items, string languageCode,
+            IEnumerable<Author> authors, int? numberOfItems)
+        {
+
+            var rssFeedTitle = Environment.GetEnvironmentVariable(
+                    variable: RssFeedTitleKey,
+                    target: EnvironmentVariableTarget.Process);
+
+            var rssFeedDescription = Environment.GetEnvironmentVariable(
+                 variable: RssFeedDescriptionKey,
+                 target: EnvironmentVariableTarget.Process);
+
+            var rssFeedUrl = Environment.GetEnvironmentVariable(
+                variable: RssFeedUrlKey,
+                target: EnvironmentVariableTarget.Process);
+
+            var rssFeedImageUrl = Environment.GetEnvironmentVariable(
+                variable: RssFeedImageUrlKey,
+                target: EnvironmentVariableTarget.Process);
+
+            var orderedItems = items
+                .Where(item =>
+                    GetMaxTime(item) <= DateTimeOffset.UtcNow)
+                .OrderByDescending(item => GetMaxTime(item));
+
+            var feed = new SyndicationFeed(
+               rssFeedTitle,
+               rssFeedDescription,
+                new Uri(rssFeedUrl),
+                numberOfItems.HasValue ? orderedItems.Take(numberOfItems.Value) : orderedItems)
+            {
+                ImageUrl = new Uri(rssFeedImageUrl),
+                Copyright = new TextSyndicationContent("The copyright for each post is retained by its author."),
+                Language = languageCode,
+                LastUpdatedTime = DateTimeOffset.UtcNow
+            };
+
+            foreach (var author in authors)
+            {
+                feed.Contributors.Add(new SyndicationPerson(
+                    author.EmailAddress, $"{author.FirstName} {author.LastName}", author.WebSite.ToString()));
+            }
+
+            return feed;
+        }
+
+        private static DateTimeOffset GetMaxTime(SyndicationItem item)
+        {
+            try
+            {
+                return new[] { item.PublishDate.UtcDateTime, item.LastUpdatedTime.UtcDateTime }.Max();
+            }
+            catch
+            {
+                return item.PublishDate.UtcDateTime;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/PlanetDotnet/Services/Feeds/IFeedService.cs b/PlanetDotnet/Services/CombinedFeeds/ICombinedFeedService.cs
similarity index 61%
rename from PlanetDotnet/Services/Feeds/IFeedService.cs
rename to PlanetDotnet/Services/CombinedFeeds/ICombinedFeedService.cs
index df30fe1..9d04163 100644
--- a/PlanetDotnet/Services/Feeds/IFeedService.cs
+++ b/PlanetDotnet/Services/CombinedFeeds/ICombinedFeedService.cs
@@ -7,12 +7,10 @@
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
 
-namespace PlanetDotnet.Services.Feeds
+namespace PlanetDotnet.Services.CombinedFeeds
 {
-    public interface IFeedService
+    public interface ICombinedFeedService
     {
-        ValueTask<SyndicationFeed> GetMixedFeedAsync();
-        ValueTask LoadFeedAsync();
-        ValueTask<SyndicationFeed> RetrieveFeedAsync(string language); 
+        Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageCode = "mixed");
     }
 }
diff --git a/PlanetDotnet/Services/Feeds/FeedService.cs b/PlanetDotnet/Services/Feeds/FeedService.cs
deleted file mode 100644
index b479100..0000000
--- a/PlanetDotnet/Services/Feeds/FeedService.cs
+++ /dev/null
@@ -1,173 +0,0 @@
-// ---------------------------------------------------------------
-// Copyright (c) 2023 Planet Dotnet. All rights reserved.
-// Licensed under the MIT License.
-// See License.txt in the project root for license information.
-// ---------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.ServiceModel.Syndication;
-using System.Threading.Tasks;
-using PlanetDotnet.Authors.Models.Authors;
-using PlanetDotnet.Brokers.Authors;
-using PlanetDotnet.Brokers.DateTimes;
-using PlanetDotnet.Brokers.Feeds;
-using PlanetDotnet.Brokers.Loggings;
-using PlanetDotnet.Brokers.Serializations;
-using PlanetDotnet.Brokers.Storages;
-
-namespace PlanetDotnet.Services.Feeds
-{
-    internal partial class FeedService : IFeedService
-    {
-        private readonly IFeedBroker feedBroker;
-        private readonly IAuthorBroker authorBroker;
-        private readonly IDateTimeBroker dateTimeBroker;
-        private readonly ILoggingBroker loggingBroker;
-        private readonly ISerializationBroker serializationBroker;
-        private readonly IStorageBroker storageBroker;
-
-        private const string RssFeedTitleKey = "RssFeedTitle";
-        private const string RssFeedDescriptionKey = "RssFeedDescription";
-        private const string RssFeedUrlKey = "RssFeedUrl";
-        private const string RssFeedImageUrlKey = "RssFeedImageUrl";
-
-        public FeedService(
-            IFeedBroker feedBroker,
-            IAuthorBroker authorBroker,
-            IDateTimeBroker dateTimeBroker,
-            ILoggingBroker loggingBroker,
-            ISerializationBroker serializationBroker,
-            IStorageBroker storageBroker)
-        {
-            this.feedBroker = feedBroker;
-            this.authorBroker = authorBroker;
-            this.dateTimeBroker = dateTimeBroker;
-            this.loggingBroker = loggingBroker;
-            this.serializationBroker = serializationBroker;
-            this.storageBroker = storageBroker;
-        }
-
-        public async ValueTask<SyndicationFeed> GetMixedFeedAsync()
-        {
-            var authors = await this.authorBroker.GetAllAuthorsAsync();
-
-            return await GetCombinedFeedsAsync(authors, language: "mixed");
-        }
-
-        public async ValueTask LoadFeedAsync()
-        {
-            var authors = await this.authorBroker.GetAllAuthorsAsync();
-
-            this.loggingBroker.LogInformation($"Found {authors.Count()} author(s) globally...");
-
-            var languages = authors.Select(author => author.FeedLanguageCode).Distinct().ToList();
-
-            this.loggingBroker.LogInformation($"Available languages: {string.Join(",", languages)}.");
-
-            foreach (var language in languages)
-            {
-                var languageAuthors = authors.Where(author =>
-                    author.FeedLanguageCode == language);
-
-                this.loggingBroker.LogInformation($"{authors.Count()} author(s) are writing in '{language}'...");
-
-                var feed = await GetCombinedFeedsAsync(languageAuthors, language);
-
-                var content = await this.serializationBroker.SerializeFeedAsync(feed);
-
-                this.loggingBroker.LogInformation($"Blob for '{language}' is uploading...");
-
-                await this.storageBroker.UploadBlobAsync(language, content);
-
-                this.loggingBroker.LogInformation($"Blob for '{language}' feed was uploaded successfully.");
-            }
-        }
-
-        public async ValueTask<SyndicationFeed> RetrieveFeedAsync(string language)
-        {
-            var content = await this.storageBroker.ReadBlobAsync(language);
-
-            return this.serializationBroker.DeserializeFeed(content);
-        }
-
-        private async ValueTask<SyndicationFeed> GetCombinedFeedsAsync(
-            IEnumerable<Author> authors,
-            string language)
-        {
-            var feedItems = new List<SyndicationItem>();
-
-            foreach (var author in authors)
-            {
-                foreach (var feedUri in author.FeedUris)
-                {
-                    try
-                    {
-                        var feed = await this.feedBroker.ReadFeedAsync(feedUri.AbsoluteUri);
-
-                        feedItems.AddRange(feed.Items);
-                    }
-                    catch (Exception ex)
-                    {
-                        this.loggingBroker.LogError(ex);
-                    }
-                }
-            }
-
-            return CreateFeedInstance(
-                items: feedItems,
-                lastUpdate: this.dateTimeBroker.GetCurrentDateTimeOffset(),
-                constributers: authors,
-                languageCode: language);
-        }
-
-        private static SyndicationFeed CreateFeedInstance(
-            List<SyndicationItem> items,
-            DateTimeOffset lastUpdate,
-            IEnumerable<Author> constributers,
-            string languageCode = "mixed")
-        {
-            var rssFeedTitle = Environment.GetEnvironmentVariable(
-                variable: RssFeedTitleKey,
-                target: EnvironmentVariableTarget.Process);
-
-            var rssFeedDescription = Environment.GetEnvironmentVariable(
-                 variable: RssFeedDescriptionKey,
-                 target: EnvironmentVariableTarget.Process);
-
-            var rssFeedUrl = Environment.GetEnvironmentVariable(
-                variable: RssFeedUrlKey,
-                target: EnvironmentVariableTarget.Process);
-
-            var rssFeedImageUrl = Environment.GetEnvironmentVariable(
-                variable: RssFeedImageUrlKey,
-                target: EnvironmentVariableTarget.Process);
-
-            var feed = new SyndicationFeed(
-                title: rssFeedTitle,
-                description: rssFeedDescription,
-                feedAlternateLink: new Uri(rssFeedUrl),
-                items: items);
-
-            feed.ImageUrl = new Uri(rssFeedImageUrl);
-            feed.Copyright = new TextSyndicationContent("The copyright for each post is retained by its author.");
-            feed.Language = languageCode;
-            feed.LastUpdatedTime = lastUpdate;
-
-            foreach (var constributer in constributers)
-            {
-                var item = new SyndicationPerson(
-                    email: constributer.EmailAddress,
-                    name: $"{constributer.FirstName} {constributer.LastName}",
-                    uri: constributer.WebSite.ToString());
-
-                feed.Contributors.Add(item);
-            }
-
-            return feed;
-        }
-
-    }
-}
diff --git a/PlanetDotnet/Startup.cs b/PlanetDotnet/Startup.cs
index 4c615ee..bd1715d 100644
--- a/PlanetDotnet/Startup.cs
+++ b/PlanetDotnet/Startup.cs
@@ -13,7 +13,7 @@
 using PlanetDotnet.Brokers.Loggings;
 using PlanetDotnet.Brokers.Serializations;
 using PlanetDotnet.Brokers.Storages;
-using PlanetDotnet.Services.Feeds;
+using PlanetDotnet.Services.CombinedFeeds;
 
 [assembly: FunctionsStartup(typeof(PlanetDotnet.Startup))]
 namespace PlanetDotnet
@@ -30,7 +30,7 @@ public override void Configure(IFunctionsHostBuilder builder)
             builder.Services.AddScoped<IStorageBroker, StorageBroker>();
             builder.Services.AddScoped<IAuthorBroker, AuthorBroker>();
             builder.Services.AddScoped<IFeedBroker, FeedBroker>();
-            builder.Services.AddScoped<IFeedService, FeedService>();
+            builder.Services.AddScoped<ICombinedFeedService, CombinedFeedService>();
         }
     }
 }
diff --git a/PlanetDotnet/host.json b/PlanetDotnet/host.json
index 24ef1a8..fbe7613 100644
--- a/PlanetDotnet/host.json
+++ b/PlanetDotnet/host.json
@@ -7,9 +7,9 @@
         "excludedTypes": "Request"
       },
       "enableLiveMetricsFilters": true
+    },
+    "logLevel": {
+      "PlanetDotnet.Brokers.Loggings.LoggingBroker": "Information"
     }
-  },
-  "logLevel": {
-    "PlanetDotnet.Brokers.Loggings.LoggingBroker": "Information"
   }
 }
\ No newline at end of file

From 43f73e129064060ae7f82ab08f61526effc29003 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Wed, 29 Nov 2023 01:10:45 +0100
Subject: [PATCH 13/18] BROKERS: Serialize Feed

---
 .../Serializations/SerializationBroker.cs     | 42 ++++++++-
 PlanetDotnet/LoadFeedsFunction.cs             | 89 ++++++++++++-------
 .../Feeds}/CombinedFeedService.cs             | 53 ++++++-----
 .../Feeds}/ICombinedFeedService.cs            |  2 +-
 PlanetDotnet/Startup.cs                       |  2 +-
 5 files changed, 120 insertions(+), 68 deletions(-)
 rename PlanetDotnet/Services/{CombinedFeeds => Foundations/Feeds}/CombinedFeedService.cs (84%)
 rename PlanetDotnet/Services/{CombinedFeeds => Foundations/Feeds}/ICombinedFeedService.cs (91%)

diff --git a/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs b/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs
index 6a4256a..5657951 100644
--- a/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs
+++ b/PlanetDotnet/Brokers/Serializations/SerializationBroker.cs
@@ -6,6 +6,7 @@
 
 using System;
 using System.IO;
+using System.Linq;
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
 using System.Xml;
@@ -32,13 +33,46 @@ public async ValueTask<Stream> SerializeFeedAsync(SyndicationFeed feed)
             var memoryStream = new MemoryStream();
             using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
             {
-                Async = true
+                Async = true,
+                Indent = true
             });
 
-            var rssFormatter = new Rss20FeedFormatter(feed);
-            rssFormatter.WriteTo(xmlWriter);
-            await xmlWriter.FlushAsync();
+            xmlWriter.WriteStartDocument();
+            xmlWriter.WriteStartElement("rss");
+            xmlWriter.WriteAttributeString("version", "2.0");
+            xmlWriter.WriteStartElement("channel");
+            xmlWriter.WriteElementString("title", feed.Title?.Text ?? string.Empty);
+            xmlWriter.WriteElementString("link", feed.Links.FirstOrDefault()?.Uri.AbsoluteUri ?? string.Empty);
+            xmlWriter.WriteElementString("description", feed.Description?.Text ?? string.Empty);
+
+            if (feed.Language != null)
+                xmlWriter.WriteElementString("language", feed.Language);
+
+            if (feed.LastUpdatedTime != DateTimeOffset.MinValue)
+                xmlWriter.WriteElementString("lastBuildDate", feed.LastUpdatedTime.ToString("R"));
+
+            // Write items
+            foreach (var item in feed.Items)
+            {
+                xmlWriter.WriteStartElement("item");
 
+                xmlWriter.WriteElementString("title", item.Title?.Text ?? string.Empty);
+                xmlWriter.WriteElementString("link", item.Links.FirstOrDefault()?.Uri.AbsoluteUri ?? string.Empty);
+                xmlWriter.WriteElementString("description", item.Summary?.Text ?? string.Empty);
+
+                if (item.Id != null)
+                    xmlWriter.WriteElementString("guid", item.Id);
+
+                if (item.PublishDate != DateTimeOffset.MinValue)
+                    xmlWriter.WriteElementString("pubDate", item.PublishDate.ToString("R"));
+
+                xmlWriter.WriteEndElement(); // item
+            }
+
+            xmlWriter.WriteEndElement(); // channel
+            xmlWriter.WriteEndElement(); // rss
+
+            await xmlWriter.FlushAsync();
             memoryStream.Seek(0, SeekOrigin.Begin);
 
             return memoryStream;
diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
index 3aab4ee..bafc578 100644
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -15,7 +15,7 @@
 using Microsoft.Extensions.Logging;
 using PlanetDotnet.Brokers.Authors;
 using PlanetDotnet.Brokers.Storages;
-using PlanetDotnet.Services.CombinedFeeds;
+using PlanetDotnet.Services.Foundations.Feeds;
 
 namespace PlanetDotnet
 {
@@ -79,47 +79,68 @@ public async Task Run(
 
         private static async Task<Stream> SerializeFeed(SyndicationFeed feed)
         {
-            FixInvalidLastUpdatedTime(feed);
-
-            var memoryStream = new MemoryStream();
-            using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
+            try
             {
-                Async = true
-            });
 
-            var rssFormatter = new Rss20FeedFormatter(feed);
-            rssFormatter.WriteTo(xmlWriter);
-            await xmlWriter.FlushAsync();
+                var memoryStream = new MemoryStream();
+                using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
+                {
+                    Async = true,
+                    Indent = true // Makes the output XML easier to read, optional
+                });
 
-            memoryStream.Seek(0, SeekOrigin.Begin);
+                xmlWriter.WriteStartDocument();
+                xmlWriter.WriteStartElement("rss");
+                xmlWriter.WriteAttributeString("version", "2.0");
 
-            return memoryStream;
-        }
+                xmlWriter.WriteStartElement("channel");
 
-        private static void FixInvalidLastUpdatedTime(SyndicationFeed feed)
-        {
-            foreach (var item in feed.Items)
-            {
-                // Check if both PublishDate and LastUpdatedTime are invalid
-                if (item.PublishDate == DateTimeOffset.MinValue && item.LastUpdatedTime == DateTimeOffset.MinValue)
-                {
-                    item.PublishDate = DateTimeOffset.UtcNow;
-                    item.LastUpdatedTime = DateTimeOffset.UtcNow;
-                }
-                else
+                // Write channel elements
+                xmlWriter.WriteElementString("title", feed.Title?.Text ?? string.Empty);
+                xmlWriter.WriteElementString("link", feed.Links.FirstOrDefault()?.Uri.AbsoluteUri ?? string.Empty);
+                xmlWriter.WriteElementString("description", feed.Description?.Text ?? string.Empty);
+
+                // Optional channel elements (add as needed)
+                if (feed.Language != null)
+                    xmlWriter.WriteElementString("language", feed.Language);
+
+                if (feed.LastUpdatedTime != DateTimeOffset.MinValue)
+                    xmlWriter.WriteElementString("lastBuildDate", feed.LastUpdatedTime.ToString("R")); // RFC-822 format
+
+                // More optional elements like image, categories, etc. can be added here
+
+                // Write items
+                foreach (var item in feed.Items)
                 {
-                    // If only PublishDate is invalid, set it to LastUpdatedTime
-                    if (item.PublishDate == DateTimeOffset.MinValue)
-                    {
-                        item.PublishDate = item.LastUpdatedTime;
-                    }
+                    xmlWriter.WriteStartElement("item");
 
-                    // If only LastUpdatedTime is invalid, set it to PublishDate
-                    if (item.LastUpdatedTime == DateTimeOffset.MinValue)
-                    {
-                        item.LastUpdatedTime = item.PublishDate;
-                    }
+                    xmlWriter.WriteElementString("title", item.Title?.Text ?? string.Empty);
+                    xmlWriter.WriteElementString("link", item.Links.FirstOrDefault()?.Uri.AbsoluteUri ?? string.Empty);
+                    xmlWriter.WriteElementString("description", item.Summary?.Text ?? string.Empty);
+
+                    // Other optional elements for each item (guid, pubDate, etc.)
+                    if (item.Id != null)
+                        xmlWriter.WriteElementString("guid", item.Id);
+
+                    if (item.PublishDate != DateTimeOffset.MinValue)
+                        xmlWriter.WriteElementString("pubDate", item.PublishDate.ToString("R")); // RFC-822 format
+
+                    // Additional elements for each item can be added here
+
+                    xmlWriter.WriteEndElement(); // item
                 }
+
+                xmlWriter.WriteEndElement(); // channel
+                xmlWriter.WriteEndElement(); // rss
+
+                await xmlWriter.FlushAsync();
+                memoryStream.Seek(0, SeekOrigin.Begin);
+
+                return memoryStream;
+            }
+            catch (Exception ex)
+            {
+                throw;
             }
         }
 
diff --git a/PlanetDotnet/Services/CombinedFeeds/CombinedFeedService.cs b/PlanetDotnet/Services/Foundations/Feeds/CombinedFeedService.cs
similarity index 84%
rename from PlanetDotnet/Services/CombinedFeeds/CombinedFeedService.cs
rename to PlanetDotnet/Services/Foundations/Feeds/CombinedFeedService.cs
index f7789e0..d53faae 100644
--- a/PlanetDotnet/Services/CombinedFeeds/CombinedFeedService.cs
+++ b/PlanetDotnet/Services/Foundations/Feeds/CombinedFeedService.cs
@@ -15,13 +15,14 @@
 using System.Xml;
 using PlanetDotnet.Authors.Models.Authors;
 using PlanetDotnet.Brokers.Authors;
+using PlanetDotnet.Brokers.Feeds;
 using PlanetDotnet.Brokers.Loggings;
 using PlanetDotnet.Extensions;
 using PlanetDotnet.Models.Feeds.Exceptions;
 using Polly;
 using Polly.Retry;
 
-namespace PlanetDotnet.Services.CombinedFeeds
+namespace PlanetDotnet.Services.Foundations.Feeds
 {
     public class CombinedFeedService : ICombinedFeedService
     {
@@ -29,6 +30,7 @@ public class CombinedFeedService : ICombinedFeedService
         private readonly AsyncRetryPolicy _retryPolicy;
         private readonly IAuthorBroker authorBroker;
         private readonly ILoggingBroker loggingBroker;
+        private readonly IFeedBroker feedBroker;
 
         private const string RssFeedTitleKey = "RssFeedTitle";
         private const string RssFeedDescriptionKey = "RssFeedDescription";
@@ -38,6 +40,7 @@ public class CombinedFeedService : ICombinedFeedService
         public CombinedFeedService(
             IAuthorBroker authorBroker,
             ILoggingBroker loggingBroker,
+            IFeedBroker feedBroker,
             HttpClient httpClient)
         {
             this.httpClient = httpClient;
@@ -48,23 +51,15 @@ public CombinedFeedService(
 
             this.authorBroker = authorBroker;
             this.loggingBroker = loggingBroker;
-        }
-
-        private void EnsureHttpClient()
-        {
-            this.httpClient.DefaultRequestHeaders.UserAgent.Add(
-                new ProductInfoHeaderValue("PlanetDotnet", $"{GetType().Assembly.GetName().Version}"));
-
-            this.httpClient.Timeout = TimeSpan.FromSeconds(15);
-
-            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
+            this.feedBroker = feedBroker;
         }
 
         public async Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageCode = "mixed")
         {
-            var authors = await this.authorBroker.GetAllAuthorsAsync();
+            var authors = await authorBroker.GetAllAuthorsAsync();
 
             IEnumerable<Author> languageAuthors;
+
             if (languageCode == null || languageCode == "mixed") // use all tamarins
             {
                 languageAuthors = authors;
@@ -76,10 +71,12 @@ public async Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageC
 
             var feedTasks = languageAuthors.SelectMany(t => TryReadFeeds(t)).ToArray();
 
-            this.loggingBroker.LogInformation($"Loading feed for language: {languageCode} for {feedTasks.Length} authors");
+            loggingBroker.LogInformation($"Loading feed for language: {languageCode} for {feedTasks.Length} authors");
 
             var syndicationItems = await Task.WhenAll(feedTasks).ConfigureAwait(false);
+
             var combinedFeed = GetCombinedFeed(syndicationItems.SelectMany(f => f), languageCode, languageAuthors, numberOfItems);
+
             return combinedFeed;
         }
 
@@ -96,7 +93,7 @@ private async Task<IEnumerable<SyndicationItem>> TryReadFeed(Author tamarin, str
             }
             catch (FailedFeedException ex)
             {
-                this.loggingBroker.LogError(ex, $"{tamarin.FirstName} {tamarin.LastName}'s feed of {ex.Data["FeedUri"]} failed to load.");
+                loggingBroker.LogError(ex, $"{tamarin.FirstName} {tamarin.LastName}'s feed of {ex.Data["FeedUri"]} failed to load.");
             }
 
             return Array.Empty<SyndicationItem>();
@@ -104,22 +101,13 @@ private async Task<IEnumerable<SyndicationItem>> TryReadFeed(Author tamarin, str
 
         private async Task<IEnumerable<SyndicationItem>> ReadFeed(string feedUri)
         {
-            HttpResponseMessage response;
             try
             {
-                this.loggingBroker.LogInformation($"Loading feed {feedUri}");
-
-                response = await httpClient.GetAsync(feedUri).ConfigureAwait(false);
+                loggingBroker.LogInformation($"Loading feed {feedUri}");
 
-                if (response.IsSuccessStatusCode)
-                {
-                    using var feedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
-                    using var reader = XmlReader.Create(feedStream);
-                    var feed = SyndicationFeed.Load(reader);
-                    var filteredItems = feed.Items;
+                var feed = await feedBroker.ReadFeedAsync(feedUri);
 
-                    return filteredItems;
-                }
+                return feed.Items;
             }
             catch (HttpRequestException hex)
             {
@@ -148,8 +136,7 @@ private async Task<IEnumerable<SyndicationItem>> ReadFeed(string feedUri)
             }
 
             throw new FailedFeedException("Loading remote syndication feed failed.")
-                .WithData("FeedUri", feedUri)
-                .WithData("HttpStatusCode", (int)response.StatusCode);
+                .WithData("FeedUri", feedUri);
         }
 
         private SyndicationFeed GetCombinedFeed(IEnumerable<SyndicationItem> items, string languageCode,
@@ -209,5 +196,15 @@ private static DateTimeOffset GetMaxTime(SyndicationItem item)
                 return item.PublishDate.UtcDateTime;
             }
         }
+
+        private void EnsureHttpClient()
+        {
+            httpClient.DefaultRequestHeaders.UserAgent.Add(
+                new ProductInfoHeaderValue("PlanetDotnet", $"{GetType().Assembly.GetName().Version}"));
+
+            httpClient.Timeout = TimeSpan.FromSeconds(15);
+
+            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
+        }
     }
 }
\ No newline at end of file
diff --git a/PlanetDotnet/Services/CombinedFeeds/ICombinedFeedService.cs b/PlanetDotnet/Services/Foundations/Feeds/ICombinedFeedService.cs
similarity index 91%
rename from PlanetDotnet/Services/CombinedFeeds/ICombinedFeedService.cs
rename to PlanetDotnet/Services/Foundations/Feeds/ICombinedFeedService.cs
index 9d04163..03bd1a9 100644
--- a/PlanetDotnet/Services/CombinedFeeds/ICombinedFeedService.cs
+++ b/PlanetDotnet/Services/Foundations/Feeds/ICombinedFeedService.cs
@@ -7,7 +7,7 @@
 using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
 
-namespace PlanetDotnet.Services.CombinedFeeds
+namespace PlanetDotnet.Services.Foundations.Feeds
 {
     public interface ICombinedFeedService
     {
diff --git a/PlanetDotnet/Startup.cs b/PlanetDotnet/Startup.cs
index bd1715d..f7b9671 100644
--- a/PlanetDotnet/Startup.cs
+++ b/PlanetDotnet/Startup.cs
@@ -13,7 +13,7 @@
 using PlanetDotnet.Brokers.Loggings;
 using PlanetDotnet.Brokers.Serializations;
 using PlanetDotnet.Brokers.Storages;
-using PlanetDotnet.Services.CombinedFeeds;
+using PlanetDotnet.Services.Foundations.Feeds;
 
 [assembly: FunctionsStartup(typeof(PlanetDotnet.Startup))]
 namespace PlanetDotnet

From 5e105f8faf8aaeb99c9654c69c1432f36d4532b0 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Wed, 29 Nov 2023 01:42:25 +0100
Subject: [PATCH 14/18] FOUNDATIONS: Load Feed

---
 PlanetDotnet/LoadFeedsFunction.cs             | 86 ++-----------------
 ...{CombinedFeedService.cs => FeedService.cs} |  6 +-
 ...CombinedFeedService.cs => IFeedService.cs} |  4 +-
 PlanetDotnet/Startup.cs                       |  2 +-
 4 files changed, 15 insertions(+), 83 deletions(-)
 rename PlanetDotnet/Services/Foundations/Feeds/{CombinedFeedService.cs => FeedService.cs} (97%)
 rename PlanetDotnet/Services/Foundations/Feeds/{ICombinedFeedService.cs => IFeedService.cs} (76%)

diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
index bafc578..9edb1b4 100644
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -6,14 +6,12 @@
 
 using System;
 using System.Globalization;
-using System.IO;
 using System.Linq;
-using System.ServiceModel.Syndication;
 using System.Threading.Tasks;
-using System.Xml;
 using Microsoft.Azure.WebJobs;
 using Microsoft.Extensions.Logging;
 using PlanetDotnet.Brokers.Authors;
+using PlanetDotnet.Brokers.Serializations;
 using PlanetDotnet.Brokers.Storages;
 using PlanetDotnet.Services.Foundations.Feeds;
 
@@ -21,18 +19,21 @@ namespace PlanetDotnet
 {
     public class LoadFeedsFunction
     {
-        private readonly ICombinedFeedService feedService;
+        private readonly IFeedService feedService;
         private readonly IStorageBroker storageBroker;
         private readonly IAuthorBroker authorBroker;
+        private readonly ISerializationBroker serializationBroker;
 
         public LoadFeedsFunction(
-            ICombinedFeedService feedService,
+            IFeedService feedService,
             IStorageBroker storageBroker,
-            IAuthorBroker authorBroker)
+            IAuthorBroker authorBroker,
+            ISerializationBroker serializationBroker)
         {
             this.feedService = feedService;
             this.storageBroker = storageBroker;
             this.authorBroker = authorBroker;
+            this.serializationBroker = serializationBroker;
         }
 
         [FunctionName("LoadFeedsFunction")]
@@ -58,8 +59,8 @@ public async Task Run(
                     {
                         CultureInfo.CurrentCulture = new CultureInfo(language);
                         log.LogInformation($"Loading {language} combined author feed");
-                        var feed = await feedService.LoadFeed(null, language);
-                        using var stream = await SerializeFeed(feed);
+                        var feed = await feedService.LoadFeedAsync(null, language);
+                        using var stream = await this.serializationBroker.SerializeFeedAsync(feed);
                         await this.storageBroker.UploadBlobAsync(language, stream);
                     }
                     catch (Exception ex)
@@ -76,74 +77,5 @@ public async Task Run(
             }
             log.LogInformation($"Load feeds Finished at: {DateTime.Now}");
         }
-
-        private static async Task<Stream> SerializeFeed(SyndicationFeed feed)
-        {
-            try
-            {
-
-                var memoryStream = new MemoryStream();
-                using var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings
-                {
-                    Async = true,
-                    Indent = true // Makes the output XML easier to read, optional
-                });
-
-                xmlWriter.WriteStartDocument();
-                xmlWriter.WriteStartElement("rss");
-                xmlWriter.WriteAttributeString("version", "2.0");
-
-                xmlWriter.WriteStartElement("channel");
-
-                // Write channel elements
-                xmlWriter.WriteElementString("title", feed.Title?.Text ?? string.Empty);
-                xmlWriter.WriteElementString("link", feed.Links.FirstOrDefault()?.Uri.AbsoluteUri ?? string.Empty);
-                xmlWriter.WriteElementString("description", feed.Description?.Text ?? string.Empty);
-
-                // Optional channel elements (add as needed)
-                if (feed.Language != null)
-                    xmlWriter.WriteElementString("language", feed.Language);
-
-                if (feed.LastUpdatedTime != DateTimeOffset.MinValue)
-                    xmlWriter.WriteElementString("lastBuildDate", feed.LastUpdatedTime.ToString("R")); // RFC-822 format
-
-                // More optional elements like image, categories, etc. can be added here
-
-                // Write items
-                foreach (var item in feed.Items)
-                {
-                    xmlWriter.WriteStartElement("item");
-
-                    xmlWriter.WriteElementString("title", item.Title?.Text ?? string.Empty);
-                    xmlWriter.WriteElementString("link", item.Links.FirstOrDefault()?.Uri.AbsoluteUri ?? string.Empty);
-                    xmlWriter.WriteElementString("description", item.Summary?.Text ?? string.Empty);
-
-                    // Other optional elements for each item (guid, pubDate, etc.)
-                    if (item.Id != null)
-                        xmlWriter.WriteElementString("guid", item.Id);
-
-                    if (item.PublishDate != DateTimeOffset.MinValue)
-                        xmlWriter.WriteElementString("pubDate", item.PublishDate.ToString("R")); // RFC-822 format
-
-                    // Additional elements for each item can be added here
-
-                    xmlWriter.WriteEndElement(); // item
-                }
-
-                xmlWriter.WriteEndElement(); // channel
-                xmlWriter.WriteEndElement(); // rss
-
-                await xmlWriter.FlushAsync();
-                memoryStream.Seek(0, SeekOrigin.Begin);
-
-                return memoryStream;
-            }
-            catch (Exception ex)
-            {
-                throw;
-            }
-        }
-
     }
-
 }
diff --git a/PlanetDotnet/Services/Foundations/Feeds/CombinedFeedService.cs b/PlanetDotnet/Services/Foundations/Feeds/FeedService.cs
similarity index 97%
rename from PlanetDotnet/Services/Foundations/Feeds/CombinedFeedService.cs
rename to PlanetDotnet/Services/Foundations/Feeds/FeedService.cs
index d53faae..e4b7c49 100644
--- a/PlanetDotnet/Services/Foundations/Feeds/CombinedFeedService.cs
+++ b/PlanetDotnet/Services/Foundations/Feeds/FeedService.cs
@@ -24,7 +24,7 @@
 
 namespace PlanetDotnet.Services.Foundations.Feeds
 {
-    public class CombinedFeedService : ICombinedFeedService
+    public class FeedService : IFeedService
     {
         private readonly HttpClient httpClient;
         private readonly AsyncRetryPolicy _retryPolicy;
@@ -37,7 +37,7 @@ public class CombinedFeedService : ICombinedFeedService
         private const string RssFeedUrlKey = "RssFeedUrl";
         private const string RssFeedImageUrlKey = "RssFeedImageUrl";
 
-        public CombinedFeedService(
+        public FeedService(
             IAuthorBroker authorBroker,
             ILoggingBroker loggingBroker,
             IFeedBroker feedBroker,
@@ -54,7 +54,7 @@ public CombinedFeedService(
             this.feedBroker = feedBroker;
         }
 
-        public async Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageCode = "mixed")
+        public async Task<SyndicationFeed> LoadFeedAsync(int? numberOfItems, string languageCode = "mixed")
         {
             var authors = await authorBroker.GetAllAuthorsAsync();
 
diff --git a/PlanetDotnet/Services/Foundations/Feeds/ICombinedFeedService.cs b/PlanetDotnet/Services/Foundations/Feeds/IFeedService.cs
similarity index 76%
rename from PlanetDotnet/Services/Foundations/Feeds/ICombinedFeedService.cs
rename to PlanetDotnet/Services/Foundations/Feeds/IFeedService.cs
index 03bd1a9..8218eb8 100644
--- a/PlanetDotnet/Services/Foundations/Feeds/ICombinedFeedService.cs
+++ b/PlanetDotnet/Services/Foundations/Feeds/IFeedService.cs
@@ -9,8 +9,8 @@
 
 namespace PlanetDotnet.Services.Foundations.Feeds
 {
-    public interface ICombinedFeedService
+    public interface IFeedService
     {
-        Task<SyndicationFeed> LoadFeed(int? numberOfItems, string languageCode = "mixed");
+        Task<SyndicationFeed> LoadFeedAsync(int? numberOfItems, string languageCode = "mixed");
     }
 }
diff --git a/PlanetDotnet/Startup.cs b/PlanetDotnet/Startup.cs
index f7b9671..9355519 100644
--- a/PlanetDotnet/Startup.cs
+++ b/PlanetDotnet/Startup.cs
@@ -30,7 +30,7 @@ public override void Configure(IFunctionsHostBuilder builder)
             builder.Services.AddScoped<IStorageBroker, StorageBroker>();
             builder.Services.AddScoped<IAuthorBroker, AuthorBroker>();
             builder.Services.AddScoped<IFeedBroker, FeedBroker>();
-            builder.Services.AddScoped<ICombinedFeedService, CombinedFeedService>();
+            builder.Services.AddScoped<IFeedService, FeedService>();
         }
     }
 }

From 5ff708258b33691abf2505b037351c5b92c454a9 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Wed, 29 Nov 2023 01:49:44 +0100
Subject: [PATCH 15/18] PROCESSINGS: Process Feed Loading

---
 PlanetDotnet/LoadFeedsFunction.cs             | 31 +-------
 .../Feeds/FeedProcessingService.cs            | 70 +++++++++++++++++++
 .../Feeds/IFeedProcessingService.cs           | 15 ++++
 PlanetDotnet/Startup.cs                       |  2 +
 4 files changed, 89 insertions(+), 29 deletions(-)
 create mode 100644 PlanetDotnet/Services/Processings/Feeds/FeedProcessingService.cs
 create mode 100644 PlanetDotnet/Services/Processings/Feeds/IFeedProcessingService.cs

diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
index 9edb1b4..4fc5f59 100644
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -19,10 +19,7 @@ namespace PlanetDotnet
 {
     public class LoadFeedsFunction
     {
-        private readonly IFeedService feedService;
-        private readonly IStorageBroker storageBroker;
-        private readonly IAuthorBroker authorBroker;
-        private readonly ISerializationBroker serializationBroker;
+        
 
         public LoadFeedsFunction(
             IFeedService feedService,
@@ -45,31 +42,7 @@ public async Task Run(
 
             try
             {
-                await this.storageBroker.InitializeAsync();
-
-                var authors = await this.authorBroker.GetAllAuthorsAsync();
-
-                var languages = authors.Select(author => author.FeedLanguageCode).Distinct().ToList();
-
-                var mainCulture = CultureInfo.CurrentCulture;
-
-                foreach (var language in languages)
-                {
-                    try
-                    {
-                        CultureInfo.CurrentCulture = new CultureInfo(language);
-                        log.LogInformation($"Loading {language} combined author feed");
-                        var feed = await feedService.LoadFeedAsync(null, language);
-                        using var stream = await this.serializationBroker.SerializeFeedAsync(feed);
-                        await this.storageBroker.UploadBlobAsync(language, stream);
-                    }
-                    catch (Exception ex)
-                    {
-                        log.LogError(ex, "error");
-                    }
-                }
-
-                CultureInfo.CurrentCulture = mainCulture;
+                
             }
             catch (Exception ex)
             {
diff --git a/PlanetDotnet/Services/Processings/Feeds/FeedProcessingService.cs b/PlanetDotnet/Services/Processings/Feeds/FeedProcessingService.cs
new file mode 100644
index 0000000..6a7e06d
--- /dev/null
+++ b/PlanetDotnet/Services/Processings/Feeds/FeedProcessingService.cs
@@ -0,0 +1,70 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using PlanetDotnet.Brokers.Authors;
+using PlanetDotnet.Brokers.Loggings;
+using PlanetDotnet.Brokers.Serializations;
+using PlanetDotnet.Brokers.Storages;
+using PlanetDotnet.Services.Foundations.Feeds;
+
+namespace PlanetDotnet.Services.Processings.Feeds
+{
+    public class FeedProcessingService : IFeedProcessingService
+    {
+        private readonly IFeedService feedService;
+        private readonly IStorageBroker storageBroker;
+        private readonly IAuthorBroker authorBroker;
+        private readonly ISerializationBroker serializationBroker;
+        private readonly ILoggingBroker loggingBroker;
+
+        public FeedProcessingService(
+            IFeedService feedService,
+            IStorageBroker storageBroker,
+            IAuthorBroker authorBroker,
+            ISerializationBroker serializationBroker,
+            ILoggingBroker loggingBroker)
+        {
+            this.feedService = feedService;
+            this.storageBroker = storageBroker;
+            this.authorBroker = authorBroker;
+            this.serializationBroker = serializationBroker;
+            this.loggingBroker = loggingBroker;
+        }
+
+        public async ValueTask ProcessFeedLoadingAsync()
+        {
+            await this.storageBroker.InitializeAsync();
+
+            var authors = await this.authorBroker.GetAllAuthorsAsync();
+
+            var languages = authors.Select(author => author.FeedLanguageCode).Distinct().ToList();
+
+            var mainCulture = CultureInfo.CurrentCulture;
+
+            foreach (var language in languages)
+            {
+                try
+                {
+                    CultureInfo.CurrentCulture = new CultureInfo(language);
+                    this.loggingBroker.LogInformation($"Loading {language} combined author feed");
+                    var feed = await feedService.LoadFeedAsync(null, language);
+                    using var stream = await this.serializationBroker.SerializeFeedAsync(feed);
+                    await this.storageBroker.UploadBlobAsync(language, stream);
+                }
+                catch (Exception ex)
+                {
+                    this.loggingBroker.LogError(ex, "error");
+                }
+            }
+
+            CultureInfo.CurrentCulture = mainCulture;
+        }
+    }
+}
diff --git a/PlanetDotnet/Services/Processings/Feeds/IFeedProcessingService.cs b/PlanetDotnet/Services/Processings/Feeds/IFeedProcessingService.cs
new file mode 100644
index 0000000..2d08eda
--- /dev/null
+++ b/PlanetDotnet/Services/Processings/Feeds/IFeedProcessingService.cs
@@ -0,0 +1,15 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
+using System.Threading.Tasks;
+
+namespace PlanetDotnet.Services.Processings.Feeds
+{
+    public interface IFeedProcessingService
+    {
+        ValueTask ProcessFeedLoadingAsync();
+    }
+}
diff --git a/PlanetDotnet/Startup.cs b/PlanetDotnet/Startup.cs
index 9355519..e4a30e0 100644
--- a/PlanetDotnet/Startup.cs
+++ b/PlanetDotnet/Startup.cs
@@ -14,6 +14,7 @@
 using PlanetDotnet.Brokers.Serializations;
 using PlanetDotnet.Brokers.Storages;
 using PlanetDotnet.Services.Foundations.Feeds;
+using PlanetDotnet.Services.Processings.Feeds;
 
 [assembly: FunctionsStartup(typeof(PlanetDotnet.Startup))]
 namespace PlanetDotnet
@@ -31,6 +32,7 @@ public override void Configure(IFunctionsHostBuilder builder)
             builder.Services.AddScoped<IAuthorBroker, AuthorBroker>();
             builder.Services.AddScoped<IFeedBroker, FeedBroker>();
             builder.Services.AddScoped<IFeedService, FeedService>();
+            builder.Services.AddScoped<IFeedProcessingService, FeedProcessingService>();
         }
     }
 }

From 75e192192c4a503d24f60e2a074d33d5d0f2f66b Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Wed, 29 Nov 2023 01:55:25 +0100
Subject: [PATCH 16/18] FUNCTIONS: Load Feeds Function

---
 PlanetDotnet/LoadFeedsFunction.cs | 33 ++++++++++---------------------
 1 file changed, 10 insertions(+), 23 deletions(-)

diff --git a/PlanetDotnet/LoadFeedsFunction.cs b/PlanetDotnet/LoadFeedsFunction.cs
index 4fc5f59..7d96325 100644
--- a/PlanetDotnet/LoadFeedsFunction.cs
+++ b/PlanetDotnet/LoadFeedsFunction.cs
@@ -5,50 +5,37 @@
 // ---------------------------------------------------------------
 
 using System;
-using System.Globalization;
-using System.Linq;
 using System.Threading.Tasks;
 using Microsoft.Azure.WebJobs;
 using Microsoft.Extensions.Logging;
-using PlanetDotnet.Brokers.Authors;
-using PlanetDotnet.Brokers.Serializations;
-using PlanetDotnet.Brokers.Storages;
-using PlanetDotnet.Services.Foundations.Feeds;
+using PlanetDotnet.Services.Processings.Feeds;
 
 namespace PlanetDotnet
 {
     public class LoadFeedsFunction
     {
-        
+        private readonly IFeedProcessingService feedProcessingService;
 
-        public LoadFeedsFunction(
-            IFeedService feedService,
-            IStorageBroker storageBroker,
-            IAuthorBroker authorBroker,
-            ISerializationBroker serializationBroker)
-        {
-            this.feedService = feedService;
-            this.storageBroker = storageBroker;
-            this.authorBroker = authorBroker;
-            this.serializationBroker = serializationBroker;
-        }
+        public LoadFeedsFunction(IFeedProcessingService feedProcessingService) =>
+            this.feedProcessingService = feedProcessingService;
 
         [FunctionName("LoadFeedsFunction")]
         public async Task Run(
             [TimerTrigger("0 0 */1 * * *", RunOnStartup = true)] TimerInfo myTimer,
             ILogger log)
         {
-            log.LogInformation($"Load feeds Timer trigger function executed at: {DateTime.Now}");
-
             try
             {
-                
+                log.LogInformation($"Load feeds Timer trigger function executed at: {DateTime.Now}");
+
+                await this.feedProcessingService.ProcessFeedLoadingAsync();
+
+                log.LogInformation($"Load feeds Finished at: {DateTime.Now}");
             }
             catch (Exception ex)
             {
-                log.LogError(ex, "error");
+                log.LogError(ex, "Loading feeds could'nt be processed.");
             }
-            log.LogInformation($"Load feeds Finished at: {DateTime.Now}");
         }
     }
 }

From 802283f9e440bfe9b06ac07b2930af17799a2ea7 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Wed, 29 Nov 2023 01:55:40 +0100
Subject: [PATCH 17/18] CODE RUB: Clean up

---
 PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs  | 6 ++++++
 PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs | 6 ++++++
 PlanetDotnet/Extensions/ExceptionExtensions.cs    | 6 +++---
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs b/PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs
index 1a91c52..2109e7d 100644
--- a/PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs
+++ b/PlanetDotnet/Brokers/DateTimes/DateTimeBroker.cs
@@ -1,3 +1,9 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
 using System;
 
 namespace PlanetDotnet.Brokers.DateTimes
diff --git a/PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs b/PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs
index d771b78..d4505c8 100644
--- a/PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs
+++ b/PlanetDotnet/Brokers/DateTimes/IDateTimeBroker.cs
@@ -1,3 +1,9 @@
+// ---------------------------------------------------------------
+// Copyright (c) 2023 Planet Dotnet. All rights reserved.
+// Licensed under the MIT License.
+// See License.txt in the project root for license information.
+// ---------------------------------------------------------------
+
 using System;
 
 namespace PlanetDotnet.Brokers.DateTimes
diff --git a/PlanetDotnet/Extensions/ExceptionExtensions.cs b/PlanetDotnet/Extensions/ExceptionExtensions.cs
index 5ce0dbc..a563f30 100644
--- a/PlanetDotnet/Extensions/ExceptionExtensions.cs
+++ b/PlanetDotnet/Extensions/ExceptionExtensions.cs
@@ -11,9 +11,9 @@ namespace PlanetDotnet.Extensions
     internal static class ExceptionExtensions
     {
         public static TException WithData<TException>(
-            this TException exception, 
-            string key, 
-            object value) 
+            this TException exception,
+            string key,
+            object value)
             where TException : Exception
         {
             exception.Data[key] = value;

From ad0f059f61131ea0123140de2d978bd785747217 Mon Sep 17 00:00:00 2001
From: "Mabrouk.Mahdhi" <Mabrouk.Mahdhi@ebizcon.de>
Date: Wed, 29 Nov 2023 02:19:48 +0100
Subject: [PATCH 18/18] CODE RUB: Clean up

---
 .../Services/Foundations/Feeds/FeedService.cs | 37 +++++++++++--------
 PlanetDotnet/Startup.cs                       | 18 ++++-----
 2 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/PlanetDotnet/Services/Foundations/Feeds/FeedService.cs b/PlanetDotnet/Services/Foundations/Feeds/FeedService.cs
index e4b7c49..2929c59 100644
--- a/PlanetDotnet/Services/Foundations/Feeds/FeedService.cs
+++ b/PlanetDotnet/Services/Foundations/Feeds/FeedService.cs
@@ -27,7 +27,7 @@ namespace PlanetDotnet.Services.Foundations.Feeds
     public class FeedService : IFeedService
     {
         private readonly HttpClient httpClient;
-        private readonly AsyncRetryPolicy _retryPolicy;
+        private readonly AsyncRetryPolicy retryPolicy;
         private readonly IAuthorBroker authorBroker;
         private readonly ILoggingBroker loggingBroker;
         private readonly IFeedBroker feedBroker;
@@ -38,25 +38,25 @@ public class FeedService : IFeedService
         private const string RssFeedImageUrlKey = "RssFeedImageUrl";
 
         public FeedService(
-            IAuthorBroker authorBroker,
-            ILoggingBroker loggingBroker,
+            HttpClient httpClient,
             IFeedBroker feedBroker,
-            HttpClient httpClient)
+            IAuthorBroker authorBroker,
+            ILoggingBroker loggingBroker)
         {
             this.httpClient = httpClient;
+            this.feedBroker = feedBroker;
+            this.authorBroker = authorBroker;
+            this.loggingBroker = loggingBroker;
+
             EnsureHttpClient();
 
-            _retryPolicy ??= Policy.Handle<FailedFeedException>()
+            this.retryPolicy ??= Policy.Handle<FailedFeedException>()
                 .WaitAndRetryAsync(2, retry => TimeSpan.FromSeconds(retry * Math.Pow(1.2, retry)));
-
-            this.authorBroker = authorBroker;
-            this.loggingBroker = loggingBroker;
-            this.feedBroker = feedBroker;
         }
 
         public async Task<SyndicationFeed> LoadFeedAsync(int? numberOfItems, string languageCode = "mixed")
         {
-            var authors = await authorBroker.GetAllAuthorsAsync();
+            var authors = await this.authorBroker.GetAllAuthorsAsync();
 
             IEnumerable<Author> languageAuthors;
 
@@ -71,7 +71,7 @@ public async Task<SyndicationFeed> LoadFeedAsync(int? numberOfItems, string lang
 
             var feedTasks = languageAuthors.SelectMany(t => TryReadFeeds(t)).ToArray();
 
-            loggingBroker.LogInformation($"Loading feed for language: {languageCode} for {feedTasks.Length} authors");
+            this.loggingBroker.LogInformation($"Loading feed for language: {languageCode} for {feedTasks.Length} authors");
 
             var syndicationItems = await Task.WhenAll(feedTasks).ConfigureAwait(false);
 
@@ -89,7 +89,7 @@ private async Task<IEnumerable<SyndicationItem>> TryReadFeed(Author tamarin, str
         {
             try
             {
-                return await _retryPolicy.ExecuteAsync(context => ReadFeed(feedUri), new Context(feedUri)).ConfigureAwait(false);
+                return await retryPolicy.ExecuteAsync(context => ReadFeed(feedUri), new Context(feedUri)).ConfigureAwait(false);
             }
             catch (FailedFeedException ex)
             {
@@ -199,12 +199,17 @@ private static DateTimeOffset GetMaxTime(SyndicationItem item)
 
         private void EnsureHttpClient()
         {
-            httpClient.DefaultRequestHeaders.UserAgent.Add(
-                new ProductInfoHeaderValue("PlanetDotnet", $"{GetType().Assembly.GetName().Version}"));
+            this.httpClient.DefaultRequestHeaders.UserAgent.Add(
+                new ProductInfoHeaderValue(
+                    productName: "PlanetDotnet",
+                    productVersion: $"{GetType().Assembly.GetName().Version}"));
 
-            httpClient.Timeout = TimeSpan.FromSeconds(15);
+            this.httpClient.Timeout = TimeSpan.FromSeconds(15);
 
-            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
+            ServicePointManager.SecurityProtocol =
+                SecurityProtocolType.Tls13
+                | SecurityProtocolType.Tls12
+                | SecurityProtocolType.Tls11;
         }
     }
 }
\ No newline at end of file
diff --git a/PlanetDotnet/Startup.cs b/PlanetDotnet/Startup.cs
index e4a30e0..2b8b95a 100644
--- a/PlanetDotnet/Startup.cs
+++ b/PlanetDotnet/Startup.cs
@@ -24,15 +24,15 @@ public class Startup : FunctionsStartup
         public override void Configure(IFunctionsHostBuilder builder)
         {
             builder.Services.AddLogging();
-            builder.Services.AddScoped<ILogger<LoggingBroker>, Logger<LoggingBroker>>();
-            builder.Services.AddScoped<ILoggingBroker, LoggingBroker>();
-            builder.Services.AddScoped<IDateTimeBroker, DateTimeBroker>();
-            builder.Services.AddScoped<ISerializationBroker, SerializationBroker>();
-            builder.Services.AddScoped<IStorageBroker, StorageBroker>();
-            builder.Services.AddScoped<IAuthorBroker, AuthorBroker>();
-            builder.Services.AddScoped<IFeedBroker, FeedBroker>();
-            builder.Services.AddScoped<IFeedService, FeedService>();
-            builder.Services.AddScoped<IFeedProcessingService, FeedProcessingService>();
+            builder.Services.AddSingleton<ILogger<LoggingBroker>, Logger<LoggingBroker>>();
+            builder.Services.AddSingleton<ILoggingBroker, LoggingBroker>();
+            builder.Services.AddSingleton<IDateTimeBroker, DateTimeBroker>();
+            builder.Services.AddSingleton<ISerializationBroker, SerializationBroker>();
+            builder.Services.AddSingleton<IStorageBroker, StorageBroker>();
+            builder.Services.AddSingleton<IAuthorBroker, AuthorBroker>();
+            builder.Services.AddSingleton<IFeedBroker, FeedBroker>();
+            builder.Services.AddSingleton<IFeedService, FeedService>();
+            builder.Services.AddSingleton<IFeedProcessingService, FeedProcessingService>();
         }
     }
 }