static public IList<MetadataEntry> GetMetadata(string file)
		{
            var exifInvoker = new ExifToolInvoker();
			exifInvoker.Run("-a -j -g \"{0}\"", file);
			var info = JArray.Parse(exifInvoker.OutputString);

			var list = new List<MetadataEntry>();

			if (info.Count == 1)
			{
				foreach (var child in info[0].Children())
				{
					var prop = child as JProperty;
					if (prop != null)
					{
						foreach (var grandchild in child.Children())
						{
							var obj = grandchild as JObject;
							if (obj != null)
							{
								bool addedCategory = false;
								foreach (var kv in obj)
								{
									var val = ToString(kv.Value);
									if (val.StartsWith("(Binary data "))
									{
										continue;
									}

									var path = string.Format("{0}.{1}", prop.Name, kv.Key);
									if (IncludeInProperties.Contains(path))
									{
										AddProperty(list, kv);
									}

									if (ExcludedCategories.Contains(prop.Name))
									{
										continue;
									}

									bool isExcluded = false;
									foreach (var prefix in ExcludedElementsPrefix)
									{
										if (path.StartsWith(prefix, System.StringComparison.InvariantCultureIgnoreCase))
										{
											isExcluded = true;
											break;
										}
									}

									if (isExcluded)
									{
										continue;
									}

									if (!addedCategory)
									{
										list.Add(new MetadataEntry(prop.Name, null, null));
										addedCategory = true;
									}

									list.Add(new MetadataEntry(null, kv.Key, val));
								}
							}
						}
					}
				}
			}

			return list;
		}
        private IDictionary<string,JToken> GetExifData()
        {
            using (var timer = new LogTimer(logger, LogLevel.Error, "GetExifData for {0}", folderName))
            {
                var invoker = new ExifToolInvoker { TimeoutSeconds = Preferences.Instance.ExifToolTimeoutSeconds };
                invoker.Run("-a -j -g -x Directory -x FileAccessDate -x FileInodeChangeDate \"{0}\"", folderName);

                var result = new Dictionary<string,JToken>();
                var json = invoker.OutputString;
                if (!String.IsNullOrEmpty(json))
                {
                    json = json.Replace(baseFolder, "");

                    var info = JArray.Parse(json);
                    foreach (var obj in info)
                    {
                        var filename = (string) obj["SourceFile"];
                        result[filename.ToLower()] = obj;
                    }
                }

                return result;
            }
        }
        private IDictionary<string,JToken> BatchExifTool(string folder)
        {
            var invoker = new ExifToolInvoker { TimeoutSeconds = Preferences.Instance.ExifToolTimeoutSeconds };
            invoker.Run("-a -j -g -x Directory -x FileAccessDate -x FileInodeChangeDate \"{0}\"", folder);


            var result = new Dictionary<string,JToken>();
            var json = invoker.OutputString;
            if (!String.IsNullOrEmpty(json))
            {
                foreach (var folderPrefix in Preferences.Instance.FoldersToWatch)
                    json = json.Replace(folderPrefix, "");

                var info = JArray.Parse(json);
                foreach (var obj in info)
                {
                    var filename = (string) obj["SourceFile"];
                    result[filename.ToLower()] = obj;
                }
            }

            return result;
        }