/// <summary>
        /// Add items to the specified collection from metadata accessed through the Windows Presentation Foundation (WPF)
        /// classes. This includes the following items: Title, Author, Data taken, Camera model, Camera manufacturer, Keywords,
        /// Rating, Comment, Copyright, Subject. If any of these items are null, they are not added.
        /// </summary>
        /// <param name="imageFilePath">The image file path.</param>
        /// <param name="metadataItems">The collection of <see cref="IGalleryObjectMetadataItem" /> objects to add to.</param>
        /// <exception cref="System.Security.SecurityException">This function requires running under Full Trust, and will
        /// throw a security exception if it doesn't have it.</exception>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="metadataItems" /> is null.</exception>
        public static void AddWpfBitmapMetadata(string imageFilePath, IGalleryObjectMetadataItemCollection metadataItems)
        {
            if (metadataItems == null)
                throw new ArgumentNullException("metadataItems");

            BitmapMetadata bmpMetadata = GetBitmapMetadata(imageFilePath);

            if (bmpMetadata != null)
            {
                AddGpsMetadata(bmpMetadata, metadataItems);

                AddIptcMetadata(bmpMetadata, metadataItems);

                try
                {
                    if ((bmpMetadata.Title != null) && (!String.IsNullOrEmpty(bmpMetadata.Title.Trim())))
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Title, Resources.Metadata_Title, bmpMetadata.Title.Trim(), true);

                    if (bmpMetadata.Author != null)
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Author, Resources.Metadata_Author, ConvertStringCollectionToDelimitedString(bmpMetadata.Author), true);

                    if (bmpMetadata.DateTaken != null)
                    {
                        DateTime dateTaken = TryParseDate(bmpMetadata.DateTaken);
                        if (dateTaken.Year > DateTime.MinValue.Year)
                        {
                            metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.DatePictureTaken, Resources.Metadata_DatePictureTaken, dateTaken.ToString(DateTimeFormatStringForMetadata, CultureInfo.InvariantCulture), true);
                        }
                    }

                    if ((bmpMetadata.CameraModel != null) && (!String.IsNullOrEmpty(bmpMetadata.CameraModel.Trim())))
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.CameraModel, Resources.Metadata_CameraModel, bmpMetadata.CameraModel.Trim(), true);

                    if ((bmpMetadata.CameraManufacturer != null) && (!String.IsNullOrEmpty(bmpMetadata.CameraManufacturer.Trim())))
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.EquipmentManufacturer, Resources.Metadata_EquipmentManufacturer, bmpMetadata.CameraManufacturer.Trim(), true);

                    if (bmpMetadata.Keywords != null)
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Keywords, Resources.Metadata_Keywords, ConvertStringCollectionToDelimitedString(bmpMetadata.Keywords), true);

                    if (bmpMetadata.Rating > 0)
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Rating, Resources.Metadata_Rating, bmpMetadata.Rating.ToString(CultureInfo.InvariantCulture), true);

                    if ((bmpMetadata.Comment != null) && (!String.IsNullOrEmpty(bmpMetadata.Comment.Trim())))
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Comment, Resources.Metadata_Comment, bmpMetadata.Comment.Trim(), true);

                    if ((bmpMetadata.Copyright != null) && (!String.IsNullOrEmpty(bmpMetadata.Copyright.Trim())))
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Copyright, Resources.Metadata_Copyright, bmpMetadata.Copyright.Trim(), true);

                    if ((bmpMetadata.Subject != null) && (!String.IsNullOrEmpty(bmpMetadata.Subject.Trim())))
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Subject, Resources.Metadata_Subject, bmpMetadata.Subject.Trim(), true);
                }
                catch (NotSupportedException) { } // Some image types, such as png, throw a NotSupportedException. Let's swallow them and move on.
            }
        }
        /// <summary>
        /// Adds GPS data from the <paramref name="bmpMetadata" /> to the <paramref name="metadataItems" /> collection.
        /// </summary>
        /// <param name="bmpMetadata">An object containing the metadata.</param>
        /// <param name="metadataItems">The metadata items.</param>
        private static void AddGpsMetadata(BitmapMetadata bmpMetadata, IGalleryObjectMetadataItemCollection metadataItems)
        {
            GpsLocation gps = GpsLocation.Parse(bmpMetadata);

            if (!String.IsNullOrEmpty(gps.Version))
            {
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsVersion, GetResource(FormattedMetadataItemName.GpsVersion), gps.Version, true);
            }

            if ((gps.Latitude != null) && (gps.Longitude != null))
            {
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsLocation, GetResource(FormattedMetadataItemName.GpsLocation), gps.ToLatitudeLongitudeDecimalString(), true);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsLatitude, GetResource(FormattedMetadataItemName.GpsLatitude), gps.Latitude.ToDouble().ToString("F6", CultureInfo.InvariantCulture), true);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsLongitude, GetResource(FormattedMetadataItemName.GpsLongitude), gps.Longitude.ToDouble().ToString("F6", CultureInfo.InvariantCulture), true);
            }

            if (gps.Altitude.HasValue)
            {
                string altitude = String.Concat(gps.Altitude.Value.ToString("N0", CultureInfo.CurrentCulture), " ", Resources.Metadata_meters);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsAltitude, GetResource(FormattedMetadataItemName.GpsAltitude), altitude, true);
            }

            if ((gps.DestLatitude != null) && (gps.DestLongitude != null))
            {
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsDestLocation, GetResource(FormattedMetadataItemName.GpsDestLocation), gps.ToDestLatitudeLongitudeDecimalString(), true);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsDestLatitude, GetResource(FormattedMetadataItemName.GpsDestLatitude), gps.DestLatitude.ToDouble().ToString("F6", CultureInfo.InvariantCulture), true);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsDestLongitude, GetResource(FormattedMetadataItemName.GpsDestLongitude), gps.DestLongitude.ToDouble().ToString("F6", CultureInfo.InvariantCulture), true);
            }
        }
		/// <summary>
		/// Add items to the specified collection from metadata accessed through the Windows Presentation Foundation (WPF)
		/// classes. This includes the following items: Title, Author, Data taken, Camera model, Camera manufacturer, Keywords,
		/// Rating, Comment, Copyright, Subject. If any of these items are null, they are not added.
		/// </summary>
		/// <param name="imageFilePath">The image file path.</param>
		/// <param name="metadataItems">The collection of <see cref="IGalleryObjectMetadataItem" /> objects to add to.</param>
		/// <exception cref="System.Security.SecurityException">This function requires running under Full Trust, and will
		/// throw a security exception if it doesn't have it.</exception>
		public static void AddWpfBitmapMetadata(string imageFilePath, IGalleryObjectMetadataItemCollection metadataItems)
		{
			//return;
			BitmapMetadata bmpMetadata = GetBitmapMetadata(imageFilePath);

			if (bmpMetadata != null)
			{
				try
				{
					if (bmpMetadata.Title != null)
						metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Title, Resources.Metadata_Title, bmpMetadata.Title, true);

					if (bmpMetadata.Author != null)
						metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Author, Resources.Metadata_Author, ConvertStringCollectionToDelimitedString(bmpMetadata.Author), true);

					if (bmpMetadata.DateTaken != null)
					{
						DateTime dateTaken;
						if (DateTime.TryParse(bmpMetadata.DateTaken, out dateTaken))
						{
							metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.DatePictureTaken, Resources.Metadata_DatePictureTaken, dateTaken.ToString("R", CultureInfo.InvariantCulture), true);
						}
					}

					if (bmpMetadata.CameraModel != null)
						metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.CameraModel, Resources.Metadata_CameraModel, bmpMetadata.CameraModel, true);

					if (bmpMetadata.CameraManufacturer != null)
						metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.EquipmentManufacturer, Resources.Metadata_EquipmentManufacturer, bmpMetadata.CameraManufacturer, true);

					if (bmpMetadata.Keywords != null)
						metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Keywords, Resources.Metadata_Keywords, ConvertStringCollectionToDelimitedString(bmpMetadata.Keywords), true);

					// Rating is an int, so we can't check for null.
					metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Rating, Resources.Metadata_Rating, bmpMetadata.Rating.ToString(CultureInfo.InvariantCulture), true);

					if (bmpMetadata.Comment != null)
						metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Comment, Resources.Metadata_Comment, bmpMetadata.Comment, true);

					if (bmpMetadata.Copyright != null)
						metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Copyright, Resources.Metadata_Copyright, bmpMetadata.Copyright, true);

					if (bmpMetadata.Subject != null)
						metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Subject, Resources.Metadata_Subject, bmpMetadata.Subject, true);
				}
				catch (NotSupportedException) { } // Some image types, such as png, throw a NotSupportedException. Let's swallow them and move on.
			}

		}
        private static void AddIptcMetadata(BitmapMetadata bmpMetadata, IGalleryObjectMetadataItemCollection metadataItems)
        {
            foreach (KeyValuePair <FormattedMetadataItemName, string> iptcQueryParm in GetIptcQueryParameters())
            {
                string iptcValue;
                try
                {
                    iptcValue = bmpMetadata.GetQuery(String.Format(CultureInfo.InvariantCulture, IptcQueryFormatString, iptcQueryParm.Value)) as string;
                }
                catch (InvalidOperationException)
                {
                    // Some images throw this exception. When this happens, just exit.
                    break;
                }

                if (!String.IsNullOrEmpty(iptcValue))
                {
                    switch (iptcQueryParm.Key)
                    {
                    case FormattedMetadataItemName.IptcDateCreated:
                    {
                        DateTime dateTaken = TryParseDate(iptcValue);

                        if (dateTaken.Year > DateTime.MinValue.Year)
                        {
                            metadataItems.AddNew(int.MinValue, iptcQueryParm.Key, GetResource(iptcQueryParm.Key), dateTaken.ToString(DateTimeFormatStringForMetadata, CultureInfo.InvariantCulture), true);
                        }
                        break;
                    }

                    default:
                    {
                        metadataItems.AddNew(int.MinValue, iptcQueryParm.Key, GetResource(iptcQueryParm.Key), iptcValue, true);
                        break;
                    }
                    }
                }
            }
        }
        /// <summary>
        /// Adds GPS data from the <paramref name="bmpMetadata" /> to the <paramref name="metadataItems" /> collection.
        /// </summary>
        /// <param name="bmpMetadata">An object containing the metadata.</param>
        /// <param name="metadataItems">The metadata items.</param>
        private static void AddGpsMetadata(BitmapMetadata bmpMetadata, IGalleryObjectMetadataItemCollection metadataItems)
        {
            GpsLocation gps = GpsLocation.Parse(bmpMetadata);

            if (!String.IsNullOrEmpty(gps.Version))
            {
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsVersion, GetResource(FormattedMetadataItemName.GpsVersion), gps.Version, true);
            }

            if ((gps.Latitude != null) && (gps.Longitude != null))
            {
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsLocation, GetResource(FormattedMetadataItemName.GpsLocation), gps.ToLatitudeLongitudeDecimalString(), true);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsLatitude, GetResource(FormattedMetadataItemName.GpsLatitude), gps.Latitude.ToDouble().ToString("F6", CultureInfo.InvariantCulture), true);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsLongitude, GetResource(FormattedMetadataItemName.GpsLongitude), gps.Longitude.ToDouble().ToString("F6", CultureInfo.InvariantCulture), true);
            }

            if (gps.Altitude.HasValue)
            {
                string altitude = String.Concat(gps.Altitude.Value.ToString("N0", CultureInfo.CurrentCulture), " ", Resources.Metadata_meters);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsAltitude, GetResource(FormattedMetadataItemName.GpsAltitude), altitude, true);
            }

            if ((gps.DestLatitude != null) && (gps.DestLongitude != null))
            {
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsDestLocation, GetResource(FormattedMetadataItemName.GpsDestLocation), gps.ToDestLatitudeLongitudeDecimalString(), true);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsDestLatitude, GetResource(FormattedMetadataItemName.GpsDestLatitude), gps.DestLatitude.ToDouble().ToString("F6", CultureInfo.InvariantCulture), true);
                metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.GpsDestLongitude, GetResource(FormattedMetadataItemName.GpsDestLongitude), gps.DestLongitude.ToDouble().ToString("F6", CultureInfo.InvariantCulture), true);
            }
        }
        private static void AddIptcMetadata(BitmapMetadata bmpMetadata, IGalleryObjectMetadataItemCollection metadataItems)
        {
            foreach (KeyValuePair<FormattedMetadataItemName, string> iptcQueryParm in GetIptcQueryParameters())
            {
                string iptcValue = bmpMetadata.GetQuery(String.Format(CultureInfo.InvariantCulture, IptcQueryFormatString, iptcQueryParm.Value)) as string;

                if (!String.IsNullOrEmpty(iptcValue))
                {
                    switch (iptcQueryParm.Key)
                    {
                        case FormattedMetadataItemName.IptcDateCreated:
                            {
                                DateTime dateTaken = TryParseDate(iptcValue);

                                if (dateTaken.Year > DateTime.MinValue.Year)
                                {
                                    metadataItems.AddNew(int.MinValue, iptcQueryParm.Key, GetResource(iptcQueryParm.Key), dateTaken.ToString(DateTimeFormatStringForMetadata, CultureInfo.InvariantCulture), true);
                                }
                                break;
                            }
                        default:
                            {
                                metadataItems.AddNew(int.MinValue, iptcQueryParm.Key, GetResource(iptcQueryParm.Key), iptcValue, true);
                                break;
                            }
                    }
                }
            }
        }
        /// <summary>
        /// Add items to the specified collection from metadata accessed through the Windows Presentation Foundation (WPF)
        /// classes. This includes the following items: Title, Author, Data taken, Camera model, Camera manufacturer, Keywords,
        /// Rating, Comment, Copyright, Subject. If any of these items are null, they are not added.
        /// </summary>
        /// <param name="imageFilePath">The image file path.</param>
        /// <param name="metadataItems">The collection of <see cref="IGalleryObjectMetadataItem" /> objects to add to.</param>
        /// <exception cref="System.Security.SecurityException">This function requires running under Full Trust, and will
        /// throw a security exception if it doesn't have it.</exception>
        public static void AddWpfBitmapMetadata(string imageFilePath, IGalleryObjectMetadataItemCollection metadataItems)
        {
            //return;
            BitmapMetadata bmpMetadata = GetBitmapMetadata(imageFilePath);

            if (bmpMetadata != null)
            {
                try
                {
                    if (bmpMetadata.Title != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Title, Resources.Metadata_Title, bmpMetadata.Title, true);
                    }

                    if (bmpMetadata.Author != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Author, Resources.Metadata_Author, ConvertStringCollectionToDelimitedString(bmpMetadata.Author), true);
                    }

                    if (bmpMetadata.DateTaken != null)
                    {
                        DateTime dateTaken;
                        if (DateTime.TryParse(bmpMetadata.DateTaken, out dateTaken) && (dateTaken.Year > DateTime.MinValue.Year))
                        {
                            metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.DatePictureTaken, Resources.Metadata_DatePictureTaken, dateTaken.ToString("R", CultureInfo.InvariantCulture), true);
                        }
                    }

                    if (bmpMetadata.CameraModel != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.CameraModel, Resources.Metadata_CameraModel, bmpMetadata.CameraModel, true);
                    }

                    if (bmpMetadata.CameraManufacturer != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.EquipmentManufacturer, Resources.Metadata_EquipmentManufacturer, bmpMetadata.CameraManufacturer, true);
                    }

                    if (bmpMetadata.Keywords != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Keywords, Resources.Metadata_Keywords, ConvertStringCollectionToDelimitedString(bmpMetadata.Keywords), true);
                    }

                    // Rating is an int, so we can't check for null.
                    metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Rating, Resources.Metadata_Rating, bmpMetadata.Rating.ToString(CultureInfo.InvariantCulture), true);

                    if (bmpMetadata.Comment != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Comment, Resources.Metadata_Comment, bmpMetadata.Comment, true);
                    }

                    if (bmpMetadata.Copyright != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Copyright, Resources.Metadata_Copyright, bmpMetadata.Copyright, true);
                    }

                    if (bmpMetadata.Subject != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Subject, Resources.Metadata_Subject, bmpMetadata.Subject, true);
                    }
                }
                catch (NotSupportedException) { }                 // Some image types, such as png, throw a NotSupportedException. Let's swallow them and move on.
            }
        }
        /// <summary>
        /// Add items to the specified collection from metadata accessed through the Windows Presentation Foundation (WPF)
        /// classes. This includes the following items: Title, Author, Data taken, Camera model, Camera manufacturer, Keywords,
        /// Rating, Comment, Copyright, Subject. If any of these items are null, they are not added.
        /// </summary>
        /// <param name="imageFilePath">The image file path.</param>
        /// <param name="metadataItems">The collection of <see cref="IGalleryObjectMetadataItem" /> objects to add to.</param>
        /// <exception cref="System.Security.SecurityException">This function requires running under Full Trust, and will
        /// throw a security exception if it doesn't have it.</exception>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="metadataItems" /> is null.</exception>
        public static void AddWpfBitmapMetadata(string imageFilePath, IGalleryObjectMetadataItemCollection metadataItems)
        {
            if (metadataItems == null)
            {
                throw new ArgumentNullException("metadataItems");
            }

            BitmapMetadata bmpMetadata = GetBitmapMetadata(imageFilePath);

            if (bmpMetadata != null)
            {
                AddGpsMetadata(bmpMetadata, metadataItems);

                AddIptcMetadata(bmpMetadata, metadataItems);

                try
                {
                    if ((bmpMetadata.Title != null) && (!String.IsNullOrEmpty(bmpMetadata.Title.Trim())))
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Title, Resources.Metadata_Title, bmpMetadata.Title.Trim(), true);
                    }

                    if (bmpMetadata.Author != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Author, Resources.Metadata_Author, ConvertStringCollectionToDelimitedString(bmpMetadata.Author), true);
                    }

                    if (bmpMetadata.DateTaken != null)
                    {
                        DateTime dateTaken = TryParseDate(bmpMetadata.DateTaken);
                        if (dateTaken.Year > DateTime.MinValue.Year)
                        {
                            metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.DatePictureTaken, Resources.Metadata_DatePictureTaken, dateTaken.ToString(DateTimeFormatStringForMetadata, CultureInfo.InvariantCulture), true);
                        }
                    }

                    if ((bmpMetadata.CameraModel != null) && (!String.IsNullOrEmpty(bmpMetadata.CameraModel.Trim())))
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.CameraModel, Resources.Metadata_CameraModel, bmpMetadata.CameraModel.Trim(), true);
                    }

                    if ((bmpMetadata.CameraManufacturer != null) && (!String.IsNullOrEmpty(bmpMetadata.CameraManufacturer.Trim())))
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.EquipmentManufacturer, Resources.Metadata_EquipmentManufacturer, bmpMetadata.CameraManufacturer.Trim(), true);
                    }

                    if (bmpMetadata.Keywords != null)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Keywords, Resources.Metadata_Keywords, ConvertStringCollectionToDelimitedString(bmpMetadata.Keywords), true);
                    }

                    if (bmpMetadata.Rating > 0)
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Rating, Resources.Metadata_Rating, bmpMetadata.Rating.ToString(CultureInfo.InvariantCulture), true);
                    }

                    if ((bmpMetadata.Comment != null) && (!String.IsNullOrEmpty(bmpMetadata.Comment.Trim())))
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Comment, Resources.Metadata_Comment, bmpMetadata.Comment.Trim(), true);
                    }

                    if ((bmpMetadata.Copyright != null) && (!String.IsNullOrEmpty(bmpMetadata.Copyright.Trim())))
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Copyright, Resources.Metadata_Copyright, bmpMetadata.Copyright.Trim(), true);
                    }

                    if ((bmpMetadata.Subject != null) && (!String.IsNullOrEmpty(bmpMetadata.Subject.Trim())))
                    {
                        metadataItems.AddNew(int.MinValue, FormattedMetadataItemName.Subject, Resources.Metadata_Subject, bmpMetadata.Subject.Trim(), true);
                    }
                }
                catch (NotSupportedException) { }                 // Some image types, such as png, throw a NotSupportedException. Let's swallow them and move on.
                catch (ArgumentException) { }
                catch (InvalidOperationException) { }
            }
        }