diff -rNuwb a/include/DialogFeatures.h b/include/DialogFeatures.h
--- a/include/DialogFeatures.h	2012-07-22 15:29:22.000000000 +0200
+++ b/include/DialogFeatures.h	2012-07-22 22:02:40.481288253 +0200
@@ -55,6 +55,7 @@
 		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > move ;
 		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > copy ;
 		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > check ;
+		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > change_format ;
 		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > label ;
 		Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > uuid ;
 		Gtk::TreeModelColumn<Glib::ustring> software ;
@@ -68,6 +69,7 @@
 			add( move ) ;
 			add( copy ) ;
 			add( check ) ;
+			add( change_format ) ;
 			add( label ) ;
 			add( uuid ) ;
 			add( software ) ;
diff -rNuwb a/include/FileSystem.h b/include/FileSystem.h
--- a/include/FileSystem.h	2012-07-22 15:29:22.000000000 +0200
+++ b/include/FileSystem.h	2012-07-22 22:02:40.481288253 +0200
@@ -37,6 +37,12 @@
 	virtual const Glib::ustring get_custom_text( CUSTOM_TEXT ttype, int index = 0 ) ;
 	static const Glib::ustring get_generic_text( CUSTOM_TEXT ttype, int index = 0 ) ;
 
+	// this method MUST be called instead of get_filesystem_support()
+	// calls get_filesystem_support() then perform post-inizialization of returned FS object
+	FS init_filesystem_support();
+
+	// this method MUST be implemented by sub-classes, but MUST NOT be called directly:
+	// please call init_filesystem_support() instead. Max: make this method protected?
 	virtual FS get_filesystem_support() = 0 ;
 	virtual void set_used_sectors( Partition & partition ) = 0 ;
 	virtual void read_label( Partition & partition ) = 0 ;
@@ -56,6 +62,11 @@
 			   OperationDetail & operationdetail ) = 0 ;
 	virtual bool check_repair( const Partition & partition, OperationDetail & operationdetail ) = 0 ;
 	
