diff --git a/src/main/java/org/openepics/names/rest/controller/StructuresController.java b/src/main/java/org/openepics/names/rest/controller/StructuresController.java
index 8bd7609928d44bc88240df13a80ead7a62c765f7..27965f40f9003cab971afbb97a171a9b9365eef2 100644
--- a/src/main/java/org/openepics/names/rest/controller/StructuresController.java
+++ b/src/main/java/org/openepics/names/rest/controller/StructuresController.java
@@ -142,11 +142,11 @@ public class StructuresController implements IStructures {
 
     @Override
     public ResponsePageStructureElements readStructures(Type type, Status[] statuses, Boolean deleted,
-            String uuid, String parentUuid, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
+            String uuid, String parentuuid, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
             FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
         try {
             return structuresService.readStructures(type, statuses, deleted,
-                    uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
+                    uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
                     orderBy, isAsc, page, pageSize);
         } catch (ServiceException e) {
             logService.logServiceException(LOGGER, Level.WARNING, e);
@@ -160,10 +160,10 @@ public class StructuresController implements IStructures {
 
     @Override
     public ResponseEntity<Resource> readStructuresDownload(Type type, Status[] statuses, Boolean deleted,
-            String uuid, String parentUuid, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
+            String uuid, String parentuuid, String name, String mnemonic, String mnemonicequivalence, String mnemonicpath, String description,
             FieldStructure orderBy, Boolean isAsc, Integer page, Integer pageSize) {
         ResponsePageStructureElements structureElements = readStructures(type, statuses, deleted,
-                uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
+                uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
                 orderBy, isAsc, page, pageSize);
         InputStreamResource isr = new InputStreamResource(ExcelUtil.structureElementsToExcel(structureElements));
         return ResponseEntity.ok()
diff --git a/src/main/java/org/openepics/names/service/NamesService.java b/src/main/java/org/openepics/names/service/NamesService.java
index f8fcec326f7ddd0af8bf5e6ebc1c126737baf5bd..122be9916967928f3204e08aa00f7407fb2339d5 100644
--- a/src/main/java/org/openepics/names/service/NamesService.java
+++ b/src/main/java/org/openepics/names/service/NamesService.java
@@ -218,19 +218,19 @@ public class NamesService {
             String uuid, String name, String nameequivalence, String systemstructure, String devicestructure, String index, String description,
             Boolean includeHistory, FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
-        LOGGER.log(Level.FINE, "readNames, deleted:            {0}", deleted);
-        LOGGER.log(Level.FINE, "readNames, uuid:               {0}", uuid);
-        LOGGER.log(Level.FINE, "readNames, name:               {0}", name);
-        LOGGER.log(Level.FINE, "readNames, nameequivalence:    {0}", nameequivalence);
-        LOGGER.log(Level.FINE, "readNames, systemstructure:    {0}", systemstructure);
-        LOGGER.log(Level.FINE, "readNames, devicestructure:    {0}", devicestructure);
-        LOGGER.log(Level.FINE, "readNames, index:              {0}", index);
-        LOGGER.log(Level.FINE, "readNames, description:        {0}", description);
-        LOGGER.log(Level.FINE, "readNames, includeHistory:     {0}", includeHistory);
-        LOGGER.log(Level.FINE, "readNames, orderBy:            {0}", orderBy);
-        LOGGER.log(Level.FINE, "readNames, isAsc:              {0}", isAsc);
-        LOGGER.log(Level.FINE, "readNames, offset:             {0}", offset);
-        LOGGER.log(Level.FINE, "readNames, limit:              {0}", limit);
+        LOGGER.log(Level.FINE, "readNames, deleted:         {0}", deleted);
+        LOGGER.log(Level.FINE, "readNames, uuid:            {0}", uuid);
+        LOGGER.log(Level.FINE, "readNames, name:            {0}", name);
+        LOGGER.log(Level.FINE, "readNames, nameequivalence: {0}", nameequivalence);
+        LOGGER.log(Level.FINE, "readNames, systemstructure: {0}", systemstructure);
+        LOGGER.log(Level.FINE, "readNames, devicestructure: {0}", devicestructure);
+        LOGGER.log(Level.FINE, "readNames, index:           {0}", index);
+        LOGGER.log(Level.FINE, "readNames, description:     {0}", description);
+        LOGGER.log(Level.FINE, "readNames, includeHistory:  {0}", includeHistory);
+        LOGGER.log(Level.FINE, "readNames, orderBy:         {0}", orderBy);
+        LOGGER.log(Level.FINE, "readNames, isAsc:           {0}", isAsc);
+        LOGGER.log(Level.FINE, "readNames, offset:          {0}", offset);
+        LOGGER.log(Level.FINE, "readNames, limit:           {0}", limit);
 
         // validate input
         //     queryFields and queryValues
@@ -258,14 +258,14 @@ public class NamesService {
         }
 
         ResponsePageNameElements response = new ResponsePageNameElements(nameElements, totalCount, nameElements.size(), offset, limit);
-        LOGGER.log(Level.FINE, "readNames, response:           {0}", response);
+        LOGGER.log(Level.FINE, "readNames, response:        {0}", response);
         return response;
     }
 
     public ResponsePageNameElements readNames(String name,
             FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
-        LOGGER.log(Level.FINE, "readNames, name:              {0}", name);
+        LOGGER.log(Level.FINE, "readNames, name: {0}", name);
 
         // validate input
         //     name or uuid
@@ -293,7 +293,7 @@ public class NamesService {
                     orderBy, isAsc, offset, limit);
         }
 
-        return new ResponsePageNameElements();
+        return new ResponsePageNameElements(nameElements, Long.valueOf(nameElements.size()), nameElements.size(), offset, limit);
     }
 
     public ResponsePageNameElements readNamesSystemStructure(String mnemonicpath,
@@ -340,7 +340,7 @@ public class NamesService {
 
     public ResponsePageNameElements readNamesHistory(String uuid,
             FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
-        LOGGER.log(Level.FINE, "readNamesHistory, uuid:              {0}", uuid);
+        LOGGER.log(Level.FINE, "readNamesHistory, uuid: {0}", uuid);
 
         // note
         //     HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return
diff --git a/src/main/java/org/openepics/names/service/StructuresService.java b/src/main/java/org/openepics/names/service/StructuresService.java
index 95eef282358e97a1b47c93692dd9c5225d1a7018..181173c3dd13955e41c36d47d50cc8cbc7ccb18e 100644
--- a/src/main/java/org/openepics/names/service/StructuresService.java
+++ b/src/main/java/org/openepics/names/service/StructuresService.java
@@ -274,25 +274,25 @@ public class StructuresService {
             Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit,
             StructureChoice structureChoice) {
 
-        LOGGER.log(Level.FINE, "readStructures, type:                   {0}", type);
-        LOGGER.log(Level.FINE, "readStructures, statuses.length:        {0}", String.valueOf(statuses != null ? statuses.length : "null"));
-        LOGGER.log(Level.FINE, "readStructures, deleted:                {0}", deleted);
-        LOGGER.log(Level.FINE, "readStructures, uuid:                   {0}", uuid);
-        LOGGER.log(Level.FINE, "readStructures, parentUuid:             {0}", parentUuid);
-        LOGGER.log(Level.FINE, "readStructures, name:                   {0}", name);
-        LOGGER.log(Level.FINE, "readStructures, mnemonic:               {0}", mnemonic);
-        LOGGER.log(Level.FINE, "readStructures, mnemonicequivalence:    {0}", mnemonicequivalence);
-        LOGGER.log(Level.FINE, "readStructures, mnemonicpath:           {0}", mnemonicpath);
-        LOGGER.log(Level.FINE, "readStructures, description:            {0}", description);
-        LOGGER.log(Level.FINE, "readStructures, includeHistory:         {0}", includeHistory);
-        LOGGER.log(Level.FINE, "readStructures, orderBy:                {0}", orderBy);
-        LOGGER.log(Level.FINE, "readStructures, isAsc:                  {0}", isAsc);
-        LOGGER.log(Level.FINE, "readStructures, offset:                 {0}", offset);
-        LOGGER.log(Level.FINE, "readStructures, limit:                  {0}", limit);
-        LOGGER.log(Level.FINE, "readStructures, structureChoice:        {0}", structureChoice);
+        LOGGER.log(Level.FINE, "readStructures, type:                {0}", type);
+        LOGGER.log(Level.FINE, "readStructures, statuses.length:     {0}", String.valueOf(statuses != null ? statuses.length : "null"));
+        LOGGER.log(Level.FINE, "readStructures, deleted:             {0}", deleted);
+        LOGGER.log(Level.FINE, "readStructures, uuid:                {0}", uuid);
+        LOGGER.log(Level.FINE, "readStructures, parentUuid:          {0}", parentUuid);
+        LOGGER.log(Level.FINE, "readStructures, name:                {0}", name);
+        LOGGER.log(Level.FINE, "readStructures, mnemonic:            {0}", mnemonic);
+        LOGGER.log(Level.FINE, "readStructures, mnemonicequivalence: {0}", mnemonicequivalence);
+        LOGGER.log(Level.FINE, "readStructures, mnemonicpath:        {0}", mnemonicpath);
+        LOGGER.log(Level.FINE, "readStructures, description:         {0}", description);
+        LOGGER.log(Level.FINE, "readStructures, includeHistory:      {0}", includeHistory);
+        LOGGER.log(Level.FINE, "readStructures, orderBy:             {0}", orderBy);
+        LOGGER.log(Level.FINE, "readStructures, isAsc:               {0}", isAsc);
+        LOGGER.log(Level.FINE, "readStructures, offset:              {0}", offset);
+        LOGGER.log(Level.FINE, "readStructures, limit:               {0}", limit);
+        LOGGER.log(Level.FINE, "readStructures, structureChoice:     {0}", structureChoice);
         if (statuses != null && statuses.length > 0) {
             for (Status status : statuses) {
-                LOGGER.log(Level.FINE, "readStructures, status:                 {0}", status);
+                LOGGER.log(Level.FINE, "readStructures, status:              {0}", status);
             }
         }
 
@@ -317,13 +317,20 @@ public class StructuresService {
         final List<StructureElement> structureElements = Lists.newArrayList();
         Long totalCount = null;
         if (Type.SYSTEMGROUP.equals(type)) {
-            List<SystemGroup> systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(statuses, deleted,
-                    uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
-                    includeHistory, orderBy, isAsc, offset, limit);
-            totalCount = holderRepositories.getSystemGroupRepository().countSystemGroups(statuses, deleted,
-                    uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
-                    includeHistory);
-            LOGGER.log(Level.FINE, "readStructures, systemGroups.size:      {0}", systemGroups.size());
+            // system group has no parent uuid
+            List<SystemGroup> systemGroups = null;
+            if (StringUtils.isEmpty(parentUuid)) {
+                systemGroups = holderRepositories.getSystemGroupRepository().readSystemGroups(statuses, deleted,
+                        uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
+                        includeHistory, orderBy, isAsc, offset, limit);
+                totalCount = holderRepositories.getSystemGroupRepository().countSystemGroups(statuses, deleted,
+                        uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
+                        includeHistory);
+            } else {
+                systemGroups = Lists.newArrayList();
+                totalCount = 0L;
+            }
+            LOGGER.log(Level.FINE, "readStructures, systemGroups.size:   {0}", systemGroups.size());
             structureElements.addAll(StructureElementUtil.getStructureElementsForSystemGroups(systemGroups, holder, structureChoice));
         } else if (Type.SYSTEM.equals(type)) {
             List<System> systems = holderRepositories.getSystemRepository().readSystems(statuses, deleted,
@@ -332,7 +339,7 @@ public class StructuresService {
             totalCount = holderRepositories.getSystemRepository().countSystems(statuses, deleted,
                     uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
                     includeHistory);
-            LOGGER.log(Level.FINE, "readStructures, systems.size:           {0}", systems.size());
+            LOGGER.log(Level.FINE, "readStructures, systems.size:        {0}", systems.size());
             structureElements.addAll(StructureElementUtil.getStructureElementsForSystems(systems, holder, structureChoice));
         } else if (Type.SUBSYSTEM.equals(type)) {
             List<Subsystem> subsystems = holderRepositories.getSubsystemRepository().readSubsystems(statuses, deleted,
@@ -341,16 +348,23 @@ public class StructuresService {
             totalCount = holderRepositories.getSubsystemRepository().countSubsystems(statuses, deleted,
                     uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
                     includeHistory);
-            LOGGER.log(Level.FINE, "readStructures, subsystems.size:        {0}", subsystems.size());
+            LOGGER.log(Level.FINE, "readStructures, subsystems.size:     {0}", subsystems.size());
             structureElements.addAll(StructureElementUtil.getStructureElementsForSubsystems(subsystems, holder, structureChoice));
         } else if (Type.DISCIPLINE.equals(type)) {
-            List<Discipline> disciplines = holderRepositories.getDisciplineRepository().readDisciplines(statuses, deleted,
-                    uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
-                    includeHistory, orderBy, isAsc, offset, limit);
-            totalCount = holderRepositories.getDisciplineRepository().countDisciplines(statuses, deleted,
-                    uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
-                    includeHistory);
-            LOGGER.log(Level.FINE, "readStructures, disciplines.size:       {0}", disciplines.size());
+            // discipline has no parent uuid
+            List<Discipline> disciplines = null;
+            if (StringUtils.isEmpty(parentUuid)) {
+                disciplines = holderRepositories.getDisciplineRepository().readDisciplines(statuses, deleted,
+                        uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
+                        includeHistory, orderBy, isAsc, offset, limit);
+                totalCount = holderRepositories.getDisciplineRepository().countDisciplines(statuses, deleted,
+                        uuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
+                        includeHistory);
+            } else {
+                disciplines = Lists.newArrayList();
+                totalCount = 0L;
+            }
+            LOGGER.log(Level.FINE, "readStructures, disciplines.size:    {0}", disciplines.size());
             structureElements.addAll(StructureElementUtil.getStructureElementsForDisciplines(disciplines, holder, structureChoice));
         } else if (Type.DEVICEGROUP.equals(type)) {
             List<DeviceGroup> deviceGroups = holderRepositories.getDeviceGroupRepository().readDeviceGroups(statuses, deleted,
@@ -359,7 +373,7 @@ public class StructuresService {
             totalCount = holderRepositories.getDeviceGroupRepository().countDeviceGroups(statuses, deleted,
                     uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
                     includeHistory);
-            LOGGER.log(Level.FINE, "readStructures, deviceGroups.size:      {0}", deviceGroups.size());
+            LOGGER.log(Level.FINE, "readStructures, deviceGroups.size:   {0}", deviceGroups.size());
             structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceGroups(deviceGroups, holder, structureChoice));
         } else if (Type.DEVICETYPE.equals(type)) {
             List<DeviceType> deviceTypes = holderRepositories.getDeviceTypeRepository().readDeviceTypes(statuses, deleted,
@@ -368,12 +382,12 @@ public class StructuresService {
             totalCount = holderRepositories.getDeviceTypeRepository().countDeviceTypes(statuses, deleted,
                     uuid, parentUuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description,
                     includeHistory);
-            LOGGER.log(Level.FINE, "readStructures, deviceTypes.size:       {0}", deviceTypes.size());
+            LOGGER.log(Level.FINE, "readStructures, deviceTypes.size:    {0}", deviceTypes.size());
             structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceTypes(deviceTypes, holder, structureChoice));
         }
 
         ResponsePageStructureElements response = new ResponsePageStructureElements(structureElements, totalCount, structureElements.size(), offset, limit);
-        LOGGER.log(Level.FINE, "readStructures, response:           {0}", response);
+        LOGGER.log(Level.FINE, "readStructures, response:            {0}", response);
         return response;
     }
 
@@ -388,8 +402,8 @@ public class StructuresService {
         // return
         //     structure elements for structures
 
-        LOGGER.log(Level.FINE, "readStructuresChildren, type:                   {0}", type);
-        LOGGER.log(Level.FINE, "readStructuresChildren, uuid:                   {0}", uuid);
+        LOGGER.log(Level.FINE, "readStructuresChildren, type: {0}", type);
+        LOGGER.log(Level.FINE, "readStructuresChildren, uuid: {0}", uuid);
 
         // validate input
         ValidateUtil.validateInputType(type);
@@ -437,6 +451,8 @@ public class StructuresService {
         // return
         //     structure elements for structures
 
+        LOGGER.log(Level.FINE, "readStructuresMnemonic, mnemonic: {0}", mnemonic);
+
         // validate input
         ValidateUtil.validateInputMnemonic(mnemonic);
 
@@ -471,6 +487,8 @@ public class StructuresService {
         // return
         //     structure elements for structures
 
+        LOGGER.log(Level.FINE, "readStructuresMnemonicpath, mnemonicpath: {0}", mnemonicpath);
+
         // validate input
         ValidateUtil.validateInputMnemonic(mnemonicpath);
 
@@ -515,6 +533,9 @@ public class StructuresService {
         // return
         //     structure elements for structures
 
+        LOGGER.log(Level.FINE, "readStructuresHistory, uuid: {0}", uuid);
+        LOGGER.log(Level.FINE, "readStructuresHistory, type: {0}", type);
+
         // validate input
         ValidateUtil.validateInputUuid(uuid);
 
@@ -587,6 +608,8 @@ public class StructuresService {
         // do
         //     exists
 
+        LOGGER.log(Level.FINE, "equivalenceMnemonic, mnemonic: {0}", mnemonic);
+
         // validate input
         ValidateUtil.validateInputMnemonic(mnemonic);
 
@@ -599,6 +622,8 @@ public class StructuresService {
         // do
         //     exists
 
+        LOGGER.log(Level.FINE, "existsStructure, mnemonicpath: {0}", mnemonicpath);
+
         // validate input
         ValidateUtil.validateInputType(type);
         ValidateUtil.validateInputMnemonicpath(mnemonicpath);
@@ -638,6 +663,8 @@ public class StructuresService {
         // validate data
         //     not exists
 
+        LOGGER.log(Level.FINE, "isValidToCreateStructure, mnemonicpath: {0}", mnemonicpath);
+
         // validate input
         ValidateUtil.validateInputType(type);
         ValidateUtil.validateInputMnemonicpath(mnemonicpath);
@@ -1183,7 +1210,7 @@ public class StructuresService {
                 if (!StringUtils.isEmpty(systemGroup.getMnemonic())) {
                     NameElementCommand nameElement = new NameElementCommand(null, systemGroup.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
                     NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
-                    LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:      {0}", createdNameElement.getName());
+                    LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:  {0}", createdNameElement.getName());
                 }
 
                 // add
@@ -1221,7 +1248,7 @@ public class StructuresService {
                 if (!StringUtils.isEmpty(system.getMnemonic())) {
                     NameElementCommand nameElement = new NameElementCommand(null, system.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
                     NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
-                    LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:      {0}", createdNameElement.getName());
+                    LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:  {0}", createdNameElement.getName());
                 }
 
                 // add
@@ -1259,7 +1286,7 @@ public class StructuresService {
                 if (!StringUtils.isEmpty(subsystem.getMnemonic())) {
                     NameElementCommand nameElement = new NameElementCommand(null, subsystem.getUuid(), null, null, SYSTEM_STRUCTURE_ONLY, null);
                     NameElement createdNameElement = namesService.createName(nameElement, holder, processed, processedBy);
-                    LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:      {0}", createdNameElement.getName());
+                    LOGGER.log(Level.FINE, "approveStructures, nameElement created, name:  {0}", createdNameElement.getName());
                 }
 
                 // add
diff --git a/src/main/java/org/openepics/names/util/EncodingUtility.java b/src/main/java/org/openepics/names/util/EncodingUtility.java
new file mode 100644
index 0000000000000000000000000000000000000000..578a178db7e5a1947e16ff293dcb4755882ffa40
--- /dev/null
+++ b/src/main/java/org/openepics/names/util/EncodingUtility.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018 European Spallation Source ERIC.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+package org.openepics.names.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+/**
+ * Utility class for encoding a value according to encoding scheme.
+ *
+ * @author Lars Johansson
+ *
+ * @see EncodingUtility#ENCODING_SCHEME
+ */
+public class EncodingUtility {
+
+    public static final String ENCODING_SCHEME = "UTF-8";
+
+    /**
+     * This class is not to be instantiated.
+     */
+    private EncodingUtility() {
+        throw new IllegalStateException("Utility class");
+    }
+
+    /**
+     * Encode a <code>String</code> and return the encoded value.
+     *
+     * @param s the string to encode
+     * @return the encoded value
+     *
+     * @see EncodingUtility#ENCODING_SCHEME
+     * @see URLEncoder#encode(String, String)
+     */
+    public static String encode(String s) {
+        try {
+            return URLEncoder.encode(s, ENCODING_SCHEME);
+        } catch (UnsupportedEncodingException e) {
+            return s;
+        }
+    }
+
+    /**
+     * Decode a <code>String</code> and return the decoded value.
+     *
+     * @param s the string to decode
+     * @return the decoded value
+     *
+     * @see EncodingUtility#ENCODING_SCHEME
+     * @see URLDecoder#decode(String, String)
+     */
+    public static String decode(String s) {
+        try {
+            return URLDecoder.decode(s, ENCODING_SCHEME);
+        } catch (UnsupportedEncodingException e) {
+            return s;
+        }
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/util/URLUtility.java b/src/main/java/org/openepics/names/util/URLUtility.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0a115a74ef6b00f5b4bb288586a4fd85ad50e0c
--- /dev/null
+++ b/src/main/java/org/openepics/names/util/URLUtility.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2018 European Spallation Source ERIC.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+package org.openepics.names.util;
+
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Utility class for URL handling, e.g. encoding URL.
+ *
+ * @author Lars Johansson
+ *
+ * @see EncodingUtility
+ */
+public class URLUtility {
+
+    /**
+     * / corresponds to Unicode \u002F
+     */
+    private static final String DELIMITER_PATH = "\u002F";
+    /**
+     * ? corresponds to Unicode \u003F
+     */
+    private static final String DELIMITER_PATH_QUERY = "\u003F";
+    /**
+     * & corresponds to Unicode \u003F
+     */
+    private static final String DELIMITER_ATTRIBUTES_VALUES = "\u0026";
+    /**
+     * = corresponds to Unicode \u003D
+     */
+    private static final String DELIMITER_ATTRIBUTE_VALUE = "\u003D";
+
+    private static final Pattern PATTERN_DELIMITER_PATH_QUERY =
+            Pattern.compile("\\" + DELIMITER_PATH_QUERY);
+    private static final Pattern PATTERN_DELIMITER_ATTRIBUTES_VALUES =
+            Pattern.compile("\\" + DELIMITER_ATTRIBUTES_VALUES);
+    private static final Pattern PATTERN_DELIMITER_ATTRIBUTE_VALUE =
+            Pattern.compile("\\" + DELIMITER_ATTRIBUTE_VALUE);
+
+    /**
+     * This class is not to be instantiated.
+     */
+    private URLUtility() {
+        throw new IllegalStateException("Utility class");
+    }
+
+    /**
+     * Encode a URL and return the encoded value.
+     *
+     * <p>
+     * Note that all or parts of URL may be encoded. In case of attributes, attribute values but not names are to be encoded.
+     * There are special characters that are used to separate parts of URL. Such characters are / ? & =
+     * </p>
+     *
+     * <br/> Different URLs
+     * <ul>
+     * <li> a           </li>
+     * <li> a/b         </li>
+     * <li> a/b?c       </li>
+     * <li> a/b?c=d     </li>
+     * <li> a/b?c=d&e=f </li>
+     * <li> ...         </li>
+     * </ul>
+     *
+     * <p>
+     *     Example a.
+     *     <ul>
+     *     <li>a is encoded</li>
+     *     </ul>
+     * </p>
+     * <p>
+     *     Example a/b.
+     *     <li>a is not encoded</li>
+     *     <li>b is encoded</li>
+     * </p>
+     * <p>
+     *     Example a/b?c.
+     *     <li>a is not encoded</li>
+     *     <li>b is encoded</li>
+     *     <li>c is encoded</li>
+     * </p>
+     * <p>
+     *     Example a/b?c=d.
+     *     <li>a is not encoded</li>
+     *     <li>b is encoded</li>
+     *     <li>c is not encoded</li>
+     *     <li>d is encoded</li>
+     * </p>
+     * <p>
+     *     Example a/b?c=d&e=f.
+     *     <li>a is not encoded</li>
+     *     <li>b is encoded</li>
+     *     <li>c is not encoded</li>
+     *     <li>d is encoded</li>
+     *     <li>e is not encoded</li>
+     *     <li>f is encoded</li>
+     * </p>
+     *
+     * <p>
+     * Example 1. For <code>abc.xhtml?attribute1=value1&amp;attribute2=value2</code>, it corresponds to b?c=d&e=f above.
+     * Then <code>abc.xhtml</code>, <code>value1</code> and <code>value2</code> are to be encoded, not other parts of url.
+     * <7p>
+     *
+     * <p>
+     * Example 2. For <code>cable-types.xhtml?cableTypeName=1C20RG-58HV+ 2C20</code>, it corresponds to b?c=d above.
+     * Then <code>cable-types.xhtml</code> and <code>1C20RG-58HV+ 2C20</code> is to be encoded, not other parts of url.
+     * </p>
+     *
+     * @param url a url
+     * @return the encoded value
+     *
+     * @see EncodingUtility#ENCODING_SCHEME
+     * @see EncodingUtility#encode(String)
+     * @see EncodingUtility#decode(String)
+     */
+    public static String encodeURL(String url) {
+        if (url == null)
+            return url;
+
+        // not trim url
+
+        // start prepare return value
+        StringBuilder encodedURL = new StringBuilder();
+
+        String path0 = null;
+        String path1 = null;
+
+        // split path on last DELIMITER_PATH
+        String reverseUrl = StringUtils.reverse(url);
+        int index = reverseUrl.indexOf(DELIMITER_PATH);
+        if (index == -1) {
+            path0 = null;
+            path1 = url;
+        } else {
+            path0 = StringUtils.reverse(reverseUrl.substring(index + 1));
+            path1 = StringUtils.reverse(reverseUrl.substring(0, index));
+            encodedURL.append(path0);
+            encodedURL.append(DELIMITER_PATH);
+        }
+
+      // split path and query
+      String[] pathQuery = PATTERN_DELIMITER_PATH_QUERY.split(path1, 2);
+      if (pathQuery.length != 2) {
+          encodedURL.append(EncodingUtility.encode(path1));
+          return encodedURL.toString();
+      }
+      encodedURL.append(pathQuery[0]);
+      encodedURL.append(DELIMITER_PATH_QUERY);
+
+        // split attribute-value pairs
+        String[] attributesValues = PATTERN_DELIMITER_ATTRIBUTES_VALUES.split(pathQuery[1]);
+
+        // loop through attributes_values, encode values
+        for (String pair : attributesValues) {
+            // split attribute and value
+            String[] attributeValue = PATTERN_DELIMITER_ATTRIBUTE_VALUE.split(pair, 2);
+
+            if (attributeValue.length == 1) {
+                // not encode attribute
+                encodedURL.append(EncodingUtility.encode(attributeValue[0]));
+                encodedURL.append(DELIMITER_ATTRIBUTES_VALUES);
+            } else {
+                // encode value
+              encodedURL.append(attributeValue[0]);
+              encodedURL.append(DELIMITER_ATTRIBUTE_VALUE);
+              encodedURL.append(EncodingUtility.encode(attributeValue[1]));
+              encodedURL.append(DELIMITER_ATTRIBUTES_VALUES);
+            }
+        }
+
+        // remove trailing delimiter
+        int length = encodedURL.length();
+        if (encodedURL.substring(length - 1).equals(DELIMITER_ATTRIBUTES_VALUES)) {
+            encodedURL.setLength(length - 1);
+        }
+
+        return encodedURL.toString();
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/docker/ITUtil.java b/src/test/java/org/openepics/names/docker/ITUtil.java
index ec376d2d9510f2b02cfcee973d1fef8535278f68..400e1bc3aa54567014bf5e50b4558f2eda661046 100644
--- a/src/test/java/org/openepics/names/docker/ITUtil.java
+++ b/src/test/java/org/openepics/names/docker/ITUtil.java
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.openepics.names.rest.beans.response.Response;
 import org.openepics.names.rest.beans.response.ResponseBoolean;
 import org.openepics.names.rest.beans.response.ResponseBooleanList;
+import org.openepics.names.util.URLUtility;
 
 /**
  * Utility class to help (Docker) integration tests for Naming and PostgreSQL.
@@ -104,7 +105,9 @@ public class ITUtil {
      * @throws IOException
      */
     static String[] doGetJson(String spec) throws IOException {
-        URL url = new URL(spec);
+        // note that URL is encoded
+
+        URL url = new URL(URLUtility.encodeURL(spec));
         HttpURLConnection con = (HttpURLConnection) url.openConnection();
         int responseCode = con.getResponseCode();
 
diff --git a/src/test/java/org/openepics/names/docker/NamesIT.java b/src/test/java/org/openepics/names/docker/NamesIT.java
index 799def8298db5a86bb1682ef1f63312333d88e41..77f45e504b1d3cfdb8be1ed64e37f079ca2012c4 100644
--- a/src/test/java/org/openepics/names/docker/NamesIT.java
+++ b/src/test/java/org/openepics/names/docker/NamesIT.java
@@ -790,38 +790,81 @@ class NamesIT {
         responseNameElement = ITUtilNameElement.assertDelete(nameElement8);
 
         try {
-            // read
-
+            // read & search
+            //     deleted, uuid, name, nameequivalence, systemstructure, devicestructure, index, description
+            //     combination
             ITUtilNameElement.assertRead("", 8, -1);
 
-            ITUtilNameElement.assertRead("?uuid=" + uuid.toString(),   1);
-            ITUtilNameElement.assertRead("?nameequivalence=RFQ-10%25", 8, -1);
-            ITUtilNameElement.assertRead("?nameequivalence=RFQ-10%25&devicestructure=EMR-FS", 6, -1);
-            ITUtilNameElement.assertRead("?index=003", 1);
-
             ITUtilNameElement.assertRead("?deleted=false", 6, -1);
             ITUtilNameElement.assertRead("?deleted=true",  2, -1);
 
-            ITUtilNameElement.assertRead("/RFQ-010:EMR-FS-005",  1);
-            ITUtilNameElement.assertRead("/RFQ-010:EMR-FS-0",    0);
-            ITUtilNameElement.assertRead("/RFQ-010:EMR-FS-0__",  6, -1);
-            ITUtilNameElement.assertRead("/RFQ-010:EMR-FS-0%25", 6, -1);
+            ITUtilNameElement.assertRead("?uuid=" + deviceTypeFS.toString(), 0);
+            ITUtilNameElement.assertRead("?uuid=" + uuid.toString(),         1);
 
-            ITUtilNameElement.assertRead("/systemstructure/RFQ-010",  6, -1);
-            ITUtilNameElement.assertRead("/systemstructure/RFQ-0",    0);
-            ITUtilNameElement.assertRead("/systemstructure/RFQ-0__",  6, -1);
-            ITUtilNameElement.assertRead("/systemstructure/RFQ-N1U1", 1);
+            ITUtilNameElement.assertRead("?name=RFQ-010:EMR-FS-005",  1);
+            ITUtilNameElement.assertRead("?name=RFQ-010%",            8, -1);
+            ITUtilNameElement.assertRead("?name=RFQ-10%",             0);
 
-            ITUtilNameElement.assertRead("/devicestructure/EMR-FS", 6, -1);
-            ITUtilNameElement.assertRead("/devicestructure/EMR-F",  0);
-            ITUtilNameElement.assertRead("/devicestructure/EMR-F_", 6, -1);
-            ITUtilNameElement.assertRead("/devicestructure/EMR-TT", 0);
+            ITUtilNameElement.assertRead("?nameequivalence=RFQ-10%",  8, -1);
 
-            // history
+            ITUtilNameElement.assertRead("?systemstructure=RFQ-010",  6, -1);
+            ITUtilNameElement.assertRead("?systemstructure=RFQ-0",    0);
+            ITUtilNameElement.assertRead("?systemstructure=RFQ-0__",  6, -1);
+            ITUtilNameElement.assertRead("?systemstructure=RFQ-N1U1", 1);
+
+            ITUtilNameElement.assertRead("?devicestructure=EMR-FS",   6, -1);
+            ITUtilNameElement.assertRead("?devicestructure=EMR-F",    0);
+            ITUtilNameElement.assertRead("?devicestructure=EMR-F_",   6, -1);
+            ITUtilNameElement.assertRead("?devicestructure=EMR-TT",   0);
 
-            ITUtilNameElement.assertRead("/history/" + systemRFQ.toString(), 0);
-            ITUtilNameElement.assertRead("/history/" + uuid.toString(),      3);
-            ITUtilNameElement.assertRead("/history/" + uuid2.toString(),     1);
+            ITUtilNameElement.assertRead("?index=003", 1);
+
+            ITUtilNameElement.assertRead("?description=description",               7, -1);
+            ITUtilNameElement.assertRead("?description=%description%",             8, -1);
+            ITUtilNameElement.assertRead("?description=updated description",       0, -1);
+            ITUtilNameElement.assertRead("?description=updated description%",      1, -1);
+            ITUtilNameElement.assertRead("?description=updated description again", 1);
+
+            ITUtilNameElement.assertRead("?nameequivalence=RFQ-10%&devicestructure=EMR-FS", 6, -1);
+
+            // name or uuid
+            //     /{name}
+            ITUtilNameElement.assertRead("/" + systemGroupAcc.toString(), 0);
+            ITUtilNameElement.assertRead("/" + systemRFQ.toString(),      0);
+            ITUtilNameElement.assertRead("/" + subsystem010.toString(),   0);
+            ITUtilNameElement.assertRead("/" + disciplineEMR.toString(),  0);
+            ITUtilNameElement.assertRead("/" + deviceGroupEMR.toString(), 0);
+            ITUtilNameElement.assertRead("/" + deviceTypeFS.toString(),   0);
+            ITUtilNameElement.assertRead("/" + uuid.toString(),           1);
+            ITUtilNameElement.assertRead("/RFQ-010:EMR-FS-001",           1);
+            ITUtilNameElement.assertRead("/RFQ-010:EMR-FS-0",             0);
+            ITUtilNameElement.assertRead("/RFQ-010:EMR-FS-0__",           6, -1);
+            ITUtilNameElement.assertRead("/RFQ-010:EMR-FS-0%",            6, -1);
+
+            // system structure mnemonic path
+            //     /systemstructure/{mnemonicpath}
+            ITUtilNameElement.assertRead("/systemstructure/RFQ-010",      6, -1);
+            ITUtilNameElement.assertRead("/systemstructure/RFQ-0",        0);
+            ITUtilNameElement.assertRead("/systemstructure/RFQ-0__",      6, -1);
+            ITUtilNameElement.assertRead("/systemstructure/RFQ-N1U1",     1);
+
+            // device structure mnemonic path
+            //     /devicestructure/{mnemonicpath}
+            ITUtilNameElement.assertRead("/devicestructure/EMR-FS",       6, -1);
+            ITUtilNameElement.assertRead("/devicestructure/EMR-F",        0);
+            ITUtilNameElement.assertRead("/devicestructure/EMR-F_",       6, -1);
+            ITUtilNameElement.assertRead("/devicestructure/EMR-TT",       0);
+
+            // history
+            //     /history/{uuid}
+            ITUtilNameElement.assertRead("/history/" + systemGroupAcc.toString(), 0);
+            ITUtilNameElement.assertRead("/history/" + systemRFQ.toString(),      0);
+            ITUtilNameElement.assertRead("/history/" + subsystem010.toString(),   0);
+            ITUtilNameElement.assertRead("/history/" + disciplineEMR.toString(),  0);
+            ITUtilNameElement.assertRead("/history/" + deviceGroupEMR.toString(), 0);
+            ITUtilNameElement.assertRead("/history/" + deviceTypeFS.toString(),   0);
+            ITUtilNameElement.assertRead("/history/" + uuid.toString(),           3);
+            ITUtilNameElement.assertRead("/history/" + uuid2.toString(),          1);
         } catch (Exception e) {
             fail();
         }
diff --git a/src/test/java/org/openepics/names/docker/StructuresDeviceGroupIT.java b/src/test/java/org/openepics/names/docker/StructuresDeviceGroupIT.java
index 297b399ddef98cd31355e5f04b4f5a3d315ce1d6..d6de272fb47c862ed359242559d84995b5b6aebf 100644
--- a/src/test/java/org/openepics/names/docker/StructuresDeviceGroupIT.java
+++ b/src/test/java/org/openepics/names/docker/StructuresDeviceGroupIT.java
@@ -1773,6 +1773,10 @@ class StructuresDeviceGroupIT {
             // from first structure element
             assertNotNull(uuid);
 
+            // read & search
+            //     /{type}
+            //     type, statuses, deleted, uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            //     combination
             ITUtilStructureElement.assertRead("/DEVICEGROUP?mnemonicpath=Di2",                                                  30);
             ITUtilStructureElement.assertRead("/DEVICEGROUP?statuses=PENDING&mnemonicpath=Di2",                                  5);
             ITUtilStructureElement.assertRead("/DEVICEGROUP?statuses=APPROVED&mnemonicpath=Di2",                                20);
@@ -1794,10 +1798,58 @@ class StructuresDeviceGroupIT {
             ITUtilStructureElement.assertRead("/DEVICEGROUP?deleted=true&statuses=REJECTED&mnemonicpath=Di2",                    5);
             ITUtilStructureElement.assertRead("/DEVICEGROUP?deleted=true&statuses=PENDING&statuses=APPROVED&mnemonicpath=Di2",  10);
 
-            ITUtilStructureElement.assertRead("/children/DEVICEGROUP/" + uuid.toString(),          0);
-            ITUtilStructureElement.assertRead("/children/DISCIPLINE/" + disciplineUuid.toString(), 1, -1);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?uuid=" + discipline2Uuid.toString(),       0);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?uuid=" + uuid.toString(),                  1);
+
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?parentuuid=" + discipline2Uuid.toString(), 45, -1);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?parentuuid=" + uuid.toString(),            0);
+
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?name=na",                  0);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?name=na_",                 0);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?name=na__",               45, -1);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?name=na___",               0);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?name=na%",                45, -1);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?name=name",               45, -1);
+
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?mnemonicequivalence=A__",  0);
+
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?mnemonic=A__",             0);
+
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?description=desc",         0);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?description=desc%",       35, -1);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?description=sc",           0);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?description=sc%",          0);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?description=%sc",          0);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?description=%sc%",        45, -1);
+            ITUtilStructureElement.assertRead("/DEVICEGROUP?description=description", 35, -1);
+
+            // children
+            //     /children/{type}/{uuid}
+            //     type, uuid, statuses, deleted, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            ITUtilStructureElement.assertRead("/children/DEVICEGROUP/" + uuid.toString(),             0);
+            ITUtilStructureElement.assertRead("/children/DISCIPLINE/"  + discipline2Uuid.toString(), 15, -1);
+
+            // mnemonic
+            //     /mnemonic/{mnemonic}
+            ITUtilStructureElement.assertRead("/mnemonic/A",        0);
+            ITUtilStructureElement.assertRead("/mnemonic/A__",      0);
+            ITUtilStructureElement.assertRead("/mnemonic/AG_",      0);
+            ITUtilStructureElement.assertRead("/mnemonic/AG1",      0);
+            ITUtilStructureElement.assertRead("/mnemonic/Di2",      1);
+
+            // mnemonic path
+            //     /mnemonicpath/{mnemonicpath}
+            ITUtilStructureElement.assertRead("/mnemonicpath/D",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/D%",  16, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/D__", 16, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Di_", 16, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Di2", 16);
+
+            // history
+            //     /history/{uuid}
+            ITUtilStructureElement.assertRead("/history/" + uuid.toString(),            1);
+            ITUtilStructureElement.assertRead("/history/" + discipline2Uuid.toString(), 1);
 
-            ITUtilStructureElement.assertExists(Type.DEVICEGROUP, "Di",  Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.DEVICEGROUP, "Di2", Boolean.TRUE);
         } catch (Exception e) {
             fail();
diff --git a/src/test/java/org/openepics/names/docker/StructuresDeviceTypeIT.java b/src/test/java/org/openepics/names/docker/StructuresDeviceTypeIT.java
index c1e33320a87d2af8653cedf21dab86ea6b179ad1..4103702cee272a84a62fc74b090d7b4f793bd7ae 100644
--- a/src/test/java/org/openepics/names/docker/StructuresDeviceTypeIT.java
+++ b/src/test/java/org/openepics/names/docker/StructuresDeviceTypeIT.java
@@ -1789,6 +1789,10 @@ class StructuresDeviceTypeIT {
             // from first structure element
             assertNotNull(uuid);
 
+            // read & search
+            //     /{type}
+            //     type, statuses, deleted, uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            //     combination
             ITUtilStructureElement.assertRead("/DEVICETYPE?mnemonic=A__",                                                  45);
             ITUtilStructureElement.assertRead("/DEVICETYPE?statuses=PENDING&mnemonic=A__",                                 10);
             ITUtilStructureElement.assertRead("/DEVICETYPE?statuses=APPROVED&mnemonic=A__",                                20);
@@ -1810,9 +1814,65 @@ class StructuresDeviceTypeIT {
             ITUtilStructureElement.assertRead("/DEVICETYPE?deleted=true&statuses=REJECTED&mnemonic=A__",                    5);
             ITUtilStructureElement.assertRead("/DEVICETYPE?deleted=true&statuses=PENDING&statuses=APPROVED&mnemonic=A__",  10);
 
-            ITUtilStructureElement.assertRead("/children/DEVICETYPE/" + uuid.toString(),             0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?uuid=" + disciplineUuid.toString(),         0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?uuid=" + deviceGroupUuid.toString(),        0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?uuid=" + uuid.toString(),                   1);
+
+            ITUtilStructureElement.assertRead("/DEVICETYPE?parentuuid=" + disciplineUuid.toString(),   0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?parentuuid=" + deviceGroupUuid.toString(), 45, -1);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?parentuuid=" + uuid.toString(),             0);
+
+            ITUtilStructureElement.assertRead("/DEVICETYPE?name=na",                  0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?name=na_",                 0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?name=na__",               45, -1);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?name=na___",               0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?name=na%",                45, -1);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?name=name",               45, -1);
+
+            ITUtilStructureElement.assertRead("/DEVICETYPE?mnemonicequivalence=A__", 45, -1);
+
+            ITUtilStructureElement.assertRead("/DEVICETYPE?mnemonicepath=A__",       45, -1);
+
+            ITUtilStructureElement.assertRead("/DEVICETYPE?description=desc",         0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?description=desc%",       35, -1);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?description=sc",           0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?description=sc%",          0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?description=%sc",          0);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?description=%sc%",        45, -1);
+            ITUtilStructureElement.assertRead("/DEVICETYPE?description=description", 35, -1);
+
+            // children
+            //     /children/{type}/{uuid}
+            //     type, uuid, statuses, deleted, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            ITUtilStructureElement.assertRead("/children/DEVICETYPE/"  + uuid.toString(),            0);
             ITUtilStructureElement.assertRead("/children/DEVICEGROUP/" + deviceGroupUuid.toString(), 1, -1);
-            ITUtilStructureElement.assertRead("/children/DISCIPLINE/" + disciplineUuid.toString(),   1, -1);
+            ITUtilStructureElement.assertRead("/children/DISCIPLINE/"  + disciplineUuid.toString(),  1, -1);
+
+            // mnemonic
+            //     /mnemonic/{mnemonic}
+            ITUtilStructureElement.assertRead("/mnemonic/A",           0);
+            ITUtilStructureElement.assertRead("/mnemonic/A__",        15, -1);
+            ITUtilStructureElement.assertRead("/mnemonic/AG_",         5);
+            ITUtilStructureElement.assertRead("/mnemonic/AG1",         1);
+            ITUtilStructureElement.assertRead("/mnemonic/Di",          1);
+
+            // mnemonic path
+            //     /mnemonicpath/{mnemonicpath}
+            ITUtilStructureElement.assertRead("/mnemonicpath/A",       0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/A__",     0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG_",     0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG1",     0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Di-A%",  15, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Di-A",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Di-A__", 15, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Di-AG_",  5);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Di-AG1",  1);
+
+            // history
+            //     /history/{uuid}
+            ITUtilStructureElement.assertRead("/history/" + uuid.toString(),            1);
+            ITUtilStructureElement.assertRead("/history/" + deviceGroupUuid.toString(), 1);
+            ITUtilStructureElement.assertRead("/history/" + disciplineUuid.toString(),  1);
 
             ITUtilStructureElement.assertExists(Type.DEVICETYPE, "Di-AA1", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.DEVICETYPE, "Di-AA2", Boolean.TRUE);
diff --git a/src/test/java/org/openepics/names/docker/StructuresDisciplineIT.java b/src/test/java/org/openepics/names/docker/StructuresDisciplineIT.java
index 496cbd5a9da69263f12808e5ffa615eb2b559c49..f18cf5d44c726dfae5465d66023428595362edb6 100644
--- a/src/test/java/org/openepics/names/docker/StructuresDisciplineIT.java
+++ b/src/test/java/org/openepics/names/docker/StructuresDisciplineIT.java
@@ -1694,6 +1694,10 @@ class StructuresDisciplineIT {
             // from first structure element
             assertNotNull(uuid);
 
+            // read & search
+            //     /{type}
+            //     type, statuses, deleted, uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            //     combination
             ITUtilStructureElement.assertRead("/DISCIPLINE?mnemonic=A__",                                                  45);
             ITUtilStructureElement.assertRead("/DISCIPLINE?statuses=PENDING&mnemonic=A__",                                 10);
             ITUtilStructureElement.assertRead("/DISCIPLINE?statuses=APPROVED&mnemonic=A__",                                20);
@@ -1715,8 +1719,52 @@ class StructuresDisciplineIT {
             ITUtilStructureElement.assertRead("/DISCIPLINE?deleted=true&statuses=REJECTED&mnemonic=A__",                    5);
             ITUtilStructureElement.assertRead("/DISCIPLINE?deleted=true&statuses=PENDING&statuses=APPROVED&mnemonic=A__",  10);
 
+            ITUtilStructureElement.assertRead("/DISCIPLINE?uuid=" + uuid.toString(),        1);
+
+            ITUtilStructureElement.assertRead("/DISCIPLINE?parentuuid=" + uuid.toString(),  0);
+
+            ITUtilStructureElement.assertRead("/DISCIPLINE?name=na",                        0);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?name=na_",                       0);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?name=na__",                     45, -1);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?name=na___",                     0);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?name=na%",                      45, -1);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?name=name",                     45, -1);
+
+            ITUtilStructureElement.assertRead("/DISCIPLINE?mnemonicequivalence=A__",       45, -1);
+
+            ITUtilStructureElement.assertRead("/DISCIPLINE?mnemonicepath=A__",             45, -1);
+
+            ITUtilStructureElement.assertRead("/DISCIPLINE?description=desc",               0);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?description=desc%",             35, -1);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?description=sc",                 0);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?description=sc%",                0);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?description=%sc",                0);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?description=%sc%",              45, -1);
+            ITUtilStructureElement.assertRead("/DISCIPLINE?description=description",       35, -1);
+
+            // children
+            //     /children/{type}/{uuid}
+            //     type, uuid, statuses, deleted, name, mnemonic, mnemonicequivalence, mnemonicpath, description
             ITUtilStructureElement.assertRead("/children/DISCIPLINE/" + uuid.toString(), 0);
 
+            // mnemonic
+            //     /mnemonic/{mnemonic}
+            ITUtilStructureElement.assertRead("/mnemonic/A",        0);
+            ITUtilStructureElement.assertRead("/mnemonic/A__",     15, -1);
+            ITUtilStructureElement.assertRead("/mnemonic/AG_",      5);
+            ITUtilStructureElement.assertRead("/mnemonic/AG1",      1);
+
+            // mnemonic path
+            //     /mnemonicpath/{mnemonicpath}
+            ITUtilStructureElement.assertRead("/mnemonicpath/A",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/A__", 15, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG_",  5);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG1",  1);
+
+            // history
+            //     /history/{uuid}
+            ITUtilStructureElement.assertRead("/history/" + uuid.toString(),  1);
+
             ITUtilStructureElement.assertExists(Type.DISCIPLINE, "AA1", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.DISCIPLINE, "AA2", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.DISCIPLINE, "AA3", Boolean.TRUE);
diff --git a/src/test/java/org/openepics/names/docker/StructuresSubsystemIT.java b/src/test/java/org/openepics/names/docker/StructuresSubsystemIT.java
index 0cf4086cf2c395da33d445bfe3f7e268a0741af3..142a8170d5b116e23ca513b7020a11ab6a63ef34 100644
--- a/src/test/java/org/openepics/names/docker/StructuresSubsystemIT.java
+++ b/src/test/java/org/openepics/names/docker/StructuresSubsystemIT.java
@@ -1841,6 +1841,10 @@ class StructuresSubsystemIT {
             // from first structure element
             assertNotNull(uuid);
 
+            // read & search
+            //     /{type}
+            //     type, statuses, deleted, uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            //     combination
             ITUtilStructureElement.assertRead("/SUBSYSTEM?mnemonic=A__",                                                  45);
             ITUtilStructureElement.assertRead("/SUBSYSTEM?statuses=PENDING&mnemonic=A__",                                 10);
             ITUtilStructureElement.assertRead("/SUBSYSTEM?statuses=APPROVED&mnemonic=A__",                                20);
@@ -1862,10 +1866,82 @@ class StructuresSubsystemIT {
             ITUtilStructureElement.assertRead("/SUBSYSTEM?deleted=true&statuses=REJECTED&mnemonic=A__",                    5);
             ITUtilStructureElement.assertRead("/SUBSYSTEM?deleted=true&statuses=PENDING&statuses=APPROVED&mnemonic=A__",  10);
 
-            ITUtilStructureElement.assertRead("/children/SUBSYSTEM/" + uuid.toString(),              0);
-            ITUtilStructureElement.assertRead("/children/SYSTEM/" + systemUuid.toString(),           1, -1);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?uuid=" + systemGroupUuid.toString(),        0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?uuid=" + systemUuid.toString(),             0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?uuid=" + uuid.toString(),                   1);
+
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?parentuuid=" + systemGroupUuid.toString(),  0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?parentuuid=" + systemUuid.toString(),      45, -1);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?parentuuid=" + uuid.toString(),             0);
+
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?name=na",                  0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?name=na_",                 0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?name=na__",               45, -1);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?name=na___",               0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?name=na%",                45, -1);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?name=name",               45, -1);
+
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?mnemonicequivalence=A__", 45, -1);
+
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?mnemonicepath=A__",       45, -1);
+
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?description=desc",         0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?description=desc%",       35, -1);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?description=sc",           0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?description=sc%",          0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?description=%sc",          0);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?description=%sc%",        45, -1);
+            ITUtilStructureElement.assertRead("/SUBSYSTEM?description=description", 35, -1);
+
+            // children
+            //     /children/{type}/{uuid}
+            //     type, uuid, statuses, deleted, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            ITUtilStructureElement.assertRead("/children/SUBSYSTEM/"   + uuid.toString(),            0);
+            ITUtilStructureElement.assertRead("/children/SUBSYSTEM/"   + systemUuid.toString(),      0);
+            ITUtilStructureElement.assertRead("/children/SUBSYSTEM/"   + systemGroupUuid.toString(), 0);
+            ITUtilStructureElement.assertRead("/children/SYSTEM/"      + uuid.toString(),            0);
+            ITUtilStructureElement.assertRead("/children/SYSTEM/"      + systemUuid.toString(),      1, -1);
+            ITUtilStructureElement.assertRead("/children/SYSTEM/"      + systemGroupUuid.toString(), 0);
+            ITUtilStructureElement.assertRead("/children/SYSTEMGROUP/" + uuid.toString(),            0);
+            ITUtilStructureElement.assertRead("/children/SYSTEMGROUP/" + systemUuid.toString(),      0);
             ITUtilStructureElement.assertRead("/children/SYSTEMGROUP/" + systemGroupUuid.toString(), 1, -1);
 
+            // mnemonic
+            //     /mnemonic/{mnemonic}
+            ITUtilStructureElement.assertRead("/mnemonic/A",             0);
+            ITUtilStructureElement.assertRead("/mnemonic/A__",          15, -1);
+            ITUtilStructureElement.assertRead("/mnemonic/AG_",           5);
+            ITUtilStructureElement.assertRead("/mnemonic/AG1",           1);
+            ITUtilStructureElement.assertRead("/mnemonic/Sg",            1);
+
+            // mnemonic path
+            //     /mnemonicpath/{mnemonicpath}
+            ITUtilStructureElement.assertRead("/mnemonicpath/A",         0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/A__",       0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG_",       0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG1",       0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sys-A%",   15, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sys-A",     0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sys-A__",  15, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sys-AG_",   5);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sys-AG1",   1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-A%",     0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-A",      0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-A__",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-AG_",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-AG1",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-Sys%",   0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-Sys",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-Sys__",  0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-Sys_",   0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-Sys",    0);
+
+            // history
+            //     /history/{uuid}
+            ITUtilStructureElement.assertRead("/history/" + uuid.toString(),            1);
+            ITUtilStructureElement.assertRead("/history/" + systemUuid.toString(),      1);
+            ITUtilStructureElement.assertRead("/history/" + systemGroupUuid.toString(), 1);
+
             ITUtilStructureElement.assertExists(Type.SUBSYSTEM, "Sys-AA1", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.SUBSYSTEM, "Sys-AA2", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.SUBSYSTEM, "Sys-AA3", Boolean.TRUE);
diff --git a/src/test/java/org/openepics/names/docker/StructuresSystemGroupIT.java b/src/test/java/org/openepics/names/docker/StructuresSystemGroupIT.java
index 79c37105c4a4814fa0dd8137ad0592c96846fe2d..543d8afbff944f1a09d84b612d16d494c41d3b6f 100644
--- a/src/test/java/org/openepics/names/docker/StructuresSystemGroupIT.java
+++ b/src/test/java/org/openepics/names/docker/StructuresSystemGroupIT.java
@@ -1738,6 +1738,10 @@ class StructuresSystemGroupIT {
             // from first structure element
             assertNotNull(uuid);
 
+            // read & search
+            //     /{type}
+            //     type, statuses, deleted, uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            //     combination
             ITUtilStructureElement.assertRead("/SYSTEMGROUP?mnemonic=A__",                                                  45);
             ITUtilStructureElement.assertRead("/SYSTEMGROUP?statuses=PENDING&mnemonic=A__",                                 10);
             ITUtilStructureElement.assertRead("/SYSTEMGROUP?statuses=APPROVED&mnemonic=A__",                                20);
@@ -1759,8 +1763,52 @@ class StructuresSystemGroupIT {
             ITUtilStructureElement.assertRead("/SYSTEMGROUP?deleted=true&statuses=REJECTED&mnemonic=A__",                    5);
             ITUtilStructureElement.assertRead("/SYSTEMGROUP?deleted=true&statuses=PENDING&statuses=APPROVED&mnemonic=A__",  10);
 
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?uuid=" + uuid.toString(),        1);
+
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?parentuuid=" + uuid.toString(),  0);
+
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?name=na",                        0);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?name=na_",                       0);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?name=na__",                     45, -1);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?name=na___",                     0);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?name=na%",                      45, -1);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?name=name",                     45, -1);
+
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?mnemonicequivalence=A__",       45, -1);
+
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?mnemonicepath=A__",             45, -1);
+
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?description=desc",               0);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?description=desc%",             35, -1);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?description=sc",                 0);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?description=sc%",                0);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?description=%sc",                0);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?description=%sc%",              45, -1);
+            ITUtilStructureElement.assertRead("/SYSTEMGROUP?description=description",       35, -1);
+
+            // children
+            //     /children/{type}/{uuid}
+            //     type, uuid, statuses, deleted, name, mnemonic, mnemonicequivalence, mnemonicpath, description
             ITUtilStructureElement.assertRead("/children/SYSTEMGROUP/" + uuid.toString(), 0);
 
+            // mnemonic
+            //     /mnemonic/{mnemonic}
+            ITUtilStructureElement.assertRead("/mnemonic/A",        0);
+            ITUtilStructureElement.assertRead("/mnemonic/A__",     15, -1);
+            ITUtilStructureElement.assertRead("/mnemonic/AG_",      5);
+            ITUtilStructureElement.assertRead("/mnemonic/AG1",      1);
+
+            // mnemonic path
+            //     /mnemonicpath/{mnemonicpath}
+            ITUtilStructureElement.assertRead("/mnemonicpath/A",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/A__", 15, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG_",  5);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG1",  1);
+
+            // history
+            //     /history/{uuid}
+            ITUtilStructureElement.assertRead("/history/" + uuid.toString(), 1);
+
             ITUtilStructureElement.assertExists(Type.SYSTEMGROUP, "AA1", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.SYSTEMGROUP, "AA2", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.SYSTEMGROUP, "AA3", Boolean.TRUE);
diff --git a/src/test/java/org/openepics/names/docker/StructuresSystemIT.java b/src/test/java/org/openepics/names/docker/StructuresSystemIT.java
index 97190d68b9c78f66b135f890ca4c42cea936dea5..0ef774dd18edcb19a3e3da00a94c825e11cd1091 100644
--- a/src/test/java/org/openepics/names/docker/StructuresSystemIT.java
+++ b/src/test/java/org/openepics/names/docker/StructuresSystemIT.java
@@ -1774,6 +1774,10 @@ class StructuresSystemIT {
             // from first structure element
             assertNotNull(uuid);
 
+            // read & search
+            //     /{type}
+            //     type, statuses, deleted, uuid, parentuuid, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            //     combination
             ITUtilStructureElement.assertRead("/SYSTEM?mnemonic=A__",                                                  45);
             ITUtilStructureElement.assertRead("/SYSTEM?statuses=PENDING&mnemonic=A__",                                 10);
             ITUtilStructureElement.assertRead("/SYSTEM?statuses=APPROVED&mnemonic=A__",                                20);
@@ -1795,9 +1799,64 @@ class StructuresSystemIT {
             ITUtilStructureElement.assertRead("/SYSTEM?deleted=true&statuses=REJECTED&mnemonic=A__",                    5);
             ITUtilStructureElement.assertRead("/SYSTEM?deleted=true&statuses=PENDING&statuses=APPROVED&mnemonic=A__",  10);
 
-            ITUtilStructureElement.assertRead("/children/SYSTEM/" + uuid.toString(),                 0);
+            ITUtilStructureElement.assertRead("/SYSTEM?uuid=" + systemGroupUuid.toString(),        0);
+            ITUtilStructureElement.assertRead("/SYSTEM?uuid=" + uuid.toString(),                   1);
+
+            ITUtilStructureElement.assertRead("/SYSTEM?parentuuid=" + systemGroupUuid.toString(), 45, -1);
+            ITUtilStructureElement.assertRead("/SYSTEM?parentuuid=" + uuid.toString(),             0);
+
+            ITUtilStructureElement.assertRead("/SYSTEM?name=na",                        0);
+            ITUtilStructureElement.assertRead("/SYSTEM?name=na_",                       0);
+            ITUtilStructureElement.assertRead("/SYSTEM?name=na__",                     45, -1);
+            ITUtilStructureElement.assertRead("/SYSTEM?name=na___",                     0);
+            ITUtilStructureElement.assertRead("/SYSTEM?name=na%",                      45, -1);
+            ITUtilStructureElement.assertRead("/SYSTEM?name=name",                     45, -1);
+
+            ITUtilStructureElement.assertRead("/SYSTEM?mnemonicequivalence=A__",       45, -1);
+
+            ITUtilStructureElement.assertRead("/SYSTEM?mnemonicepath=A__",             45, -1);
+
+            ITUtilStructureElement.assertRead("/SYSTEM?description=desc",               0);
+            ITUtilStructureElement.assertRead("/SYSTEM?description=desc%",             35, -1);
+            ITUtilStructureElement.assertRead("/SYSTEM?description=sc",                 0);
+            ITUtilStructureElement.assertRead("/SYSTEM?description=sc%",                0);
+            ITUtilStructureElement.assertRead("/SYSTEM?description=%sc",                0);
+            ITUtilStructureElement.assertRead("/SYSTEM?description=%sc%",              45, -1);
+            ITUtilStructureElement.assertRead("/SYSTEM?description=description",       35, -1);
+
+            // children
+            //     /children/{type}/{uuid}
+            //     type, uuid, statuses, deleted, name, mnemonic, mnemonicequivalence, mnemonicpath, description
+            ITUtilStructureElement.assertRead("/children/SYSTEM/"      + uuid.toString(),            0);
+            ITUtilStructureElement.assertRead("/children/SYSTEM/"      + systemGroupUuid.toString(), 0);
+            ITUtilStructureElement.assertRead("/children/SYSTEMGROUP/" + uuid.toString(),            0);
             ITUtilStructureElement.assertRead("/children/SYSTEMGROUP/" + systemGroupUuid.toString(), 1, -1);
 
+            // mnemonic
+            //     /mnemonic/{mnemonic}
+            ITUtilStructureElement.assertRead("/mnemonic/A",           0);
+            ITUtilStructureElement.assertRead("/mnemonic/A__",        15, -1);
+            ITUtilStructureElement.assertRead("/mnemonic/AG_",         5);
+            ITUtilStructureElement.assertRead("/mnemonic/AG1",         1);
+            ITUtilStructureElement.assertRead("/mnemonic/Sg",          1);
+
+            // mnemonic path
+            //     /mnemonicpath/{mnemonicpath}
+            ITUtilStructureElement.assertRead("/mnemonicpath/A",       0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/A__",    15, -1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG_",     5);
+            ITUtilStructureElement.assertRead("/mnemonicpath/AG1",     1);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-A%",   0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-A",    0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-A__",  0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-AG_",  0);
+            ITUtilStructureElement.assertRead("/mnemonicpath/Sg-AG1",  0);
+
+            // history
+            //     /history/{uuid}
+            ITUtilStructureElement.assertRead("/history/" + uuid.toString(),            1);
+            ITUtilStructureElement.assertRead("/history/" + systemGroupUuid.toString(), 1);
+
             ITUtilStructureElement.assertExists(Type.SYSTEM, "AA1", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.SYSTEM, "AA2", Boolean.TRUE);
             ITUtilStructureElement.assertExists(Type.SYSTEM, "AA3", Boolean.TRUE);
diff --git a/src/test/java/org/openepics/names/util/EncodingUtilityTest.java b/src/test/java/org/openepics/names/util/EncodingUtilityTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..247c5a2a902dd3cfea5eb2e4b32ed161a9fe3fe4
--- /dev/null
+++ b/src/test/java/org/openepics/names/util/EncodingUtilityTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2018 European Spallation Source ERIC.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+package org.openepics.names.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Purpose to test EncodingUtility class.
+ *
+ * @author Lars Johansson
+ */
+public class EncodingUtilityTest {
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringNull() {
+        String s = null;
+        assertThrows(NullPointerException.class, () -> { EncodingUtility.encode(s); });
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringEmpty() {
+        String s = "";
+        assertEquals(s, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringPercent() {
+        String s = "%";
+        String expected = "%25";
+        assertEquals(expected, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringPlus() {
+        String s = "+";
+        String expected = "%2B";
+        assertEquals(expected, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringUnderscore() {
+        String s = "_";
+        String expected ="_";
+        assertEquals(expected, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringWhitespace() {
+        String s = " ";
+        String expected ="+";
+        assertEquals(expected, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringNumbers() {
+        String s = "12345678";
+        assertEquals(s, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringLetters() {
+        String s = "abcdefgh";
+        assertEquals(s, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringLettersPlus() {
+        String s = "abc+efgh";
+        String expected = "abc%2Befgh";
+        assertEquals(expected, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringLettersWhitespace() {
+        String s = "abcd fgh";
+        String expected = "abcd+fgh";
+        assertEquals(expected, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testEncodeStringLettersPlusWhitespace() {
+        String s = "ab de+gh";
+        String expected = "ab+de%2Bgh";
+        assertEquals(expected, EncodingUtility.encode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringNull() {
+        String s = null;
+        assertThrows(NullPointerException.class, () -> { EncodingUtility.decode(s); });
+
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringEmpty() {
+        String s = "";
+        assertEquals(s, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringPercent() {
+        String s = "%25";
+        String expected = "%";
+        assertEquals(expected, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringPlus() {
+        String s = "%2B";
+        String expected = "+";
+        assertEquals(expected, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringUnderscore() {
+        String s = "_";
+        String expected = "_";
+        assertEquals(expected, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringWhitespace() {
+        String s = "+";
+        String expected = " ";
+        assertEquals(expected, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringNumbers() {
+        String s = "12345678";
+        assertEquals(s, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringLetters() {
+        String s = "abcdefgh";
+        assertEquals(s, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringLettersPlus() {
+        String s = "abc%2Befgh";
+        String expected = "abc+efgh";
+        assertEquals(expected, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringLettersWhitespace() {
+        String s = "abcd+fgh";
+        String expected = "abcd fgh";
+        assertEquals(expected, EncodingUtility.decode(s));
+    }
+
+    /**
+     * Test for encoding a string.
+     */
+    @Test
+    void testDecodeStringLettersPlusWhitespace() {
+        String s = "ab+de%2Bgh";
+        String expected = "ab de+gh";
+        assertEquals(expected, EncodingUtility.decode(s));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/util/URLUtilityTest.java b/src/test/java/org/openepics/names/util/URLUtilityTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c835be49bd5d14512135444ff9e5ecef48052f9c
--- /dev/null
+++ b/src/test/java/org/openepics/names/util/URLUtilityTest.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2018 European Spallation Source ERIC.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+package org.openepics.names.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Purpose to test URLUtility class.
+ *
+ * @author Lars Johansson
+ */
+public class URLUtilityTest {
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLNull() {
+        String url = null;
+        assertEquals(url, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLEmpty() {
+        String url = "";
+        assertEquals(url, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLWhitespace() {
+        String url = " ";
+        String expected = "+";
+        assertEquals(expected, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLString() {
+        String url = "abcd1234";
+        assertEquals(url, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPath() {
+        String url = "abcd.xhtml";
+        assertEquals(url, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQuery() {
+        String url = "abcd.xhtml?efgh";
+        assertEquals(url, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryPercent() {
+        String url = "/abcd.xhtml?uvwx-0%";
+        String expected = "/abcd.xhtml?uvwx-0%25";
+        assertEquals(expected, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryPlus() {
+        String url = "abcd.xhtml?efg+h";
+        String expected = "abcd.xhtml?efg%2Bh";
+        assertEquals(expected, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryWhitespace() {
+        String url = "abcd.xhtml?ef gh";
+        String expected = "abcd.xhtml?ef+gh";
+        assertEquals(expected, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryAttributeValue1Pair() {
+        String url = "abcd.xhtml?efgh=ijkl";
+        assertEquals(url, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryAttributeValue1PairEmpty() {
+        String url = "abcd.xhtml?efgh=";
+        assertEquals(url, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryAttributeValue1PairComplex() {
+        String url = "abcd.xhtml?efgh=ijkl mnop+qrst+ uvwx";
+        String expected = "abcd.xhtml?efgh=ijkl+mnop%2Bqrst%2B+uvwx";
+        assertEquals(expected, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryAttributeValue2Pairs() {
+        String url = "abcd.xhtml?efgh=ijkl&mnop=qrst";
+        assertEquals(url, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryAttributeValue2PairsComplex() {
+        String url = "abcd.xhtml?efgh=i+kl&mnop=qr t";
+        String expected = "abcd.xhtml?efgh=i%2Bkl&mnop=qr+t";
+        assertEquals(expected, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryAttributeValue3PairsComplex() {
+        String url = "abcd.xhtml?efgh&uvwx=yzabc  def++ghijklm+ nop&abcdefgh=";
+        String expected = "abcd.xhtml?efgh&uvwx=yzabc++def%2B%2Bghijklm%2B+nop&abcdefgh=";
+        assertEquals(expected, URLUtility.encodeURL(url));
+    }
+
+    /**
+     * Test for encoding a URL.
+     */
+    @Test
+    void testEncodeURLPathQueryIpPortPercent() {
+        String url = "http://127.0.0.1:8080/a/b/c/d/e/f/RFQ-010:EMR-FS-0%";
+        String expected = "http://127.0.0.1:8080/a/b/c/d/e/f/RFQ-010%3AEMR-FS-0%25";
+        assertEquals(expected, URLUtility.encodeURL(url));
+    }
+
+}