diff --git a/libbanshee/banshee-player-cdda.c b/libbanshee/banshee-player-cdda.c
index 58fb14b..047ebc2 100644
--- a/libbanshee/banshee-player-cdda.c
+++ b/libbanshee/banshee-player-cdda.c
@@ -33,63 +33,10 @@
 // Private Functions
 // ---------------------------------------------------------------------------
 
-static GstElement *
-bp_cdda_get_cdda_source (GstElement *playbin)
-{
-    GstElement *source = NULL;
-    
-    if (playbin == NULL) {
-        return NULL;
-    }
-    
-    g_object_get (playbin, "source", &source, NULL);
-    
-    if (source == NULL || !GST_IS_CDDA_BASE_SRC (source)) {
-        if (source != NULL) {
-            g_object_unref (source);
-        }
-        
-        return NULL;
-    }
-    
-    return source;
-}
-
-static void
-bp_cdda_on_notify_source (GstElement *playbin, gpointer unknown, BansheePlayer *player)
-{
-    GstElement *cdda_src = NULL;
-    
-    g_return_if_fail (IS_BANSHEE_PLAYER (player));
-    
-    if (player->cdda_device == NULL) {
-        return;
-    }
-    
-    cdda_src = bp_cdda_get_cdda_source (playbin);
-    if (cdda_src == NULL) {
-        return;
-    }
-    
-    // Technically don't need to check the class, since GstCddaBaseSrc elements will always have this
-    if (G_LIKELY (g_object_class_find_property (G_OBJECT_GET_CLASS (cdda_src), "device"))) {
-        bp_debug ("bp_cdda: setting device property on source (%s)", player->cdda_device);
-        g_object_set (cdda_src, "device", player->cdda_device, NULL);
-    }
-    
-    // If the GstCddaBaseSrc is cdparanoia, it will have this property, so set it
-    if (g_object_class_find_property (G_OBJECT_GET_CLASS (cdda_src), "paranoia-mode")) {
-        g_object_set (cdda_src, "paranoia-mode", 0, NULL);
-    }
-    
-    g_object_unref (cdda_src);
-}
-
 static gboolean
-bp_cdda_source_seek_to_track (GstElement *playbin, guint track)
+bp_cdda_source_seek_to_track (BansheePlayer *player, guint track)
 {
     static GstFormat format = GST_FORMAT_UNDEFINED;
-    GstElement *cdda_src = NULL;
     GstState state;
     
     format = gst_format_get_by_nick ("track");
@@ -97,7 +44,7 @@ bp_cdda_source_seek_to_track (GstElement *playbin, guint track)
         return FALSE;
     }
     
-    gst_element_get_state (playbin, &state, NULL, 0);
+    gst_element_get_state (player->pipeline, &state, NULL, 0);
     if (state < GST_STATE_PAUSED) {
         // We can only seek if the pipeline is playing or paused, otherwise
         // we just allow playbin to do its thing, which will re-start the
@@ -105,19 +52,16 @@ bp_cdda_source_seek_to_track (GstElement *playbin, guint track)
         return FALSE;
     }
 