+	// transform a partition from a file system type to another.
+	// Default implementation uses external command 'fstransform', which takes a very long time to complete.
+	// Sub-classes should override this method if they have a more efficient implementation available.
+	virtual bool change_format( const Partition & original_partition, const Partition & new_partition, OperationDetail & operationdetail ) ;
+
 protected:
 	int execute_command( const Glib::ustring & command, OperationDetail & operationdetail ) ;
 	int execute_command_timed( const Glib::ustring & command
diff -rNuwb a/include/FSTransform.h b/include/FSTransform.h
--- a/include/FSTransform.h	1970-01-01 01:00:00.000000000 +0100
+++ b/include/FSTransform.h	2012-07-22 22:02:40.481288253 +0200
@@ -0,0 +1,70 @@
+/* Copyright (C) 2012 Massimiliano Ghilardi
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* READ THIS!
+ * This class was created in an effort to reduce the complexity of the
+ * GParted_Core class.
+ * This class provides support for 'fstransform' program.
+ * Static elements are used in order to reduce the disk accesses required to
+ * load the data structures upon each initialization of the class.
+ */
+
+#ifndef FSTRANSFORM_H_
+#define FSTRANSFORM_H_
+
+#include "../include/Utils.h"
+
+#include <set>
+
+namespace GParted
+{
+
+
+class FSTransform
+{
+public:
+	FSTransform( bool do_refresh = false ) ;
+	~FSTransform() ;
+
+	/** return true if fstranform is available */
+	static bool is_fstransform_supported() ;
+
+	/** return true if specified source file system is supported by fstransform */
+	static bool is_source_filesystem_supported( FILESYSTEM source_filesystem ) ;
+
+	/** return true if specified target file system is supported by fstransform */
+	static bool is_target_filesystem_supported( FILESYSTEM target_filesystem ) ;
+
+	/** return fstranform exact command name: it can be fstransform, fstransform.sh ... */
+	static inline const Glib::ustring & get_fstransform_command()
+	{
+		return ( fstransform_command ) ;
+	}
+
+private:
+	static void initialize_once( bool do_refresh = false );
+	static void find_command() ;
+	static void load_cache() ;
+	static std::set<FILESYSTEM> source_filesystems ;
+	static std::set<FILESYSTEM> target_filesystems ;
+	static Glib::ustring fstransform_command ;
+	static bool fstransform_cache_initialized ;
+};
+
+}//GParted
+
+#endif /* FSTRANSFORM_H_ */
diff -rNuwb a/include/GParted_Core.h b/include/GParted_Core.h
--- a/include/GParted_Core.h	2012-07-22 15:29:22.000000000 +0200
+++ b/include/GParted_Core.h	2012-07-22 22:02:40.481288253 +0200
@@ -102,6 +102,10 @@
 	
 	bool change_uuid( const Partition & partition, OperationDetail & operation_detail ) ;
 
+	FS::Support change_format_support( const FS & original_fs, const FS & partition_fs ) const ;
+
+	bool change_format( const Partition & original, const Partition & partition, OperationDetail & operation_detail ) ;
+
 	bool resize_move( const Device & device,
 			  const Partition & partition_old,
 			  Partition & partition_new,
diff -rNuwb a/include/Makefile.am b/include/Makefile.am
--- a/include/Makefile.am	2012-07-22 15:29:22.000000000 +0200
+++ b/include/Makefile.am	2012-07-22 22:02:40.481288253 +0200
@@ -19,6 +19,7 @@
 	Frame_Resizer_Base.h		\
 	Frame_Resizer_Extended.h	\
 	FS_Info.h				\
+	FSTransform.h  			\
 	GParted_Core.h    		\
 	HBoxOperations.h    		\
 	LVM2_PV_Info.h			\
@@ -31,6 +32,7 @@
 	OperationFormat.h		\
 	OperationResizeMove.h		\
 	OperationChangeUUID.h		\
+	OperationChangeFormat.h		\
 	OperationLabelPartition.h	\
 	Partition.h  			\
 	Proc_Partitions_Info.h	\
diff -rNuwb a/include/OperationChangeFormat.h b/include/OperationChangeFormat.h
--- a/include/OperationChangeFormat.h	1970-01-01 01:00:00.000000000 +0100
+++ b/include/OperationChangeFormat.h	2012-07-22 22:02:40.481288253 +0200
@@ -0,0 +1,41 @@
+/* Copyright (C) 2012 Massimiliano Ghilardi
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef OPERATIONCHANGEFORMAT
+#define OPERATIONCHANGEFORMAT
+
+#include "../include/Operation.h"
+
+namespace GParted
+{
+
+class OperationChangeFormat : public Operation
+{
+public:
+	OperationChangeFormat( const Device & device,
+			 const Partition & partition_orig,
+			 const Partition & partition_new ) ;
+
+	void apply_to_visual( std::vector<Partition> & partitions ) ;
+
+private:
+	void create_description() ;
+} ;
+
+} //GParted
+
+#endif //OPERATIONTRANSFORM
diff -rNuwb a/include/Operation.h b/include/Operation.h
--- a/include/Operation.h	2012-07-22 15:29:22.000000000 +0200
+++ b/include/Operation.h	2012-07-22 22:02:40.481288253 +0200
@@ -33,7 +33,8 @@
 	OPERATION_FORMAT	= 4,
 	OPERATION_COPY		= 5,
 	OPERATION_LABEL_PARTITION = 6,
-	OPERATION_CHANGE_UUID	= 7
+	OPERATION_CHANGE_UUID	= 7,
+	OPERATION_CHANGE_FORMAT	= 8
 };
 
 class Operation
diff -rNuwb a/include/Partition.h b/include/Partition.h
--- a/include/Partition.h	2012-07-22 15:29:22.000000000 +0200
+++ b/include/Partition.h	2012-07-22 22:02:40.481288253 +0200
@@ -41,7 +41,8 @@
 	STAT_REAL	=	0,
 	STAT_NEW	=	1,
 	STAT_COPY	=	2,
-	STAT_FORMATTED	=	3
+	STAT_FORMATTED	=	3,
+	STAT_FORMAT_CHANGED = 4
 };
 
 enum PartitionAlignment {
diff -rNuwb a/include/Utils.h b/include/Utils.h
--- a/include/Utils.h	2012-07-22 15:29:22.000000000 +0200
+++ b/include/Utils.h	2012-07-22 22:02:40.481288253 +0200
@@ -125,15 +125,25 @@
 	Support move ; //startpoint and endpoint
 	Support check ; //some checktool available?
 	Support copy ;
+	Support change_format_source ;
+	Support change_format_target ;
 
 	Byte_Value MIN ; 
 	Byte_Value MAX ;
 	
 	FS()
 	{
-		read = read_label = write_label = read_uuid = write_uuid = create = grow = shrink = move = check = copy = NONE;
+		read = read_label = write_label = read_uuid = write_uuid = create = grow = shrink = move = check = copy
+				= change_format_source = change_format_target = NONE;
 		MIN = MAX = 0 ;
 	} 
+
+	inline Support change_format() const
+	{
+		if ( change_format_source == change_format_target )
+			return ( change_format_source ) ;
+		return ( NONE );
+	}
 } ;
 
 
@@ -151,6 +161,7 @@
 	static Glib::ustring num_to_str( Sector number ) ;
 	static Glib::ustring get_color( FILESYSTEM filesystem ) ;
 	static Glib::RefPtr<Gdk::Pixbuf> get_color_as_pixbuf( FILESYSTEM filesystem, int width, int height ) ;
+	static FILESYSTEM get_filesystem_enum( const Glib::ustring & fs ) ;
 	static Glib::ustring get_filesystem_string( FILESYSTEM filesystem ) ;
 	static Glib::ustring get_filesystem_software( FILESYSTEM filesystem ) ;
 	static bool kernel_supports_fs( const Glib::ustring & fs ) ;
diff -rNuwb a/include/Win_GParted.h b/include/Win_GParted.h
--- a/include/Win_GParted.h	2012-07-22 15:29:22.000000000 +0200
+++ b/include/Win_GParted.h	2012-07-22 22:02:40.481288253 +0200
@@ -50,6 +50,7 @@
 	void init_toolbar() ;
 	void init_partition_menu() ;
 	Gtk::Menu * create_format_menu() ;
+	Gtk::Menu * create_change_format_menu() ;
 	void init_device_info() ;
 	void init_hpaned_main() ;
 
@@ -93,6 +94,9 @@
 	void allow_format( bool state )	{ 
 		toggle_item( state, MENU_FORMAT ) ; }
 	
+	void allow_change_format( bool state )	{
+		toggle_item( state, MENU_CHANGE_FORMAT ) ; }
+
 	void allow_toggle_swap_mount_state( bool state )	{ 
 		toggle_item( state, MENU_TOGGLE_MOUNT_SWAP ) ; }
 
@@ -164,6 +168,7 @@
 	void activate_delete();
 	void activate_info();
 	void activate_format( GParted::FILESYSTEM new_fs );
+	void activate_change_format( GParted::FILESYSTEM new_fs );
 	void toggle_swap_mount_state() ;
 	void activate_mount_partition( unsigned int index ) ;
 	void activate_disklabel() ;
@@ -235,6 +240,7 @@
         MENU_COPY, TOOLBAR_COPY,
         MENU_PASTE, TOOLBAR_PASTE,
         MENU_FORMAT,
+         MENU_CHANGE_FORMAT,
         MENU_TOGGLE_MOUNT_SWAP,
         MENU_MOUNT,
         MENU_FLAGS,
diff -rNuwb a/src/DialogFeatures.cc b/src/DialogFeatures.cc
--- a/src/DialogFeatures.cc	2012-07-22 15:29:22.000000000 +0200
+++ b/src/DialogFeatures.cc	2012-07-22 22:02:40.481288253 +0200
@@ -39,6 +39,7 @@
 	treeview_filesystems .append_column( _("Move"), treeview_filesystems_columns .move );
 	treeview_filesystems .append_column( _("Copy"), treeview_filesystems_columns .copy );
 	treeview_filesystems .append_column( _("Check"), treeview_filesystems_columns .check );
+	treeview_filesystems .append_column( _("Transform"), treeview_filesystems_columns .change_format );
 	treeview_filesystems .append_column( _("Label"), treeview_filesystems_columns .label );
 	treeview_filesystems .append_column( _("UUID"), treeview_filesystems_columns .uuid );
 	treeview_filesystems .append_column( _("Required Software"), treeview_filesystems_columns .software );
@@ -144,6 +145,7 @@
 	treerow[ treeview_filesystems_columns .move ] = fs .move ? icon_yes : icon_no ;  
 	treerow[ treeview_filesystems_columns .copy ] = fs .copy ? icon_yes : icon_no ; 
 	treerow[ treeview_filesystems_columns .check ] = fs .check ? icon_yes : icon_no ; 
+	treerow[ treeview_filesystems_columns .change_format ] = fs .change_format() ? icon_yes : icon_no ;
 	treerow[ treeview_filesystems_columns .label ] = fs .write_label ? icon_yes : icon_no ; 
 	treerow[ treeview_filesystems_columns .uuid ] = fs .write_uuid ? icon_yes : icon_no ;
 
diff -rNuwb a/src/FileSystem.cc b/src/FileSystem.cc
--- a/src/FileSystem.cc	2012-07-22 15:29:22.000000000 +0200
+++ b/src/FileSystem.cc	2012-07-22 22:02:40.481288253 +0200
@@ -17,6 +17,7 @@
  
  
 #include "../include/FileSystem.h"
+#include "../include/FSTransform.h"
 
 #include <cerrno>
 
@@ -48,6 +49,37 @@
 	}
 }
 
+// perform post-inizialization of FS object returned by get_filesystem_support()
+FS FileSystem::init_filesystem_support()
+{
+	FS fs = get_filesystem_support();
+
+	if (fs.change_format_source == FS::NONE && FSTransform::is_source_filesystem_supported( fs.filesystem ) )
+		fs.change_format_source = FS::EXTERNAL;
+
+	if (fs.change_format_target == FS::NONE && FSTransform::is_target_filesystem_supported( fs.filesystem ) )
+		fs.change_format_target = FS::EXTERNAL;
+
+	return fs;
+}
+
+// transform a partition from a file system type to another.
+// Default implementation uses external command 'fstransform', which takes a very long time to complete.
+// Sub-classes should override this method if they have a more efficient implementation available.
+bool FileSystem::change_format( const Partition & original_partition, const Partition & new_partition, OperationDetail & operationdetail )
+{
+	Glib::ustring str_temp
+		= FSTransform::get_fstransform_command() + " --no-questions " + new_partition .get_path()
+		+ " " + Utils::get_filesystem_string( new_partition .filesystem ) ;
+
+	bool success = ! execute_command_timed( str_temp, operationdetail, true ) ;
+
+	operationdetail .set_status( success ? STATUS_SUCCES : STATUS_ERROR ) ;
+
+	return success ;
+}
+
+
 int FileSystem::execute_command( const Glib::ustring & command, OperationDetail & operationdetail ) 
 {
 	operationdetail .add_child( OperationDetail( command, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
diff -rNuwb a/src/FSTransform.cc b/src/FSTransform.cc
--- a/src/FSTransform.cc	1970-01-01 01:00:00.000000000 +0100
+++ b/src/FSTransform.cc	2012-07-22 22:02:40.481288253 +0200
@@ -0,0 +1,156 @@
+/* Copyright (C) 2012 Massimiliano Ghilardi
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "../include/FSTransform.h"
+
+namespace GParted
+{
+
+//Initialize static data elements
+bool                 FSTransform::fstransform_cache_initialized = false ;
+Glib::ustring        FSTransform::fstransform_command ;
+std::set<FILESYSTEM> FSTransform::source_filesystems ;
+std::set<FILESYSTEM> FSTransform::target_filesystems ;
+
+FSTransform::FSTransform( bool do_refresh )
+{
+	initialize_once( do_refresh );
+}
+
+FSTransform::~FSTransform()
+{
+}
+
+void FSTransform::initialize_once( bool do_refresh )
+{
+	//Ensure that cache has been loaded at least once
+	if ( ! fstransform_cache_initialized )
+	{
+		fstransform_cache_initialized = true ;
+		do_refresh = true;
+	}
+	if ( do_refresh )
+	{
+		find_command() ;
+		load_cache() ;
+	}
+}
+
+void FSTransform::find_command()
+{
+	// Check and cache whether fstransform command is available in PATH
+	fstransform_command .clear();
+
+	Glib::ustring cmd[] = {
+	   // current fstransform command name (versions 0.9.2 and later)
+	   "fstransform",
+	   // old command name (up to version 0.9.1)
+	   "fstransform.sh",
+	} ;
+
+	for ( unsigned int i = 0, n = sizeof(cmd)/sizeof(cmd[0]) ; i < n ; i++ )
+	{
+		if (! Glib::find_program_in_path( cmd[ i ] ) .empty() )
+		{
+			fstransform_command = cmd[ i ];
+			break;
+		}
+	}
+}
+
+void FSTransform::load_cache()
+{
+	// Load data into source_filesystems and target_filesystems
+	source_filesystems .clear() ;
+	target_filesystems .clear() ;
+
+	if ( fstransform_command .empty() )
+		return;
+
+	// current fstransform (versions 0.9.3 and later) have options --list-source-file-systems and --list-target-file-systems
+	Glib::ustring output, error ;
+	FILESYSTEM filesystem = FS_UNKNOWN;
+	if ( ! Utils::execute_command( fstransform_command + " --list-source-file-systems", output, error, true ) && output .size() > 0 )
+	{
+		std::vector<Glib::ustring> temp_arr ;
+		Utils::tokenize( output, temp_arr, "\n" ) ;
+		for ( unsigned int k = 0; k < temp_arr .size(); k++ )
+		{
+			Glib::ustring temp = Utils::regexp_label( temp_arr[k], "^([-_A-Za-z0-9]*)$" ) ;
+			if ( temp .size() > 0 ) {
+				filesystem = Utils::get_filesystem_enum( temp ) ;
+				if (filesystem != FS_UNKNOWN )
+					source_filesystems .insert( filesystem ) ;
+			}
+		}
+	}
+	if ( ! Utils::execute_command( fstransform_command + " --list-target-file-systems", output, error, true ) && output .size() > 0 )
+	{
+		std::vector<Glib::ustring> temp_arr ;
+		Utils::tokenize( output, temp_arr, "\n" ) ;
+		for ( unsigned int k = 0; k < temp_arr .size(); k++ )
+		{
+			Glib::ustring temp = Utils::regexp_label( temp_arr[k], "^([-_A-Za-z0-9]*)$" ) ;
+			if ( temp .size() > 0 ) {
+				filesystem = Utils::get_filesystem_enum( temp ) ;
+				if (filesystem != FS_UNKNOWN )
+					target_filesystems .insert( filesystem ) ;
+			}
+		}
+	}
+
+	// old fstransform versions (up to 0.9.2) do not have options --list-source-file-systems and --list-target-file-systems
+	// anyway we know they support minix (not interesting), ext2, ext3, ext4, jfs, reiserfs and xfs,
+	// and all of them are supported both as source and as target
+	if ( source_filesystems .empty() && target_filesystems .empty() )
+	{
+		FILESYSTEM supported_old[] = { FS_EXT2, FS_EXT3, FS_EXT4, FS_JFS, FS_REISERFS, FS_XFS } ;
+		for ( unsigned int k = 0, n = sizeof(supported_old) / sizeof(supported_old[0]) ; k < n ; k++ )
+		{
+			source_filesystems .insert( supported_old[ k ] );
+			target_filesystems .insert( supported_old[ k ] );
+		}
+	}
+}
+
+
+/** Return true if fstransform command is available */
+bool FSTransform::is_fstransform_supported()
+{
+	initialize_once();
+
+	return ( ! fstransform_command .empty() ) ;
+}
+
+
+/** return list of source file systems fstransform is able to transform FROM */
+bool FSTransform::is_source_filesystem_supported( FILESYSTEM source_filesystem )
+{
+	initialize_once();
+
+	return ( source_filesystems.count( source_filesystem ) > 0 );
+}
+
+/** return list of target file systems fstransform is able to transform TO */
+bool FSTransform::is_target_filesystem_supported( FILESYSTEM target_filesystem )
+{
+	initialize_once();
+
+	return ( target_filesystems.count( target_filesystem ) > 0 );
+}
+
+}//GParted
diff -rNuwb a/src/GParted_Core.cc b/src/GParted_Core.cc
--- a/src/GParted_Core.cc	2012-07-22 15:29:22.000000000 +0200
+++ b/src/GParted_Core.cc	2012-07-22 22:02:40.481288253 +0200
@@ -92,7 +92,7 @@
 
 void GParted_Core::find_supported_filesystems()
 {
-	std::map< FILESYSTEM, FileSystem * >::iterator f ;
+	std::map< FILESYSTEM, FileSystem * >::iterator f, fend ;
 
 	// TODO: determine whether it is safe to initialize this only once
 	for ( f = FILESYSTEM_MAP .begin() ; f != FILESYSTEM_MAP .end() ; f++ ) {
@@ -126,9 +126,9 @@
 	FILESYSTEMS .clear() ;
 
 	FS fs_notsupp;
-	for ( f = FILESYSTEM_MAP .begin() ; f != FILESYSTEM_MAP .end() ; f++ ) {
+	for ( f = FILESYSTEM_MAP .begin(), fend = FILESYSTEM_MAP .end() ; f != fend ; ++f ) {
 		if ( f ->second )
-			FILESYSTEMS .push_back( f ->second ->get_filesystem_support() ) ;
+			FILESYSTEMS .push_back( f ->second ->init_filesystem_support() ) ;
 		else {
 			fs_notsupp .filesystem = f ->first ;
 			FILESYSTEMS .push_back( fs_notsupp ) ;
@@ -697,6 +697,9 @@
 			case OPERATION_CHANGE_UUID:
 				succes = change_uuid( operation ->partition_new, operation ->operation_detail ) ;
 				break ;
+			case OPERATION_CHANGE_FORMAT:
+				succes = change_format( operation ->partition_original, operation ->partition_new, operation ->operation_detail ) ;
+				break ;
 		}
 
 	if ( libparted_messages .size() > 0 )
@@ -1800,6 +1803,57 @@
 	return set_partition_type( partition, operationdetail ) && create_filesystem( partition, operationdetail ) ;
 }
 
+/**
+ * return the supported mechanism to change a partition from one file system to another.
+ * Result depends on _both_ original and new file systems!
+ */
+FS::Support GParted_Core::change_format_support( const FS & original_fs, const FS & partition_fs ) const
+{
+	FS::Support original_support = original_fs.change_format_source;
+	FS::Support partition_support = partition_fs.change_format_target;
+
+	if (original_support == partition_support)
+		return original_support;
+
+	return FS::NONE;
+}
+
+bool GParted_Core::change_format( const Partition & original, const Partition & partition, OperationDetail & operationdetail )
+{
+	/*TO TRANSLATORS: looks like transform file system from jfs to reiserfs */
+	operationdetail .add_child( OperationDetail( String::ucompose(
+							_("transform file system from %1 to %2"),
+							Utils::get_filesystem_string( original .filesystem ),
+							Utils::get_filesystem_string( partition .filesystem ) ) ) ) ;
+
+	const FS & original_fs = get_fs( original .filesystem );
+	const FS & partition_fs = get_fs( partition .filesystem );
+
+	bool succes = false ;
+	switch ( change_format_support( original_fs, partition_fs ) )
+	{
+		case GParted::FS::NONE:
+			break ;
+		case GParted::FS::GPARTED:
+			break ;
+#ifndef HAVE_LIBPARTED_3_0_PLUS
+		case GParted::FS::LIBPARTED:
+			break ;
+#endif
+		case GParted::FS::EXTERNAL:
+			succes = set_proper_filesystem( partition .filesystem ) &&
+				 p_filesystem ->change_format( original, partition, operationdetail .get_last_child() ) ;
+			break ;
+
+		default:
+			break ;
+	}
+
+	operationdetail .get_last_child() .set_status(  succes ? STATUS_SUCCES : STATUS_ERROR ) ;
+	return succes ;
+}
+
+
 bool GParted_Core::Delete( const Partition & partition, OperationDetail & operationdetail ) 
 {
 	operationdetail .add_child( OperationDetail( _("delete partition") ) ) ;
@@ -3445,7 +3499,11 @@
 
 GParted_Core::~GParted_Core() 
 {
-	delete p_filesystem;
+	// p_filesystem belongs to FILESYSTEM_MAP
+	// and is allocated only once by find_supported_filesystems():
+	// we must not delete it
+
+	// delete p_filesystem;
 }
 
 Glib::Thread *GParted_Core::mainthread;
diff -rNuwb a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am	2012-07-22 15:29:22.000000000 +0200
+++ b/src/Makefile.am	2012-07-22 22:02:40.481288253 +0200
@@ -29,10 +29,12 @@
 	Frame_Resizer_Base.cc		\
 	Frame_Resizer_Extended.cc	\
 	FS_Info.cc				\
+	FSTransform.cc			\
 	GParted_Core.cc			\
 	HBoxOperations.cc		\
 	LVM2_PV_Info.cc			\
 	Operation.cc			\
+	OperationChangeFormat.cc	\
 	OperationChangeUUID.cc		\
 	OperationCopy.cc		\
 	OperationCheck.cc		\
diff -rNuwb a/src/OperationChangeFormat.cc b/src/OperationChangeFormat.cc
--- a/src/OperationChangeFormat.cc	1970-01-01 01:00:00.000000000 +0100
+++ b/src/OperationChangeFormat.cc	2012-07-22 22:02:40.481288253 +0200
@@ -0,0 +1,64 @@
+/* Copyright (C) 2012 Massimiliano Ghilardi
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "../include/OperationChangeFormat.h"
+
+namespace GParted
+{
+
+OperationChangeFormat::OperationChangeFormat( const Device & device,
+				  const Partition & partition_orig,
+				  const Partition & partition_new )
+{
+	type = OPERATION_CHANGE_FORMAT ;
+
+	this ->device = device ;
+	this ->partition_original = partition_orig ;
+	this ->partition_new = partition_new ;
+}
+
+void OperationChangeFormat::apply_to_visual( std::vector<Partition> & partitions )
+{
+	if ( partition_original .inside_extended )
+	{
+		index_extended = find_index_extended( partitions ) ;
+
+		if ( index_extended >= 0 )
+			index = find_index_original( partitions[ index_extended ] .logicals ) ;
+
+		if ( index >= 0 )
+			partitions[ index_extended ] .logicals[ index ] = partition_new ;
+	}
+	else
+	{
+		index = find_index_original( partitions ) ;
+
+		if ( index >= 0 )
+			partitions[ index ] = partition_new ;
+	}
+}
+
+void OperationChangeFormat::create_description()
+{
+	/*TO TRANSLATORS: looks like  Transform /dev/hda4 file system reiserfs to ext4*/
+	description = String::ucompose( _("Transform %1 from %2 to %3"),
+					partition_original .get_path(),
+					Utils::get_filesystem_string( partition_original .filesystem ),
+					Utils::get_filesystem_string( partition_new .filesystem ) ) ;
+}
+
+} //GParted
diff -rNuwb a/src/Utils.cc b/src/Utils.cc
--- a/src/Utils.cc	2012-07-22 15:29:22.000000000 +0200
+++ b/src/Utils.cc	2012-07-22 22:02:40.481288253 +0200
@@ -167,6 +167,39 @@
 	}
 }
 
+FILESYSTEM Utils::get_filesystem_enum( const Glib::ustring & fs )
+{
+	FILESYSTEM filesystem;
+	if (fs == "extended")				filesystem = FS_EXTENDED ;
+	else if (fs == "btrfs")				filesystem = FS_BTRFS ;
+	else if (fs == "ext2")				filesystem = FS_EXT2 ;
+	else if (fs == "ext3")				filesystem = FS_EXT3 ;
+	else if (fs == "ext4")				filesystem = FS_EXT4 ;
+	else if (fs == "linux-swap")		filesystem = FS_LINUX_SWAP ;
+	else if (fs == "fat16")				filesystem = FS_FAT16 ;
+	else if (fs == "fat32")				filesystem = FS_FAT32 ;
+	else if (fs == "exfat")				filesystem = FS_EXFAT ;
+	else if (fs == "nilfs2")			filesystem = FS_NILFS2 ;
+	else if (fs == "reiserfs")			filesystem = FS_REISERFS ;
+	else if (fs == "reiser4")			filesystem = FS_REISER4 ;
+	else if (fs == "xfs")				filesystem = FS_XFS ;
+	else if (fs == "jfs")				filesystem = FS_JFS ;
+	else if (fs == "hfs")				filesystem = FS_HFS ;
+	else if (fs == "hfs+")				filesystem = FS_HFSPLUS ;
+	else if (fs == "ufs")				filesystem = FS_UFS ;
+	else if (fs == "lvm2 pv")			filesystem = FS_LVM2_PV ;
+	else if (fs == "crypt-luks")		filesystem = FS_LUKS ;
+	// we put translated names as last, in case they are translated to one of the names above
+	else if (fs == _("unallocated"))	filesystem = FS_UNALLOCATED ;
+	else if (fs == _("unknown"))		filesystem = FS_UNKNOWN ;
+	else if (fs == _("unformatted"))	filesystem = FS_UNFORMATTED ;
+	else if (fs == _("used"))			filesystem = FS_USED ;
+	else if (fs == _("unused"))			filesystem = FS_UNUSED ;
+	else								filesystem = FS_UNKNOWN;
+
+	return filesystem;
+}
+
 Glib::ustring Utils::get_filesystem_software( FILESYSTEM filesystem )
 {
 	switch( filesystem )
diff -rNuwb a/src/Win_GParted.cc b/src/Win_GParted.cc
--- a/src/Win_GParted.cc	2012-07-22 15:29:22.000000000 +0200
+++ b/src/Win_GParted.cc	2012-07-22 22:21:28.007986311 +0200
@@ -32,6 +32,7 @@
 #include "../include/OperationCreate.h"
 #include "../include/OperationDelete.h"
 #include "../include/OperationFormat.h"
+#include "../include/OperationChangeFormat.h"
 #include "../include/OperationResizeMove.h"
 #include "../include/OperationChangeUUID.h"
 #include "../include/OperationLabelPartition.h"
@@ -60,7 +61,7 @@
         MENU_RESIZE_MOVE = TOOLBAR_RESIZE_MOVE =
         MENU_COPY = TOOLBAR_COPY =
         MENU_PASTE = TOOLBAR_PASTE =
-        MENU_FORMAT =
+         MENU_FORMAT = MENU_CHANGE_FORMAT =
         MENU_TOGGLE_MOUNT_SWAP =
         MENU_MOUNT =
         MENU_FLAGS =
@@ -329,6 +330,14 @@
 							  sigc::mem_fun(*this, &Win_GParted::activate_resize) ) );
 	MENU_RESIZE_MOVE = index++ ;
 	
