diff --git a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js
index 8e59ac4369ec24086aa74e17b39da22b2da10a13..8d4132f78dd93497fad8fb1f32bf7bea293a661c 100644
--- a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js
+++ b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js
@@ -27,6 +27,7 @@ define([ 'jquery', 'openbis', 'underscore', 'test/dtos' ], function($, defaultOp
 		this.SampleCreation = dtos.SampleCreation;
 		this.MaterialCreation = dtos.MaterialCreation;
 		this.AttachmentCreation = dtos.AttachmentCreation;
+		this.VocabularyCreation = dtos.VocabularyCreation;
 		this.VocabularyTermCreation = dtos.VocabularyTermCreation;
 		this.TagCreation = dtos.TagCreation;
 		this.AuthorizationGroupCreation = dtos.AuthorizationGroupCreation;
@@ -130,6 +131,7 @@ define([ 'jquery', 'openbis', 'underscore', 'test/dtos' ], function($, defaultOp
 		this.MaterialFetchOptions = dtos.MaterialFetchOptions;
 		this.MaterialTypeFetchOptions = dtos.MaterialTypeFetchOptions;
 		this.ExternalDmsFetchOptions = dtos.ExternalDmsFetchOptions;
+		this.VocabularyFetchOptions = dtos.VocabularyFetchOptions;
 		this.VocabularyTermFetchOptions = dtos.VocabularyTermFetchOptions;
 		this.TagFetchOptions = dtos.TagFetchOptions;
 		this.AuthorizationGroupFetchOptions = dtos.AuthorizationGroupFetchOptions;
@@ -169,6 +171,7 @@ define([ 'jquery', 'openbis', 'underscore', 'test/dtos' ], function($, defaultOp
 		this.GetSamplesOperation = dtos.GetSamplesOperation;
 		this.GetDataSetsOperation = dtos.GetDataSetsOperation;
 		this.GetMaterialsOperation = dtos.GetMaterialsOperation;
+		this.GetVocabulariesOperation = dtos.GetVocabulariesOperation;
 		this.GetVocabularyTermsOperation = dtos.GetVocabularyTermsOperation;
 		this.GetTagsOperation = dtos.GetTagsOperation;
 		this.GetAuthorizationGroupsOperation = dtos.GetAuthorizationGroupsOperation;
@@ -187,6 +190,7 @@ define([ 'jquery', 'openbis', 'underscore', 'test/dtos' ], function($, defaultOp
 		this.CreateDataSetTypesOperation = dtos.CreateDataSetTypesOperation;
 		this.CreateMaterialsOperation = dtos.CreateMaterialsOperation;
 		this.CreateMaterialTypesOperation = dtos.CreateMaterialTypesOperation;
+		this.CreateVocabulariesOperation = dtos.CreateVocabulariesOperation;
 		this.CreateVocabularyTermsOperation = dtos.CreateVocabularyTermsOperation;
 		this.CreateTagsOperation = dtos.CreateTagsOperation;
 		this.CreateAuthorizationGroupsOperation = dtos.CreateAuthorizationGroupsOperation;
@@ -404,6 +408,15 @@ define([ 'jquery', 'openbis', 'underscore', 'test/dtos' ], function($, defaultOp
 			});
 		}.bind(this);
 
+		this.createVocabulary = function(facade) {
+			var c = this;
+			var creation = new dtos.VocabularyCreation();
+			creation.setCode(c.generateId("VOCABULARY"));
+			return facade.createVocabularies([ creation ]).then(function(permIds) {
+				return permIds[0];
+			});
+		}.bind(this);
+		
 		this.createVocabularyTerm = function(facade) {
 			var c = this;
 			var creation = new dtos.VocabularyTermCreation();
@@ -594,6 +607,13 @@ define([ 'jquery', 'openbis', 'underscore', 'test/dtos' ], function($, defaultOp
 			});
 		}.bind(this);
 
+		this.findVocabulary = function(facade, id) {
+			var c = this;
+			return facade.getVocabularies([ id ], c.createVocabularyFetchOptions()).then(function(vocabularies) {
+				return vocabularies[id];
+			});
+		}.bind(this);
+		
 		this.findVocabularyTerm = function(facade, id) {
 			var c = this;
 			return facade.getVocabularyTerms([ id ], c.createVocabularyTermFetchOptions()).then(function(terms) {
diff --git a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js
index 2d78d38d312bdd82c61c75b720a090385da9e352..36e0a89a64a7d4c541e2e56a5a1b50f113ef4dcd 100644
--- a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js
+++ b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js
@@ -593,6 +593,9 @@ var sources = [
 	'as/dto/vocabulary/search/SearchVocabulariesOperationResult',
 	'as/dto/vocabulary/search/SearchVocabularyTermsOperation',
 	'as/dto/vocabulary/search/SearchVocabularyTermsOperationResult',
+	'as/dto/vocabulary/create/VocabularyCreation',
+	'as/dto/vocabulary/create/CreateVocabulariesOperation',
+	'as/dto/vocabulary/create/CreateVocabulariesOperationResult',
 	'as/dto/vocabulary/create/VocabularyTermCreation',
 	'as/dto/vocabulary/create/CreateVocabularyTermsOperation',
 	'as/dto/vocabulary/create/CreateVocabularyTermsOperationResult',
@@ -600,6 +603,8 @@ var sources = [
 	'as/dto/vocabulary/delete/VocabularyTermReplacement',
 	'as/dto/vocabulary/delete/DeleteVocabularyTermsOperation',
 	'as/dto/vocabulary/delete/DeleteVocabularyTermsOperationResult',
+	'as/dto/vocabulary/get/GetVocabulariesOperation',
+	'as/dto/vocabulary/get/GetVocabulariesOperationResult',
 	'as/dto/vocabulary/get/GetVocabularyTermsOperation',
 	'as/dto/vocabulary/get/GetVocabularyTermsOperationResult',
 	'as/dto/vocabulary/update/VocabularyTermUpdate',
diff --git a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js
index 623191c58308bc68b2c424e8e0950deeef0ab885..90838a6f42fcc7d275e58652da0877982b6c999d 100644
--- a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js
+++ b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js
@@ -133,6 +133,10 @@ define([ 'jquery', 'openbis', 'test/common' ], function($, openbis, common) {
 			return this._executeCreateOperation(new c.CreateVocabularyTermsOperation(creations));
 		}
 
+		this.createVocabularies = function(creations) {
+			return this._executeCreateOperation(new c.CreateVocabulariesOperation(creations));
+		}
+		
 		this.createTags = function(creations) {
 			return this._executeCreateOperation(new c.CreateTagsOperation(creations));
 		}
@@ -245,10 +249,14 @@ define([ 'jquery', 'openbis', 'test/common' ], function($, openbis, common) {
 			return this._executeGetOperation(new c.GetMaterialsOperation(ids, fetchOptions));
 		}
 
+		this.getVocabularies = function(ids, fetchOptions) {
+			return this._executeGetOperation(new c.GetVocabulariesOperation(ids, fetchOptions));
+		}
+
 		this.getVocabularyTerms = function(ids, fetchOptions) {
 			return this._executeGetOperation(new c.GetVocabularyTermsOperation(ids, fetchOptions));
 		}
-
+		
 		this.getTags = function(ids, fetchOptions) {
 			return this._executeGetOperation(new c.GetTagsOperation(ids, fetchOptions));
 		}
diff --git a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-create.js b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-create.js
index 8d8d7ef30737bcb775f70c607ca30089589be9ed..583e24915b426e6448c7cf6768c25416cef165d2 100644
--- a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-create.js
+++ b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-create.js
@@ -468,10 +468,40 @@ define([ 'jquery', 'underscore', 'openbis', 'test/openbis-execute-operations', '
 			testCreate(c, fCreate, c.findMaterialType, fCheck);
 		});
 
+		QUnit.test("createVocabularies()", function(assert) {
+			var c = new common(assert, openbis);
+			var code = c.generateId("VOCABULARY");
+
+			var fCreate = function(facade) {
+				var vocabularyCreation = new c.VocabularyCreation();
+				vocabularyCreation.setCode(code);
+				vocabularyCreation.setDescription("test description");
+				vocabularyCreation.setManagedInternally(true);
+				vocabularyCreation.setInternalNameSpace(true);
+				vocabularyCreation.setChosenFromList(true);
+				vocabularyCreation.setUrlTemplate("https://www.ethz.ch");
+				var termCreation = new c.VocabularyTermCreation();
+				termCreation.setCode("alpha");
+				vocabularyCreation.setTerms([termCreation]);
+				return facade.createVocabularies([ vocabularyCreation ]);
+			}
+
+			var fCheck = function(vocabulary) {
+				c.assertEqual(vocabulary.getCode(), "$" + code, "Code");
+				c.assertEqual(vocabulary.getDescription(), "test description", "Description");
+				c.assertEqual(vocabulary.isManagedInternally(), true, "Managed internally");
+				c.assertEqual(vocabulary.isInternalNameSpace(), true, "Internal name space");
+				c.assertEqual(vocabulary.isChosenFromList(), true, "Chosen from list");
+				c.assertEqual(vocabulary.getUrlTemplate(), "https://www.ethz.ch", "URL template");
+			}
+
+			testCreate(c, fCreate, c.findVocabulary, fCheck);
+		});
+
 		QUnit.test("createVocabularyTerms()", function(assert) {
 			var c = new common(assert, openbis);
 			var code = c.generateId("VOCABULARY_TERM");
-
+			
 			var fCreate = function(facade) {
 				var termCreation = new c.VocabularyTermCreation();
 				termCreation.setVocabularyId(new c.VocabularyPermId("TEST-VOCABULARY"));
@@ -482,7 +512,7 @@ define([ 'jquery', 'underscore', 'openbis', 'test/openbis-execute-operations', '
 				termCreation.setPreviousTermId(new c.VocabularyTermPermId("TEST-TERM-1", "TEST-VOCABULARY"))
 				return facade.createVocabularyTerms([ termCreation ]);
 			}
-
+			
 			var fCheck = function(term) {
 				c.assertEqual(term.getCode(), code, "Term code");
 				c.assertEqual(term.getVocabulary().getCode(), "TEST-VOCABULARY", "Term vocabulary code");
@@ -491,10 +521,10 @@ define([ 'jquery', 'underscore', 'openbis', 'test/openbis-execute-operations', '
 				c.assertEqual(term.isOfficial(), true, "Term official");
 				c.assertEqual(term.getOrdinal(), 2, "Term ordinal");
 			}
-
+			
 			testCreate(c, fCreate, c.findVocabularyTerm, fCheck);
 		});
-
+		
 		QUnit.test("createExternalDataManagementSystem()", function(assert) {
 			var c = new common(assert, openbis);
 			var code = c.generateId("EDMS");
diff --git a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-get.js b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-get.js
index 6f56a254c74c312aa3862fd1d2b30f9336414cf6..f295e9540249e302d20d781baf6b6562a34d8efa 100644
--- a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-get.js
+++ b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-get.js
@@ -273,30 +273,54 @@ define([ 'jquery', 'underscore', 'openbis', 'test/openbis-execute-operations', '
 			testGet(c, fCreate, fGet, fGetEmptyFetchOptions, fechOptionsTestConfig);
 		});
 
-		QUnit.test("getVocabularyTerms()", function(assert) {
+		QUnit.test("getVocabularies()", function(assert) {
 			var c = new common(assert, openbis);
-			var fo = new c.VocabularyTermFetchOptions();
+			var fo = new c.VocabularyFetchOptions();
 			var fechOptionsTestConfig = getConfigForFetchOptions(fo);
 			fechOptionsTestConfig.SortBy = null;
 
 			var fCreate = function(facade) {
-				return $.when(c.createVocabularyTerm(facade), c.createVocabularyTerm(facade)).then(function(permId1, permId2) {
+				return $.when(c.createVocabulary(facade), c.createVocabulary(facade)).then(function(permId1, permId2) {
 					return [ permId1, permId2 ];
 				});
 			}
 
 			var fGet = function(facade, permIds) {
 				testFetchOptionsAssignation(c, fo, fechOptionsTestConfig);
-				return facade.getVocabularyTerms(permIds, fo);
+				return facade.getVocabularies(permIds, fo);
 			}
 
 			var fGetEmptyFetchOptions = function(facade, permIds) {
-				return facade.getVocabularyTerms(permIds, new c.VocabularyTermFetchOptions());
+				return facade.getVocabularies(permIds, new c.VocabularyFetchOptions());
 			}
 
 			testGet(c, fCreate, fGet, fGetEmptyFetchOptions, fechOptionsTestConfig);
 		});
 
+		QUnit.test("getVocabularyTerms()", function(assert) {
+			var c = new common(assert, openbis);
+			var fo = new c.VocabularyTermFetchOptions();
+			var fechOptionsTestConfig = getConfigForFetchOptions(fo);
+			fechOptionsTestConfig.SortBy = null;
+			
+			var fCreate = function(facade) {
+				return $.when(c.createVocabularyTerm(facade), c.createVocabularyTerm(facade)).then(function(permId1, permId2) {
+					return [ permId1, permId2 ];
+				});
+			}
+			
+			var fGet = function(facade, permIds) {
+				testFetchOptionsAssignation(c, fo, fechOptionsTestConfig);
+				return facade.getVocabularyTerms(permIds, fo);
+			}
+			
+			var fGetEmptyFetchOptions = function(facade, permIds) {
+				return facade.getVocabularyTerms(permIds, new c.VocabularyTermFetchOptions());
+			}
+			
+			testGet(c, fCreate, fGet, fGetEmptyFetchOptions, fechOptionsTestConfig);
+		});
+		
 		QUnit.test("getExternalDms()", function(assert) {
 			var c = new common(assert, openbis);
 			var fo = new c.ExternalDmsFetchOptions();
diff --git a/microservice-server/README.md b/microservice-server/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..404d6e820c05d893527631e0f878cbd344b38113
--- /dev/null
+++ b/microservice-server/README.md
@@ -0,0 +1,80 @@
+## MICROSERVICE SERVER ##
+
+# Introduction #
+
+This project holds is supposed to be used to developed Java micro services.
+
+# Configuration #
+
+A json file with the configuration should be given during the startup as an argument, if not given the default "config.json" will be loaded (mostly used for distribution) and if not found "./conf/config.json" is loaded (mostly used for development).
+
+# Build #
+
+./gradlew distZip
+
+The build will be found at ./build/distributions/microservice-server.zip
+
+# Startup #
+
+Unzip the build and execute
+
+./bin/microservice-server
+
+# Main packages #
+
+## ch.ethz.sis.microservices.api ##
+Supposed to contain only immutable DTOs annotated with lombok's @Data.
+
+## ch.ethz.sis.microservices.server.json ##
+JSON object mapper interface and implementations.
+
+## ch.ethz.sis.microservices.server.logging ##
+Logging interface and implementation.
+
+## ch.ethz.sis.microservices.server.services ##
+Service interface and implementation.
+
+## ch.ethz.sis.microservices.server.startup ##
+Main class and launcher.
+
+## ch.ethz.sis.microservices.util ##
+Utility classes.
+
+# Configuration #
+
+The json configuration file currently have two sections.
+
+{
+	"port" : 8080,
+	"services" : []
+}
+
+The port used by the web server and a list of Services.
+
+## ch.ethz.sis.microservices.server.services.store.FileInfoHandler ##
+
+{	
+			"className" : "ch.ethz.sis.microservices.server.services.store.FileInfoHandler", 
+			"url" : "/file-information",
+			"parameters" : {
+				"openbis-url" : "http://localhost:8888/openbis/openbis/rmi-application-server-v3",
+				"datastore-url" : "http://localhost:8889/datastore_server/rmi-data-store-server-v3",
+				"services-timeout" : "10000",
+				"allowedExternalDMSCode" : "ADMIN-BS-MBPR28.D.ETHZ.CH-E96954A7",
+				"allowedContentCopyPath" : "/Users/localadmin/obis_data/"
+			}
+}
+
+## ch.ethz.sis.microservices.server.services.store.DownloadHandler ##
+
+{ 
+			"className" : "ch.ethz.sis.microservices.server.services.store.DownloadHandler", 
+			"url" : "/download",
+			"parameters" : { 
+				"openbis-url" : "http://localhost:8888/openbis/openbis/rmi-application-server-v3",
+				"datastore-url" : "http://localhost:8889/datastore_server/rmi-data-store-server-v3",
+				"services-timeout" : "10000",
+				"allowedExternalDMSCode" : "ADMIN-BS-MBPR28.D.ETHZ.CH-E96954A7",
+				"allowedContentCopyPath" : "/Users/localadmin/obis_data/"
+			}
+}
\ No newline at end of file
diff --git a/microservice-server/build.gradle b/microservice-server/build.gradle
index 102904d066390e9b8f32243d7a0bcaf451b2426d..646dd1cdbfecdca95918ae4d6ebe6eea19cdf337 100644
--- a/microservice-server/build.gradle
+++ b/microservice-server/build.gradle
@@ -25,7 +25,7 @@ dependencies {
 }
 
 
-mainClassName = "ch.ethz.sis.microservices.download.server.startup.Main"
+mainClassName = "ch.ethz.sis.microservices.server.startup.Main"
 
 distZip {
     into(project.name) {
diff --git a/microservice-server/src/main/java/ch/ethz/sis/microservices/server/startup/Main.java b/microservice-server/src/main/java/ch/ethz/sis/microservices/server/startup/Main.java
index 2fc922e26a4da911279c6a874b0f6093226d8eb7..9194cdb64d5ec35d4edf8ef7bcc627e9d4593468 100644
--- a/microservice-server/src/main/java/ch/ethz/sis/microservices/server/startup/Main.java
+++ b/microservice-server/src/main/java/ch/ethz/sis/microservices/server/startup/Main.java
@@ -27,7 +27,14 @@ public class Main
         if (args.length < 1)
         {
             configFile = new File("./conf/config.json");
-            logger.info("No arguments given, starting with default config file: " + (configFile.getAbsolutePath()));
+            if(configFile.exists()) {
+            		logger.info("No arguments given, starting with default config file: " + (configFile.getAbsolutePath()));
+            } else {
+            		configFile = new File("./config.json");
+            		if(configFile.exists()) {
+                		logger.info("No arguments given, starting with default config file: " + (configFile.getAbsolutePath()));
+                }
+            }
         } else
         {
             configFile = new File(args[0]);
diff --git a/microservice-server/src/main/java/ch/ethz/sis/microservices/server/startup/HttpClient.java b/microservice-server/src/main/java/ch/ethz/sis/microservices/util/HttpClient.java
similarity index 97%
rename from microservice-server/src/main/java/ch/ethz/sis/microservices/server/startup/HttpClient.java
rename to microservice-server/src/main/java/ch/ethz/sis/microservices/util/HttpClient.java
index ce95d4f4bb9c07c45eb346bea3d5e58ec7a9b7a1..5e1ef57a354b9fb46c915d2173fdeeccab87ac1b 100644
--- a/microservice-server/src/main/java/ch/ethz/sis/microservices/server/startup/HttpClient.java
+++ b/microservice-server/src/main/java/ch/ethz/sis/microservices/util/HttpClient.java
@@ -1,4 +1,4 @@
-package ch.ethz.sis.microservices.server.startup;
+package ch.ethz.sis.microservices.util;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
diff --git a/microservice-server/src/test/java/ch/ethz/sis/microservices/server/services/store/AbstractFileServiceTest.java b/microservice-server/src/test/java/ch/ethz/sis/microservices/server/services/store/AbstractFileServiceTest.java
index 3652c69da6155d89d700484e7e8451d1cff45832..4dcf5b8da81804b0506750573a26174e18c9f899 100644
--- a/microservice-server/src/test/java/ch/ethz/sis/microservices/server/services/store/AbstractFileServiceTest.java
+++ b/microservice-server/src/test/java/ch/ethz/sis/microservices/server/services/store/AbstractFileServiceTest.java
@@ -5,7 +5,7 @@ import java.util.Map;
 
 import ch.ethz.sis.microservices.server.logging.LogManager;
 import ch.ethz.sis.microservices.server.logging.log4j.Log4J2LogFactory;
-import ch.ethz.sis.microservices.server.startup.HttpClient;
+import ch.ethz.sis.microservices.util.HttpClient;
 import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
 import ch.systemsx.cisd.common.spring.HttpInvokerUtils;
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
index 58f145ce83f98a2be044a782e813f6845ef03326..3964a2f40fcc8e3ea1f51ebcd07a24344f7dd800 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
@@ -331,8 +331,11 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.update.TagUpdate;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.update.UpdateTagsOperation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.CreateVocabulariesOperation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.CreateVocabulariesOperationResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.CreateVocabularyTermsOperation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.CreateVocabularyTermsOperationResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.DeleteVocabularyTermsOperation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.VocabularyTermDeletionOptions;
@@ -344,6 +347,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.get.GetVocabularyTerm
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.get.GetVocabularyTermsOperationResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyTermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyTermPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.SearchVocabulariesOperation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.SearchVocabulariesOperationResult;
@@ -508,6 +512,14 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
         return result.getObjectIds();
     }
 
+    @Override
+    @Transactional
+    public List<VocabularyPermId> createVocabularies(String sessionToken, List<VocabularyCreation> creations)
+    {
+        CreateVocabulariesOperationResult result = executeOperation(sessionToken, new CreateVocabulariesOperation(creations));
+        return result.getObjectIds();
+    }
+
     @Override
     @Transactional
     public List<VocabularyTermPermId> createVocabularyTerms(String sessionToken, List<VocabularyTermCreation> creations)
@@ -515,7 +527,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
         CreateVocabularyTermsOperationResult result = executeOperation(sessionToken, new CreateVocabularyTermsOperation(creations));
         return result.getObjectIds();
     }
-
+    
     @Override
     @Transactional
     public List<TagPermId> createTags(String sessionToken, List<TagCreation> creations)
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
index fa6d5be93cd0ffdb42ecd0c692cbc24bd1331750..6a33499c620eee84a550e182ad81a23abebc3a29 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
@@ -176,12 +176,14 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.search.TagSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.update.TagUpdate;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.VocabularyTermDeletionOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyTermFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyTermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyTermPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularyTermSearchCriteria;
@@ -304,13 +306,20 @@ public class ApplicationServerApiLogger extends AbstractServerLogger implements
         return null;
     }
 
+    @Override
+    public List<VocabularyPermId> createVocabularies(String sessionToken, List<VocabularyCreation> newVocabularies)
+    {
+        logAccess(sessionToken, "create-vocabularies", "NEW_VOCABULARIES(%s)", abbreviate(newVocabularies));
+        return null;
+    }
+
     @Override
     public List<VocabularyTermPermId> createVocabularyTerms(String sessionToken, List<VocabularyTermCreation> newVocabularyTerms)
     {
         logAccess(sessionToken, "create-vocabulary-terms", "NEW_VOCABULARY_TERMS(%s)", abbreviate(newVocabularyTerms));
         return null;
     }
-
+    
     @Override
     public List<TagPermId> createTags(String sessionToken, List<TagCreation> newTags)
     {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/operation/OperationsExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/operation/OperationsExecutor.java
index 81147baa532fb3afb559c982fd7c186a20b904d2..6ca78393d18ff289421645819ec49f36bc87c55f 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/operation/OperationsExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/operation/OperationsExecutor.java
@@ -120,6 +120,7 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.IDeleteTagsOpera
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.IGetTagsOperationExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.ISearchTagsOperationExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.tag.IUpdateTagsOperationExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.vocabulary.ICreateVocabulariesOperationExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.vocabulary.ICreateVocabularyTermsOperationExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.vocabulary.IDeleteVocabularyTermsOperationExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.vocabulary.IGetVocabulariesOperationExecutor;
@@ -214,6 +215,9 @@ public class OperationsExecutor implements IOperationsExecutor
     @Autowired
     private ICreateSemanticAnnotationsOperationExecutor createSemanticAnnotationsExecutor;
 
+    @Autowired
+    private ICreateVocabulariesOperationExecutor createVocabulariesExecutor;
+    
     @Autowired
     private ICreateVocabularyTermsOperationExecutor createVocabularyTermsExecutor;
 
@@ -573,6 +577,7 @@ public class OperationsExecutor implements IOperationsExecutor
             Map<IOperation, IOperationResult> resultMap, IOperationContext context)
     {
         resultMap.putAll(createPersonsExecutor.execute(context, operations));
+        resultMap.putAll(createVocabulariesExecutor.execute(context, operations));
         resultMap.putAll(createVocabularyTermsExecutor.execute(context, operations));
         resultMap.putAll(createExperimentTypesExecutor.execute(context, operations));
         resultMap.putAll(createSampleTypesExecutor.execute(context, operations));
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/CreateVocabulariesOperationExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/CreateVocabulariesOperationExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f45656aafe74d8f28026a756bf573ef55dd6eb63
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/CreateVocabulariesOperationExecutor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.vocabulary;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.create.CreateObjectsOperation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.create.CreateObjectsOperationResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.CreateVocabulariesOperation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.CreateVocabulariesOperationResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.create.CreateObjectsOperationExecutor;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+@Component
+public class CreateVocabulariesOperationExecutor
+        extends CreateObjectsOperationExecutor<VocabularyCreation, VocabularyPermId>
+        implements ICreateVocabulariesOperationExecutor
+{
+
+    @Autowired
+    private ICreateVocabularyExecutor executor;
+
+    @Override
+    protected Class<? extends CreateObjectsOperation<VocabularyCreation>> getOperationClass()
+    {
+        return CreateVocabulariesOperation.class;
+    }
+
+    @Override
+    protected CreateObjectsOperationResult<VocabularyPermId> doExecute(IOperationContext context,
+            CreateObjectsOperation<VocabularyCreation> operation)
+    {
+        return new CreateVocabulariesOperationResult(executor.create(context, operation.getCreations()));
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/CreateVocabularyExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/CreateVocabularyExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..603197afd45ef43b1d2032f21124161b33055e6a
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/CreateVocabularyExecutor.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.vocabulary;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.context.IProgress;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.AbstractCreateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.common.batch.CollectionBatch;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.common.batch.CollectionBatchProcessor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.common.batch.MapBatch;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.entity.progress.CreateProgress;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.DataAccessExceptionTranslator;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+@Component
+public class CreateVocabularyExecutor
+        extends AbstractCreateEntityExecutor<VocabularyCreation, VocabularyPE, VocabularyPermId>
+        implements ICreateVocabularyExecutor
+{
+    @Autowired
+    private IDAOFactory daoFactory;
+
+    @Autowired
+    private IVocabularyAuthorizationExecutor authorizationExecutor;
+    
+    @Autowired
+    private ICreateVocabularyTermExecutor createTermExecutor;
+
+    @Override
+    protected IObjectId getId(VocabularyPE entity)
+    {
+        return new VocabularyPermId(entity.getCode());
+    }
+
+    @Override
+    protected VocabularyPermId createPermId(IOperationContext context, VocabularyPE entity)
+    {
+        return new VocabularyPermId(entity.getCode());
+    }
+
+    @Override
+    protected void checkData(IOperationContext context, VocabularyCreation creation)
+    {
+        if (StringUtils.isEmpty(creation.getCode()))
+        {
+            throw new UserFailureException("Code cannot be empty.");
+        }
+    }
+
+    @Override
+    protected void checkAccess(IOperationContext context)
+    {
+        authorizationExecutor.canCreate(context);
+    }
+
+    @Override
+    protected void checkAccess(IOperationContext context, VocabularyPE entity)
+    {
+    }
+
+    @Override
+    protected List<VocabularyPE> createEntities(IOperationContext context, CollectionBatch<VocabularyCreation> batch)
+    {
+        List<VocabularyPE> vocabularies = new ArrayList<>();
+        PersonPE person = context.getSession().tryGetPerson();
+        new CollectionBatchProcessor<VocabularyCreation>(context, batch)
+            {
+                @Override
+                public void process(VocabularyCreation vocabularyCreation)
+                {
+                    VocabularyPE vocabulary = new VocabularyPE();
+                    vocabulary.setCode(vocabularyCreation.getCode());
+                    vocabulary.setDescription(vocabularyCreation.getDescription());
+                    vocabulary.setManagedInternally(vocabularyCreation.isManagedInternally());
+                    vocabulary.setInternalNamespace(vocabularyCreation.isInternalNameSpace());
+                    vocabulary.setChosenFromList(vocabularyCreation.isChosenFromList());
+                    vocabulary.setURLTemplate(vocabularyCreation.getUrlTemplate());
+                    vocabulary.setRegistrator(person);
+                    vocabularies.add(vocabulary);
+                }
+
+                @Override
+                public IProgress createProgress(VocabularyCreation object, int objectIndex, int totalObjectCount)
+                {
+                    return new CreateProgress(object, objectIndex, totalObjectCount);
+                }
+            };
+        return vocabularies;
+    }
+
+    @Override
+    protected void save(IOperationContext context, List<VocabularyPE> entities, boolean clearCache)
+    {
+        for (VocabularyPE vocabulary : entities)
+        {
+            daoFactory.getVocabularyDAO().createOrUpdateVocabulary(vocabulary);
+        }
+    }
+    
+    @Override
+    protected void updateBatch(IOperationContext context, MapBatch<VocabularyCreation, VocabularyPE> batch)
+    {
+    }
+
+    @Override
+    protected void updateAll(IOperationContext context, MapBatch<VocabularyCreation, VocabularyPE> batch)
+    {
+        for (Entry<VocabularyCreation, VocabularyPE> entry : batch.getObjects().entrySet())
+        {
+            VocabularyCreation vocabularyCreation = entry.getKey();
+            List<VocabularyTermCreation> terms = vocabularyCreation.getTerms();
+            if (terms != null)
+            {
+                for (VocabularyTermCreation termCreation : terms)
+                {
+                    termCreation.setVocabularyId(new VocabularyPermId(entry.getValue().getCode()));
+                }
+                createTermExecutor.create(context, terms);
+            }
+        }
+    }
+
+    @Override
+    protected List<VocabularyPE> list(IOperationContext context, Collection<Long> ids)
+    {
+        List<VocabularyPE> allVocabularies = daoFactory.getVocabularyDAO().listAllEntities();
+        return allVocabularies.stream().filter(v -> ids.contains(v.getId())).collect(Collectors.toList());
+    }
+
+    @Override
+    protected void handleException(DataAccessException e)
+    {
+        DataAccessExceptionTranslator.throwException(e, "vocabulary", null);
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/ICreateVocabulariesOperationExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/ICreateVocabulariesOperationExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..bbf87c758d8475ea5bda2e57bb8ededd4c44157d
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/ICreateVocabulariesOperationExecutor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.vocabulary;
+
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.IOperationExecutor;
+
+/**
+ * @author Franz-Josef Elmer
+ *
+ */
+public interface ICreateVocabulariesOperationExecutor extends IOperationExecutor
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/ICreateVocabularyExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/ICreateVocabularyExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..afebb95a0e910a936188452f7be3afd7ec69f06a
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/ICreateVocabularyExecutor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.vocabulary;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.entity.ICreateEntityExecutor;
+
+/**
+ * @author Franz-Josef Elmer
+ *
+ */
+public interface ICreateVocabularyExecutor extends ICreateEntityExecutor<VocabularyCreation, VocabularyPermId>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/IVocabularyAuthorizationExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/IVocabularyAuthorizationExecutor.java
index 226a028a1c9bb4634cbd52676662f18abd821199..67e15c94d6bf60375efea53c3c067bb74a99884b 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/IVocabularyAuthorizationExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/IVocabularyAuthorizationExecutor.java
@@ -27,4 +27,6 @@ public interface IVocabularyAuthorizationExecutor extends IObjectAuthorizationEx
 
     void canGet(IOperationContext context);
 
+    void canCreate(IOperationContext context);
+
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/VocabularyAuthorizationExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/VocabularyAuthorizationExecutor.java
index c9245ef3c21abb6a92946d5ec0a779cd4b82d898..156287f7225bd79ec8688417e43e294ee72a269e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/VocabularyAuthorizationExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/vocabulary/VocabularyAuthorizationExecutor.java
@@ -30,12 +30,18 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 public class VocabularyAuthorizationExecutor implements IVocabularyAuthorizationExecutor
 {
 
+    @Override
+    @RolesAllowed({ RoleWithHierarchy.INSTANCE_ADMIN })
+    @Capability("CREATE_VOCABULARY")
+    public void canCreate(IOperationContext context)
+    {
+    }
+    
     @Override
     @RolesAllowed({ RoleWithHierarchy.PROJECT_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     @Capability("GET_VOCABULARY")
     public void canGet(IOperationContext context)
     {
-
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/sort/ComparatorFactory.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/sort/ComparatorFactory.java
index 33ed16230b8551fffe2c969825f955f5110588b4..70b7236e69aa7ce3d4384b9f14125102575dafe6 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/sort/ComparatorFactory.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/sort/ComparatorFactory.java
@@ -30,6 +30,7 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.property.PropertyAssig
 import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.sample.SampleComparatorFactory;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.space.SpaceComparatorFactory;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.tag.TagComparatorFactory;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.vocabulary.VocabularyComparatorFactory;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.vocabulary.VocabularyTermComparatorFactory;
 
 /**
@@ -46,6 +47,7 @@ public abstract class ComparatorFactory
         factories.add(new GlobalSearchObjectComparatorFactory());
         factories.add(new TagComparatorFactory());
         factories.add(new AuthorizationGroupComparatorFactory());
+        factories.add(new VocabularyComparatorFactory());
         factories.add(new VocabularyTermComparatorFactory());
         factories.add(new SpaceComparatorFactory());
         factories.add(new ProjectComparatorFactory());
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/vocabulary/VocabularyComparatorFactory.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/vocabulary/VocabularyComparatorFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6740821d46a54076e9774439a2cbebe95b88f10
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/helper/vocabulary/VocabularyComparatorFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.asapi.v3.helper.vocabulary;
+
+import java.util.Comparator;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularySortOptions;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.sort.CodeComparator;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.helper.sort.ComparatorFactory;
+
+/**
+ * @author Franz-Josef Elmer
+ *
+ */
+public class VocabularyComparatorFactory extends ComparatorFactory
+{
+
+    @Override
+    public boolean accepts(Class<?> sortOptionsClass)
+    {
+        return VocabularySortOptions.class.isAssignableFrom(sortOptionsClass);
+    }
+
+    @Override
+    public Comparator<Vocabulary> getComparator(String field)
+    {
+        if (VocabularySortOptions.CODE.equals(field))
+        {
+            return new CodeComparator<Vocabulary>();
+        } else
+        {
+            return null;
+        }
+    }
+
+    @Override
+    public Comparator<Vocabulary> getDefaultComparator()
+    {
+        return new CodeComparator<Vocabulary>();
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyBaseRecord.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyBaseRecord.java
index d9222697f6f3a7adeab242877f7870c786cb0670..55f9e51229e82bab01f692d3c65b79ce0aab48a4 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyBaseRecord.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyBaseRecord.java
@@ -30,9 +30,13 @@ public class VocabularyBaseRecord extends ObjectBaseRecord
 
     public String description;
 
-    public Boolean isInternalNamespace;
+    public boolean isInternalNamespace;
     
-    public Boolean isManagedInternally;
+    public boolean isManagedInternally;
+    
+    public boolean isChosenFromList;
+    
+    public String urlTemplate;
 
     public Date registrationDate;
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyQuery.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyQuery.java
index 3aedf51c47a6eb7911260a25cd8642153e8a4f6d..b4ef26e9a6264ac15baf31f560a55eb4af581a32 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyQuery.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyQuery.java
@@ -34,7 +34,8 @@ public interface VocabularyQuery extends ObjectQuery
 {
 
     @Select(sql = "select v.id, v.code, v.description, v.is_internal_namespace as isInternalNamespace, "
-            + "v.is_managed_internally as isManagedInternally, v.modification_timestamp as modificationDate, v.registration_timestamp as registrationDate "
+            + "v.is_managed_internally as isManagedInternally, v.is_chosen_from_list as isChosenFromList,"
+            + "v.source_uri as urlTemplate, v.modification_timestamp as modificationDate, v.registration_timestamp as registrationDate "
             + "from controlled_vocabularies v where v.id = any(?{1})", parameterBindings = { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public List<VocabularyBaseRecord> getVocabularies(LongSet vocabularyIds);
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyTranslator.java
index 1f9b1f5a5f3bc8e75127fb884a5671d4c14fdb87..ec78309262deced9f13cae439e1a6ae7b3c2ad75 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/vocabulary/VocabularyTranslator.java
@@ -87,6 +87,8 @@ public class VocabularyTranslator extends AbstractCachingTranslator<Long, Vocabu
         result.setRegistrationDate(baseRecord.registrationDate);
         result.setInternalNameSpace(baseRecord.isInternalNamespace);
         result.setManagedInternally(baseRecord.isManagedInternally);
+        result.setChosenFromList(baseRecord.isChosenFromList);
+        result.setUrlTemplate(baseRecord.urlTemplate);
 
         if (fetchOptions.hasRegistrator())
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/exception/UndefinedSpaceException.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/exception/UndefinedSpaceException.java
index 06325e17d2d173f739fcbe1396a5f06ea719187c..252e810c98a813f31f6a4bacb7984450fb73db2f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/exception/UndefinedSpaceException.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/exception/UndefinedSpaceException.java
@@ -25,7 +25,8 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
  */
 public final class UndefinedSpaceException extends UserFailureException
 {
-    private static final long serialVersionUID = 1L;
+
+	private static final long serialVersionUID = 1L;
 
     private final static String MESSAGE = "Space not specified, home space unknown";
 
@@ -33,4 +34,5 @@ public final class UndefinedSpaceException extends UserFailureException
     {
         super(MESSAGE);
     }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/authorizationgroup/create/AuthorizationGroupCreation.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/authorizationgroup/create/AuthorizationGroupCreation.js
index 348d8c736e8a29591dc6f217369193b2a0faf0f4..b57661a7f73d3ac8fc54d4ec22dda5809f71916b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/authorizationgroup/create/AuthorizationGroupCreation.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/authorizationgroup/create/AuthorizationGroupCreation.js
@@ -27,7 +27,7 @@ define([ "stjs" ], function(stjs) {
 			this.userIds = userIds;
 		};
 	}, {
-		users : {
+		userIds : {
 			name : "List",
 			arguments : [ "Object" ]
 		}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/Vocabulary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/Vocabulary.js
index a8172f9447bce926ad1e9ad04537293c7922d3fa..346bfde38da687c6370730f8c468d4bee57a98c3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/Vocabulary.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/Vocabulary.js
@@ -2,7 +2,7 @@
  * Class automatically generated with
  * {@link ch.ethz.sis.openbis.generic.shared.api.v3.dto.generators.DtoGenerator}
  */
-define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
+define([ "stjs", "util/Exceptions", "as/dto/vocabulary/id/VocabularyPermId" ], function(stjs, exceptions) {
 	var Vocabulary = function() {
 	};
 	stjs.extend(Vocabulary, null, [], function(constructor, prototype) {
@@ -16,6 +16,8 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
 		prototype.modificationDate = null;
 		prototype.managedInternally = null;
 		prototype.internalNameSpace = null;
+		prototype.chosenFromList = null;
+		prototype.urlTemplate = null;
 		prototype.terms = null;
 
 		prototype.getFetchOptions = function() {
@@ -27,6 +29,10 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
 		prototype.getCode = function() {
 			return this.code;
 		};
+		prototype.getPermId = function() {
+			var VocabularyPermId = require("as/dto/vocabulary/id/VocabularyPermId");
+			return new VocabularyPermId(this.code);
+		};
 		prototype.setCode = function(code) {
 			this.code = code;
 		};
@@ -70,6 +76,18 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
 		prototype.setInternalNameSpace = function(internalNameSpace) {
 			this.internalNameSpace = internalNameSpace;
 		};
+		prototype.isChosenFromList = function() {
+			return this.chosenFromList;
+		};
+		prototype.setChosenFromList = function(chosenFromList) {
+			this.chosenFromList = chosenFromList;
+		};
+		prototype.getUrlTemplate = function() {
+			return this.urlTemplate;
+		};
+		prototype.setUrlTemplate = function(urlTemplate) {
+			this.urlTemplate = urlTemplate;
+		};
 		prototype.getTerms = function() {
 			if (this.getFetchOptions() && this.getFetchOptions().hasTerms()) {
 				return this.terms;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/CreateVocabulariesOperation.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/CreateVocabulariesOperation.js
new file mode 100644
index 0000000000000000000000000000000000000000..338b816fd5cbf8d745d4050d40146c9defee3673
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/CreateVocabulariesOperation.js
@@ -0,0 +1,13 @@
+define([ "stjs", "as/dto/common/create/CreateObjectsOperation" ], function(stjs, CreateObjectsOperation) {
+	var CreateVocabulariesOperation = function(creations) {
+		CreateObjectsOperation.call(this, creations);
+	};
+	stjs.extend(CreateVocabulariesOperation, CreateObjectsOperation, [ CreateObjectsOperation ], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.vocabulary.create.CreateVocabulariesOperation';
+		prototype.getMessage = function() {
+			return "CreateVocabulariesOperation";
+		};
+	}, {});
+	return CreateVocabulariesOperation;
+})
+
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/CreateVocabulariesOperationResult.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/CreateVocabulariesOperationResult.js
new file mode 100644
index 0000000000000000000000000000000000000000..3cadc26399deb9230eb55d2065e9fbf9a5c59a5d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/CreateVocabulariesOperationResult.js
@@ -0,0 +1,12 @@
+define([ "stjs", "as/dto/common/create/CreateObjectsOperationResult" ], function(stjs, CreateObjectsOperationResult) {
+	var CreateVocabulariesOperationResult = function(objectIds) {
+		CreateObjectsOperationResult.call(this, objectIds);
+	};
+	stjs.extend(CreateVocabulariesOperationResult, CreateObjectsOperationResult, [ CreateObjectsOperationResult ], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.vocabulary.create.CreateVocabulariesOperationResult';
+		prototype.getMessage = function() {
+			return "CreateVocabulariesOperationResult";
+		};
+	}, {});
+	return CreateVocabulariesOperationResult;
+})
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/VocabularyCreation.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/VocabularyCreation.js
new file mode 100644
index 0000000000000000000000000000000000000000..382e58d523b6d7aceedaf2bc2979e458fb3f79bb
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/create/VocabularyCreation.js
@@ -0,0 +1,63 @@
+define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
+	var VocabularyCreation = function() {
+	};
+	stjs.extend(VocabularyCreation, null, [], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.vocabulary.create.VocabularyCreation';
+		constructor.serialVersionUID = 1;
+		prototype.code = null;
+		prototype.description = null;
+		prototype.managedInternally = null;
+		prototype.internalNameSpace = null;
+		prototype.chosenFromList = null;
+		prototype.urlTemplate = null;
+		prototype.terms = null;
+		prototype.getCode = function() {
+			return this.code;
+		};
+		prototype.setCode = function(code) {
+			this.code = code;
+		};
+		prototype.getDescription = function() {
+			return this.description;
+		};
+		prototype.setDescription = function(description) {
+			this.description = description;
+		};
+		prototype.isManagedInternally = function() {
+			return this.managedInternally;
+		};
+		prototype.setManagedInternally = function(managedInternally) {
+			this.managedInternally = managedInternally;
+		};
+		prototype.isInternalNameSpace = function() {
+			return this.internalNameSpace;
+		};
+		prototype.setInternalNameSpace = function(internalNameSpace) {
+			this.internalNameSpace = internalNameSpace;
+		};
+		prototype.isChosenFromList = function() {
+			return this.chosenFromList;
+		};
+		prototype.setChosenFromList = function(chosenFromList) {
+			this.chosenFromList = chosenFromList;
+		};
+		prototype.getUrlTemplate = function() {
+			return this.urlTemplate;
+		};
+		prototype.setUrlTemplate = function(urlTemplate) {
+			this.urlTemplate = urlTemplate;
+		};
+		prototype.getTerms = function() {
+			return this.terms;
+		};
+		prototype.setTerms = function(terms) {
+			this.terms = terms;
+		};
+	}, {
+		terms : {
+			name : "List",
+			arguments : [ "Object" ]
+		}
+	});
+	return VocabularyCreation;
+})
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/fetchoptions/VocabularySortOptions.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/fetchoptions/VocabularySortOptions.js
index 21f00d638cbb36e3eac49f71f68f43587b5283eb..48f42a5dd1e99ab66e215cc39fb5940fcc52aae3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/fetchoptions/VocabularySortOptions.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/fetchoptions/VocabularySortOptions.js
@@ -2,9 +2,21 @@ define([ "require", "stjs", "as/dto/common/fetchoptions/SortOptions" ], function
 	var VocabularySortOptions = function() {
 		SortOptions.call(this);
 	};
+	
+	var fields = {
+		CODE: "CODE",
+	};
+
 	stjs.extend(VocabularySortOptions, SortOptions, [ SortOptions ], function(constructor, prototype) {
 		prototype['@type'] = 'as.dto.vocabulary.fetchoptions.VocabularySortOptions';
 		constructor.serialVersionUID = 1;
+		prototype.code = function() {
+			return this.getOrCreateSorting(fields.CODE);
+		};
+
+		prototype.getCode = function() {
+			return this.getSorting(fields.CODE);
+		};
 	}, {});
 	return VocabularySortOptions;
 })
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/get/GetVocabulariesOperation.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/get/GetVocabulariesOperation.js
new file mode 100644
index 0000000000000000000000000000000000000000..9ee19fa24a6edf4dfaafd2aff7ce5ece3d499144
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/get/GetVocabulariesOperation.js
@@ -0,0 +1,12 @@
+define([ "stjs", "as/dto/common/get/GetObjectsOperation" ], function(stjs, GetObjectsOperation) {
+	var GetVocabulariesOperation = function(objectIds, fetchOptions) {
+		GetObjectsOperation.call(this, objectIds, fetchOptions);
+	};
+	stjs.extend(GetVocabulariesOperation, GetObjectsOperation, [ GetObjectsOperation ], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.vocabulary.get.GetVocabulariesOperation';
+		prototype.getMessage = function() {
+			return "GetVocabulariesOperation";
+		};
+	}, {});
+	return GetVocabulariesOperation;
+})
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/get/GetVocabulariesOperationResult.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/get/GetVocabulariesOperationResult.js
new file mode 100644
index 0000000000000000000000000000000000000000..1fbdbb38e1ca6c5784e054bdf90d2514cd265cf1
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/vocabulary/get/GetVocabulariesOperationResult.js
@@ -0,0 +1,12 @@
+define([ "stjs", "as/dto/common/get/GetObjectsOperationResult" ], function(stjs, GetObjectsOperationResult) {
+	var GetVocabulariesOperationResult = function(objectMap) {
+		GetObjectsOperationResult.call(this, objectMap);
+	};
+	stjs.extend(GetVocabulariesOperationResult, GetObjectsOperationResult, [ GetObjectsOperationResult ], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.vocabulary.get.GetVocabulariesOperationResult';
+		prototype.getMessage = function() {
+			return "GetVocabulariesOperationResult";
+		};
+	}, {});
+	return GetVocabulariesOperationResult;
+})
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/openbis.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/openbis.js
index 5a39722716eea9d3752fb6ee5f31e287218d697b..0370e3b659e8573a8a9757697afdb84edd02726c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/openbis.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/openbis.js
@@ -447,6 +447,21 @@ define([ 'jquery', 'util/Json', 'as/dto/datastore/search/DataStoreSearchCriteria
 			});
 		}
 
+		this.createVocabularies = function(creations) {
+			var thisFacade = this;
+			return thisFacade._private.ajaxRequest({
+				url : openbisUrl,
+				data : {
+					"method" : "createVocabularies",
+					"params" : [ thisFacade._private.sessionToken, creations ]
+				},
+				returnType : {
+					name : "List",
+					arguments : [ "VocabularyPermId" ]
+				}
+			});
+		}
+
 		this.createVocabularyTerms = function(creations) {
 			var thisFacade = this;
 			return thisFacade._private.ajaxRequest({
@@ -461,7 +476,7 @@ define([ 'jquery', 'util/Json', 'as/dto/datastore/search/DataStoreSearchCriteria
 				}
 			});
 		}
-
+		
 		this.createTags = function(creations) {
 			var thisFacade = this;
 			return thisFacade._private.ajaxRequest({
@@ -814,6 +829,21 @@ define([ 'jquery', 'util/Json', 'as/dto/datastore/search/DataStoreSearchCriteria
 			});
 		}
 
+		this.getVocabularies = function(ids, fetchOptions) {
+			var thisFacade = this;
+			return thisFacade._private.ajaxRequest({
+				url : openbisUrl,
+				data : {
+					"method" : "getVocabularies",
+					"params" : [ thisFacade._private.sessionToken, ids, fetchOptions ]
+				},
+				returnType : {
+					name : "Map",
+					arguments : [ "IVocabularyId", "Vocabulary" ]
+				}
+			});
+		}
+		
 		this.getVocabularyTerms = function(ids, fetchOptions) {
 			var thisFacade = this;
 			return thisFacade._private.ajaxRequest({
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateAuthorizationGroupTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateAuthorizationGroupTest.java
index d031a3b2d6a77b1de4b8875f7e3a4eeef00d95e9..f7f25db7baa470a721ecf2459b42a5d2d5cdcb59 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateAuthorizationGroupTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateAuthorizationGroupTest.java
@@ -58,7 +58,7 @@ public class CreateAuthorizationGroupTest extends AbstractTest
         // Given
         String sessionToken = v3api.login(TEST_USER, PASSWORD);
         AuthorizationGroupCreation newGroup = new AuthorizationGroupCreation();
-        newGroup.setCode("NEW_GROUP");
+        newGroup.setCode("MY_TEST_GROUP");
         newGroup.setDescription("Testing");
         newGroup.setUserIds(Arrays.asList(new PersonPermId(TEST_OBSERVER_CISD), new Me()));
         
@@ -81,6 +81,32 @@ public class CreateAuthorizationGroupTest extends AbstractTest
         v3api.logout(sessionToken);
     }
     
+    @Test
+    public void testCreateAuthorizationGroupWithInvalidCode()
+    {
+        // Given
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        AuthorizationGroupCreation newGroup = new AuthorizationGroupCreation();
+        newGroup.setCode("invalid code");
+        newGroup.setDescription("Testing");
+
+        assertUserFailureException(new IDelegatedAction()
+            {
+
+                @Override
+                public void execute()
+                {
+                    // When
+                    v3api.createAuthorizationGroups(sessionToken, Arrays.asList(newGroup));
+
+                }
+            },
+                // Then
+                "Given code 'invalid code' contains illegal characters (allowed: A-Z, a-z, 0-9 and _, -, .");
+
+        v3api.logout(sessionToken);
+    }
+
     @Test
     public void testCreateAuthorizationGroupWithNoUsers()
     {
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateVocabulariesTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateVocabulariesTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1124663dc53ad98f72e46e4db0983d57236737f8
--- /dev/null
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateVocabulariesTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.systemtest.asapi.v3;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
+import ch.systemsx.cisd.common.action.IDelegatedAction;
+
+/**
+ * @author Franz-Josef Elmer
+ *
+ */
+public class CreateVocabulariesTest extends AbstractTest
+{
+    @Test
+    public void testCreateVocabulary()
+    {
+        // Given
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        VocabularyCreation vocabularyCreation = new VocabularyCreation();
+        vocabularyCreation.setCode("CREATION_TEST");
+        vocabularyCreation.setDescription("creation test");
+        vocabularyCreation.setManagedInternally(true);
+        vocabularyCreation.setInternalNameSpace(true);
+        vocabularyCreation.setChosenFromList(true);
+        vocabularyCreation.setUrlTemplate("https://en.wikipedia.org/wiki/${term}");
+        VocabularyTermCreation term1 = new VocabularyTermCreation();
+        term1.setCode("OMEGA");
+        VocabularyTermCreation term2 = new VocabularyTermCreation();
+        term2.setCode("ALPHA");
+        vocabularyCreation.setTerms(Arrays.asList(term1, term2));
+        
+        // When
+        List<VocabularyPermId> vocabularies = v3api.createVocabularies(sessionToken, Arrays.asList(vocabularyCreation));
+        
+        // Then
+        VocabularyFetchOptions fetchOptions = new VocabularyFetchOptions();
+        fetchOptions.withTerms();
+        fetchOptions.withRegistrator();
+        Vocabulary vocabulary = v3api.getVocabularies(sessionToken, vocabularies, fetchOptions).get(vocabularies.get(0));
+        assertEquals(vocabulary.getCode(), "$" + vocabularyCreation.getCode());
+        assertEquals(vocabulary.getDescription(), vocabularyCreation.getDescription());
+        assertEquals(vocabulary.isManagedInternally(), vocabularyCreation.isManagedInternally());
+        assertEquals(vocabulary.isInternalNameSpace(), vocabularyCreation.isInternalNameSpace());
+        assertEquals(vocabulary.isChosenFromList(), vocabularyCreation.isChosenFromList());
+        assertEquals(vocabulary.getUrlTemplate(), vocabularyCreation.getUrlTemplate());
+        List<VocabularyTerm> terms = vocabulary.getTerms();
+        assertEquals(terms.toString(), "[VocabularyTerm ALPHA, VocabularyTerm OMEGA]");
+        assertEquals(vocabularies.size(), 1);
+        
+        v3api.logout(sessionToken);
+    }
+    
+    @Test
+    public void testCreateVocabularyWithMissingCode()
+    {
+        // Given
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        VocabularyCreation vocabularyCreation = new VocabularyCreation();
+        
+        assertUserFailureException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    // When
+                    v3api.createVocabularies(sessionToken, Arrays.asList(vocabularyCreation));
+                }
+            },
+                // Then
+                "Code cannot be empty.");
+        
+        v3api.logout(sessionToken);
+    }
+    
+    @Test
+    public void testCreateVocabularyWithInvalidCode()
+    {
+        // Given
+        String sessionToken = v3api.login(TEST_USER, PASSWORD);
+        VocabularyCreation vocabularyCreation = new VocabularyCreation();
+        vocabularyCreation.setCode("invalid code");
+        
+        assertUserFailureException(new IDelegatedAction()
+        {
+            @Override
+            public void execute()
+            {
+                // When
+                v3api.createVocabularies(sessionToken, Arrays.asList(vocabularyCreation));
+            }
+        },
+        // Then
+                "Given code 'INVALID CODE' contains illegal characters (allowed: A-Z, a-z, 0-9 and _, -, .");
+        
+        v3api.logout(sessionToken);
+    }
+    
+    @Test(dataProvider = "usersNotAllowedToCreateVocabularies")
+    public void testCreateWithUserCausingAuthorizationFailure(final String user)
+    {
+        assertAuthorizationFailureException(new IDelegatedAction()
+            {
+                @Override
+                public void execute()
+                {
+                    String sessionToken = v3api.login(user, PASSWORD);
+                    VocabularyCreation vocabularyCreation = new VocabularyCreation();
+                    vocabularyCreation.setCode("AUTHORIZATION_TEST_VOCABULARY");
+                    v3api.createVocabularies(sessionToken, Arrays.asList(vocabularyCreation));
+                }
+            });
+    }
+
+    @DataProvider
+    Object[][] usersNotAllowedToCreateVocabularies()
+    {
+        return createTestUsersProvider(TEST_GROUP_ADMIN, TEST_GROUP_OBSERVER, TEST_GROUP_POWERUSER,
+                TEST_INSTANCE_OBSERVER, TEST_OBSERVER_CISD, TEST_POWER_USER_CISD, TEST_SPACE_USER);
+    }
+}
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/GetVocabulariesTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/GetVocabulariesTest.java
index c283bb939ef76badef17fb610a86a9b55880765a..449c46ca3cc452b389893d7f9c664b76385705ab 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/GetVocabulariesTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/GetVocabulariesTest.java
@@ -53,6 +53,8 @@ public class GetVocabulariesTest extends AbstractTest
         assertEquals(v1.getDescription(), "available-organism");
         assertEquals(v1.isInternalNameSpace(), false);
         assertEquals(v1.isManagedInternally(), false);
+        assertEquals(v1.isChosenFromList(), true);
+        assertEquals(v1.getUrlTemplate(), null);
         assertEquals(v1.getTerms().toString(), 
                 "[VocabularyTerm DOG, VocabularyTerm FLY, VocabularyTerm GORILLA, VocabularyTerm HUMAN, VocabularyTerm RAT]");
         Vocabulary v2 = result.get(id2);
@@ -60,6 +62,8 @@ public class GetVocabulariesTest extends AbstractTest
         assertEquals(v2.getDescription(), "The on-disk storage format of a data set");
         assertEquals(v2.isInternalNameSpace(), true);
         assertEquals(v2.isManagedInternally(), true);
+        assertEquals(v2.isChosenFromList(), true);
+        assertEquals(v2.getUrlTemplate(), null);
         assertEquals(v2.getTerms().toString(), "[VocabularyTerm BDS_DIRECTORY, VocabularyTerm PROPRIETARY]");
         assertEquals(v2.getTerms().get(1).getLabel(), "proprietary label");
         assertEquals(v2.getTerms().get(1).getDescription(), "proprietary description");
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
index 199af3060a764eef64c6f198d3890d441f294188..2e839878dde2b5931fa4d9585c18e954b06a2179 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
@@ -175,12 +175,14 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.search.TagSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.update.TagUpdate;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.delete.VocabularyTermDeletionOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyTermFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyTermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyTermPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularyTermSearchCriteria;
@@ -238,8 +240,10 @@ public interface IApplicationServerApi extends IRpcService
 
     public List<EntityTypePermId> createMaterialTypes(String sessionToken, List<MaterialTypeCreation> newMaterialTypes);
 
-    public List<VocabularyTermPermId> createVocabularyTerms(String sessionToken, List<VocabularyTermCreation> newVocabularyTerms);
+    public List<VocabularyPermId> createVocabularies(String sessionToken, List<VocabularyCreation> newVocabularies);
 
+    public List<VocabularyTermPermId> createVocabularyTerms(String sessionToken, List<VocabularyTermCreation> newVocabularyTerms);
+    
     public List<TagPermId> createTags(String sessionToken, List<TagCreation> newTags);
 
     public List<AuthorizationGroupPermId> createAuthorizationGroups(String sessionToken, List<AuthorizationGroupCreation> newAuthorizationGroups);
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/Vocabulary.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/Vocabulary.java
index 7925f286a914a66a6c3d3acd5ef72fcf7e0f0439..b043e22bfb5f2910a8a04f325fb5c807b0fc9f88 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/Vocabulary.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/Vocabulary.java
@@ -22,6 +22,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistrationD
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistratorHolder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.NotFetchedException;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -62,6 +63,12 @@ public class Vocabulary implements Serializable, ICodeHolder, IDescriptionHolder
     @JsonProperty
     private boolean internalNameSpace;
     
+    @JsonProperty
+    private boolean chosenFromList;
+    
+    @JsonProperty
+    private String urlTemplate;
+    
     @JsonProperty
     private List<VocabularyTerm> terms;
 
@@ -78,6 +85,12 @@ public class Vocabulary implements Serializable, ICodeHolder, IDescriptionHolder
         this.fetchOptions = fetchOptions;
     }
 
+    @JsonIgnore
+    public VocabularyPermId getPermId()
+    {
+        return new VocabularyPermId(code);
+    }
+    
     // Method automatically generated with DtoGenerator
     @JsonIgnore
     @Override
@@ -177,6 +190,28 @@ public class Vocabulary implements Serializable, ICodeHolder, IDescriptionHolder
         this.internalNameSpace = internalNameSpace;
     }
 
+    @JsonIgnore
+    public boolean isChosenFromList()
+    {
+        return chosenFromList;
+    }
+
+    public void setChosenFromList(boolean chosenFromList)
+    {
+        this.chosenFromList = chosenFromList;
+    }
+
+    @JsonIgnore
+    public String getUrlTemplate()
+    {
+        return urlTemplate;
+    }
+
+    public void setUrlTemplate(String urlTemplate)
+    {
+        this.urlTemplate = urlTemplate;
+    }
+
     @JsonIgnore
     public List<VocabularyTerm> getTerms()
     {
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/CreateVocabulariesOperation.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/CreateVocabulariesOperation.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a9159b02d97f3a0dfce36d462bb1a11c592fcdb
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/CreateVocabulariesOperation.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.create.CreateObjectsOperation;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author Franz-Josef Elmer
+ *
+ */
+@JsonObject("as.dto.vocabulary.create.CreateVocabulariesOperation")
+public class CreateVocabulariesOperation extends CreateObjectsOperation<VocabularyCreation>
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private CreateVocabulariesOperation()
+    {
+    }
+
+    public CreateVocabulariesOperation(VocabularyCreation... creations)
+    {
+        super(creations);
+    }
+
+    public CreateVocabulariesOperation(List<VocabularyCreation> creations)
+    {
+        super(creations);
+    }
+
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/CreateVocabulariesOperationResult.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/CreateVocabulariesOperationResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..f55d9068fdc30bb1227a24d7ba50632c17429505
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/CreateVocabulariesOperationResult.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.create.CreateObjectsOperationResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author Franz-Josef Elmer
+ *
+ */
+@JsonObject("as.dto.vocabulary.create.CreateVocabulariesOperationResult")
+public class CreateVocabulariesOperationResult extends CreateObjectsOperationResult<VocabularyPermId>
+{
+
+    private static final long serialVersionUID = 1L;
+
+    @SuppressWarnings("unused")
+    private CreateVocabulariesOperationResult()
+    {
+    }
+
+    public CreateVocabulariesOperationResult(List<VocabularyPermId> objectIds)
+    {
+        super(objectIds);
+    }
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/VocabularyCreation.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/VocabularyCreation.java
new file mode 100644
index 0000000000000000000000000000000000000000..1fba427fbe19db2daef40c9349f5427b6af1c2d5
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/create/VocabularyCreation.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2018 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.create.ICreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.create.IObjectCreation;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author Franz-Josef Elmer
+ *
+ */
+@JsonObject("as.dto.vocabulary.create.VocabularyCreation")
+public class VocabularyCreation implements ICreation, IObjectCreation
+{
+    private static final long serialVersionUID = 1L;
+
+    private String code;
+    
+    private String description;
+    
+    private boolean managedInternally;
+    
+    private boolean internalNameSpace;
+    
+    private boolean chosenFromList;
+    
+    private String urlTemplate;
+    
+    private List<VocabularyTermCreation> terms;
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(String code)
+    {
+        this.code = code;
+    }
+
+    public String getDescription()
+    {
+        return description;
+    }
+
+    public void setDescription(String description)
+    {
+        this.description = description;
+    }
+
+    public boolean isManagedInternally()
+    {
+        return managedInternally;
+    }
+
+    public void setManagedInternally(boolean managedInternally)
+    {
+        this.managedInternally = managedInternally;
+    }
+
+    public boolean isInternalNameSpace()
+    {
+        return internalNameSpace;
+    }
+
+    public void setInternalNameSpace(boolean internalNameSpace)
+    {
+        this.internalNameSpace = internalNameSpace;
+    }
+
+    public boolean isChosenFromList()
+    {
+        return chosenFromList;
+    }
+
+    public void setChosenFromList(boolean chosenFromList)
+    {
+        this.chosenFromList = chosenFromList;
+    }
+
+    public String getUrlTemplate()
+    {
+        return urlTemplate;
+    }
+
+    public void setUrlTemplate(String urlTemplate)
+    {
+        this.urlTemplate = urlTemplate;
+    }
+
+    public List<VocabularyTermCreation> getTerms()
+    {
+        return terms;
+    }
+
+    public void setTerms(List<VocabularyTermCreation> terms)
+    {
+        this.terms = terms;
+    }
+
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/fetchoptions/VocabularySortOptions.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/fetchoptions/VocabularySortOptions.java
index f642d51b2053a9a5f565ac91a93f8344bba953ce..e145b5ef3bf4fc7838755b84940521ddfa69bcfa 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/fetchoptions/VocabularySortOptions.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/vocabulary/fetchoptions/VocabularySortOptions.java
@@ -16,7 +16,10 @@
 
 package ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.fetchoptions.SortOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.fetchoptions.SortOrder;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 
@@ -29,4 +32,17 @@ public class VocabularySortOptions extends SortOptions<Vocabulary>
 
     private static final long serialVersionUID = 1L;
 
+    @JsonIgnore
+    public static final String CODE = "CODE";
+
+    public SortOrder code()
+    {
+        return getOrCreateSorting(CODE);
+    }
+
+    public SortOrder getCode()
+    {
+        return getSorting(CODE);
+    }
+
 }
diff --git a/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt b/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
index 7957a4bd4ed2b9b9277fa13714c23e5efe58267f..724a63f02644ef83e83a6081f552f64bc12824c1 100644
--- a/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
+++ b/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
@@ -1851,4 +1851,13 @@ Search Vocabularies Operation Result
 set Terms
 with Terms
 with Terms Using
+create Vocabularies
+Create Vocabularies Operation
+Create Vocabularies Operation Result
+get Vocabularies
+Get Vocabularies Operation
+Get Vocabularies Operation Result
+is Chosen From List
+set Chosen From List
+Vocabulary Creation