diff --git a/contrib/mobile/Android/res/raw/models.zip b/contrib/mobile/Android/res/raw/models.zip
index de8f6ff724bec17b9e76ab05fdbd88d6f17e3578..c97774202966cc557d8262faa482cd0965fb3340 100644
Binary files a/contrib/mobile/Android/res/raw/models.zip and b/contrib/mobile/Android/res/raw/models.zip differ
diff --git a/contrib/mobile/Android/res/xml/models.xml b/contrib/mobile/Android/res/xml/models.xml
deleted file mode 100644
index 6f6dcd891a657fe73cfea0671cb6f0d21f65549b..0000000000000000000000000000000000000000
--- a/contrib/mobile/Android/res/xml/models.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?> 
-
-<models>
-    <model>
-        <title>Magnet</title>
-        <summary>Simple magnet example</summary>
-        <file type="geo">magnet.geo</file>
-    </model>
-    
-    <model>
-        <title>Eight-pole permanent magnet synchronous machine</title>
-        <summary></summary>
-        <file type="geo">pmsm.geo</file>
-    </model>
-</models>
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/ModelList.java b/contrib/mobile/Android/src/org/geuz/onelab/ModelList.java
index 1f0a1c6d81209610b946ed21018aa140b7192fd4..79eda56922d300f257ffd207fba8994e67c0ed2c 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/ModelList.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/ModelList.java
@@ -1,8 +1,10 @@
 package org.geuz.onelab;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FilenameFilter;
 import java.io.IOException;
+import java.io.InputStream;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -17,6 +19,7 @@ import android.content.res.XmlResourceParser;
 import android.graphics.Color;
 import android.os.Bundle;
 import android.os.Environment;