+	image = manage( new Gtk::Image( Gtk::Stock::SAVE_AS, Gtk::ICON_SIZE_MENU ) );
+	/*TO TRANSLATORS: menuitem which holds a submenu with file systems.. */
+	menu_partition .items() .push_back(
+			Gtk::Menu_Helpers::ImageMenuElem( _("_Transform to"),
+							  *image,
+							  * create_change_format_menu() ) ) ;
+	MENU_CHANGE_FORMAT = index++ ;
+
 	menu_partition .items() .push_back( Gtk::Menu_Helpers::SeparatorElem() );
 	index++ ;
 	
@@ -441,6 +450,52 @@
 	return menu ;
 }
 	
+Gtk::Menu * Win_GParted::create_change_format_menu()
+{
+	menu = manage( new Gtk::Menu() ) ;
+
+	const std::vector<FS> & fs_list = gparted_core .get_filesystems();
+
+	for ( size_t t = 0, n = fs_list.size() ; t < n ; t++ )
+	{
+		const FS & t_fs = fs_list[ t ];
+		const FILESYSTEM t_filesystem = t_fs .filesystem;
+
+		//Skip luks, lvm2, and unknown because these are not file systems
+		if (
+			 t_filesystem == GParted::FS_LUKS    ||
+			 t_filesystem == GParted::FS_LVM2_PV ||
+			 t_filesystem == GParted::FS_UNKNOWN
+		   )
+			continue ;
+
+		hbox = manage( new Gtk::HBox() );
+
+		//the colored square
+		hbox ->pack_start( * manage( new Gtk::Image(
+					Utils::get_color_as_pixbuf(
+							t_filesystem, 16, 16 ) ) ),
+				   Gtk::PACK_SHRINK ) ;
+
+		//the label...
+		hbox ->pack_start( * Utils::mk_label(
+					" " +
+					Utils::get_filesystem_string( t_filesystem ) ),
+				   Gtk::PACK_SHRINK );
+
+		menu ->items() .push_back( * manage( new Gtk::MenuItem( *hbox ) ) );
+		if ( t_fs .change_format_target )
+			menu ->items() .back() .signal_activate() .connect(
+				sigc::bind<GParted::FILESYSTEM>(sigc::mem_fun(*this, &Win_GParted::activate_change_format),
+				t_filesystem ) ) ;
+		else
+			menu ->items() .back() .set_sensitive( false ) ;
+	}
+
+	return menu ;
+}
+
+
 void Win_GParted::init_device_info()
 {
 	vbox_info.set_spacing( 5 );
@@ -809,6 +864,20 @@
 
 		return true;
 	}
