/// <summary>
        /// settings loaded from a file
        /// </summary>
        /// <param name="fileName">file name</param>
        /// <param name="converter"></param>
        /// <param name="deserializer">deserializer</param>
        public XmlFileSettings(string fileName, IStringConverter converter, IGenericDeserializer deserializer)
            : base(converter, deserializer)
        {
            try
            {
                fileName = System.IO.Path.GetFullPath(fileName);
                var content = File.ReadAllBytes(fileName);

                _root = XDocument.Load(new MemoryStream(content)).Root;
                Identity = this.GetIdentitySource(fileName);
                Path = System.IO.Path.GetDirectoryName(fileName);
                _fm = this.GetMonitoring(fileName, content);
            }
            catch(SystemException ex)
            {
                throw new ApplicationException(string.Format("Unable to load file `{0}'", fileName), ex);
            }
        }
        public void FileChange(WatchMode mode, int? ms)
        {
            TimeSpan? ts = null;
            if (ms != null)
                ts = TimeSpan.FromMilliseconds(ms.Value);

            string file = Path.GetTempFileName();
            File.WriteAllBytes(file, new byte[]{1, 2, 3});

            var m = new FileMonitor(file, new byte[] { 1, 2, 3 }, mode, ts);

            var wait = new ManualResetEvent(false);

            m.Changed += (a, e) =>
            {
                wait.Set();
            };

            var t = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                using (var fs = new FileStream(file, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
                {
                    fs.Position = 2;
                    fs.WriteByte(1);
                    fs.Close();
                };
            }, TaskCreationOptions.LongRunning);

            Task.WaitAll(t);

            Assert.IsTrue(wait.WaitOne(10000), "10 sec elapsed");

            wait.Reset();

            m.Changed += (a, e) =>
            {
                wait.Set();
            };

            Assert.IsTrue(wait.WaitOne(10000), "10 sec elapsed");
        }
        public IniFileSettings(string fileName, IStringConverter converter, IGenericDeserializer deserializer)
            : base(converter, deserializer)
        {
            try
            {
                fileName = System.IO.Path.GetFullPath(fileName);
                var content = File.ReadAllBytes(fileName);

                var context = new ParseContext();
                context.ParseSource(Encoding.UTF8.GetString(content));
                _sections = new List<Section>(context.Sections);

                Identity = this.GetIdentitySource(fileName);
                Path = System.IO.Path.GetDirectoryName(fileName);
                _fm = this.GetMonitoring(fileName, content);
            }
            catch(SystemException ex)
            {
                throw new ApplicationException(string.Format("Unable to load file `{0}'", fileName), ex);
            }
        }
        public JsonFileSettings(string fileName, IStringConverter converter, IGenericDeserializer deserializer)
            : base(converter, deserializer)
        {
            try
            {
                fileName = System.IO.Path.GetFullPath(fileName);
                var content = File.ReadAllBytes(fileName);

                var val = JValue.Parse(Encoding.UTF8.GetString(content));
                if (val.Type != TokenType.Object)
                    throw new FormatException("required json object in content");

                _obj = (JObject)val;

                Identity = this.GetIdentitySource(fileName);
                Path = System.IO.Path.GetDirectoryName(fileName);
                _fm = this.GetMonitoring(fileName, content);
            }
            catch(SystemException ex)
            {
                throw new ApplicationException(string.Format("Unable to load file `{0}'", fileName), ex);
            }
        }