diff --git a/Makefile.am b/Makefile.am
index b894c2c..40a6746 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,8 @@ SUBDIRS += libtinymailui
 
 if BUILD_GNOME
 SUBDIRS += libtinymailui-gnome-keyring
-SUBDIRS += libtinymail-gnomevfs 
+SUBDIRS += libtinymail-gnomevfs
+SUBDIRS += libtinymail-gio
 endif
 
 if BUILD_UIGTK
@@ -70,6 +71,7 @@ DIST_SUBDIRS = \
 	libtinymail \
 	libtinymailui \
 	libtinymail-gnomevfs \
+	libtinymail-gio \
 	libtinymailui-gtk \
 	libtinymail-camel \
 	docs \
diff --git a/configure.ac b/configure.ac
index 68beffa..c371eb5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -417,6 +417,28 @@ fi
 AC_SUBST(LIBTINYMAIL_GNOMEVFS_CFLAGS)
 AC_SUBST(LIBTINYMAIL_GNOMEVFS_LIBS)
 
+
+dnl ### libtinymail-gio, a tnystreamiface for gio ##
+if test x$build_gnome = xtrue; then
+extragtkpkgs+=" libgnomeui-2.0 gnome-keyring-1"
+extratnypkgs+=" gio-2.0"
+  PKG_CHECK_MODULES(LIBTINYMAIL_GIO, gio-2.0)
+elif test x$build_maemo = xtrue; then
+extragtkpkgs=
+extratnypkgs+=" gio-2.0"
+  PKG_CHECK_MODULES(LIBTINYMAIL_GIO, gio-2.0)
+else
+  LIBTINYMAIL_GIO_CFLAGS=
+  LIBTINYMAIL_GIO_LIBS=
+  extragtkpkgs=
+  extratnypkgs=
+fi
+
+AC_SUBST(LIBTINYMAIL_GIO_CFLAGS)
+AC_SUBST(LIBTINYMAIL_GIO_LIBS)
+
+
+
 dnl ### libtinymailui-gtk, a gtk+ implementation of libtinymail-ui ##
 PKG_CHECK_MODULES(LIBTINYMAILUI_GTK, glib-2.0 >= 2.8 gobject-2.0 $extragtkpkgs gtk+-2.0)
 AC_SUBST(LIBTINYMAILUI_GTK_CFLAGS)
@@ -613,6 +635,8 @@ libtinymailui-mozembed/libtinymailui-mozembed.pc
 libtinymailui-gnome-keyring/Makefile
 libtinymail-gnomevfs/Makefile
 libtinymail-gnomevfs/libtinymail-gnomevfs.pc
+libtinymail-gio/Makefile
+libtinymail-gio/libtinymail-gio.pc
 libtinymail-gnome-desktop/Makefile
 libtinymail-gnome-desktop/libtinymail-gnome-desktop.pc
 libtinymail-olpc/Makefile
