diff --git a/Books.ConsoleApp.sln b/Books.ConsoleApp.sln
new file mode 100644
index 0000000..4eeac28
--- /dev/null
+++ b/Books.ConsoleApp.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29509.3
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Books.ConsoleApp", "Books.ConsoleApp\Books.ConsoleApp.csproj", "{A09D7905-08C5-41F3-ADE6-2037471A2403}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A09D7905-08C5-41F3-ADE6-2037471A2403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A09D7905-08C5-41F3-ADE6-2037471A2403}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A09D7905-08C5-41F3-ADE6-2037471A2403}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A09D7905-08C5-41F3-ADE6-2037471A2403}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {6F1B272A-118E-4F00-8E83-C7C02A973BD2}
+ EndGlobalSection
+EndGlobal
diff --git a/Books.ConsoleApp/Books.ConsoleApp.csproj b/Books.ConsoleApp/Books.ConsoleApp.csproj
new file mode 100644
index 0000000..958d2f1
--- /dev/null
+++ b/Books.ConsoleApp/Books.ConsoleApp.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ netcoreapp3.0
+
+
+
diff --git a/Books.ConsoleApp/Program.cs b/Books.ConsoleApp/Program.cs
new file mode 100644
index 0000000..c0051a3
--- /dev/null
+++ b/Books.ConsoleApp/Program.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace Books.ConsoleApp
+{
+ class Program
+ {
+ List BooksByAuthorCatalogue = null;
+ static void Main(string[] args)
+ {
+ Book[] books = BookSource.Read();
+ BooksByAuthorCatalogue = new List();
+
+ for (int i = 0; i < books.Length; i++)
+ {
+ var book = books[i];
+ if (AuthorIsAlreadyCataloged(book.author))
+ {
+ // there are some(1 or more) books by this author already found and catalogued
+ var authorCatalogueIndex = LocateAuthorAlreadyCataloged(book.author);
+
+ var existingBooks = BooksByAuthorCatalogue[authorCatalogIndex].Books;
+ existingBooks.Add(book);
+ }
+ else
+ {
+ CatalogueNewAuthor(book);
+ }
+
+ }
+
+ }
+
+ private static bool AuthorIsAlreadyCataloged(string author)
+ {
+ var authorAlreadyCatalogued = false;
+
+ // we'll iterate over the catalogue to find the author - if athors's already been cataloged
+ for (int j = 0; j < BooksByAuthorCatalogue.Count; j++)
+ {
+ var entry = BooksByAuthorCatalogue[j];
+ if (entry.author == author)
+ {
+ authorAlreadyCatalogued = true;
+ break;
+ }
+ }
+
+ return authorAlreadyCatalogued;
+
+ }
+
+ private static int LocateAuthorAlreadyCataloged(string author)
+ {
+ var authorCatalogIndex = 0;
+
+ // We'll iterate over the cataloge to find the author's index
+ for (int j = 0; j < BooksByAuthorCatalogue.Count; j++)
+ {
+ var entry = BooksByAuthorCatalogue[j];
+ if (entry.Author == author)
+ {
+ authorCatalogIndex = j;
+ break;
+ }
+ }
+
+ }
+
+ private static void CatalogueNewAuthor(Book b)
+ {
+ // there are NONE books by this author already found and cataloged
+
+ var newBookList = new List {b};
+ var authorAndBooks = new BooksByAuthor(b.Author, newBookList);
+
+ BooksByAuthorCatalogue.Add(authorAndBooks);
+ }
+
+ private static void OutputBooksByAuthor()
+ {
+ for (int i = 0; i < BooksByAuthorCatalogue.Count; i++)
+ {
+ BooksByAuthor ba = BooksByAuthorCatalogue[i];
+ Console.Write("Author: {0, -28} Books: ", ba.Author);
+ for (int j = 0; j < ba.Books.Count; j++)
+ {
+ Console.Write(ba.Books[j].title + ", ");
+ }
+ Console.Write(Environment.NewLine);
+ }
+ }
+
+ }
+
+ public class BooksByAuthor
+ {
+ public readonly string Author;
+ public readonly List Books;
+
+ public BooksByAuthor(string author, List books)
+ {
+ Author = author;
+ Books = books;
+ }
+ }
+
+}
diff --git a/Books.ConsoleApp/SearchByAuthor.cs b/Books.ConsoleApp/SearchByAuthor.cs
new file mode 100644
index 0000000..aad112f
--- /dev/null
+++ b/Books.ConsoleApp/SearchByAuthor.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Data.SqlTypes;
+using System.Linq;
+using System.Text;
+
+namespace Books.ConsoleApp
+{
+ public static class SearchByAuthor
+ {
+ public static IEnumerable MatchBy(
+ IEnumerable books, string searchCriteria)
+ {
+ return books
+ .ExtractAuthors()
+ .ListAuthorsMatching(searchCriteria);
+ }
+
+ public static IEnumerable SuggestAuthors(
+ IEnumerable books, int suggestionLength = 5)
+ {
+ return books
+ .ExtractAuthors()
+ .RandomizeOrder()
+ .Take(suggestionLength);
+ }
+
+ public static IEnumerable ListBooks(IEnumerable books, string author)
+ {
+ return books
+ .CatalogueByAuthor()
+ .BooksBy(author);
+ }
+
+ public static AuthorCatalogue CatalogueByAuthor(this IEnumerable books)
+ {
+ return books
+ .ToLookup(b => b.author)
+ // Mark Twain : {The Adventures of Huckleberry Finn},
+ // Shakespeare: {Othello, Hamlet, ...}
+ // ...
+ ;
+ }
+
+
+ public static IEnumerable BooksBy(this AuthorCatalogue catalogue, string author)
+ {
+ return catalogue.Contains(author)
+ ? catalogue[author]
+ : Enumerable.Empty();
+ }
+
+ public static IEnumerable ExtractAuthors(this IEnumerable books)
+ {
+ return books.Select(b =>
+ {
+ //do stuff here
+ return b.author;
+
+ }).Distinct();
+ }
+
+ public static IEnumerable ListAuthorsMatching(
+ this IEnumerable authors, string searchCriteria)
+ {
+ var partOfNameLower = searchCriteria.ToLower();
+ return authors.Where(a => a.ToLower().Contains(partOfNameLower));
+ }
+
+ private static IOrderedEnumerable RandomizeOrder(this IEnumerable authors)
+ {
+ return authors.OrderBy(_ => Guid.NewGuid());
+ }
+
+ }
+
+ public class AuthorCatalogue
+ {
+ }
+
+ public class Book
+ {
+
+ }
+}