Index: src/Core/Banshee.Base/Banshee.Metadata/MetadataProviderFactory.cs
===================================================================
--- src/Core/Banshee.Base/Banshee.Metadata/MetadataProviderFactory.cs	(revision 1933)
+++ src/Core/Banshee.Base/Banshee.Metadata/MetadataProviderFactory.cs	(working copy)
@@ -33,6 +33,7 @@
     public static class MetadataProviderFactory
     {
         private static Type [] providers = new Type [] {
+            typeof(Banshee.Metadata.Embedded.EmbeddedMetadataProvider),
             typeof(Banshee.Metadata.Rhapsody.RhapsodyMetadataProvider)
         };
         
Index: src/Core/Banshee.Base/Paths.cs
===================================================================
--- src/Core/Banshee.Base/Paths.cs	(revision 1933)
+++ src/Core/Banshee.Base/Paths.cs	(working copy)
@@ -76,11 +76,16 @@
             }
         }
         
-        public static string GetCoverArtPath(string asin)
+        public static string GetCoverArtPath(string artist_album_id)
         {
-            return CoverArtDirectory + asin + ".jpg";
+            return GetCoverArtPath(artist_album_id, ".jpg");
         }
         
+        public static string GetCoverArtPath(string artist_album_id, string extension)
+        {
+            return CoverArtDirectory + artist_album_id + extension;
+        }
+        
         public static string DefaultLibraryPath {
             get {
                 return Environment.GetFolderPath(
Index: src/Core/Banshee.Base/TrackInfo.cs
===================================================================
--- src/Core/Banshee.Base/TrackInfo.cs	(revision 1933)
+++ src/Core/Banshee.Base/TrackInfo.cs	(working copy)
@@ -163,6 +163,18 @@
             set { remote_lookup_status = value; }
         }
         
+        protected static string[] cover_names = { "cover", "Cover", "folder", "Folder" };
+        public static string[] CoverNames 
+        {
+            get { return TrackInfo.cover_names; }
+        }
+        
+        protected static string[] cover_extensions = { "jpg", "png", "jpeg", "gif" };
+        public static string[] CoverExtensions
+        {
+            get { return TrackInfo.cover_extensions; }
+        }
+        
         protected string cover_art_file = null;
         public string CoverArtFileName { 
             get {
@@ -175,11 +187,13 @@
                     cover_art_file = path;
                     return path;
                 }
-                
-                path = Paths.GetCoverArtPath(CreateArtistAlbumID(Artist, Album, false));
-                if(File.Exists(path)) {
-                    cover_art_file = path;
-                    return path;
+                                
+                foreach(string ext in TrackInfo.CoverExtensions) {
+                    path = Paths.GetCoverArtPath(CreateArtistAlbumID(Artist, Album, false), "." + ext);
+                    if(File.Exists(path)) {
+                        cover_art_file = path;
+                        return path;
+                    }
                 }
                
                 string basepath = Path.GetDirectoryName(Uri.AbsolutePath) + Path.DirectorySeparatorChar;
@@ -189,12 +203,9 @@
                     cover_art_file = path;
                     return path;
                 }
-               
-                string [] cover_names = { "cover", "Cover", "folder", "Folder" };
-                string [] cover_extensions = { "jpg", "png", "jpeg", "gif" };
                 
-                foreach(string cover in cover_names) {
-                    foreach(string ext in cover_extensions) {
+                foreach(string cover in TrackInfo.CoverNames) {
+                    foreach(string ext in TrackInfo.CoverExtensions) {
                         string img = basepath + cover + "." + ext;
                         if(File.Exists(img)) {
                             cover_art_file = img;
Index: src/Core/Banshee.Base/Banshee.Base.mdp
===================================================================
--- src/Core/Banshee.Base/Banshee.Base.mdp	(revision 1933)
+++ src/Core/Banshee.Base/Banshee.Base.mdp	(working copy)
@@ -98,6 +98,8 @@
     <File name="./Banshee.Metadata/SchedulerMetadataProvider.cs" subtype="Code" buildaction="Compile" />
     <File name="./Banshee.Metadata.Rhapsody/RhapsodyMetadataProvider.cs" subtype="Code" buildaction="Compile" />
     <File name="./Banshee.Metadata.Rhapsody/RhapsodyQueryJob.cs" subtype="Code" buildaction="Compile" />
+    <File name="./Banshee.Metadata.Embedded/EmbeddedMetadataProvider.cs" subtype="Code" buildaction="Compile" />
+    <File name="./Banshee.Metadata.Embedded/EmbeddedQueryJob.cs" subtype="Code" buildaction="Compile" />
     <File name="./Banshee.Playlists.Formats/M3u.cs" subtype="Code" buildaction="Compile" />
     <File name="./Banshee.Playlists.Formats/PlaylistFile.cs" subtype="Code" buildaction="Compile" />
     <File name="./Banshee.Playlists.Formats/Pls.cs" subtype="Code" buildaction="Compile" />
@@ -264,4 +266,4 @@
     <ProjectReference type="Project" localcopy="False" refto="BooBuddy" />
     <ProjectReference type="Project" localcopy="False" refto="Last.FM" />
   </References>
-</Project>
\ No newline at end of file
+</Project>
Index: src/Core/Banshee.Base/Banshee.Metadata.Embedded/EmbeddedMetadataProvider.cs
===================================================================
--- src/Core/Banshee.Base/Banshee.Metadata.Embedded/EmbeddedMetadataProvider.cs	(revision 0)
+++ src/Core/Banshee.Base/Banshee.Metadata.Embedded/EmbeddedMetadataProvider.cs	(revision 0)
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *  EmbeddedMetadataProvider.cs
+ *
+ *  Copyright (C) 2006-2007 Novell, Inc.
+ *  Written by Trey Ethridge <tale@juno.com>
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),  
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.Collections.Generic;
+
+using Banshee.Base;
+using Banshee.Metadata;
+
+namespace Banshee.Metadata.Embedded
+{
+    public class EmbeddedMetadataProvider : SchedulerMetadataProvider
+    {
+        public EmbeddedMetadataProvider() : base()
+        {
+        }
+        
+        protected override SchedulerMetadataLookupJob CreateJob(IBasicTrackInfo track)
+        {
+            return new EmbeddedQueryJob(track);
+        }
+    }
+}
Index: src/Core/Banshee.Base/Banshee.Metadata.Embedded/EmbeddedQueryJob.cs
===================================================================
--- src/Core/Banshee.Base/Banshee.Metadata.Embedded/EmbeddedQueryJob.cs	(revision 0)
+++ src/Core/Banshee.Base/Banshee.Metadata.Embedded/EmbeddedQueryJob.cs	(revision 0)
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *  EmbeddedQueryJob.cs
+ *
+ *  Copyright (C) 2006-2007 Novell, Inc.
+ *  Written by Trey Ethridge <tale@juno.com>
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),  
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.Collections.Generic;
+
+using Gdk;
+using TagLib;
+
+using Banshee.Base;
+using Banshee.Metadata;
+using Banshee.Kernel;
+
+namespace Banshee.Metadata.Embedded
+{
+    public class EmbeddedQueryJob : SchedulerMetadataLookupJob
+    {
+        private IBasicTrackInfo track;
+        private List<StreamTag> tags;
+        
+        public EmbeddedQueryJob(IBasicTrackInfo track)
+        {
+            this.track = track;
+        }
+        
+        public override void Run()
+        {
+            if (track == null || !(track is TrackInfo) || (track as TrackInfo).CoverArtFileName != null) {
+                return;
+            }
+                    
+            try {                
+                string embedded_cover_art_file = Fetch((track as TrackInfo));
+                if (embedded_cover_art_file != null) {
+                    (track as TrackInfo).CoverArtFileName = embedded_cover_art_file;
+                }
+            } catch {
+            }
+        }
+        
+        protected string Fetch(TrackInfo ti)
+        {
+            string image_path = null;
+            
+            if (ti == null) {
+                return image_path;
+            }
+            
+            string artist_album_id = TrackInfo.CreateArtistAlbumID(track.Artist, track.Album, false);
+
+            if (artist_album_id == null) {
+                return image_path;
+            }
+            
+            IPicture[] pictures = GetEmbeddedPictures(ti.Uri);
+                    
+            if (pictures != null && pictures.Length > 0) {
+                int preferred_index = GetPictureIndexToUse(pictures);
+                IPicture picture = pictures[preferred_index];
+                string path = Paths.GetCoverArtPath(artist_album_id, GetFileExtension(picture));
+                
+                if (SavePicture(picture, path)) {                                    
+                    tags = new List<StreamTag>();
+                    StreamTag tag = new StreamTag();
+                    tag.Name = CommonTags.AlbumCoverID;
+                    tag.Value = artist_album_id;
+                    tags.Add(tag);               
+                } 
+            }
+            
+            return image_path;
+        }
+
+        protected IPicture[] GetEmbeddedPictures(SafeUri uri)
+        {
+            TagLib.File file = StreamTagger.ProcessUri(uri);            
+            return file.Tag.Pictures;            
+        }
+        
+        protected int GetPictureIndexToUse(IPicture[] pictures)
+        {
+            int preferred_index = -1;
+            
+            // Use the front cover.  If we don't find it, use the first image. 
+            for (int i = 0; i < pictures.Length; i++) {
+                if (preferred_index == -1) {
+                    preferred_index = i;
+                }
+                
+                if (pictures[i].Type == PictureType.FrontCover) {
+                    preferred_index = i;
+                    break;
+                }
+            }
+            
+            return preferred_index;
+        }
+        
+        protected string GetFileExtension(IPicture picture)
+        {
+            string ext = "";
+            
+            string[] tokens = picture.MimeType.Split(new char[] {'/'});
+            if (tokens.Length == 2) {
+                ext = "." + tokens[1];
+            }
+            
+            return ext;
+        }
+        
+        protected bool SavePicture(IPicture picture, string image_path)
+        {
+            // If data is empty, return.
+            if (picture.Data.Count == 0) {
+                return false;
+            }
+            
+            // Write the byte array to a file.
+            System.IO.FileStream fs = null;
+            try {            
+                fs = System.IO.File.Create(image_path);
+            } catch {
+                // Unable to create input file.
+                return false;
+            }
+
+            // Write the byte array to it.
+            try {
+                byte[] data = picture.Data.Data;
+                fs.Write(data, 0, data.Length);
+            } catch {
+                // Unable to write to the file.
+                fs.Close();
+                return false;
+            }
+
+            // Close the file.
+            fs.Close();
+
+            return true;
+        }
+        
+        
+        public override IBasicTrackInfo Track {
+            get { return track; }
+        }
+        
+        public override IList<StreamTag> ResultTags {
+            get { return tags; }
+        }
+    }
+}
Index: src/Core/Banshee.Base/StreamTagger.cs
===================================================================
--- src/Core/Banshee.Base/StreamTagger.cs	(revision 1933)
+++ src/Core/Banshee.Base/StreamTagger.cs	(working copy)
@@ -149,7 +149,13 @@
                         track.MimeType = (string)tag.Value;
                         break;
                     case CommonTags.AlbumCoverID:
-                        track.CoverArtFileName = Paths.GetCoverArtPath((string)tag.Value);
+                        foreach(string ext in TrackInfo.CoverExtensions) {
+                            string path = Paths.GetCoverArtPath((string) tag.Value, "." + ext);
+                            if(System.IO.File.Exists(path)) {
+                                track.CoverArtFileName = path;
+                                break;
+                            }
+                        }
                         break;
                 }
             } catch {
Index: src/Core/Banshee.Base/Makefile.am
===================================================================
--- src/Core/Banshee.Base/Makefile.am	(revision 1933)
+++ src/Core/Banshee.Base/Makefile.am	(working copy)
@@ -146,6 +146,10 @@
 BANSHEE_METADATA_RHAPSODY_SOURCES = \
 	$(srcdir)/Banshee.Metadata.Rhapsody/RhapsodyMetadataProvider.cs \
 	$(srcdir)/Banshee.Metadata.Rhapsody/RhapsodyQueryJob.cs
+	
+BANSHEE_METADATA_EMBEDDED_SOURCES = \
+	$(srcdir)/Banshee.Metadata.Embedded/EmbeddedMetadataProvider.cs \
+	$(srcdir)/Banshee.Metadata.Embedded/EmbeddedQueryJob.cs
 
 IO_SOURCES = \
 	$(srcdir)/IO/Utilities.cs \
@@ -253,6 +257,7 @@
 	$(BANSHEE_CONFIGURATION_SCHEMA_SOURCES) \
 	$(BANSHEE_METADATA_SOURCES) \
 	$(BANSHEE_METADATA_RHAPSODY_SOURCES) \
+	$(BANSHEE_METADATA_EMBEDDED_SOURCES) \
 	$(NOTIFICATIONS_SOURCES) \
 	$(BANSHEE_AUDIOPROFILES_SOURCES) \
 	$(BANSHEE_AUDIOPROFILES_GUI_SOURCES) \
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 1933)
+++ ChangeLog	(working copy)
@@ -1,3 +1,22 @@
+2007-01-03  Trey Ethridge  <tale@juno.com>
+
+    * src/Core/Banshee.Base/Banshee.Metadata/MetadataProviderFactory.cs: Added
+    EmbeddedMetadataProvider.
+    * src/Core/Banshee.Base/Paths.cs: Added overloaded method to get
+    cover art path that takes the file extension
+    * src/Core/Banshee.Base/TrackInfo.cs: Updated CoverArtFileName to try all
+    possible file extensions that we support when using the new artist_album_id.    
+    * src/Core/Banshee.Base/Banshee.Base.mdp: Added the new files for the 
+    embedded metadata provider.
+    * src/Core/Banshee.Base/Banshee.Metadata.Embedded/EmbeddedMetadataProvider.cs:
+    Implements the metadata provider interface.    
+    * src/Core/Banshee.Base/Banshee.Metadata.Embedded/EmbeddedQueryJob.cs:
+    Does the work of retrieving the cover art from the file and caching it.
+    * src/Core/Banshee.Base/StreamTagger.cs: Updated TrackInfoMerge method
+    to use any file extension.  It was hard coded to only use ".jpg".
+    * src/Core/Banshee.Base/Makefile.am:
+    Added metadata provider to retrieve embedded cover art from music files.
+
 2007-01-02  Ruben Vermeersch  <ruben@savanne.be>
 
 	* src/Plugins/Banshee.Plugins.NotificationAreaIcon/NotificationAreaIconPlugin.cs: 
