Configuration manager class.
        /// <summary>
        /// Initializes Logger instance.
        /// </summary>
        /// <param name="configuration">Configuration for logger.</param>
        public Logger(SConfigManager configuration)
        {
            // Configuration passed from parent, who initialized this instance.
            _configuration = configuration;

            Console.WriteLine("Logs are saved to: " + _configuration.Settings["LogDirectory"]);

            _enabled = Convert.ToBoolean(_configuration.Settings["Enabled"]);
        }
        /// <summary>
        /// Monitor initializes application by reading configuration, parsing it and initializing child-components.
        /// </summary>
        public MonitorAgent()
        {
            // Get path to the configuration file using settings in app.config.
            // Standard configuration is used only to get the path to our custom configuration.
            string configurationFilePath =
                System.Configuration.ConfigurationManager.AppSettings[CONFIGURATION_SETTING_KEY];

            // Throw exception if cannot get information about xml configuration file.
            if (String.IsNullOrEmpty(configurationFilePath)) {
                throw new ArgumentException("Could not find setting with path to ther configuration file. "
                    +"Please check your config file contains key \""+
                    CONFIGURATION_SETTING_KEY+"\" and that key is set properly");
            }

            Console.WriteLine("Initializing configuration at root level...");
            // Use static method of SConfigManager class to read configuration from the file.
            string configurationXml = SConfigManager.ReadConfigFromFile(configurationFilePath);

            // Initialize SConfigManager using configuration string.
            _configuration = new SConfigManager(configurationXml);
            Console.WriteLine("Initialized." + System.Environment.NewLine);

            Console.WriteLine("Initializing logger...");
            // Initialize logger by passing child of root configuration into its constructor.
            logger = new Logger(_configuration.Children["Logger"]);

            logger.Log("Logger initialised.");
            Console.WriteLine("Logger initialized." + System.Environment.NewLine);

            // DirectoryWatchers
            if (_configuration.Children.ContainsKey("Watchers"))
            {
                // Iterate Children of "Watchers" child of root configuration
                foreach (KeyValuePair<string, SConfigManager> element in _configuration.Children["Watchers"].Children)
                {
                    SConfigManager config = (SConfigManager)element.Value;

                    // Initialize new directoryWatcher by passing configuration into its constructor.
                    Console.WriteLine("Initializing DirectoryWatcher: "  +config.Name + "...");
                    DirectoryWatcher directoryWatcher = new DirectoryWatcher(config);
                    directoryWatcher.LogHandler += new LogEventHandler(OnAction);
                    Console.WriteLine("DirectoryWatcher initialized: " + config.Name + "..."
                        + System.Environment.NewLine);

                    // Add new directoryWatcher to the list of directoryWatchers
                    _directoryWatchers.Add(directoryWatcher);
                }
            }

            Console.WriteLine("Watchers are now listening for any changes in watched directories."+
                "Make any action, like create or rename a file in those directories to see its working."
                + System.Environment.NewLine);
        }
        /// <summary>
        /// Initializes the DirectoryWatcher instance.
        /// </summary>
        /// <param name="configuration">Configuration object conatining all necessary configuration for 
        /// this class.</param>
        public DirectoryWatcher(SConfigManager configuration)
        {
            // Configuration passed from parent, who initialized this instance.
            _configuration = configuration;

            Console.WriteLine("Watched directory: : " + _configuration.Settings["Directory"]);

            _watcher = new FileSystemWatcher();
            _watcher.Path = _configuration.Settings["Directory"];
            _watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite;
            _watcher.Filter = _configuration.Settings["Filter"];
            _watcher.Created += new FileSystemEventHandler(OnCreated);
            _watcher.Renamed += new RenamedEventHandler(OnRenamed);
            _watcher.Deleted += new FileSystemEventHandler(OnDeleted);
            _watcher.EnableRaisingEvents = true;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TimConfigurationManager.ConfigurationManager"/> class. 
        /// It parses given configuration which have to be in proper XML format.
        /// </summary>
        /// <example>  
        /// This sample shows how to call the initialize the <see cref="TimConfigurationManager.ConfigurationManager"/> class.
        /// <code> 
        /// class TestClass  
        /// { 
        ///     static int Main()  
        ///     { 
        ///         // Prepare path to file with configuration
        ///         string pathToFile = "path/to/file.txt";
        /// 
        ///         // Call static method to read content of a configuration file
        ///         string configString = ConfigurationManager.ReadConfigFromFile(pathToFile);
        /// 
        ///         // Initialize new Configuration Manager class by passing string with configuration
        ///         ConfigurationManager configurationManager = new ConfigurationManager(configString);
        ///         
        ///         //...
        ///     } 
        /// } 
        /// </code> 
        /// </example> 
        /// <param name="configuration">String containing configuration (in XML format) to be parsed into object.</param>
        /// <exception cref="System.Exception"></exception>
        public SConfigManager(string configuration)
        {
            this._configXml = configuration;
            XmlDocument configXml = null;

            // Initializing XmlDocument
            try
            {
                configXml = new XmlDocument();
                configXml.LoadXml(configuration);
            }
            catch (Exception e)
            {
                Exception exception = new Exception("Cannot parse XML file", e);
                throw exception;
            }

            // Read Name of the configuration section
            try
            {
                Name = configXml.DocumentElement.Attributes["name"].Value;

                if (Name == "")
                {
                    throw new Exception();
                }
            }
            catch (Exception)
            {
                ArgumentException exception = new ArgumentException("Argument cannot null nor empty", "name");
                throw exception;
            }

            try
            {
                // parse settings
                Settings = new Dictionary<string, string>();

                XmlNodeList xnList = configXml.SelectNodes("/configuration/settings//setting");

                foreach (XmlNode xn in xnList)
                {
                    string key = xn.Attributes["key"].Value;
                    string value = xn.Attributes["value"].Value;
                    Settings.Add(key, value);
                }

                // get custom xml
                xnList = configXml.SelectNodes("/configuration/custom");

                if (xnList.Count > 0)
                {
                    CustomXml = xnList[0].InnerXml.ToString();
                }

                // get children
                Children = new Dictionary<string, SConfigManager>();

                xnList = configXml.SelectNodes("/configuration/children/configuration");

                if (xnList.Count > 0)
                {
                    foreach (XmlNode xmlNode in xnList)
                    {
                        SConfigManager childConfig = new SConfigManager(xmlNode.OuterXml.ToString());

                        Children.Add(childConfig.Name, childConfig);
                    }
                }
            }
            catch (Exception ex)
            {
                Exception exception = new Exception("Error while processing XML", ex);
                throw exception;
            }
        }