diff --git a/libtinymail-gio/libtinymail-gio-1.0.pc b/libtinymail-gio/libtinymail-gio-1.0.pc
new file mode 100755
index 0000000..bf20994
--- /dev/null
+++ b/libtinymail-gio/libtinymail-gio-1.0.pc
@@ -0,0 +1,11 @@
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: libtinymail-gio
+Description: TinyMail generic library implemented for gio
+Version: 1.0.0
+Requires: libtinymail-1.0 gio-2.0
+Libs: -L${libdir} -ltinymail-gio-1.0
+Cflags: -I${includedir}/libtinymail-gio-1.0
diff --git a/libtinymail-gio/libtinymail-gio.pc.in b/libtinymail-gio/libtinymail-gio.pc.in
new file mode 100755
index 0000000..aaff7f5
--- /dev/null
+++ b/libtinymail-gio/libtinymail-gio.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libtinymail-gio
+Description: TinyMail generic library implemented for gio
+Version: @VERSION@
+Requires: libtinymail-@API_VERSION@ gio-2.0
+Libs: -L${libdir} -ltinymail-gio-@API_VERSION@
+Cflags: -I${includedir}/libtinymail-gio-@API_VERSION@
diff --git a/libtinymail-gio/tny-gio-input-stream.c b/libtinymail-gio/tny-gio-input-stream.c
new file mode 100644
index 0000000..916ba11
--- /dev/null
+++ b/libtinymail-gio/tny-gio-input-stream.c
@@ -0,0 +1,382 @@
+/* libtinymail-gio - The Tiny Mail base library for Gio
+ * Copyright (C) 2009 Javier Jardón <javierjc1982@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with self library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * A Gio to CamelStream mapper.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <tny-gio-input-stream.h>
+
+static GObjectClass *parent_class = NULL;
+
+typedef struct _TnyGioInputStreamPriv TnyGioInputStreamPriv;
+
+struct _TnyGioInputStreamPriv
+{
+        GInputStream *input_stream;
+	gboolean eos;
+	off_t position;		/* current postion in the input stream */
+	off_t bound_start;	/* first valid position */
+	off_t bound_end;	/* first invalid position */
+};
+
+#define TNY_GIO_INPUT_STREAM_GET_PRIVATE(o) \
+	(G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_GIO_INPUT_STREAM, TnyGioInputStreamPriv))
+
+
+static gssize
+tny_gio_input_stream_write_to_stream (TnyStream *self, TnyStream *output)
+{
+        g_warning (  "You can't use the tny_stream_write_to_stream API on input "
+		     "streams. This problem indicates a bug in the software");
+
+        return -1;
+}
+
+static gssize
+tny_gio_input_stream_read  (TnyStream *self, char *buffer, gsize n)
+{
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+
+        gssize nread = 0;
+        GError *error = NULL;
+
+	if (priv->bound_end != (~0))
+		n = MIN (priv->bound_end - priv->position, n);
+
+        nread = g_input_stream_read (priv->input_stream, buffer, n, NULL, &error);
+
+        if (nread > 0)
+		priv->position += nread;
+	else if (nread == 0)
+                priv->eos = TRUE;
+
+	return nread;
+}
+
+static gssize
+tny_gio_input_stream_write (TnyStream *self, const char *buffer, gsize n)
+{
+        g_warning (  "You can't use the tny_stream_write API on input "
+		     "streams. This problem indicates a bug in the software");
+
+        return -1;
+}
+
+static gint
+tny_gio_input_stream_close (TnyStream *self)
+{
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+	GError *error;
+
+        if (!g_input_stream_close (priv->input_stream, NULL, &error))
+                return -1;
+
+        priv->input_stream = NULL;
+        priv->eos = TRUE;
+
+	return 0;
+}
+
+
+/**
+ * tny_gio_input_stream_set_stream:
+ * @self: A #TnyGioStream instance
+ * @input_stream: the stream to read from
+ *
+ * Set the input stream to play adaptor for
+ *
+ **/
+void
+tny_gio_input_stream_set_stream (TnyGioInputStream *self, GInputStream *input_stream)
+{
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+        GError *error;
+
+        if (!input_stream)
+                return;
+
+	if (priv->input_stream) {
+                g_input_stream_close (priv->input_stream, NULL, &error);
+		priv->input_stream = NULL;
+	}
+
+	priv->input_stream = input_stream;
+	priv->eos = FALSE;
+	priv->position = 0;
+
+        g_seekable_seek (GSEEKABLE (input_stream), priv->position,
+                         G_SEEK_CUR, NULL, &error);
+
+	return;
+}
+
+/**
+ * tny_gio_input_stream_new:
+ * @input_stream: The stream to read from
+ *
+ * Create an adaptor instance between #TnyStream and #Gio input stream
+ *
+ * Return value: a new #TnyStream instance
+ **/
+TnyStream*
+tny_gio_input_stream_new (GInputStream *input_stream)
+{
+	TnyGioInputStream *self = g_object_new (TNY_TYPE_GIO_INPUT_STREAM, NULL);
+
+	tny_gio_input_stream_set_streams (self, input_stream);
+
+	return TNY_STREAM (self);
+}
+
+static void
+tny_gio_input_stream_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+	TnyGioInputStream *self = (TnyGioInputStream *)instance;
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+
+        priv->input_stream = NULL;
+	priv->eos = FALSE;
+	priv->bound_start = 0;
+	priv->bound_end = (~0);
+	priv->position = 0;
+
+	return;
+}
+
+static void
+tny_gio_input_stream_finalize (GObject *object)
+{
+	TnyGioInputStream *self = (TnyGioInputStream *)object;
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+        GError *error = NULL;
+
+        if (G_LIKELY (priv->input_stream))
+                g_input_stream_close (priv->input_stream, NULL, &error);
+
+	(*parent_class->finalize) (object);
+
+	return;
+}
+
+static gint
+tny_gio_input_flush (TnyStream *self)
+{
+         g_warning (  "You can't use the tny_stream_write_to_stream API on input "
+		     "streams. This problem indicates a bug in the software");
+
+        return -1;
+}
+
+static gboolean
+tny_gio_input_is_eos (TnyStream *self)
+{
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+
+	return priv->eos;
+}
+
+static gint
+tny_gio_input_reset (TnyStream *self)
+{
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+	gint retval = 0;
+	GError *error;
+
+	if (priv->input_stream == NULL)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+        if (!g_seekable_seek (GSEEKABLE (priv->input_stream), 0, G_SEEK_SET, NULL, &error))
+                return -1;
+
+        priv->position = 0;
+	priv->eos = FALSE;
+
+	return 0;
+}
+
+
+
+static off_t
+tny_gio_input_seek (TnySeekable *self, off_t offset, int policy)//TODO
+{
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+
+        goffset real = 0;
+        GError *error;
+
+	switch (policy) {
+	case SEEK_SET:
+		real = offset;
+		break;
+	case SEEK_CUR:
+		real = priv->position + offset;
+		break;
+	case SEEK_END:
+		if (priv->bound_end == (~0)) {
+                        if (!g_seekable_seek (G_SEEKABLE (priv->input_stream), GOFFSET (offset), G_SEEK_SET, NULL, &error))
+                                return -1;
+                        real = g_seekable_tell (G_SEEKABLE (priv->input_stream));
+			if (real != -1) {
+				if (real<priv->bound_start)
+					real = priv->bound_start;
+				priv->position = real;
+			}
+			return real;
+		}
+		real = priv->bound_end + offset;
+		break;
+	}
+
+	if (priv->bound_end != (~0))
+		real = MIN (real, priv->bound_end);
+	real = MAX (real, priv->bound_start);
+
+        if (!g_seekable_seek (G_SEEKABLE (priv->input_stream), real, G_SEEK_SET, NULL, &error))
+                return -1;
+
+	if (real != priv->position && priv->eos)
+		priv->eos = FALSE;
+
+	priv->position = real;
+
+	return real;
+}
+
+static off_t
+tny_gio_input_tell (TnySeekable *self)
+{
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+
+	return priv->position;
+}
+
+static gint
+tny_gio_input_set_bounds (TnySeekable *self, off_t start, off_t end)
+{
+	TnyGioInputStreamPriv *priv = TNY_GIO_INPUT_STREAM_GET_PRIVATE (self);
+
+	priv->bound_end = end;
+	priv->bound_start = start;
+
+	return 0;
+}
+
+static void
+tny_stream_init (gpointer g, gpointer iface_data)
+{
+	TnyStreamIface *klass = (TnyStreamIface *)g;
+
+	klass->reset= tny_gio_input_reset;
+	klass->flush= tny_gio_input_flush;
+	klass->is_eos= tny_gio_input_is_eos;
+	klass->read= tny_gio_input_stream_read;
+	klass->write= tny_gio_input_stream_write;
+	klass->close= tny_gio_input_stream_close;
+	klass->write_to_stream= tny_gio_input_stream_write_to_stream;
+
+	return;
+}
+
+
+static void
+tny_seekable_init (gpointer g, gpointer iface_data)
+{
+	TnySeekableIface *klass = (TnySeekableIface *)g;
+
+	klass->seek= tny_gio_input_seek;
+	klass->tell= tny_gio_input_tell;
+	klass->set_bounds= tny_gio_input_set_bounds;
+
+	return;
+}
+
+static void
+tny_gio_input_stream_class_init (TnyGioInputStreamClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	object_class = (GObjectClass*) class;
+
+	object_class->finalize = tny_gio_input_stream_finalize;
+
+	g_type_class_add_private (object_class, sizeof (TnyGioInputStreamPriv));
+
+	return;
+}
+
+static gpointer
+tny_gio_input_stream_register_type (gpointer notused)
+{
+	GType type = 0;
+
+	static const GTypeInfo info =
+		{
+			sizeof (TnyGioInputStreamClass),
+			NULL,   /* base_init */
+			NULL,   /* base_finalize */
+			(GClassInitFunc) tny_gio_input_stream_class_init,   /* class_init */
+			NULL,   /* class_finalize */
+			NULL,   /* class_data */
+			sizeof (TnyGioInputStream),
+			0,      /* n_preallocs */
+			tny_gio_input_stream_instance_init,/* instance_init */
+			NULL
+		};
+
+	static const GInterfaceInfo tny_stream_info =
+		{
+			(GInterfaceInitFunc) tny_stream_init, /* interface_init */
+			NULL,         /* interface_finalize */
+			NULL          /* interface_data */
+		};
+
+	static const GInterfaceInfo tny_seekable_info =
+		{
+			(GInterfaceInitFunc) tny_seekable_init, /* interface_init */
+			NULL,         /* interface_finalize */
+			NULL          /* interface_data */
+		};
+
+	type = g_type_register_static (G_TYPE_OBJECT,
+				       "TnyVfsStream",
+				       &info, 0);
+
+	g_type_add_interface_static (type, TNY_TYPE_STREAM,
+				     &tny_stream_info);
+
+	g_type_add_interface_static (type, TNY_TYPE_SEEKABLE,
+				     &tny_seekable_info);
+
+	return GUINT_TO_POINTER (type);
+}
+
+GType
+tny_gio_input_stream_get_type (void)
+{
+	static GOnce once = G_ONCE_INIT;
+	g_once (&once, tny_gio_input_stream_register_type, NULL);
+	return GPOINTER_TO_UINT (once.retval);
+}
diff --git a/libtinymail-gio/tny-gio-input-stream.h b/libtinymail-gio/tny-gio-input-stream.h
new file mode 100644
index 0000000..58fa50e
--- /dev/null
+++ b/libtinymail-gio/tny-gio-input-stream.h
@@ -0,0 +1,58 @@
+#ifndef TNY_GIO_INPUT_STREAM_H
+#define TNY_GIO_INPUT_STREAM_H
+
+/* libtinymail-gio - The Tiny Mail base library for Gio
+ * Copyright (C) 2009 Javier Jardón <javierjc1982@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with self library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#include <tny-stream.h>
+#include <tny-seekable.h>
+
+G_BEGIN_DECLS
+
+#define TNY_TYPE_GIO_INPUT_STREAM		(tny_gio_input_stream_get_type ())	
+#define TNY_GIO_INPUT_STREAM(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), TNY_TYPE_GIO_INPUT_STREAM, TnyGioInputStream))
+#define TNY_GIO_INPUT_STREAM_CLASS(vtable)	(G_TYPE_CHECK_CLASS_CAST ((vtable), TNY_TYPE_GIO_INPUT_STREAM, TnyGioInputStreamClass))
+#define TNY_IS_GIO_INPUT_STREAM(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TNY_TYPE_GIO_INPUT_STREAM))
+#define TNY_IS_GIO_INPUT_STREAM_CLASS(vtable)	(G_TYPE_CHECK_CLASS_TYPE ((vtable), TNY_TYPE_GIO_INPUT_STREAM))
+#define TNY_GIO_INPUT_STREAM_GET_CLASS(inst)	(G_TYPE_INSTANCE_GET_CLASS ((inst), TNY_TYPE_GIO_INPUT_STREAM, TnyGioInputStreamClass))
+
+typedef struct _TnyGioInputStream TnyGioInputStream;
+typedef struct _TnyGioInputStreamClass TnyGioInputStreamClass;
+
+struct _TnyGioInputStream
+{
+	GObject parent;
+};
+
+struct _TnyGioInputStreamClass
+{
+	GObjectClass parent;
+};
+
+GType tny_gio_input_stream_get_type (void);
+TnyStream* tny_gio_input_stream_new (GInputStream *input_stream);
+void tny_gio_input_stream_set_stream (TnyGioInputStream *self, GInputStream *input_stream);
+
+G_END_DECLS
+
+#endif
diff --git a/libtinymail-gio/tny-gio-output-stream.c b/libtinymail-gio/tny-gio-output-stream.c
new file mode 100644
index 0000000..d240a7a
--- /dev/null
+++ b/libtinymail-gio/tny-gio-output-stream.c
@@ -0,0 +1,407 @@
+/* libtinymail-gio - The Tiny Mail base library for Gio
+ * Copyright (C) 2009 Javier Jardón <javierjc1982@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with self library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * A Gio to CamelStream mapper.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <tny-gio-output-stream.h>
+
+static GObjectClass *parent_class = NULL;
+
+typedef struct _TnyGioOutputStreamPriv TnyGioOutputStreamPriv;
+
+struct _TnyGioOutputStreamPriv
+{
+        GOutputStream *output_stream;
+	gboolean eos;
+	off_t position;		/* current postion in the input stream */
+	off_t bound_start;	/* first valid position */
+	off_t bound_end;	/* first invalid position */
+};
+
+#define TNY_GIO_OUTPUT_STREAM_GET_PRIVATE(o) \
+	(G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_GIO_OUTPUT_STREAM, TnyGioOutputStreamPriv))
+
+
+static gssize
+tny_gio_output_stream_write_to_stream (TnyStream *self, TnyStream *output)
+{
+	char tmp_buf[4096];
+	gssize total = 0;
+	gssize nb_read;
+	gssize nb_written;
+
+	g_assert (TNY_IS_STREAM (output));
+
+	while (G_UNLIKELY (!tny_stream_is_eos (self))) {
+		nb_read = tny_stream_read (self, tmp_buf, sizeof (tmp_buf));
+		if (G_UNLIKELY (nb_read < 0))
+			return -1;
+		else if (G_LIKELY (nb_read > 0)) {
+			nb_written = 0;
+
+			while (G_LIKELY (nb_written < nb_read))
+			{
+				gssize len = tny_stream_write (output, tmp_buf + nb_written,
+								  nb_read - nb_written);
+				if (G_UNLIKELY (len < 0))
+					return -1;
+				nb_written += len;
+			}
+			total += nb_written;
+		}
+	}
+	return total;
+}
+
+static gssize
+tny_gio_output_stream_read  (TnyStream *self, char *buffer, gsize n)
+{
+        g_warning (  "You can't use the tny_stream_read API on output "
+		     "streams. This problem indicates a bug in the software");
+
+	return -1;
+}
+
+static gssize
+tny_gio_output_stream_write (TnyStream *self, const char *buffer, gsize n)
+{
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+
+        gssize nwritten = 0;
+        GError *error = NULL;
+
+	if (priv->bound_end != (~0))
+		n = MIN (priv->bound_end - priv->position, n);
+
+        nwritten = g_output_stream_write (priv->output_stream, buffer, n, NULL, &error);
+
+	if (nwritten > 0)
+		priv->position += nwritten;
+	else if (nwritten == 0)
+                priv->eos = TRUE;
+
+	return nwritten;
+}
+
+static gint
+tny_gio_output_stream_close (TnyStream *self)
+{
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+	GError *error;
+
+        if (!g_output_stream_close (priv->output_stream, NULL, &error))
+                return -1;
+
+        priv->output_stream = NULL;
+        priv->eos = TRUE;
+
+	return 0;
+}
+
+
+/**
+ * tny_gio_output_stream_set_stream:
+ * @self: A #TnyGioStream instance
+ * @output_stream: the stream to write to
+ *
+ * Set the output stream to play adaptor for
+ *
+ **/
+void
+tny_gio_output_stream_set_stream (TnyGioOutputStream *self, GOutputStream *output_stream)
+{
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+        GError *error;
+
+        if (!output_stream)
+                return;
+
+	if (priv->output_stream) {
+                g_output_stream_close (priv->output_stream, NULL, &error);
+		priv->output_stream = NULL;
+	}
+
+	priv->output_stream = output_stream;
+	priv->eos = FALSE;
+	priv->position = 0;
+
+        g_seekable_seek (GSEEKABLE (output_stream), priv->position,
+                         G_SEEK_CUR, NULL, &error);
+
+	return;
+}
+
+/**
+ * tny_gio_output_stream_new:
+ * @output_stream: The stream to read from
+ *
+ * Create an adaptor instance between #TnyStream and #Gio input stream
+ *
+ * Return value: a new #TnyStream instance
+ **/
+TnyStream*
+tny_gio_output_stream_new (GOutputStream *output_stream)
+{
+	TnyGioOutputStream *self = g_object_new (TNY_TYPE_GIO_OUTPUT_STREAM, NULL);
+
+	tny_gio_output_stream_set_streams (self, output_stream);
+
+	return TNY_STREAM (self);
+}
+
+static void
+tny_gio_output_stream_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+	TnyGioOutputStream *self = (TnyGioOutputStream *)instance;
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+
+        priv->output_stream = NULL;
+	priv->eos = FALSE;
+	priv->bound_start = 0;
+	priv->bound_end = (~0);
+	priv->position = 0;
+
+	return;
+}
+
+static void
+tny_gio_output_stream_finalize (GObject *object)
+{
+	TnyGioOutputStream *self = (TnyGioOutputStream *)object;
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+        GError *error = NULL;
+
+        if (G_LIKELY (priv->output_stream))
+                g_output_stream_close (priv->output_stream, NULL, &error);
+
+	(*parent_class->finalize) (object);
+
+	return;
+}
+
+static gint
+tny_gio_output_flush (TnyStream *self)
+{
+        TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+        GError *error;
+
+        if (!g_output_stream_flush (priv->output_stream, NULL, &error))
+                return -1;
+
+	return 0;
+}
+
+static gboolean
+tny_gio_output_is_eos (TnyStream *self)
+{
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+
+	return priv->eos;
+}
+
+static gint
+tny_gio_output_reset (TnyStream *self)
+{
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+	gint retval = 0;
+	GError *error;
+
+	if (priv->output_stream == NULL)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+        if (!g_seekable_seek (GSEEKABLE (priv->output_stream), 0, G_SEEK_SET, NULL, &error))
+                return -1;
+
+        priv->position = 0;
+	priv->eos = FALSE;
+
+	return 0;
+}
+
+
+
+static off_t
+tny_gio_output_seek (TnySeekable *self, off_t offset, int policy)//TODO
+{
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+
+        goffset real = 0;
+        GError *error;
+
+	switch (policy) {
+	case SEEK_SET:
+		real = offset;
+		break;
+	case SEEK_CUR:
+		real = priv->position + offset;
+		break;
+	case SEEK_END:
+		if (priv->bound_end == (~0)) {
+                        if (!g_seekable_seek (G_SEEKABLE (priv->output_stream), GOFFSET (offset), G_SEEK_SET, NULL, &error))
+                                return -1;
+                        real = g_seekable_tell (G_SEEKABLE (priv->output_stream));
+			if (real != -1) {
+				if (real<priv->bound_start)
+					real = priv->bound_start;
+				priv->position = real;
+			}
+			return real;
+		}
+		real = priv->bound_end + offset;
+		break;
+	}
+
+	if (priv->bound_end != (~0))
+		real = MIN (real, priv->bound_end);
+	real = MAX (real, priv->bound_start);
+
+        if (!g_seekable_seek (G_SEEKABLE (priv->output_stream), real, G_SEEK_SET, NULL, &error))
+                return -1;
+
+	if (real != priv->position && priv->eos)
+		priv->eos = FALSE;
+
+	priv->position = real;
+
+	return real;
+}
+
+static off_t
+tny_gio_output_tell (TnySeekable *self)
+{
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+
+	return priv->position;
+}
+
+static gint
+tny_gio_output_set_bounds (TnySeekable *self, off_t start, off_t end)
+{
+	TnyGioOutputStreamPriv *priv = TNY_GIO_OUTPUT_STREAM_GET_PRIVATE (self);
+
+	priv->bound_end = end;
+	priv->bound_start = start;
+
+	return 0;
+}
+
+static void
+tny_stream_init (gpointer g, gpointer iface_data)
+{
+	TnyStreamIface *klass = (TnyStreamIface *)g;
+
+	klass->reset= tny_gio_output_reset;
+	klass->flush= tny_gio_output_flush;
+	klass->is_eos= tny_gio_output_is_eos;
+	klass->read= tny_gio_output_stream_read;
+	klass->write= tny_gio_output_stream_write;
+	klass->close= tny_gio_output_stream_close;
+	klass->write_to_stream= tny_gio_output_stream_write_to_stream;
+
+	return;
+}
+
+
+static void
+tny_seekable_init (gpointer g, gpointer iface_data)
+{
+	TnySeekableIface *klass = (TnySeekableIface *)g;
+
+	klass->seek= tny_gio_output_seek;
+	klass->tell= tny_gio_output_tell;
+	klass->set_bounds= tny_gio_output_set_bounds;
+
+	return;
+}
+
+static void
+tny_gio_output_stream_class_init (TnyGioOutputStreamClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	object_class = (GObjectClass*) class;
+
+	object_class->finalize = tny_gio_output_stream_finalize;
+
+	g_type_class_add_private (object_class, sizeof (TnyGioOutputStreamPriv));
+
+	return;
+}
+
+static gpointer
+tny_gio_output_stream_register_type (gpointer notused)
+{
+	GType type = 0;
+
+	static const GTypeInfo info =
+		{
+			sizeof (TnyGioOutputStreamClass),
+			NULL,   /* base_init */
+			NULL,   /* base_finalize */
+			(GClassInitFunc) tny_gio_output_stream_class_init,   /* class_init */
+			NULL,   /* class_finalize */
+			NULL,   /* class_data */
+			sizeof (TnyGioOutputStream),
+			0,      /* n_preallocs */
+			tny_gio_output_stream_instance_init,/* instance_init */
+			NULL
+		};
+
+	static const GInterfaceInfo tny_stream_info =
+		{
+			(GInterfaceInitFunc) tny_stream_init, /* interface_init */
+			NULL,         /* interface_finalize */
+			NULL          /* interface_data */
+		};
+
+	static const GInterfaceInfo tny_seekable_info =
+		{
+			(GInterfaceInitFunc) tny_seekable_init, /* interface_init */
+			NULL,         /* interface_finalize */
+			NULL          /* interface_data */
+		};
+
+	type = g_type_register_static (G_TYPE_OBJECT,
+				       "TnyVfsStream",
+				       &info, 0);
+
+	g_type_add_interface_static (type, TNY_TYPE_STREAM,
+				     &tny_stream_info);
+
+	g_type_add_interface_static (type, TNY_TYPE_SEEKABLE,
+				     &tny_seekable_info);
+
+	return GUINT_TO_POINTER (type);
+}
+
+GType
+tny_gio_output_stream_get_type (void)
+{
+	static GOnce once = G_ONCE_INIT;
+	g_once (&once, tny_gio_output_stream_register_type, NULL);
+	return GPOINTER_TO_UINT (once.retval);
+}
diff --git a/libtinymail-gio/tny-gio-output-stream.h b/libtinymail-gio/tny-gio-output-stream.h
new file mode 100644
index 0000000..0dda0bb
--- /dev/null
+++ b/libtinymail-gio/tny-gio-output-stream.h
@@ -0,0 +1,58 @@
+#ifndef TNY_GIO_OUTPUT_STREAM_H
+#define TNY_GIO_OUTPUT_STREAM_H
+
+/* libtinymail-gio - The Tiny Mail base library for Gio
+ * Copyright (C) 2009 Javier Jardón <javierjc1982@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with self library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#include <tny-stream.h>
+#include <tny-seekable.h>
+
+G_BEGIN_DECLS
+
+#define TNY_TYPE_GIO_OUTPUT_STREAM             (tny_gio_output_stream_get_type ())
+#define TNY_GIO_OUTPUT_STREAM(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), TNY_TYPE_GIO_OUTPUT_STREAM, TnyGioOutputStream))
+#define TNY_GIO_OUTPUT_STREAM_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), TNY_TYPE_GIO_OUTPUT_STREAM, TnyGioOutputStreamClass))
+#define TNY_IS_GIO_OUTPUT_STREAM(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TNY_TYPE_GIO_OUTPUT_STREAM))
+#define TNY_IS_GIO_OUTPUT_STREAM_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), TNY_TYPE_GIO_OUTPUT_STREAM))
+#define TNY_GIO_OUTPUT_STREAM_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), TNY_TYPE_GIO_OUTPUT_STREAM, TnyGioOutputStreamClass))
+
+typedef struct _TnyGioOutputStream TnyGioOutputStream;
+typedef struct _TnyGioOutputStreamClass TnyGioOutputStreamClass;
+
+struct _TnyGioOutputStream
+{
+	GObject parent;
+};
+
+struct _TnyGioOutputStreamClass
+{
+	GObjectClass parent;
+};
+
+GType tny_gio_output_stream_get_type (void);
+TnyStream* tny_gio_output_stream_new (GOutputStream *output_stream);
+void tny_gio_output_stream_set_stream (TnyGioOutputStream *self, GOutputStream *output_stream);
+
+G_END_DECLS
+
+#endif