+	// Two change file system operations of the same partition
+	else if ( operations[ first ]->type == OPERATION_CHANGE_FORMAT &&
+		  operations[ second ]->type == OPERATION_CHANGE_FORMAT &&
+		  operations[ first ]->partition_new == operations[ second ]->partition_original
+		)
+	{
+		operations[ first ]->partition_new = operations[ second ]->partition_new;
+		operations[ first ]->create_description() ;
+		remove_operation( second );
+
+		Refresh_Visual();
+
+		return true;
+	}
 
 	return false;
 }
@@ -907,7 +976,7 @@
 void Win_GParted::set_valid_operations()
 {
 	allow_new( false ); allow_delete( false ); allow_resize( false ); allow_copy( false );
-	allow_paste( false ); allow_format( false ); allow_toggle_swap_mount_state( false ) ;
+	allow_paste( false ); allow_format( false ); allow_change_format( false ); allow_toggle_swap_mount_state( false ) ;
 	allow_manage_flags( false ) ; allow_check( false ) ; allow_label_partition( false ) ;
 	allow_change_uuid( false ); allow_info( false ) ;
 	
@@ -1055,6 +1124,16 @@
 		if ( selected_partition .status == GParted::STAT_REAL && fs .write_uuid )
 			allow_change_uuid( true ) ;
 
+		//only allow changing format of REAL, COPY and FORMAT_CHANGED partitions that support it:
+		//if a partition is NEW or FORMATTED, then it contains no data -> transforming it is meaningless
+		if ( ( selected_partition .status == GParted::STAT_REAL
+				|| selected_partition .status == GParted::STAT_COPY
+				|| selected_partition .status == GParted::STAT_FORMAT_CHANGED
+				) && fs .change_format_source )
+		{
+			allow_change_format( true ) ;
+		}
+
 		//Generate Mount on submenu, except for LVM2 PVs
 		//  borrowing mount point to display the VGNAME
 		if (   selected_partition .filesystem != GParted::FS_LVM2_PV
@@ -1909,15 +1988,45 @@
 				Operation * operation = new OperationCreate( devices[ current_device ],
 									     selected_partition,
 								 	     part_temp ) ;
+
 				operation ->icon = render_icon( Gtk::Stock::NEW, Gtk::ICON_SIZE_MENU );
 
 				Add_Operation( operation, t ) ;
 					
-				break;
+				return;
+			}
+		}
+	}
+	//if selected partition is FORMAT_CHANGED we simply remove the last FORMAT_CHANGED operation from the list and
+	//add a FORMAT operation with the new file system
+	if ( selected_partition .status == GParted::STAT_FORMAT_CHANGED ) {
+		//remove operation which creates this partition
+		for ( unsigned int t1 = operations .size() ; t1 > 0 ; t1-- )
+		{
+			unsigned int t = t1 - 1;
+			if ( operations[ t ] ->partition_new == selected_partition )
+			{
+				remove_operation( t ) ;
+
+
+				//And insert the new partition at the old position in the operations list
+				//(NOTE: we set status to STAT_FORMATTED)
+
+				Operation * operation = new OperationFormat( devices[ current_device ],
+												selected_partition,
+												part_temp ) ;
+
+				operation ->icon = render_icon( Gtk::Stock::CONVERT, Gtk::ICON_SIZE_MENU );
+
+				Add_Operation( operation, t ) ;
+
+				return;
+
 			}
 		}
 	}
