diff --git a/podcast/Makefile.am b/podcast/Makefile.am
index c1af587..4896f07 100644
--- a/podcast/Makefile.am
+++ b/podcast/Makefile.am
@@ -14,7 +14,9 @@ librbpodcast_la_SOURCES =				\
 	rb-podcast-parse.c				\
 	rb-podcast-parse.h				\
 	rb-podcast-manager.c				\
-	rb-podcast-manager.h
+	rb-podcast-manager.h				\
+	rb-podcast-bookmark-callbacks.c			\
+	rb-podcast-bookmark-callbacks.h
 librbpodcast_la_LIBADD =				\
 	librbpodcast_parse.la
 
@@ -35,6 +37,8 @@ INCLUDES =						\
 	-I$(top_srcdir)/shell				\
 	-I$(top_srcdir)/metadata			\
 	-I$(top_srcdir)/library				\
+	-I$(top_srcdir)/sources				\
+	-I$(top_srcdir)/backends			\
 	-I$(top_builddir)/lib 				\
 	$(RHYTHMBOX_CFLAGS)
 
diff --git a/podcast/rb-podcast-bookmark-callbacks.c b/podcast/rb-podcast-bookmark-callbacks.c
new file mode 100644
index 0000000..860a94e
--- /dev/null
+++ b/podcast/rb-podcast-bookmark-callbacks.c
@@ -0,0 +1,51 @@
+#include "rhythmdb.h"
+#include "rb-shell-player.h"
+#include "rb-player.h"
+#include "rb-debug.h"
+#include "rb-podcast-bookmark-callbacks.h"
+
+void
+rb_podcast_song_changing_cb (RBShellPlayer *player, RhythmDBEntry *old_entry)
+{
+	if (old_entry) {
+		if (rhythmdb_entry_get_entry_type (old_entry) == 
+		    RHYTHMDB_ENTRY_TYPE_PODCAST_POST) {
+			guint cur_time;
+			RhythmDB * db;
+
+			// FIXME look at GError (last argument)
+			rb_shell_player_get_playing_time(player, &cur_time, NULL);
+			gulong duration = rhythmdb_entry_get_ulong (old_entry, RHYTHMDB_PROP_DURATION);
+			GValue val = {0,};
+		
+			/* save the position, if not withing 5 seconds of either end */
+			if ((cur_time < 5) || (cur_time > duration - 5))
+				cur_time = 0;
+		
+			rb_debug ("saving podcast playback position %u", cur_time);
+			g_value_init (&val, G_TYPE_ULONG);
+			g_value_set_ulong (&val, cur_time);
+
+			g_object_get (player, "db", &db, NULL);
+			g_assert (db != NULL);
+			rhythmdb_entry_set (db, old_entry, RHYTHMDB_PROP_PLAYBACK_POS, &val);
+			g_object_unref (db);
+
+			g_value_unset (&val);
+		}
+	}
+ }
+
+void
+rb_podcast_recall_position_cb (RBShellPlayer *player, RhythmDBEntry * entry)
+{
+ 	if (entry && 
+	    rhythmdb_entry_get_entry_type (entry) == RHYTHMDB_ENTRY_TYPE_PODCAST_POST) {
+ 		gulong save_time = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_PLAYBACK_POS);
+ 		rb_debug ("restoring podcast playback position %lu", save_time);
+		// FIXME look at GError (last argument)
+		rb_shell_player_set_playing_time(player, save_time, NULL);
+ 	}
+}
+
+
diff --git a/podcast/rb-podcast-bookmark-callbacks.h b/podcast/rb-podcast-bookmark-callbacks.h
new file mode 100644
index 0000000..962379a
--- /dev/null
+++ b/podcast/rb-podcast-bookmark-callbacks.h
@@ -0,0 +1,7 @@
+#ifndef RB_PODCAST_BOOKMARK_CALLBACKS_H
+#define RB_PODCAST_BOOKMARK_CALLBACKS_H
+
+void rb_podcast_song_changing_cb (RBShellPlayer *player, RhythmDBEntry *entry);
+void rb_podcast_recall_position_cb(RBShellPlayer *player, RhythmDBEntry * entry);
+
+#endif /* RB_PODCAST_BOOKMARK_CALLBACKS_H */
diff --git a/rhythmdb/rhythmdb-private.h b/rhythmdb/rhythmdb-private.h
index 30726f5..ebe6c08 100644
--- a/rhythmdb/rhythmdb-private.h
+++ b/rhythmdb/rhythmdb-private.h
@@ -52,6 +52,7 @@ typedef struct {
 			   102: wait
 			   103: pause */
 	gulong post_time;
+ 	gulong playback_pos; /* saved playback position */
 } RhythmDBPodcastFields;
 
 enum {
diff --git a/rhythmdb/rhythmdb-tree.c b/rhythmdb/rhythmdb-tree.c
index 96dd3a5..c07cb83 100644
--- a/rhythmdb/rhythmdb-tree.c
+++ b/rhythmdb/rhythmdb-tree.c
@@ -1004,6 +1004,10 @@ save_entry (RhythmDBTree *db,
 			if (podcast)
 				save_entry_ulong (ctx, elt_name, podcast->post_time, FALSE);
 			break;
+ 		case RHYTHMDB_PROP_PLAYBACK_POS:
+ 			if (podcast)
+ 				save_entry_ulong (ctx, elt_name, podcast->playback_pos, FALSE);
+  			break;			
 		case RHYTHMDB_PROP_KEYWORD:
 			keywords = rhythmdb_entry_keywords_get (RHYTHMDB (db), entry);
 
diff --git a/rhythmdb/rhythmdb.c b/rhythmdb/rhythmdb.c
index d93f9d5..fde667b 100644
--- a/rhythmdb/rhythmdb.c
+++ b/rhythmdb/rhythmdb.c
@@ -2917,6 +2917,10 @@ rhythmdb_entry_set_internal (RhythmDB *db,
 			g_assert (podcast);
 			podcast->post_time = g_value_get_ulong (value);
 			break;
+ 		case RHYTHMDB_PROP_PLAYBACK_POS:
+			g_assert (podcast);
+ 			podcast->playback_pos = g_value_get_ulong (value);
+ 			break;	
 		case RHYTHMDB_NUM_PROPERTIES:
 			g_assert_not_reached ();
 			break;
@@ -3676,7 +3680,7 @@ rhythmdb_prop_type_get_type (void)
 			ENUM_ENTRY (RHYTHMDB_PROP_COPYRIGHT, "Podcast copyright (gchararray) [copyright]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_IMAGE, "Podcast image(gchararray) [image]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_POST_TIME, "Podcast time of post (gulong) [post-time]"),
-
+ 			ENUM_ENTRY (RHYTHMDB_PROP_PLAYBACK_POS, "Saved playback position (gulong) [playback-position]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_KEYWORD, "Keywords applied to track (gchararray) [keyword]"),
 			{ 0, 0, 0 }
 		};
@@ -4607,6 +4611,11 @@ rhythmdb_entry_get_ulong (RhythmDBEntry *entry,
 			return podcast->post_time;
 		else
 			return 0;
+ 	case RHYTHMDB_PROP_PLAYBACK_POS:
+ 		if (podcast)
+ 			return podcast->playback_pos;
+  		else
+  			return 0;
 	case RHYTHMDB_PROP_STATUS:
 		if (podcast)
 			return podcast->status;
diff --git a/rhythmdb/rhythmdb.h b/rhythmdb/rhythmdb.h
index 2b91b65..3a83f1f 100644
--- a/rhythmdb/rhythmdb.h
+++ b/rhythmdb/rhythmdb.h
@@ -203,6 +203,8 @@ typedef enum
 	RHYTHMDB_PROP_MUSICBRAINZ_ALBUMARTISTID,
 	RHYTHMDB_PROP_MUSICBRAINZ_ARTISTSORTNAME,
 
+ 	RHYTHMDB_PROP_PLAYBACK_POS, 	
+
 	RHYTHMDB_NUM_PROPERTIES
 } RhythmDBPropType;
 
diff --git a/shell/rb-shell-player.c b/shell/rb-shell-player.c
index 4b554c4..da24147 100644
--- a/shell/rb-shell-player.c
+++ b/shell/rb-shell-player.c
@@ -62,6 +62,7 @@
 #include "rhythmdb.h"
 #include "rb-podcast-manager.h"
 #include "rb-marshal.h"
+#include "rb-podcast-bookmark-callbacks.h"
 
 /* Play Orders */
 #include "rb-play-order-linear.h"
@@ -277,6 +278,7 @@ enum
 	PLAYING_SONG_CHANGED,
 	PLAYING_URI_CHANGED,
 	PLAYING_SONG_PROPERTY_CHANGED,
+	PLAYING_SONG_CHANGING,
 	LAST_SIGNAL
 };
 
@@ -480,6 +482,17 @@ rb_shell_player_class_init (RBShellPlayerClass *klass)
 			      1,
 			      RHYTHMDB_TYPE_ENTRY);
 
+	rb_shell_player_signals[PLAYING_SONG_CHANGING] =
+		g_signal_new ("playing-song-changing",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBShellPlayerClass, playing_song_changing),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__BOXED,
+			      G_TYPE_NONE,
+			      1,
+			      RHYTHMDB_TYPE_ENTRY);
+
 	rb_shell_player_signals[PLAYING_URI_CHANGED] =
 		g_signal_new ("playing-uri-changed",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -551,6 +564,9 @@ rb_shell_player_constructor (GType type,
 			  G_CALLBACK (rb_shell_player_playing_changed_cb),
 			  NULL);
 
+	klass->playing_song_changing = rb_podcast_song_changing_cb;
+	klass->playing_song_changed = rb_podcast_recall_position_cb;
+
 	return G_OBJECT (player);
 }
 