-    cdda_src = bp_cdda_get_cdda_source (playbin);
-    if (G_UNLIKELY (cdda_src == NULL)) {
+    if (G_UNLIKELY (player->current_stream->source == NULL)) {
         return FALSE;
     }
     
-    if (gst_element_seek (playbin, 1.0, format, GST_SEEK_FLAG_FLUSH, 
+    if (gst_element_seek (player->current_stream->source, 1.0, format, GST_SEEK_FLAG_FLUSH, 
         GST_SEEK_TYPE_SET, track - 1, GST_SEEK_TYPE_NONE, -1)) {
         bp_debug ("bp_cdda: seeking to track %d, avoiding playbin", track);
-        g_object_unref (cdda_src);
         return TRUE;
     }
     
-    g_object_unref (cdda_src);
     return FALSE;
 }
 
@@ -128,8 +72,26 @@ bp_cdda_source_seek_to_track (GstElement *playbin, guint track)
 void
 _bp_cdda_pipeline_setup (BansheePlayer *player)
 {
-    if (player != NULL && player->playbin != NULL) {
-        g_signal_connect (player->playbin, "notify::source", G_CALLBACK (bp_cdda_on_notify_source), player);
+    if (player != NULL && player->pipeline != NULL) {
+        
+		if (player->cdda_device == NULL) {
+	        return;
+	    }
+	    
+	    if (player->current_stream->source == NULL) {
+	        return;
+	    }
+	    
+	    // Technically don't need to check the class, since GstCddaBaseSrc elements will always have this
+	    if (G_LIKELY (g_object_class_find_property (G_OBJECT_GET_CLASS (player->current_stream->source), "device"))) {
+	        bp_debug ("bp_cdda: setting device property on source (%s)", player->cdda_device);
+	        g_object_set (G_OBJECT (player->current_stream->source), "device", player->cdda_device, NULL);
+	    }
+	    
+	    // If the GstCddaBaseSrc is cdparanoia, it will have this property, so set it
+	    if (g_object_class_find_property (G_OBJECT_GET_CLASS (player->current_stream->source), "paranoia-mode")) {
+	        g_object_set (player->current_stream->source, "paranoia-mode", 0, NULL);
+	    }
     }
 }
 
@@ -186,7 +148,7 @@ _bp_cdda_handle_uri (BansheePlayer *player, const gchar *uri)
         g_free (track_str);
         bp_debug ("bp_cdda: fast seeking to track on already playing device (%s)", player->cdda_device);
         
-        return bp_cdda_source_seek_to_track (player->playbin, track_num);
+        return bp_cdda_source_seek_to_track (player, track_num);
     }
     
     // We were already playing some CD, but switched to a different device node, 
diff --git a/libbanshee/banshee-player-missing-elements.c b/libbanshee/banshee-player-missing-elements.c
index 38bb6cb..4faaee9 100644
--- a/libbanshee/banshee-player-missing-elements.c
+++ b/libbanshee/banshee-player-missing-elements.c
@@ -72,8 +72,8 @@ bp_missing_elements_handle_install_failed (BansheePlayer *player)
     bp_slist_destroy (player->missing_element_details);
     player->missing_element_details = NULL;
     
-    if (GST_IS_ELEMENT (player->playbin)) {
-        gst_element_set_state (player->playbin, GST_STATE_READY);
+    if (GST_IS_ELEMENT (player->pipeline)) {
+        gst_element_set_state (player->pipeline, GST_STATE_READY);
     }
     
     if (player->error_cb != NULL) {
diff --git a/libbanshee/banshee-player-pipeline.c b/libbanshee/banshee-player-pipeline.c
index d246c92..9c03062 100644
--- a/libbanshee/banshee-player-pipeline.c
+++ b/libbanshee/banshee-player-pipeline.c
@@ -34,6 +34,8 @@
 #include "banshee-player-replaygain.h"
 #include "banshee-player-vis.h"
 
+
+
 // ---------------------------------------------------------------------------
 // Private Functions
 // ---------------------------------------------------------------------------
@@ -72,6 +74,7 @@ bp_pipeline_bus_callback (GstBus *bus, GstMessage *message, gpointer userdata)
     
     switch (GST_MESSAGE_TYPE (message)) {
         case GST_MESSAGE_EOS: {
+            _bp_close_stream(player);
             if (player->eos_cb != NULL) {
                 player->eos_cb (player);
             }
@@ -104,13 +107,13 @@ bp_pipeline_bus_callback (GstBus *bus, GstMessage *message, gpointer userdata)
             if (buffering_progress >= 100) {
                 player->buffering = FALSE;
                 if (player->target_state == GST_STATE_PLAYING) {
-                    gst_element_set_state (player->playbin, GST_STATE_PLAYING);
+                    gst_element_set_state (player->pipeline, GST_STATE_PLAYING);
                 }
             } else if (!player->buffering && player->target_state == GST_STATE_PLAYING) {
                 GstState current_state;
-                gst_element_get_state (player->playbin, &current_state, NULL, 0);
+                gst_element_get_state (player->pipeline, &current_state, NULL, 0);
                 if (current_state == GST_STATE_PLAYING) {
-                    gst_element_set_state (player->playbin, GST_STATE_PAUSED);
+                    gst_element_set_state (player->pipeline, GST_STATE_PAUSED);
                 }
                 player->buffering = TRUE;
             } 
@@ -175,11 +178,13 @@ bp_pipeline_bus_callback (GstBus *bus, GstMessage *message, gpointer userdata)
 // Internal Functions
 // ---------------------------------------------------------------------------
 
+//TODO add volume after adder to be used as the pevious playerbin volume!
+
 gboolean 
 _bp_pipeline_construct (BansheePlayer *player)
 {
     GstBus *bus;
-    GstPad *teepad;
+    //GstPad *teepad;
     GstElement *audiosink;
     GstElement *audiosinkqueue;
     GstElement *eq_audioconvert = NULL;
@@ -187,12 +192,10 @@ _bp_pipeline_construct (BansheePlayer *player)
     
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
     
-    // Playbin is the core element that handles autoplugging (finding the right
-    // source and decoder elements) based on source URI and stream content
-    player->playbin = gst_element_factory_make ("playbin", "playbin");
-    g_return_val_if_fail (player->playbin != NULL, FALSE);
-
-    // Try to find an audio sink, prefer gconf, which typically is set to auto these days,
+    player->pipeline = gst_pipeline_new ("BansheePlayer");
+    g_return_val_if_fail (player->pipeline != NULL, FALSE);
+    
+	// Try to find an audio sink, prefer gconf, which typically is set to auto these days,
     // fall back on auto, which should work on windows, and as a last ditch, try alsa
     audiosink = gst_element_factory_make ("gconfaudiosink", "audiosink");
     if (audiosink == NULL) {
@@ -218,6 +221,9 @@ _bp_pipeline_construct (BansheePlayer *player)
     player->audiobin = gst_bin_new ("audiobin");
     g_return_val_if_fail (player->audiobin != NULL, FALSE);
     
+    player->adder = gst_element_factory_make ("adder", "adder");
+    g_return_val_if_fail (player->adder != NULL, FALSE);
+        
     // Our audio sink is a tee, so plugins can attach their own pipelines
     player->audiotee = gst_element_factory_make ("tee", "audiotee");
     g_return_val_if_fail (player->audiotee != NULL, FALSE);
@@ -233,6 +239,8 @@ _bp_pipeline_construct (BansheePlayer *player)
         player->preamp = gst_element_factory_make ("volume", "preamp");
     }
     
+    gst_bin_add (GST_BIN (player->audiobin), player->adder);
+    
     // Add elements to custom audio sink
     gst_bin_add (GST_BIN (player->audiobin), player->audiotee);
     
@@ -247,27 +255,28 @@ _bp_pipeline_construct (BansheePlayer *player)
     gst_bin_add (GST_BIN (player->audiobin), audiosink);
    
     // Ghost pad the audio bin so audio is passed from the bin into the tee
-    teepad = gst_element_get_pad (player->audiotee, "sink");
-    gst_element_add_pad (player->audiobin, gst_ghost_pad_new ("sink", teepad));
-    gst_object_unref (teepad);
+    player->ghost_pad = gst_ghost_pad_new ("sink", gst_element_get_pad (player->adder, "sink"));
+    gst_element_add_pad (player->audiobin, player->ghost_pad);
 
     // Link the queue and the actual audio sink
     if (player->equalizer != NULL) {
         // link in equalizer, preamp and audioconvert.
-        gst_element_link_many (audiosinkqueue, eq_audioconvert, player->preamp, 
+        gst_element_link_many (player->adder, audiosinkqueue, eq_audioconvert, player->preamp, 
             player->equalizer, eq_audioconvert2, audiosink, NULL);
     } else {
         // link the queue with the real audio sink
-        gst_element_link (audiosinkqueue, audiosink);
+        gst_element_link_many (player->adder, audiosinkqueue, audiosink, NULL);
     }
     
+    //gst_element_link (GST_BIN (player->pipeline), adder, audiobin, NULL);
+    
     _bp_vis_pipeline_setup (player);
     
-    // Now that our internal audio sink is constructed, tell playbin to use it
-    g_object_set (G_OBJECT (player->playbin), "audio-sink", player->audiobin, NULL);
+	// Now that our internal audio sink is constructed, tell playbin to use it
+    //g_object_set (G_OBJECT (player->playbin), "audio-sink", player->audiobin, NULL);
     
     // Connect to the bus to get messages
-    bus = gst_pipeline_get_bus (GST_PIPELINE (player->playbin));    
+    bus = gst_pipeline_get_bus (GST_PIPELINE (player->audiobin));    
     gst_bus_add_watch (bus, bp_pipeline_bus_callback, player);
     
     // Now allow specialized pipeline setups
@@ -293,22 +302,172 @@ _bp_pipeline_construct (BansheePlayer *player)
     return TRUE;
 }
 
+void 
+bp_decodebin_newpad (GstElement *decodebin, GstPad *pad, gboolean last, gpointer data)
+{
+	GstCaps *caps;
+	GstStructure *str;
+	BansheeStream *stream = (BansheeStream *)data;
+	GstStructure *structure;
+	const gchar *mimetype;
+
+	caps = gst_pad_get_caps (pad);
+	structure = gst_caps_get_structure (caps, 0);
+	mimetype = gst_structure_get_name (structure);
+
+	if (g_str_has_prefix (mimetype, "audio/")) {
+	    stream->prerollqueue = gst_element_factory_make ("queue", "prerollqueue");
+        g_return_val_if_fail (stream->prerollqueue != NULL, FALSE);
+    
+        stream->volume = gst_element_factory_make ("volume", NULL);
+        g_return_val_if_fail (stream->volume != NULL, FALSE);
+        
+        gst_bin_add_many (GST_BIN (stream->bin),
+			stream->prerollqueue,
+			stream->volume,
+			NULL);
+		
+	    gst_element_link_many (stream->decoder,
+			stream->prerollqueue,
+			stream->volume,
+			NULL);
+		
+		gst_pad_link (pad, stream->player->ghost_pad);
+	}  else if (g_str_has_prefix (mimetype, "video/")) {
+		gst_pad_link (pad, stream->player->videosink);
+	} else if (g_str_has_prefix (mimetype, "video/x-dvd-subpicture")) {
+		//subtitle
+		return;
+	} else if (g_str_has_prefix (mimetype, "text/")) {
+		//subtitle
+		return;
+	}
+
+	gst_caps_unref (caps);
+	gst_object_unref (pad);
+    //TODO if audio put volume link and fader here and link to adder
+    //else if video link to videosink
+    //else subtitle?
+}
+
+BansheeStream *
+_bp_stream_construct (BansheePlayer *player, const char *uri)
+{
+	BansheeStream *stream = g_new0 (BansheeStream, 1);
+	stream->player = player;
+	
+    stream->bin = gst_bin_new (NULL);
+
+    stream->source = gst_element_make_from_uri (GST_URI_SRC, uri, "streamsource");
+    g_return_val_if_fail (stream->source != NULL, FALSE);
+    
+    if (!strncmp (uri, "http://", 7) && g_object_class_find_property (G_OBJECT_GET_CLASS (stream->source), "iradio-mode")) 
+    {
+    	g_object_set (stream->source, "iradio-mode", TRUE, NULL);
+    }
+    
+    /* TODO
+    if (g_object_class_find_property (G_OBJECT_GET_CLASS (stream->source), "connection-speed")) 
+    {
+		g_object_set (stream->source, "connection-speed", play_base_bin->connection_speed / 1000, NULL);
+	}*/
+	
+    stream->queue = gst_element_factory_make ("queue", "streamqueue");
+    g_return_val_if_fail (stream->queue != NULL, FALSE);
+    
+    stream->decoder = gst_element_factory_make ("decodebin", NULL);
+    g_return_val_if_fail (stream->decoder != NULL, FALSE);
+    g_signal_connect (stream->decoder, "new-decoded-pad", G_CALLBACK (bp_decodebin_newpad), (gpointer)stream);
+
+   
+    
+    gst_bin_add_many (GST_BIN (stream->bin),
+		stream->source,
+		stream->queue,
+		stream->decoder,
+		NULL);
+		
+	gst_element_link_many (stream->source,
+		stream->queue,
+		stream->decoder,
+		NULL);
+
+	gst_bin_add (GST_BIN (player->pipeline), stream->bin);
+	
+    GstPad *src_pad = gst_element_get_pad (stream->volume, "src");
+    stream->proxy = gst_ghost_pad_new ("src", src_pad);
+    gst_element_add_pad (stream->bin, stream->proxy);
+    gst_object_unref (src_pad);
+    
+    stream->adder = gst_element_get_request_pad (player->adder, "sink%d");
+    gst_pad_link (stream->proxy, stream->adder);
+    
+    //TODO link to adder and add in pipeline!
+    
+    gst_element_set_bus (stream->bin, gst_element_get_bus (player->audiobin));
+    
+    GstController *ctrl = gst_controller_new (G_OBJECT (stream->volume), "volume", NULL);
+
+    stream->volume_control = gst_interpolation_control_source_new();
+    gst_controller_set_control_source (ctrl, "volume", GST_CONTROL_SOURCE (stream->volume_control));
+    gst_interpolation_control_source_set_interpolation_mode (stream->volume_control, GST_INTERPOLATE_LINEAR);
+
+    return stream;
+}
+
+void
+_bp_fade_stream (BansheeStream *stream, float start, float end)
+{
+	GValue start_val = { 0, };
+    GValue end_val = { 0, };
+    
+    g_value_init (&start_val, G_TYPE_DOUBLE);
+    g_value_init (&end, G_TYPE_DOUBLE);
+	
+	g_value_set_double (&start_val, start);
+    g_value_set_double (&end, end);
+    
+    gst_interpolation_control_source_set (stream->volume_control, CROSSFADE_TIME * GST_SECOND, &start);
+    
+    gst_interpolation_control_source_set (stream->volume_control, CROSSFADE_TIME * GST_SECOND, &end);
+}
+
+void
+_bp_close_stream (BansheePlayer *player)
+{
+   _bp_dispose_stream(player->current_stream);
+   player->current_stream  = player->next_stream;
+   player->next_stream = NULL;
+}
+
+void
+_bp_stream_destroy (BansheeStream *stream)
+{
+    if (stream == NULL) {
+        return;
+    }
+    
+	gst_element_set_state (stream->bin, GST_STATE_NULL);
+	gst_pad_unlink (stream->proxy, stream->adder);
+	gst_object_unref (GST_OBJECT (stream->bin));
+}
+
 void
 _bp_pipeline_destroy (BansheePlayer *player)
 {
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
     
-    if (player->playbin == NULL) {
+    if (player->pipeline == NULL) {
         return;
     }
     
-    if (GST_IS_ELEMENT (player->playbin)) {
+    if (GST_IS_ELEMENT (player->pipeline)) {
         player->target_state = GST_STATE_NULL;
-        gst_element_set_state (player->playbin, GST_STATE_NULL);
-        gst_object_unref (GST_OBJECT (player->playbin));
+        gst_element_set_state (player->pipeline, GST_STATE_NULL);
+        gst_object_unref (GST_OBJECT (player->pipeline));
     }
     
     _bp_vis_pipeline_destroy (player);
     
-    player->playbin = NULL;
+    player->pipeline = NULL;
 }
diff --git a/libbanshee/banshee-player-private.h b/libbanshee/banshee-player-private.h
index 5cbaa40..8dcf3d5 100644
--- a/libbanshee/banshee-player-private.h
+++ b/libbanshee/banshee-player-private.h
@@ -38,6 +38,9 @@
 #include <gst/base/gstadapter.h>
 #include <gdk/gdk.h>
 #include <gst/fft/gstfftf32.h>
+#include <gst/controller/gstinterpolationcontrolsource.h>
+#include <gst/controller/gstcontroller.h>
+
 
 #ifdef HAVE_GST_PBUTILS
 #  include <gst/pbutils/pbutils.h>
@@ -60,6 +63,7 @@
 
 #define IS_BANSHEE_PLAYER(e) (e != NULL)
 #define SET_CALLBACK(cb_name) { if(player != NULL) { player->cb_name = cb; } }
+#define CROSSFADE_TIME 1.0
 
 #ifdef WIN32
 // TODO Windows doesn't like the ... varargs
@@ -69,6 +73,7 @@
 #endif
 
 typedef struct BansheePlayer BansheePlayer;
+typedef struct BansheeStream BansheeStream;
 
 typedef void (* BansheePlayerEosCallback)          (BansheePlayer *player);
 typedef void (* BansheePlayerErrorCallback)        (BansheePlayer *player, GQuark domain, gint code, 
@@ -87,6 +92,14 @@ typedef enum {
     BP_VIDEO_DISPLAY_CONTEXT_CUSTOM = 2
 } BpVideoDisplayContextType;
 
+//NEW PIPELINE
+//
+//CURRENT STREAM --
+//                  \
+//                   Adder -- output bin   
+//                  /
+//NEXT STREAM -----
+
 struct BansheePlayer {
     // Player Callbacks
     BansheePlayerEosCallback eos_cb;
@@ -98,8 +111,17 @@ struct BansheePlayer {
     BansheePlayerVisDataCallback vis_data_cb;
     BansheePlayerVideoPipelineSetupCallback video_pipeline_setup_cb;
 
-    // Pipeline Elements
-    GstElement *playbin;
+	//multi stream for cross fading
+	BansheeStream *current_stream;
+    BansheeStream *next_stream;
+    
+    //bin tree pipeline contain outputbin + streams bins
+    GstElement *pipeline;
+    GstElement *videosink;
+    GstPad *ghost_pad;
+    
+    // output Elements
+    GstElement *adder;
     GstElement *audiotee;
     GstElement *audiobin;
     GstElement *equalizer;
@@ -158,4 +180,22 @@ struct BansheePlayer {
     gdouble track_peak;
 };
 
+struct BansheeStream {
+	
+	GstElement *bin;
+    // stream Elements
+    GstElement *source;
+    GstElement *queue;//for web radio
+    GstElement *decoder;
+    GstElement *prerollqueue;//for preroll
+    GstElement *volume;//for fade in and out
+    
+    GstPad *proxy;
+    GstPad *adder;
+    
+    BansheePlayer * player;
+    
+    GstInterpolationControlSource *volume_control;
+};
+
 #endif /* _BANSHEE_PLAYER_PRIVATE_H */
diff --git a/libbanshee/banshee-player-replaygain.c b/libbanshee/banshee-player-replaygain.c
index 78fe083..4c21b8e 100644
--- a/libbanshee/banshee-player-replaygain.c
+++ b/libbanshee/banshee-player-replaygain.c
@@ -132,13 +132,13 @@ _bp_replaygain_update_volume (BansheePlayer *player)
     GValue value = { 0, };
     gdouble scale;
     
-    if (player == NULL || player->playbin == NULL) {
+    if (player == NULL || player->pipeline == NULL) {
         return;
     }
     
     scale = player->replaygain_enabled ? player->volume_scale_history[0] : 1.0;
     
-    volume_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (player->playbin), "volume");
+    volume_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (player->pipeline), "volume");
     g_value_init (&value, G_TYPE_DOUBLE);
     g_value_set_double (&value, player->current_volume * scale);
     g_param_value_validate (volume_spec, &value);
@@ -148,7 +148,7 @@ _bp_replaygain_update_volume (BansheePlayer *player)
             g_value_get_double (&value));
     }
     
-    g_object_set_property (G_OBJECT (player->playbin), "volume", &value);
+    g_object_set_property (G_OBJECT (player->pipeline), "volume", &value);
     g_value_unset (&value);
 }
 
diff --git a/libbanshee/banshee-player-video.c b/libbanshee/banshee-player-video.c
index 21bc0ce..2173cb3 100644
--- a/libbanshee/banshee-player-video.c
+++ b/libbanshee/banshee-player-video.c
@@ -37,15 +37,12 @@
 static gboolean
 bp_video_find_xoverlay (BansheePlayer *player)
 {
-    GstElement *video_sink = NULL;
     GstElement *xoverlay;
     GstXOverlay *previous_xoverlay;
 
     previous_xoverlay = player->xoverlay;
     
-    g_object_get (player->playbin, "video-sink", &video_sink, NULL);
-    
-    if (video_sink == NULL) {
+    if (player->videosink == NULL) {
         player->xoverlay = NULL;
         if (previous_xoverlay != NULL) {
             gst_object_unref (previous_xoverlay);
@@ -54,9 +51,9 @@ bp_video_find_xoverlay (BansheePlayer *player)
         return FALSE;
     }
     
-    xoverlay = GST_IS_BIN (video_sink)
-        ? gst_bin_get_by_interface (GST_BIN (video_sink), GST_TYPE_X_OVERLAY)
-        : video_sink;
+    xoverlay = GST_IS_BIN (player->videosink)
+        ? gst_bin_get_by_interface (GST_BIN (player->videosink), GST_TYPE_X_OVERLAY)
+        : player->videosink;
     
     player->xoverlay = GST_IS_X_OVERLAY (xoverlay) ? GST_X_OVERLAY (xoverlay) : NULL;
     
@@ -74,8 +71,6 @@ bp_video_find_xoverlay (BansheePlayer *player)
         g_object_set (G_OBJECT (player->xoverlay), "handle-events", FALSE, NULL);
     }
 
-    gst_object_unref (video_sink);
-
     return player->xoverlay != NULL;
 }
 
@@ -127,11 +122,16 @@ _bp_video_pipeline_setup (BansheePlayer *player, GstBus *bus)
     GstElement *videosink;
     
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
-    
+    //Best is to generate a special stream for video or generate the old pipeline with playbin here link to videosink
+    //and set pipeline to null at eos to regenrate it when video have finished 
      if (player->video_pipeline_setup_cb != NULL) {
         videosink = player->video_pipeline_setup_cb (player, bus);
         if (videosink != NULL && GST_IS_ELEMENT (videosink)) {
-            g_object_set (G_OBJECT (player->playbin), "video-sink", videosink, NULL);
+            
+            //TODO store video_sink bin in player
+            //g_object_set (G_OBJECT (player->pipeline), "video-sink", videosink, NULL);
+            player->videosink = videosink;
+            gst_bin_add (GST_BIN (player->pipeline), player->videosink);
             player->video_display_context_type = BP_VIDEO_DISPLAY_CONTEXT_CUSTOM;
             return;
         }
@@ -153,7 +153,8 @@ _bp_video_pipeline_setup (BansheePlayer *player, GstBus *bus)
         }
     }
     
-    g_object_set (G_OBJECT (player->playbin), "video-sink", videosink, NULL);
+    player->videosink = videosink;
+    gst_bin_add (GST_BIN (player->pipeline), player->videosink);
     
     gst_bus_set_sync_handler (bus, gst_bus_sync_signal_handler, player);
     g_signal_connect (bus, "sync-message::element", G_CALLBACK (bp_video_bus_element_sync_message), player);
@@ -173,7 +174,8 @@ _bp_video_pipeline_setup (BansheePlayer *player, GstBus *bus)
         g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
     }
     
-    g_object_set (G_OBJECT (player->playbin), "video-sink", videosink, NULL);
+    player->videosink = videosink;
+    gst_bin_add (GST_BIN (player->pipeline), player->videosink);
 
     #endif
     
diff --git a/libbanshee/banshee-player.c b/libbanshee/banshee-player.c
index 4052d06..d358343 100644
--- a/libbanshee/banshee-player.c
+++ b/libbanshee/banshee-player.c
@@ -79,9 +79,9 @@ bp_pipeline_set_state (BansheePlayer *player, GstState state)
         bp_iterate_timeout_stop (player);
     }
     
-    if (GST_IS_ELEMENT (player->playbin)) {
+    if (GST_IS_ELEMENT (player->pipeline)) {
         player->target_state = state;
-        gst_element_set_state (player->playbin, state);
+        gst_element_set_state (player->pipeline, state);
     }
     
     if (state == GST_STATE_PLAYING) {
@@ -143,7 +143,7 @@ bp_open (BansheePlayer *player, const gchar *uri)
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
     
     // Build the pipeline if we need to
-    if (player->playbin == NULL && !_bp_pipeline_construct (player)) {
+    if (player->pipeline == NULL && !_bp_pipeline_construct (player)) {
         return FALSE;
     }
 
@@ -151,23 +151,28 @@ bp_open (BansheePlayer *player, const gchar *uri)
     // in case it is able to perform a fast seek to a track
     if (_bp_cdda_handle_uri (player, uri)) {
         return TRUE;
-    } else if (player->playbin == NULL) {
+    } else if (player->pipeline == NULL) {
         return FALSE;
     }
     
     // Set the pipeline to the proper state
-    gst_element_get_state (player->playbin, &state, NULL, 0);
+    gst_element_get_state (player->pipeline, &state, NULL, 0);
     if (state >= GST_STATE_PAUSED) {
         player->target_state = GST_STATE_READY;
-        gst_element_set_state (player->playbin, GST_STATE_READY);
+        gst_element_set_state (player->pipeline, GST_STATE_READY);
     }
     
     // Pass the request off to playbin
-    g_object_set (G_OBJECT (player->playbin), "uri", uri, NULL);
+    //g_object_set (G_OBJECT (player->pipeline), "uri", uri, NULL);
     
+    player->next_stream = _bp_stream_construct (player, uri);
+        
+    gst_element_set_state (player->next_stream->bin, GST_STATE_PLAYING);
+    _bp_fade_stream(player->next_stream, 0.0, 1.0);
+    _bp_fade_stream(player->current_stream, 1.0, 0.0);
     return TRUE;
 }
-
+//TODO parametter to switch on/off cross fading
 P_INVOKE void
 bp_stop (BansheePlayer *player, gboolean nullstate)
 {
@@ -183,18 +188,37 @@ bp_stop (BansheePlayer *player, gboolean nullstate)
     bp_debug ("bp_stop: setting state to %s", 
         state == GST_STATE_NULL ? "GST_STATE_NULL" : "GST_STATE_PAUSED");
     
+    _bp_fade_stream(player->current_stream, 1.0, 0.0);
+    
+    //Is there an event for end of stream
+    GstClockID clock_id = gst_clock_new_single_shot_id (clock, gst_clock_get_time (clock) + (CROSSFADE_TIME * GST_SECOND));
+
+	GstClockReturn wait_ret;
+    if ((wait_ret = gst_clock_id_wait (clock_id, NULL)) != GST_CLOCK_OK) {
+       GST_WARNING ("clock_id_wait returned: %d", wait_ret);
+     }
+
     bp_pipeline_set_state (player, state);
 }
 
 P_INVOKE void
 bp_pause (BansheePlayer *player)
 {
+	_bp_fade_stream(player->current_stream, 1.0, 0.0);
+    //Is there an event for end of stream
+    GstClockID clock_id = gst_clock_new_single_shot_id (clock, gst_clock_get_time (clock) + (CROSSFADE_TIME * GST_SECOND));
+
+	GstClockReturn wait_ret;
+    if ((wait_ret = gst_clock_id_wait (clock_id, NULL)) != GST_CLOCK_OK) {
+       GST_WARNING ("clock_id_wait returned: %d", wait_ret);
+     }
     bp_pipeline_set_state (player, GST_STATE_PAUSED);
 }
 
 P_INVOKE void
 bp_play (BansheePlayer *player)
 {
+	_bp_fade_stream(player->current_stream, 0.0, 1.0);
     bp_pipeline_set_state (player, GST_STATE_PLAYING);
 }
 
@@ -203,7 +227,7 @@ bp_set_position (BansheePlayer *player, guint64 time_ms)
 {
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
     
-    if (player->playbin == NULL || !gst_element_seek (player->playbin, 1.0, 
+    if (player->pipeline == NULL || !gst_element_seek (player->pipeline, 1.0, 
         GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
         GST_SEEK_TYPE_SET, time_ms * GST_MSECOND, 
         GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
@@ -222,7 +246,7 @@ bp_get_position (BansheePlayer *player)
 
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0);
 
-    if (player->playbin != NULL && gst_element_query_position (player->playbin, &format, &position)) {
+    if (player->pipeline != NULL && gst_element_query_position (player->pipeline, &format, &position)) {
         return position / GST_MSECOND;
     }
     
@@ -237,7 +261,7 @@ bp_get_duration (BansheePlayer *player)
 
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0);
 
-    if (player->playbin != NULL && gst_element_query_duration (player->playbin, &format, &duration)) {
+    if (player->pipeline != NULL && gst_element_query_duration (player->pipeline, &format, &duration)) {
         return duration / GST_MSECOND;
     }
     
@@ -252,12 +276,12 @@ bp_can_seek (BansheePlayer *player)
     
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
     
-    if (player->playbin == NULL) {
+    if (player->pipeline == NULL) {
         return FALSE;
     }
     
     query = gst_query_new_seeking (GST_FORMAT_TIME);
-    if (!gst_element_query (player->playbin, query)) {
+    if (!gst_element_query (player->pipeline, query)) {
         // This will probably fail, 100% of the time, because it's apparently 
         // very unimplemented in GStreamer... when it's fixed
         // we will return FALSE here, and show the warning
@@ -287,11 +311,11 @@ bp_get_volume (BansheePlayer *player)
 }
 
 P_INVOKE gboolean
-bp_get_pipeline_elements (BansheePlayer *player, GstElement **playbin, GstElement **audiobin, GstElement **audiotee)
+bp_get_pipeline_elements (BansheePlayer *player, GstElement **pipeline, GstElement **audiobin, GstElement **audiotee)
 {
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
     
-    *playbin = player->playbin;
+    *pipeline = player->pipeline;
     *audiobin = player->audiobin;
     *audiotee = player->audiotee;
     
diff --git a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
index be40856..22b5042 100644
--- a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
+++ b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
@@ -70,6 +70,7 @@ namespace Banshee.GStreamer
         private uint GST_STREAM_ERROR = 0; 
     
         private HandleRef handle;
+        //TODO done an event to know when about to finished to open next stream on gstreamer backend...
         
         private BansheePlayerEosCallback eos_callback;
         private BansheePlayerErrorCallback error_callback;
@@ -647,7 +648,7 @@ namespace Banshee.GStreamer
         private static extern ulong bp_get_duration (HandleRef player);
         
         [DllImport ("libbanshee.dll")]
-        private static extern bool bp_get_pipeline_elements (HandleRef player, out IntPtr playbin,
+        private static extern bool bp_get_pipeline_elements (HandleRef player, out IntPtr pipeline,
             out IntPtr audiobin, out IntPtr audiotee);
             
         [DllImport ("libbanshee.dll")]
