diff --git a/model/src/main/java/lcsb/mapviewer/model/user/User.java b/model/src/main/java/lcsb/mapviewer/model/user/User.java
index 216c7837dbf52005d912857520f45af158284698..6c7b603a06c1e26f9f12ca6dd274502ce426f002 100644
--- a/model/src/main/java/lcsb/mapviewer/model/user/User.java
+++ b/model/src/main/java/lcsb/mapviewer/model/user/User.java
@@ -96,7 +96,7 @@ public class User implements Serializable {
 	 * Set of user privileges.
 	 */
 	@OneToMany(fetch = FetchType.EAGER, mappedBy = "user", orphanRemoval = true, cascade = CascadeType.ALL)
-	private Set<BasicPrivilege>	 privileges				= new HashSet<BasicPrivilege>();
+	private Set<BasicPrivilege>	 privileges				= new HashSet<>();
 
 	/**
 	 * Default annotations schema used by this user.
diff --git a/model/src/main/java/lcsb/mapviewer/model/user/UserAnnotationSchema.java b/model/src/main/java/lcsb/mapviewer/model/user/UserAnnotationSchema.java
index 820f94fceec024971f038725a6166d6f05678096..2e919ca9930498c3eae0de35228e854c58ec84cf 100644
--- a/model/src/main/java/lcsb/mapviewer/model/user/UserAnnotationSchema.java
+++ b/model/src/main/java/lcsb/mapviewer/model/user/UserAnnotationSchema.java
@@ -38,13 +38,13 @@ public class UserAnnotationSchema implements Serializable {
 	/**
 	 * 
 	 */
-	private static final long									serialVersionUID				= 1L;
+	private static final long									 serialVersionUID				 = 1L;
 
 	/**
 	 * Default class logger.
 	 */
 	@Transient
-	private final transient Logger						 logger									= Logger.getLogger(UserAnnotationSchema.class);
+	private final transient Logger						 logger									 = Logger.getLogger(UserAnnotationSchema.class);
 
 	/**
 	 * Unique identifier in the database.
@@ -52,7 +52,7 @@ public class UserAnnotationSchema implements Serializable {
 	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	@Column(name = "idDb", unique = true, nullable = false)
-	private Integer														id;
+	private Integer														 id;
 
 	/**
 	 * {@link User} for which annotation schema is defined.
@@ -63,18 +63,26 @@ public class UserAnnotationSchema implements Serializable {
 	/**
 	 * Should the miriam types be validated?
 	 */
-	private Boolean														validateMiriamTypes		 = false;
+	private Boolean														 validateMiriamTypes		 = false;
+
+	private Boolean														 annotateModel					 = false;
+
+	private Boolean														 cacheData							 = false;
+
+	private Boolean														 autoResizeMap					 = true;
+
+	private Boolean														 semanticZooming				 = false;
 
 	/**
 	 * Should map be visualized as sbgn?
 	 */
-	private Boolean														sbgnFormat							= false;
+	private Boolean														 sbgnFormat							 = false;
 
 	/**
 	 * Should the default view be network (if not then it will be pathways and
 	 * compartments)?
 	 */
-	private Boolean														networkLayoutAsDefault	= false;
+	private Boolean														 networkLayoutAsDefault	 = false;
 
 	/**
 	 * List of class annotators for specific object types.
@@ -82,7 +90,7 @@ public class UserAnnotationSchema implements Serializable {
 	@Cascade({ CascadeType.ALL })
 	@OneToMany(mappedBy = "annotationSchema")
 	@OrderBy("id")
-	private List<UserClassAnnotators>					classAnnotators				 = new ArrayList<UserClassAnnotators>();
+	private List<UserClassAnnotators>					 classAnnotators				 = new ArrayList<>();
 
 	/**
 	 * List of valid annotations for given object type.
@@ -90,7 +98,7 @@ public class UserAnnotationSchema implements Serializable {
 	@Cascade({ CascadeType.ALL })
 	@OneToMany(mappedBy = "annotationSchema")
 	@OrderBy("id")
-	private List<UserClassValidAnnotations>		classValidAnnotators		= new ArrayList<UserClassValidAnnotations>();
+	private List<UserClassValidAnnotations>		 classValidAnnotators		 = new ArrayList<>();
 
 	/**
 	 * List of required annotations for given object type.
@@ -98,7 +106,7 @@ public class UserAnnotationSchema implements Serializable {
 	@Cascade({ CascadeType.ALL })
 	@OneToMany(mappedBy = "annotationSchema")
 	@OrderBy("id")
-	private List<UserClassRequiredAnnotations> classRequiredAnnotators = new ArrayList<UserClassRequiredAnnotations>();
+	private List<UserClassRequiredAnnotations> classRequiredAnnotators = new ArrayList<>();
 
 	/**
 	 * @return the user
@@ -321,7 +329,8 @@ public class UserAnnotationSchema implements Serializable {
 	}
 
 	/**
-	 * @param sbgnFormat the sbgnFormat to set
+	 * @param sbgnFormat
+	 *          the sbgnFormat to set
 	 * @see #sbgnFormat
 	 */
 	public void setSbgnFormat(Boolean sbgnFormat) {
@@ -337,10 +346,79 @@ public class UserAnnotationSchema implements Serializable {
 	}
 
 	/**
-	 * @param networkLayoutAsDefault the networkLayoutAsDefault to set
+	 * @param networkLayoutAsDefault
+	 *          the networkLayoutAsDefault to set
 	 * @see #networkLayoutAsDefault
 	 */
 	public void setNetworkLayoutAsDefault(Boolean networkLayoutAsDefault) {
 		this.networkLayoutAsDefault = networkLayoutAsDefault;
 	}
+
+	/**
+	 * @return the annotateModel
+	 * @see #annotateModel
+	 */
+	public Boolean getAnnotateModel() {
+		return annotateModel;
+	}
+
+	/**
+	 * @param annotateModel
+	 *          the annotateModel to set
+	 * @see #annotateModel
+	 */
+	public void setAnnotateModel(Boolean annotateModel) {
+		this.annotateModel = annotateModel;
+	}
+
+	/**
+	 * @return the cacheData
+	 * @see #cacheData
+	 */
+	public Boolean getCacheData() {
+		return cacheData;
+	}
+
+	/**
+	 * @param cacheData
+	 *          the cacheData to set
+	 * @see #cacheData
+	 */
+	public void setCacheData(Boolean cacheData) {
+		this.cacheData = cacheData;
+	}
+
+	/**
+	 * @return the autoResizeMap
+	 * @see #autoResizeMap
+	 */
+	public Boolean getAutoResizeMap() {
+		return autoResizeMap;
+	}
+
+	/**
+	 * @param autoResizeMap
+	 *          the autoResizeMap to set
+	 * @see #autoResizeMap
+	 */
+	public void setAutoResizeMap(Boolean autoResizeMap) {
+		this.autoResizeMap = autoResizeMap;
+	}
+
+	/**
+	 * @return the semanticZooming
+	 * @see #semanticZooming
+	 */
+	public Boolean getSemanticZooming() {
+		return semanticZooming;
+	}
+
+	/**
+	 * @param semanticZooming
+	 *          the semanticZooming to set
+	 * @see #semanticZooming
+	 */
+	public void setSemanticZooming(Boolean semanticZooming) {
+		this.semanticZooming = semanticZooming;
+	}
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/user/UserClassAnnotators.java b/model/src/main/java/lcsb/mapviewer/model/user/UserClassAnnotators.java
index 9e1c1d6657920a585980f47fc4632c8ccb5e928d..d0d7f2753a75593dc21460a6c65d13b43485e1b6 100644
--- a/model/src/main/java/lcsb/mapviewer/model/user/UserClassAnnotators.java
+++ b/model/src/main/java/lcsb/mapviewer/model/user/UserClassAnnotators.java
@@ -32,7 +32,7 @@ public class UserClassAnnotators implements Serializable {
 	/**
 	 * 
 	 */
-	private static final long	serialVersionUID	= 1L;
+	private static final long		 serialVersionUID	= 1L;
 
 	/**
 	 * Unique identifier in the database.
@@ -40,19 +40,19 @@ public class UserClassAnnotators implements Serializable {
 	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	@Column(name = "idDb", unique = true, nullable = false)
-	private Integer								id;
+	private Integer							 id;
 
 	/**
 	 * {@link UserAnnotationSchema} that defines which user is using this set of
 	 * annotators.
 	 */
 	@ManyToOne
-	private UserAnnotationSchema	annotationSchema;
+	private UserAnnotationSchema annotationSchema;
 
 	/**
 	 * Class for which this set of annotators is defined.
 	 */
-	private String								className;
+	private String							 className;
 
 	/**
 	 * List of strings defining set of annotators (canonical class names).
@@ -61,7 +61,7 @@ public class UserClassAnnotators implements Serializable {
 	@CollectionTable(name = "class_annotator_annotators_table", joinColumns = @JoinColumn(name = "class_annotator_iddb"))
 	@IndexColumn(name = "idx")
 	@Column(name = "annotator_name")
-	private List<String>					annotators	= new ArrayList<String>();
+	private List<String>				 annotators				= new ArrayList<>();
 
 	/**
 	 * Default constructor.
diff --git a/model/src/main/java/lcsb/mapviewer/model/user/UserClassRequiredAnnotations.java b/model/src/main/java/lcsb/mapviewer/model/user/UserClassRequiredAnnotations.java
index 526e03041ca21099a2c2afedc0be14280444dd92..31665d2109fb9c64241dd9837280a6d74e475b54 100644
--- a/model/src/main/java/lcsb/mapviewer/model/user/UserClassRequiredAnnotations.java
+++ b/model/src/main/java/lcsb/mapviewer/model/user/UserClassRequiredAnnotations.java
@@ -69,18 +69,18 @@ public class UserClassRequiredAnnotations implements Serializable {
 	/**
 	 * Are the annotations required?
 	 */
-	private Boolean								 requireAtLestOneAnnotation;
+	private Boolean								 requireAtLeastOneAnnotation;
 
 	/**
 	 * One of this annotations will be required if
-	 * {@link #requireAtLestOneAnnotation} is set.
+	 * {@link #requireAtLeastOneAnnotation} is set.
 	 */
 	@ElementCollection
 	@JoinTable(name = "class_required_annotation_miriam_type_table", joinColumns = @JoinColumn(name = "class_required_annotation_iddb"))
 	@Column(name = "miriam_type_name", nullable = false)
 	@IndexColumn(name = "idx")
 	@Enumerated(EnumType.STRING)
-	private List<MiriamType>			 requiredMiriamTypes = new ArrayList<MiriamType>();
+	private List<MiriamType>			 requiredMiriamTypes = new ArrayList<>();
 
 	/**
 	 * Default constructor.
@@ -100,10 +100,10 @@ public class UserClassRequiredAnnotations implements Serializable {
 	public UserClassRequiredAnnotations(Class<?> clazz, Collection<MiriamType> miriamTypes) {
 		setClassName(clazz);
 		if (miriamTypes != null) {
-			setRequireAtLestOneAnnotation(true);
+			setRequireAtLeastOneAnnotation(true);
 			this.requiredMiriamTypes.addAll(miriamTypes);
 		} else {
-			setRequireAtLestOneAnnotation(false);
+			setRequireAtLeastOneAnnotation(false);
 		}
 	}
 
@@ -120,7 +120,7 @@ public class UserClassRequiredAnnotations implements Serializable {
 		for (MiriamType miriamType : miriamTypes) {
 			this.requiredMiriamTypes.add(miriamType);
 		}
-		setRequireAtLestOneAnnotation(miriamTypes.length > 0);
+		setRequireAtLeastOneAnnotation(miriamTypes.length > 0);
 	}
 
 	/**
@@ -213,18 +213,18 @@ public class UserClassRequiredAnnotations implements Serializable {
 
 	/**
 	 * @return the requireAtLestOneAnnotation
-	 * @see #requireAtLestOneAnnotation
+	 * @see #requireAtLeastOneAnnotation
 	 */
-	public Boolean getRequireAtLestOneAnnotation() {
-		return requireAtLestOneAnnotation;
+	public Boolean getRequireAtLeastOneAnnotation() {
+		return requireAtLeastOneAnnotation;
 	}
 
 	/**
-	 * @param requireAtLestOneAnnotation
+	 * @param requireAtLeastOneAnnotation
 	 *          the requireAtLestOneAnnotation to set
-	 * @see #requireAtLestOneAnnotation
+	 * @see #requireAtLeastOneAnnotation
 	 */
-	public void setRequireAtLestOneAnnotation(Boolean requireAtLestOneAnnotation) {
-		this.requireAtLestOneAnnotation = requireAtLestOneAnnotation;
+	public void setRequireAtLeastOneAnnotation(Boolean requireAtLeastOneAnnotation) {
+		this.requireAtLeastOneAnnotation = requireAtLeastOneAnnotation;
 	}
 }
diff --git a/model/src/main/java/lcsb/mapviewer/model/user/UserClassValidAnnotations.java b/model/src/main/java/lcsb/mapviewer/model/user/UserClassValidAnnotations.java
index 60549ebb454c78f6764150a783789a23a893baf6..636492bf379f4ce829c876500f7c2931a7ca3e7e 100644
--- a/model/src/main/java/lcsb/mapviewer/model/user/UserClassValidAnnotations.java
+++ b/model/src/main/java/lcsb/mapviewer/model/user/UserClassValidAnnotations.java
@@ -65,7 +65,7 @@ public class UserClassValidAnnotations implements Serializable {
 	@Column(name = "miriam_type_name", nullable = false)
 	@IndexColumn(name = "idx")
 	@Enumerated(EnumType.STRING)
-	private List<MiriamType>			validMiriamTypes	= new ArrayList<MiriamType>();
+	private List<MiriamType>			validMiriamTypes	= new ArrayList<>();
 
 	/**
 	 * Default constructor.
diff --git a/model/src/test/java/lcsb/mapviewer/model/user/UserClassRequiredAnnotationsTest.java b/model/src/test/java/lcsb/mapviewer/model/user/UserClassRequiredAnnotationsTest.java
index 7b3b8c5ca346e15fb9eef26adf38011bb1c960a9..0c35b87210e2a449dd6d6f3a0a9fdc8f511141f2 100644
--- a/model/src/test/java/lcsb/mapviewer/model/user/UserClassRequiredAnnotationsTest.java
+++ b/model/src/test/java/lcsb/mapviewer/model/user/UserClassRequiredAnnotationsTest.java
@@ -46,12 +46,12 @@ public class UserClassRequiredAnnotationsTest {
 			
 			obj.setId(id);
 			obj.setRequiredMiriamTypes(requiredMiriamTypes);
-			obj.setRequireAtLestOneAnnotation(requireAtLestOneAnnotation);
+			obj.setRequireAtLeastOneAnnotation(requireAtLestOneAnnotation);
 			obj.setAnnotationSchema(annotationSchema);
 			
 			assertEquals(id, obj.getId());
 			assertEquals(requiredMiriamTypes, obj.getRequiredMiriamTypes());
-			assertEquals(requireAtLestOneAnnotation, obj.getRequireAtLestOneAnnotation());
+			assertEquals(requireAtLestOneAnnotation, obj.getRequireAtLeastOneAnnotation());
 			
 			assertEquals(annotationSchema, obj.getAnnotationSchema());
 			
@@ -67,7 +67,7 @@ public class UserClassRequiredAnnotationsTest {
 	public void testConstructor() {
 		try {
 			UserClassRequiredAnnotations obj = new UserClassRequiredAnnotations(String.class,(Collection<MiriamType>)null);
-			assertFalse(obj.getRequireAtLestOneAnnotation());
+			assertFalse(obj.getRequireAtLeastOneAnnotation());
 		} catch (Exception e) {
 			e.printStackTrace();
 			throw e;
@@ -78,7 +78,7 @@ public class UserClassRequiredAnnotationsTest {
 	public void testConstructor2() {
 		try {
 			UserClassRequiredAnnotations obj = new UserClassRequiredAnnotations(String.class,new MiriamType[]{MiriamType.CAS});
-			assertTrue(obj.getRequireAtLestOneAnnotation());
+			assertTrue(obj.getRequireAtLeastOneAnnotation());
 		} catch (Exception e) {
 			e.printStackTrace();
 			throw e;
@@ -88,7 +88,7 @@ public class UserClassRequiredAnnotationsTest {
 	public void testConstructor3() {
 		try {
 			UserClassRequiredAnnotations obj = new UserClassRequiredAnnotations(String.class,new MiriamType[]{});
-			assertFalse(obj.getRequireAtLestOneAnnotation());
+			assertFalse(obj.getRequireAtLeastOneAnnotation());
 		} catch (Exception e) {
 			e.printStackTrace();
 			throw e;
diff --git a/persist/src/db/11.1.0/fix_db_20170829.sql b/persist/src/db/11.1.0/fix_db_20170829.sql
new file mode 100644
index 0000000000000000000000000000000000000000..c5d18a2ac2cca017e749cd449d76970d507c4047
--- /dev/null
+++ b/persist/src/db/11.1.0/fix_db_20170829.sql
@@ -0,0 +1,6 @@
+--user prferences for uploading map
+alter table user_annotation_schema_table add column annotatemodel boolean default false;
+alter table user_annotation_schema_table add column autoresizemap boolean default true;
+alter table user_annotation_schema_table add column cachedata boolean default true;
+alter table user_annotation_schema_table add column semanticzooming boolean default false;
+alter table class_required_annotation_table RENAME column requireatlestoneannotation to requireatleastoneannotation;
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
index 2a845a6ed6ac844fa77ca077e6126be329b441e1..e210ca049b46b67c266fa57be45dfacf142aa0c4 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
@@ -49,8 +49,7 @@ public abstract class BaseController {
 		}
 	}
 
-	protected Map<String, Object> parseBody(String body) throws IOException, JsonParseException, JsonMappingException {
-		logger.debug("Parse body: " + body);
+	public Map<String, Object> parseBody(String body) throws IOException, JsonParseException, JsonMappingException {
 		ObjectNode result = mapper.readValue(body, ObjectNode.class);
 		return mapper.convertValue(result, Map.class);
 	}
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java
index 41b26a7ef9715f951922ae7dbfb9010a54819ea3..0ed3cd9889fe6e0510dbe6773e1e5e8146a50b03 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java
@@ -15,18 +15,27 @@ import lcsb.mapviewer.api.BaseRestImpl;
 import lcsb.mapviewer.api.ObjectNotFoundException;
 import lcsb.mapviewer.api.QueryException;
 import lcsb.mapviewer.common.exception.InvalidArgumentException;
+import lcsb.mapviewer.model.map.MiriamType;
 import lcsb.mapviewer.model.user.BasicPrivilege;
 import lcsb.mapviewer.model.user.ObjectPrivilege;
 import lcsb.mapviewer.model.user.PrivilegeType;
 import lcsb.mapviewer.model.user.User;
+import lcsb.mapviewer.model.user.UserAnnotationSchema;
+import lcsb.mapviewer.model.user.UserClassAnnotators;
+import lcsb.mapviewer.model.user.UserClassRequiredAnnotations;
+import lcsb.mapviewer.model.user.UserClassValidAnnotations;
 import lcsb.mapviewer.services.SecurityException;
 import lcsb.mapviewer.services.interfaces.ILayoutService;
-import lcsb.mapviewer.services.interfaces.IUserService;
 import lcsb.mapviewer.services.view.AuthenticationToken;
 
 @Transactional(value = "txManager")
 public class UserRestImpl extends BaseRestImpl {
-	Logger								 logger	= Logger.getLogger(UserRestImpl.class);
+
+	/**
+	 * Default class logger.
+	 */
+	@SuppressWarnings("unused")
+	private Logger				 logger	= Logger.getLogger(UserRestImpl.class);
 
 	@Autowired
 	private ILayoutService layoutService;
@@ -43,7 +52,6 @@ public class UserRestImpl extends BaseRestImpl {
 			if (user == null) {
 				throw new ObjectNotFoundException("User doesn't exist");
 			}
-			logger.debug(user.hashCode());
 			return prepareUse(user, columnSet, isAdmin);
 		} else {
 			throw new SecurityException("You cannot access data of the user with given id");
@@ -63,6 +71,7 @@ public class UserRestImpl extends BaseRestImpl {
 			columnsSet.add("simpleColor");
 			columnsSet.add("removed");
 			columnsSet.add("privileges");
+			columnsSet.add("preferences");
 		} else {
 			for (String str : columns.split(",")) {
 				columnsSet.add(str);
@@ -96,6 +105,8 @@ public class UserRestImpl extends BaseRestImpl {
 				value = user.isRemoved();
 			} else if (column.equals("privileges") && admin) {
 				value = preparePrivileges(user);
+			} else if (column.equals("preferences")) {
+				value = preparePreferences(user);
 			} else {
 				value = "Unknown column";
 			}
@@ -104,6 +115,125 @@ public class UserRestImpl extends BaseRestImpl {
 		return result;
 	}
 
+	private Map<String, Object> preparePreferences(User user) {
+		Map<String, Object> result = new HashMap<>();
+		UserAnnotationSchema schema = getProjectService().prepareUserAnnotationSchema(user);
+		result.put("project-upload", prepareProjectUploadPreferences(schema));
+		result.put("element-annotators", prepareElementAnnotators(schema.getClassAnnotators()));
+		result.put("element-required-annotations", prepareRequiredAnnotations(schema.getClassRequiredAnnotators()));
+		result.put("element-valid-annotations", prepareValidAnnotations(schema.getClassValidAnnotators()));
+		return result;
+	}
+
+	private Map<String, Object> prepareValidAnnotations(List<UserClassValidAnnotations> classValidAnnotators) {
+		Map<String, Object> result = new HashMap<>();
+		for (UserClassValidAnnotations userClassAnnotators : classValidAnnotators) {
+			result.put(userClassAnnotators.getClassName(), userClassAnnotators.getValidMiriamTypes());
+		}
+		return result;
+	}
+
+	private void updateValidAnnotations(UserAnnotationSchema schema, Map<String, Object> data) {
+		for (String key : data.keySet()) {
+			UserClassValidAnnotations annotator = null;
+			for (UserClassValidAnnotations userClassAnnotators : schema.getClassValidAnnotators()) {
+				if (userClassAnnotators.getClassName().equals(key)) {
+					annotator = userClassAnnotators;
+				}
+			}
+			if (annotator == null) {
+				annotator = new UserClassValidAnnotations();
+				annotator.setClassName(key);
+				schema.addClassValidAnnotations(annotator);
+			}
+			annotator.getValidMiriamTypes().clear();
+			for (Object row : (List<?>) data.get(key)) {
+				annotator.getValidMiriamTypes().add(MiriamType.valueOf((String) row));
+			}
+		}
+	}
+
+	private Map<String, Object> prepareRequiredAnnotations(List<UserClassRequiredAnnotations> classRequiredAnnotators) {
+		Map<String, Object> result = new HashMap<>();
+		for (UserClassRequiredAnnotations requiredAnnotations : classRequiredAnnotators) {
+			Map<String, Object> row = new HashMap<>();
+			row.put("require-at-least-one", requiredAnnotations.getRequireAtLeastOneAnnotation());
+			row.put("annotation-list", requiredAnnotations.getRequiredMiriamTypes());
+			result.put(requiredAnnotations.getClassName(), row);
+		}
+		return result;
+	}
+
+	private void updateRequiredAnnotations(UserAnnotationSchema schema, Map<String, Object> data) throws QueryException {
+		for (String key : data.keySet()) {
+			UserClassRequiredAnnotations annotator = null;
+			for (UserClassRequiredAnnotations userClassAnnotators : schema.getClassRequiredAnnotators()) {
+				if (userClassAnnotators.getClassName().equals(key)) {
+					annotator = userClassAnnotators;
+				}
+			}
+			if (annotator == null) {
+				annotator = new UserClassRequiredAnnotations();
+				annotator.setClassName(key);
+				schema.addClassRequiredAnnotations(annotator);
+			}
+			updateAnnotator(annotator, (Map<String, Object>) data.get(key));
+		}
+	}
+
+	private void updateAnnotator(UserClassRequiredAnnotations annotator, Map<String, Object> data) throws QueryException {
+		for (String key : data.keySet()) {
+			if (key.equals("require-at-least-one")) {
+				annotator.setRequireAtLeastOneAnnotation((Boolean) data.get("require-at-least-one"));
+			} else if (key.equals("annotation-list")) {
+				annotator.getRequiredMiriamTypes().clear();
+				for (Object row : (List<?>) data.get(key)) {
+					annotator.getRequiredMiriamTypes().add(MiriamType.valueOf((String) row));
+				}
+			} else {
+				throw new QueryException("Unknown field: " + key);
+			}
+		}
+
+	}
+
+	private Map<String, Object> prepareElementAnnotators(List<UserClassAnnotators> classAnnotators) {
+		Map<String, Object> result = new HashMap<>();
+		for (UserClassAnnotators userClassAnnotators : classAnnotators) {
+			result.put(userClassAnnotators.getClassName(), userClassAnnotators.getAnnotators());
+		}
+		return result;
+	}
+
+	private void updateElementAnnotators(UserAnnotationSchema schema, Map<String, Object> data) {
+		for (String key : data.keySet()) {
+			UserClassAnnotators annotator = null;
+			for (UserClassAnnotators userClassAnnotators : schema.getClassAnnotators()) {
+				if (userClassAnnotators.getClassName().equals(key)) {
+					annotator = userClassAnnotators;
+				}
+			}
+			if (annotator == null) {
+				annotator = new UserClassAnnotators();
+				annotator.setClassName(key);
+				schema.addClassAnnotator(annotator);
+			}
+			annotator.getAnnotators().clear();
+			annotator.getAnnotators().addAll((List<String>) data.get(key));
+		}
+	}
+
+	private Map<String, Object> prepareProjectUploadPreferences(UserAnnotationSchema schema) {
+		Map<String, Object> result = new HashMap<>();
+		result.put("validate-miriam", schema.getValidateMiriamTypes());
+		result.put("annotate-model", schema.getAnnotateModel());
+		result.put("cache-data", schema.getCacheData());
+		result.put("auto-resize", schema.getAutoResizeMap());
+		result.put("semantic-zooming", schema.getSemanticZooming());
+		result.put("sbgn", schema.getSbgnFormat());
+		return result;
+	}
+
 	private List<Map<String, Object>> preparePrivileges(User user) {
 		List<Map<String, Object>> result = new ArrayList<>();
 		for (BasicPrivilege privilege : user.getPrivileges()) {
@@ -174,11 +304,9 @@ public class UserRestImpl extends BaseRestImpl {
 		if (privilegesData == null) {
 			throw new QueryException("Privileges not defined");
 		}
-		logger.debug(privilegesData);
 		try {
 			AuthenticationToken authenticationToken = getUserService().getToken(token);
 			User modifiedUser = getUserService().getUserByLogin(login);
-			logger.debug(modifiedUser.hashCode());
 
 			for (String key : privilegesData.keySet()) {
 				Object value = privilegesData.get(key);
@@ -207,4 +335,64 @@ public class UserRestImpl extends BaseRestImpl {
 		}
 	}
 
+	public Map<String, Object> updatePreferences(String token, String login, Map<String, Object> preferencesData) throws SecurityException, QueryException {
+		if (preferencesData == null) {
+			throw new QueryException("Preferences not defined");
+		}
+		try {
+			AuthenticationToken authenticationToken = getUserService().getToken(token);
+			User modifiedUser = getUserService().getUserByLogin(login);
+			if (modifiedUser == null) {
+				throw new ObjectNotFoundException("User doesn't exist");
+			}
+
+			UserAnnotationSchema schema = getProjectService().prepareUserAnnotationSchema(modifiedUser);
+
+			for (String key : preferencesData.keySet()) {
+				Map<String, Object> value = (Map<String, Object>) preferencesData.get(key);
+
+				if (key.equals("project-upload")) {
+					updateUploadPreferences(schema, value);
+				} else if (key.equals("element-annotators")) {
+					updateElementAnnotators(schema, value);
+				} else if (key.equals("element-required-annotations")) {
+					updateRequiredAnnotations(schema, value);
+				} else if (key.equals("element-valid-annotations")) {
+					updateValidAnnotations(schema, value);
+				} else {
+					throw new QueryException("Unknown preferences field: " + key);
+				}
+			}
+			modifiedUser.setAnnotationSchema(schema);
+			getUserService().updateUser(modifiedUser, authenticationToken);
+			return getUser(token, login, "");
+		} catch (IllegalArgumentException e) {
+			throw new QueryException("Invalid input", e);
+		}
+	}
+
+	private void updateUploadPreferences(UserAnnotationSchema schema, Map<String, Object> data) throws QueryException {
+		for (String key : data.keySet()) {
+			Boolean value = (Boolean) data.get(key);
+			if (value != null) {
+				if (key.equals("validate-miriam")) {
+					schema.setValidateMiriamTypes(value);
+				} else if (key.equals("annotate-model")) {
+					schema.setAnnotateModel(value);
+				} else if (key.equals("cache-data")) {
+					schema.setCacheData(value);
+				} else if (key.equals("auto-resize")) {
+					schema.setAutoResizeMap(value);
+				} else if (key.equals("semantic-zooming")) {
+					schema.setSemanticZooming(value);
+				} else if (key.equals("sbgn")) {
+					schema.setSbgnFormat(value);
+				} else {
+					throw new QueryException("Unknown upload preference field: " + key);
+				}
+			}
+		}
+
+	}
+
 }
diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/users/UserRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/users/UserRestImplTest.java
index 84d244b2db876707218d8b662641fbbab66c6a98..e5f026e7832ead26f5036e1f931b182c681b017f 100644
--- a/rest-api/src/test/java/lcsb/mapviewer/api/users/UserRestImplTest.java
+++ b/rest-api/src/test/java/lcsb/mapviewer/api/users/UserRestImplTest.java
@@ -3,7 +3,9 @@ package lcsb.mapviewer.api.users;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -12,8 +14,16 @@ import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.gson.Gson;
+
+import lcsb.mapviewer.api.BaseController;
 import lcsb.mapviewer.api.RestTestFunctions;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.model.user.PrivilegeType;
@@ -54,17 +64,36 @@ public class UserRestImplTest extends RestTestFunctions {
 			data.put(PrivilegeType.ADD_MAP.name(), 1);
 			userRestImpl.updatePrivileges(adminToken.getId(), Configuration.ANONYMOUS_LOGIN, data);
 			assertTrue(userService.userHasPrivilege(userService.getUserByLogin(Configuration.ANONYMOUS_LOGIN), PrivilegeType.ADD_MAP));
-			
+
 			data.put(PrivilegeType.ADD_MAP.name(), 0);
 			userRestImpl.updatePrivileges(adminToken.getId(), Configuration.ANONYMOUS_LOGIN, data);
 			assertFalse(userService.userHasPrivilege(userService.getUserByLogin(Configuration.ANONYMOUS_LOGIN), PrivilegeType.ADD_MAP));
-			
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw e;
+		}
+	}
+
+	@Test
+	public void testUpdatePreferences() throws Exception {
+		try {
+			Map<String, Object> data = deserialize(userRestImpl.getUser(adminToken.getId(), Configuration.ANONYMOUS_LOGIN, ""));
+			userRestImpl.updatePreferences(adminToken.getId(), Configuration.ANONYMOUS_LOGIN, (Map<String, Object>) data.get("preferences"));
+
 		} catch (Exception e) {
 			e.printStackTrace();
 			throw e;
 		}
 	}
 
+	private Map<String, Object> deserialize(Map<String, Object> data) throws JsonParseException, JsonMappingException, IOException {
+		String body = new Gson().toJson(data);
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode result = mapper.readValue(body, ObjectNode.class);
+		return mapper.convertValue(result, Map.class);
+	}
+
 	@Test
 	public void testGetUsers() throws Exception {
 		try {
diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java b/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java
index a15818fb09a7252ca59c83b1d2199ba296bf3d28..db91fe0556f28ab1fa735cf66073fbd4176f376d 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java
@@ -1364,7 +1364,7 @@ public class ProjectService implements IProjectService {
 	 *          for this users {@link UserAnnotationSchema} will be prepared
 	 * @return {@link UserAnnotationSchema} for {@link User}
 	 */
-	private UserAnnotationSchema prepareUserAnnotationSchema(User user) {
+	public UserAnnotationSchema prepareUserAnnotationSchema(User user) {
 		UserAnnotationSchema annotationSchema = null;
 		if (user != null) {
 			annotationSchema = userDao.getById(user.getId()).getAnnotationSchema();
@@ -1391,6 +1391,9 @@ public class ProjectService implements IProjectService {
 					nodes.add(node);
 				}
 			}
+			User dbUser = userDao.getById(user.getId());
+			dbUser.setAnnotationSchema(annotationSchema);
+			userDao.update(dbUser);
 		}
 		return annotationSchema;
 	}
diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java b/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java
index d6f80c3facdbb16bbeb576bc58533cbdc379de5c..cacf6683061cf1e86980e3b6cd4c6d7b13e72a55 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java
@@ -25,6 +25,7 @@ import lcsb.mapviewer.model.user.ConfigurationElementType;
 import lcsb.mapviewer.model.user.ObjectPrivilege;
 import lcsb.mapviewer.model.user.PrivilegeType;
 import lcsb.mapviewer.model.user.User;
+import lcsb.mapviewer.model.user.UserAnnotationSchema;
 import lcsb.mapviewer.persist.dao.ProjectDao;
 import lcsb.mapviewer.persist.dao.user.PrivilegeDao;
 import lcsb.mapviewer.persist.dao.user.UserDao;
@@ -639,4 +640,16 @@ public class UserService implements IUserService {
 		}
 
 	}
+
+	@Override
+	public void updateUser(User modifiedUser, AuthenticationToken token) throws SecurityException {
+		User user = getUserByToken(token);
+		if (user.getLogin().equals(modifiedUser.getLogin()) || userHasPrivilege(token, PrivilegeType.USER_MANAGEMENT)) {
+			updateUser(modifiedUser);
+		} else {
+			throw new SecurityException("You cannot modify user");
+		}
+
+	}
+
 }
diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/IProjectService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/IProjectService.java
index 509e0d421d9313bdfd161175e4a4d8beb17cd0d4..651d472fdcc757bed1fd81696880cb7fa5151003 100644
--- a/service/src/main/java/lcsb/mapviewer/services/interfaces/IProjectService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/IProjectService.java
@@ -6,6 +6,7 @@ import org.primefaces.model.TreeNode;
 
 import lcsb.mapviewer.model.Project;
 import lcsb.mapviewer.model.user.User;
+import lcsb.mapviewer.model.user.UserAnnotationSchema;
 import lcsb.mapviewer.services.SecurityException;
 import lcsb.mapviewer.services.UserAccessException;
 import lcsb.mapviewer.services.utils.CreateProjectParams;
@@ -187,4 +188,6 @@ public interface IProjectService {
 	 */
 	byte[] getInputDataForProject(ProjectView projectView);
 
+	UserAnnotationSchema prepareUserAnnotationSchema(User user);
+
 }
diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java
index b6895941e010e92fc76afab143ef9e63f2e60829..05f95e7fe02a3872a45b5420febdd3f12b0391a3 100644
--- a/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java
@@ -7,6 +7,7 @@ import lcsb.mapviewer.commands.ColorExtractor;
 import lcsb.mapviewer.model.user.BasicPrivilege;
 import lcsb.mapviewer.model.user.PrivilegeType;
 import lcsb.mapviewer.model.user.User;
+import lcsb.mapviewer.model.user.UserAnnotationSchema;
 import lcsb.mapviewer.services.SecurityException;
 import lcsb.mapviewer.services.view.AuthenticationToken;
 import lcsb.mapviewer.services.view.UserView;
@@ -262,4 +263,7 @@ public interface IUserService {
 	void setUserPrivilege(User modifiedUser, PrivilegeType type, Object privilegeToSet, AuthenticationToken authenticationToken) throws SecurityException;
 
 	void setUserPrivilege(User modifiedUser, PrivilegeType type, Object privilegeToSet, Integer objectId, AuthenticationToken authenticationToken) throws SecurityException;
+
+	void updateUser(User modifiedUser, AuthenticationToken authenticationToken) throws SecurityException;
+
 }