@@ -1015,6 +1031,7 @@ static void
 rb_shell_player_dispose (GObject *object)
 {
 	RBShellPlayer *player;
+	RhythmDBEntry *entry;
 
 	g_return_if_fail (object != NULL);
 	g_return_if_fail (RB_IS_SHELL_PLAYER (object));
@@ -1023,6 +1040,11 @@ rb_shell_player_dispose (GObject *object)
 
 	g_return_if_fail (player->priv != NULL);
 
+	entry = rb_shell_player_get_playing_entry (player);
+	g_signal_emit (G_OBJECT (player),
+		       rb_shell_player_signals[PLAYING_SONG_CHANGING], 0,
+		       entry);
+
 	if (player->priv->gconf_play_order_id != 0) {
 		eel_gconf_notification_remove (player->priv->gconf_play_order_id);
 		player->priv->gconf_play_order_id = 0;
@@ -1503,7 +1525,6 @@ rb_shell_player_set_playing_entry (RBShellPlayer *player,
 	if (rb_shell_player_open_location (player, entry, play_type, error) == FALSE) {
 		goto lose;
 	}
-
 	rb_shell_player_sync_replaygain (player, entry);
 
 	rb_debug ("Success!");
@@ -2678,6 +2699,12 @@ void
 rb_shell_player_set_playing_source (RBShellPlayer *player,
 				    RBSource *source)
 {
+	RhythmDBEntry *entry;
+	entry = rb_shell_player_get_playing_entry (player);
+	g_signal_emit (G_OBJECT (player),
+		       rb_shell_player_signals[PLAYING_SONG_CHANGING], 0,
+		       entry);
+
 	rb_shell_player_set_playing_source_internal (player, source, TRUE);
 }
 
@@ -3003,6 +3030,7 @@ new_playing_stream_idle_cb (RBShellPlayer *player)
 	entry = rb_shell_player_get_playing_entry (player);
 	location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
 	rb_debug ("new playing stream: %s", location);
+
 	g_signal_emit (G_OBJECT (player),
 		       rb_shell_player_signals[PLAYING_SONG_CHANGED], 0,
 		       entry);
diff --git a/shell/rb-shell-player.h b/shell/rb-shell-player.h
index 7882e04..cc12e69 100644
--- a/shell/rb-shell-player.h
+++ b/shell/rb-shell-player.h
@@ -78,6 +78,7 @@ typedef struct
 					       const char *property,
 					       GValue *old,
 					       GValue *newValue);
+	void (*playing_song_changing) (RBShellPlayer *player, RhythmDBEntry *entry);
 } RBShellPlayerClass;
 
 GType			rb_shell_player_get_type   (void);
diff --git a/widgets/rb-header.c b/widgets/rb-header.c
index 6eb229a..1e4e82f 100644
--- a/widgets/rb-header.c
+++ b/widgets/rb-header.c
@@ -479,17 +479,13 @@ rb_header_sync_time (RBHeader *header)
 	seconds = header->priv->elapsed_time;
 
 	if (header->priv->duration > 0) {
-		double progress = 0.0;
-
-		if (seconds > 0) {
-			progress = (double) seconds;
-		} else {
+		if (header->priv->adjustment->upper != header->priv->duration) {
 			header->priv->adjustment->upper = header->priv->duration;
 			g_signal_emit_by_name (G_OBJECT (header->priv->adjustment), "changed");
 		}
 
 		header->priv->slider_locked = TRUE;
-		gtk_adjustment_set_value (header->priv->adjustment, progress);
+		gtk_adjustment_set_value (header->priv->adjustment, (double) seconds);
 		header->priv->slider_locked = FALSE;
 		gtk_widget_set_sensitive (header->priv->scale, header->priv->seekable);
 	} else {