+import android.util.Xml;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.widget.AdapterView;
@@ -34,7 +37,15 @@ public class ModelList extends Activity {
 		super.onCreate(savedInstanceState);
 		
 		this.modelList = new Models();
-		this.getModels();
+		try {
+			this.getModels();
+		} catch (XmlPullParserException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
 		
 		LinearLayout layout = new LinearLayout(this);
     	layout.setOrientation(LinearLayout.VERTICAL);
@@ -56,11 +67,10 @@ public class ModelList extends Activity {
 			public void onItemClick(AdapterView<?> parent, View view, int position,
 					long id) {
 				int model = (position < modelList.size())? position : 0;
-				String path = getFilesDir() + "/" + modelList.getFile(model);
 				
 				Intent intent = new Intent(ModelList.this, MainActivity.class);
 				intent.putExtra("model", model);
-				intent.putExtra("file", path);
+				intent.putExtra("file", modelList.getFile(model));
 				intent.putExtra("name", modelList.getName(model));
 				startActivity(intent);
 			}
@@ -71,52 +81,82 @@ public class ModelList extends Activity {
 		layout.setBackgroundColor(Color.argb(255, 67, 67, 67));
 	}
 	
-	private void getModels()
+	private void getModels() throws XmlPullParserException, IOException
     {
-    	XmlResourceParser parser =  getResources().getXml(R.xml.models);
-    	int eventType;
-		try {
-			eventType = parser.getEventType();
-    	while (eventType != XmlPullParser.END_DOCUMENT) {
-            if(eventType == XmlPullParser.START_DOCUMENT){
-            	eventType = parser.next();
-            	continue;
-            }
-            else if(eventType == XmlPullParser.START_TAG && parser.getName().equals("model")) {
-            	String title = "", file = "", summary = "";
-            	while(eventType != XmlPullParser.END_TAG || !parser.getName().equals("model"))
-            	{
-            		
-            		eventType = parser.next();
-            		if(eventType == XmlPullParser.START_TAG && parser.getName().equals("title")){
-            			eventType = parser.next();
-            			if(eventType == XmlPullParser.TEXT)
-            				title = parser.getText();
-            		}
-            		else if(eventType == XmlPullParser.START_TAG && parser.getName().equals("summary")){
-            			eventType = parser.next();
-            			if(eventType == XmlPullParser.TEXT)
-            				summary = parser.getText();
-            		}
-            		else if(eventType == XmlPullParser.START_TAG && parser.getName().equals("file")){
-            			eventType = parser.next();
-            			if(eventType == XmlPullParser.TEXT)
-            				file = parser.getText();
-            		}
-            	}
-            	if(title.length() > 0) modelList.addModel(title, summary, file);
-            }
-            eventType = parser.next();
-           }
-		} catch (XmlPullParserException e) {
-			// TODO Error in XML file
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Error in XML file
-			e.printStackTrace();
+		File document = this.getFilesDir();
+		File files[] = document.listFiles();
+		for(int i=0; i<files.length; i++) {
+			if(files[i].isDirectory()) { // models are in directory
+				File xmlInfos = new File(files[i], "infos.xml");
+				if(!xmlInfos.isFile()) continue;
+				InputStream in = new FileInputStream(xmlInfos);
+				try {
+					XmlPullParser parser = Xml.newPullParser();
+					parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
+					parser.setInput(in, null);
+					parser.nextTag();
+					parser.require(XmlPullParser.START_TAG, null, "models");
+					while (parser.next() != XmlPullParser.END_TAG) {
+						if (parser.getEventType() != XmlPullParser.START_TAG) continue;
+						String tagName = parser.getName();
+						if(tagName.equals("model"))
+							readModel(parser, files[i].toString());
+						else
+							skipTag(parser);
+					}
+				}
+				finally {
+					in.close();
+				}
+			}
 		}
-
     }
+	private void readModel(XmlPullParser parser, String dir) throws XmlPullParserException, IOException{
+		parser.require(XmlPullParser.START_TAG, null, "model");
+		String title = null;
+	    String summary = null;
+	    String file = null;
+	    while (parser.next() != XmlPullParser.END_TAG) {
+	    	if (parser.getEventType() != XmlPullParser.START_TAG) continue;
+	    	String name = parser.getName();
+	    	if(name.equals("title")) {
+	    		if (parser.next() == XmlPullParser.TEXT) {
+	    			title = parser.getText();
+	    			parser.nextTag();
+	    		}
+	    	}
+	    	else if(name.equals("summary")) {
+	    		if (parser.next() == XmlPullParser.TEXT) {
+	    			summary = parser.getText();
+	    			parser.nextTag();
+	    		}
+	    	}
+	    	else if(name.equals("file")) {
+	    		//String relType = parser.getAttributeValue(null, "type"); 
+	    		if (parser.next() == XmlPullParser.TEXT) {
+	    			file = parser.getText();
+	    			parser.nextTag();
+	    		}
+	    	}
+	    }
+	    modelList.addModel(title, summary, dir+"/"+file);
+	}
+	private void skipTag(XmlPullParser parser) throws XmlPullParserException, IOException {
+	    if (parser.getEventType() != XmlPullParser.START_TAG) {
+	        throw new IllegalStateException();
+	    }
+	    int depth = 1;
+	    while (depth != 0) {
+	        switch (parser.next()) {
+	        case XmlPullParser.END_TAG:
+	            depth--;
+	            break;
+	        case XmlPullParser.START_TAG:
+	            depth++;
+	            break;
+	        }
+	    }
+	 }
 	
 
     private class SDFileChooser{
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/OptionsFragment.java b/contrib/mobile/Android/src/org/geuz/onelab/OptionsFragment.java
index e9e7aaba38508751ee25a2b8379d1843d69df3d9..f3aca46baad53ac8c0e567cbec099cb927394a89 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/OptionsFragment.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/OptionsFragment.java
@@ -12,6 +12,7 @@ import android.app.FragmentTransaction;
 public class OptionsFragment extends Fragment{
 
 	private Gmsh _gmsh;
+	private int _viewN;
 	private OptionsDisplayFragment _optionDisplayFragment;
 	private OptionsModelFragment _optionModelFragment;
 	
@@ -30,6 +31,9 @@ public class OptionsFragment extends Fragment{
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		_gmsh = getArguments().getParcelable("Gmsh");
+		_viewN = 0;
+		if(savedInstanceState != null)
+			_viewN = savedInstanceState.getInt("viewN");
 	}
 	
 	@Override
@@ -37,12 +41,19 @@ public class OptionsFragment extends Fragment{
 			Bundle savedInstanceState) {
 		LinearLayout rootView = (LinearLayout)inflater.inflate(R.layout.fragment_options, container, false);
 		_optionModelFragment = OptionsModelFragment.newInstance(_gmsh);
-		getFragmentManager().beginTransaction().add(R.id.options_fragment, _optionModelFragment).commit();
 		_optionDisplayFragment = OptionsDisplayFragment.newInstance(_gmsh);
 		final Button optionModel = (Button) rootView.findViewById(R.id.goto_options_model);
 		final Button optionDisplay = (Button) rootView.findViewById(R.id.goto_options_display);
-		optionDisplay.setEnabled(true);
-		optionModel.setEnabled(false);
+		if(_viewN == 0) {
+			optionDisplay.setEnabled(true);
+			optionModel.setEnabled(false);
+			getFragmentManager().beginTransaction().add(R.id.options_fragment, _optionModelFragment).commit();
+		}
+		else {
+			optionDisplay.setEnabled(false);
+			optionModel.setEnabled(true);
+			getFragmentManager().beginTransaction().add(R.id.options_fragment, _optionDisplayFragment).commit();
+		}
 		optionModel.setOnClickListener(new View.OnClickListener() {
 			
 			public void onClick(View v) {
@@ -52,6 +63,7 @@ public class OptionsFragment extends Fragment{
 	            ft.replace(R.id.options_fragment, _optionModelFragment);
 	            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
 	            ft.commit();
+	            _viewN = 0;
 			}
 		});
 		optionDisplay.setOnClickListener(new View.OnClickListener() {
@@ -63,11 +75,18 @@ public class OptionsFragment extends Fragment{
 	            ft.replace(R.id.options_fragment, _optionDisplayFragment);
 	            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
 	            ft.commit();
+	            _viewN = 1;
 			}
 		});
 		return rootView;
 	}
 	
+	@Override
+	public void onSaveInstanceState(Bundle outState) {
+		super.onSaveInstanceState(outState);
+		outState.putInt("viewN", _viewN);
+	}
+	
 	public void refresh() {
 		if(_optionDisplayFragment != null)_optionDisplayFragment.refresh();
 		if(_optionModelFragment != null)_optionModelFragment.refresh();
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/OptionsModelFragment.java b/contrib/mobile/Android/src/org/geuz/onelab/OptionsModelFragment.java
index 9834b441f159fca39fc7bb03a501c2eecdcdedbf..2eeb99ddf4d9fb5867b7838df576d834399c2143 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/OptionsModelFragment.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/OptionsModelFragment.java
@@ -52,7 +52,7 @@ public class OptionsModelFragment extends Fragment{
 		for(String s : tmp){ // for each parameters in ONEALB
 			boolean found = false;
 			for(Parameter p : params){ // for each parameters
-				if(s.split("\n")[2].equals(p.getName())){ // the parameter already exist, just refresh it
+				if(s.split(Character.toString((char)0x03))[2].equals(p.getName())){ // the parameter already exist, just refresh it
 					if(p.getType().equals("ParameterNumber"))
 						((ParameterNumber)p).fromString(s);
 					else if(p.getType().equals("ParameterString"))
@@ -63,14 +63,14 @@ public class OptionsModelFragment extends Fragment{
 			}
 			if(found) continue;
 			// add new parameter
-			if(s.split("\n")[1].equals("number")){
+			if(s.split(Character.toString((char)0x03))[1].equals("number")){
 				final ParameterNumber mParam = new ParameterNumber(_listView.getContext(), _gmsh, mCallback, "");
 				if(mParam.fromString(s) == -1) continue;
 				params.add(mParam);
 				if(_listView != null)
 					_listView.addItem(mParam.getName().split("/")[0].equals("Parameters")? mParam.getName().split("/")[0] + " > " + mParam.getName().split("/")[1]: mParam.getName().split("/")[0], mParam.getView());
 			}
-			else if(s.split("\n")[1].equals("string")){
+			else if(s.split("|")[1].equals("string")){
 				ParameterString mParam = new ParameterString(_listView.getContext(), _gmsh, mCallback, "");
 				if(mParam.fromString(s) != -1){
 					params.add(mParam);
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/Parameter.java b/contrib/mobile/Android/src/org/geuz/onelab/Parameter.java
index 328eb662b9572dacce097285a43feba4d0c028f9..75a4db6fd83a7a475bf60946f53de804d6f272a6 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/Parameter.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/Parameter.java
@@ -54,7 +54,7 @@ public class Parameter {
 	public boolean isReadOnly() {return _readOnly;}
 	public String getLabel() {return _label;}
 	public int fromString(String s){
-		String[] infos = s.split("\n");
+		String[] infos = s.split(Character.toString((char)0x03));
 		int pos=0;
 		pos++;// version
 		pos++;// type
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/ParameterNumber.java b/contrib/mobile/Android/src/org/geuz/onelab/ParameterNumber.java
index 49e47f7e29c022e02da7708cb0e917fabdb13fff..d21964b92603c5e8b1cc801a118419d9b1a2c292 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/ParameterNumber.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/ParameterNumber.java
@@ -129,7 +129,7 @@ public class ParameterNumber extends Parameter{
 	public int fromString(String s){
 		int pos = super.fromString(s);
 		if(pos <= 0) return -1; // error
-		String[] infos = s.split("\n");
+		String[] infos = s.split(Character.toString((char)0x03));
 		String tmpVal = infos[pos++];
 		if(tmpVal.equals("Inf")) // TODO set value to max ???
 			_value = 1;
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java b/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java
index 81be749cb58ea6b6c34ecd5970c8eeecf5618c32..ae6c5f8c3805615889ae119346f3d0638fa69107 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java
@@ -75,7 +75,7 @@ public class ParameterString extends Parameter{
 	public int fromString(String s){
 		int pos = super.fromString(s);
 		if(pos <= 0) return -1; // error
-		String[] infos = s.split("\n");
+		String[] infos = s.split(Character.toString((char)0x03));
 		String value = infos[pos++];
 		setKind(infos[pos++]); // generic file 
 		if(_kind.equals("file"))
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/SplashScreen.java b/contrib/mobile/Android/src/org/geuz/onelab/SplashScreen.java
index 56653765f13986820805fa4574c87a1af5b7185f..3320d54aef7c20f1d0944a341c0a937d9870c17d 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/SplashScreen.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/SplashScreen.java
@@ -1,6 +1,7 @@
 package org.geuz.onelab;
 
 import java.io.BufferedInputStream;
+import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.zip.ZipEntry;
@@ -64,7 +65,21 @@ public class SplashScreen extends Activity{
     		ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(getResources().openRawResource(R.raw.models)));
 			ZipEntry entry;
 		     while ((entry = zipStream.getNextEntry()) != null) {
-				FileOutputStream outputStream = openFileOutput(entry.getName(), Context.MODE_PRIVATE);
+		    	 String name = entry.getName();
+		    	 FileOutputStream outputStream;
+		    	 if(name.charAt(name.length()-1) == '/') {
+		    		 continue;
+		    	 }
+		    	 else if(name.lastIndexOf("/") > 0) {
+		    		 File document = this.getFilesDir();
+		    		 File currentDirectory = new File(document,name.substring(0, name.lastIndexOf("/")));
+		    		 currentDirectory.mkdir();
+		    		 File currentFile = new File(currentDirectory, name.substring(name.lastIndexOf("/")+1));
+		    		 outputStream = new FileOutputStream(currentFile);
+		    	 }
+		    	 else {
+		    		outputStream = openFileOutput(name, Context.MODE_PRIVATE);
+		    	 }
 				byte[] buffer = new byte[2048];
 				for (int i = zipStream.read(buffer, 0, buffer.length); i > 0;i = zipStream.read(buffer, 0, buffer.length)) 
 					outputStream.write(buffer,0,i);
diff --git a/contrib/mobile/androidGModel.cpp b/contrib/mobile/androidGModel.cpp
index 8575ab12ef5e34fbf0555446501166b85549fb25..459f20644c583006a38c26ebdc68da7cc843fe5e 100644
--- a/contrib/mobile/androidGModel.cpp
+++ b/contrib/mobile/androidGModel.cpp
@@ -236,7 +236,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_geuz_onelab_Gmsh_getParams
 	std::vector<std::string> tmp =  onelab::server::instance()->toChar();
 	for(unsigned int i=0;i<tmp.size();i++)
 		for(unsigned int j=0; j<tmp[i].size();j++)
-			if(tmp[i][j] == '\0') tmp[i][j] = '\n';
+			if(tmp[i][j] == '\0') tmp[i][j] = 0x03;
 	jobjectArray params = env->NewObjectArray(tmp.size(), stringClass, 0);
 	for(int i=0; i<tmp.size();i++){
 		jstring s = env->NewStringUTF(tmp[i].c_str());