-	else//normal formatting of an existing partition
+
+	//normal formatting of an existing partition
 	{
 		Operation *operation = new OperationFormat( devices[ current_device ],
 				 			    selected_partition,
@@ -1934,6 +2043,104 @@
 	}
 }
 
+void Win_GParted::activate_change_format( GParted::FILESYSTEM new_fs )
+{
+	//check for some limits...
+	fs = gparted_core .get_fs( new_fs ) ;
+
+	if ( ( selected_partition .get_byte_length() < fs .MIN ) ||
+	     ( fs .MAX && selected_partition .get_byte_length() > fs .MAX ) )
+	{
+		Gtk::MessageDialog dialog( *this,
+					   String::ucompose(
+							/* TO TRANSLATORS: looks like
+							* Cannot transform this file system to fat16.
+							*/
+							_( "Cannot transform this file system to %1." ),
+							   Utils::get_filesystem_string( new_fs ) ) ,
+					   false,
+					   Gtk::MESSAGE_ERROR,
+					   Gtk::BUTTONS_OK,
+					   true );
+
+		if ( selected_partition .get_byte_length() < fs .MIN )
+			dialog .set_secondary_text( String::ucompose(
+						/* TO TRANSLATORS: looks like
+						 * A fat16 file system requires a partition of at least 16.00 MiB.
+						 */
+						_( "A %1 file system requires a partition of at least %2."),
+						Utils::get_filesystem_string( new_fs ),
+						Utils::format_size( fs .MIN, 1 /* Byte */ ) ) );
+		else
+			dialog .set_secondary_text( String::ucompose(
+						/* TO TRANSLATORS: looks like
+						 * A partition with a hfs file system has a maximum size of 2.00 GiB.
+						 */
+						_( "A partition with a %1 file system has a maximum size of %2."),
+						Utils::get_filesystem_string( new_fs ),
+						Utils::format_size( fs .MAX, 1 /* Byte */ ) ) );
+
+		dialog .run() ;
+		return ;
+	}
+
+	//ok we made it. lets create a fitting partition object
+	Partition part_temp ;
+	part_temp .Set( devices[ current_device ] .get_path(),
+			selected_partition .get_path(),
+			selected_partition .partition_number,
+			selected_partition .type,
+			new_fs,
+			selected_partition .sector_start,
+			selected_partition .sector_end,
+			devices[ current_device ] .sector_size,
+			selected_partition .inside_extended,
+			false ) ;
+	part_temp .set_sector_usage( selected_partition .get_sector_length(), selected_partition .get_sectors_unused() );
+
+	part_temp .status = GParted::STAT_FORMAT_CHANGED ;
+
+	//normal transformation of an already formatted partition that contains (possibly) useful data
+	{
+		Operation *operation = new OperationChangeFormat( devices[ current_device ],
+							    selected_partition,
+							    part_temp );
+		operation ->icon = render_icon( Gtk::Stock::SAVE_AS, Gtk::ICON_SIZE_MENU );
+
+		//Warn that transform operation might take long time
+		Gtk::MessageDialog dialog( *this
+					 , _( "Transforming a partition might cause your operating system to fail to boot." )
+					 , false
+					 , Gtk::MESSAGE_WARNING
+					 , Gtk::BUTTONS_OK
+					 , true
+					 ) ;
+		Glib::ustring tmp_msg =
+			/*TO TRANSLATORS: looks like   You queued an operation to tranform the file system of partition /dev/sda3. */
+			String::ucompose( _( "You have queued an operation to transform the file system of partition %1." )
+					, operation ->partition_original .get_path()
+					) ;
+		tmp_msg += _( "  Failure to boot is most likely to occur if you tranform the GNU/Linux partition containing /boot." ) ;
+		tmp_msg += "\n" ;
+		tmp_msg += _( "You can learn how to repair the boot configuration in the GParted FAQ." ) ;
+		tmp_msg += "\n" ;
+		tmp_msg += "http://gparted.org/faq.php" ;
+		tmp_msg += "\n\n" ;
+		tmp_msg += _( "Transforming a partition might take a very long time to apply." ) ;
+		dialog .set_secondary_text( tmp_msg ) ;
+		dialog .run() ;
+
+		Add_Operation( operation ) ;
+
+		// Try to merge with previous operation
+		if ( operations .size() >= 2 )
+		{
+			Merge_Operations( operations .size() - 2, operations .size() - 1 );
+		}
+	}
+}
+
+
 void Win_GParted::thread_unmount_partition( bool * succes, Glib::ustring * error ) 
 {
 	std::vector<Glib::ustring> errors, failed_mountpoints, mountpoints = gparted_core .get_all_mountpoints() ;
