private static void Main(string[] args)
        {
            var keywords = new List<Keyword>()
              {
            new Keyword() { Id = 1, Name = "Mercedes-Benz" },
            new Keyword() { Id = 2, Name = "GLK" },
            new Keyword() { Id = 3, Name = "Citan" },
              };

              var categories = new List<Category>()
              {
            new Category(){Id=1, Name="Car"},
            new Category(){Id=2, Name="Truck"},
              };

              var keywordAdCategories = new List<KeywordAdCategory>()
              {
            new KeywordAdCategory(){Ad_Id=1, Keyword_Id=1, Category_Id=1},
            new KeywordAdCategory(){Ad_Id=2, Keyword_Id=1, Category_Id=2},
            new KeywordAdCategory(){Ad_Id=1, Keyword_Id=2, Category_Id=1},
            new KeywordAdCategory(){Ad_Id=2, Keyword_Id=3, Category_Id=2},
              };

              var searchDomain = new SearchDomain()
              {
            Keywords = keywords,
            Categories = categories,
            KeywordAdCategories = keywordAdCategories
              };

              var searchTerm = "Mercedes-Benz";
              var categoriesWithCounts = KeywordSearch.FromStringInput(searchTerm, searchDomain);
              DisplayFoundAdCategories(searchTerm, categoriesWithCounts);

              searchTerm = "Mercedes-Benz GLK";
              categoriesWithCounts = KeywordSearch.FromStringInput(searchTerm, searchDomain);
              DisplayFoundAdCategories(searchTerm, categoriesWithCounts);

              searchTerm = "Mercedes Citan";
              categoriesWithCounts = KeywordSearch.FromStringInput(searchTerm, searchDomain);
              DisplayFoundAdCategories(searchTerm, categoriesWithCounts);

              Console.Write("Press any key to exit.");
              Console.ReadKey();
        }
        internal static Dictionary<Category, Dictionary<int, List<KeywordAdCategory>>> FromStringInput(string searchPhrase, SearchDomain searchDomain)
        {
            var identifiedKeywords = searchPhrase
            .Split(keywordPartsSplitter);

              var knownKeywordParts = identifiedKeywords
            .Where
            (ik =>
              searchDomain
              .Keywords
              .SelectMany(x => x.GetKeywordParts())
              .Any(kp => kp.Equals(ik, StringComparison.InvariantCultureIgnoreCase))
            );

              var keywordkSearches = knownKeywordParts
            .Select((kkp, n) => new KeywordSearch()
            {
              Id = n,
              Name = kkp,
              Keyword = searchDomain
            .Keywords
            .Single
            (k =>
              k.GetKeywordParts()
                .Any(kp => kp.Equals(kkp, StringComparison.InvariantCultureIgnoreCase))
            )
            });

              var relevantKeywords = keywordkSearches
            .Select(ks => ks.Keyword)
            .Distinct();

              var keywordAdCategoriesByCategory = searchDomain.Categories
            .GroupJoin
            (
              searchDomain.KeywordAdCategories,
              c => c.Id,
              kac => kac.Category_Id,
              (c, kac) => new { Category = c, AdKeywordsForCategory = kac }
            );

              var relevantKeywordAdCategories = keywordAdCategoriesByCategory
            .Where
            (kacbk =>
              relevantKeywords
            .All
            (rk =>
              kacbk
                .AdKeywordsForCategory
                .Any(kac => kac.Keyword_Id == rk.Id)
            )
            );

              var foundAdsInCategories = relevantKeywordAdCategories
            .ToDictionary
            (rkac =>
              rkac.Category,
              rkac => rkac.AdKeywordsForCategory
            .GroupBy(g => g.Ad_Id)
            .ToDictionary(x => x.Key, x => x.ToList())
            );

              return foundAdsInCategories;
        }
        internal static Dictionary <Category, Dictionary <int, List <KeywordAdCategory> > > FromStringInput(string searchPhrase, SearchDomain searchDomain)
        {
            var identifiedKeywords = searchPhrase
                                     .Split(keywordPartsSplitter);

            var knownKeywordParts = identifiedKeywords
                                    .Where
                                        (ik =>
                                        searchDomain
                                        .Keywords
                                        .SelectMany(x => x.GetKeywordParts())
                                        .Any(kp => kp.Equals(ik, StringComparison.InvariantCultureIgnoreCase))
                                        );

            var keywordkSearches = knownKeywordParts
                                   .Select((kkp, n) => new KeywordSearch()
            {
                Id      = n,
                Name    = kkp,
                Keyword = searchDomain
                          .Keywords
                          .Single
                              (k =>
                              k.GetKeywordParts()
                              .Any(kp => kp.Equals(kkp, StringComparison.InvariantCultureIgnoreCase))
                              )
            });

            var relevantKeywords = keywordkSearches
                                   .Select(ks => ks.Keyword)
                                   .Distinct();

            var keywordAdCategoriesByCategory = searchDomain.Categories
                                                .GroupJoin
                                                (
                searchDomain.KeywordAdCategories,
                c => c.Id,
                kac => kac.Category_Id,
                (c, kac) => new { Category = c, AdKeywordsForCategory = kac }
                                                );

            var relevantKeywordAdCategories = keywordAdCategoriesByCategory
                                              .Where
                                                  (kacbk =>
                                                  relevantKeywords
                                                  .All
                                                      (rk =>
                                                      kacbk
                                                      .AdKeywordsForCategory
                                                      .Any(kac => kac.Keyword_Id == rk.Id)
                                                      )
                                                  );

            var foundAdsInCategories = relevantKeywordAdCategories
                                       .ToDictionary
                                           (rkac =>
                                           rkac.Category,
                                           rkac => rkac.AdKeywordsForCategory
                                           .GroupBy(g => g.Ad_Id)
                                           .ToDictionary(x => x.Key, x => x.ToList())
                                           );

            return(foundAdsInCategories);
        }
        private static void Main(string[] args)
        {
            var keywords = new List <Keyword>()
            {
                new Keyword()
                {
                    Id = 1, Name = "Mercedes-Benz"
                },
                new Keyword()
                {
                    Id = 2, Name = "GLK"
                },
                new Keyword()
                {
                    Id = 3, Name = "Citan"
                },
            };

            var categories = new List <Category>()
            {
                new Category()
                {
                    Id = 1, Name = "Car"
                },
                new Category()
                {
                    Id = 2, Name = "Truck"
                },
            };

            var keywordAdCategories = new List <KeywordAdCategory>()
            {
                new KeywordAdCategory()
                {
                    Ad_Id = 1, Keyword_Id = 1, Category_Id = 1
                },
                new KeywordAdCategory()
                {
                    Ad_Id = 2, Keyword_Id = 1, Category_Id = 2
                },
                new KeywordAdCategory()
                {
                    Ad_Id = 1, Keyword_Id = 2, Category_Id = 1
                },
                new KeywordAdCategory()
                {
                    Ad_Id = 2, Keyword_Id = 3, Category_Id = 2
                },
            };

            var searchDomain = new SearchDomain()
            {
                Keywords            = keywords,
                Categories          = categories,
                KeywordAdCategories = keywordAdCategories
            };

            var searchTerm           = "Mercedes-Benz";
            var categoriesWithCounts = KeywordSearch.FromStringInput(searchTerm, searchDomain);

            DisplayFoundAdCategories(searchTerm, categoriesWithCounts);

            searchTerm           = "Mercedes-Benz GLK";
            categoriesWithCounts = KeywordSearch.FromStringInput(searchTerm, searchDomain);
            DisplayFoundAdCategories(searchTerm, categoriesWithCounts);

            searchTerm           = "Mercedes Citan";
            categoriesWithCounts = KeywordSearch.FromStringInput(searchTerm, searchDomain);
            DisplayFoundAdCategories(searchTerm, categoriesWithCounts);

            Console.Write("Press any key to exit.");
            Console.ReadKey();
        }