static void
impl_set_property (GObject *object,
		   guint prop_id,
		   const GValue *value,
		   GParamSpec *pspec)
{
	RBTrackTransferQueue *queue = RB_TRACK_TRANSFER_QUEUE (object);

	switch (prop_id) {
	case PROP_SHELL:
		queue->priv->shell = g_value_get_object (value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
static void
impl_dispose (GObject *object)
{
	RBTrackTransferQueue *queue = RB_TRACK_TRANSFER_QUEUE (object);

	if (queue->priv->current != NULL) {
		_rb_track_transfer_batch_cancel (queue->priv->current);
		g_object_unref (queue->priv->current);
		queue->priv->current = NULL;
	}

	if (queue->priv->batch_queue != NULL) {
		g_queue_foreach (queue->priv->batch_queue, (GFunc) _rb_track_transfer_batch_cancel, NULL);
		g_queue_foreach (queue->priv->batch_queue, (GFunc) g_object_unref, NULL);
		g_queue_free (queue->priv->batch_queue);
	}

	if (queue->priv->shell != NULL) {
		/* we don't own a reference on the shell. */
		queue->priv->shell = NULL;
	}

	G_OBJECT_CLASS (rb_track_transfer_queue_parent_class)->dispose (object);
}
/**
 * _rb_track_transfer_batch_start:
 * @batch: a #RBTrackTransferBatch
 * @queue: the #RBTrackTransferQueue
 *
 * Starts the batch transfer.  Only to be called by the #RBTrackTransferQueue.
 */
void
_rb_track_transfer_batch_start (RBTrackTransferBatch *batch, GObject *queue)
{
	gboolean total_duration_valid;
	gboolean total_size_valid;
	gboolean origin_valid;
	guint64 filesize;
	gulong duration;
	RBSource *origin = NULL;
	RBShell *shell;
	GList *l;

	g_object_get (queue, "shell", &shell, NULL);

	/* calculate total duration and file size and figure out the
	 * origin source if we weren't given one to start with.
	 */
	total_duration_valid = TRUE;
	total_size_valid = TRUE;
	origin_valid = TRUE;
	for (l = batch->priv->entries; l != NULL; l = l->next) {
		RhythmDBEntry *entry = (RhythmDBEntry *)l->data;

		filesize = rhythmdb_entry_get_uint64 (entry, RHYTHMDB_PROP_FILE_SIZE);
		if (total_size_valid && filesize > 0) {
			batch->priv->total_size += filesize;
		} else {
			total_size_valid = FALSE;
			batch->priv->total_size = 0;
		}

		duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION);
		if (total_duration_valid && duration > 0) {
			batch->priv->total_duration += duration;
		} else {
			total_duration_valid = FALSE;
			batch->priv->total_duration = 0;
		}

		if (batch->priv->source == NULL) {
			RhythmDBEntryType *entry_type;
			RBSource *entry_origin;

			entry_type = rhythmdb_entry_get_entry_type (entry);
			entry_origin = rb_shell_get_source_by_entry_type (shell, entry_type);
			if (origin == NULL && origin_valid  == TRUE) {
				origin = entry_origin;
			} else if (origin != entry_origin) {
				origin = NULL;
				origin_valid = FALSE;
			}
		}
	}

	g_object_unref (shell);

	if (origin != NULL) {
		batch->priv->source = origin;
	}

	batch->priv->queue = RB_TRACK_TRANSFER_QUEUE (queue);
	batch->priv->cancelled = FALSE;
	batch->priv->total_fraction = 0.0;

	g_signal_emit (batch, signals[STARTED], 0);
	g_object_notify (G_OBJECT (batch), "task-progress");
	g_object_notify (G_OBJECT (batch), "task-detail");

	start_next (batch);
}