private void InitializeCodeSnippetSource()
        {
            try
            {
                var codeSnippetSourceList = new List<XmlCodeSnippetSource>();
                var codeSnippetSourceInvalidList = new List<string>();
                foreach (var checkedCodeSnippetSource in Configuration
                    .CheckedCodeSnippetSources
                    .Where(t => t.Item2)
                    .Select(t => t.Item1))
                    try
                    {
                        var xmlBlock = XmlHelper.DeserializeFromFile<XmlBlock>(checkedCodeSnippetSource);
                        codeSnippetSourceList.Add(new XmlCodeSnippetSource(xmlBlock, checkedCodeSnippetSource));
                    }
                    catch
                    {
                        codeSnippetSourceInvalidList.Add(checkedCodeSnippetSource);
                    }

                if (codeSnippetSourceInvalidList.Count > 0)
                    ErrorReport.Report("The following files could not be deserialized: " + Environment.NewLine +
                                       string.Join(Environment.NewLine, codeSnippetSourceInvalidList));

                _codeSnippetSource = new CompositeCodeSnippetSource(codeSnippetSourceList);

                var tagPreprocessing = Configuration.TagPreprocessing;
                var tagPreprocessorList = new List<ITagPreprocessor>();
                if ((tagPreprocessing & Configuration.TagPreprocess.LowerCase) ==
                    Configuration.TagPreprocess.LowerCase)
                    tagPreprocessorList.Add(new LowerCaseTagPreprocessor());
                if ((tagPreprocessing & Configuration.TagPreprocess.RemoveSpecialChars) ==
                    Configuration.TagPreprocess.RemoveSpecialChars)
                    tagPreprocessorList.Add(new SpecialCharsTagPreprocessor());
                _codeSnippetSource.TagPreprocessor = new CompositeTagPreprocessor(tagPreprocessorList);

                var tagMatching = Configuration.TagMatching;
                switch (tagMatching)
                {
                    case Configuration.TagMatch.Exact:
                        _codeSnippetSource.TagMatcher = null;
                        break;
                    case Configuration.TagMatch.Prefix:
                        _codeSnippetSource.TagMatcher = (filterTag, tag) => tag.StartsWith(filterTag);
                        break;
                    case Configuration.TagMatch.Substring:
                        _codeSnippetSource.TagMatcher = (filterTag, tag) => tag.Contains(filterTag);
                        break;
                    default:
                        throw new InvalidProgramException();
                }
            }
            catch (Exception exception)
            {
                ErrorReport.Report(exception);
                _codeSnippetSource = null;
            }
        }
        public void CompositeCodeSnippetSourceTest()
        {
            var xmlBlock1 = new XmlBlock
                {
                    Name = XmlBlockTestName,
                    Syntax = XmlBlockTestSyntax,
                    Tags = XmlBlockTestTags,
                    Description = XmlBlockTestDescription,
                    Prerequisites = XmlBlockTestPrerequisites,
                    CodeSnippets = new[]
                        {
                            new XmlCode
                                {
                                    Tags = XmlSubItem1TestTags,
                                    Code = XmlSubItem1TestCode
                                }
                        }
                };

            var xmlBlock2 = new XmlBlock
                {
                    Name = XmlBlockTestName,
                    Syntax = XmlBlockTestSyntax,
                    Tags = XmlBlockTestTags,
                    Description = XmlBlockTestDescription,
                    Prerequisites = XmlBlockTestPrerequisites,
                    CodeSnippets = new[]
                        {
                            new XmlCode
                                {
                                    Tags = XmlSubItem2TestTags,
                                    Code = XmlSubItem2TestCode
                                }
                        }
                };

            var xmlCodeSnippetSource1 = new XmlCodeSnippetSource(xmlBlock1);
            var xmlCodeSnippetSource2 = new XmlCodeSnippetSource(xmlBlock2);
            var compositeCodeSnippetSource = new CompositeCodeSnippetSource(
                new List<CodeSnippetSourceBase>
                    {
                        xmlCodeSnippetSource1,
                        xmlCodeSnippetSource2
                    });

            var result = compositeCodeSnippetSource.Search(new SortedSet<string>(new[] {"constructor"}));
            Assert.AreEqual(result.Count, 1);
            Assert.AreEqual(result[0].Code, "datetime(2013, 5, 7, 12, 0, 0, 0)");
            Assert.AreEqual(result[0].Syntax, "python");
            Assert.AreEqual(result[0].SpecificTags, new SortedSet<string>(new[] { "constructor" }));
            Assert.AreEqual(result[0].AllTags, new SortedSet<string>(new[] { "constructor", "datetime", "python" }));
            Assert.AreEqual(result[0].Context.Name, "Date and Time Data Types and Tools");
            Assert.AreEqual(result[0].Context.Prerequisites, "from datatime import datetime");
            Assert.AreEqual(result[0].Context.Description, "http://pandas.pydata.org/");
            Assert.AreEqual(result[0].Context.Syntax, "python");
            Assert.AreEqual(result[0].Context.SpecificTags, new SortedSet<string>(new[] { "datetime", "python" }));
            Assert.AreEqual(result[0].Context.AllTags, new SortedSet<string>(new[] { "datetime", "python" }));
        }